user_sever.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. #include "user_server.h"
  2. #include "user_nfc.h"
  3. #include "user_elect.h"
  4. #include "user_led.h"
  5. #include "dip_sw.h"
  6. tmosTaskID user_server_task_id = INVALID_TASK_ID;
  7. static uint32_t offline_timeout = CAN_OFFLINE_TIMEOUT_DEFAULT / USER_SERVER_INTERVAL;
  8. static bool offline_stat = false;
  9. static uint8_t can_idx = 0xFF;
  10. static lock_data_s lock_data = {
  11. .lock_stat = 0,
  12. .elect_stat = 0,
  13. .lock_id = {0},
  14. };
  15. static can_open_data_s can_open_data;
  16. /*******************************************************************************
  17. * @函数名称 prvUser_server_dev_type_protocol
  18. * @函数说明 设备类型索引解析
  19. * @输入参数 无
  20. * @输出参数 无
  21. * @返回参数 无
  22. *******************************************************************************/
  23. static void prvUser_server_dev_type_protocol(void)
  24. {
  25. if(can_open_data.subidx == REG_DEV_TYPE_SUBIDX)
  26. {
  27. if(can_open_data.ins == S_INS_RD)
  28. {
  29. can_open_data_s s_data;
  30. s_data.ins = R_INS_RD_WORD;
  31. s_data.idx = REG_DEV_TYPE_IDX;
  32. s_data.subidx = REG_DEV_TYPE_SUBIDX;
  33. s_data.data[0] = DEV_TYPE;
  34. s_data.data[1] = DEV_TYPE >> 8;
  35. s_data.data[2] = 0;
  36. s_data.data[3] = 0;
  37. vUser_can_send_data((uint8_t *)&s_data, 8);
  38. }
  39. else{
  40. can_open_data_s s_data;
  41. s_data.ins = R_INS_WR_FAIL;
  42. s_data.idx = REG_DEV_TYPE_IDX;
  43. s_data.subidx = REG_DEV_TYPE_SUBIDX;
  44. memset(s_data.data, 0, 4);
  45. vUser_can_send_data((uint8_t *)&s_data, 8);
  46. }
  47. }
  48. }
  49. /*******************************************************************************
  50. * @函数名称 prvUser_server_version_protocol
  51. * @函数说明 版本号索引解析
  52. * @输入参数 无
  53. * @输出参数 无
  54. * @返回参数 无
  55. *******************************************************************************/
  56. static void prvUser_server_version_protocol(void)
  57. {
  58. if(can_open_data.subidx == REG_VERSION_SUBIDX)
  59. {
  60. if(can_open_data.ins == S_INS_RD)
  61. {
  62. can_open_data_s s_data;
  63. s_data.ins = R_INS_RD_DWORD;
  64. s_data.idx = REG_VERSION_IDX;
  65. s_data.subidx = REG_VERSION_SUBIDX;
  66. s_data.data[0] = HARDWARE_VERSION;
  67. s_data.data[1] = HARDWARE_VERSION >> 8;
  68. s_data.data[2] = SOFTWARE_VERSION;
  69. s_data.data[3] = SOFTWARE_VERSION >> 8;
  70. vUser_can_send_data((uint8_t *)&s_data, 8);
  71. }
  72. else{
  73. can_open_data_s s_data;
  74. s_data.ins = R_INS_WR_FAIL;
  75. s_data.idx = REG_VERSION_IDX;
  76. s_data.subidx = REG_VERSION_SUBIDX;
  77. memset(s_data.data, 0, 4);
  78. vUser_can_send_data((uint8_t *)&s_data, 8);
  79. }
  80. }
  81. }
  82. /*******************************************************************************
  83. * @函数名称 prvUser_server_lock_stat_protocol
  84. * @函数说明 挂锁索引解析
  85. * @输入参数 无
  86. * @输出参数 无
  87. * @返回参数 无
  88. *******************************************************************************/
  89. static void prvUser_server_lock_stat_protocol(void)
  90. {
  91. if(can_open_data.subidx == REG_LOCK_STAT_SUBIDX)
  92. {
  93. if(can_open_data.ins == S_INS_RD)
  94. {
  95. can_open_data_s s_data;
  96. s_data.ins = R_INS_RD_BYTE;
  97. s_data.idx = REG_LOCK_STAT_IDX;
  98. s_data.subidx = REG_LOCK_STAT_SUBIDX;
  99. memset(s_data.data, 0, 4);
  100. memcpy(s_data.data,(uint8_t *)&(lock_data.lock_stat), 1);
  101. vUser_can_send_data((uint8_t *)&s_data, 8);
  102. }
  103. else{
  104. can_open_data_s s_data;
  105. s_data.ins = R_INS_WR_FAIL;
  106. s_data.idx = REG_LOCK_STAT_IDX;
  107. s_data.subidx = REG_LOCK_STAT_SUBIDX;
  108. memset(s_data.data, 0, 4);
  109. vUser_can_send_data((uint8_t *)&s_data, 8);
  110. }
  111. }
  112. }
  113. /*******************************************************************************
  114. * @函数名称 prvUser_server_elect_stat_protocol
  115. * @函数说明 电磁锁控制索引解析
  116. * @输入参数 无
  117. * @输出参数 无
  118. * @返回参数 无
  119. *******************************************************************************/
  120. static void prvUser_server_elect_stat_protocol(void)
  121. {
  122. if(can_open_data.subidx == REG_ELECT_STAT_SUBIDX)
  123. {
  124. if(can_open_data.ins == S_INS_RD)
  125. {
  126. can_open_data_s s_data;
  127. s_data.ins = R_INS_RD_WORD;
  128. s_data.idx = REG_ELECT_STAT_IDX;
  129. s_data.subidx = REG_ELECT_STAT_SUBIDX;
  130. memset(s_data.data, 0, 4);
  131. memcpy(s_data.data,(uint8_t *)&(lock_data.elect_stat), 2);
  132. vUser_can_send_data((uint8_t *)&s_data, 8);
  133. }
  134. else if(can_open_data.ins == S_INS_WR_WORD)
  135. {
  136. uint16_t temp = 0;
  137. memcpy((uint8_t *)&temp, (uint8_t *)&can_open_data.data, 2);
  138. can_open_data_s s_data;
  139. s_data.ins = R_INS_WR_SUCC;
  140. s_data.idx = REG_ELECT_STAT_IDX;
  141. s_data.subidx = REG_ELECT_STAT_SUBIDX;
  142. memset(s_data.data, 0, 4);
  143. memcpy(s_data.data,(uint8_t *)&temp, 2);
  144. vUser_can_send_data((uint8_t *)&s_data, 8);
  145. for(int i = 0; i < LOCK_COUNT; i++)
  146. {
  147. if((temp & (1 << (i + 8))) != 0)
  148. {
  149. if((temp & (1 << i)) != 0)
  150. {
  151. set_elect_work_stat(i, true);
  152. }
  153. else{
  154. set_elect_work_stat(i, false);
  155. }
  156. }
  157. }
  158. }
  159. else{
  160. can_open_data_s s_data;
  161. s_data.ins = R_INS_WR_FAIL;
  162. s_data.idx = REG_ELECT_STAT_IDX;
  163. s_data.subidx = REG_ELECT_STAT_SUBIDX;
  164. memset(s_data.data, 0, 4);
  165. vUser_can_send_data((uint8_t *)&s_data, 8);
  166. }
  167. }
  168. }
  169. /*******************************************************************************
  170. * @函数名称 prvUser_server_lock_id_protocol
  171. * @函数说明 挂锁NFC号索引解析
  172. * @输入参数 无
  173. * @输出参数 无
  174. * @返回参数 无
  175. *******************************************************************************/
  176. static void prvUser_server_lock_id_protocol(void)
  177. {
  178. if(can_open_data.subidx == REG_LOCK_01_ID_SUBIDX)
  179. {
  180. if(can_open_data.ins == S_INS_RD)
  181. {
  182. can_open_data_s s_data;
  183. s_data.ins = R_INS_RD_DWORD;
  184. s_data.idx = REG_LOCK_ID_IDX;
  185. s_data.subidx = REG_LOCK_01_ID_SUBIDX;
  186. memset(s_data.data, 0, 4);
  187. memcpy(s_data.data,(uint8_t *)&(lock_data.lock_id[0]), 4);
  188. vUser_can_send_data((uint8_t *)&s_data, 8);
  189. }
  190. else{
  191. can_open_data_s s_data;
  192. s_data.ins = R_INS_WR_FAIL;
  193. s_data.idx = REG_LOCK_ID_IDX;
  194. s_data.subidx = REG_LOCK_01_ID_SUBIDX;
  195. memset(s_data.data, 0, 4);
  196. vUser_can_send_data((uint8_t *)&s_data, 8);
  197. }
  198. }
  199. else if(can_open_data.subidx == REG_LOCK_02_ID_SUBIDX)
  200. {
  201. if(can_open_data.ins == S_INS_RD)
  202. {
  203. can_open_data_s s_data;
  204. s_data.ins = R_INS_RD_DWORD;
  205. s_data.idx = REG_LOCK_ID_IDX;
  206. s_data.subidx = REG_LOCK_02_ID_SUBIDX;
  207. memset(s_data.data, 0, 4);
  208. memcpy(s_data.data,(uint8_t *)&(lock_data.lock_id[1]), 4);
  209. vUser_can_send_data((uint8_t *)&s_data, 8);
  210. }
  211. else{
  212. can_open_data_s s_data;
  213. s_data.ins = R_INS_WR_FAIL;
  214. s_data.idx = REG_LOCK_ID_IDX;
  215. s_data.subidx = REG_LOCK_02_ID_SUBIDX;
  216. memset(s_data.data, 0, 4);
  217. vUser_can_send_data((uint8_t *)&s_data, 8);
  218. }
  219. }
  220. else if(can_open_data.subidx == REG_LOCK_03_ID_SUBIDX)
  221. {
  222. if(can_open_data.ins == S_INS_RD)
  223. {
  224. can_open_data_s s_data;
  225. s_data.ins = R_INS_RD_DWORD;
  226. s_data.idx = REG_LOCK_ID_IDX;
  227. s_data.subidx = REG_LOCK_03_ID_SUBIDX;
  228. memset(s_data.data, 0, 4);
  229. memcpy(s_data.data,(uint8_t *)&(lock_data.lock_id[2]), 4);
  230. vUser_can_send_data((uint8_t *)&s_data, 8);
  231. }
  232. else{
  233. can_open_data_s s_data;
  234. s_data.ins = R_INS_WR_FAIL;
  235. s_data.idx = REG_LOCK_ID_IDX;
  236. s_data.subidx = REG_LOCK_03_ID_SUBIDX;
  237. memset(s_data.data, 0, 4);
  238. vUser_can_send_data((uint8_t *)&s_data, 8);
  239. }
  240. }
  241. else if(can_open_data.subidx == REG_LOCK_04_ID_SUBIDX)
  242. {
  243. if(can_open_data.ins == S_INS_RD)
  244. {
  245. can_open_data_s s_data;
  246. s_data.ins = R_INS_RD_DWORD;
  247. s_data.idx = REG_LOCK_ID_IDX;
  248. s_data.subidx = REG_LOCK_04_ID_SUBIDX;
  249. memset(s_data.data, 0, 4);
  250. memcpy(s_data.data,(uint8_t *)&(lock_data.lock_id[3]), 4);
  251. vUser_can_send_data((uint8_t *)&s_data, 8);
  252. }
  253. else{
  254. can_open_data_s s_data;
  255. s_data.ins = R_INS_WR_FAIL;
  256. s_data.idx = REG_LOCK_ID_IDX;
  257. s_data.subidx = REG_LOCK_04_ID_SUBIDX;
  258. memset(s_data.data, 0, 4);
  259. vUser_can_send_data((uint8_t *)&s_data, 8);
  260. }
  261. }
  262. else if(can_open_data.subidx == REG_LOCK_05_ID_SUBIDX)
  263. {
  264. if(can_open_data.ins == S_INS_RD)
  265. {
  266. can_open_data_s s_data;
  267. s_data.ins = R_INS_RD_DWORD;
  268. s_data.idx = REG_LOCK_ID_IDX;
  269. s_data.subidx = REG_LOCK_05_ID_SUBIDX;
  270. memset(s_data.data, 0, 4);
  271. memcpy(s_data.data,(uint8_t *)&(lock_data.lock_id[4]), 4);
  272. vUser_can_send_data((uint8_t *)&s_data, 8);
  273. }
  274. else{
  275. can_open_data_s s_data;
  276. s_data.ins = R_INS_WR_FAIL;
  277. s_data.idx = REG_LOCK_ID_IDX;
  278. s_data.subidx = REG_LOCK_05_ID_SUBIDX;
  279. memset(s_data.data, 0, 4);
  280. vUser_can_send_data((uint8_t *)&s_data, 8);
  281. }
  282. }
  283. }
  284. /*******************************************************************************
  285. * @函数名称 prvUser_server_can_protocol
  286. * @函数说明 can总线协议解析
  287. * @输入参数 无
  288. * @输出参数 无
  289. * @返回参数 无
  290. *******************************************************************************/
  291. static void prvUser_server_can_protocol(void)
  292. {
  293. bool stat = false;
  294. switch(can_open_data.idx)
  295. {
  296. case REG_DEV_TYPE_IDX:{
  297. prvUser_server_dev_type_protocol();
  298. stat = true;
  299. }break;
  300. case REG_VERSION_IDX:{
  301. prvUser_server_version_protocol();
  302. stat = true;
  303. }break;
  304. case REG_LOCK_STAT_IDX:{
  305. prvUser_server_lock_stat_protocol();
  306. stat = true;
  307. }break;
  308. case REG_ELECT_STAT_IDX:{
  309. prvUser_server_elect_stat_protocol();
  310. stat = true;
  311. }break;
  312. case REG_LOCK_ID_IDX:{
  313. prvUser_server_lock_id_protocol();
  314. stat = true;
  315. }break;
  316. default:break;
  317. }
  318. if(stat == true)
  319. {
  320. offline_timeout = CAN_OFFLINE_TIMEOUT_DEFAULT / USER_SERVER_INTERVAL;
  321. if(offline_stat == true)
  322. {
  323. offline_stat = false;
  324. vUser_led_set_alarm_view(LED_ALL_ALARM_OFFLINE, false);
  325. }
  326. }
  327. }
  328. /*******************************************************************************
  329. * @函数名称 ble_action_rst_pro
  330. * @函数说明 重启倒计时
  331. * @输入参数 无
  332. * @输出参数 无
  333. * @返回参数 无
  334. *******************************************************************************/
  335. static uint8_t rst_timeout = 5;
  336. static void ble_action_rst_pro(void)
  337. {
  338. if(rst_timeout == 0)
  339. {
  340. /* Software reset */
  341. NVIC_SystemReset();
  342. }
  343. else{
  344. rst_timeout--;
  345. PRINT("Restart countdown %d second\n", rst_timeout);
  346. }
  347. }
  348. /*******************************************************************************
  349. * @函数名称 prvUser_server_can_offline_check
  350. * @函数说明 CAN总线离线检测
  351. * @输入参数 无
  352. * @输出参数 无
  353. * @返回参数 无
  354. *******************************************************************************/
  355. static void prvUser_server_can_offline_check(void)
  356. {
  357. if(offline_timeout > 0)
  358. {
  359. if(offline_timeout == 1)
  360. {
  361. if(offline_stat == false)
  362. {
  363. offline_stat = true;
  364. vUser_led_set_alarm_view(LED_ALL_ALARM_OFFLINE, true);
  365. }
  366. }
  367. offline_timeout--;
  368. }
  369. }
  370. /*******************************************************************************
  371. * @函数名称 user_server_task_process_event
  372. * @函数说明 task的event处理回调函数,需要在注册task时候,传进去
  373. * @输入参数 task_id:任务ID
  374. events:事件
  375. * @输出参数 无
  376. * @返回参数 无
  377. *******************************************************************************/
  378. static uint16_t user_server_task_process_event(uint8_t task_id, uint16_t events)
  379. {
  380. //event 处理
  381. if(events & (1 << SERVER_QUEUE_TIME))
  382. {
  383. prvUser_server_can_offline_check();
  384. return (events ^ (1 << SERVER_QUEUE_TIME)); //异或的方式清除该事件运行标志,并返回未运行的事件标志
  385. }
  386. if(events & (1 << SERVER_QUEUE_CAN))
  387. {
  388. prvUser_server_can_protocol();
  389. return (events ^ (1 << SERVER_QUEUE_CAN)); //异或的方式清除该事件运行标志,并返回未运行的事件标志
  390. }
  391. if(events & (1 <<SERVER_BLE_RST))
  392. {
  393. ble_action_rst_pro();
  394. return (events ^ (1 << SERVER_BLE_RST)); //异或的方式清除该事件运行标志,并返回未运行的事件标志
  395. }
  396. return 0;
  397. }
  398. /*******************************************************************************
  399. * @函数名称 vUser_server_task_start
  400. * @函数说明 定时任务开始
  401. * @输入参数 无
  402. * @输出参数 无
  403. * @返回参数 无
  404. *******************************************************************************/
  405. void vUser_server_task_start(void)
  406. {
  407. bStatus_t stat = tmos_start_reload_task(user_server_task_id, (1 << SERVER_QUEUE_TIME), MS1_TO_SYSTEM_TIME(USER_SERVER_INTERVAL));
  408. }
  409. /*******************************************************************************
  410. * @函数名称 vUser_server_set_led_stat
  411. * @函数说明 设置LED灯变化
  412. * @输入参数 idx:底座号
  413. * @输出参数 无
  414. * @返回参数 无
  415. *******************************************************************************/
  416. static void vUser_server_set_led_stat(uint8_t idx)
  417. {
  418. if(((lock_data.elect_stat & (1 << idx)) != 0 ) && ((lock_data.lock_stat & (1 << idx)) != 0))
  419. {
  420. vUser_led_set_view_stat(idx, LED_VIEW_LOCK_ELECT);
  421. }
  422. else if(((lock_data.elect_stat & (1 << idx)) == 0 ) && ((lock_data.lock_stat & (1 << idx)) == 0))
  423. {
  424. vUser_led_set_view_stat(idx, LED_VIEW_NOLOCK_NOELECT);
  425. }
  426. else if(((lock_data.elect_stat & (1 << idx)) == 0 ) && ((lock_data.lock_stat & (1 << idx)) != 0))
  427. {
  428. vUser_led_set_view_stat(idx, LED_VIEW_LOCK_NOELECT);
  429. }
  430. else if(((lock_data.elect_stat & (1 << idx)) != 0 ) && ((lock_data.lock_stat & (1 << idx)) == 0))
  431. {
  432. vUser_led_set_view_stat(idx, LED_VIEW_NOLOCK_ELECT);
  433. }
  434. }
  435. /*******************************************************************************
  436. * @函数名称 vUser_server_get_lock_data
  437. * @函数说明 获取挂锁底座数据变量
  438. * @输入参数 无
  439. * @输出参数 无
  440. * @返回参数 挂锁底座数据变量指针
  441. *******************************************************************************/
  442. lock_data_s *vUser_server_get_lock_data(void)
  443. {
  444. return &lock_data;
  445. }
  446. /*******************************************************************************
  447. * @函数名称 vUser_can_recv_data_callback
  448. * @函数说明 can接收数据上报回调
  449. * @输入参数 data:数据指针
  450. size:数据长度
  451. * @输出参数 无
  452. * @返回参数 无
  453. *******************************************************************************/
  454. static void prvUser_can_recv_data_callback(uint8_t *data, uint8_t size)
  455. {
  456. memcpy(&can_open_data, data, sizeof(can_open_data_s));
  457. bStatus_t stat = tmos_start_task(user_server_task_id, (1 << SERVER_QUEUE_CAN), MS1_TO_SYSTEM_TIME(1));
  458. }
  459. /*******************************************************************************
  460. * @函数名称 vUser_nfc_upload_card_callback
  461. * @函数说明 钥匙nfc标签读取上报回调
  462. * @输入参数 idx:挂锁底座号
  463. stat:是否有挂锁
  464. card:挂锁RFID号
  465. * @输出参数 无
  466. * @返回参数 无
  467. *******************************************************************************/
  468. static void prvUser_nfc_upload_card_callback(uint8_t idx, bool stat, unsigned char *card)
  469. {
  470. if(stat == true)
  471. {
  472. lock_data.lock_stat |= (1 << idx);
  473. memcpy(lock_data.lock_id[idx], &card[4], 4);
  474. }
  475. else{
  476. lock_data.lock_stat &= ~(1 << idx);
  477. memcpy(lock_data.lock_id[idx], &card[4], 4);
  478. }
  479. vUser_server_set_led_stat(idx);
  480. }
  481. /*******************************************************************************
  482. * @函数名称 vUser_elect_upload_stat_callback
  483. * @函数说明 设置挂锁位电磁锁状态回调
  484. * @输入参数 idx:挂锁底座号
  485. stat:电磁锁是否锁死
  486. * @输出参数 无
  487. * @返回参数 无
  488. *******************************************************************************/
  489. static void vUser_elect_upload_stat_callback(uint8_t idx, bool stat)
  490. {
  491. if(stat == true)
  492. {
  493. lock_data.elect_stat |= (1 << idx);
  494. }
  495. else{
  496. lock_data.elect_stat &= ~(1 << idx);
  497. }
  498. vUser_server_set_led_stat(idx);
  499. }
  500. /*******************************************************************************
  501. * @函数名称 prvDipsw_upload_callback
  502. * @函数说明 地址读取回调
  503. * @输入参数 无
  504. * @输出参数 无
  505. * @返回参数 无
  506. *******************************************************************************/
  507. static void prvDipsw_upload_callback(uint8_t addr)
  508. {
  509. vUser_can_set_addr(addr);
  510. elect_start(addr);
  511. if(addr != can_idx)
  512. {
  513. can_idx = addr;
  514. if(addr > 0)
  515. {
  516. vUser_led_set_alarm_view(LED_ALL_ALARM_CAN_IDX_ERROR, false);
  517. }
  518. else{
  519. vUser_led_set_alarm_view(LED_ALL_ALARM_CAN_IDX_ERROR, true);
  520. }
  521. }
  522. }
  523. /*******************************************************************************
  524. * @函数名称 vUser_server_init
  525. * @函数说明 初始化
  526. * @输入参数 无
  527. * @输出参数 无
  528. * @返回参数 无
  529. *******************************************************************************/
  530. void vUser_server_init(void)
  531. {
  532. vUser_can_set_recv_data_func(prvUser_can_recv_data_callback);
  533. vUser_nfc_set_upload_key_stat_func(prvUser_nfc_upload_card_callback);
  534. vUser_elect_set_upload_stat_func(vUser_elect_upload_stat_callback);
  535. vDipsw_set_upload_func(prvDipsw_upload_callback);
  536. user_server_task_id = TMOS_ProcessEventRegister(user_server_task_process_event);
  537. PRINT("user_server_task_id=%d\n", user_server_task_id);
  538. }