#include "at_command.h"

#include <unistd.h>

static char cmd_buffer[CMD_BUFFER_SIZE] = {0};
static int cmd_indx = 0;

Ciss_data_struct m_dev;

UCHAR convert_string_2_hex8(CHAR* ascii)
{
	UCHAR r = 0;
	SHORT i = 0;

	for(i=0; i<2; i++)
	{
		if((ascii[i] >='a') && (ascii[i] <='z'))
		{
			ascii[i] -= 0x20;
		}
	}

	r = (ascii[0]>'9') ? (ascii[0] - 'A' + 10) : (ascii[0] - '0');
	r <<= 4;

	r += (ascii[1]>'9') ? (ascii[1] - 'A' + 10) : (ascii[1] - '0');

	return r;
}

SHORT convert_string_2_hex16(CHAR* ascii)
{
	SHORT r = 0;
	SHORT i = 0;


	for(i=0; i<4; i++)
	{
		if((ascii[i] >='a') && (ascii[i] <='z'))
		{
			ascii[i] -= 0x20;
		}

		r += (ascii[i]>'9') ? (ascii[i] - 'A' + 10) : (ascii[i] - '0');

		if(i<3)
			r <<= 4;
	}

	return r;
}



UINT convert_string_2_hex32(CHAR* ascii)
{
	UINT r = 0;
	SHORT i = 0;

	for(i=0; i<8; i++)
	{
		if((ascii[i] >='a') && (ascii[i] <='z'))
		{
			ascii[i] -= 0x20;
		}

		r += (ascii[i]>'9') ? (ascii[i] - 'A' + 10) : (ascii[i] - '0');

		if(i<7)
			r <<= 4;
	}

	return r;
}


static void at_cmd_get_value(char*buf, int len, int x, char* desBuf, int l)
{
	int i = 0;
	int inx = 0;
	int j = 0;
	int k = 0;

	for(j=0; j<len; j++)	///find the = char
	{
		if(buf[j] == '=')
		{
			j++;
			break;
		}

	}
	////find the , char positon
	for(i=j; i<len; i++)
	{
		if(inx == x)
		{
			if(k >= l)
			{
				break;
			}
			else
			{
				desBuf[k++] = buf[i];
			}

		}
		else
		{
			if(buf[i] == ',')
			{
				inx++;
			}
		}
	}
}

extern void Ciss_data_post(void);

static void at_cmd_DT(char*buf, int len)
{
	CHAR macAddr[16] ={0};
	CHAR Value[5] ={0};

	printf("process cmd DT =%d !\r\n", len);


	at_cmd_get_value(buf, len, 0, macAddr, 12);
	memcpy(m_dev.dev_sn, macAddr, 12);

	/////acc xyz
	at_cmd_get_value(buf, len, 1, Value, 4);
	m_dev.motion_data.Acc_x = convert_string_2_hex16(Value);
	at_cmd_get_value(buf, len, 2, Value, 4);
	m_dev.motion_data.Acc_y = convert_string_2_hex16(Value);
	at_cmd_get_value(buf, len, 3, Value, 4);
	m_dev.motion_data.Acc_z = convert_string_2_hex16(Value);


	/////gro xyz
	at_cmd_get_value(buf, len, 4, Value, 4);
	m_dev.motion_data.Gro_x = convert_string_2_hex16(Value);
	at_cmd_get_value(buf, len, 5, Value, 4);
	m_dev.motion_data.Gro_y = convert_string_2_hex16(Value);
	at_cmd_get_value(buf, len, 6, Value, 4);
	m_dev.motion_data.Gro_z = convert_string_2_hex16(Value);

	/////mag xyz
	at_cmd_get_value(buf, len, 7, Value, 4);
	m_dev.motion_data.Mag_x = convert_string_2_hex16(Value);
	at_cmd_get_value(buf, len, 8, Value, 4);
	m_dev.motion_data.Mag_y = convert_string_2_hex16(Value);
	at_cmd_get_value(buf, len, 9, Value, 4);
	m_dev.motion_data.Mag_z = convert_string_2_hex16(Value);


	printf("dev sn = %s  ",m_dev.dev_sn);
	printf("motion data  acc x= %d, y=%d, z=%d   ", m_dev.motion_data.Acc_x,
			m_dev.motion_data.Acc_y, m_dev.motion_data.Acc_z);
	printf("gro x= %d, y=%d, z=%d   ", m_dev.motion_data.Gro_x,
				m_dev.motion_data.Gro_y, m_dev.motion_data.Gro_z);
	printf("mag x= %d, y=%d, z=%d   \r\n", m_dev.motion_data.Mag_x,
					m_dev.motion_data.Mag_y, m_dev.motion_data.Mag_z);

	Ciss_data_post();
}

static void at_cmd_VT(char*buf, int len)
{
	CHAR macAddr[16] ={0};
	CHAR Value[5] ={0};
	CHAR ValueM[9] ={0};
	/////&ET=02891B550346,00ed,114d,00018f00,00ed,00018f00
	printf("process cmd ET =%d !\r\n", len);
	at_cmd_get_value(buf, len, 0, macAddr, 12);
	memcpy(m_dev.dev_sn, macAddr, 12);
	/////temprature
	at_cmd_get_value(buf, len, 1, Value, 4);
	m_dev.evr_data.temp = convert_string_2_hex16(Value);
	/////humid
	at_cmd_get_value(buf, len, 2, Value, 4);
	m_dev.evr_data.humid = convert_string_2_hex16(Value);
	////pressure
	at_cmd_get_value(buf, len, 3, ValueM, 8);
	m_dev.evr_data.pressure = convert_string_2_hex32(ValueM);
	////noise
	at_cmd_get_value(buf, len, 4, Value, 4);
	m_dev.evr_data.noise = convert_string_2_hex16(Value);
	////light
	at_cmd_get_value(buf, len, 5, ValueM, 8);
	m_dev.evr_data.light = convert_string_2_hex32(ValueM);

	printf("devv sn = %s  ",m_dev.dev_sn);
	printf("motion data  temp=%d, humid=%d, pressure = %d   ", m_dev.evr_data.temp,
			m_dev.evr_data.humid, m_dev.evr_data.pressure);
	printf("noise= %d, light=%d  \r\n", m_dev.evr_data.noise,
				m_dev.evr_data.light);

	Ciss_data_post();
}

static void at_cmd_CN(char*buf, int len)
{
	CHAR Value[5] ={0};
	UCHAR byt = 0;
	at_cmd_get_value(buf, len, 0, Value, 2);
	byt = convert_string_2_hex8(Value);
	if(byt == 0x00)
	{
		printf("process cmd CONNECTED!\r\n");
		m_dev.dev_state = STATE_CONNECTED;
	}
	else
	{
		m_dev.dev_state = STATE_IDLE;
	}
}

static void at_cmd_IT(char*buf, int len)
{
	CHAR Value[5] ={0};
	UCHAR byt = 0;
	at_cmd_get_value(buf, len, 0, Value, 2);
	byt = convert_string_2_hex8(Value);
	if(byt == 0x00)
	{
		printf("process cmd IT ON!\r\n");
		m_dev.dev_state = STATE_CH_OPEN;
	}
	else
	{
		m_dev.dev_state = STATE_IDLE;
	}
}

static void at_cmd_ET(char*buf, int len)
{
	CHAR Value[5] ={0};
	UCHAR byt = 0;
	at_cmd_get_value(buf, len, 0, Value, 2);
	byt = convert_string_2_hex8(Value);
	if(byt == 0x00)
	{
		printf("process cmd ET ON!\r\n");
		m_dev.dev_state = STATE_CH_OPEN;
	}
	else
	{
		m_dev.dev_state = STATE_IDLE;
	}
}

static void at_cmd_DC(char*buf, int len)
{
	CHAR Value[5] ={0};
	UCHAR byt = 0;
	at_cmd_get_value(buf, len, 0, Value, 2);
	byt = convert_string_2_hex8(Value);
	if(byt == 0x00)
	{
		printf("process cmd DISCONNECT!\r\n");
		m_dev.dev_state = STATE_IDLE;
	}
}

static void at_cmd_CF(char*buf, int len)
{
	CHAR Value[5] ={0};
	UCHAR byt = 0;
	at_cmd_get_value(buf, len, 0, Value, 2);
	byt = convert_string_2_hex8(Value);
	if(byt == 0x00)
	{
		m_dev.dev_state = STATE_SAMPLE;
		printf("process cmd START SAMPLE!\r\n");
	}
}

static void at_cmd_LS(char*buf, int len)
{
	printf("process cmd LS =%d !\r\n", len);
}

static void at_cmd_PW(char*buf, int len)
{
	CHAR Value[5] ={0};
	UCHAR byt = 0;
	at_cmd_get_value(buf, len, 0, Value, 2);
	byt = convert_string_2_hex8(Value);
	if(byt == 0x00)
	{
		m_dev.dev_state = STATE_IDLE;
		printf("process cmd POWER ON!\r\n");
	}
}

#define CMD_NUM (sizeof(uartCmd)/sizeof(uartCmdProcess))

static const uartCmdProcess uartCmd[] =
{
	{true, (ptr_const)"&CN=", at_cmd_CN},
	{true, (ptr_const)"&CF=", at_cmd_CF},
	{true, (ptr_const)"&IT=", at_cmd_IT},
	{true, (ptr_const)"&ET=", at_cmd_ET},
	{true, (ptr_const)"&DT=", at_cmd_DT},
	{true, (ptr_const)"&VT=", at_cmd_VT},
	{true, (ptr_const)"&DC=", at_cmd_DC},		////maybe can't use , because bypass mode
	{true, (ptr_const)"&LS=", at_cmd_LS},
	{true, (ptr_const)"&PW=", at_cmd_PW},

	{false, (ptr_const)"&NC=",NULL},
};


bool Uart_frame_over(UCHAR*buf, USHORT len)
{
	USHORT i = 0;
	for(i=0; i<len; i++)
	{
		if(buf[i] == '\n')
			return true;
	}

	return false;
}


void at_command_buf_clean(void)
{
	memset(cmd_buffer, 0, CMD_BUFFER_SIZE);
	cmd_indx = 0;
}


SHORT at_command_process(CHAR* strBuf, USHORT len)
{
	int j = 0;
	struct timeval tv;

	if(strBuf[0] != '&')
		return -1;

	if(strBuf[len-1] != '\n')
		return -2;


	gettimeofday(&tv,NULL);
	m_dev.send_tim = tv.tv_sec*1000;
	m_dev.send_tim += tv.tv_usec/1000;

	printf("time stamp = %ld, %f\r\n", m_dev.send_tim, m_dev.send_tim);

	for(j=0; uartCmd[j].continual==true; j++)
	{
		if(memcmp(strBuf, uartCmd[j].cmdString,4) == 0)
		{
			uartCmd[j].processer(strBuf, len);
			return 0;
		}
		else
		{
			continue;
		}
	}

	return -3;
}


