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.

583 lines
23 KiB

3 years ago
3 years ago
3 years ago
  1. #include "ble_gatts_table.h"
  2. static uint8_t adv_config_done = 0;
  3. uint16_t heart_rate_handle_table[HRS_IDX_NB];
  4. static prepare_type_env_t prepare_write_env;
  5. #ifdef CONFIG_SET_RAW_ADV_DATA
  6. static uint8_t raw_adv_data[] = {
  7. /* flags */
  8. 0x02, 0x01, 0x06,
  9. /* tx power*/
  10. 0x02, 0x0a, 0xeb,
  11. /* service uuid */
  12. 0x03, 0x03, 0xFF, 0x00,
  13. /* device name */
  14. 0x0f, 0x09, 'E', 'S', 'P', '_', 'G', 'A', 'T', 'T', 'S', '_', 'D', 'E', 'M', 'O'};
  15. static uint8_t raw_scan_rsp_data[] = {
  16. /* flags */
  17. 0x02, 0x01, 0x06,
  18. /* tx power */
  19. 0x02, 0x0a, 0xeb,
  20. /* service uuid */
  21. 0x03, 0x03, 0xFF, 0x00};
  22. #else
  23. static uint8_t service_uuid[16] = {
  24. /* LSB <--------------------------------------------------------------------------------> MSB */
  25. // first uuid, 16bit, [12],[13] is the value
  26. 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, //
  27. };
  28. /* The length of adv data must be less than 31 bytes */
  29. static esp_ble_adv_data_t adv_data = {
  30. .set_scan_rsp = false,
  31. .include_name = true,
  32. .include_txpower = true,
  33. .min_interval = 0x0006, // slave connection min interval, Time = min_interval * 1.25 msec
  34. .max_interval = 0x0010, // slave connection max interval, Time = max_interval * 1.25 msec
  35. .appearance = 0x00,
  36. .manufacturer_len = 0, // TEST_MANUFACTURER_DATA_LEN,
  37. .p_manufacturer_data = NULL, // test_manufacturer,
  38. .service_data_len = 0,
  39. .p_service_data = NULL,
  40. .service_uuid_len = sizeof(service_uuid),
  41. .p_service_uuid = service_uuid,
  42. .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
  43. };
  44. // scan response data
  45. static esp_ble_adv_data_t scan_rsp_data = {
  46. .set_scan_rsp = true,
  47. .include_name = true,
  48. .include_txpower = true,
  49. .min_interval = 0x0006,
  50. .max_interval = 0x0010,
  51. .appearance = 0x00,
  52. .manufacturer_len = 0, // TEST_MANUFACTURER_DATA_LEN,
  53. .p_manufacturer_data = NULL, //&test_manufacturer[0],
  54. .service_data_len = 0,
  55. .p_service_data = NULL,
  56. .service_uuid_len = sizeof(service_uuid),
  57. .p_service_uuid = service_uuid,
  58. .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
  59. };
  60. #endif /* CONFIG_SET_RAW_ADV_DATA */
  61. static esp_ble_adv_params_t adv_params = {
  62. .adv_int_min = 0x20,
  63. .adv_int_max = 0x40,
  64. .adv_type = ADV_TYPE_IND,
  65. .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
  66. .channel_map = ADV_CHNL_ALL,
  67. .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
  68. };
  69. static void gatts_profile_event_handler(esp_gatts_cb_event_t event,
  70. esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
  71. /* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */
  72. static struct gatts_profile_inst heart_rate_profile_tab[PROFILE_NUM] = {
  73. [PROFILE_APP_IDX] = {
  74. .gatts_cb = gatts_profile_event_handler,
  75. .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
  76. },
  77. };
  78. /* Service */
  79. // static const uint16_t GATTS_SERVICE_UUID_TEST = 0x00FF;
  80. // static const uint16_t GATTS_CHAR_UUID_TEST_A = 0xFF01;
  81. // static const uint16_t GATTS_CHAR_UUID_TEST_B = 0xFF02;
  82. // static const uint16_t GATTS_CHAR_UUID_TEST_C = 0xFF03;
  83. static const uint8_t adv_service_uuid128[16] = {
  84. /* LSB <--------------------------------------------------------------------------------> MSB */
  85. 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x01, 0x00, 0x40, 0x6E, //
  86. };
  87. static const uint8_t adv_char_uuid128_a[16] = {
  88. /* LSB <--------------------------------------------------------------------------------> MSB */
  89. 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x02, 0x00, 0x40, 0x6E, //
  90. };
  91. static const uint8_t adv_char_uuid128_b[16] = {
  92. /* LSB <--------------------------------------------------------------------------------> MSB */
  93. 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x03, 0x00, 0x40, 0x6E, //
  94. };
  95. static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE;
  96. static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
  97. static const uint16_t character_client_config_uuid = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
  98. static const uint8_t char_prop_read = ESP_GATT_CHAR_PROP_BIT_READ;
  99. // static const uint8_t char_prop_write = ESP_GATT_CHAR_PROP_BIT_WRITE;
  100. static const uint8_t char_prop_read_write_notify = ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
  101. static const uint8_t heart_measurement_ccc[2] = {0x00, 0x00};
  102. static const uint8_t char_value[4] = {0x11, 0x22, 0x33, 0x44};
  103. /* Full Database Description - Used to add attributes into the database */
  104. static const esp_gatts_attr_db_t gatt_db[HRS_IDX_NB] =
  105. {
  106. // Service Declaration
  107. [IDX_SVC] =
  108. {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ, //
  109. sizeof(adv_service_uuid128), sizeof(adv_service_uuid128), (uint8_t *)&adv_service_uuid128}},
  110. /* Characteristic Declaration */
  111. [IDX_CHAR_A] =
  112. {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, //
  113. CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write_notify}},
  114. /* Characteristic Value */
  115. [IDX_CHAR_VAL_A] =
  116. {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_128, (uint8_t *)&adv_char_uuid128_a, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, //
  117. GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(char_value), (uint8_t *)char_value}},
  118. /* Client Characteristic Configuration Descriptor */
  119. [IDX_CHAR_CFG_A] =
  120. {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, //
  121. sizeof(uint16_t), sizeof(heart_measurement_ccc), (uint8_t *)heart_measurement_ccc}},
  122. /* Characteristic Declaration */
  123. [IDX_CHAR_B] =
  124. {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, //
  125. CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read}},
  126. /* Characteristic Value */
  127. [IDX_CHAR_VAL_B] =
  128. {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_128, (uint8_t *)&adv_char_uuid128_b, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, //
  129. GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(char_value), (uint8_t *)char_value}},
  130. // /* Characteristic Declaration */
  131. // [IDX_CHAR_C] =
  132. // {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
  133. // CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_write}},
  134. // /* Characteristic Value */
  135. // [IDX_CHAR_VAL_C] =
  136. // {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&GATTS_CHAR_UUID_TEST_C, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  137. // GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(char_value), (uint8_t *)char_value}},
  138. };
  139. static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
  140. {
  141. switch (event)
  142. {
  143. #ifdef CONFIG_SET_RAW_ADV_DATA
  144. case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
  145. adv_config_done &= (~ADV_CONFIG_FLAG);
  146. if (adv_config_done == 0)
  147. {
  148. esp_ble_gap_start_advertising(&adv_params);
  149. }
  150. break;
  151. case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
  152. adv_config_done &= (~SCAN_RSP_CONFIG_FLAG);
  153. if (adv_config_done == 0)
  154. {
  155. esp_ble_gap_start_advertising(&adv_params);
  156. }
  157. break;
  158. #else
  159. case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
  160. adv_config_done &= (~ADV_CONFIG_FLAG);
  161. if (adv_config_done == 0)
  162. {
  163. esp_ble_gap_start_advertising(&adv_params);
  164. }
  165. break;
  166. case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
  167. adv_config_done &= (~SCAN_RSP_CONFIG_FLAG);
  168. if (adv_config_done == 0)
  169. {
  170. esp_ble_gap_start_advertising(&adv_params);
  171. }
  172. break;
  173. #endif
  174. case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
  175. /* advertising start complete event to indicate advertising start successfully or failed */
  176. if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS)
  177. {
  178. ESP_LOGE(GATTS_TABLE_TAG, "advertising start failed");
  179. }
  180. else
  181. {
  182. ESP_LOGI(GATTS_TABLE_TAG, "advertising start successfully");
  183. }
  184. break;
  185. case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
  186. if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS)
  187. {
  188. ESP_LOGE(GATTS_TABLE_TAG, "Advertising stop failed");
  189. }
  190. else
  191. {
  192. ESP_LOGI(GATTS_TABLE_TAG, "Stop adv successfully\n");
  193. }
  194. break;
  195. case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
  196. ESP_LOGI(GATTS_TABLE_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
  197. param->update_conn_params.status,
  198. param->update_conn_params.min_int,
  199. param->update_conn_params.max_int,
  200. param->update_conn_params.conn_int,
  201. param->update_conn_params.latency,
  202. param->update_conn_params.timeout);
  203. break;
  204. default:
  205. break;
  206. }
  207. }
  208. void example_prepare_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
  209. {
  210. ESP_LOGI(GATTS_TABLE_TAG, "prepare write, handle = %d, value len = %d", param->write.handle, param->write.len);
  211. esp_gatt_status_t status = ESP_GATT_OK;
  212. if (prepare_write_env->prepare_buf == NULL)
  213. {
  214. prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t));
  215. prepare_write_env->prepare_len = 0;
  216. if (prepare_write_env->prepare_buf == NULL)
  217. {
  218. ESP_LOGE(GATTS_TABLE_TAG, "%s, Gatt_server prep no mem", __func__);
  219. status = ESP_GATT_NO_RESOURCES;
  220. }
  221. }
  222. else
  223. {
  224. if (param->write.offset > PREPARE_BUF_MAX_SIZE)
  225. {
  226. status = ESP_GATT_INVALID_OFFSET;
  227. }
  228. else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE)
  229. {
  230. status = ESP_GATT_INVALID_ATTR_LEN;
  231. }
  232. }
  233. /*send response when param->write.need_rsp is true */
  234. if (param->write.need_rsp)
  235. {
  236. esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t));
  237. if (gatt_rsp != NULL)
  238. {
  239. gatt_rsp->attr_value.len = param->write.len;
  240. gatt_rsp->attr_value.handle = param->write.handle;
  241. gatt_rsp->attr_value.offset = param->write.offset;
  242. gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
  243. memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
  244. esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp);
  245. if (response_err != ESP_OK)
  246. {
  247. ESP_LOGE(GATTS_TABLE_TAG, "Send response error");
  248. }
  249. free(gatt_rsp);
  250. }
  251. else
  252. {
  253. ESP_LOGE(GATTS_TABLE_TAG, "%s, malloc failed", __func__);
  254. }
  255. }
  256. if (status != ESP_GATT_OK)
  257. {
  258. return;
  259. }
  260. memcpy(prepare_write_env->prepare_buf + param->write.offset,
  261. param->write.value,
  262. param->write.len);
  263. prepare_write_env->prepare_len += param->write.len;
  264. }
  265. void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
  266. {
  267. if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC && prepare_write_env->prepare_buf)
  268. {
  269. esp_log_buffer_hex(GATTS_TABLE_TAG, prepare_write_env->prepare_buf, prepare_write_env->prepare_len);
  270. }
  271. else
  272. {
  273. ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATT_PREP_WRITE_CANCEL");
  274. }
  275. if (prepare_write_env->prepare_buf)
  276. {
  277. free(prepare_write_env->prepare_buf);
  278. prepare_write_env->prepare_buf = NULL;
  279. }
  280. prepare_write_env->prepare_len = 0;
  281. }
  282. static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
  283. {
  284. switch (event)
  285. {
  286. case ESP_GATTS_REG_EVT:
  287. {
  288. esp_err_t set_dev_name_ret = esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME);
  289. if (set_dev_name_ret)
  290. {
  291. ESP_LOGE(GATTS_TABLE_TAG, "set device name failed, error code = %x", set_dev_name_ret);
  292. }
  293. #ifdef CONFIG_SET_RAW_ADV_DATA
  294. esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data));
  295. if (raw_adv_ret)
  296. {
  297. ESP_LOGE(GATTS_TABLE_TAG, "config raw adv data failed, error code = %x ", raw_adv_ret);
  298. }
  299. adv_config_done |= ADV_CONFIG_FLAG;
  300. esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data));
  301. if (raw_scan_ret)
  302. {
  303. ESP_LOGE(GATTS_TABLE_TAG, "config raw scan rsp data failed, error code = %x", raw_scan_ret);
  304. }
  305. adv_config_done |= SCAN_RSP_CONFIG_FLAG;
  306. #else
  307. // config adv data
  308. esp_err_t ret = esp_ble_gap_config_adv_data(&adv_data);
  309. if (ret)
  310. {
  311. ESP_LOGE(GATTS_TABLE_TAG, "config adv data failed, error code = %x", ret);
  312. }
  313. adv_config_done |= ADV_CONFIG_FLAG;
  314. // config scan response data
  315. ret = esp_ble_gap_config_adv_data(&scan_rsp_data);
  316. if (ret)
  317. {
  318. ESP_LOGE(GATTS_TABLE_TAG, "config scan response data failed, error code = %x", ret);
  319. }
  320. adv_config_done |= SCAN_RSP_CONFIG_FLAG;
  321. #endif
  322. esp_err_t create_attr_ret = esp_ble_gatts_create_attr_tab(gatt_db, gatts_if, HRS_IDX_NB, SVC_INST_ID);
  323. if (create_attr_ret)
  324. {
  325. ESP_LOGE(GATTS_TABLE_TAG, "create attr table failed, error code = %x", create_attr_ret);
  326. }
  327. }
  328. break;
  329. case ESP_GATTS_READ_EVT:
  330. ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_READ_EVT");
  331. break;
  332. case ESP_GATTS_WRITE_EVT:
  333. if (!param->write.is_prep)
  334. {
  335. // the data length of gattc write must be less than GATTS_DEMO_CHAR_VAL_LEN_MAX.
  336. ESP_LOGI(GATTS_TABLE_TAG, "GATT_WRITE_EVT, handle = %d, value len = %d, value :", param->write.handle, param->write.len);
  337. esp_log_buffer_hex(GATTS_TABLE_TAG, param->write.value, param->write.len);
  338. if (heart_rate_handle_table[IDX_CHAR_CFG_A] == param->write.handle && param->write.len == 2)
  339. {
  340. uint16_t descr_value = param->write.value[1] << 8 | param->write.value[0];
  341. if (descr_value == 0x0001)
  342. {
  343. ESP_LOGI(GATTS_TABLE_TAG, "notify enable");
  344. uint8_t notify_data[15];
  345. for (int i = 0; i < sizeof(notify_data); ++i)
  346. {
  347. notify_data[i] = i % 0xff;
  348. }
  349. // the size of notify_data[] need less than MTU size
  350. esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, heart_rate_handle_table[IDX_CHAR_VAL_A],
  351. sizeof(notify_data), notify_data, false);
  352. }
  353. else if (descr_value == 0x0002)
  354. {
  355. ESP_LOGI(GATTS_TABLE_TAG, "indicate enable");
  356. uint8_t indicate_data[15];
  357. for (int i = 0; i < sizeof(indicate_data); ++i)
  358. {
  359. indicate_data[i] = i % 0xff;
  360. }
  361. // the size of indicate_data[] need less than MTU size
  362. esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, heart_rate_handle_table[IDX_CHAR_VAL_A],
  363. sizeof(indicate_data), indicate_data, true);
  364. }
  365. else if (descr_value == 0x0000)
  366. {
  367. ESP_LOGI(GATTS_TABLE_TAG, "notify/indicate disable ");
  368. }
  369. else
  370. {
  371. ESP_LOGE(GATTS_TABLE_TAG, "unknown descr value");
  372. esp_log_buffer_hex(GATTS_TABLE_TAG, param->write.value, param->write.len);
  373. }
  374. }
  375. /* send response when param->write.need_rsp is true*/
  376. if (param->write.need_rsp)
  377. {
  378. esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
  379. }
  380. }
  381. else
  382. {
  383. /* handle prepare write */
  384. example_prepare_write_event_env(gatts_if, &prepare_write_env, param);
  385. }
  386. break;
  387. case ESP_GATTS_EXEC_WRITE_EVT:
  388. // the length of gattc prepare write data must be less than GATTS_DEMO_CHAR_VAL_LEN_MAX.
  389. ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_EXEC_WRITE_EVT");
  390. example_exec_write_event_env(&prepare_write_env, param);
  391. break;
  392. case ESP_GATTS_MTU_EVT:
  393. ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
  394. break;
  395. case ESP_GATTS_CONF_EVT:
  396. ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_CONF_EVT, status = %d, attr_handle %d", param->conf.status, param->conf.handle);
  397. break;
  398. case ESP_GATTS_START_EVT:
  399. ESP_LOGI(GATTS_TABLE_TAG, "SERVICE_START_EVT, status %d, service_handle %d", param->start.status, param->start.service_handle);
  400. break;
  401. case ESP_GATTS_CONNECT_EVT:
  402. ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_CONNECT_EVT, conn_id = %d", param->connect.conn_id);
  403. esp_log_buffer_hex(GATTS_TABLE_TAG, param->connect.remote_bda, 6);
  404. esp_ble_conn_update_params_t conn_params = {0};
  405. memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
  406. /* For the iOS system, please refer to Apple official documents about the BLE connection parameters restrictions. */
  407. conn_params.latency = 0;
  408. conn_params.max_int = 0x20; // max_int = 0x20*1.25ms = 40ms
  409. conn_params.min_int = 0x10; // min_int = 0x10*1.25ms = 20ms
  410. conn_params.timeout = 400; // timeout = 400*10ms = 4000ms
  411. // start sent the update connection parameters to the peer device.
  412. esp_ble_gap_update_conn_params(&conn_params);
  413. break;
  414. case ESP_GATTS_DISCONNECT_EVT:
  415. ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_DISCONNECT_EVT, reason = 0x%x", param->disconnect.reason);
  416. esp_ble_gap_start_advertising(&adv_params);
  417. break;
  418. case ESP_GATTS_CREAT_ATTR_TAB_EVT:
  419. {
  420. if (param->add_attr_tab.status != ESP_GATT_OK)
  421. {
  422. ESP_LOGE(GATTS_TABLE_TAG, "create attribute table failed, error code=0x%x", param->add_attr_tab.status);
  423. }
  424. else if (param->add_attr_tab.num_handle != HRS_IDX_NB)
  425. {
  426. ESP_LOGE(GATTS_TABLE_TAG, "create attribute table abnormally, num_handle (%d) \
  427. doesn't equal to HRS_IDX_NB(%d)",
  428. param->add_attr_tab.num_handle, HRS_IDX_NB);
  429. }
  430. else
  431. {
  432. ESP_LOGI(GATTS_TABLE_TAG, "create attribute table successfully, the number handle = %d\n", param->add_attr_tab.num_handle);
  433. memcpy(heart_rate_handle_table, param->add_attr_tab.handles, sizeof(heart_rate_handle_table));
  434. esp_ble_gatts_start_service(heart_rate_handle_table[IDX_SVC]);
  435. }
  436. break;
  437. }
  438. case ESP_GATTS_STOP_EVT:
  439. case ESP_GATTS_OPEN_EVT:
  440. case ESP_GATTS_CANCEL_OPEN_EVT:
  441. case ESP_GATTS_CLOSE_EVT:
  442. case ESP_GATTS_LISTEN_EVT:
  443. case ESP_GATTS_CONGEST_EVT:
  444. case ESP_GATTS_UNREG_EVT:
  445. case ESP_GATTS_DELETE_EVT:
  446. default:
  447. break;
  448. }
  449. }
  450. static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
  451. {
  452. /* If event is register event, store the gatts_if for each profile */
  453. if (event == ESP_GATTS_REG_EVT)
  454. {
  455. if (param->reg.status == ESP_GATT_OK)
  456. {
  457. heart_rate_profile_tab[PROFILE_APP_IDX].gatts_if = gatts_if;
  458. }
  459. else
  460. {
  461. ESP_LOGE(GATTS_TABLE_TAG, "reg app failed, app_id %04x, status %d",
  462. param->reg.app_id,
  463. param->reg.status);
  464. return;
  465. }
  466. }
  467. do
  468. {
  469. int idx;
  470. for (idx = 0; idx < PROFILE_NUM; idx++)
  471. {
  472. /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
  473. if (gatts_if == ESP_GATT_IF_NONE || gatts_if == heart_rate_profile_tab[idx].gatts_if)
  474. {
  475. if (heart_rate_profile_tab[idx].gatts_cb)
  476. {
  477. heart_rate_profile_tab[idx].gatts_cb(event, gatts_if, param);
  478. }
  479. }
  480. }
  481. } while (0);
  482. }
  483. void ble_init(void)
  484. {
  485. esp_err_t ret;
  486. /* Initialize NVS. */
  487. ret = nvs_flash_init();
  488. if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
  489. {
  490. ESP_ERROR_CHECK(nvs_flash_erase());
  491. ret = nvs_flash_init();
  492. }
  493. ESP_ERROR_CHECK(ret);
  494. ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
  495. esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
  496. ret = esp_bt_controller_init(&bt_cfg);
  497. if (ret)
  498. {
  499. ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
  500. return;
  501. }
  502. ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
  503. if (ret)
  504. {
  505. ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
  506. return;
  507. }
  508. ret = esp_bluedroid_init();
  509. if (ret)
  510. {
  511. ESP_LOGE(GATTS_TABLE_TAG, "%s init bluetooth failed: %s", __func__, esp_err_to_name(ret));
  512. return;
  513. }
  514. ret = esp_bluedroid_enable();
  515. if (ret)
  516. {
  517. ESP_LOGE(GATTS_TABLE_TAG, "%s enable bluetooth failed: %s", __func__, esp_err_to_name(ret));
  518. return;
  519. }
  520. ret = esp_ble_gatts_register_callback(gatts_event_handler);
  521. if (ret)
  522. {
  523. ESP_LOGE(GATTS_TABLE_TAG, "gatts register error, error code = %x", ret);
  524. return;
  525. }
  526. ret = esp_ble_gap_register_callback(gap_event_handler);
  527. if (ret)
  528. {
  529. ESP_LOGE(GATTS_TABLE_TAG, "gap register error, error code = %x", ret);
  530. return;
  531. }
  532. ret = esp_ble_gatts_app_register(ESP_APP_ID);
  533. if (ret)
  534. {
  535. ESP_LOGE(GATTS_TABLE_TAG, "gatts app register error, error code = %x", ret);
  536. return;
  537. }
  538. esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500);
  539. if (local_mtu_ret)
  540. {
  541. ESP_LOGE(GATTS_TABLE_TAG, "set local MTU failed, error code = %x", local_mtu_ret);
  542. }
  543. }