COAPHandle.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959
  1. #define BC26 //定义引入得通讯模块 BC26 | ESP8266
  2. #include "coap.h"
  3. #include <string.h>
  4. #include "mbedtls_util.h"
  5. #include "COAPHandle.h"
  6. #include "module_wrapper.h"
  7. #include "TypeDefine.h"
  8. #include "SystemAlarm.h"
  9. #include "sys.h"
  10. #include "crc.h"
  11. #include "DrawLCDGUI.h"
  12. #include "ProgramData.h"
  13. #include "Driver.h"
  14. #include "cJSON.h"
  15. #include "ControlSystem.h"
  16. #ifdef BC26
  17. #include "bc26.h"
  18. #elif defined(ESP8266)
  19. #include "esp8266.h"
  20. #endif
  21. void endpoint_setup(void)
  22. {
  23. }
  24. coap_endpoint_t endpoints[1]= {0};
  25. #define BUF_SIZE 1024
  26. static uint8_t buf[BUF_SIZE];
  27. extern uint8 tcp_connect_status;
  28. extern valid_data_t valid_data;
  29. extern uint8_t TurnOffACKTone;
  30. static char iv[17] = "543yhjy97ae7fyfg";
  31. static const char *coap_con_path="auth";
  32. static const uint8_t coap_content_json = COAP_CONTENTTYPE_APPLICATION_JSON;
  33. static char* sign_format = "clientId%s.%sdeviceName%sproductKey%sseq%d";
  34. static char* payload_format="{\"clientId\":\"%s.%s\",\"signmethod\":\"%s\",\"sign\":\"%s\",\"productKey\":\"%s\",\"deviceName\":\"%s\",\"seq\":%d}";
  35. int module_check_status; //模块检测
  36. static auth_token_t auth_token =
  37. {
  38. .flag = AUTH_FAILURE,
  39. };
  40. static uint16_t coap_auth_id = AUTH_MID;
  41. coap_packet_t coap_send_pkt = //coap发送包
  42. {
  43. .hdr.ver=0x01,
  44. .hdr.t=COAP_TYPE_CON,
  45. .hdr.tkl=0,
  46. .hdr.code=COAP_METHOD_POST,
  47. .numopts=0,
  48. };
  49. coap_packet_t coap_rec_pkt = {0}; //coap接受包
  50. #define PAYLOAD_DATA_LEN 48 //数据包
  51. uint8_t PumpType_Normal=0;
  52. static uint8_t pumpData[PAYLOAD_DATA_LEN]; //包数据
  53. extern uint8_t StartToRun_flag; //当按下运行按键的时候,置位该标志
  54. extern char mqtt_publish_topic[100]; //发布主题
  55. extern uint8_t Alarm_flag; //报警状态
  56. extern uint8_t Start_send ; //开始发送标志,0:发送
  57. extern uint16_t send_cont; //数据发送次数
  58. static uint16_t send_num = 0; //发送数据数量
  59. static uint16_t send_suc_num = 0;//发送成功数据数量
  60. uint16_t send_fall_num = 0; //发送失败数据数量
  61. static uint8_t repeat_send_count = 0;//重发次数
  62. static uint16_t pre_send_num = 0;
  63. uint8_t repeat_send_switch = 0; //0关闭重发,1开启重发
  64. static int firstSendFlag = 1;
  65. static int moduleInitCou = 0; //模块连续初始化次数
  66. static uint8_t pumpState = 0; //运行状态标志
  67. static uint16_t pumpAlarm = 0; //报警标志
  68. static uint8_t pumpPreAlarm = 0; //预报标志
  69. static uint8_t pumpStateLast = 0; //上次运行状态标志
  70. static uint16_t pumpAlarmLast = 0; //上次报警标志
  71. static uint8_t pumpPreAlarmLast = 0; //上次预报标志
  72. static uint8_t signData[4]={0};
  73. static void setValue(uint8_t **p,void* data,int len)
  74. {
  75. memcpy(*p,data,len);
  76. *p+=len;
  77. }
  78. static void generateCoapKey(void)
  79. {
  80. int i = 0;
  81. char out[80]={0};
  82. char sign_content[100]={0};
  83. if(auth_token.flag == AUTH_SUCCESS)
  84. {
  85. snprintf(sign_content, sizeof(sign_content), "%s,%s",registInfo->deviceSecret,auth_token.random);
  86. utils_sha256(sign_content, strlen(sign_content), out);
  87. memset(auth_token.key,0,sizeof(auth_token.key));
  88. memcpy(auth_token.key,out+8,16); //获取key
  89. }
  90. }
  91. /**
  92. * @Title 封装数据并通过mqtt发送
  93. */
  94. static void packPumbDataCoapSend(void)
  95. {
  96. int i = 0;
  97. //if(mqtt_status.ping_status != MQTT_SUCCESS) return; //外调该接口时,做网络判断
  98. if(send_num < 0 )
  99. {
  100. send_num = 0;
  101. }
  102. send_num++;
  103. send_fall_num=send_num-send_suc_num;
  104. send_cont = send_num;
  105. uint8_t *ptr =pumpData;
  106. if(EngineeringModeValue.test == 1)
  107. {
  108. PumpType_Normal=0x15;
  109. }
  110. else
  111. {
  112. PumpType_Normal=0x16;
  113. }
  114. unsigned short crc = 0;
  115. if(tcp_connect_status != TCP_OPEN)
  116. {
  117. return;
  118. }
  119. memset(pumpData,0,sizeof(pumpData));
  120. *ptr++ = 0xEF; //[0] 固定值
  121. *ptr++ = PAYLOAD_DATA_LEN-2; //[1]数据长度
  122. *ptr++ = PumpType_Normal; //[2]泵类型,网络泵
  123. setValue(&ptr,classification,4);//[3-6]分类标识
  124. setValue(&ptr,&send_num,sizeof(send_num));//[7-8]数据编号
  125. *ptr++=8; //[9]住院号长度
  126. setValue(&ptr,&verifyInfo.hospitalNO,8); //[10-17]住院号
  127. setValue(&ptr,&verifyInfo.sickroom,2); //[18-19]病区
  128. setValue(&ptr,&verifyInfo.bedNO,2); //[20-21]床号
  129. setValue(&ptr,&setParamInfo.totalDose,2); //[22-23]总量
  130. setValue(&ptr,&setParamInfo.limitDose1,2); //[24-25]极限零
  131. setValue(&ptr,&setParamInfo.superaddition1,2); //[26-27] 追加量
  132. setValue(&ptr,&setParamInfo.lockTime1,2); //[28-29] 锁时时间
  133. setValue(&ptr,&setParamInfo.continueDose1,2); //[30,31]持续量
  134. setValue(&ptr,&realTimeData.inputDose,2); //[32-33]已输入量
  135. *ptr++ = (uint8_t)(setParamInfo.firstDose & 0x00ff); //[34]首次量
  136. *ptr++ = (uint8_t)( realTimeData.validCount & 0x00ff ); //[35]有效次数
  137. *ptr++ = (uint8_t)( realTimeData.invalidCount & 0x00ff );//[36]无效次数
  138. if( realTimeData.batteryVolt > 100 )//[37]电池电量,发送电量百分比
  139. {
  140. *ptr++ = 100;
  141. }
  142. else
  143. {
  144. *ptr++ = realTimeData.batteryVolt;
  145. }
  146. switch( realTimeData.stateRun ) //[38]泵运行状态
  147. {
  148. case FirstRun:
  149. case MainRun:
  150. case Airout:
  151. case PCARun:
  152. pumpData[38] = 0x02;//运行状态 0000 0010
  153. break;
  154. case Pause:
  155. pumpData[38] = 0x04;//暂停状态 0000 0100
  156. break;
  157. case Poweroff:
  158. pumpData[38] = 0x00;//关机状态 0000 0000
  159. break;
  160. case Poweron:
  161. pumpData[38] = 0x01;//开机状态 0000 0001
  162. break;
  163. default:
  164. pumpData[38] = 0x08;//待机状态 0000 1000,
  165. break;
  166. }
  167. ptr++;
  168. if( sysAlarmFlag.BubbleFault == ALARM_ON )
  169. {
  170. pumpData[39] |= 0x01;//气泡或无液故障 0000 0001
  171. }
  172. if( sysAlarmFlag.JamFault == ALARM_ON )
  173. {
  174. pumpData[39] |= 0x02;//堵塞故障 0000 0010
  175. }
  176. if( sysAlarmFlag.InputTotal == ALARM_ON )
  177. {
  178. pumpData[39] |= 0x04;//输入总量报警 0000 0100
  179. }
  180. if( sysAlarmFlag.MaxFault == ALARM_ON )
  181. {
  182. pumpData[39] |= 0x08;//极限量报警 0000 1000
  183. }
  184. if( sysAlarmFlag.VoltLowest == ALARM_ON )//电量耗尽
  185. {
  186. pumpData[39] |= 0x10;// 0001 0000
  187. }
  188. if( sysAlarmFlag.InputEnd == ALARM_ON )//输液结束
  189. {
  190. pumpData[39] |= 0x20;// 0010 0000
  191. }
  192. if( sysAlarmFlag.MotorFalt == ALARM_ON )//电机失控
  193. {
  194. pumpData[39] |= 0x40;// 0100 0000
  195. }
  196. if( (sysAlarmFlag.MechanicalFault == ALARM_ON ) || ( sysAlarmFlag.MechanicalFault == ALARM_CONTINUE ) )//机械故障
  197. {
  198. pumpData[39] |= 0x80;// 1000 0010;
  199. }
  200. ptr++;
  201. if( sysAlarmFlag.NonePillCase == ALARM_ON )
  202. {
  203. pumpData[40] |= 0x01;//未装药盒报警 0000 0001
  204. }
  205. ptr++;
  206. if( sysAlarmFlag.InputEnding == ALARM_ON )
  207. {
  208. pumpData[41] |= 0x01;//输液将要结束 0000 0001
  209. }
  210. if( sysAlarmFlag.Zhentongxiaoguo == ALARM_ON )
  211. {
  212. pumpData[41] |= 0x02;//阵痛不足预报 0000 0010
  213. }
  214. if( sysAlarmFlag.VoltLowest == ALARM_PREPARE )
  215. {
  216. pumpData[41] |= 0x04;//电量偏低预报 0000 0100
  217. }
  218. ptr++;
  219. setValue(&ptr,&signData,4); //[18-19]病区
  220. crc = CRC16_CCITT((unsigned char*)pumpData, sizeof(pumpData)-2);
  221. setValue(&ptr,&crc,2); //[42-43]CRC
  222. UsartPrintf(USART_DEBUG,"发布数据包:%d\r\n",sizeof(pumpData));
  223. for(i = 0;i<sizeof(pumpData);i++)
  224. {
  225. UsartPrintf(USART_DEBUG,"%02x",pumpData[i]);
  226. }
  227. UsartPrintf(USART_DEBUG,"\r\n");
  228. CoapPublish(pumpData,sizeof(pumpData));
  229. }
  230. //将泵状态报警信息封装在一起
  231. static void IntePumpStateCoap()
  232. {
  233. switch( realTimeData.stateRun ) //[38]泵运行状态
  234. {
  235. case FirstRun:
  236. case MainRun:
  237. case Airout:
  238. case PCARun:
  239. pumpState = 0x02;//运行状态 0000 0010
  240. break;
  241. case Pause:
  242. pumpState = 0x04;//暂停状态 0000 0100
  243. break;
  244. case Poweroff:
  245. pumpState = 0x00;//关机状态 0000 0000
  246. break;
  247. case Poweron:
  248. pumpState = 0x01;//开机状态 0000 0001
  249. break;
  250. default:
  251. pumpState = 0x08;//待机状态 0000 1000,
  252. break;
  253. }
  254. if( sysAlarmFlag.BubbleFault == ALARM_ON )
  255. {
  256. pumpAlarm |= 0x0001;//气泡或无液故障 0000 0001
  257. }
  258. if( sysAlarmFlag.JamFault == ALARM_ON )
  259. {
  260. pumpAlarm |= 0x0002;//堵塞故障 0000 0010
  261. }
  262. if( sysAlarmFlag.InputTotal == ALARM_ON )
  263. {
  264. pumpAlarm |= 0x0004;//输入总量报警 0000 0100
  265. }
  266. if( sysAlarmFlag.MaxFault == ALARM_ON )
  267. {
  268. pumpAlarm |= 0x0008;//极限量报警 0000 1000
  269. }
  270. if( sysAlarmFlag.VoltLowest == ALARM_ON )//电量耗尽
  271. {
  272. pumpAlarm |= 0x0010;// 0001 0000
  273. }
  274. if( sysAlarmFlag.InputEnd == ALARM_ON )//输液结束
  275. {
  276. pumpAlarm |= 0x0020;// 0010 0000
  277. }
  278. if( sysAlarmFlag.MotorFalt == ALARM_ON )//电机失控
  279. {
  280. pumpAlarm |= 0x0040;// 0100 0000
  281. }
  282. if( (sysAlarmFlag.MechanicalFault == ALARM_ON ) || ( sysAlarmFlag.MechanicalFault == ALARM_CONTINUE ) )//机械故障
  283. {
  284. pumpAlarm |= 0x0080;// 1000 0010;
  285. }
  286. if( sysAlarmFlag.NonePillCase == ALARM_ON )
  287. {
  288. pumpAlarm |= 0x0100;//未装药盒报警 0000 0001
  289. }
  290. if( sysAlarmFlag.InputEnding == ALARM_ON )
  291. {
  292. pumpPreAlarm |= 0x01;//输液将要结束 0000 0001
  293. }
  294. if( sysAlarmFlag.Zhentongxiaoguo == ALARM_ON )
  295. {
  296. pumpPreAlarm |= 0x02;//阵痛不足预报 0000 0010
  297. }
  298. if( sysAlarmFlag.VoltLowest == ALARM_PREPARE )
  299. {
  300. pumpPreAlarm |= 0x04;//电量偏低预报 0000 0100
  301. }
  302. }
  303. static void DecideSendFlagCoap()
  304. {
  305. static int addition_active=0;// 报警发送激活
  306. static int first_dose_active = 0;// 首次量结束发送激活
  307. //开始
  308. if(firstSendFlag ==1 && StartToRun_flag == 1)
  309. {
  310. firstSendFlag = 0;
  311. TaskSchedulerFlag.MqttSendFlag = TASK_FLAG_SET;
  312. //UsartPrintf(USART_DEBUG, "====firstSendFlag=====\r\n");
  313. }else if(StartToRun_flag == 0)
  314. {
  315. firstSendFlag = 1;
  316. }
  317. //泵状态发生改变
  318. if(pumpState != pumpStateLast || pumpAlarm != pumpAlarmLast || pumpPreAlarm != pumpPreAlarmLast)
  319. {
  320. // UsartPrintf(USART_DEBUG, "====state change:%d,%d,%d,%d,%d,%d\r\n",pumpState,pumpStateLast,pumpAlarm,pumpAlarmLast,pumpPreAlarm,pumpPreAlarmLast);
  321. pumpStateLast = pumpState;
  322. pumpAlarmLast = pumpAlarm;
  323. pumpPreAlarmLast = pumpPreAlarm;
  324. TaskSchedulerFlag.MqttSendFlag = TASK_FLAG_SET;
  325. }
  326. //首次量结束发送数据
  327. if(realTimeData.firstDose == 0)
  328. {
  329. if(first_dose_active == 1)
  330. {
  331. first_dose_active = 0;
  332. TaskSchedulerFlag.MqttSendFlag = TASK_FLAG_SET;
  333. //UsartPrintf(USART_DEBUG, "====firstDose=====\r\n");
  334. }
  335. }
  336. else if(realTimeData.firstDose > 0)
  337. {
  338. first_dose_active = 1;
  339. }
  340. //追加量结束发送数据
  341. if(realTimeData.superaddition == 0)
  342. {
  343. if(addition_active == 1)
  344. {
  345. addition_active = 0;
  346. TaskSchedulerFlag.MqttSendFlag = TASK_FLAG_SET;
  347. //UsartPrintf(USART_DEBUG, "====superaddition====\r\n");
  348. }
  349. }
  350. else if(realTimeData.superaddition > 0)
  351. {
  352. addition_active = 1;
  353. }
  354. }
  355. void CoapConnect(void)
  356. {
  357. static uint32 seq = 1;
  358. int buf_len = 0;
  359. char sign_content[100]={0};
  360. char out[50]={0};
  361. char payload_content[512];
  362. int i=0;
  363. uint16_t coap_port = my_atoi(registInfo->port);//端口
  364. auth_token.flag = AUTH_HANDLING;
  365. coap_auth_id++;
  366. if(coap_auth_id < AUTH_MID)
  367. {
  368. coap_auth_id = AUTH_MID;
  369. }
  370. coap_send_pkt.hdr.id[0]=(uint8_t)(coap_auth_id&0x00ff);
  371. coap_send_pkt.hdr.id[1]=(uint8_t)(coap_auth_id>>8);
  372. // coap_send_pkt.hdr.id[0]=AUTH_MID;
  373. // coap_send_pkt.hdr.id[1]=0;
  374. coap_send_pkt.numopts=5;
  375. coap_send_pkt.opts[0].num=COAP_OPTION_URI_HOST;
  376. coap_send_pkt.opts[0].buf.len=strlen(registInfo->address);
  377. coap_send_pkt.opts[0].buf.p=(uint8_t*)registInfo->address;
  378. coap_send_pkt.opts[1].num=COAP_OPTION_URI_PORT;
  379. coap_send_pkt.opts[1].buf.len=sizeof(coap_port);
  380. coap_send_pkt.opts[1].buf.p=(uint8_t*)&coap_port;
  381. coap_send_pkt.opts[2].num=COAP_OPTION_URI_PATH;
  382. coap_send_pkt.opts[2].buf.len=strlen(coap_con_path);
  383. coap_send_pkt.opts[2].buf.p=(uint8_t*)coap_con_path;
  384. coap_send_pkt.opts[3].num=COAP_OPTION_CONTENT_FORMAT,
  385. coap_send_pkt.opts[3].buf.len=sizeof(coap_content_json),
  386. coap_send_pkt.opts[3].buf.p=&coap_content_json,
  387. coap_send_pkt.opts[4].num=COAP_OPTION_ACCEPT,
  388. coap_send_pkt.opts[4].buf.len=sizeof(coap_content_json),
  389. coap_send_pkt.opts[4].buf.p=&coap_content_json,
  390. seq++;
  391. snprintf(sign_content, sizeof(sign_content), sign_format,registInfo->productKey,registInfo->deviceName,registInfo->deviceName,registInfo->productKey,seq);
  392. utils_hmac_sha1_str(sign_content, strlen(sign_content), out, registInfo->deviceSecret, strlen(registInfo->deviceSecret));
  393. UsartPrintf(USART_DEBUG,"sign_content:%s,sign:%s\r\n",sign_content,out);
  394. snprintf(payload_content, sizeof(payload_content), payload_format,registInfo->productKey,registInfo->deviceName,"hmacsha1",out,registInfo->productKey,registInfo->deviceName,seq);
  395. coap_send_pkt.payload.len=strlen(payload_content);
  396. coap_send_pkt.payload.p=(uint8_t*)payload_content;
  397. UsartPrintf(USART_DEBUG,"auth_payload:%s\r\n",payload_content);
  398. memset(buf,0,BUF_SIZE);
  399. buf_len = BUF_SIZE;
  400. coap_build(buf,&buf_len,&coap_send_pkt);
  401. // UsartPrintf(USART_DEBUG,"\r\nauth byte,%d:\r\n",buf_len);
  402. // for(i=0;i<buf_len;i++)
  403. // {
  404. // UsartPrintf(USART_DEBUG,"%02x",buf[i]);
  405. // }
  406. at_module_send_rai(buf,buf_len,ONE_RRC);
  407. }
  408. void CoapPublish(uint8_t* payload,int len)
  409. {
  410. int buf_len = 0;
  411. char seq_conent[20] = {0};
  412. uint8_t seq[8] = {0};
  413. char paybyte[100] = {0};
  414. char *topic[] = {"topic","sys",registInfo->productKey, registInfo->deviceName,"thing","model","up_raw"};
  415. int topic_len = sizeof(topic)/sizeof(topic[0]);
  416. int optnum = 0;
  417. int i=0;
  418. uint16_t coap_port = my_atoi(registInfo->port);
  419. coap_send_pkt.hdr.id[0]=(uint8_t)(send_num&0x00ff);
  420. coap_send_pkt.hdr.id[1]=(uint8_t)(send_num>>8);
  421. coap_send_pkt.numopts=6+topic_len;
  422. coap_send_pkt.opts[optnum].num=COAP_OPTION_URI_HOST;
  423. coap_send_pkt.opts[optnum].buf.len=strlen(registInfo->address);
  424. coap_send_pkt.opts[optnum++].buf.p=(uint8_t*)registInfo->address;
  425. coap_send_pkt.opts[optnum].num=COAP_OPTION_URI_PORT;
  426. coap_send_pkt.opts[optnum].buf.len=sizeof(coap_port);
  427. coap_send_pkt.opts[optnum++].buf.p=(uint8_t*)&coap_port;
  428. for(i=0;i<topic_len;i++)
  429. {
  430. coap_send_pkt.opts[optnum].num=COAP_OPTION_URI_PATH;
  431. coap_send_pkt.opts[optnum].buf.len=strlen(topic[i]);
  432. coap_send_pkt.opts[optnum++].buf.p=(uint8_t*)topic[i];
  433. }
  434. coap_send_pkt.opts[optnum].num=COAP_OPTION_CONTENT_FORMAT,
  435. coap_send_pkt.opts[optnum].buf.len=sizeof(coap_content_json),
  436. coap_send_pkt.opts[optnum++].buf.p=&coap_content_json,
  437. coap_send_pkt.opts[optnum].num=COAP_OPTION_ACCEPT,
  438. coap_send_pkt.opts[optnum].buf.len=sizeof(coap_content_json),
  439. coap_send_pkt.opts[optnum++].buf.p=&coap_content_json,
  440. auth_token.seqOffset++;
  441. //UsartPrintf(USART_DEBUG,"===发送数据认证: %d,%s,%s:\r\n",auth_token.seqOffset,auth_token.random,auth_token.token);
  442. my_itoa(auth_token.seqOffset,(char*)seq,10);
  443. int seqlen = utils_aes128_cbc_enc((char*)auth_token.key, iv, (char*)seq, seq_conent);
  444. coap_send_pkt.opts[optnum].num=2088;
  445. coap_send_pkt.opts[optnum].buf.len=strlen(auth_token.token);
  446. coap_send_pkt.opts[optnum++].buf.p=(uint8_t*)auth_token.token;
  447. coap_send_pkt.opts[optnum].num=2089;
  448. coap_send_pkt.opts[optnum].buf.len=seqlen;
  449. coap_send_pkt.opts[optnum++].buf.p=(uint8_t*)seq_conent;
  450. int paylen = utils_aes128_cbc_base64_enc((char*)auth_token.key, iv, payload,len, paybyte);
  451. //UsartPrintf(USART_DEBUG,"===发送数据paylen: %d\r\n",paylen);
  452. coap_send_pkt.payload.len=paylen;
  453. coap_send_pkt.payload.p=(uint8_t*)paybyte;
  454. memset(buf,0,BUF_SIZE);
  455. buf_len = BUF_SIZE;
  456. coap_build(buf,&buf_len,&coap_send_pkt);
  457. // UsartPrintf(USART_DEBUG,"\r\npush byte,%d:\r\n",buf_len);
  458. // for(i=0;i<buf_len;i++)
  459. // {
  460. // UsartPrintf(USART_DEBUG,"%02x",buf[i]);
  461. // }
  462. // UsartPrintf(USART_DEBUG,"\r\n");
  463. at_module_send_rai(buf,buf_len,ONE_RRC);
  464. }
  465. static void ModuleKeepOnLine(void)
  466. {
  467. if(module_start_status == MODULE_OK && module_init_status == MODULE_OK)
  468. {
  469. TaskSchedulerFlag.NET_ONLINE_FLAG = TASK_FLAG_SET;//模块联网
  470. if(moduleInitCou > 0) // 连接基站成功
  471. {
  472. moduleInitCou = 0;
  473. DrawSignalDisplay();
  474. at_module_udpreopen(registInfo->address,registInfo->port);
  475. if(repeat_send_switch)//有数据发送, 重设重发时间
  476. {
  477. TaskSchedulerTimer.MQTTReSendTimer = FIVE_SECOND_TIMER;
  478. TaskSchedulerFlag.MqttReSendFlag = TASK_FLAG_CLEAR;
  479. }
  480. freshSignal((char*)signData,sizeof(signData));
  481. }
  482. if(auth_token.flag == AUTH_FAILURE)
  483. {
  484. if(tcp_connect_status == TCP_OPEN)
  485. {
  486. freshSignal((char*)signData,sizeof(signData));
  487. UsartPrintf(USART_DEBUG, "===CoapConnect=====\r\n");
  488. CoapConnect(); //coap认证
  489. }
  490. else
  491. {
  492. if(tcp_connect_status == TCP_CLOSED)
  493. {
  494. UsartPrintf(USART_DEBUG, "===udp open=====\r\n");
  495. at_module_udpreopen(registInfo->address,registInfo->port);
  496. }
  497. }
  498. }
  499. if(repeat_send_switch)
  500. {
  501. if(TaskSchedulerFlag.MqttReSendFlag == TASK_FLAG_SET)
  502. {
  503. TaskSchedulerFlag.MqttReSendFlag = TASK_FLAG_CLEAR;
  504. repeat_send_count++;
  505. UsartPrintf(USART_DEBUG, "\r\n===repeat send:%d=====\r\n",repeat_send_count);
  506. // if(repeat_send_count == 2)
  507. // {
  508. // at_module_udpreopen(registInfo->address,registInfo->port);
  509. // return;
  510. // }
  511. if(repeat_send_count == 4 || (repeat_send_count == 3 && tcp_connect_status != TCP_OPEN))
  512. {
  513. repeat_send_switch = 0; //关闭重发
  514. repeat_send_count = 0;
  515. module_start_status = MODULE_FAIL; //模块再次启动
  516. module_init_status = MODULE_FAIL;
  517. tcp_connect_status = TCP_CLOSED;
  518. TaskSchedulerFlag.ModuleInitFlag = TASK_FLAG_CLEAR;
  519. TaskSchedulerTimer.ModuleInitTimer = ONE_HOUR_TIMER;
  520. return;
  521. }
  522. send_num--;
  523. packPumbDataCoapSend();//重新发送
  524. }
  525. }
  526. }
  527. else
  528. {
  529. TaskSchedulerFlag.NET_ONLINE_FLAG = TASK_FLAG_CLEAR;//模块未联网
  530. if(TaskSchedulerFlag.ModuleInitFlag == TASK_FLAG_SET)
  531. {
  532. TaskSchedulerFlag.ModuleInitFlag = TASK_FLAG_CLEAR;
  533. TaskSchedulerTimer.ModuleInitTimer = FIFTEEN_SECOND_TIMER;
  534. moduleInitCou++;
  535. UsartPrintf(USART_DEBUG, "===start module=====%d\r\n",moduleInitCou);
  536. if(moduleInitCou >= 2 && module_start_status == MODULE_FAIL)
  537. {
  538. moduleInitCou = 0;
  539. DrawSignalDisplay();
  540. TaskSchedulerTimer.ModuleInitTimer = ONE_HOUR_TIMER;//连续5次启动失败,启动间隔变为半小时
  541. if (emSysWorkStep != EnterDetection)
  542. {
  543. at_module_low_power();//低功耗
  544. }
  545. repeat_send_switch = 0; //关闭重发
  546. repeat_send_count = 0;
  547. return;
  548. }
  549. if(module_start_status == MODULE_FAIL)
  550. {
  551. UsartPrintf(USART_DEBUG, "===restart module=====\r\n");
  552. at_module_start();
  553. }
  554. else if(module_init_status == MODULE_FAIL)
  555. {
  556. UsartPrintf(USART_DEBUG, "===init module=====\r\n");
  557. at_module_init();
  558. }
  559. }
  560. }
  561. }
  562. /**
  563. * 处理认证信息
  564. */
  565. static void AuthHandle(void)
  566. {
  567. cJSON *json = NULL,*json_seqOffset=NULL,*json_random=NULL,*json_token = NULL;
  568. json = cJSON_Parse((char*)coap_rec_pkt.payload.p);
  569. if(!json)
  570. {
  571. UsartPrintf(USART_DEBUG, "json parse error,%s\r\n",cJSON_GetErrorPtr());
  572. goto end;
  573. }
  574. json_seqOffset = cJSON_GetObjectItem(json,"seqOffset");
  575. json_random = cJSON_GetObjectItem(json,"random");
  576. json_token = cJSON_GetObjectItem(json,"token");
  577. if(json_random && json_token)
  578. {
  579. memset(&auth_token,0,sizeof(auth_token));
  580. if(json_seqOffset)
  581. {
  582. UsartPrintf(USART_DEBUG, "==认证成功=====%d,%s,%s\r\n",json_seqOffset->valueint,json_random->valuestring,json_token->valuestring);
  583. auth_token.seqOffset = json_seqOffset->valueint;
  584. }
  585. else
  586. {
  587. UsartPrintf(USART_DEBUG, "==认证成功=====%s,%s\r\n",json_random->valuestring,json_token->valuestring);
  588. auth_token.seqOffset = 100;
  589. }
  590. auth_token.flag = AUTH_SUCCESS;
  591. memcpy(auth_token.random,json_random->valuestring,strlen(json_random->valuestring));
  592. memcpy(auth_token.token,json_token->valuestring,strlen(json_token->valuestring));
  593. generateCoapKey();
  594. }
  595. else
  596. {
  597. UsartPrintf(USART_DEBUG, "==认证失败=====\r\n");
  598. // auth_token.flag = AUTH_FAILURE;
  599. }
  600. end:
  601. cJSON_Delete(json);
  602. }
  603. /**
  604. * 处理Coap返回消息
  605. */
  606. static void HandleCoapValidData()
  607. {
  608. int i = 0;
  609. uint16_t back_send_num = 0;
  610. static uint16_t last_send_num = 0;
  611. int ret = coap_parse(&coap_rec_pkt, (uint8_t*)valid_data.buf, valid_data.len);
  612. UsartPrintf(USART_DEBUG, "coap back,%d:\r\n",valid_data.len);
  613. for(i=0;i<valid_data.len;i++)
  614. {
  615. UsartPrintf(USART_DEBUG, "%02x",valid_data.buf[i]);
  616. }
  617. if(ret)
  618. {
  619. UsartPrintf(USART_DEBUG, "\r\n==解析失败,%d=====\r\n",ret);
  620. }
  621. else
  622. {
  623. //UsartPrintf(USART_DEBUG, "\r\n==解析成功====\r\n");
  624. back_send_num = (uint16_t)coap_rec_pkt.hdr.id[1]<<8;
  625. back_send_num |= coap_rec_pkt.hdr.id[0];
  626. if(coap_rec_pkt.hdr.code == SUC_ACK_CODE)
  627. {
  628. if(back_send_num == coap_auth_id) //认证返回
  629. {
  630. AuthHandle();
  631. }
  632. else if(back_send_num == send_num ) //上传返回
  633. {
  634. repeat_send_switch = 0; //收到最新回复关闭重发
  635. if(last_send_num < send_num)
  636. {
  637. last_send_num = send_num;
  638. send_suc_num++;
  639. }
  640. freshSignal((char*)signData,sizeof(signData));
  641. }
  642. }
  643. else if((coap_rec_pkt.hdr.code == UNAUTH_ACK_CODE || coap_rec_pkt.hdr.code == BADREQ_ACK_CODE) && back_send_num == send_num)
  644. {
  645. UsartPrintf(USART_DEBUG, "\r\n==未授权的请求=====\r\n");
  646. repeat_send_switch = 0;
  647. auth_token.flag = AUTH_FAILURE;
  648. }
  649. }
  650. valid_data_clear(); //清除有效数据
  651. }
  652. void CoapHandleEvent(void)
  653. {
  654. at_module_handle_event();
  655. if(valid_data.len>0)
  656. {
  657. HandleCoapValidData();
  658. }
  659. }
  660. //发送泵数据
  661. static void SendCoapPumpData()
  662. {
  663. static uint8_t send_flag = 1;
  664. if(!send_flag) return;
  665. IntePumpStateCoap();
  666. DecideSendFlagCoap();
  667. if(TaskSchedulerFlag.MqttSendFlag == TASK_FLAG_SET && motorWorkState != MOTOR_WORK_ON )
  668. {
  669. TaskSchedulerFlag.MqttSendFlag = TASK_FLAG_CLEAR;
  670. TaskSchedulerTimer.MQTTSendTimer = TWENTY_MINUTE_TIMER;
  671. if(EngineeringModeValue.test == 0)
  672. {
  673. TaskSchedulerTimer.MQTTSendTimer = TWENTY_SECOND_TIMER;
  674. if(send_num >= 300) //测试模式下最多发送300条数据
  675. {
  676. at_module_low_power();
  677. send_flag = 0;
  678. return;
  679. }
  680. }
  681. if(module_init_status == MODULE_FAIL && moduleInitCou == 0)
  682. {
  683. TaskSchedulerFlag.ModuleInitFlag = TASK_FLAG_SET;
  684. }
  685. if(repeat_send_switch == 0)
  686. {
  687. repeat_send_switch = 1;//准备重发
  688. repeat_send_count = 0;
  689. }
  690. packPumbDataCoapSend();
  691. TaskSchedulerTimer.MQTTReSendTimer = FIVE_SECOND_TIMER;
  692. TaskSchedulerFlag.MqttReSendFlag = TASK_FLAG_CLEAR;
  693. }
  694. }
  695. void CoapHandle(void)
  696. {
  697. ModuleKeepOnLine(); //保持网络连接
  698. CoapHandleEvent(); //处理接收数据
  699. if((Start_send == 0 && TurnOffACKTone == 0) || realTimeData.stateRun == Poweroff)
  700. {
  701. if(realTimeData.stateRun == Poweroff)
  702. {
  703. SpeakerCtl( DRIVER_OFF );//蜂鸣器
  704. LCDBLACtl( DRIVER_OFF );//LCD背光
  705. TaskSchedulerFlag.lcdBlackFlag = TASK_FLAG_CLEAR;
  706. }
  707. SendCoapPumpData(); //发送数据
  708. }
  709. if(realTimeData.stateRun == Poweroff)
  710. {
  711. delay_ms(500);
  712. TaskSchedulerFlag.sysPowerOffFlag = TASK_FLAG_SET;//关机
  713. }
  714. }
  715. void ModelRegister(void)
  716. {
  717. GPIO_InitTypeDef GPIO_InitStruct;
  718. /* enable clock */
  719. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  720. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  721. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
  722. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  723. //GPIO_InitStruct.Pull = GPIO_NOPULL;
  724. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  725. GPIO_Init(GPIOA, &GPIO_InitStruct);
  726. // GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
  727. // GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  728. // //GPIO_InitStruct.Pull = GPIO_NOPULL;
  729. // GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  730. // GPIO_Init(GPIOC, &GPIO_InitStruct);
  731. // BC26_WAKE_LOW();
  732. #ifdef BC26
  733. bc26_sal_register();
  734. #elif defined(ESP8266)
  735. esp8266_sal_register();
  736. #endif
  737. }
  738. /**
  739. * 模块信号强度,为负值
  740. */
  741. int16_t GetModeldBm(void)
  742. {
  743. char *recvdiff[9] = {0};//分割字符串地址
  744. uint8_t data[200]={0};
  745. uint16 dBm = 0;
  746. #ifdef BC26
  747. const char *SIGN = "+QENG: ";
  748. char *signStr = NULL;
  749. at_module_cmd_back("AT+QENG=0\r\n",(char*)data,sizeof(data));
  750. signStr = strstr((const char*)data,SIGN);
  751. if(signStr)
  752. {
  753. signStr+=strlen(SIGN);
  754. splitCharLimit((char*)data,',',recvdiff,9);
  755. dBm = my_atoi(recvdiff[7]);
  756. }
  757. #elif defined(ESP8266)
  758. #endif
  759. return dBm;
  760. }
  761. int16_t GetModelCSQ(void)
  762. {
  763. uint8_t data[50]={0};
  764. uint16 dBm = 0;
  765. #ifdef BC26
  766. const char *SIGN = "+CSQ: ";
  767. char *signStr = NULL;
  768. at_module_cmd_back("AT+CSQ\r\n",(char*)data,sizeof(data));
  769. signStr = strstr((const char*)data,SIGN);
  770. if(signStr)
  771. {
  772. signStr+=strlen(SIGN);
  773. dBm = my_atoi(signStr);
  774. }
  775. #endif
  776. return dBm;
  777. }
  778. /**
  779. * @Title 获取基站信号信息
  780. * @Param backdata1 小区信息, len1 backdata1长度,backdata2 信号强度信息,len2 backdata2长度
  781. */
  782. void GetSignalDetail(char* backdata1,int len1,char* backdata2,int len2)
  783. {
  784. char *recvdiff[10] = {0};
  785. uint8_t data[200]={0};
  786. const char *SIGN = "+QENG: ";
  787. char *signStr = NULL;
  788. at_module_cmd("AT\r\n");
  789. delay_ms(5);
  790. at_module_cmd("AT+QPING=0,\"iot-060a0bgd.coap.iothub.aliyuncs.com\",4,1\r\n");
  791. delay_ms(200);
  792. uint16 csq = GetModelCSQ();
  793. at_module_cmd_back("AT+QENG=0\r\n",(char*)data,sizeof(data));
  794. signStr = strstr((const char*)data,SIGN);
  795. if(signStr)
  796. {
  797. UsartPrintf(USART_DEBUG, "===signal detail 4=====:%s\r\n",data);
  798. signStr+=strlen(SIGN);
  799. int limit = splitCharLimit((char*)data,',',recvdiff,10);
  800. if(limit > 8)
  801. {
  802. *(recvdiff[4]+strlen(recvdiff[4])-1)=0;
  803. snprintf(backdata1,len1,"%s,%s",recvdiff[3],recvdiff[4]+1);
  804. //UsartPrintf(USART_DEBUG, "===signal detail 7=====:%s\r\n",backdata1);
  805. snprintf(backdata2,len2,"%s,%s,%s,%s,%d",recvdiff[5],recvdiff[6],recvdiff[7],recvdiff[8],csq);
  806. //UsartPrintf(USART_DEBUG, "===signal detail 8=====:%s\r\n",backdata2);
  807. }
  808. }
  809. }
  810. /**
  811. * @Title 刷新信后质量
  812. * @Param signData 信号质量存储位置, signDataLen 存储位置大小
  813. */
  814. void freshSignal(char* signData,int signDataLen)
  815. {
  816. char *recvdiff[10] = {0};
  817. uint8_t data[200]= {0};
  818. const char *SIGN = "+QENG: ";
  819. char *signStr = NULL;
  820. int i = 0;
  821. at_module_cmd_back("AT+QENG=0\r\n",(char*)data,sizeof(data));
  822. signStr = strstr((const char*)data,SIGN);
  823. if(signStr)
  824. {
  825. signStr+=strlen(SIGN);
  826. int limit = splitCharLimit((char*)signStr,',',recvdiff,10);
  827. if(signDataLen >=4 && limit > 8)
  828. {
  829. signData[0]= my_atoabs(recvdiff[5]);
  830. signData[1]= my_atoabs(recvdiff[6]);
  831. int num1 = my_atoi(recvdiff[7]);
  832. if(num1 == 99)
  833. {
  834. signData[2] = 255;
  835. }
  836. else
  837. {
  838. signData[2]= -num1;;
  839. }
  840. signData[3]= my_atoi(recvdiff[8]);
  841. }
  842. }
  843. }