esp_hid_gap.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. #include <string.h>
  7. #include <stdbool.h>
  8. #include <inttypes.h>
  9. #include "freertos/FreeRTOS.h"
  10. #include "freertos/task.h"
  11. #include "freertos/semphr.h"
  12. #include "esp_hid_gap.h"
  13. static const char *TAG = "ESP_HID_GAP";
  14. // uncomment to print all devices that were seen during a scan
  15. #define GAP_DBG_PRINTF(...) //printf(__VA_ARGS__)
  16. //static const char * gap_bt_prop_type_names[5] = {"","BDNAME","COD","RSSI","EIR"};
  17. static esp_hid_scan_result_t *bt_scan_results = NULL;
  18. static size_t num_bt_scan_results = 0;
  19. static esp_hid_scan_result_t *ble_scan_results = NULL;
  20. static size_t num_ble_scan_results = 0;
  21. static SemaphoreHandle_t bt_hidh_cb_semaphore = NULL;
  22. #define WAIT_BT_CB() xSemaphoreTake(bt_hidh_cb_semaphore, portMAX_DELAY)
  23. #define SEND_BT_CB() xSemaphoreGive(bt_hidh_cb_semaphore)
  24. static SemaphoreHandle_t ble_hidh_cb_semaphore = NULL;
  25. #define WAIT_BLE_CB() xSemaphoreTake(ble_hidh_cb_semaphore, portMAX_DELAY)
  26. #define SEND_BLE_CB() xSemaphoreGive(ble_hidh_cb_semaphore)
  27. #define SIZEOF_ARRAY(a) (sizeof(a)/sizeof(*a))
  28. static const char *ble_gap_evt_names[] = { "ADV_DATA_SET_COMPLETE", "SCAN_RSP_DATA_SET_COMPLETE", "SCAN_PARAM_SET_COMPLETE", "SCAN_RESULT", "ADV_DATA_RAW_SET_COMPLETE", "SCAN_RSP_DATA_RAW_SET_COMPLETE", "ADV_START_COMPLETE", "SCAN_START_COMPLETE", "AUTH_CMPL", "KEY", "SEC_REQ", "PASSKEY_NOTIF", "PASSKEY_REQ", "OOB_REQ", "LOCAL_IR", "LOCAL_ER", "NC_REQ", "ADV_STOP_COMPLETE", "SCAN_STOP_COMPLETE", "SET_STATIC_RAND_ADDR", "UPDATE_CONN_PARAMS", "SET_PKT_LENGTH_COMPLETE", "SET_LOCAL_PRIVACY_COMPLETE", "REMOVE_BOND_DEV_COMPLETE", "CLEAR_BOND_DEV_COMPLETE", "GET_BOND_DEV_COMPLETE", "READ_RSSI_COMPLETE", "UPDATE_WHITELIST_COMPLETE"};
  29. static const char *bt_gap_evt_names[] = { "DISC_RES", "DISC_STATE_CHANGED", "RMT_SRVCS", "RMT_SRVC_REC", "AUTH_CMPL", "PIN_REQ", "CFM_REQ", "KEY_NOTIF", "KEY_REQ", "READ_RSSI_DELTA"};
  30. static const char *ble_addr_type_names[] = {"PUBLIC", "RANDOM", "RPA_PUBLIC", "RPA_RANDOM"};
  31. const char *ble_addr_type_str(esp_ble_addr_type_t ble_addr_type)
  32. {
  33. if (ble_addr_type > BLE_ADDR_TYPE_RPA_RANDOM) {
  34. return "UNKNOWN";
  35. }
  36. return ble_addr_type_names[ble_addr_type];
  37. }
  38. const char *ble_gap_evt_str(uint8_t event)
  39. {
  40. if (event >= SIZEOF_ARRAY(ble_gap_evt_names)) {
  41. return "UNKNOWN";
  42. }
  43. return ble_gap_evt_names[event];
  44. }
  45. const char *bt_gap_evt_str(uint8_t event)
  46. {
  47. if (event >= SIZEOF_ARRAY(bt_gap_evt_names)) {
  48. return "UNKNOWN";
  49. }
  50. return bt_gap_evt_names[event];
  51. }
  52. #if CONFIG_BT_BLE_ENABLED
  53. const char *esp_ble_key_type_str(esp_ble_key_type_t key_type)
  54. {
  55. const char *key_str = NULL;
  56. switch (key_type) {
  57. case ESP_LE_KEY_NONE:
  58. key_str = "ESP_LE_KEY_NONE";
  59. break;
  60. case ESP_LE_KEY_PENC:
  61. key_str = "ESP_LE_KEY_PENC";
  62. break;
  63. case ESP_LE_KEY_PID:
  64. key_str = "ESP_LE_KEY_PID";
  65. break;
  66. case ESP_LE_KEY_PCSRK:
  67. key_str = "ESP_LE_KEY_PCSRK";
  68. break;
  69. case ESP_LE_KEY_PLK:
  70. key_str = "ESP_LE_KEY_PLK";
  71. break;
  72. case ESP_LE_KEY_LLK:
  73. key_str = "ESP_LE_KEY_LLK";
  74. break;
  75. case ESP_LE_KEY_LENC:
  76. key_str = "ESP_LE_KEY_LENC";
  77. break;
  78. case ESP_LE_KEY_LID:
  79. key_str = "ESP_LE_KEY_LID";
  80. break;
  81. case ESP_LE_KEY_LCSRK:
  82. key_str = "ESP_LE_KEY_LCSRK";
  83. break;
  84. default:
  85. key_str = "INVALID BLE KEY TYPE";
  86. break;
  87. }
  88. return key_str;
  89. }
  90. #endif /* CONFIG_BT_BLE_ENABLED */
  91. void esp_hid_scan_results_free(esp_hid_scan_result_t *results)
  92. {
  93. esp_hid_scan_result_t *r = NULL;
  94. while (results) {
  95. r = results;
  96. results = results->next;
  97. if (r->name != NULL) {
  98. free((char *)r->name);
  99. }
  100. free(r);
  101. }
  102. }
  103. #if (CONFIG_BT_HID_DEVICE_ENABLED || CONFIG_BT_BLE_ENABLED)
  104. static esp_hid_scan_result_t *find_scan_result(esp_bd_addr_t bda, esp_hid_scan_result_t *results)
  105. {
  106. esp_hid_scan_result_t *r = results;
  107. while (r) {
  108. if (memcmp(bda, r->bda, sizeof(esp_bd_addr_t)) == 0) {
  109. return r;
  110. }
  111. r = r->next;
  112. }
  113. return NULL;
  114. }
  115. #endif /* (CONFIG_BT_HID_DEVICE_ENABLED || CONFIG_BT_BLE_ENABLED) */
  116. #if CONFIG_BT_HID_DEVICE_ENABLED
  117. static void add_bt_scan_result(esp_bd_addr_t bda, esp_bt_cod_t *cod, esp_bt_uuid_t *uuid, uint8_t *name, uint8_t name_len, int rssi)
  118. {
  119. esp_hid_scan_result_t *r = find_scan_result(bda, bt_scan_results);
  120. if (r) {
  121. //Some info may come later
  122. if (r->name == NULL && name && name_len) {
  123. char *name_s = (char *)malloc(name_len + 1);
  124. if (name_s == NULL) {
  125. ESP_LOGE(TAG, "Malloc result name failed!");
  126. return;
  127. }
  128. memcpy(name_s, name, name_len);
  129. name_s[name_len] = 0;
  130. r->name = (const char *)name_s;
  131. }
  132. if (r->bt.uuid.len == 0 && uuid->len) {
  133. memcpy(&r->bt.uuid, uuid, sizeof(esp_bt_uuid_t));
  134. }
  135. if (rssi != 0) {
  136. r->rssi = rssi;
  137. }
  138. return;
  139. }
  140. r = (esp_hid_scan_result_t *)malloc(sizeof(esp_hid_scan_result_t));
  141. if (r == NULL) {
  142. ESP_LOGE(TAG, "Malloc bt_hidh_scan_result_t failed!");
  143. return;
  144. }
  145. r->transport = ESP_HID_TRANSPORT_BT;
  146. memcpy(r->bda, bda, sizeof(esp_bd_addr_t));
  147. memcpy(&r->bt.cod, cod, sizeof(esp_bt_cod_t));
  148. memcpy(&r->bt.uuid, uuid, sizeof(esp_bt_uuid_t));
  149. r->usage = esp_hid_usage_from_cod((uint32_t)cod);
  150. r->rssi = rssi;
  151. r->name = NULL;
  152. if (name_len && name) {
  153. char *name_s = (char *)malloc(name_len + 1);
  154. if (name_s == NULL) {
  155. free(r);
  156. ESP_LOGE(TAG, "Malloc result name failed!");
  157. return;
  158. }
  159. memcpy(name_s, name, name_len);
  160. name_s[name_len] = 0;
  161. r->name = (const char *)name_s;
  162. }
  163. r->next = bt_scan_results;
  164. bt_scan_results = r;
  165. num_bt_scan_results++;
  166. }
  167. #endif
  168. #if CONFIG_BT_BLE_ENABLED
  169. static void add_ble_scan_result(esp_bd_addr_t bda, esp_ble_addr_type_t addr_type, uint16_t appearance, uint8_t *name, uint8_t name_len, int rssi)
  170. {
  171. if (find_scan_result(bda, ble_scan_results)) {
  172. ESP_LOGW(TAG, "Result already exists!");
  173. return;
  174. }
  175. esp_hid_scan_result_t *r = (esp_hid_scan_result_t *)malloc(sizeof(esp_hid_scan_result_t));
  176. if (r == NULL) {
  177. ESP_LOGE(TAG, "Malloc ble_hidh_scan_result_t failed!");
  178. return;
  179. }
  180. r->transport = ESP_HID_TRANSPORT_BLE;
  181. memcpy(r->bda, bda, sizeof(esp_bd_addr_t));
  182. r->ble.appearance = appearance;
  183. r->ble.addr_type = addr_type;
  184. r->usage = esp_hid_usage_from_appearance(appearance);
  185. r->rssi = rssi;
  186. r->name = NULL;
  187. if (name_len && name) {
  188. char *name_s = (char *)malloc(name_len + 1);
  189. if (name_s == NULL) {
  190. free(r);
  191. ESP_LOGE(TAG, "Malloc result name failed!");
  192. return;
  193. }
  194. memcpy(name_s, name, name_len);
  195. name_s[name_len] = 0;
  196. r->name = (const char *)name_s;
  197. }
  198. r->next = ble_scan_results;
  199. ble_scan_results = r;
  200. num_ble_scan_results++;
  201. }
  202. #endif /* CONFIG_BT_BLE_ENABLED */
  203. void print_uuid(esp_bt_uuid_t *uuid)
  204. {
  205. if (uuid->len == ESP_UUID_LEN_16) {
  206. GAP_DBG_PRINTF("UUID16: 0x%04x", uuid->uuid.uuid16);
  207. } else if (uuid->len == ESP_UUID_LEN_32) {
  208. GAP_DBG_PRINTF("UUID32: 0x%08x", uuid->uuid.uuid32);
  209. } else if (uuid->len == ESP_UUID_LEN_128) {
  210. GAP_DBG_PRINTF("UUID128: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x", uuid->uuid.uuid128[0],
  211. uuid->uuid.uuid128[1], uuid->uuid.uuid128[2], uuid->uuid.uuid128[3],
  212. uuid->uuid.uuid128[4], uuid->uuid.uuid128[5], uuid->uuid.uuid128[6],
  213. uuid->uuid.uuid128[7], uuid->uuid.uuid128[8], uuid->uuid.uuid128[9],
  214. uuid->uuid.uuid128[10], uuid->uuid.uuid128[11], uuid->uuid.uuid128[12],
  215. uuid->uuid.uuid128[13], uuid->uuid.uuid128[14], uuid->uuid.uuid128[15]);
  216. }
  217. }
  218. #if CONFIG_BT_HID_DEVICE_ENABLED
  219. static void handle_bt_device_result(struct disc_res_param *disc_res)
  220. {
  221. GAP_DBG_PRINTF("BT : " ESP_BD_ADDR_STR, ESP_BD_ADDR_HEX(disc_res->bda));
  222. uint32_t codv = 0;
  223. esp_bt_cod_t *cod = (esp_bt_cod_t *)&codv;
  224. int8_t rssi = 0;
  225. uint8_t *name = NULL;
  226. uint8_t name_len = 0;
  227. esp_bt_uuid_t uuid;
  228. uuid.len = ESP_UUID_LEN_16;
  229. uuid.uuid.uuid16 = 0;
  230. for (int i = 0; i < disc_res->num_prop; i++) {
  231. esp_bt_gap_dev_prop_t *prop = &disc_res->prop[i];
  232. if (prop->type != ESP_BT_GAP_DEV_PROP_EIR) {
  233. GAP_DBG_PRINTF(", %s: ", gap_bt_prop_type_names[prop->type]);
  234. }
  235. if (prop->type == ESP_BT_GAP_DEV_PROP_BDNAME) {
  236. name = (uint8_t *)prop->val;
  237. name_len = strlen((const char *)name);
  238. GAP_DBG_PRINTF("%s", (const char *)name);
  239. } else if (prop->type == ESP_BT_GAP_DEV_PROP_RSSI) {
  240. rssi = *((int8_t *)prop->val);
  241. GAP_DBG_PRINTF("%d", rssi);
  242. } else if (prop->type == ESP_BT_GAP_DEV_PROP_COD) {
  243. memcpy(&codv, prop->val, sizeof(uint32_t));
  244. GAP_DBG_PRINTF("major: %s, minor: %d, service: 0x%03x", esp_hid_cod_major_str(cod->major), cod->minor, cod->service);
  245. } else if (prop->type == ESP_BT_GAP_DEV_PROP_EIR) {
  246. uint8_t len = 0;
  247. uint8_t *data = 0;
  248. data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_16BITS_UUID, &len);
  249. if (data == NULL) {
  250. data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_16BITS_UUID, &len);
  251. }
  252. if (data && len == ESP_UUID_LEN_16) {
  253. uuid.len = ESP_UUID_LEN_16;
  254. uuid.uuid.uuid16 = data[0] + (data[1] << 8);
  255. GAP_DBG_PRINTF(", "); print_uuid(&uuid);
  256. continue;
  257. }
  258. data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_32BITS_UUID, &len);
  259. if (data == NULL) {
  260. data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_32BITS_UUID, &len);
  261. }
  262. if (data && len == ESP_UUID_LEN_32) {
  263. uuid.len = len;
  264. memcpy(&uuid.uuid.uuid32, data, sizeof(uint32_t));
  265. GAP_DBG_PRINTF(", "); print_uuid(&uuid);
  266. continue;
  267. }
  268. data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_128BITS_UUID, &len);
  269. if (data == NULL) {
  270. data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_128BITS_UUID, &len);
  271. }
  272. if (data && len == ESP_UUID_LEN_128) {
  273. uuid.len = len;
  274. memcpy(uuid.uuid.uuid128, (uint8_t *)data, len);
  275. GAP_DBG_PRINTF(", "); print_uuid(&uuid);
  276. continue;
  277. }
  278. //try to find a name
  279. if (name == NULL) {
  280. data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &len);
  281. if (data == NULL) {
  282. data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &len);
  283. }
  284. if (data && len) {
  285. name = data;
  286. name_len = len;
  287. GAP_DBG_PRINTF(", NAME: ");
  288. for (int x = 0; x < len; x++) {
  289. GAP_DBG_PRINTF("%c", (char)data[x]);
  290. }
  291. }
  292. }
  293. }
  294. }
  295. GAP_DBG_PRINTF("\n");
  296. if (cod->major == ESP_BT_COD_MAJOR_DEV_PERIPHERAL || (find_scan_result(disc_res->bda, bt_scan_results) != NULL)) {
  297. add_bt_scan_result(disc_res->bda, cod, &uuid, name, name_len, rssi);
  298. }
  299. }
  300. #endif
  301. #if CONFIG_BT_BLE_ENABLED
  302. static void handle_ble_device_result(struct ble_scan_result_evt_param *scan_rst)
  303. {
  304. uint16_t uuid = 0;
  305. uint16_t appearance = 0;
  306. char name[64] = {0};
  307. uint8_t uuid_len = 0;
  308. uint8_t *uuid_d = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_16SRV_CMPL, &uuid_len);
  309. if (uuid_d != NULL && uuid_len) {
  310. uuid = uuid_d[0] + (uuid_d[1] << 8);
  311. }
  312. uint8_t appearance_len = 0;
  313. uint8_t *appearance_d = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_APPEARANCE, &appearance_len);
  314. if (appearance_d != NULL && appearance_len) {
  315. appearance = appearance_d[0] + (appearance_d[1] << 8);
  316. }
  317. uint8_t adv_name_len = 0;
  318. uint8_t *adv_name = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len);
  319. if (adv_name == NULL) {
  320. adv_name = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_NAME_SHORT, &adv_name_len);
  321. }
  322. if (adv_name != NULL && adv_name_len) {
  323. memcpy(name, adv_name, adv_name_len);
  324. name[adv_name_len] = 0;
  325. }
  326. GAP_DBG_PRINTF("BLE: " ESP_BD_ADDR_STR ", ", ESP_BD_ADDR_HEX(scan_rst->bda));
  327. GAP_DBG_PRINTF("RSSI: %d, ", scan_rst->rssi);
  328. GAP_DBG_PRINTF("UUID: 0x%04x, ", uuid);
  329. GAP_DBG_PRINTF("APPEARANCE: 0x%04x, ", appearance);
  330. GAP_DBG_PRINTF("ADDR_TYPE: '%s'", ble_addr_type_str(scan_rst->ble_addr_type));
  331. if (adv_name_len) {
  332. GAP_DBG_PRINTF(", NAME: '%s'", name);
  333. }
  334. GAP_DBG_PRINTF("\n");
  335. if (uuid == ESP_GATT_UUID_HID_SVC) {
  336. add_ble_scan_result(scan_rst->bda, scan_rst->ble_addr_type, appearance, adv_name, adv_name_len, scan_rst->rssi);
  337. }
  338. }
  339. #endif /* CONFIG_BT_BLE_ENABLED */
  340. #if CONFIG_BT_HID_DEVICE_ENABLED
  341. /*
  342. * BT GAP
  343. * */
  344. static void bt_gap_event_handler(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
  345. {
  346. switch (event) {
  347. case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: {
  348. ESP_LOGV(TAG, "BT GAP DISC_STATE %s", (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) ? "START" : "STOP");
  349. if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) {
  350. SEND_BT_CB();
  351. }
  352. break;
  353. }
  354. case ESP_BT_GAP_DISC_RES_EVT: {
  355. handle_bt_device_result(&param->disc_res);
  356. break;
  357. }
  358. case ESP_BT_GAP_PIN_REQ_EVT: {
  359. ESP_LOGI(TAG, "BT GAP PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit);
  360. if (param->pin_req.min_16_digit) {
  361. ESP_LOGI(TAG, "Input pin code: 0000 0000 0000 0000");
  362. esp_bt_pin_code_t pin_code = {0};
  363. esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code);
  364. } else {
  365. ESP_LOGI(TAG, "Input pin code: 1234");
  366. esp_bt_pin_code_t pin_code;
  367. pin_code[0] = '1';
  368. pin_code[1] = '2';
  369. pin_code[2] = '3';
  370. pin_code[3] = '4';
  371. esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code);
  372. }
  373. break;
  374. }
  375. #if (CONFIG_EXAMPLE_SSP_ENABLED == true)
  376. case ESP_BT_GAP_CFM_REQ_EVT:
  377. ESP_LOGI(TAG, "BT GAP CFM_REQ_EVT Please compare the numeric value: %" PRIu32,
  378. param->cfm_req.num_val);
  379. esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
  380. break;
  381. case ESP_BT_GAP_KEY_NOTIF_EVT:
  382. ESP_LOGI(TAG, "BT GAP KEY_NOTIF_EVT passkey:%" PRIu32, param->key_notif.passkey);
  383. break;
  384. case ESP_BT_GAP_KEY_REQ_EVT:
  385. ESP_LOGI(TAG, "BT GAP KEY_REQ_EVT Please enter passkey!");
  386. break;
  387. #endif
  388. case ESP_BT_GAP_MODE_CHG_EVT:
  389. ESP_LOGI(TAG, "BT GAP MODE_CHG_EVT mode:%d", param->mode_chg.mode);
  390. break;
  391. default:
  392. ESP_LOGV(TAG, "BT GAP EVENT %s", bt_gap_evt_str(event));
  393. break;
  394. }
  395. }
  396. static esp_err_t init_bt_gap(void)
  397. {
  398. esp_err_t ret;
  399. #if (CONFIG_EXAMPLE_SSP_ENABLED)
  400. /* Set default parameters for Secure Simple Pairing */
  401. esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
  402. esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_NONE;
  403. esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
  404. #endif
  405. /*
  406. * Set default parameters for Legacy Pairing
  407. * Use fixed pin code
  408. */
  409. esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED;
  410. esp_bt_pin_code_t pin_code;
  411. pin_code[0] = '1';
  412. pin_code[1] = '2';
  413. pin_code[2] = '3';
  414. pin_code[3] = '4';
  415. esp_bt_gap_set_pin(pin_type, 4, pin_code);
  416. if ((ret = esp_bt_gap_register_callback(bt_gap_event_handler)) != ESP_OK) {
  417. ESP_LOGE(TAG, "esp_bt_gap_register_callback failed: %d", ret);
  418. return ret;
  419. }
  420. // Allow BT devices to connect back to us
  421. if ((ret = esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE)) != ESP_OK) {
  422. ESP_LOGE(TAG, "esp_bt_gap_set_scan_mode failed: %d", ret);
  423. return ret;
  424. }
  425. return ret;
  426. }
  427. static esp_err_t start_bt_scan(uint32_t seconds)
  428. {
  429. esp_err_t ret = ESP_OK;
  430. if ((ret = esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, (int)(seconds / 1.28), 0)) != ESP_OK) {
  431. ESP_LOGE(TAG, "esp_bt_gap_start_discovery failed: %d", ret);
  432. return ret;
  433. }
  434. return ret;
  435. }
  436. #endif
  437. #if CONFIG_BT_BLE_ENABLED
  438. /*
  439. * BLE GAP
  440. * */
  441. extern void ble_hid_task_start_up(void);
  442. static void ble_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
  443. {
  444. switch (event) {
  445. /*
  446. * SCAN
  447. * */
  448. case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: {
  449. ESP_LOGV(TAG, "BLE GAP EVENT SCAN_PARAM_SET_COMPLETE");
  450. SEND_BLE_CB();
  451. break;
  452. }
  453. case ESP_GAP_BLE_SCAN_RESULT_EVT: {
  454. esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param;
  455. switch (scan_result->scan_rst.search_evt) {
  456. case ESP_GAP_SEARCH_INQ_RES_EVT: {
  457. handle_ble_device_result(&scan_result->scan_rst);
  458. break;
  459. }
  460. case ESP_GAP_SEARCH_INQ_CMPL_EVT:
  461. ESP_LOGV(TAG, "BLE GAP EVENT SCAN DONE: %d", scan_result->scan_rst.num_resps);
  462. SEND_BLE_CB();
  463. break;
  464. default:
  465. break;
  466. }
  467. break;
  468. }
  469. case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: {
  470. ESP_LOGV(TAG, "BLE GAP EVENT SCAN CANCELED");
  471. break;
  472. }
  473. /*
  474. * ADVERTISEMENT
  475. * */
  476. case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
  477. ESP_LOGV(TAG, "BLE GAP ADV_DATA_SET_COMPLETE");
  478. break;
  479. case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
  480. ESP_LOGV(TAG, "BLE GAP ADV_START_COMPLETE");
  481. break;
  482. /*
  483. * AUTHENTICATION
  484. * */
  485. case ESP_GAP_BLE_AUTH_CMPL_EVT:
  486. if (!param->ble_security.auth_cmpl.success) {
  487. // if AUTH ERROR,hid maybe don't work.
  488. ESP_LOGE(TAG, "BLE GAP AUTH ERROR: 0x%x", param->ble_security.auth_cmpl.fail_reason);
  489. } else {
  490. ESP_LOGI(TAG, "BLE GAP AUTH SUCCESS");
  491. }
  492. ble_hid_task_start_up();
  493. break;
  494. case ESP_GAP_BLE_KEY_EVT: //shows the ble key info share with peer device to the user.
  495. ESP_LOGI(TAG, "BLE GAP KEY type = %s", esp_ble_key_type_str(param->ble_security.ble_key.key_type));
  496. break;
  497. case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: // ESP_IO_CAP_OUT
  498. // The app will receive this evt when the IO has Output capability and the peer device IO has Input capability.
  499. // Show the passkey number to the user to input it in the peer device.
  500. ESP_LOGI(TAG, "BLE GAP PASSKEY_NOTIF passkey:%"PRIu32, param->ble_security.key_notif.passkey);
  501. break;
  502. case ESP_GAP_BLE_NC_REQ_EVT: // ESP_IO_CAP_IO
  503. // The app will receive this event when the IO has DisplayYesNO capability and the peer device IO also has DisplayYesNo capability.
  504. // show the passkey number to the user to confirm it with the number displayed by peer device.
  505. ESP_LOGI(TAG, "BLE GAP NC_REQ passkey:%"PRIu32, param->ble_security.key_notif.passkey);
  506. esp_ble_confirm_reply(param->ble_security.key_notif.bd_addr, true);
  507. break;
  508. case ESP_GAP_BLE_PASSKEY_REQ_EVT: // ESP_IO_CAP_IN
  509. // The app will receive this evt when the IO has Input capability and the peer device IO has Output capability.
  510. // See the passkey number on the peer device and send it back.
  511. ESP_LOGI(TAG, "BLE GAP PASSKEY_REQ");
  512. //esp_ble_passkey_reply(param->ble_security.ble_req.bd_addr, true, 1234);
  513. break;
  514. case ESP_GAP_BLE_SEC_REQ_EVT:
  515. ESP_LOGI(TAG, "BLE GAP SEC_REQ");
  516. // Send the positive(true) security response to the peer device to accept the security request.
  517. // If not accept the security request, should send the security response with negative(false) accept value.
  518. esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
  519. break;
  520. default:
  521. ESP_LOGV(TAG, "BLE GAP EVENT %s", ble_gap_evt_str(event));
  522. break;
  523. }
  524. }
  525. static esp_err_t init_ble_gap(void)
  526. {
  527. esp_err_t ret;
  528. if ((ret = esp_ble_gap_register_callback(ble_gap_event_handler)) != ESP_OK) {
  529. ESP_LOGE(TAG, "esp_ble_gap_register_callback failed: %d", ret);
  530. return ret;
  531. }
  532. return ret;
  533. }
  534. static esp_ble_scan_params_t hid_scan_params = {
  535. .scan_type = BLE_SCAN_TYPE_ACTIVE,
  536. .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
  537. .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
  538. .scan_interval = 0x50,
  539. .scan_window = 0x30,
  540. .scan_duplicate = BLE_SCAN_DUPLICATE_ENABLE,
  541. };
  542. static esp_err_t start_ble_scan(uint32_t seconds)
  543. {
  544. esp_err_t ret = ESP_OK;
  545. if ((ret = esp_ble_gap_set_scan_params(&hid_scan_params)) != ESP_OK) {
  546. ESP_LOGE(TAG, "esp_ble_gap_set_scan_params failed: %d", ret);
  547. return ret;
  548. }
  549. WAIT_BLE_CB();
  550. if ((ret = esp_ble_gap_start_scanning(seconds)) != ESP_OK) {
  551. ESP_LOGE(TAG, "esp_ble_gap_start_scanning failed: %d", ret);
  552. return ret;
  553. }
  554. return ret;
  555. }
  556. esp_err_t esp_hid_ble_gap_adv_init(uint16_t appearance, const char *device_name)
  557. {
  558. esp_err_t ret;
  559. const uint8_t hidd_service_uuid128[] = {
  560. 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x12, 0x18, 0x00, 0x00,
  561. };
  562. esp_ble_adv_data_t ble_adv_data = {
  563. .set_scan_rsp = false,
  564. .include_name = true,
  565. .include_txpower = true,
  566. .min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec
  567. .max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec
  568. .appearance = appearance,
  569. .manufacturer_len = 0,
  570. .p_manufacturer_data = NULL,
  571. .service_data_len = 0,
  572. .p_service_data = NULL,
  573. .service_uuid_len = sizeof(hidd_service_uuid128),
  574. .p_service_uuid = (uint8_t *)hidd_service_uuid128,
  575. .flag = 0x6,
  576. };
  577. esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND;
  578. //esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT;//you have to enter the key on the host
  579. //esp_ble_io_cap_t iocap = ESP_IO_CAP_IN;//you have to enter the key on the device
  580. esp_ble_io_cap_t iocap = ESP_IO_CAP_IO;//you have to agree that key matches on both
  581. //esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE;//device is not capable of input or output, unsecure
  582. uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
  583. uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
  584. uint8_t key_size = 16; //the key size should be 7~16 bytes
  585. uint32_t passkey = 1234;//ESP_IO_CAP_OUT
  586. if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, 1)) != ESP_OK) {
  587. ESP_LOGE(TAG, "GAP set_security_param AUTHEN_REQ_MODE failed: %d", ret);
  588. return ret;
  589. }
  590. if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, 1)) != ESP_OK) {
  591. ESP_LOGE(TAG, "GAP set_security_param IOCAP_MODE failed: %d", ret);
  592. return ret;
  593. }
  594. if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, 1)) != ESP_OK) {
  595. ESP_LOGE(TAG, "GAP set_security_param SET_INIT_KEY failed: %d", ret);
  596. return ret;
  597. }
  598. if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, 1)) != ESP_OK) {
  599. ESP_LOGE(TAG, "GAP set_security_param SET_RSP_KEY failed: %d", ret);
  600. return ret;
  601. }
  602. if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, 1)) != ESP_OK) {
  603. ESP_LOGE(TAG, "GAP set_security_param MAX_KEY_SIZE failed: %d", ret);
  604. return ret;
  605. }
  606. if ((ret = esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t))) != ESP_OK) {
  607. ESP_LOGE(TAG, "GAP set_security_param SET_STATIC_PASSKEY failed: %d", ret);
  608. return ret;
  609. }
  610. if ((ret = esp_ble_gap_set_device_name(device_name)) != ESP_OK) {
  611. ESP_LOGE(TAG, "GAP set_device_name failed: %d", ret);
  612. return ret;
  613. }
  614. if ((ret = esp_ble_gap_config_adv_data(&ble_adv_data)) != ESP_OK) {
  615. ESP_LOGE(TAG, "GAP config_adv_data failed: %d", ret);
  616. return ret;
  617. }
  618. return ret;
  619. }
  620. esp_err_t esp_hid_ble_gap_adv_start(void)
  621. {
  622. static esp_ble_adv_params_t hidd_adv_params = {
  623. .adv_int_min = 0x20,
  624. .adv_int_max = 0x30,
  625. .adv_type = ADV_TYPE_IND,
  626. .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
  627. .channel_map = ADV_CHNL_ALL,
  628. .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
  629. };
  630. return esp_ble_gap_start_advertising(&hidd_adv_params);
  631. }
  632. #endif /* CONFIG_BT_BLE_ENABLED */
  633. /*
  634. * CONTROLLER INIT
  635. * */
  636. static esp_err_t init_low_level(uint8_t mode)
  637. {
  638. esp_err_t ret;
  639. esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
  640. #if CONFIG_IDF_TARGET_ESP32
  641. bt_cfg.mode = mode;
  642. #endif
  643. #if CONFIG_BT_HID_DEVICE_ENABLED
  644. if (mode & ESP_BT_MODE_CLASSIC_BT) {
  645. bt_cfg.bt_max_acl_conn = 3;
  646. bt_cfg.bt_max_sync_conn = 3;
  647. } else
  648. #endif
  649. {
  650. ret = esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
  651. if (ret) {
  652. ESP_LOGE(TAG, "esp_bt_controller_mem_release failed: %d", ret);
  653. return ret;
  654. }
  655. }
  656. ret = esp_bt_controller_init(&bt_cfg);
  657. if (ret) {
  658. ESP_LOGE(TAG, "esp_bt_controller_init failed: %d", ret);
  659. return ret;
  660. }
  661. ret = esp_bt_controller_enable(mode);
  662. if (ret) {
  663. ESP_LOGE(TAG, "esp_bt_controller_enable failed: %d", ret);
  664. return ret;
  665. }
  666. esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT();
  667. #if (CONFIG_EXAMPLE_SSP_ENABLED == false)
  668. bluedroid_cfg.ssp_en = false;
  669. #endif
  670. ret = esp_bluedroid_init_with_cfg(&bluedroid_cfg);
  671. if (ret) {
  672. ESP_LOGE(TAG, "esp_bluedroid_init failed: %d", ret);
  673. return ret;
  674. }
  675. ret = esp_bluedroid_enable();
  676. if (ret) {
  677. ESP_LOGE(TAG, "esp_bluedroid_enable failed: %d", ret);
  678. return ret;
  679. }
  680. #if CONFIG_BT_HID_DEVICE_ENABLED
  681. if (mode & ESP_BT_MODE_CLASSIC_BT) {
  682. ret = init_bt_gap();
  683. if (ret) {
  684. return ret;
  685. }
  686. }
  687. #endif
  688. #if CONFIG_BT_BLE_ENABLED
  689. if (mode & ESP_BT_MODE_BLE) {
  690. ret = init_ble_gap();
  691. if (ret) {
  692. return ret;
  693. }
  694. }
  695. #endif /* CONFIG_BT_BLE_ENABLED */
  696. return ret;
  697. }
  698. esp_err_t esp_hid_gap_init(uint8_t mode)
  699. {
  700. esp_err_t ret;
  701. if (!mode || mode > ESP_BT_MODE_BTDM) {
  702. ESP_LOGE(TAG, "Invalid mode given!");
  703. return ESP_FAIL;
  704. }
  705. if (bt_hidh_cb_semaphore != NULL) {
  706. ESP_LOGE(TAG, "Already initialised");
  707. return ESP_FAIL;
  708. }
  709. bt_hidh_cb_semaphore = xSemaphoreCreateBinary();
  710. if (bt_hidh_cb_semaphore == NULL) {
  711. ESP_LOGE(TAG, "xSemaphoreCreateMutex failed!");
  712. return ESP_FAIL;
  713. }
  714. ble_hidh_cb_semaphore = xSemaphoreCreateBinary();
  715. if (ble_hidh_cb_semaphore == NULL) {
  716. ESP_LOGE(TAG, "xSemaphoreCreateMutex failed!");
  717. vSemaphoreDelete(bt_hidh_cb_semaphore);
  718. bt_hidh_cb_semaphore = NULL;
  719. return ESP_FAIL;
  720. }
  721. ret = init_low_level(mode);
  722. if (ret != ESP_OK) {
  723. vSemaphoreDelete(bt_hidh_cb_semaphore);
  724. bt_hidh_cb_semaphore = NULL;
  725. vSemaphoreDelete(ble_hidh_cb_semaphore);
  726. ble_hidh_cb_semaphore = NULL;
  727. return ret;
  728. }
  729. return ESP_OK;
  730. }
  731. esp_err_t esp_hid_scan(uint32_t seconds, size_t *num_results, esp_hid_scan_result_t **results)
  732. {
  733. if (num_bt_scan_results || bt_scan_results || num_ble_scan_results || ble_scan_results) {
  734. ESP_LOGE(TAG, "There are old scan results. Free them first!");
  735. return ESP_FAIL;
  736. }
  737. #if CONFIG_BT_BLE_ENABLED
  738. if (start_ble_scan(seconds) == ESP_OK) {
  739. WAIT_BLE_CB();
  740. } else {
  741. return ESP_FAIL;
  742. }
  743. #endif /* CONFIG_BT_BLE_ENABLED */
  744. #if CONFIG_BT_HID_DEVICE_ENABLED
  745. if (start_bt_scan(seconds) == ESP_OK) {
  746. WAIT_BT_CB();
  747. } else {
  748. return ESP_FAIL;
  749. }
  750. #endif
  751. *num_results = num_bt_scan_results + num_ble_scan_results;
  752. *results = bt_scan_results;
  753. if (num_bt_scan_results) {
  754. while (bt_scan_results->next != NULL) {
  755. bt_scan_results = bt_scan_results->next;
  756. }
  757. bt_scan_results->next = ble_scan_results;
  758. } else {
  759. *results = ble_scan_results;
  760. }
  761. num_bt_scan_results = 0;
  762. bt_scan_results = NULL;
  763. num_ble_scan_results = 0;
  764. ble_scan_results = NULL;
  765. return ESP_OK;
  766. }