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.

408 lines
16 KiB

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