#include "mx_frame_core.h" 
#include "string.h"

static uint16_t CalChecksum(uint8_t * data, uint16_t len)
{
    uint16_t sum = 0;
    for(int i = 0; i < len; ++i)
    {
        sum += data[i];
    }
    return sum;
}



/*
功能：帧接收处理校验函数
参数：rev_buff--接收好一帧数据的buff地址,rev_buff_len--接收好一帧数据的长度，
返回：帧数据正确或错误代号


*/
uint8_t mx_frame_rev(uint8_t* rev_buff, uint16_t rev_buff_len, mx_frame_struct *mx_out_frame)
{
		uint8_t scan_max_number = 30;
		uint8_t state = 0;
		uint16_t index = 0;
		uint16_t start_index = 0;
		uint16_t surplus_len = 0;
		
		uint16_t frame_sof = 0;
		uint8_t frame_trantype = 0;
		uint16_t frame_datalen = 0;
		uint8_t *frame_data = NULL;
		uint8_t frame_type = 0;
		uint16_t frame_checksum = 0;

	
		if(rev_buff_len < 8)
		{
				return FRAME_LEN_LITTLE;
		}
	
		while(1)
		{
				switch(state)
				{
					case SOF_GET:
						{
								frame_sof = (rev_buff[index]<<8) + rev_buff[index + 1];
								index++;
								surplus_len = rev_buff_len - index;
								if(frame_sof == FRAME_HEAD)
								{
										start_index = index - 1;
										state = TRANTYPE_GET;
										index++;
								}
								else if(index == scan_max_number || surplus_len < 8)
								{
										return SOF_ERR;
								}
						}
						break;
						
					case TRANTYPE_GET:
						{
								frame_trantype = rev_buff[index];
								index++;
								state = DATALEN_GET;
						}
						break;
						
					case DATALEN_GET:
						{
								frame_datalen = rev_buff[index] + (rev_buff[index + 1]<<8);
								index = index + 2;
								surplus_len = rev_buff_len - index;
								if(frame_datalen - 3 <= surplus_len)
								{
										state = TYPE_GET;
								}
								else
								{
										return DATA_LEN_OVER;
								}
						}
						break;
						
					case TYPE_GET:
						{
								frame_type = rev_buff[index];
								index++;
								state = DATA_GET;
						}
						break;
					
					case DATA_GET:
						{
								frame_data = &rev_buff[index];
								index = index + frame_datalen - 6;
								state = CHECKSUM_GET;
						}
						break;
						
					case CHECKSUM_GET:
						{
								frame_checksum = (rev_buff[index + 1]<<8) + rev_buff[index];
								if(frame_checksum == CalChecksum((uint8_t*)&rev_buff[start_index], frame_datalen))
								{
										mx_out_frame->type = frame_type;
										mx_out_frame->trantype = frame_trantype;
										mx_out_frame->sof = frame_sof;
										mx_out_frame->datalen = frame_datalen;
										mx_out_frame->data = frame_data;
										//memcpy(mx_out_frame->data,frame_data,frame_datalen-6);//有bug
										mx_out_frame->checksum = frame_checksum;
										return REV_SUCCESSFUL;
								}
								else
								{
										return CHECK_SUM_ERR;
								}
						}
					
					
				}
			
		}
}


uint16_t create_frame(uint8_t *out_frame_buff, uint16_t out_fram_buff_len, mx_frame_struct *mx_input_frame)
{
		uint16_t num = 0;
		uint16_t loop = 0;
		uint16_t checksum = 0;
		uint8_t *tx_buff = out_frame_buff;
		
		if(tx_buff == NULL)
		{
				return 0;
		}
		tx_buff[num++] = (uint8_t)SERIAL_HEAD;
		tx_buff[num++] = SERIAL_HEAD>>8;
		tx_buff[num++] =	mx_input_frame->trantype;
		tx_buff[num++] = (mx_input_frame->datalen + 6) & 0xff;
		tx_buff[num++] = (mx_input_frame->datalen + 6) >> 8;
		tx_buff[num++] = mx_input_frame->type;
		for(loop = 0; loop < mx_input_frame->datalen; loop++)
		{
			tx_buff[num++] = mx_input_frame->data[loop];
		}
		
		checksum = CalChecksum(tx_buff, num);
		
		tx_buff[num++] = checksum & 0xff;
		tx_buff[num] = checksum >> 8;
		return num + 1;
}

