esp_hid_gap.c 28 KB

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