#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>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>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(¤t[12]); current[12] = 0; p_gun->last_price = atoi(¤t[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; }