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.

455 lines
17 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 year ago
1 year ago
1 year ago
1 year ago
  1. #include "zble_module.h"
  2. #include <stdint.h>
  3. #include <string.h>
  4. #include "ble_bas.h"
  5. #include "znordic.h"
  6. #include "basic/version.h"
  7. #if BLE_DFU_ENABLED
  8. #include "nrf_bootloader_info.h"
  9. #endif
  10. /*******************************************************************************
  11. * ?? *
  12. *******************************************************************************/
  13. #define MIN_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
  14. #define MAX_CONN_INTERVAL MSEC_TO_UNITS(75, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
  15. #define SLAVE_LATENCY 0 /**< Slave latency. */
  16. #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
  17. #define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */
  18. #define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
  19. #define APP_ADV_DURATION 18000 /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
  20. BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */
  21. /*******************************************************************************
  22. * GATT *
  23. *******************************************************************************/
  24. NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */
  25. /*******************************************************************************
  26. * Ӳ *
  27. *******************************************************************************/
  28. #define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
  29. #define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
  30. #define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */
  31. /*******************************************************************************
  32. * CODE *
  33. *******************************************************************************/
  34. static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< ��ǰ���Ӿ��� */
  35. static uint16_t m_mtu_size = BLE_GATT_ATT_MTU_DEFAULT - 3;
  36. static zble_event_listener_t m_event_listener;
  37. static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
  38. {
  39. uint32_t err_code;
  40. static zble_event_t zevent;
  41. switch (p_ble_evt->header.evt_id)
  42. {
  43. case BLE_GAP_EVT_CONNECTED:
  44. m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
  45. zevent.eventType = kzble_event_connected;
  46. if (m_event_listener)
  47. m_event_listener(&zevent);
  48. break;
  49. case BLE_GAP_EVT_DISCONNECTED:
  50. m_conn_handle = BLE_CONN_HANDLE_INVALID;
  51. zevent.eventType = kzble_event_disconnected;
  52. if (m_event_listener)
  53. m_event_listener(&zevent);
  54. break;
  55. case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
  56. {
  57. NRF_LOG_DEBUG("PHY update request.");
  58. ble_gap_phys_t const phys = {
  59. .rx_phys = BLE_GAP_PHY_AUTO,
  60. .tx_phys = BLE_GAP_PHY_AUTO,
  61. };
  62. err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
  63. ZERROR_CHECK(err_code);
  64. }
  65. break;
  66. case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
  67. // Pairing not supported
  68. err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
  69. ZERROR_CHECK(err_code);
  70. break;
  71. case BLE_GATTS_EVT_SYS_ATTR_MISSING:
  72. // No system attributes have been stored.
  73. err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
  74. ZERROR_CHECK(err_code);
  75. break;
  76. case BLE_GATTC_EVT_TIMEOUT:
  77. // Disconnect on GATT Client timeout event.
  78. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
  79. ZERROR_CHECK(err_code);
  80. break;
  81. case BLE_GATTS_EVT_TIMEOUT:
  82. // Disconnect on GATT Server timeout event.
  83. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
  84. ZERROR_CHECK(err_code);
  85. break;
  86. default:
  87. // No implementation needed.
  88. break;
  89. }
  90. }
  91. static void gatt_evt_handler(nrf_ble_gatt_t *p_gatt, nrf_ble_gatt_evt_t const *p_evt)
  92. {
  93. /*******************************************************************************
  94. * MTU SIZE *
  95. *******************************************************************************/
  96. if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
  97. {
  98. m_mtu_size = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
  99. NRF_LOG_DEBUG("ATT MTU exchange completed. central %d peripheral %d", p_gatt->att_mtu_desired_central, p_gatt->att_mtu_desired_periph);
  100. }
  101. }
  102. static void on_conn_params_evt(ble_conn_params_evt_t *p_evt)
  103. {
  104. uint32_t err_code;
  105. if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
  106. {
  107. err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
  108. ZERROR_CHECK(err_code);
  109. }
  110. }
  111. static void conn_params_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); }
  112. static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
  113. {
  114. switch (ble_adv_evt)
  115. {
  116. case BLE_ADV_EVT_FAST:
  117. // err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
  118. // ZERROR_CHECK(err_code);
  119. break;
  120. case BLE_ADV_EVT_IDLE:
  121. // sleep_mode_enter();
  122. break;
  123. default:
  124. break;
  125. }
  126. }
  127. void zble_module_start_adv()
  128. {
  129. uint32_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
  130. ZERROR_CHECK(err_code);
  131. }
  132. void zble_module_stop_adv()
  133. {
  134. sd_ble_gap_adv_stop(m_advertising.adv_handle);
  135. // ZERROR_CHECK(err_code);
  136. }
  137. bool zble_module_is_connected() { return m_conn_handle != BLE_CONN_HANDLE_INVALID; }
  138. /*******************************************************************************
  139. * INIT *
  140. *******************************************************************************/
  141. void zble_module_reglistener(zble_event_listener_t event_listener) { m_event_listener = event_listener; }
  142. #if BLE_DFU_ENABLED
  143. /**@brief Handler for shutdown preparation.
  144. *
  145. * @details During shutdown procedures, this function will be called at a 1 second interval
  146. * untill the function returns true. When the function returns true, it means that the
  147. * app is ready to reset to DFU mode.
  148. *
  149. * @param[in] event Power manager event.
  150. *
  151. * @retval True if shutdown is allowed by this power manager handler, otherwise false.
  152. */
  153. static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event)
  154. {
  155. switch (event)
  156. {
  157. case NRF_PWR_MGMT_EVT_PREPARE_DFU:
  158. NRF_LOG_INFO("Power management wants to reset to DFU mode.");
  159. // YOUR_JOB: Get ready to reset into DFU mode
  160. //
  161. // If you aren't finished with any ongoing tasks, return "false" to
  162. // signal to the system that reset is impossible at this stage.
  163. //
  164. // Here is an example using a variable to delay resetting the device.
  165. //
  166. // if (!m_ready_for_reset)
  167. // {
  168. // return false;
  169. // }
  170. // else
  171. //{
  172. //
  173. // // Device ready to enter
  174. // uint32_t err_code;
  175. // err_code = sd_softdevice_disable();
  176. // APP_ERROR_CHECK(err_code);
  177. // err_code = app_timer_stop_all();
  178. // APP_ERROR_CHECK(err_code);
  179. //}
  180. break;
  181. default:
  182. // YOUR_JOB: Implement any of the other events available from the power management module:
  183. // -NRF_PWR_MGMT_EVT_PREPARE_SYSOFF
  184. // -NRF_PWR_MGMT_EVT_PREPARE_WAKEUP
  185. // -NRF_PWR_MGMT_EVT_PREPARE_RESET
  186. return true;
  187. }
  188. NRF_LOG_INFO("Power management allowed to reset to DFU mode.");
  189. return true;
  190. }
  191. // lint -esym(528, m_app_shutdown_handler)
  192. /**@brief Register application shutdown handler with priority 0.
  193. */
  194. NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0);
  195. static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void *p_context)
  196. {
  197. if (state == NRF_SDH_EVT_STATE_DISABLED)
  198. {
  199. // Softdevice was disabled before going into reset. Inform bootloader to skip CRC on next boot.
  200. nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC);
  201. // Go to system off.
  202. nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
  203. }
  204. }
  205. /* nrf_sdh state observer. */
  206. NRF_SDH_STATE_OBSERVER(m_buttonless_dfu_state_obs, 0) = {
  207. .handler = buttonless_dfu_sdh_state_observer,
  208. };
  209. static void advertising_config_get(ble_adv_modes_config_t *p_config)
  210. {
  211. memset(p_config, 0, sizeof(ble_adv_modes_config_t));
  212. p_config->ble_adv_fast_enabled = true;
  213. p_config->ble_adv_fast_interval = APP_ADV_INTERVAL;
  214. p_config->ble_adv_fast_timeout = APP_ADV_DURATION;
  215. }
  216. static void disconnect(uint16_t conn_handle, void *p_context)
  217. {
  218. UNUSED_PARAMETER(p_context);
  219. ret_code_t err_code = sd_ble_gap_disconnect(conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
  220. if (err_code != NRF_SUCCESS)
  221. {
  222. NRF_LOG_WARNING("Failed to disconnect connection. Connection handle: %d Error: %d", conn_handle, err_code);
  223. }
  224. else
  225. {
  226. NRF_LOG_DEBUG("Disconnected connection handle %d", conn_handle);
  227. }
  228. }
  229. // YOUR_JOB: Update this code if you want to do anything given a DFU event (optional).
  230. /**@brief Function for handling dfu events from the Buttonless Secure DFU service
  231. *
  232. * @param[in] event Event from the Buttonless Secure DFU service.
  233. */
  234. static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event)
  235. {
  236. switch (event)
  237. {
  238. case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
  239. {
  240. NRF_LOG_INFO("Device is preparing to enter bootloader mode.");
  241. // Prevent device from advertising on disconnect.
  242. ble_adv_modes_config_t config;
  243. advertising_config_get(&config);
  244. config.ble_adv_on_disconnect_disabled = true;
  245. ble_advertising_modes_config_set(&m_advertising, &config);
  246. // Disconnect all other bonded devices that currently are connected.
  247. // This is required to receive a service changed indication
  248. // on bootup after a successful (or aborted) Device Firmware Update.
  249. uint32_t conn_count = ble_conn_state_for_each_connected(disconnect, NULL);
  250. NRF_LOG_INFO("Disconnected %d links.", conn_count);
  251. break;
  252. }
  253. case BLE_DFU_EVT_BOOTLOADER_ENTER:
  254. // YOUR_JOB: Write app-specific unwritten data to FLASH, control finalization of this
  255. // by delaying reset by reporting false in app_shutdown_handler
  256. NRF_LOG_INFO("Device will enter bootloader mode.");
  257. break;
  258. case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
  259. NRF_LOG_ERROR("Request to enter bootloader mode failed asynchroneously.");
  260. // YOUR_JOB: Take corrective measures to resolve the issue
  261. // like calling APP_ERROR_CHECK to reset the device.
  262. break;
  263. case BLE_DFU_EVT_RESPONSE_SEND_ERROR:
  264. NRF_LOG_ERROR("Request to send a response to client failed.");
  265. // YOUR_JOB: Take corrective measures to resolve the issue
  266. // like calling APP_ERROR_CHECK to reset the device.
  267. APP_ERROR_CHECK(false);
  268. break;
  269. default:
  270. NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless.");
  271. break;
  272. }
  273. }
  274. #endif
  275. // static ble_uuid_t m_adv_uuids[] = /**< Universally unique service identifier. */
  276. // {{0x0002, BLE_UUID_TYPE_VENDOR_BEGIN}};
  277. // static ble_uuid_t m_adv_uuids[] = {{BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE}};
  278. #define COMPANY_IDENTIFIER_DATA_LEGTH 2 /**< Total length of information advertised by the Beacon. */
  279. static uint8_t p_company_identifier_data[COMPANY_IDENTIFIER_DATA_LEGTH] =
  280. {
  281. (FIRMWARE_VERSION >> 8) & 0xFF,
  282. FIRMWARE_VERSION & 0xFF,
  283. };
  284. void zble_module_init(zble_module_cfg_t *cfg)
  285. {
  286. /**
  287. * @brief
  288. * ʼЭջע¼̶??
  289. */
  290. {
  291. NRF_SDH_BLE_OBSERVER(m_ble_observer, 3, ble_evt_handler, NULL);
  292. }
  293. /*******************************************************************************
  294. * GAPʼ?? *
  295. *******************************************************************************/
  296. {
  297. uint32_t err_code;
  298. ble_gap_conn_params_t gap_conn_params;
  299. ble_gap_conn_sec_mode_t sec_mode;
  300. BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
  301. err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)cfg->deviceName, strlen(cfg->deviceName));
  302. ZERROR_CHECK(err_code);
  303. memset(&gap_conn_params, 0, sizeof(gap_conn_params));
  304. gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
  305. gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
  306. gap_conn_params.slave_latency = SLAVE_LATENCY;
  307. gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
  308. err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
  309. ZERROR_CHECK(err_code);
  310. }
  311. /*******************************************************************************
  312. * GATT ʼ?? *
  313. *******************************************************************************/
  314. {
  315. ret_code_t err_code;
  316. err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
  317. ZERROR_CHECK(err_code);
  318. err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
  319. ZERROR_CHECK(err_code);
  320. }
  321. /*******************************************************************************
  322. * ʼ?? *
  323. *******************************************************************************/
  324. {
  325. uint32_t err_code;
  326. ble_advertising_init_t init;
  327. memset(&init, 0, sizeof(init));
  328. static ble_advdata_manuf_data_t manuf_specific_data;
  329. manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
  330. manuf_specific_data.data.p_data = (uint8_t *)p_company_identifier_data;
  331. manuf_specific_data.data.size = COMPANY_IDENTIFIER_DATA_LEGTH;
  332. init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
  333. init.advdata.include_appearance = true;
  334. init.advdata.p_manuf_specific_data = &manuf_specific_data;
  335. // init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
  336. init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
  337. // init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
  338. // init.srdata.uuids_complete.p_uuids = m_adv_uuids;
  339. err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR);
  340. APP_ERROR_CHECK(err_code);
  341. init.srdata.uuids_complete.uuid_cnt = 0;
  342. init.srdata.uuids_complete.p_uuids = NULL;
  343. init.config.ble_adv_fast_enabled = true;
  344. init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
  345. init.config.ble_adv_fast_timeout = 0;
  346. init.evt_handler = on_adv_evt;
  347. err_code = ble_advertising_init(&m_advertising, &init);
  348. ZERROR_CHECK(err_code);
  349. ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
  350. }
  351. /*******************************************************************************
  352. * ʼ?? *
  353. *******************************************************************************/
  354. #if BLE_DFU_ENABLED
  355. {
  356. ble_dfu_buttonless_init_t dfus_init = {0};
  357. dfus_init.evt_handler = ble_dfu_evt_handler;
  358. ret_code_t err_code = ble_dfu_buttonless_init(&dfus_init);
  359. ZERROR_CHECK(err_code);
  360. if (cfg->on_service_init)
  361. cfg->on_service_init();
  362. }
  363. #endif
  364. /*******************************************************************************
  365. * Ӳʼ?? *
  366. *******************************************************************************/
  367. {
  368. uint32_t err_code;
  369. ble_conn_params_init_t cp_init;
  370. memset(&cp_init, 0, sizeof(cp_init));
  371. cp_init.p_conn_params = NULL;
  372. cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
  373. cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
  374. cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
  375. cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
  376. cp_init.disconnect_on_fail = false;
  377. cp_init.evt_handler = on_conn_params_evt;
  378. cp_init.error_handler = conn_params_error_handler;
  379. err_code = ble_conn_params_init(&cp_init);
  380. ZERROR_CHECK(err_code);
  381. }
  382. // zble_module_start_adv();
  383. }
  384. int32_t zble_module_get_mtu_size() { return m_mtu_size; }
  385. bool zble_module_disconnect(){
  386. ble_conn_state_for_each_connected(disconnect, NULL);
  387. return true;
  388. }