You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

366 lines
14 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include "app_ble_service.h"
  2. #include "../../ify_hrs_protocol/heart_rate_sensor_protocol.h"
  3. #include "app_event.h"
  4. #include "app_event_distribute.h"
  5. #include "app_scheduler.h"
  6. #include "board/board.h"
  7. #include "board/board_battery_state.h"
  8. #include "device_ctrl_service.h"
  9. #include "heart_wave_sample_service.h"
  10. #include "sample_data_manager_service.h"
  11. #include "zble_module.h"
  12. #include "zdatachannel_service.h"
  13. #include "znordic.h"
  14. #include "znordic_device_info_mgr.h"
  15. static uint8_t rxbufcache[256];
  16. static bool is_rxbufcache_used = false; // ���յ�����Ϣ�Ƿ����ڱ�������
  17. static bool m_realtime_report_state = false; // ʵʱ�ϱ�״̬
  18. static uint8_t m_txbuf[128];
  19. static uint8_t m_reportbuf[128];
  20. static void prvf_process_ble_rx_data(void* p_event_data, uint16_t event_size);
  21. static void process_ble_rx_data(void* p_event_data, uint16_t event_size);
  22. /*******************************************************************************
  23. * ע *
  24. *******************************************************************************/
  25. ZDATACHANNEL_DEF(m_zhrs, 2 /*���ȼ�*/, 1 /*client num*/);
  26. /**
  27. * @brief Ϣص
  28. */
  29. static void zdatachannel_data_handler(zdatachannel_evt_t* p_evt) {
  30. if (p_evt->type != ZDATACHANNEL_EVT_RX_DATA) {
  31. return;
  32. }
  33. // ��Ϣ���ڱ������У�������������Ϣ
  34. if (is_rxbufcache_used) return;
  35. if (p_evt->params.rx_data.length > sizeof(rxbufcache)) return;
  36. memcpy(rxbufcache, p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
  37. uint32_t suc = app_sched_event_put(rxbufcache, p_evt->params.rx_data.length, process_ble_rx_data);
  38. if (suc == 0) {
  39. is_rxbufcache_used = true;
  40. }
  41. }
  42. /*******************************************************************************
  43. * UTILS *
  44. *******************************************************************************/
  45. int ble_start_realtime_report() {
  46. m_realtime_report_state = true;
  47. return 0;
  48. }
  49. int ble_stop_realtime_report() {
  50. m_realtime_report_state = false;
  51. return 0;
  52. }
  53. static void send_error_receipt(ify_hrs_packet_t* rxpacket, int32_t errorcode) {
  54. ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)m_txbuf;
  55. error_receipt_t* receipt = (error_receipt_t*)txheader->data;
  56. uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(error_receipt_t);
  57. txheader->cmd = rxpacket->cmd;
  58. txheader->frame_index = rxpacket->frame_index;
  59. txheader->frame_type = kifyhrs_pt_error_receipt;
  60. txheader->frame_type = kifyhrs_pt_error_receipt;
  61. receipt->errorcode = kifyhrs_ecode_cmd_not_support;
  62. zdatachannel_data_send2(m_txbuf, sendlen);
  63. }
  64. static void send_success_receipt(ify_hrs_packet_t* rxpacket, int32_t emptydatasize) {
  65. ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)m_txbuf;
  66. uint16_t sendlen = sizeof(ify_hrs_packet_t) + emptydatasize;
  67. txheader->cmd = rxpacket->cmd;
  68. txheader->frame_index = rxpacket->frame_index;
  69. txheader->frame_type = kifyhrs_pt_cmd_receipt;
  70. zdatachannel_data_send2(m_txbuf, sendlen);
  71. }
  72. static void prvf_try_report_sensor_drop_event(uint8_t dropstate0, uint8_t dropstate1) {
  73. sensor_drop_event_report_packet_t* reportpacket = (sensor_drop_event_report_packet_t*)m_reportbuf;
  74. reportpacket->cmd = ify_hrs_report_sensor_drop_detect;
  75. reportpacket->frame_index = 0;
  76. reportpacket->frame_type = kifyhrs_pt_report;
  77. reportpacket->drop_state0 = dropstate0;
  78. reportpacket->drop_state1 = dropstate1;
  79. uint16_t sendlen = sizeof(sensor_drop_event_report_packet_t);
  80. zdatachannel_data_send2(m_reportbuf, sendlen);
  81. return;
  82. }
  83. static void prvf_try_report_sample_end_event() {
  84. ify_hrs_packet_t* reportpacket = (ify_hrs_packet_t*)m_reportbuf;
  85. reportpacket->cmd = ify_hrs_report_sample_finish_end;
  86. reportpacket->frame_index = 0;
  87. reportpacket->frame_type = kifyhrs_pt_report;
  88. uint16_t sendlen = sizeof(ify_hrs_packet_t);
  89. zdatachannel_data_send2(m_reportbuf, sendlen);
  90. return;
  91. }
  92. void prvf_report_sample_data(uint32_t frameIndex, uint32_t data, uint32_t data2, uint32_t data3) {
  93. if (!m_realtime_report_state) {
  94. return;
  95. }
  96. heartrate_report_packet_t* reportpacket = (heartrate_report_packet_t*)m_reportbuf;
  97. reportpacket->cmd = ify_hrs_report_heartrate_data;
  98. reportpacket->frame_index = 0;
  99. reportpacket->frame_type = kifyhrs_pt_report;
  100. reportpacket->sample_data_index = frameIndex;
  101. /**
  102. * @brief һ
  103. */
  104. reportpacket->data[0] = (data >> 0) & 0xFF;
  105. reportpacket->data[1] = (data >> 8) & 0xFF;
  106. reportpacket->data[2] = (data >> 16) & 0xFF;
  107. reportpacket->data[3] = 0;
  108. /**
  109. * @brief ڶ
  110. */
  111. reportpacket->data[4] = (data2 >> 0) & 0xFF;
  112. reportpacket->data[5] = (data2 >> 8) & 0xFF;
  113. reportpacket->data[6] = (data2 >> 16) & 0xFF;
  114. reportpacket->data[7] = 0;
  115. /**
  116. * @brief
  117. */
  118. reportpacket->data[8] = (data3 >> 0) & 0xFF;
  119. reportpacket->data[9] = (data3 >> 8) & 0xFF;
  120. reportpacket->data[10] = (data3 >> 16) & 0xFF;
  121. reportpacket->data[11] = 0;
  122. uint16_t sendlen = sizeof(heartrate_report_packet_t) + 4 * 3;
  123. zdatachannel_data_send2(m_reportbuf, sendlen);
  124. return;
  125. }
  126. /*******************************************************************************
  127. * Ϣ *
  128. *******************************************************************************/
  129. static void process_ble_rx_data(void* p_event_data, uint16_t event_size) { //
  130. prvf_process_ble_rx_data(p_event_data, event_size);
  131. is_rxbufcache_used = false;
  132. }
  133. static void prvf_process_ble_rx_data(void* p_event_data, uint16_t len) {
  134. ify_hrs_packet_t* rxheader = (ify_hrs_packet_t*)p_event_data;
  135. ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)m_txbuf;
  136. ify_hrs_cmd_t cmd = (ify_hrs_cmd_t)rxheader->cmd;
  137. memset(m_txbuf, 0, sizeof(m_txbuf));
  138. ZLOGI("rx:");
  139. NRF_LOG_HEXDUMP_INFO(p_event_data, len);
  140. ZLOGI("rx cmd:%d index:%d datalen:%d", cmd, rxheader->frame_index, len - sizeof(ify_hrs_packet_t));
  141. txheader->cmd = rxheader->cmd;
  142. txheader->frame_index = rxheader->frame_index;
  143. txheader->frame_type = kifyhrs_pt_cmd_receipt;
  144. NRF_LOG_HEXDUMP_INFO(rxheader->data, len - sizeof(ify_hrs_packet_t));
  145. if (cmd == ify_hrs_cmd_read_device_version) {
  146. device_version_info_receipt_t* receipt = (device_version_info_receipt_t*)txheader->data;
  147. uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(device_version_info_receipt_t);
  148. receipt->blestack_version = device_info_read_blestack_version();
  149. receipt->bootloader_version = device_info_read_bootloader_version();
  150. receipt->firmware_version = device_info_read_firmware_version();
  151. receipt->hardware_version = device_info_read_hardware_version();
  152. zdatachannel_data_send2(m_txbuf, sendlen);
  153. }
  154. else if (cmd == ify_hrs_cmd_read_sensor_info) {
  155. sensor_info_receipt_t* receipt = (sensor_info_receipt_t*)txheader->data;
  156. uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(sensor_info_receipt_t);
  157. receipt->sensor_num = 1;
  158. receipt->sensor_precision = SAMPLE_PRECISION;
  159. receipt->sensor_sample_rate = SAMPLE_RATE / 10;
  160. receipt->sensor0_pos = kifyhrs_sensor_pos_II;
  161. receipt->sensor1_pos = kifyhrs_sensor_pos_V1;
  162. receipt->sensor2_pos = kifyhrs_sensor_pos_V5;
  163. zdatachannel_data_send2(m_txbuf, sendlen);
  164. }
  165. else if (cmd == ify_hrs_cmd_read_device_state) {
  166. device_state_receipt_t* receipt = (device_state_receipt_t*)txheader->data;
  167. uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(device_state_receipt_t);
  168. receipt->drop_state0 = hwss_get_drop_state0();
  169. receipt->drop_state1 = hwss_get_drop_state1();
  170. receipt->drop_state1 = 0x00;
  171. receipt->device_state0.sampling_state = (DeviceCtrl_now_state() == kdevice_state_sampling);
  172. receipt->device_state0.report_state = m_realtime_report_state;
  173. receipt->device_state0.low_battery = (BoardBattery_get_battery_level() < 20);
  174. receipt->device_state0.full_storge = (SampleDataMgr_storageIsFull());
  175. receipt->device_state1 = 0;
  176. receipt->powerlevel = BoardBattery_get_battery_level();
  177. receipt->storage_item_num = SampleDataMgr_getFileNum();
  178. zdatachannel_data_send2(m_txbuf, sendlen);
  179. }
  180. else if (cmd == ify_hrs_cmd_read_time) {
  181. read_time_receipt_t* receipt = (read_time_receipt_t*)txheader->data;
  182. uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(read_time_receipt_t);
  183. static ztm_t ztm;
  184. znordic_rtc_gettime(&ztm);
  185. receipt->year = (ztm.tm_year + 1900 - 2000);
  186. receipt->month = ztm.tm_mon + 1;
  187. receipt->day = ztm.tm_mday;
  188. receipt->hour = ztm.tm_hour;
  189. receipt->minute = ztm.tm_min;
  190. receipt->second = ztm.tm_sec;
  191. zdatachannel_data_send2(m_txbuf, sendlen);
  192. }
  193. else if (cmd == ify_hrs_cmd_sync_time) {
  194. sync_time_cmd_t* cmd = (sync_time_cmd_t*)rxheader->data;
  195. uint16_t sendlen = sizeof(ify_hrs_packet_t);
  196. znordic_rtc_settime(cmd->year + 2000, cmd->month, cmd->day, cmd->hour, cmd->minute, cmd->second);
  197. zdatachannel_data_send2(m_txbuf, sendlen);
  198. }
  199. else if (cmd == ify_hrs_cmd_start_capture) {
  200. hwss_start_capture();
  201. send_success_receipt(rxheader, 0);
  202. }
  203. else if (cmd == ify_hrs_cmd_stop_capture) {
  204. hwss_stop_capture();
  205. send_success_receipt(rxheader, 0);
  206. }
  207. else if (cmd == ify_hrs_cmd_start_realtime_report) {
  208. // unsupport cmd
  209. int ecode = ble_start_realtime_report();
  210. if (ecode == 0) {
  211. send_success_receipt(rxheader, 8); // ��8���ֽڣ�ʹ������ִ���ֽڳ���ͬ�ϱ�������һ�£���������
  212. } else {
  213. send_error_receipt(rxheader, ecode);
  214. }
  215. }
  216. else if (cmd == ify_hrs_cmd_stop_realtime_report) {
  217. int ecode = ble_stop_realtime_report();
  218. if (ecode == 0) {
  219. send_success_receipt(rxheader, 0);
  220. } else {
  221. send_error_receipt(rxheader, ecode);
  222. }
  223. }
  224. else if (cmd == ify_hrs_cmd_read_records_info) {
  225. // ָ�� 10-��ȡ������¼ͷ����Ϣ
  226. read_record_info_cmd_t* cmd = (read_record_info_cmd_t*)rxheader->data;
  227. read_record_info_receipt_t* receipt = (read_record_info_receipt_t*)txheader->data;
  228. uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(read_record_info_receipt_t);
  229. uint8_t recordoff = cmd->record_index;
  230. // ����ʱ��֧��
  231. if (hwss_is_capturing()) {
  232. send_error_receipt(rxheader, kifyhrs_ecode_device_busy);
  233. return;
  234. }
  235. sample_data_fileinfo_list_t* recordlist = SampleDataMgr_getFileinfoList();
  236. if (recordoff >= recordlist->count) {
  237. send_error_receipt(rxheader, kifyhrs_ecode_no_record_find);
  238. return;
  239. }
  240. sample_data_fileinfo_t* fileinfo = recordlist->fileinfo[recordoff];
  241. memcpy(receipt->record_id, fileinfo->filename, 6);
  242. receipt->frameNum = fileinfo->size / 2; // 2byte per frame
  243. receipt->dataSize = fileinfo->size;
  244. receipt->sensorNum = 1;
  245. receipt->captureRate = SAMPLE_RATE / 10;
  246. receipt->capturePrecision = SAMPLE_PRECISION;
  247. receipt->compressAlgorithm = 0;
  248. zdatachannel_data_send2(m_txbuf, sendlen);
  249. }
  250. else if (cmd == ify_hrs_cmd_del_record) {
  251. // ָ�� 11-ɾ��������¼
  252. del_record_cmd_t* cmd = (del_record_cmd_t*)rxheader->data;
  253. static sample_data_filename_t filename;
  254. memset(&filename, 0, sizeof(filename));
  255. memcpy(&filename, cmd->record_id, sizeof(cmd->record_id));
  256. send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support);
  257. }
  258. else if (cmd == ify_hrs_cmd_start_upload_record) {
  259. // ָ�� 12-�ϴ��ɼ���¼
  260. send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support);
  261. }
  262. else if (cmd == ify_hrs_cmd_enter_ota) {
  263. send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support);
  264. }
  265. else if (cmd == ify_hrs_cmd_read_sn) {
  266. read_sn_receipt_t* receipt = (read_sn_receipt_t*)txheader->data;
  267. uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(read_sn_receipt_t);
  268. device_info_read_sn((sn_t*)&receipt->sn);
  269. zdatachannel_data_send2(m_txbuf, sendlen);
  270. }
  271. else if (cmd == ify_hrs_cmd_reset) {
  272. NVIC_SystemReset();
  273. }
  274. //
  275. else {
  276. send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support);
  277. }
  278. }
  279. void AppBleService_onServiceInitCB() {
  280. ZLOGI("init zdatachannel service");
  281. static zdatachannel_init_t zdatachannle_init;
  282. memset(&zdatachannle_init, 0, sizeof(zdatachannle_init));
  283. zdatachannle_init.data_handler = zdatachannel_data_handler;
  284. ZERROR_CHECK(zdatachannel_init(&m_zhrs, &zdatachannle_init));
  285. }
  286. static void app_event_listener(void* p_event_data, uint16_t event_size) { //
  287. app_event_t* event = (app_event_t*)p_event_data;
  288. if (event->eventType == kevent_sensor_drop) {
  289. prvf_try_report_sensor_drop_event(event->val.sensor_drop.drop0, event->val.sensor_drop.drop1);
  290. } else if (event->eventType == kevent_sample_stop_event) {
  291. prvf_try_report_sample_end_event();
  292. } else if (event->eventType == kevent_capture_little_data_block_event) {
  293. // �ϱ���������
  294. if (m_realtime_report_state) {
  295. // �ϱ���������
  296. prvf_report_sample_data(event->val.little_data_block.frameIndex, //
  297. event->val.little_data_block.data[0].data0, //
  298. event->val.little_data_block.data[0].data1, //
  299. event->val.little_data_block.data[0].data2);
  300. }
  301. }
  302. }
  303. void AppBleService_init() { AppEvent_regListener(app_event_listener); }