/*
 * rfid.c
 *
 *  Created on: Mar 22, 2012
 *      Author: RomanM
 */

#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include "../../uip.h"
#include "../uip-app.h"
#include "ServicePort/setting.h"
#include "rfid.h"
#include "aes/aes.h"

enum {
	RFID_CONNECTED,
	RFID_PIN,
	RFID_END,
	RFID_DISCONNECTED
};

struct app_state *s;

extern void prepareNoRespond(void);
extern void prepareDenied(char *message);
extern void prepareOpen(void);
extern void preparePIN(void);
extern int8_t pinOK;

extern uint8_t cardId[];
extern uint8_t pin[];

extern unsigned char aes_key[];
extern aes_context aes_ctx;

// ----------------------------------------------------------------------------

void uip_rfid_request(void) {
	uip_connect((uip_ipaddr_t*)setting.serverAddress, HTONS(RFID_REQUEST_PORT));
}

void uip_rfid_call(void) {
	char toSend_plain[32];
	uint8_t toSend_aes[32];

	s = &(uip_conn->appstate);

	if (uip_connected()) {
		s->state = RFID_CONNECTED;

		memset(toSend_plain, 0, sizeof(toSend_plain));
		sprintf(toSend_plain,
				"CARD %02X%02X%02X%02X%02X",
				cardId[0],
				cardId[1],
				cardId[2],
				cardId[3],
				cardId[4]);

		aes_setkey_enc(&aes_ctx, aes_key, 128);
		aes_crypt_ecb(&aes_ctx, AES_ENCRYPT, (uint8_t*)toSend_plain, toSend_aes);
		aes_crypt_ecb(&aes_ctx, AES_ENCRYPT, (uint8_t*)toSend_plain + 16, toSend_aes + 16);
		uip_send(toSend_aes, sizeof(toSend_aes));
	}
	else if (uip_newdata()) {
		aes_setkey_dec(&aes_ctx, aes_key, 128);
		aes_crypt_ecb(&aes_ctx, AES_DECRYPT, uip_appdata, uip_appdata);
		aes_crypt_ecb(&aes_ctx, AES_DECRYPT, uip_appdata + 16, uip_appdata + 16);

		if (!strcmp(uip_appdata,"OK")) {
			prepareOpen();
			s->state = RFID_END;
		}
		else if (!strcmp(uip_appdata, "PIN")) {
			preparePIN();
			s->state = RFID_PIN;
		}
		else if (!memcmp(uip_appdata, "ERR ", 4)) {
			prepareDenied(uip_appdata + 4);
			s->state = RFID_END;
		}
		else {
			prepareDenied("Access denied");
			s->state = RFID_END;
		}
	}
	else if (uip_acked()) {
		if (s->state == RFID_END) {
			uip_close();
			s->state = RFID_DISCONNECTED;
		}
	}
	else if (uip_timedout()) {
		uip_abort();
		s->state = RFID_DISCONNECTED;
		prepareNoRespond();
	}
	else if (uip_aborted()) {
		s->state = RFID_DISCONNECTED;
		uip_close();
	}
	else if (uip_closed()) {
			s->state = RFID_DISCONNECTED;
			uip_close();
		}
	else if (s->state == RFID_PIN && pinOK == 1) {
		s->state = RFID_CONNECTED;
		memset(toSend_plain, 0, sizeof(toSend_plain));
		sprintf(toSend_plain,
				"PIN %c%c%c%c",
				pin[0],
				pin[1],
				pin[2],
				pin[3]);

		aes_setkey_enc(&aes_ctx, aes_key, 128);
		aes_crypt_ecb(&aes_ctx, AES_ENCRYPT, (uint8_t*)toSend_plain, toSend_aes);
		aes_crypt_ecb(&aes_ctx, AES_ENCRYPT, (uint8_t*)toSend_plain + 16, toSend_aes + 16);
		uip_send(toSend_aes, sizeof(toSend_aes));
	}
	else if (s->state == RFID_PIN && pinOK == -1) {
		memset(toSend_plain, 0, sizeof(toSend_plain));
		strcpy(toSend_plain, "PIN xxxx");

		aes_setkey_enc(&aes_ctx, aes_key, 128);
		aes_crypt_ecb(&aes_ctx, AES_ENCRYPT, (uint8_t*)toSend_plain, toSend_aes);
		aes_crypt_ecb(&aes_ctx, AES_ENCRYPT, (uint8_t*)toSend_plain + 16, toSend_aes + 16);
		uip_send(toSend_aes, sizeof(toSend_aes));
		s->state = RFID_CONNECTED;
	}
}
