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.

599 lines
23 KiB

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