tax_ctrl.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. #include "includes.h"
  2. #include "device.h"
  3. #include "tax_ctrl.h"
  4. #include "net_proc.h"
  5. #include "uart.h"
  6. #include "des.h"
  7. #include "BSP.h"
  8. #include "net_ctrl.h"
  9. int rs485_send_flag = 0;
  10. #define CRC_INIT_VALUE 0x0000
  11. rcv_data_0x8C_t g_tax8Cda;
  12. /*密文*/
  13. int ytsf_0xa2_0x00_anaylse(void *puser, uint8_t *data, uint8_t data_len)
  14. {/* 信息类型[1byte] + 枪号[1byte] + 读取结果[1byte] +
  15. 读取数据[Mbytes] 监 控 序 列 号 (BCD码)[5bytes]+序列号(ASCII 码)[10bytes] */
  16. tax_info_t * p_tax = (tax_info_t *)puser;
  17. uint8_t tax_data = *(data + 8);
  18. int ret = 0;
  19. p_tax->gun_num = 1;
  20. if(isdigit(tax_data)) {//英泰赛福
  21. p_tax->factory = 1;
  22. switch(tax_data) {
  23. case '0':
  24. case '1':
  25. p_tax->gun_num = 1;
  26. break;
  27. case '2':
  28. case '3':
  29. p_tax->gun_num = 2;
  30. break;
  31. default:
  32. p_tax->gun_num = tax_data - '0';
  33. break;
  34. }
  35. } else if(isalpha(tax_data)) {//拓盛
  36. p_tax->factory = 2;
  37. if((tax_data >= 'A')&&(tax_data <= 'Z')) {
  38. p_tax->gun_num = tax_data - 'A' + 1;
  39. } else if((tax_data >= 'a')&&(tax_data <= 'z')) {
  40. p_tax->gun_num = tax_data - 'a' + 1;
  41. }
  42. }
  43. memcpy(p_tax->monitor_serino, data + 3, 15);
  44. data_dump("monitor_serino", p_tax->monitor_serino, 16);
  45. return ret;
  46. }
  47. int tax_0x70_anaylse(void *puser, uint8_t *data, uint8_t data_len)
  48. {
  49. tax_info_t * p_tax = (tax_info_t *)puser;
  50. if(data_len > 20)
  51. {
  52. if(isdigit(data[1])) {// 数字为英泰
  53. p_tax->factory = 1;
  54. switch(data[1]) {
  55. case '0':
  56. case '1':
  57. p_tax->gun_num = 1;
  58. break;
  59. case '2':
  60. case '3':
  61. p_tax->gun_num = 2;
  62. break;
  63. default:
  64. p_tax->gun_num = data[1] - '0';
  65. break;
  66. }
  67. } else if(isalpha(data[1])) {//字母 为排成
  68. p_tax->factory = 2;
  69. if((data[1] >= 'A')&&(data[1] <= 'Z')) {
  70. p_tax->gun_num = data[1] - 'A' + 1;
  71. } else if((data[1] >= 'a')&&(data[1] <= 'z')) {
  72. p_tax->gun_num = data[1] - 'a' + 1;
  73. }
  74. }
  75. memcpy(&p_tax->monitor_serino[5],data+1,10);
  76. //memcpy(p_tax->bmq_serino,data+11,10);
  77. //data_dump("tax_serino",p_tax->tax_serino,10);
  78. }
  79. return 0;
  80. }
  81. /**
  82. * @brief hex convert ascii
  83. * @par param[in] *ascii:ascii data
  84. * @par param[in] *hex:hex data
  85. * @par param[in] hexLen:length of hex
  86. * @retval length
  87. */
  88. uint32_t Hex2Dec(uint8_t *hex, uint16_t hexLen)
  89. {
  90. uint32_t data = 0;
  91. uint8_t i;
  92. for(i=0;i<hexLen;i++) {
  93. data = data * 100;
  94. data += (hex[i]>>4)*10 + (hex[i]&0x0F);
  95. }
  96. return data;
  97. }
  98. uint64_t Hex2Dec64(uint8_t *hex, uint16_t hexLen)
  99. {
  100. uint64_t data = 0;
  101. uint8_t i;
  102. for(i=0;i<hexLen;i++) {
  103. data = data * 100;
  104. data += (hex[i]>>4)*10 + (hex[i]&0x0F);
  105. }
  106. return data;
  107. }
  108. int ytsf_0xa1_0x11_anaylse(void *puser, uint8_t *data, uint8_t data_len)
  109. {/* 累计类型[1byte] + 枪号[1byte] + 读取结果[1byte] +
  110. 读取数据[Mbytes] 时间[3bytes]+油量[5bytes]+金额[5bytes]+单价[3bytes]
  111. 0x11 查当次加油信息*/
  112. gun_info_t * p_gun = (gun_info_t *)puser;
  113. uint8_t *current = (uint8_t *)data + 6;
  114. int ret = 0;
  115. if(data_len < 19) {
  116. return -1;
  117. }
  118. // data_dump("0x86 data :", data, data_len);
  119. p_gun->time_day = *(data+3);
  120. p_gun->time_hour = *(data+4);
  121. p_gun->time_minute = *(data+5);
  122. // printf("%02x,%02x,%02x\r\n",p_gun->time_day,p_gun->time_hour,p_gun->time_minute);
  123. p_gun->last_oil_volume = Hex2Dec(current, 5);
  124. p_gun->last_price = Hex2Dec(current + 5, 5);
  125. p_gun->last_unit_price = Hex2Dec(current + 10, 3);
  126. return ret;
  127. }
  128. int ytsf_0xa1_0x14_anaylse(void *puser, uint8_t *data, uint8_t data_len)
  129. {/* 累计类型[1byte] + 枪号[1byte] + 读取结果[1byte] +
  130. 读取数据[Mbytes] 油量[7bytes]+金额[7bytes]
  131. 0x14 查总累计信息*/
  132. gun_info_t * p_gun = (gun_info_t *)puser;
  133. char *total = (char *)data + 3;
  134. int ret = 0;
  135. if(data_len < 17) {
  136. return -1;
  137. }
  138. p_gun->total_oil_volume = Hex2Dec64((uint8_t*)total, 7);
  139. p_gun->total_price = Hex2Dec64((uint8_t*)(total+7), 7);
  140. return ret;
  141. }
  142. uint16_t _crc16_get(uint8_t *_buff,uint32_t _len)
  143. {
  144. uint32_t i,j;
  145. uint16_t crc;
  146. uint16_t temp;
  147. crc=(uint16_t)CRC_INIT_VALUE;
  148. for(i=0;i<_len;i++) {
  149. temp=_buff[i];
  150. temp &=0x00FF;
  151. crc^=temp;
  152. for(j=0;j<8;j++) {
  153. if((crc&0x0001)!=0x00) {
  154. crc>>=1;
  155. crc^=0xA001;
  156. } else {
  157. crc>>=1;
  158. }
  159. }
  160. }
  161. return crc;
  162. }
  163. /*转义*/
  164. int _ytsf_data_code(uint8_t *buff, uint8_t *len)
  165. {
  166. uint8_t buff_code[128];
  167. uint8_t i, tlen = 0;
  168. /* 帧中除了帧头为 BB 外,不再出现 BB,如果出现 BB 则转义为
  169. BA 01;如果出现 BA 则转义为 BA 00;帧长度和校验码都按转义前
  170. 来计算。*/
  171. for(i = 0;i < *len; i ++){
  172. if(buff[i] == 0xba){
  173. buff_code[tlen++] = 0xba;
  174. buff_code[tlen++] = 0x00;
  175. } else if(i&&buff[i] == 0xbb){
  176. buff_code[tlen++] = 0xba;
  177. buff_code[tlen++] = 0x01;
  178. }
  179. else{
  180. buff_code[tlen++] = buff[i];
  181. }
  182. }
  183. memcpy(buff, buff_code, tlen);
  184. *len = tlen;
  185. return 0;
  186. }
  187. /*反转义*/
  188. int _ytsf_data_decode(uint8_t *buff, uint8_t *len)
  189. {
  190. uint8_t buff_code[128];
  191. uint8_t i, tlen = 0;
  192. /* 帧中除了帧头为 BB 外,不再出现 BB,如果出现 BB 则转义为
  193. BA 01;如果出现 BA 则转义为 BA 00;帧长度和校验码都按转义前
  194. 来计算。*/
  195. for(i = 0;i < *len; i ++){
  196. if((buff[i] == 0xba)&&(buff[i+1] == 0x00)) {
  197. buff_code[tlen++] = 0xba;
  198. i += 1;
  199. } else if((buff[i] == 0xba)&&(buff[i+1] == 0x01)){
  200. buff_code[tlen++] = 0xbb;
  201. i += 1;
  202. }
  203. else{
  204. buff_code[tlen++] = buff[i];
  205. }
  206. }
  207. memcpy(buff, buff_code, tlen);
  208. *len = tlen;
  209. return 0;
  210. }
  211. /*没有用到*/
  212. 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)
  213. {/* 帧头(1)+帧长度(1)+帧号(1)+端口号(1)+命令码(1)+参数[n]+CRC校验码[2] */
  214. int ret = -1;
  215. uint8_t rcv_buf[128], rcv_size = 0, send_buf[128], send_size, *fparm;
  216. uint16_t *p_crc, crc;
  217. tYTSFCommFrame_t *p_tax_tx = (tYTSFCommFrame_t *)send_buf;
  218. tYTSFCommFrame_t *p_tax_rx = (tYTSFCommFrame_t *)rcv_buf;
  219. memset(send_buf, 0, sizeof(send_buf));
  220. p_crc = (uint16_t *)&send_buf[sizeof(tYTSFCommFrame_t) + size];
  221. p_tax_tx->fhead = 0xbb;
  222. p_tax_tx->flen = 5+size; //长度码为命令码、帧号、参数和校验码的字节数之和
  223. p_tax_tx->findex = 0x81; //帧号标识本帧的特征信息,帧号OFFH表示单帧命令;
  224. p_tax_tx->fport = port;
  225. p_tax_tx->fcmd = cmd;
  226. fparm = &send_buf[sizeof(tYTSFCommFrame_t)];
  227. memcpy(fparm, parm, size);
  228. //caculate crc val;
  229. *p_crc = _crc16_get(&p_tax_tx->fhead, p_tax_tx->flen);//校验码为帧号、命令码和参数逐字节的逻辑和
  230. *p_crc = htons(*p_crc);
  231. send_size = p_tax_tx->flen + 2;
  232. _ytsf_data_code(send_buf, &send_size); /* 编码发送 */
  233. //send and rcv;
  234. data_dump("ytsf send", (uint8_t *)p_tax_tx, send_size);
  235. uart_msg_send(uart, (char *)p_tax_tx, send_size);
  236. rcv_size = uart_blocking_read((char *)rcv_buf, uart, 3000);
  237. if(rcv_size) {
  238. data_dump("ytsf rcv", rcv_buf, rcv_size);
  239. //verify ok
  240. _ytsf_data_decode(rcv_buf, &rcv_size); /* 接收解码 */
  241. crc = _crc16_get(&p_tax_rx->fhead, p_tax_rx->flen);
  242. p_crc = (uint16_t *)&rcv_buf[p_tax_rx->flen];
  243. *p_crc = ntohs(*p_crc);
  244. if((p_tax_rx->fhead == p_tax_tx->fhead)&&
  245. (p_tax_rx->fcmd == p_tax_tx->fcmd)&&
  246. (p_tax_rx->findex == p_tax_tx->findex)&&
  247. (p_tax_rx->fport == p_tax_tx->fport)&&
  248. (crc == *p_crc)) {
  249. fparm = &rcv_buf[sizeof(tYTSFCommFrame_t)];
  250. if(proc) {/* process. */
  251. ret = proc(puser, fparm, p_tax_rx->flen-5);
  252. }
  253. }
  254. }
  255. return ret;
  256. }
  257. static uint16_t _crc_get(uint8_t *data, uint8_t size)
  258. {
  259. uint8_t i, crc = 0;
  260. for(i = 0;i < size;i++){
  261. crc ^=data[i];
  262. }
  263. return crc;
  264. }
  265. /*明文*/
  266. int tax_0x83_anaylse(void *puser, uint8_t *data, uint8_t data_len)
  267. {/* status 十 tax_ data为税务信息数据,格式和初始化数据相同,其中时间为税控加油机实时时钟的当前时间。
  268. 总长48字节,依次为:出厂编号 (10);油枪位编号 (2);纳税人登记证号 (20);
  269. 油品 (4);年 (4)、月 (2)、日 (2)、时 (2)和分 (2)a*/
  270. tax_info_t * p_tax = (tax_info_t *)puser;
  271. uint8_t *tax_data = data + 1;
  272. uint8_t i;
  273. int ret = 0;
  274. if(isdigit(tax_data[0])) {//英泰赛福
  275. p_tax->factory = 1;
  276. switch(tax_data[0]) {
  277. case '0':
  278. case '1':
  279. p_tax->gun_num = 1;
  280. break;
  281. case '2':
  282. case '3':
  283. p_tax->gun_num = 2;
  284. break;
  285. default:
  286. p_tax->gun_num = tax_data[0] - '0';
  287. break;
  288. }
  289. } else if(isalpha(tax_data[0])) {//拓盛
  290. p_tax->factory = 2;
  291. if((tax_data[0] >= 'A')&&(tax_data[0] <= 'Z')) {
  292. p_tax->gun_num = tax_data[0] - 'A' + 1;
  293. } else if((tax_data[0] >= 'a')&&(tax_data[0] <= 'z')) {
  294. p_tax->gun_num = tax_data[0] - 'a' + 1;
  295. }
  296. }
  297. for(i = 0;i < 5;i++) {
  298. p_tax->monitor_serino[i] = ((tax_data[2*i+0]<<4)&0xF0) | (tax_data[2*i+1]&0x0F);
  299. }
  300. memcpy(p_tax->taxpayer_reg_no, tax_data + 12, 20);
  301. memcpy(&p_tax->monitor_serino[5], tax_data, 10);
  302. //data_dump("0x83", data, data_len);
  303. return ret;
  304. }
  305. int tax_0x86_anaylse(void *puser, uint8_t *data, uint8_t data_len)
  306. {/* status+ 〔当次加油数据〕当次加油数据 总长 22字节,依次为:日 (2)、时 (2)、分 (2);油量 (6);金额 (6);单价 (4)0 */
  307. gun_info_t * p_gun = (gun_info_t *)puser;
  308. char *current = (char *)data + 7;
  309. int ret = 0;
  310. char temp[3] = {0};
  311. // data_dump("0x86 data :", data, data_len);
  312. strncpy(temp,(char*)(data+1),2);
  313. temp[2] = 0;
  314. sscanf(temp,"%02x",&p_gun->time_day);
  315. strncpy(temp,(char*)(data+3),2);
  316. temp[2] = 0;
  317. sscanf(temp,"%02x",&p_gun->time_hour);
  318. strncpy(temp,(char*)(data+5),2);
  319. temp[2] = 0;
  320. sscanf(temp,"%02x",&p_gun->time_minute);
  321. // printf("%02x,%02x,%02x\r\n",p_gun->time_day,p_gun->time_hour,p_gun->time_minute);
  322. p_gun->last_unit_price = atoi(&current[12]);
  323. current[12] = 0;
  324. p_gun->last_price = atoi(&current[6]);
  325. current[6] = 0;
  326. p_gun->last_oil_volume = atoi(current);
  327. p_gun->gun_type = SINGLE_DATA;
  328. return ret;
  329. }
  330. int tax_0x89_anaylse(void *puser, uint8_t *data, uint8_t data_len)
  331. {/* status十 [总累计加油数据] 总累计加油数据 总长 24字节,依次为:总累计油量 (12);总累计金额 (12) */
  332. gun_info_t * p_gun = (gun_info_t *)puser;
  333. char *total = (char *)data + 1;
  334. int ret = 0;
  335. // char *str = "206158430207";
  336. p_gun->total_price = atoll(&total[12]);
  337. // printf("\r\n total_princ = %lld \r\n",p_gun->total_price);
  338. total[12] = 0;
  339. p_gun->total_oil_volume = atoll(total);
  340. p_gun->gun_type = CUMULATIVE_DATA;
  341. return ret;
  342. }
  343. //字符串转十六进制数
  344. uint32_t strtohex(char *data, uint8_t len)
  345. {
  346. uint8_t i = 0;
  347. uint32_t p_data = 0;
  348. uint8_t temp;
  349. for(i = 0; i < len; i++)
  350. {
  351. temp = HexToChar(data[i]);
  352. if(temp == 0xff)
  353. break;
  354. p_data = (p_data<<4)|temp;
  355. }
  356. return p_data;
  357. }
  358. /*-------------------------------------------------------------------------------------
  359. * 接收0x8C指令的处理
  360. *--------------------------------------------------------------------------------------*/
  361. uint8_t tax_rcv_analyze_0x8C(uint8_t *data,void *puser,uint8_t *len)
  362. {
  363. uint8_t ret = 1;
  364. uint8_t *p_crc, crc, *fparm;
  365. char temp[3] = {0};
  366. tTaxCommFrame_t *p_tax_rx = NULL;
  367. p_tax_rx = (tTaxCommFrame_t *)data;
  368. if(p_tax_rx->fhead != 0xBB) return 0;
  369. crc = _crc_get(&p_tax_rx->findex, p_tax_rx->flen-1);
  370. p_crc = &data[p_tax_rx->flen + 1];
  371. if((p_tax_rx->fhead == 0xBB)&&(crc == *p_crc)) {
  372. if((p_tax_rx->findex != 0xFF) ){ // 帧号
  373. if((p_tax_rx->findex&0x80) != 0x80) return ret;
  374. }
  375. if(p_tax_rx->flen<6) return ret; // 长度小于8个,为帧格式错误
  376. fparm = &data[sizeof(tTaxCommFrame_t)];
  377. switch(p_tax_rx->fcmd)
  378. {
  379. case 0x8C:
  380. data_dump("rcv_0x8C",data,p_tax_rx->flen+2);
  381. memcpy(puser,data,p_tax_rx->flen+2);
  382. *len = p_tax_rx->flen + 2;
  383. ret = data[4];
  384. if(data[6] == 0x01){ // 数据结果是对的
  385. if(ret == 0x11) { // 当前交易明细
  386. strncpy((char*)temp,(char*)data+9,2);
  387. temp[2] = 0;
  388. g_tax8Cda.timer86 = strtohex(temp,2);
  389. g_tax8Cda.timer86 = (g_tax8Cda.timer86<<8);
  390. strncpy((char*)temp,(char*)data+11,2);
  391. temp[2] = 0;
  392. g_tax8Cda.timer86 |= (strtohex(temp,2)&0x00FF);
  393. g_tax8Cda.crc86 = data[p_tax_rx->flen + 1];
  394. }
  395. else if(ret == 0x14){ // 总累计
  396. g_tax8Cda.crc89 = data[p_tax_rx->flen + 1];
  397. }
  398. }
  399. else { // 数据结果是错误的
  400. //ret = 0;
  401. if(ret == 0x11){
  402. g_tax8Cda.timer86 |= data[6];
  403. g_tax8Cda.crc86 = data[p_tax_rx->flen + 1];
  404. }
  405. else if(ret == 0x14){
  406. g_tax8Cda.timer86 = data[6];
  407. g_tax8Cda.timer86 = (g_tax8Cda.timer86<<8);
  408. g_tax8Cda.crc89 = data[p_tax_rx->flen + 1];
  409. }
  410. ret = data[4]|0x80;
  411. return ret;
  412. }
  413. break;
  414. case 0x83:
  415. tax_0x83_anaylse(puser,fparm,p_tax_rx->flen-3);
  416. ret = 0x83;
  417. return ret;
  418. // break;
  419. case 0x70:
  420. data_dump("rcv_0x70",data,p_tax_rx->flen+2);
  421. printf(" data_result : %d\n",data[4]);
  422. if(data[4] == 0x01) {
  423. tax_0x70_anaylse(puser,fparm,p_tax_rx->flen-3);
  424. ret = 0x70;
  425. }
  426. else ret = 0x70 | 0x80;
  427. return ret;
  428. // break;
  429. }
  430. }
  431. else {
  432. ret = 0;
  433. printf("crc _error \r\n");
  434. }
  435. return ret;
  436. }