#include "includes.h"
#include "device.h"
#include "tax_ctrl.h"
#include "net_proc.h"
#include "uart.h"
#include "des.h"
#include "BSP.h"
#include "net_ctrl.h"

int rs485_send_flag = 0;
#define CRC_INIT_VALUE 0x0000


rcv_data_0x8C_t g_tax8Cda;

/*密文*/
int ytsf_0xa2_0x00_anaylse(void *puser, uint8_t *data, uint8_t data_len)
{/* 信息类型[1byte] + 枪号[1byte] + 读取结果[1byte] + 
读取数据[Mbytes] 监 控 序 列 号 (BCD码)[5bytes]+序列号(ASCII 码)[10bytes] */
	tax_info_t * p_tax = (tax_info_t *)puser;
	uint8_t tax_data = *(data + 8);
	int ret = 0;

	p_tax->gun_num = 1;
	if(isdigit(tax_data)) {//英泰赛福
            p_tax->factory = 1;
            switch(tax_data) {
            case '0':
            case '1':
                p_tax->gun_num = 1;
                break;
            case '2':
            case '3':
                p_tax->gun_num = 2;
                break;
            default:
                p_tax->gun_num = tax_data - '0';
                break;
            }
	} else if(isalpha(tax_data)) {//拓盛
            p_tax->factory = 2;
            if((tax_data >= 'A')&&(tax_data <= 'Z')) {
                    p_tax->gun_num = tax_data - 'A' + 1;
            } else if((tax_data >= 'a')&&(tax_data <= 'z')) {
                    p_tax->gun_num = tax_data - 'a' + 1;
            }
	}
	 
	memcpy(p_tax->monitor_serino, data + 3, 15);
	data_dump("monitor_serino", p_tax->monitor_serino, 16);

	return ret;
}

int tax_0x70_anaylse(void *puser, uint8_t *data, uint8_t data_len)
{
    tax_info_t * p_tax = (tax_info_t *)puser;

    if(data_len > 20)
    {
        if(isdigit(data[1])) {// 数字为英泰
            p_tax->factory = 1;
            switch(data[1]) {
            case '0':
            case '1':
                p_tax->gun_num = 1;
                break;
            case '2':
            case '3':
                p_tax->gun_num = 2;
                break;
            default:
                p_tax->gun_num = data[1] - '0';
                break;
            }
        } else if(isalpha(data[1])) {//字母 为排成
            p_tax->factory = 2;
            if((data[1] >= 'A')&&(data[1] <= 'Z')) {
                p_tax->gun_num = data[1] - 'A' + 1;
            } else if((data[1] >= 'a')&&(data[1] <= 'z')) {
                p_tax->gun_num = data[1] - 'a' + 1;
            }
        }
        memcpy(&p_tax->monitor_serino[5],data+1,10);
        //memcpy(p_tax->bmq_serino,data+11,10);
        //data_dump("tax_serino",p_tax->tax_serino,10);
    }
    return 0;
}
/**
  * @brief hex convert ascii
  * @par param[in] *ascii:ascii data
  * @par param[in] *hex:hex data
  * @par param[in] hexLen:length of hex
  * @retval length
  */
uint32_t Hex2Dec(uint8_t *hex, uint16_t hexLen)
{
    uint32_t data = 0;
    uint8_t i;
	
    for(i=0;i<hexLen;i++) {
        data = data * 100;
        data += (hex[i]>>4)*10 + (hex[i]&0x0F);
    }
    return data;
}
uint64_t Hex2Dec64(uint8_t *hex, uint16_t hexLen)
{
    uint64_t data = 0;
    uint8_t i;

    for(i=0;i<hexLen;i++) {
        data = data * 100;
        data += (hex[i]>>4)*10 + (hex[i]&0x0F);
    }
    return data;
}
int ytsf_0xa1_0x11_anaylse(void *puser, uint8_t *data, uint8_t data_len)
{/* 累计类型[1byte] + 枪号[1byte] + 读取结果[1byte] + 
读取数据[Mbytes] 时间[3bytes]+油量[5bytes]+金额[5bytes]+单价[3bytes]
0x11 查当次加油信息*/
	gun_info_t * p_gun = (gun_info_t *)puser;
	uint8_t *current = (uint8_t *)data + 6;
	int ret = 0;

	if(data_len < 19) {
		return -1;
	}
      //   data_dump("0x86 data :", data, data_len);
        p_gun->time_day = *(data+3);
        p_gun->time_hour = *(data+4);
        p_gun->time_minute = *(data+5);
      //   printf("%02x,%02x,%02x\r\n",p_gun->time_day,p_gun->time_hour,p_gun->time_minute);
	p_gun->last_oil_volume = Hex2Dec(current, 5);
	p_gun->last_price = Hex2Dec(current + 5, 5);
	p_gun->last_unit_price = Hex2Dec(current + 10, 3);

	return ret;
}

int ytsf_0xa1_0x14_anaylse(void *puser, uint8_t *data, uint8_t data_len)
{/* 累计类型[1byte] + 枪号[1byte] + 读取结果[1byte] + 
读取数据[Mbytes] 油量[7bytes]+金额[7bytes]
0x14 查总累计信息*/
    gun_info_t * p_gun = (gun_info_t *)puser;
    char *total = (char *)data + 3;
    int ret = 0;

    if(data_len < 17) {
            return -1;
    }

    p_gun->total_oil_volume = Hex2Dec64((uint8_t*)total, 7);
    p_gun->total_price = Hex2Dec64((uint8_t*)(total+7), 7);
    return ret;
}

uint16_t _crc16_get(uint8_t *_buff,uint32_t _len)
{
    uint32_t i,j;
    uint16_t crc;
    uint16_t temp;

    crc=(uint16_t)CRC_INIT_VALUE;
    for(i=0;i<_len;i++) {
        temp=_buff[i];
        temp &=0x00FF;
        crc^=temp;

        for(j=0;j<8;j++) {
            if((crc&0x0001)!=0x00) {
                crc>>=1;
                crc^=0xA001;
            } else {
                crc>>=1;
            }
        }
    }
 
    return crc;
}
/*转义*/
int _ytsf_data_code(uint8_t *buff, uint8_t *len)
{
	uint8_t buff_code[128];
	uint8_t i, tlen = 0;

	/* 帧中除了帧头为 BB 外，不再出现 BB，如果出现 BB 则转义为
BA 01；如果出现 BA 则转义为 BA 00；帧长度和校验码都按转义前
来计算。*/
	for(i = 0;i < *len; i ++){
		if(buff[i] == 0xba){
			buff_code[tlen++] = 0xba;
			buff_code[tlen++] = 0x00;
		} else if(i&&buff[i] == 0xbb){
			buff_code[tlen++] = 0xba;
			buff_code[tlen++] = 0x01;
		}
		else{
			buff_code[tlen++] = buff[i];
		}
	}
	memcpy(buff, buff_code, tlen);
	*len = tlen;
	return 0;
}
/*反转义*/
int _ytsf_data_decode(uint8_t *buff, uint8_t *len)
{
	uint8_t buff_code[128];
	uint8_t i, tlen = 0;

	/* 帧中除了帧头为 BB 外，不再出现 BB，如果出现 BB 则转义为
BA 01；如果出现 BA 则转义为 BA 00；帧长度和校验码都按转义前
来计算。*/
	for(i = 0;i < *len; i ++){
		if((buff[i] == 0xba)&&(buff[i+1] == 0x00)) {
			buff_code[tlen++] = 0xba;
			i += 1;
		} else if((buff[i] == 0xba)&&(buff[i+1] == 0x01)){
			buff_code[tlen++] = 0xbb;
			i += 1;
		}
		else{
			buff_code[tlen++] = buff[i];
		}
	}
	memcpy(buff, buff_code, tlen);
	*len = tlen;

	return 0;
}
/*没有用到*/
int ytsf_cmd_comm(uint8_t uart, uint8_t port, uint8_t cmd, uint8_t *parm, uint8_t size, rx_data_proc proc, void * puser)
{/* 帧头(1)+帧长度(1)+帧号(1)+端口号(1)+命令码(1)+参数[n]+CRC校验码[2] */
	int ret = -1;
	uint8_t rcv_buf[128], rcv_size = 0, send_buf[128], send_size, *fparm;
	uint16_t *p_crc, crc;
	tYTSFCommFrame_t *p_tax_tx = (tYTSFCommFrame_t *)send_buf;
	tYTSFCommFrame_t *p_tax_rx = (tYTSFCommFrame_t *)rcv_buf;

	memset(send_buf, 0, sizeof(send_buf));
	p_crc = (uint16_t *)&send_buf[sizeof(tYTSFCommFrame_t) + size];
	p_tax_tx->fhead = 0xbb;
	p_tax_tx->flen = 5+size;	//长度码为命令码、帧号、参数和校验码的字节数之和
	p_tax_tx->findex = 0x81; 	//帧号标识本帧的特征信息，帧号OFFH表示单帧命令;
	p_tax_tx->fport = port;
	p_tax_tx->fcmd = cmd;
	fparm = &send_buf[sizeof(tYTSFCommFrame_t)];
	memcpy(fparm, parm, size);

	//caculate crc val;
	*p_crc = _crc16_get(&p_tax_tx->fhead, p_tax_tx->flen);//校验码为帧号、命令码和参数逐字节的逻辑和	
	*p_crc = htons(*p_crc);
	send_size = p_tax_tx->flen + 2;
	_ytsf_data_code(send_buf, &send_size);	/* 编码发送 */
	
	//send and rcv;
	data_dump("ytsf send", (uint8_t *)p_tax_tx, send_size);
	uart_msg_send(uart, (char *)p_tax_tx, send_size);
	rcv_size = uart_blocking_read((char *)rcv_buf, uart, 3000);
	if(rcv_size) {
		data_dump("ytsf rcv", rcv_buf, rcv_size);
		//verify ok
		_ytsf_data_decode(rcv_buf, &rcv_size);	/* 接收解码 */	
		crc = _crc16_get(&p_tax_rx->fhead, p_tax_rx->flen);
		p_crc = (uint16_t *)&rcv_buf[p_tax_rx->flen];
		*p_crc = ntohs(*p_crc);		
		if((p_tax_rx->fhead == p_tax_tx->fhead)&&
			(p_tax_rx->fcmd == p_tax_tx->fcmd)&&
			(p_tax_rx->findex == p_tax_tx->findex)&&
			(p_tax_rx->fport == p_tax_tx->fport)&&
			(crc == *p_crc)) {	
			fparm = &rcv_buf[sizeof(tYTSFCommFrame_t)];
			if(proc) {/* process. */
				ret = proc(puser, fparm, p_tax_rx->flen-5);
			}
		}
	} 
	
	return ret;
}

static uint16_t _crc_get(uint8_t *data, uint8_t size)
{
        uint8_t i, crc = 0;

        for(i = 0;i < size;i++){
                crc ^=data[i];
        }

        return crc;
}

/*明文*/
int tax_0x83_anaylse(void *puser, uint8_t *data, uint8_t data_len)
{/* status 十 tax_ data为税务信息数据，格式和初始化数据相同，其中时间为税控加油机实时时钟的当前时间。
		总长48字节，依次为:出厂编号 (10);油枪位编号 (2);纳税人登记证号 (20);
		油品 (4);年 (4)、月 (2)、日 (2)、时 (2)和分 (2)a*/
	tax_info_t * p_tax = (tax_info_t *)puser;
	uint8_t *tax_data = data + 1;
	uint8_t i;
	int ret = 0;

	if(isdigit(tax_data[0])) {//英泰赛福
		p_tax->factory = 1;
		switch(tax_data[0]) {
			case '0':
			case '1':
				p_tax->gun_num = 1;
				break;
			case '2':
			case '3':
				p_tax->gun_num = 2;
				break;
			default:
				p_tax->gun_num = tax_data[0] - '0';
				break;
		}
	} else if(isalpha(tax_data[0])) {//拓盛
		p_tax->factory = 2;
		if((tax_data[0] >= 'A')&&(tax_data[0] <= 'Z')) {
                        p_tax->gun_num = tax_data[0] - 'A' + 1;
		} else if((tax_data[0] >= 'a')&&(tax_data[0] <= 'z')) {
                        p_tax->gun_num = tax_data[0] - 'a' + 1;
		}
	}

	for(i = 0;i < 5;i++) {
		p_tax->monitor_serino[i] = ((tax_data[2*i+0]<<4)&0xF0) | (tax_data[2*i+1]&0x0F);
	}
	
	memcpy(p_tax->taxpayer_reg_no, tax_data + 12, 20);
	memcpy(&p_tax->monitor_serino[5], tax_data, 10);

	//data_dump("0x83", data, data_len);
	return ret;
}

int tax_0x86_anaylse(void *puser, uint8_t *data, uint8_t data_len)
{/* status+ 〔当次加油数据〕当次加油数据 总长 22字节，依次为:日 (2)、时 (2)、分 (2);油量 (6);金额 (6);单价 (4)0 */
	gun_info_t * p_gun = (gun_info_t *)puser;
	char *current = (char *)data + 7;
	int ret = 0;
        char temp[3] = {0};
      //  data_dump("0x86 data :", data, data_len);
        strncpy(temp,(char*)(data+1),2);
        temp[2] = 0;
        sscanf(temp,"%02x",&p_gun->time_day);

        strncpy(temp,(char*)(data+3),2);
        temp[2] = 0;
        sscanf(temp,"%02x",&p_gun->time_hour);

        strncpy(temp,(char*)(data+5),2);
        temp[2] = 0;
        sscanf(temp,"%02x",&p_gun->time_minute);

     //   printf("%02x,%02x,%02x\r\n",p_gun->time_day,p_gun->time_hour,p_gun->time_minute);
	p_gun->last_unit_price = atoi(&current[12]);
	current[12] = 0;
	p_gun->last_price = atoi(&current[6]);
	current[6] = 0;
	p_gun->last_oil_volume = atoi(current);

	p_gun->gun_type = SINGLE_DATA;
	return ret;
}


int tax_0x89_anaylse(void *puser, uint8_t *data, uint8_t data_len)
{/* status十 [总累计加油数据] 总累计加油数据 总长 24字节，依次为:总累计油量 (12);总累计金额 (12)	*/
	gun_info_t * p_gun = (gun_info_t *)puser;
	char *total = (char *)data + 1;
	int ret = 0;
     //   char *str = "206158430207";
        p_gun->total_price = atoll(&total[12]);
      //  printf("\r\n total_princ = %lld \r\n",p_gun->total_price);
	total[12] = 0;
        p_gun->total_oil_volume = atoll(total);
	
	p_gun->gun_type = CUMULATIVE_DATA;
	return ret;
}
//字符串转十六进制数
uint32_t strtohex(char *data, uint8_t len)
{
    uint8_t i = 0;
    uint32_t p_data = 0;
    uint8_t temp;
    for(i = 0; i < len; i++)
    {
        temp = HexToChar(data[i]);
        if(temp == 0xff)
                break;
        p_data = (p_data<<4)|temp;
    }
    return p_data;
}

/*-------------------------------------------------------------------------------------
 * 接收0x8C指令的处理
 *--------------------------------------------------------------------------------------*/
uint8_t tax_rcv_analyze_0x8C(uint8_t *data,void *puser,uint8_t *len)
{
    uint8_t ret = 1;
    uint8_t *p_crc, crc, *fparm;
    char temp[3] = {0};
    tTaxCommFrame_t *p_tax_rx = NULL;
    p_tax_rx = (tTaxCommFrame_t *)data;
    if(p_tax_rx->fhead != 0xBB) return 0;
    crc = _crc_get(&p_tax_rx->findex, p_tax_rx->flen-1);
    p_crc = &data[p_tax_rx->flen + 1];
    if((p_tax_rx->fhead == 0xBB)&&(crc == *p_crc)) {
        if((p_tax_rx->findex != 0xFF)  ){ // 帧号
            if((p_tax_rx->findex&0x80) != 0x80) return ret;
        }
        if(p_tax_rx->flen<6) return ret; // 长度小于8个，为帧格式错误

        fparm = &data[sizeof(tTaxCommFrame_t)];
        switch(p_tax_rx->fcmd)
        {
        case 0x8C:
            data_dump("rcv_0x8C",data,p_tax_rx->flen+2);
            memcpy(puser,data,p_tax_rx->flen+2);
            *len = p_tax_rx->flen + 2;
            ret = data[4];
            if(data[6] == 0x01){ // 数据结果是对的
                if(ret == 0x11) { // 当前交易明细

                    strncpy((char*)temp,(char*)data+9,2);
                    temp[2] = 0;
                    g_tax8Cda.timer86  = strtohex(temp,2);
                    g_tax8Cda.timer86 = (g_tax8Cda.timer86<<8);
                    strncpy((char*)temp,(char*)data+11,2);
                    temp[2] = 0;
                    g_tax8Cda.timer86 |= (strtohex(temp,2)&0x00FF);
                    g_tax8Cda.crc86 = data[p_tax_rx->flen + 1];
                }
                else if(ret == 0x14){ // 总累计
                    g_tax8Cda.crc89 = data[p_tax_rx->flen + 1];
                }
            }
            else { // 数据结果是错误的
                //ret = 0;
                if(ret == 0x11){
                    g_tax8Cda.timer86 |= data[6];
                    g_tax8Cda.crc86 = data[p_tax_rx->flen + 1];
                }
                else if(ret == 0x14){

                    g_tax8Cda.timer86 = data[6];
                    g_tax8Cda.timer86 = (g_tax8Cda.timer86<<8);
                    g_tax8Cda.crc89 = data[p_tax_rx->flen + 1];
                }
                ret = data[4]|0x80;

                return ret;
            }

            break;
        case 0x83:
            tax_0x83_anaylse(puser,fparm,p_tax_rx->flen-3);
            ret = 0x83;
            return ret;
//            break;
        case 0x70:
           data_dump("rcv_0x70",data,p_tax_rx->flen+2);
           printf(" data_result : %d\n",data[4]);
           if(data[4] == 0x01) {
               tax_0x70_anaylse(puser,fparm,p_tax_rx->flen-3);
               ret = 0x70;

           }
           else ret = 0x70 | 0x80;

           return ret;
//           break;
        }
    }
    else {
        ret = 0;
        printf("crc _error \r\n");
    }
    return ret;
}
