diff --git a/components/bt/bluedroid/api/esp_gap_ble_api.c b/components/bt/bluedroid/api/esp_gap_ble_api.c index ccce399ae3..521f748b1a 100644 --- a/components/bt/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/bluedroid/api/esp_gap_ble_api.c @@ -24,9 +24,8 @@ esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback) { - if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + return (btc_profile_cb_set(BTC_PID_GAP_BLE, callback) == 0 ? ESP_OK : ESP_FAIL); } @@ -36,10 +35,8 @@ esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data) btc_msg_t msg; btc_ble_gap_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } - + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (adv_data == NULL) { return ESP_ERR_INVALID_ARG; } @@ -63,10 +60,8 @@ esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params) btc_msg_t msg; btc_ble_gap_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } - + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (scan_params == NULL) { return ESP_ERR_INVALID_ARG; } @@ -84,9 +79,7 @@ esp_err_t esp_ble_gap_start_scanning(uint32_t duration) btc_msg_t msg; btc_ble_gap_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; @@ -101,10 +94,8 @@ esp_err_t esp_ble_gap_stop_scanning(void) { btc_msg_t msg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } - + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_ACT_STOP_SCAN; @@ -116,10 +107,8 @@ esp_err_t esp_ble_gap_start_advertising(esp_ble_adv_params_t *adv_params) btc_msg_t msg; btc_ble_gap_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } - + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_ACT_START_ADV; @@ -132,10 +121,8 @@ esp_err_t esp_ble_gap_stop_advertising(void) { btc_msg_t msg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } - + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_ACT_STOP_ADV; @@ -149,10 +136,8 @@ esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params) btc_msg_t msg; btc_ble_gap_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } - + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_ACT_UPDATE_CONN_PARAM; @@ -166,10 +151,8 @@ esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_ btc_msg_t msg; btc_ble_gap_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } - + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN; @@ -185,10 +168,8 @@ esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr) btc_msg_t msg; btc_ble_gap_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } - + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_ACT_SET_RAND_ADDRESS; @@ -203,10 +184,8 @@ esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable) btc_msg_t msg; btc_ble_gap_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } - + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY; @@ -217,6 +196,8 @@ esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable) esp_err_t esp_ble_gap_set_device_name(const char *name) { + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + return esp_bt_dev_set_device_name(name); } @@ -241,9 +222,7 @@ esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_l btc_msg_t msg; btc_ble_gap_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); if (raw_data == NULL || (raw_data_len <= 0 || raw_data_len > ESP_BLE_ADV_DATA_LEN_MAX)) { @@ -265,9 +244,7 @@ esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_d btc_msg_t msg; btc_ble_gap_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); if (raw_data == NULL || (raw_data_len <= 0 || raw_data_len > ESP_BLE_SCAN_RSP_DATA_LEN_MAX)) { @@ -291,6 +268,8 @@ esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type, btc_msg_t msg; btc_ble_gap_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_SET_SECURITY_PARAM_EVT; @@ -307,6 +286,8 @@ esp_err_t esp_ble_set_encryption(esp_bd_addr_t bd_addr, esp_ble_sec_act_t sec_ac btc_msg_t msg; btc_ble_gap_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_SET_ENCRYPTION_EVT; @@ -321,6 +302,9 @@ esp_err_t esp_ble_gap_security_rsp(esp_bd_addr_t bd_addr, bool accept) { btc_msg_t msg; btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_SECURITY_RSP_EVT; @@ -337,6 +321,8 @@ esp_err_t esp_ble_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t pas btc_msg_t msg; btc_ble_gap_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_PASSKEY_REPLY_EVT; @@ -353,6 +339,8 @@ esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept) btc_msg_t msg; btc_ble_gap_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_CONFIRM_REPLY_EVT; @@ -363,14 +351,47 @@ esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr) +{ + btc_msg_t msg; + btc_ble_gap_args_t arg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_REMOVE_BOND_DEV_EVT; + memcpy(arg.remove_bond_device.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_clear_bond_device_list(void) +{ + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_CLEAR_BOND_DEV_EVT; + + return (btc_transfer_context(&msg, NULL, 0, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_get_bond_device_list(void) +{ + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_GET_BOND_DEV_EVT; + + return (btc_transfer_context(&msg, NULL, 0, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device) { btc_msg_t msg; btc_ble_gap_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; diff --git a/components/bt/bluedroid/api/esp_gattc_api.c b/components/bt/bluedroid/api/esp_gattc_api.c index b80966cd86..b58c408f80 100644 --- a/components/bt/bluedroid/api/esp_gattc_api.c +++ b/components/bt/bluedroid/api/esp_gattc_api.c @@ -23,9 +23,7 @@ #if (GATTC_INCLUDED == TRUE) esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback) { - if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); if (callback == NULL) { return ESP_FAIL; @@ -40,9 +38,7 @@ esp_err_t esp_ble_gattc_app_register(uint16_t app_id) btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); if (app_id > ESP_APP_ID_MAX) { return ESP_ERR_INVALID_ARG; @@ -61,9 +57,7 @@ esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gattc_if) btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -78,9 +72,7 @@ esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, b btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -97,9 +89,7 @@ esp_err_t esp_ble_gattc_close (esp_gatt_if_t gattc_if, uint16_t conn_id) btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -114,9 +104,7 @@ esp_err_t esp_ble_gattc_config_mtu (esp_gatt_if_t gattc_if, uint16_t conn_id, ui btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); if ((mtu < ESP_GATT_DEF_BLE_MTU_SIZE) || (mtu > ESP_GATT_MAX_MTU_SIZE)) { return ESP_GATT_ILLEGAL_PARAMETER; @@ -136,9 +124,7 @@ esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -163,9 +149,7 @@ esp_err_t esp_ble_gattc_get_characteristic(esp_gatt_if_t gattc_if, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -192,9 +176,7 @@ esp_err_t esp_ble_gattc_get_descriptor(esp_gatt_if_t gattc_if, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -223,9 +205,7 @@ esp_err_t esp_ble_gattc_get_included_service(esp_gatt_if_t gattc_if, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -253,9 +233,7 @@ esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -278,9 +256,7 @@ esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -306,9 +282,7 @@ esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -337,9 +311,7 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -368,9 +340,7 @@ esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -399,9 +369,7 @@ esp_err_t esp_ble_gattc_prepare_write_char_descr(esp_gatt_if_t gattc_if, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -423,9 +391,7 @@ esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -436,7 +402,7 @@ esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id, return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } -esp_gatt_status_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if, +esp_err_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if, esp_bd_addr_t server_bda, esp_gatt_srvc_id_t *srvc_id, esp_gatt_id_t *char_id) @@ -444,9 +410,7 @@ esp_gatt_status_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -459,7 +423,7 @@ esp_gatt_status_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if, return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } -esp_gatt_status_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if, +esp_err_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if, esp_bd_addr_t server_bda, esp_gatt_srvc_id_t *srvc_id, esp_gatt_id_t *char_id) @@ -467,9 +431,7 @@ esp_gatt_status_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if, btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; @@ -487,9 +449,7 @@ esp_err_t esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda) btc_msg_t msg; btc_ble_gattc_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTC; diff --git a/components/bt/bluedroid/api/esp_gatts_api.c b/components/bt/bluedroid/api/esp_gatts_api.c index 802256f775..4d2a6f5f8e 100644 --- a/components/bt/bluedroid/api/esp_gatts_api.c +++ b/components/bt/bluedroid/api/esp_gatts_api.c @@ -28,9 +28,8 @@ static esp_err_t esp_ble_gatts_add_char_desc_param_check(esp_attr_value_t *char_ esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback) { - if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + return (btc_profile_cb_set(BTC_PID_GATTS, callback) == 0 ? ESP_OK : ESP_FAIL); } @@ -39,9 +38,7 @@ esp_err_t esp_ble_gatts_app_register(uint16_t app_id) btc_msg_t msg; btc_ble_gatts_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); //if (app_id < ESP_APP_ID_MIN || app_id > ESP_APP_ID_MAX) { if (app_id > ESP_APP_ID_MAX) { @@ -62,9 +59,7 @@ esp_err_t esp_ble_gatts_app_unregister(esp_gatt_if_t gatts_if) btc_msg_t msg; btc_ble_gatts_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; @@ -80,9 +75,7 @@ esp_err_t esp_ble_gatts_create_service(esp_gatt_if_t gatts_if, btc_msg_t msg; btc_ble_gatts_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; @@ -102,6 +95,8 @@ esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db btc_msg_t msg; btc_ble_gatts_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; msg.act = BTC_GATTS_ACT_CREATE_ATTR_TAB; @@ -120,9 +115,7 @@ esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t i btc_msg_t msg; btc_ble_gatts_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; @@ -142,9 +135,7 @@ esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_ btc_ble_gatts_args_t arg; esp_err_t status; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); /* parameter validation check */ status = esp_ble_gatts_add_char_desc_param_check(char_val, control); @@ -183,9 +174,7 @@ esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle, btc_ble_gatts_args_t arg; esp_err_t status; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); /* parameter validation check */ status = esp_ble_gatts_add_char_desc_param_check(char_descr_val, control); @@ -219,9 +208,7 @@ esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle) btc_msg_t msg; btc_ble_gatts_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; @@ -236,9 +223,7 @@ esp_err_t esp_ble_gatts_start_service(uint16_t service_handle) btc_msg_t msg; btc_ble_gatts_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; @@ -253,9 +238,7 @@ esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle) btc_msg_t msg; btc_ble_gatts_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; @@ -272,9 +255,7 @@ esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id, btc_msg_t msg; btc_ble_gatts_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; @@ -295,9 +276,7 @@ esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id, btc_msg_t msg; btc_ble_gatts_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; @@ -316,6 +295,8 @@ esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, co btc_msg_t msg; btc_ble_gatts_args_t arg; + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; msg.act = BTC_GATTS_ACT_SET_ATTR_VALUE; @@ -327,13 +308,15 @@ esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, co btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } -esp_err_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value) +esp_gatt_status_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value) { + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + if (attr_handle == ESP_GATT_ILLEGAL_HANDLE) { - return ESP_FAIL; + return ESP_GATT_INVALID_HANDLE; } - btc_gatts_get_attr_value(attr_handle, length, (uint8_t **)value); - return ESP_OK; + + return btc_gatts_get_attr_value(attr_handle, length, (uint8_t **)value); } esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, bool is_direct) @@ -341,9 +324,7 @@ esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, b btc_msg_t msg; btc_ble_gatts_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; @@ -361,9 +342,7 @@ esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id) btc_msg_t msg; btc_ble_gatts_args_t arg; - if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { - return ESP_ERR_INVALID_STATE; - } + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; diff --git a/components/bt/bluedroid/api/include/esp_bt_defs.h b/components/bt/bluedroid/api/include/esp_bt_defs.h index e2b9553b3f..8259046e83 100644 --- a/components/bt/bluedroid/api/include/esp_bt_defs.h +++ b/components/bt/bluedroid/api/include/esp_bt_defs.h @@ -22,6 +22,12 @@ extern "C" { #endif +#define ESP_BLUEDROID_STATUS_CHECK(status) \ + if (esp_bluedroid_get_status() != (status)) { \ + return ESP_ERR_INVALID_STATE; \ + } + + /* relate to BT_STATUS_xxx in bt_def.h */ /// Status Return Value typedef enum { @@ -107,6 +113,7 @@ typedef enum { #define ESP_BLE_CSR_KEY_MASK (1 << 2) /* relate to BTM_BLE_CSR_KEY_MASK in btm_api.h */ /// Used to exchange the link key(this key just used in the BLE & BR/EDR coexist mode) in the init key & response key #define ESP_BLE_LINK_KEY_MASK (1 << 3) /* relate to BTM_BLE_LINK_KEY_MASK in btm_api.h */ +typedef uint8_t esp_ble_key_mask_t; /* the key mask type */ /// Minimum of the application id #define ESP_APP_ID_MIN 0x0000 diff --git a/components/bt/bluedroid/api/include/esp_gap_ble_api.h b/components/bt/bluedroid/api/include/esp_gap_ble_api.h index 0492bd5d84..a7cafcd35e 100644 --- a/components/bt/bluedroid/api/include/esp_gap_ble_api.h +++ b/components/bt/bluedroid/api/include/esp_gap_ble_api.h @@ -93,6 +93,11 @@ typedef enum { ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT, /*!< When set the static rand address complete, the event comes */ ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT, /*!< When update connection parameters complete, the event comes */ ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT, /*!< When set pkt lenght complete, the event comes */ + ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT, /*!< When Enable/disable privacy on the local device complete, the event comes */ + ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT, /*!< When remove the bond device complete, the event comes */ + ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT, /*!< When clear the bond device clear complete, the event comes */ + ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT, /*!< When get the bond device list complete, the event comes */ + ESP_GAP_BLE_EVT_MAX, } esp_gap_ble_cb_event_t; /// Advertising data maximum length @@ -293,7 +298,7 @@ typedef struct uint16_t ediv; /*!< The ediv value*/ uint8_t sec_level; /*!< The security level of the security link*/ uint8_t key_size; /*!< The key size(7~16) of the security link*/ -}esp_ble_penc_keys_t; /*!< The key type*/ +} esp_ble_penc_keys_t; /*!< The key type*/ /** * @brief BLE CSRK keys @@ -303,7 +308,7 @@ typedef struct uint32_t counter; /*!< The counter */ esp_bt_octet16_t csrk; /*!< The csrk key */ uint8_t sec_level; /*!< The security level */ -}esp_ble_pcsrk_keys_t; /*!< The pcsrk key type */ +} esp_ble_pcsrk_keys_t; /*!< The pcsrk key type */ /** * @brief BLE pid keys @@ -313,7 +318,7 @@ typedef struct esp_bt_octet16_t irk; /*!< The irk value */ esp_ble_addr_type_t addr_type; /*!< The address type */ esp_bd_addr_t static_addr; /*!< The static address */ -}esp_ble_pid_keys_t; /*!< The pid key type */ +} esp_ble_pid_keys_t; /*!< The pid key type */ /** * @brief BLE Encryption reproduction keys @@ -324,7 +329,7 @@ typedef struct uint16_t div; /*!< The div value */ uint8_t key_size; /*!< The key size of the security link */ uint8_t sec_level; /*!< The security level of the security link */ -}esp_ble_lenc_keys_t; /*!< The key type */ +} esp_ble_lenc_keys_t; /*!< The key type */ /** * @brief BLE SRK keys @@ -334,8 +339,8 @@ typedef struct uint32_t counter; /*!< The counter value */ uint16_t div; /*!< The div value */ uint8_t sec_level; /*!< The security level of the security link */ - esp_bt_octet16_t csrk; /*!< The csrk key value */ -}esp_ble_lcsrk_keys; /*!< The csrk key type */ + esp_bt_octet16_t csrk; /*!< The csrk key value */ +} esp_ble_lcsrk_keys; /*!< The csrk key type */ /** * @brief Structure associated with ESP_KEY_NOTIF_EVT @@ -352,7 +357,7 @@ typedef struct typedef struct { esp_bd_addr_t bd_addr; /*!< peer address */ -}esp_ble_sec_req_t; /*!< BLE security request type*/ +} esp_ble_sec_req_t; /*!< BLE security request type*/ /** * @brief union type of the security key value @@ -364,7 +369,27 @@ typedef union esp_ble_pid_keys_t pid_key; /*!< peer device ID key */ esp_ble_lenc_keys_t lenc_key; /*!< local encryption reproduction keys LTK = = d1(ER,DIV,0)*/ esp_ble_lcsrk_keys lcsrk_key; /*!< local device CSRK = d1(ER,DIV,1)*/ -}esp_ble_key_value_t; /*!< ble key value type*/ +} esp_ble_key_value_t; /*!< ble key value type*/ + +/** +* @brief struct type of the bond key informatuon value +*/ +typedef struct +{ + esp_ble_key_mask_t key_mask; /*!< the key mask to indicate witch key is present */ + esp_ble_penc_keys_t penc_key; /*!< received peer encryption key */ + esp_ble_pcsrk_keys_t pcsrk_key; /*!< received peer device SRK */ + esp_ble_pid_keys_t pid_key; /*!< peer device ID key */ +} esp_ble_bond_key_info_t; /*!< ble bond key information value type */ + +/** +* @brief struct type of the bond device value +*/ +typedef struct +{ + esp_bd_addr_t bd_addr; /*!< peer address */ + esp_ble_bond_key_info_t bond_key; /*!< the bond key information */ +} esp_ble_bond_dev_t; /*!< the ble bond device type */ /** @@ -375,7 +400,7 @@ typedef struct esp_bd_addr_t bd_addr; /*!< peer address */ esp_ble_key_type_t key_type; /*!< key type of the security link */ esp_ble_key_value_t p_key_value; /*!< the pointer to the key value */ -}esp_ble_key_t; /*!< the union to the ble key value type*/ +} esp_ble_key_t; /*!< the union to the ble key value type*/ /** * @brief structure type of the ble local id keys value @@ -384,7 +409,7 @@ typedef struct { esp_bt_octet16_t ir; /*!< the 16 bits of the ir value */ esp_bt_octet16_t irk; /*!< the 16 bits of the ir key value */ esp_bt_octet16_t dhk; /*!< the 16 bits of the dh key value */ -}esp_ble_local_id_keys_t; /*!< the structure of the ble local id keys value type*/ +} esp_ble_local_id_keys_t; /*!< the structure of the ble local id keys value type*/ /** @@ -400,7 +425,7 @@ typedef struct uint8_t fail_reason; /*!< The HCI reason/error code for when success=FALSE */ esp_ble_addr_type_t addr_type; /*!< Peer device address type */ esp_bt_dev_type_t dev_type; /*!< Device type */ -}esp_ble_auth_cmpl_t; /*!< The ble authentication complite cb type */ +} esp_ble_auth_cmpl_t; /*!< The ble authentication complite cb type */ /** * @brief union associated with ble security @@ -412,7 +437,7 @@ typedef union esp_ble_key_t ble_key; /*!< BLE SMP keys used when pairing */ esp_ble_local_id_keys_t ble_id_keys; /*!< BLE IR event */ esp_ble_auth_cmpl_t auth_cmpl; /*!< Authentication complete indication. */ -}esp_ble_sec_t; /*!< Ble secutity type */ +} esp_ble_sec_t; /*!< Ble secutity type */ /// Sub Event of ESP_GAP_BLE_SCAN_RESULT_EVT typedef enum { @@ -539,6 +564,33 @@ typedef union { esp_bt_status_t status; /*!< Indicate the set pkt data length operation success status */ esp_ble_pkt_data_length_params_t params; /*!< pkt data length value */ } pkt_data_lenth_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT + */ + struct ble_local_privacy_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the set local privacy operation success status */ + } local_privacy_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT + */ + struct ble_remove_bond_dev_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the remove bond device operation success status */ + esp_bd_addr_t bd_addr; /*!< The device address which has been remove from the bond list */ + }remove_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT + */ + struct ble_clear_bond_dev_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the clear bond device operation success status */ + }clear_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT + */ + struct ble_get_bond_dev_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the get bond device operation success status */ + uint8_t dev_num; /*!< Indicate the get number device in the bond list */ + esp_ble_bond_dev_t *bond_dev; /*!< the pointer to the bond device Structure */ + }get_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT */ } esp_ble_gap_cb_param_t; /** @@ -814,6 +866,38 @@ esp_err_t esp_ble_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t pas */ esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept); +/** +* @brief Removes a device from the security database list of +* peer device. It manages unpairing event while connected. +* +* @param[in] bd_addr : BD address of the peer device +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr); + +/** +* @brief Removes all of the device from the security database list of +* peer device. It manages unpairing event while connected. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_clear_bond_device_list(void); + +/** +* @brief Get the device from the security database list of peer device. +* It will return the device bonded information from the ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT event. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_get_bond_device_list(void); + /** * @brief This function is to disconnect the physical connection of the peer device * diff --git a/components/bt/bluedroid/api/include/esp_gattc_api.h b/components/bt/bluedroid/api/include/esp_gattc_api.h index 6e6f9396a5..f28736e3bc 100644 --- a/components/bt/bluedroid/api/include/esp_gattc_api.h +++ b/components/bt/bluedroid/api/include/esp_gattc_api.h @@ -634,7 +634,7 @@ esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id, * - other: failed * */ -esp_gatt_status_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if, +esp_err_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if, esp_bd_addr_t server_bda, esp_gatt_srvc_id_t *srvc_id, esp_gatt_id_t *char_id); @@ -653,7 +653,7 @@ esp_gatt_status_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if, * - other: failed * */ -esp_gatt_status_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if, +esp_err_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if, esp_bd_addr_t server_bda, esp_gatt_srvc_id_t *srvc_id, esp_gatt_id_t *char_id); diff --git a/components/bt/bluedroid/api/include/esp_gatts_api.h b/components/bt/bluedroid/api/include/esp_gatts_api.h index 6bbc370a7b..d964ac9b9d 100644 --- a/components/bt/bluedroid/api/include/esp_gatts_api.h +++ b/components/bt/bluedroid/api/include/esp_gatts_api.h @@ -514,11 +514,11 @@ esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, co * @param[out] value: Pointer to attribute value payload, the value cannot be modified by user * * @return - * - ESP_OK : success + * - ESP_GATT_OK : success * - other : failed * */ -esp_err_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value); +esp_gatt_status_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value); /** diff --git a/components/bt/bluedroid/bta/dm/bta_dm_act.c b/components/bt/bluedroid/bta/dm/bta_dm_act.c index 39a5f06d35..49289a9ab4 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_act.c @@ -4601,7 +4601,7 @@ void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data) *******************************************************************************/ void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data) { - BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable); + BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable, p_data->ble_local_privacy.set_local_privacy_cback); } #endif diff --git a/components/bt/bluedroid/bta/dm/bta_dm_api.c b/components/bt/bluedroid/bta/dm/bta_dm_api.c index 7ef0887619..fcb27004f0 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_api.c @@ -1575,7 +1575,7 @@ void BTA_DmBleUpdateConnectionParam(BD_ADDR bd_addr, UINT16 min_int, ** Returns void ** *******************************************************************************/ -void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable) +void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable, tBTA_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback) { ///This function used the irk to generate the resolve address #if BLE_INCLUDED == TRUE && BLE_PRIVACY_SPT == TRUE @@ -1586,7 +1586,7 @@ void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable) p_msg->hdr.event = BTA_DM_API_LOCAL_PRIVACY_EVT; p_msg->privacy_enable = privacy_enable; - + p_msg->set_local_privacy_cback = set_local_privacy_cback; bta_sys_sendmsg(p_msg); } #else diff --git a/components/bt/bluedroid/bta/dm/bta_dm_int.h b/components/bt/bluedroid/bta/dm/bta_dm_int.h index 7357781370..e4bf0fadb0 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_int.h +++ b/components/bt/bluedroid/bta/dm/bta_dm_int.h @@ -444,6 +444,7 @@ typedef struct { typedef struct { BT_HDR hdr; BOOLEAN privacy_enable; + tBTA_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback; } tBTA_DM_API_LOCAL_PRIVACY; /* set scan parameter for BLE connections */ diff --git a/components/bt/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/bluedroid/bta/gatt/bta_gattc_act.c index 292b3dfaf6..617aa02cdf 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/bluedroid/bta/gatt/bta_gattc_act.c @@ -33,6 +33,7 @@ #include "bta_gattc_int.h" #include "l2c_api.h" #include "l2c_int.h" +#include "gatt_int.h" #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE) #include "bta_hh_int.h" @@ -2410,7 +2411,12 @@ tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_ ccc_value.len = 2; ccc_value.value[0] = GATT_CLT_CONFIG_INDICATION; ccc_value.auth_req = GATT_AUTH_REQ_NONE; - write_status = GATTC_Write (conn_id, GATT_WRITE, &ccc_value); + if (gatt_is_clcb_allocated(conn_id)) { + APPL_TRACE_DEBUG("%s, GATTC_Write GATT_BUSY conn_id = %d", __func__, conn_id); + write_status = GATT_BUSY; + } else { + write_status = GATTC_Write (conn_id, GATT_WRITE, &ccc_value); + } if (write_status != GATT_SUCCESS) { start_find_ccc_timer = TRUE; result = SERVICE_CHANGE_WRITE_CCC_FAILED; diff --git a/components/bt/bluedroid/bta/gatt/bta_gatts_act.c b/components/bt/bluedroid/bta/gatt/bta_gatts_act.c index 733976c0ca..414b1e5758 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gatts_act.c +++ b/components/bt/bluedroid/bta/gatt/bta_gatts_act.c @@ -506,7 +506,7 @@ void bta_gatts_set_attr_value(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_ UINT16 service_id = p_srvc_cb->service_id; tBTA_GATTS cb_data; tBTA_GATT_STATUS gatts_status; - gatts_status = GATTS_SetAttributeValue(p_msg->api_add_char_descr.hdr.layer_specific, + gatts_status = GATTS_SetAttributeValue(p_msg->api_set_val.hdr.layer_specific, p_msg->api_set_val.length, p_msg->api_set_val.value); @@ -515,14 +515,19 @@ void bta_gatts_set_attr_value(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_ cb_data.attr_val.attr_id = p_msg->api_set_val.hdr.layer_specific; cb_data.attr_val.status = gatts_status; + if (p_msg->api_set_val.value != NULL){ + GKI_freebuf(p_msg->api_set_val.value); + } + if (p_rcb->p_cback) { (*p_rcb->p_cback)(BTA_GATTS_SET_ATTR_VAL_EVT, &cb_data); } } -void bta_gatts_get_attr_value(UINT16 attr_handle, UINT16 *length, UINT8 **value) +tGATT_STATUS bta_gatts_get_attr_value(UINT16 attr_handle, UINT16 *length, UINT8 **value) { - GATTS_GetAttributeValue(attr_handle, length, value); + + return GATTS_GetAttributeValue(attr_handle, length, value); } /******************************************************************************* diff --git a/components/bt/bluedroid/bta/gatt/bta_gatts_api.c b/components/bt/bluedroid/bta/gatt/bta_gatts_api.c index c56a9fa58a..1e7940a85b 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gatts_api.c +++ b/components/bt/bluedroid/bta/gatt/bta_gatts_api.c @@ -490,9 +490,9 @@ void BTA_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value) } -void BTA_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value) +tBTA_GATT_STATUS BTA_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value) { - bta_gatts_get_attr_value(attr_handle, length, value); + return bta_gatts_get_attr_value(attr_handle, length, value); } /******************************************************************************* diff --git a/components/bt/bluedroid/bta/include/bta_api.h b/components/bt/bluedroid/bta/include/bta_api.h index f21803b1c9..1313b90c8b 100644 --- a/components/bt/bluedroid/bta/include/bta_api.h +++ b/components/bt/bluedroid/bta/include/bta_api.h @@ -404,6 +404,8 @@ typedef void (tBTA_START_ADV_CMPL_CBACK) (tBTA_STATUS status); typedef tBTM_SET_PKT_DATA_LENGTH_CBACK tBTA_SET_PKT_DATA_LENGTH_CBACK; +typedef tBTM_SET_LOCAL_PRIVACY_CBACK tBTA_SET_LOCAL_PRIVACY_CBACK; + /* advertising channel map */ #define BTA_BLE_ADV_CHNL_37 BTM_BLE_ADV_CHNL_37 #define BTA_BLE_ADV_CHNL_38 BTM_BLE_ADV_CHNL_38 @@ -2035,11 +2037,11 @@ extern void BTA_DmSetRandAddress(BD_ADDR rand_addr); ** Description Enable/disable privacy on the local device ** ** Parameters: privacy_enable - enable/disabe privacy on remote device. -** +** set_local_privacy_cback -callback to be called with result ** Returns void ** *******************************************************************************/ -extern void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable); +extern void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable, tBTA_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback); /******************************************************************************* ** diff --git a/components/bt/bluedroid/bta/include/bta_gatt_api.h b/components/bt/bluedroid/bta/include/bta_gatt_api.h index 349c7c6a2d..e6dc5e8dbf 100644 --- a/components/bt/bluedroid/bta/include/bta_gatt_api.h +++ b/components/bt/bluedroid/bta/include/bta_gatt_api.h @@ -1409,10 +1409,10 @@ extern void BTA_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *valu ** length - the value length which has been set to the attribute. ** value - the pointer to the value ** -** Returns None +** Returns tBTA_GATT_STATUS ** *******************************************************************************/ -extern void BTA_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value); +extern tBTA_GATT_STATUS BTA_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value); /******************************************************************************* ** diff --git a/components/bt/bluedroid/bta/include/bta_gatts_int.h b/components/bt/bluedroid/bta/include/bta_gatts_int.h index 0f9e689ace..03920ddfd7 100644 --- a/components/bt/bluedroid/bta/include/bta_gatts_int.h +++ b/components/bt/bluedroid/bta/include/bta_gatts_int.h @@ -230,7 +230,7 @@ extern void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS extern void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg); extern void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg); extern void bta_gatts_set_attr_value(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg); -extern void bta_gatts_get_attr_value(UINT16 attr_handle, UINT16 *length, UINT8 **value); +extern tGATT_STATUS bta_gatts_get_attr_value(UINT16 attr_handle, UINT16 *length, UINT8 **value); extern void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg); extern void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg); extern void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg); diff --git a/components/bt/bluedroid/btc/core/btc_ble_storage.c b/components/bt/bluedroid/btc/core/btc_ble_storage.c index 1c885f4b5c..c10aa1e4e4 100644 --- a/components/bt/bluedroid/btc/core/btc_ble_storage.c +++ b/components/bt/bluedroid/btc/core/btc_ble_storage.c @@ -19,11 +19,14 @@ #include "bdaddr.h" #include "btc_ble_storage.h" #include "bta_gatts_co.h" +#include "btc_util.h" #if (SMP_INCLUDED == TRUE) btc_dm_pairing_cb_t pairing_cb; btc_dm_local_key_cb_t ble_local_key_cb; +btc_bonded_devices_t bonded_devices; + /******************************************************************************* ** @@ -47,18 +50,63 @@ bt_status_t btc_storage_load_bonded_ble_devices(void) bt_status_t btc_in_fetch_bonded_ble_devices(int add) { - btc_bonded_devices_t bonded_devices; + bt_status_t status = BT_STATUS_FAIL; + int device_type = 0; for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); iter = btc_config_section_next(iter)) { const char *name = btc_config_section_name(iter); - if (!string_is_bdaddr(name)) { + if (!string_is_bdaddr(name) || + !btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) || + ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { + continue; + } + LOG_DEBUG("%s, name = %s", __func__, name); + if (btc_in_fetch_bonded_ble_device(name, add, &bonded_devices) != BT_STATUS_SUCCESS) { + LOG_DEBUG("Remote device:%s, no link key or ble key found", name); + } else { + status = BT_STATUS_SUCCESS; + } + } + + return status; +} + +bt_status_t btc_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev) +{ + bt_bdaddr_t bd_addr; + int device_type = 0; + char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0}; + for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); + iter = btc_config_section_next(iter)) { + const char *name = btc_config_section_name(iter); + if (!string_is_bdaddr(name) || + !btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) || + ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { continue; } - if (!(btc_in_fetch_bonded_ble_device(name, add, &bonded_devices)) ) { - LOG_DEBUG("Remote device:%s, no link key or ble key found", name); - return BT_STATUS_FAIL; + string_to_bdaddr(name, &bd_addr); + memcpy(bond_dev->bd_addr, bd_addr.address, sizeof(bt_bdaddr_t)); + //resolve the peer device long term key + if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PENC, buffer, sizeof(tBTM_LE_PENC_KEYS)) + == BT_STATUS_SUCCESS) { + bond_dev->bond_key.key_mask |= ESP_BLE_ENC_KEY_MASK; + memcpy(&bond_dev->bond_key.penc_key, buffer, sizeof(tBTM_LE_PENC_KEYS)); } + //resolve the peer device csrk + if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PCSRK, buffer, sizeof(tBTM_LE_PCSRK_KEYS)) + == BT_STATUS_SUCCESS) { + bond_dev->bond_key.key_mask |= ESP_BLE_CSR_KEY_MASK; + memcpy(&bond_dev->bond_key.pcsrk_key, buffer, sizeof(tBTM_LE_PCSRK_KEYS)); + } + //resolve the peer device irk + if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PID, buffer, sizeof(tBTM_LE_PID_KEYS)) + == BT_STATUS_SUCCESS) { + bond_dev->bond_key.key_mask |= ESP_BLE_ID_KEY_MASK; + memcpy(&bond_dev->bond_key.pid_key, buffer, sizeof(tBTM_LE_PID_KEYS)); + } + //serch for the next bond device + bond_dev++; } return BT_STATUS_SUCCESS; @@ -78,6 +126,10 @@ void btc_save_ble_bonding_keys(void) bt_bdaddr_t bd_addr; bdcpy(bd_addr.address, pairing_cb.bd_addr); + bdstr_t bdstr; + bdaddr_to_string(&bd_addr, bdstr, sizeof(bdstr)); + btc_config_set_int(bdstr, BTC_LE_DEV_TYPE, BT_DEVICE_TYPE_BLE); + LOG_DEBUG("%s, penc = %d, pid = %d", __func__, pairing_cb.ble.is_penc_key_rcvd, pairing_cb.ble.is_pid_key_rcvd); if (pairing_cb.ble.is_penc_key_rcvd) { btc_storage_add_ble_bonding_key(&bd_addr, (char *) &pairing_cb.ble.penc_key, @@ -131,7 +183,6 @@ static void btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bda char buffer[100]; memset(buffer, 0, sizeof(buffer)); - if (btc_storage_get_ble_bonding_key(&bd_addr, key_type, buffer, key_len) == BT_STATUS_SUCCESS) { if (add_key) { BD_ADDR bta_bd_addr; @@ -152,13 +203,12 @@ static void btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bda } } - bt_status_t btc_storage_add_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, char *key, uint8_t key_type, uint8_t key_length) { - char bdstr[6] = {0}; + bdstr_t bdstr; bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); const char* name; switch (key_type) { @@ -205,7 +255,7 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, char *key_value, int key_length) { - char bdstr[6] = {0}; + bdstr_t bdstr; bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); const char* name; switch (key_type) { @@ -235,6 +285,38 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, } +bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr, + uint8_t key_type, void *key_value, int key_length) +{ + bdstr_t bdstr; + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + char *key_type_str; + switch (key_type) { + case BTM_LE_KEY_PENC: + key_type_str = "LE_KEY_PENC"; + break; + case BTM_LE_KEY_PID: + key_type_str = "LE_KEY_PID"; + break; + case BTM_LE_KEY_PCSRK: + key_type_str = "LE_KEY_PCSRK"; + break; + case BTM_LE_KEY_LENC: + key_type_str = "LE_KEY_LENC"; + break; + case BTM_LE_KEY_LCSRK: + key_type_str = "LE_KEY_LCSRK"; + break; + case BTM_LE_KEY_LID: + key_type_str = "LE_KEY_LID"; + default: + return false; + } + + return btc_compare_address_key_value(bdstr, key_type_str, key_value, key_length); +} + + /******************************************************************************* ** ** Function btc_storage_remove_ble_bonding_keys @@ -247,10 +329,13 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, *******************************************************************************/ bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr) { - char bdstr[6] = {0}; + bdstr_t bdstr; bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr); int ret = 1; + if (btc_config_exist(bdstr, BTC_LE_DEV_TYPE)) { + ret &= btc_config_remove(bdstr, BTC_LE_DEV_TYPE); + } if (btc_config_exist(bdstr, "LE_KEY_PENC")) { ret &= btc_config_remove(bdstr, "LE_KEY_PENC"); } @@ -266,10 +351,48 @@ bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr) if (btc_config_exist(bdstr, "LE_KEY_LCSRK")) { ret &= btc_config_remove(bdstr, "LE_KEY_LCSRK"); } + //remove the address information after delete the ble key. + ret = btc_config_remove_section(bdstr); btc_config_save(); return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; } +bt_status_t btc_storage_clear_bond_devices(void) +{ + bt_bdaddr_t bd_addr; + int device_type = 0; + for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); + iter = btc_config_section_next(iter)) { + const char *name = btc_config_section_name(iter); + if (!string_is_bdaddr(name) && + !btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) && + ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { + continue; + } + + string_to_bdaddr(name, &bd_addr); + //remove the ble bonding keys from the config and then save the config to the flash + if (btc_storage_remove_ble_bonding_keys(&bd_addr) != BT_STATUS_SUCCESS) { + LOG_ERROR("%s, remove bonding key faild", __func__); + return BT_STATUS_FAIL; + } + // the bonded_devices Structure record the devices which has been added to the BTM layer global variable + for (int i = 0; i < bonded_devices.num_devices; i++) { + //if the address is equal to the record device address, remove it from the BTM layer global variable + if (!memcmp(bd_addr.address, bonded_devices.devices[i].address, sizeof(bt_bdaddr_t))) { + BD_ADDR bta_addr; + memcpy(bta_addr, bd_addr.address, sizeof(BD_ADDR)); + if(BTA_DmRemoveDevice(bta_addr) != BTA_SUCCESS) { + LOG_ERROR("%s, remove device faild", __func__); + return BT_STATUS_FAIL; + } + } + } + } + + return BT_STATUS_SUCCESS; +} + /******************************************************************************* ** ** Function btc_storage_add_ble_local_key @@ -382,7 +505,7 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, bool device_added = false; bool key_found = false; - if (!btc_config_get_int(remote_bd_addr, "AddrType", &device_type)) { + if (!btc_config_get_int(remote_bd_addr, BTC_LE_DEV_TYPE, &device_type)) { LOG_ERROR("%s, device_type = %x", __func__, device_type); return BT_STATUS_FAIL; } @@ -413,6 +536,13 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, btc_read_le_key(BTM_LE_KEY_LCSRK, sizeof(tBTM_LE_LCSRK_KEYS), bd_addr, addr_type, add, &device_added, &key_found); + // Fill in the bonded devices + if (device_added) + { + memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++], + &bd_addr, sizeof(bt_bdaddr_t)); + } + if (key_found) { return BT_STATUS_SUCCESS; } @@ -423,7 +553,7 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, uint8_t addr_type) { - char bdstr[6] = {0}; + bdstr_t bdstr; bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bt_bdaddr_t)); int ret = btc_config_set_int(bdstr, "AddrType", (int)addr_type); btc_config_save(); @@ -443,12 +573,30 @@ bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr, int*addr_type) { - char bdstr[6] = {0}; + bdstr_t bdstr; bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); int ret = btc_config_get_int(bdstr, "AddrType", addr_type); return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; } +int btc_storage_get_num_ble_bond_devices(void) +{ + int num_dev = 0; + int device_type = 0; + for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); + iter = btc_config_section_next(iter)) { + const char *name = btc_config_section_name(iter); + if (!string_is_bdaddr(name) && + !btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) && + device_type != BT_DEVICE_TYPE_BLE) { + continue; + } + + num_dev++; + } + + return num_dev; +} void btc_dm_load_ble_local_keys(void) { diff --git a/components/bt/bluedroid/btc/core/btc_config.c b/components/bt/bluedroid/btc/core/btc_config.c index bd0bd03187..dae7c57105 100644 --- a/components/bt/bluedroid/btc/core/btc_config.c +++ b/components/bt/bluedroid/btc/core/btc_config.c @@ -31,7 +31,7 @@ static const char *CONFIG_FILE_PATH = "bt_config.conf"; static const period_ms_t CONFIG_SETTLE_PERIOD_MS = 3000; -static void timer_config_save(void *data); +static void btc_key_value_to_string(uint8_t *key_vaule, char *value_str, int key_length); // TODO(zachoverflow): Move these two functions out, because they are too specific for this file // {grumpy-cat/no, monty-python/you-make-me-sad} @@ -47,7 +47,7 @@ bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type) bdstr_t bd_addr_str; bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str)); - if (!btc_config_get_int(bd_addr_str, "DevType", p_device_type)) { + if (!btc_config_get_int(bd_addr_str, BTC_LE_DEV_TYPE, p_device_type)) { return FALSE; } @@ -77,7 +77,38 @@ bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type) static pthread_mutex_t lock; // protects operations on |config|. static config_t *config; -static osi_alarm_t *alarm_timer; + +bool btc_compare_address_key_value(const char *section, char *key_type, void *key_value, int key_length) +{ + assert(key_value != NULL); + bool status = false; + char value_str[100] = {0}; + if(key_length > sizeof(value_str)/2) { + return false; + } + btc_key_value_to_string((uint8_t *)key_value, value_str, key_length); + pthread_mutex_lock(&lock); + if ((status = config_has_key_in_section(config, key_type, value_str)) == true) { + config_remove_section(config, section); + } + pthread_mutex_unlock(&lock); + return status; +} + +static void btc_key_value_to_string(uint8_t *key_vaule, char *value_str, int key_length) +{ + const char *lookup = "0123456789abcdef"; + + assert(key_vaule != NULL); + assert(value_str != NULL); + + for (size_t i = 0; i < key_length; ++i) { + value_str[(i * 2) + 0] = lookup[(key_vaule[i] >> 4) & 0x0F]; + value_str[(i * 2) + 1] = lookup[key_vaule[i] & 0x0F]; + } + + return; +} // Module lifecycle functions @@ -93,27 +124,15 @@ bool btc_config_init(void) goto error; } } - if (config_save(config, CONFIG_FILE_PATH)) { // unlink(LEGACY_CONFIG_FILE_PATH); } - // TODO(sharvil): use a non-wake alarm for this once we have - // API support for it. There's no need to wake the system to - // write back to disk. - alarm_timer = osi_alarm_new("btc_config", timer_config_save, NULL, CONFIG_SETTLE_PERIOD_MS); - if (!alarm_timer) { - LOG_ERROR("%s unable to create alarm.\n", __func__); - goto error; - } - return true; error:; - osi_alarm_free(alarm_timer); config_free(config); pthread_mutex_destroy(&lock); - alarm_timer = NULL; config = NULL; LOG_ERROR("%s failed\n", __func__); return false; @@ -129,10 +148,8 @@ bool btc_config_clean_up(void) { btc_config_flush(); - osi_alarm_free(alarm_timer); config_free(config); pthread_mutex_destroy(&lock); - alarm_timer = NULL; config = NULL; return true; } @@ -350,51 +367,21 @@ bool btc_config_remove(const char *section, const char *key) return ret; } -void btc_config_save(void) -{ - assert(alarm_timer != NULL); - assert(config != NULL); - - osi_alarm_set(alarm_timer, CONFIG_SETTLE_PERIOD_MS); -} - -void btc_config_flush(void) +bool btc_config_remove_section(const char *section) { assert(config != NULL); - assert(alarm_timer != NULL); - osi_alarm_cancel(alarm_timer); + assert(section != NULL); pthread_mutex_lock(&lock); - config_save(config, CONFIG_FILE_PATH); + bool ret = config_remove_section(config, section); pthread_mutex_unlock(&lock); -} -int btc_config_clear(void) -{ - assert(config != NULL); - assert(alarm_timer != NULL); - - osi_alarm_cancel(alarm_timer); - - pthread_mutex_lock(&lock); - config_free(config); - - config = config_new_empty(); - if (config == NULL) { - pthread_mutex_unlock(&lock); - return false; - } - - int ret = config_save(config, CONFIG_FILE_PATH); - pthread_mutex_unlock(&lock); return ret; } -static void timer_config_save(UNUSED_ATTR void *data) +void btc_config_save(void) { - assert(config != NULL); - assert(alarm_timer != NULL); - + assert(config != NULL); // Garbage collection process: the config file accumulates // cached information about remote devices during regular // inquiry scans. We remove some of these junk entries @@ -433,7 +420,33 @@ static void timer_config_save(UNUSED_ATTR void *data) while (num_keys > 0) { config_remove_section(config, keys[--num_keys]); } - config_save(config, CONFIG_FILE_PATH); pthread_mutex_unlock(&lock); } + +void btc_config_flush(void) +{ + assert(config != NULL); + pthread_mutex_lock(&lock); + config_save(config, CONFIG_FILE_PATH); + pthread_mutex_unlock(&lock); +} + +int btc_config_clear(void) +{ + assert(config != NULL); + + + pthread_mutex_lock(&lock); + config_free(config); + + config = config_new_empty(); + if (config == NULL) { + pthread_mutex_unlock(&lock); + return false; + } + int ret = config_save(config, CONFIG_FILE_PATH); + pthread_mutex_unlock(&lock); + return ret; +} + diff --git a/components/bt/bluedroid/btc/core/btc_dm.c b/components/bt/bluedroid/btc/core/btc_dm.c index 1f98d17da9..01f1a1e660 100644 --- a/components/bt/bluedroid/btc/core/btc_dm.c +++ b/components/bt/bluedroid/btc/core/btc_dm.c @@ -23,6 +23,7 @@ #include "btc_storage.h" #include "btc_ble_storage.h" #include "esp_gap_ble_api.h" +#include "btm_int.h" #include "bta_api.h" #include "bta_gatt_api.h" @@ -118,17 +119,30 @@ static void btc_disable_bluetooth_evt(void) static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl) { /* Save link key, if not temporary */ + LOG_DEBUG("%s, status = %d", __func__, p_auth_cmpl->success); bt_status_t status = BT_STATUS_FAIL; + int addr_type; + bt_bdaddr_t bdaddr; + bdcpy(bdaddr.address, p_auth_cmpl->bd_addr); + bdcpy(pairing_cb.bd_addr, p_auth_cmpl->bd_addr); + if (p_auth_cmpl->success) { status = BT_STATUS_SUCCESS; - int addr_type; - bt_bdaddr_t bdaddr; - bdcpy(bdaddr.address, p_auth_cmpl->bd_addr); - bdcpy(pairing_cb.bd_addr, p_auth_cmpl->bd_addr); + LOG_DEBUG ("%s, - p_auth_cmpl->bd_addr: %08x%04x", __func__, + (p_auth_cmpl->bd_addr[0] << 24) + (p_auth_cmpl->bd_addr[1] << 16) + (p_auth_cmpl->bd_addr[2] << 8) + p_auth_cmpl->bd_addr[3], + (p_auth_cmpl->bd_addr[4] << 8) + p_auth_cmpl->bd_addr[5]); + LOG_DEBUG ("%s, - pairing_cb.bd_addr: %08x%04x", __func__, + (pairing_cb.bd_addr[0] << 24) + (pairing_cb.bd_addr[1] << 16) + (pairing_cb.bd_addr[2] << 8) + pairing_cb.bd_addr[3], + (pairing_cb.bd_addr[4] << 8) + pairing_cb.bd_addr[5]); if (btc_storage_get_remote_addr_type(&bdaddr, &addr_type) != BT_STATUS_SUCCESS) { btc_storage_set_remote_addr_type(&bdaddr, p_auth_cmpl->addr_type); } - + /* check the irk has been save in the flash or not, if the irk has already save, means that the peer device has bonding + before. */ + if(pairing_cb.ble.is_pid_key_rcvd) { + btc_storage_compare_address_key_value(&bdaddr, BTM_LE_KEY_PID, + (void *)&pairing_cb.ble.pid_key, sizeof(tBTM_LE_PID_KEYS)); + } btc_save_ble_bonding_keys(); } else { /*Map the HCI fail reason to bt status */ @@ -310,8 +324,8 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg) btc_clear_services_mask(); btc_storage_load_bonded_devices(); #if (SMP_INCLUDED == TRUE) - //load the ble local key whitch has been store in the flash - btc_dm_load_ble_local_keys(); + //load the bonding device to the btm layer + btc_storage_load_bonded_ble_devices(); #endif ///SMP_INCLUDED == TRUE btc_enable_bluetooth_evt(p_data->enable.status); break; @@ -335,8 +349,20 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg) case BTA_DM_BOND_CANCEL_CMPL_EVT: case BTA_DM_SP_CFM_REQ_EVT: case BTA_DM_SP_KEY_NOTIF_EVT: - - case BTA_DM_DEV_UNPAIRED_EVT: + break; + case BTA_DM_DEV_UNPAIRED_EVT: { + bt_bdaddr_t bd_addr; + rsp_app = true; + LOG_ERROR("BTA_DM_DEV_UNPAIRED_EVT"); + memcpy(bd_addr.address, p_data->link_down.bd_addr, sizeof(BD_ADDR)); + btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN); + //remove the bonded key in the config and nvs flash. + //btc_storage_remove_ble_bonding_keys(&bd_addr); + ble_msg.act = ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT; + param.remove_bond_dev_cmpl.status = (p_data->link_down.status == HCI_SUCCESS) ? ESP_BT_STATUS_SUCCESS : ESP_BT_STATUS_FAIL; + memcpy(param.remove_bond_dev_cmpl.bd_addr, p_data->link_down.bd_addr, sizeof(BD_ADDR)); + break; + } case BTA_DM_BUSY_LEVEL_EVT: case BTA_DM_LINK_UP_EVT: case BTA_DM_LINK_DOWN_EVT: diff --git a/components/bt/bluedroid/btc/core/btc_main.c b/components/bt/bluedroid/btc/core/btc_main.c index d251782e40..87892b8468 100644 --- a/components/bt/bluedroid/btc/core/btc_main.c +++ b/components/bt/bluedroid/btc/core/btc_main.c @@ -19,6 +19,7 @@ #include "esp_err.h" #include "btc_config.h" #include "alarm.h" +#include "btc_ble_storage.h" static future_t *main_future[BTC_MAIN_FUTURE_NUM]; @@ -54,8 +55,12 @@ static void btc_init_bluetooth(void) { osi_alarm_create_mux(); osi_alarm_init(); - btc_config_init(); bte_main_boot_entry(btc_init_callback); + btc_config_init(); +#if (SMP_INCLUDED) + //load the ble local key whitch has been store in the flash + btc_dm_load_ble_local_keys(); +#endif /* #if (SMP_INCLUDED) */ } diff --git a/components/bt/bluedroid/btc/include/btc_ble_storage.h b/components/bt/bluedroid/btc/include/btc_ble_storage.h index 2884d6acf3..111f1f0a2b 100644 --- a/components/bt/bluedroid/btc/include/btc_ble_storage.h +++ b/components/bt/bluedroid/btc/include/btc_ble_storage.h @@ -11,9 +11,11 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - +#ifndef __BTC_BLE_STORAGE_H__ +#define __BTC_BLE_STORAGE_H__ #include "bt_types.h" #include "bt_target.h" +#include "esp_gap_ble_api.h" #if (SMP_INCLUDED == TRUE) #define BTC_LE_LOCAL_KEY_IR (1<<0) @@ -77,9 +79,12 @@ typedef struct extern btc_dm_pairing_cb_t pairing_cb; extern btc_dm_local_key_cb_t ble_local_key_cb; +extern btc_bonded_devices_t bonded_devices; bt_status_t btc_storage_load_bonded_ble_devices(void); +bt_status_t btc_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev); + bt_status_t btc_in_fetch_bonded_ble_devices(int add); void btc_dm_remove_ble_bonding_keys(void); @@ -89,6 +94,9 @@ bt_status_t btc_storage_add_ble_bonding_key( bt_bdaddr_t *remote_bd_addr, uint8_t key_type, uint8_t key_length); +bool btc_compare_le_key_value(const uint8_t key_type, const size_t key_len, const tBTA_LE_KEY_VALUE *key_vaule, + bt_bdaddr_t bd_addr); + void btc_save_ble_bonding_keys(void); bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, @@ -99,12 +107,16 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, char *key_value, int key_length); +bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr, + uint8_t key_type, void *key_value, int key_length); bt_status_t btc_storage_add_ble_local_key(char *key, uint8_t key_type, uint8_t key_length); bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr); +bt_status_t btc_storage_clear_bond_devices(void); + bt_status_t btc_storage_remove_ble_local_keys(void); bt_status_t btc_storage_get_ble_local_key(uint8_t key_type, @@ -114,6 +126,8 @@ bt_status_t btc_storage_get_ble_local_key(uint8_t key_type, bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr, int *addr_type); +int btc_storage_get_num_ble_bond_devices(void); + bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, uint8_t addr_type); @@ -121,4 +135,5 @@ void btc_dm_load_ble_local_keys(void); void btc_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er, tBTA_BLE_LOCAL_ID_KEYS *p_id_keys); -#endif ///SMP_INCLUDED == TRUE \ No newline at end of file +#endif ///SMP_INCLUDED == TRUE +#endif ///__BTC_BLE_STORAGE_H__ \ No newline at end of file diff --git a/components/bt/bluedroid/btc/include/btc_config.h b/components/bt/bluedroid/btc/include/btc_config.h index 1472cc83c4..2367c53b40 100644 --- a/components/bt/bluedroid/btc/include/btc_config.h +++ b/components/bt/bluedroid/btc/include/btc_config.h @@ -20,6 +20,8 @@ #include "bt_types.h" +#define BTC_LE_DEV_TYPE "DevType" + typedef struct btc_config_section_iter_t btc_config_section_iter_t; bool btc_config_init(void); @@ -35,6 +37,7 @@ bool btc_config_set_str(const char *section, const char *key, const char *value) bool btc_config_get_bin(const char *section, const char *key, uint8_t *value, size_t *length); bool btc_config_set_bin(const char *section, const char *key, const uint8_t *value, size_t length); bool btc_config_remove(const char *section, const char *key); +bool btc_config_remove_section(const char *section); size_t btc_config_get_bin_length(const char *section, const char *key); @@ -49,6 +52,7 @@ int btc_config_clear(void); // TODO(zachoverflow): Eww...we need to move these out. These are peer specific, not config general. bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type); +bool btc_compare_address_key_value(const char *section, char *key_type, void *key_value, int key_length); bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type); #endif diff --git a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 3863d5e3ca..a9a667f4ed 100644 --- a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -24,6 +24,7 @@ #include "btc_gatt_util.h" #include "esp_bt_defs.h" #include "esp_gap_ble_api.h" +#include "btc_ble_storage.h" static tBTA_BLE_ADV_DATA gl_bta_adv_data; static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data; @@ -145,6 +146,12 @@ static esp_bt_status_t btc_btm_status_to_esp_status (uint8_t btm_status) case BTM_CONTROL_LE_DATA_LEN_UNSUPPORTED: esp_status = ESP_BT_STATUS_CONTROL_LE_DATA_LEN_UNSUPPORTED; break; + case BTM_SET_PRIVACY_SUCCESS: + esp_status = ESP_BT_STATUS_SUCCESS; + break; + case BTM_SET_PRIVACY_FAIL: + esp_status = ESP_BT_STATUS_FAIL; + break; default: esp_status = ESP_BT_STATUS_FAIL; break; @@ -661,6 +668,23 @@ static void btc_set_pkt_length_callback(UINT8 status, tBTM_LE_SET_PKT_DATA_LENGT } } +static void btc_set_local_privacy_callback(UINT8 status) +{ + esp_ble_gap_cb_param_t param; + bt_status_t ret; + btc_msg_t msg; + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_GAP_BLE; + msg.act = ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT; + param.local_privacy_cmpl.status = btc_btm_status_to_esp_status(status); + ret = btc_transfer_context(&msg, ¶m, + sizeof(esp_ble_gap_cb_param_t), NULL); + + if (ret != BT_STATUS_SUCCESS) { + LOG_ERROR("%s btc_transfer_context failed\n", __func__); + } +} + #if (SMP_INCLUDED == TRUE) static void btc_set_encryption_callback(BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS enc_status) @@ -756,9 +780,74 @@ static void btc_ble_set_rand_addr (BD_ADDR rand_addr) } } -static void btc_ble_config_local_privacy(bool privacy_enable) +#if (SMP_INCLUDED) +static void btc_ble_remove_bond_device(esp_bt_status_t status) { - BTA_DmBleConfigLocalPrivacy(privacy_enable); + int ret; + esp_ble_gap_cb_param_t param; + btc_msg_t msg; + param.remove_bond_dev_cmpl.status = status; + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_GAP_BLE; + msg.act = ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT; + + ret = btc_transfer_context(&msg, ¶m, + sizeof(esp_ble_gap_cb_param_t), NULL); + + if (ret != BT_STATUS_SUCCESS) { + LOG_ERROR("%s btc_transfer_context failed", __func__); + } +} + +static void btc_ble_clear_bond_device(void) +{ + int ret; + esp_ble_gap_cb_param_t param; + btc_msg_t msg; + ret = btc_storage_clear_bond_devices(); + param.clear_bond_dev_cmpl.status = ret; + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_GAP_BLE; + msg.act = ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT; + + ret = btc_transfer_context(&msg, ¶m, + sizeof(esp_ble_gap_cb_param_t), NULL); + + if (ret != BT_STATUS_SUCCESS) { + LOG_ERROR("%s btc_transfer_context failed", __func__); + } + +} + +static void btc_ble_get_bond_device_list(void) +{ + int ret; + esp_ble_gap_cb_param_t param; + esp_ble_bond_dev_t *bond_dev; + btc_msg_t msg; + int num_dev = btc_storage_get_num_ble_bond_devices(); + bond_dev = GKI_getbuf(sizeof(esp_ble_bond_dev_t)*num_dev); + + param.get_bond_dev_cmpl.status = btc_get_bonded_ble_devices_list(bond_dev); + param.get_bond_dev_cmpl.dev_num = num_dev; + param.get_bond_dev_cmpl.bond_dev = bond_dev; + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_GAP_BLE; + msg.act = ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT; + + ret = btc_transfer_context(&msg, ¶m, sizeof(esp_ble_gap_cb_param_t), btc_gap_ble_cb_deep_copy); + + if (ret != BT_STATUS_SUCCESS) { + LOG_ERROR("%s btc_transfer_context failed", __func__); + } + // release the buffer after used. + GKI_freebuf((void *)bond_dev); +} +#endif /* #if (SMP_INCLUDED) */ + +static void btc_ble_config_local_privacy(bool privacy_enable, tBTA_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback) +{ + BTA_DmBleConfigLocalPrivacy(privacy_enable, set_local_privacy_cback); } static void btc_ble_disconnect(BD_ADDR bd_addr) @@ -770,78 +859,14 @@ void btc_gap_ble_cb_handler(btc_msg_t *msg) { esp_ble_gap_cb_param_t *param = (esp_ble_gap_cb_param_t *)msg->arg; - switch (msg->act) { - case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT, param); - break; - case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT : - btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT, param); - break; - case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT, param); - break; - case ESP_GAP_BLE_SCAN_RESULT_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RESULT_EVT, param); - break; - case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT, param); - break; - case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT, param); - break; - case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_START_COMPLETE_EVT, param); - break; - case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_START_COMPLETE_EVT, param); - break; - case ESP_GAP_BLE_AUTH_CMPL_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_AUTH_CMPL_EVT, param); - break; - case ESP_GAP_BLE_KEY_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_KEY_EVT, param); - break; - btc_gap_ble_cb_to_app(ESP_GAP_BLE_KEY_EVT, param); - case ESP_GAP_BLE_SEC_REQ_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_SEC_REQ_EVT, param); - break; - case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_PASSKEY_NOTIF_EVT, param); - break; - case ESP_GAP_BLE_PASSKEY_REQ_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_PASSKEY_REQ_EVT, param); - break; - case ESP_GAP_BLE_OOB_REQ_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_OOB_REQ_EVT, param); - break; - case ESP_GAP_BLE_LOCAL_IR_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_LOCAL_IR_EVT, param); - break; - case ESP_GAP_BLE_LOCAL_ER_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_LOCAL_ER_EVT, param); - break; - case ESP_GAP_BLE_NC_REQ_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_NC_REQ_EVT, param); - case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT, param); - break; - case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT, param); - break; - case ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT, param); - break; - case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT, param); - break; - case ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT: - btc_gap_ble_cb_to_app(ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT, param); - break; - default: - break; - + if (msg->act < ESP_GAP_BLE_EVT_MAX) { + btc_gap_ble_cb_to_app(msg->act, param); + } else { + LOG_ERROR("%s, unknow msg->act = %d", __func__, msg->act); } + btc_gap_ble_cb_deep_free(msg); + } void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) @@ -913,7 +938,31 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) } } -static void btc_gap_ble_arg_deep_free(btc_msg_t *msg) +void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) +{ + switch (msg->act) { + case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: { + esp_ble_gap_cb_param_t *src = (esp_ble_gap_cb_param_t *)p_src; + esp_ble_gap_cb_param_t *dst = (esp_ble_gap_cb_param_t *)p_dest; + uint16_t length = 0; + if (src->get_bond_dev_cmpl.bond_dev) { + length = (src->get_bond_dev_cmpl.dev_num)*sizeof(esp_ble_bond_dev_t); + dst->get_bond_dev_cmpl.bond_dev = GKI_getbuf(length); + if (dst->get_bond_dev_cmpl.bond_dev != NULL) { + memcpy(dst->get_bond_dev_cmpl.bond_dev, src->get_bond_dev_cmpl.bond_dev, length); + } else { + LOG_ERROR("%s %d no mem", __func__, msg->act); + } + } + break; + } + default: + LOG_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act); + break; + } +} + +void btc_gap_ble_arg_deep_free(btc_msg_t *msg) { LOG_DEBUG("%s \n", __func__); switch (msg->act) { @@ -952,6 +1001,23 @@ static void btc_gap_ble_arg_deep_free(btc_msg_t *msg) } } +void btc_gap_ble_cb_deep_free(btc_msg_t *msg) +{ + LOG_DEBUG("%s", __func__); + switch (msg->act) { + case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: { + esp_ble_bond_dev_t *bond_dev = ((esp_ble_gap_cb_param_t *)msg->arg)->get_bond_dev_cmpl.bond_dev; + if (bond_dev) { + GKI_freebuf((void *)bond_dev); + } + break; + } + default: + LOG_DEBUG("Unhandled deep free %d", msg->act); + break; + } +} + void btc_gap_ble_call_handler(btc_msg_t *msg) { btc_ble_gap_args_t *arg = (btc_ble_gap_args_t *)msg->arg; @@ -1000,7 +1066,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) break; } case BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY: - btc_ble_config_local_privacy(arg->cfg_local_privacy.privacy_enable); + btc_ble_config_local_privacy(arg->cfg_local_privacy.privacy_enable, btc_set_local_privacy_callback); break; case BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW: btc_ble_set_adv_data_raw(arg->cfg_adv_data_raw.raw_adv, @@ -1078,6 +1144,26 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) BTA_DmBleConfirmReply(bd_addr, arg->enc_comfirm_replay.accept); break; } + case BTC_GAP_BLE_REMOVE_BOND_DEV_EVT: { + BD_ADDR bd_addr; + bt_bdaddr_t bt_addr; + memcpy(bd_addr, arg->remove_bond_device.bd_addr, sizeof(BD_ADDR)); + memcpy(bt_addr.address, arg->remove_bond_device.bd_addr, sizeof(bt_bdaddr_t)); + LOG_DEBUG("BTC_GAP_BLE_REMOVE_BOND_DEV_EVT"); + if (btc_storage_remove_ble_bonding_keys(&bt_addr) == BT_STATUS_SUCCESS) { + BTA_DmRemoveDevice(bd_addr); + } else { + LOG_ERROR("remove device failed: the address[%x:%x:%x:%x:%x:%x] didn't in the bonding list", bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); + btc_ble_remove_bond_device(ESP_BT_STATUS_FAIL); + } + break; + } + case BTC_GAP_BLE_CLEAR_BOND_DEV_EVT: + btc_ble_clear_bond_device(); + break; + case BTC_GAP_BLE_GET_BOND_DEV_EVT: + btc_ble_get_bond_device_list(); + break; #endif ///SMP_INCLUDED == TRUE case BTC_GAP_BLE_DISCONNECT_EVT: btc_ble_disconnect(arg->disconnect.remote_device); diff --git a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c b/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c index bfaa1cb7a4..35c6094bf7 100644 --- a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c +++ b/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c @@ -474,10 +474,10 @@ static esp_gatt_status_t btc_gatts_check_valid_attr_tab(esp_gatts_attr_db_t *gat return ESP_GATT_OK; } -void btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value) +esp_gatt_status_t btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value) { - BTA_GetAttributeValue(attr_handle, length, value); + return BTA_GetAttributeValue(attr_handle, length, value); } diff --git a/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h index 78c2db022c..507089a267 100644 --- a/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -40,6 +40,9 @@ typedef enum { BTC_GAP_BLE_PASSKEY_REPLY_EVT, BTC_GAP_BLE_CONFIRM_REPLY_EVT, BTC_GAP_BLE_DISCONNECT_EVT, + BTC_GAP_BLE_REMOVE_BOND_DEV_EVT, + BTC_GAP_BLE_CLEAR_BOND_DEV_EVT, + BTC_GAP_BLE_GET_BOND_DEV_EVT, } btc_gap_ble_act_t; /* btc_ble_gap_args_t */ @@ -89,44 +92,50 @@ typedef union { uint8_t *raw_scan_rsp; uint32_t raw_scan_rsp_len; } cfg_scan_rsp_data_raw; - + //BTC_GAP_BLE_SET_ENCRYPTION_EVT struct set_encryption_args { esp_bd_addr_t bd_addr; esp_ble_sec_act_t sec_act; } set_encryption; - + //BTC_GAP_BLE_SET_SECURITY_PARAM_EVT struct set_security_param_args { esp_ble_sm_param_t param_type; uint8_t len; uint8_t *value; } set_security_param; - + //BTC_GAP_BLE_SECURITY_RSP_EVT struct enc_rsp_args { esp_bd_addr_t bd_addr; bool accept; } sec_rsp; - + //BTC_GAP_BLE_PASSKEY_REPLY_EVT struct enc_passkey_reply_args { esp_bd_addr_t bd_addr; bool accept; uint32_t passkey; } enc_passkey_replay; - + //BTC_GAP_BLE_CONFIRM_REPLY_EVT struct enc_comfirm_reply_args { esp_bd_addr_t bd_addr; bool accept; } enc_comfirm_replay; - //BTC_GAP_BLE_DISCONNECT_EVT struct disconnect_args { esp_bd_addr_t remote_device; } disconnect; - + //BTC_GAP_BLE_REMOVE_BOND_DEV_EVT + struct remove_bond_device_args { + esp_bd_addr_t bd_addr; + } remove_bond_device; } btc_ble_gap_args_t; void btc_gap_ble_call_handler(btc_msg_t *msg); void btc_gap_ble_cb_handler(btc_msg_t *msg); void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); +void btc_gap_ble_arg_deep_free(btc_msg_t *msg); +void btc_gap_ble_cb_deep_free(btc_msg_t *msg); +void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); + #endif /* __BTC_GAP_BLE_H__ */ diff --git a/components/bt/bluedroid/btc/profile/std/include/btc_gatts.h b/components/bt/bluedroid/btc/profile/std/include/btc_gatts.h index 35cf84c5b1..00f73875c1 100644 --- a/components/bt/bluedroid/btc/profile/std/include/btc_gatts.h +++ b/components/bt/bluedroid/btc/profile/std/include/btc_gatts.h @@ -147,7 +147,7 @@ typedef union { void btc_gatts_call_handler(btc_msg_t *msg); void btc_gatts_cb_handler(btc_msg_t *msg); void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); -void btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value); +esp_gatt_status_t btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value); #endif /* __BTC_GATTS_H__ */ diff --git a/components/bt/bluedroid/btif/bta_dm_co.c b/components/bt/bluedroid/btif/bta_dm_co.c index d14123e823..291db9e3dd 100644 --- a/components/bt/bluedroid/btif/bta_dm_co.c +++ b/components/bt/bluedroid/btif/bta_dm_co.c @@ -502,7 +502,7 @@ void bta_dm_co_ble_set_rsp_key_req(UINT8 rsp_key) void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size) { #if (SMP_INCLUDED == TRUE) - if(ble_key_size > 7 && ble_key_size >= 16) { + if(ble_key_size >= BTM_BLE_MIN_KEY_SIZE && ble_key_size <= BTM_BLE_MAX_KEY_SIZE) { bte_appl_cfg.ble_max_key_size = ble_key_size; } else { APPL_TRACE_ERROR("%s error:Invalid key size value, key_size =%d",__func__, ble_key_size); diff --git a/components/bt/bluedroid/include/bt_target.h b/components/bt/bluedroid/include/bt_target.h index a7ed5bd3b8..a426d69fe6 100644 --- a/components/bt/bluedroid/include/bt_target.h +++ b/components/bt/bluedroid/include/bt_target.h @@ -577,7 +577,11 @@ /* The number of security records for peer devices. 100 AS Default*/ #ifndef BTM_SEC_MAX_DEVICE_RECORDS -#define BTM_SEC_MAX_DEVICE_RECORDS 8 // 100 +#if SMP_INCLUDED == TRUE +#define BTM_SEC_MAX_DEVICE_RECORDS 15 // 100 +#else +#define BTM_SEC_MAX_DEVICE_RECORDS 8 +#endif /* SMP_INCLUDED == TRUE */ #endif /* The number of security records for services. 32 AS Default*/ diff --git a/components/bt/bluedroid/osi/config.c b/components/bt/bluedroid/osi/config.c index dc617f6e55..28d53b23e5 100644 --- a/components/bt/bluedroid/osi/config.c +++ b/components/bt/bluedroid/osi/config.c @@ -28,7 +28,7 @@ #include "list.h" #include "bt_trace.h" -#define CONFIG_FILE_MAX_SIZE (1024) +#define CONFIG_FILE_MAX_SIZE (2048) #define CONFIG_KEY "bt_cfg_key" typedef struct { char *key; @@ -133,6 +133,25 @@ bool config_has_key(const config_t *config, const char *section, const char *key return (entry_find(config, section, key) != NULL); } +bool config_has_key_in_section(config_t *config, char *key, char *key_value) +{ + LOG_DEBUG("key = %s, value = %s", key, key_value); + for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { + const section_t *section = (const section_t *)list_node(node); + + for (const list_node_t *node = list_begin(section->entries); node != list_end(section->entries); node = list_next(node)) { + entry_t *entry = list_node(node); + LOG_DEBUG("entry->key = %s, entry->value = %s", entry->key, entry->value); + if (!strcmp(entry->key, key) && !strcmp(entry->value, key_value)) { + LOG_DEBUG("%s, the irk aready in the flash.", __func__); + return true; + } + } + } + + return false; +} + int config_get_int(const config_t *config, const char *section, const char *key, int def_value) { assert(config != NULL); @@ -312,8 +331,8 @@ bool config_save(const config_t *config, const char *filename) int w_cnt, w_cnt_total = 0; for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { const section_t *section = (const section_t *)list_node(node); - LOG_DEBUG("section name: %s\n", section->name); w_cnt = snprintf(line, 1024, "[%s]\n", section->name); + LOG_DEBUG("section name: %s, w_cnt + w_cnt_total = %d\n", section->name, w_cnt + w_cnt_total); if (w_cnt + w_cnt_total < CONFIG_FILE_MAX_SIZE) { memcpy(buf + w_cnt_total, line, w_cnt); w_cnt_total += w_cnt; @@ -325,6 +344,7 @@ bool config_save(const config_t *config, const char *filename) const entry_t *entry = (const entry_t *)list_node(enode); LOG_DEBUG("(key, val): (%s, %s)\n", entry->key, entry->value); w_cnt = snprintf(line, 1024, "%s = %s\n", entry->key, entry->value); + LOG_DEBUG("%s, w_cnt + w_cnt_total = %d", __func__, w_cnt + w_cnt_total); if (w_cnt + w_cnt_total < CONFIG_FILE_MAX_SIZE) { memcpy(buf + w_cnt_total, line, w_cnt); w_cnt_total += w_cnt; diff --git a/components/bt/bluedroid/osi/include/config.h b/components/bt/bluedroid/osi/include/config.h index 4f0e2cd8ae..41f5ddb18a 100644 --- a/components/bt/bluedroid/osi/include/config.h +++ b/components/bt/bluedroid/osi/include/config.h @@ -66,6 +66,10 @@ bool config_has_section(const config_t *config, const char *section); // Returns false otherwise. |config|, |section|, and |key| must not be NULL. bool config_has_key(const config_t *config, const char *section, const char *key); +// Returns true if the config file has a key named |key| and the key_value. +// Returns false otherwise. |config|, |key|, and |key_value| must not be NULL. +bool config_has_key_in_section(config_t *config, char *key, char *key_value); + // Returns the integral value for a given |key| in |section|. If |section| // or |key| do not exist, or the value cannot be fully converted to an integer, // this function returns |def_value|. |config|, |section|, and |key| must not diff --git a/components/bt/bluedroid/stack/btm/btm_ble_addr.c b/components/bt/bluedroid/stack/btm/btm_ble_addr.c index 4f6c443a5b..cfc9632750 100644 --- a/components/bt/bluedroid/stack/btm/btm_ble_addr.c +++ b/components/bt/bluedroid/stack/btm/btm_ble_addr.c @@ -60,6 +60,10 @@ static void btm_gen_resolve_paddr_cmpl(tSMP_ENC *p) btsnd_hcic_ble_set_random_addr(p_cb->private_addr); p_cb->own_addr_type = BLE_ADDR_RANDOM; + if (p_cb->set_local_privacy_cback){ + (*p_cb->set_local_privacy_cback)(BTM_SET_PRIVACY_SUCCESS); + p_cb->set_local_privacy_cback = NULL; + } /* start a periodical timer to refresh random addr */ btu_stop_timer_oneshot(&p_cb->raddr_timer_ent); @@ -73,6 +77,10 @@ static void btm_gen_resolve_paddr_cmpl(tSMP_ENC *p) } else { /* random address set failure */ BTM_TRACE_DEBUG("set random address failed"); + if (p_cb->set_local_privacy_cback){ + (*p_cb->set_local_privacy_cback)(BTM_SET_PRIVACY_FAIL); + p_cb->set_local_privacy_cback = NULL; + } } } /******************************************************************************* diff --git a/components/bt/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/bluedroid/stack/btm/btm_ble_gap.c index 523137aa0b..1029977cb2 100644 --- a/components/bt/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/bluedroid/stack/btm/btm_ble_gap.c @@ -640,10 +640,16 @@ void BTM_BleEnableMixedPrivacyMode(BOOLEAN mixed_on) ** Returns BOOLEAN privacy mode set success; otherwise failed. ** *******************************************************************************/ -BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode) +BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode, tBTM_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback) { #if BLE_PRIVACY_SPT == TRUE tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; + tBTM_LE_RANDOM_CB *random_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; + if (random_cb){ + random_cb->set_local_privacy_cback = set_local_privacy_cback; + }else{ + BTM_TRACE_ERROR("%s,random_cb = NULL", __func__); + } BTM_TRACE_EVENT ("%s\n", __func__); diff --git a/components/bt/bluedroid/stack/gatt/gatt_db.c b/components/bt/bluedroid/stack/gatt/gatt_db.c index 1fe69e0049..26cb5845b4 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/bluedroid/stack/gatt/gatt_db.c @@ -752,6 +752,14 @@ tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, GATT_TRACE_ERROR("gatts_get_attribute_value Fail:p_db->p_attr_list is NULL.\n"); return GATT_INVALID_PDU; } + if (length == NULL){ + GATT_TRACE_ERROR("gatts_get_attribute_value Fail:length is NULL.\n"); + return GATT_INVALID_PDU; + } + if (value == NULL){ + GATT_TRACE_ERROR("gatts_get_attribute_value Fail:value is NULL.\n"); + return GATT_INVALID_PDU; + } p_cur = (tGATT_ATTR16 *) p_db->p_attr_list; diff --git a/components/bt/bluedroid/stack/include/btm_api.h b/components/bt/bluedroid/stack/include/btm_api.h index 2976e497ed..d4ee7b4734 100644 --- a/components/bt/bluedroid/stack/include/btm_api.h +++ b/components/bt/bluedroid/stack/include/btm_api.h @@ -69,7 +69,9 @@ enum { BTM_REPEATED_ATTEMPTS, /* 19 repeated attempts for LE security requests */ BTM_MODE4_LEVEL4_NOT_SUPPORTED, /* 20 Secure Connections Only Mode can't be supported */ BTM_PEER_LE_DATA_LEN_UNSUPPORTED, /* 21 peer setting data length is unsupported*/ - BTM_CONTROL_LE_DATA_LEN_UNSUPPORTED /* 22 controller setting data length is unsupported*/ + BTM_CONTROL_LE_DATA_LEN_UNSUPPORTED,/* 22 controller setting data length is unsupported*/ + BTM_SET_PRIVACY_SUCCESS, /* 23 enable/disable local privacy success */ + BTM_SET_PRIVACY_FAIL, /* 24 enable/disable local privacy failed*/ }; typedef uint8_t tBTM_STATUS; @@ -175,6 +177,8 @@ typedef void (tBTM_UPDATE_CONN_PARAM_CBACK) (UINT8 status, BD_ADDR bd_addr, tBTM typedef void (tBTM_SET_PKT_DATA_LENGTH_CBACK) (UINT8 status, tBTM_LE_SET_PKT_DATA_LENGTH_PARAMS *data_length_params); +typedef void (tBTM_SET_LOCAL_PRIVACY_CBACK) (UINT8 status); + /***************************************************************************** ** DEVICE DISCOVERY - Inquiry, Remote Name, Discovery, Class of Device @@ -1412,6 +1416,7 @@ typedef UINT8 tBTM_IO_CAP; #define BTM_BLE_INITIATOR_KEY_SIZE 15 #define BTM_BLE_RESPONDER_KEY_SIZE 15 #define BTM_BLE_MAX_KEY_SIZE 16 +#define BTM_BLE_MIN_KEY_SIZE 7 typedef UINT8 tBTM_AUTH_REQ; diff --git a/components/bt/bluedroid/stack/include/btm_ble_api.h b/components/bt/bluedroid/stack/include/btm_ble_api.h index 927812453f..dda03d1810 100644 --- a/components/bt/bluedroid/stack/include/btm_ble_api.h +++ b/components/bt/bluedroid/stack/include/btm_ble_api.h @@ -1596,7 +1596,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start); ** *******************************************************************************/ //extern -BOOLEAN BTM_BleConfigPrivacy(BOOLEAN enable); +BOOLEAN BTM_BleConfigPrivacy(BOOLEAN enable, tBTM_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cabck); /******************************************************************************* ** diff --git a/components/bt/bluedroid/stack/include/btm_ble_int.h b/components/bt/bluedroid/stack/include/btm_ble_int.h index 055591d774..60684bdb32 100644 --- a/components/bt/bluedroid/stack/include/btm_ble_int.h +++ b/components/bt/bluedroid/stack/include/btm_ble_int.h @@ -185,6 +185,7 @@ typedef struct { tBTM_BLE_ADDR_CBACK *p_generate_cback; void *p; TIMER_LIST_ENT raddr_timer_ent; + tBTM_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback; } tBTM_LE_RANDOM_CB; #define BTM_BLE_MAX_BG_CONN_DEV_NUM 10 diff --git a/examples/bluetooth/gatt_client/main/gattc_demo.c b/examples/bluetooth/gatt_client/main/gattc_demo.c index 8d7dcd37c2..d38ce6af50 100644 --- a/examples/bluetooth/gatt_client/main/gattc_demo.c +++ b/examples/bluetooth/gatt_client/main/gattc_demo.c @@ -1,4 +1,4 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,7 +16,10 @@ /**************************************************************************** * -* This file is for gatt client. It can scan ble device, connect one device, +* This file is for gatt client. It can scan ble device, connect one device. +* Run the gatt_server demo, the client demo will automatically connect to the gatt_server demo. +* Client demo will enable gatt_server's notify after connection. Then the two devices will exchange +* data. * ****************************************************************************/ @@ -29,48 +32,49 @@ #include "controller.h" #include "bt.h" -#include "bt_trace.h" -#include "bt_types.h" -#include "btm_api.h" -#include "bta_api.h" -#include "bta_gatt_api.h" #include "esp_gap_ble_api.h" #include "esp_gattc_api.h" #include "esp_gatt_defs.h" #include "esp_bt_main.h" #define GATTC_TAG "GATTC_DEMO" +#define REMOTE_SERVICE_UUID 0x00FF +#define REMOTE_NOTIFY_CHAR_UUID 0xFF01 ///Declare static functions static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); -static void gattc_profile_a_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); -static void gattc_profile_b_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); +static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); -static esp_gatt_srvc_id_t alert_service_id = { +static esp_gatt_srvc_id_t gatt_server_demo_service_id = { .id = { .uuid = { .len = ESP_UUID_LEN_16, - .uuid = {.uuid16 = 0x1811,}, + .uuid = {.uuid16 = REMOTE_SERVICE_UUID,}, }, .inst_id = 0, }, .is_primary = true, }; +static esp_bt_uuid_t remote_filter_service_uuid = { + .len = ESP_UUID_LEN_16, + .uuid = {.uuid16 = REMOTE_SERVICE_UUID,}, +}; + static esp_gatt_id_t notify_descr_id = { .uuid = { .len = ESP_UUID_LEN_16, - .uuid = {.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG,}, + .uuid = {.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,}, }, .inst_id = 0, }; -#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" -#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] -static bool connect = false; -static const char device_name[] = "Alert Notification"; + +static bool connect = false; +static bool get_server = false; +static const char remote_device_name[] = "ESP_GATTS_DEMO"; static esp_ble_scan_params_t ble_scan_params = { .scan_type = BLE_SCAN_TYPE_ACTIVE, @@ -81,9 +85,8 @@ static esp_ble_scan_params_t ble_scan_params = { }; -#define PROFILE_NUM 2 +#define PROFILE_NUM 1 #define PROFILE_A_APP_ID 0 -#define PROFILE_B_APP_ID 1 struct gattc_profile_inst { esp_gattc_cb_t gattc_cb; @@ -96,16 +99,12 @@ struct gattc_profile_inst { /* One gatt-based profile one app_id and one gattc_if, this array will store the gattc_if returned by ESP_GATTS_REG_EVT */ static struct gattc_profile_inst gl_profile_tab[PROFILE_NUM] = { [PROFILE_A_APP_ID] = { - .gattc_cb = gattc_profile_a_event_handler, - .gattc_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ - }, - [PROFILE_B_APP_ID] = { - .gattc_cb = gattc_profile_b_event_handler, + .gattc_cb = gattc_profile_event_handler, .gattc_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ }, }; -static void gattc_profile_a_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) +static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) { uint16_t conn_id = 0; esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param; @@ -113,165 +112,128 @@ static void gattc_profile_a_event_handler(esp_gattc_cb_event_t event, esp_gatt_i switch (event) { case ESP_GATTC_REG_EVT: ESP_LOGI(GATTC_TAG, "REG_EVT"); - esp_ble_gap_set_scan_params(&ble_scan_params); + esp_err_t scan_ret = esp_ble_gap_set_scan_params(&ble_scan_params); + if (scan_ret){ + ESP_LOGE(GATTC_TAG, "set scan params error, error code = %x", scan_ret); + } break; - case ESP_GATTC_OPEN_EVT: - conn_id = p_data->open.conn_id; - - memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->open.remote_bda, sizeof(esp_bd_addr_t)); - ESP_LOGI(GATTC_TAG, "ESP_GATTC_OPEN_EVT conn_id %d, if %d, status %d, mtu %d", conn_id, gattc_if, p_data->open.status, p_data->open.mtu); - + case ESP_GATTC_CONNECT_EVT: + //p_data->connect.status always be ESP_GATT_OK + ESP_LOGI(GATTC_TAG, "ESP_GATTC_CONNECT_EVT conn_id %d, if %d, status %d", conn_id, gattc_if, p_data->connect.status); + conn_id = p_data->connect.conn_id; + gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->connect.conn_id; + memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t)); ESP_LOGI(GATTC_TAG, "REMOTE BDA:"); esp_log_buffer_hex(GATTC_TAG, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, sizeof(esp_bd_addr_t)); - - esp_ble_gattc_search_service(gattc_if, conn_id, NULL); + esp_err_t mtu_ret = esp_ble_gattc_config_mtu (gattc_if, conn_id, 200); + if (mtu_ret){ + ESP_LOGE(GATTC_TAG, "config MTU error, error code = %x", mtu_ret); + } + break; + case ESP_GATTC_OPEN_EVT: + if (param->open.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "open failed, status %d", p_data->open.status); + break; + } + ESP_LOGI(GATTC_TAG, "open success"); + break; + case ESP_GATTC_CFG_MTU_EVT: + if (param->cfg_mtu.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG,"config mtu failed, error status = %x", param->cfg_mtu.status); + } + ESP_LOGI(GATTC_TAG, "ESP_GATTC_CFG_MTU_EVT, Status %d, MTU %d, conn_id %d", param->cfg_mtu.status, param->cfg_mtu.mtu, param->cfg_mtu.conn_id); + esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid); break; case ESP_GATTC_SEARCH_RES_EVT: { esp_gatt_srvc_id_t *srvc_id = &p_data->search_res.srvc_id; conn_id = p_data->search_res.conn_id; - ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x", conn_id); - if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) { + if (srvc_id->id.uuid.len == ESP_UUID_LEN_16 && srvc_id->id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) { + get_server = true; ESP_LOGI(GATTC_TAG, "UUID16: %x", srvc_id->id.uuid.uuid.uuid16); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) { - ESP_LOGI(GATTC_TAG, "UUID32: %x", srvc_id->id.uuid.uuid.uuid32); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) { - ESP_LOGI(GATTC_TAG, "UUID128:"); - esp_log_buffer_hex(GATTC_TAG, srvc_id->id.uuid.uuid.uuid128, ESP_UUID_LEN_128); - } else { - ESP_LOGE(GATTC_TAG, "UNKNOWN LEN %d", srvc_id->id.uuid.len); } break; } case ESP_GATTC_SEARCH_CMPL_EVT: + if (p_data->search_cmpl.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "search service failed, error status = %x", p_data->search_cmpl.status); + break; + } conn_id = p_data->search_cmpl.conn_id; - ESP_LOGI(GATTC_TAG, "SEARCH_CMPL: conn_id = %x, status %d", conn_id, p_data->search_cmpl.status); - esp_ble_gattc_get_characteristic(gattc_if, conn_id, &alert_service_id, NULL); + if (get_server){ + esp_ble_gattc_get_characteristic(gattc_if, conn_id, &gatt_server_demo_service_id, NULL); + } break; case ESP_GATTC_GET_CHAR_EVT: if (p_data->get_char.status != ESP_GATT_OK) { + ESP_LOGE(GATTC_TAG, "get char failed, error status = %x", p_data->get_char.status); break; } - ESP_LOGI(GATTC_TAG, "GET CHAR: conn_id = %x, status %d", p_data->get_char.conn_id, p_data->get_char.status); + ESP_LOGI(GATTC_TAG, "get char success"); ESP_LOGI(GATTC_TAG, "GET CHAR: srvc_id = %04x, char_id = %04x", p_data->get_char.srvc_id.id.uuid.uuid.uuid16, p_data->get_char.char_id.uuid.uuid.uuid16); - if (p_data->get_char.char_id.uuid.uuid.uuid16 == 0x2a46) { - ESP_LOGI(GATTC_TAG, "register notify"); - esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, &alert_service_id, &p_data->get_char.char_id); + if (p_data->get_char.char_id.uuid.uuid.uuid16 == REMOTE_NOTIFY_CHAR_UUID) { + esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, &gatt_server_demo_service_id, &p_data->get_char.char_id); } - esp_ble_gattc_get_characteristic(gattc_if, conn_id, &alert_service_id, &p_data->get_char.char_id); + esp_ble_gattc_get_characteristic(gattc_if, conn_id, &gatt_server_demo_service_id, &p_data->get_char.char_id); break; case ESP_GATTC_REG_FOR_NOTIFY_EVT: { - uint16_t notify_en = 1; - ESP_LOGI(GATTC_TAG, "REG FOR NOTIFY: status %d", p_data->reg_for_notify.status); - ESP_LOGI(GATTC_TAG, "REG FOR_NOTIFY: srvc_id = %04x, char_id = %04x", p_data->reg_for_notify.srvc_id.id.uuid.uuid.uuid16, p_data->reg_for_notify.char_id.uuid.uuid.uuid16); + if (p_data->reg_for_notify.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "REG FOR NOTIFY failed: error status = %d", p_data->reg_for_notify.status); + break; + } - esp_ble_gattc_write_char_descr( - gattc_if, - conn_id, - &alert_service_id, - &p_data->reg_for_notify.char_id, - ¬ify_descr_id, - sizeof(notify_en), - (uint8_t *)¬ify_en, - ESP_GATT_WRITE_TYPE_RSP, - ESP_GATT_AUTH_REQ_NONE); + ESP_LOGI(GATTC_TAG, "REG FOR_NOTIFY: srvc_id = %04x, char_id = %04x", p_data->reg_for_notify.srvc_id.id.uuid.uuid.uuid16, p_data->reg_for_notify.char_id.uuid.uuid.uuid16); + uint16_t notify_en = 1; + esp_ble_gattc_write_char_descr( gattc_if, + conn_id, + &gatt_server_demo_service_id, + &p_data->reg_for_notify.char_id, + ¬ify_descr_id, + sizeof(notify_en), + (uint8_t *)¬ify_en, + ESP_GATT_WRITE_TYPE_RSP, + ESP_GATT_AUTH_REQ_NONE); break; } case ESP_GATTC_NOTIFY_EVT: - ESP_LOGI(GATTC_TAG, "NOTIFY: len %d, value %08x", p_data->notify.value_len, *(uint32_t *)p_data->notify.value); + ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, Receive notify value:"); + esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len); + //write back + esp_ble_gattc_write_char(gattc_if, + gl_profile_tab[PROFILE_A_APP_ID].conn_id, + &gatt_server_demo_service_id, + &p_data->notify.char_id, + p_data->notify.value_len, + p_data->notify.value, + ESP_GATT_WRITE_TYPE_RSP, + ESP_GATT_AUTH_REQ_NONE); break; case ESP_GATTC_WRITE_DESCR_EVT: - ESP_LOGI(GATTC_TAG, "WRITE: status %d", p_data->write.status); + if (p_data->write.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "write descr failed, error status = %x", p_data->write.status); + break; + } + ESP_LOGI(GATTC_TAG, "write descr success "); break; case ESP_GATTC_SRVC_CHG_EVT: { esp_bd_addr_t bda; memcpy(bda, p_data->srvc_chg.remote_bda, sizeof(esp_bd_addr_t)); - ESP_LOGI(GATTC_TAG, "ESP_GATTC_SRVC_CHG_EVT, bd_addr:%08x%04x",(bda[0] << 24) + (bda[1] << 16) + (bda[2] << 8) + bda[3], - (bda[4] << 8) + bda[5]); + ESP_LOGI(GATTC_TAG, "ESP_GATTC_SRVC_CHG_EVT, bd_addr:"); + esp_log_buffer_hex(GATTC_TAG, bda, sizeof(esp_bd_addr_t)); break; } - default: - break; - } -} - -static void gattc_profile_b_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) -{ - uint16_t conn_id = 0; - esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param; - - switch (event) { - case ESP_GATTC_REG_EVT: - ESP_LOGI(GATTC_TAG, "REG_EVT"); - break; - case ESP_GATTC_OPEN_EVT: - conn_id = p_data->open.conn_id; - - memcpy(gl_profile_tab[PROFILE_B_APP_ID].remote_bda, p_data->open.remote_bda, sizeof(esp_bd_addr_t)); - ESP_LOGI(GATTC_TAG, "ESP_GATTC_OPEN_EVT conn_id %d, if %d, status %d, mtu %d", conn_id, gattc_if, p_data->open.status, p_data->open.mtu); - - ESP_LOGI(GATTC_TAG, "REMOTE BDA:"); - esp_log_buffer_hex(GATTC_TAG, gl_profile_tab[PROFILE_B_APP_ID].remote_bda, sizeof(esp_bd_addr_t)); - esp_ble_gattc_search_service(gattc_if, conn_id, NULL); - break; - case ESP_GATTC_SEARCH_RES_EVT: { - esp_gatt_srvc_id_t *srvc_id = &p_data->search_res.srvc_id; - conn_id = p_data->search_res.conn_id; - ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x", conn_id); - if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) { - ESP_LOGI(GATTC_TAG, "UUID16: %x", srvc_id->id.uuid.uuid.uuid16); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) { - ESP_LOGI(GATTC_TAG, "UUID32: %x", srvc_id->id.uuid.uuid.uuid32); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) { - ESP_LOGI(GATTC_TAG, "UUID128:"); - esp_log_buffer_hex(GATTC_TAG, srvc_id->id.uuid.uuid.uuid128, ESP_UUID_LEN_128); - } else { - ESP_LOGE(GATTC_TAG, "UNKNOWN LEN %d", srvc_id->id.uuid.len); - } - break; - } - case ESP_GATTC_SEARCH_CMPL_EVT: - conn_id = p_data->search_cmpl.conn_id; - ESP_LOGI(GATTC_TAG, "SEARCH_CMPL: conn_id = %x, status %d", conn_id, p_data->search_cmpl.status); - esp_ble_gattc_get_characteristic(gattc_if, conn_id, &alert_service_id, NULL); - break; - case ESP_GATTC_GET_CHAR_EVT: - if (p_data->get_char.status != ESP_GATT_OK) { + case ESP_GATTC_WRITE_CHAR_EVT: + if (p_data->write.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "write char failed, error status = %x", p_data->write.status); break; } - ESP_LOGI(GATTC_TAG, "GET CHAR: conn_id = %x, status %d", p_data->get_char.conn_id, p_data->get_char.status); - ESP_LOGI(GATTC_TAG, "GET CHAR: srvc_id = %04x, char_id = %04x", p_data->get_char.srvc_id.id.uuid.uuid.uuid16, p_data->get_char.char_id.uuid.uuid.uuid16); - - if (p_data->get_char.char_id.uuid.uuid.uuid16 == 0x2a46) { - ESP_LOGI(GATTC_TAG, "register notify"); - esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_B_APP_ID].remote_bda, &alert_service_id, &p_data->get_char.char_id); - } - - esp_ble_gattc_get_characteristic(gattc_if, conn_id, &alert_service_id, &p_data->get_char.char_id); + ESP_LOGI(GATTC_TAG, "write char success "); break; - case ESP_GATTC_REG_FOR_NOTIFY_EVT: { - uint16_t notify_en = 1; - ESP_LOGI(GATTC_TAG, "REG FOR NOTIFY: status %d", p_data->reg_for_notify.status); - ESP_LOGI(GATTC_TAG, "REG FOR_NOTIFY: srvc_id = %04x, char_id = %04x", p_data->reg_for_notify.srvc_id.id.uuid.uuid.uuid16, p_data->reg_for_notify.char_id.uuid.uuid.uuid16); - - esp_ble_gattc_write_char_descr( - gattc_if, - conn_id, - &alert_service_id, - &p_data->reg_for_notify.char_id, - ¬ify_descr_id, - sizeof(notify_en), - (uint8_t *)¬ify_en, - ESP_GATT_WRITE_TYPE_RSP, - ESP_GATT_AUTH_REQ_NONE); - break; - } - case ESP_GATTC_NOTIFY_EVT: - ESP_LOGI(GATTC_TAG, "NOTIFY: len %d, value %08x", p_data->notify.value_len, *(uint32_t *)p_data->notify.value); - break; - case ESP_GATTC_WRITE_DESCR_EVT: - ESP_LOGI(GATTC_TAG, "WRITE: status %d", p_data->write.status); + case ESP_GATTC_DISCONNECT_EVT: + connect = false; + get_server = false; + ESP_LOGI(GATTC_TAG, "ESP_GATTC_DISCONNECT_EVT, status = %d", p_data->disconnect.status); break; default: break; @@ -292,29 +254,31 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: //scan start complete event to indicate scan start successfully or failed if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { - ESP_LOGE(GATTC_TAG, "Scan start failed"); + ESP_LOGE(GATTC_TAG, "scan start failed, error status = %x", param->scan_start_cmpl.status); + break; } + ESP_LOGI(GATTC_TAG, "scan start success"); + break; case ESP_GAP_BLE_SCAN_RESULT_EVT: { esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; switch (scan_result->scan_rst.search_evt) { case ESP_GAP_SEARCH_INQ_RES_EVT: esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6); - ESP_LOGI(GATTC_TAG, "Searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len); + ESP_LOGI(GATTC_TAG, "searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len); adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); - ESP_LOGI(GATTC_TAG, "Searched Device Name Len %d", adv_name_len); + ESP_LOGI(GATTC_TAG, "searched Device Name Len %d", adv_name_len); esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len); ESP_LOGI(GATTC_TAG, "\n"); if (adv_name != NULL) { - if (strlen(device_name) == adv_name_len && strncmp((char *)adv_name, device_name, adv_name_len) == 0) { - ESP_LOGI(GATTC_TAG, "Searched device %s\n", device_name); + if (strlen(remote_device_name) == adv_name_len && strncmp((char *)adv_name, remote_device_name, adv_name_len) == 0) { + ESP_LOGI(GATTC_TAG, "searched device %s\n", remote_device_name); if (connect == false) { connect = true; - ESP_LOGI(GATTC_TAG, "Connect to the remote device."); + ESP_LOGI(GATTC_TAG, "connect to the remote device."); esp_ble_gap_stop_scanning(); esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, scan_result->scan_rst.bda, true); - esp_ble_gattc_open(gl_profile_tab[PROFILE_B_APP_ID].gattc_if, scan_result->scan_rst.bda, true); } } } @@ -329,20 +293,18 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: if (param->scan_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){ - ESP_LOGE(GATTC_TAG, "Scan stop failed"); - } - else { - ESP_LOGI(GATTC_TAG, "Stop scan successfully"); + ESP_LOGE(GATTC_TAG, "scan stop failed, error status = %x", param->scan_stop_cmpl.status); + break; } + ESP_LOGI(GATTC_TAG, "stop scan successfully"); break; case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){ - ESP_LOGE(GATTC_TAG, "Adv stop failed"); - } - else { - ESP_LOGI(GATTC_TAG, "Stop adv successfully"); + ESP_LOGE(GATTC_TAG, "adv stop failed, error status = %x", param->adv_stop_cmpl.status); + break; } + ESP_LOGI(GATTC_TAG, "stop adv successfully"); break; default: @@ -359,8 +321,8 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp if (param->reg.status == ESP_GATT_OK) { gl_profile_tab[param->reg.app_id].gattc_if = gattc_if; } else { - ESP_LOGI(GATTC_TAG, "Reg app failed, app_id %04x, status %d", - param->reg.app_id, + ESP_LOGI(GATTC_TAG, "reg app failed, app_id %04x, status %d", + param->reg.app_id, param->reg.status); return; } @@ -381,34 +343,6 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp } while (0); } -void ble_client_appRegister(void) -{ - esp_err_t status; - - ESP_LOGI(GATTC_TAG, "register callback"); - - //register the scan callback function to the gap module - if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) { - ESP_LOGE(GATTC_TAG, "gap register error, error code = %x", status); - return; - } - - //register the callback function to the gattc module - if ((status = esp_ble_gattc_register_callback(esp_gattc_cb)) != ESP_OK) { - ESP_LOGE(GATTC_TAG, "gattc register error, error code = %x", status); - return; - } - esp_ble_gattc_app_register(PROFILE_A_APP_ID); - esp_ble_gattc_app_register(PROFILE_B_APP_ID); -} - -void gattc_client_test(void) -{ - esp_bluedroid_init(); - esp_bluedroid_enable(); - ble_client_appRegister(); -} - void app_main() { // Initialize NVS. @@ -420,9 +354,48 @@ void app_main() ESP_ERROR_CHECK( ret ); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - esp_bt_controller_init(&bt_cfg); - esp_bt_controller_enable(ESP_BT_MODE_BTDM); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s initialize controller failed, error code = %x\n", __func__, ret); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s enable controller failed, error code = %x\n", __func__, ret); + return; + } + + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s init bluetooth failed, error code = %x\n", __func__, ret); + return; + } + + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s enable bluetooth failed, error code = %x\n", __func__, ret); + return; + } + + //register the callback function to the gap module + ret = esp_ble_gap_register_callback(esp_gap_cb); + if (ret){ + ESP_LOGE(GATTC_TAG, "%s gap register failed, error code = %x\n", __func__, ret); + return; + } + + //register the callback function to the gattc module + ret = esp_ble_gattc_register_callback(esp_gattc_cb); + if(ret){ + ESP_LOGE(GATTC_TAG, "%s gattc register failed, error code = %x\n", __func__, ret); + return; + } + + ret = esp_ble_gattc_app_register(PROFILE_A_APP_ID); + if (ret){ + ESP_LOGE(GATTC_TAG, "%s gattc app register failed, error code = %x\n", __func__, ret); + } - gattc_client_test(); } diff --git a/examples/bluetooth/gatt_client/sdkconfig.defaults b/examples/bluetooth/gatt_client/sdkconfig.defaults index 9d51df5ee5..14f5546ffa 100644 --- a/examples/bluetooth/gatt_client/sdkconfig.defaults +++ b/examples/bluetooth/gatt_client/sdkconfig.defaults @@ -1,4 +1,3 @@ # Override some defaults so BT stack is enabled -# and WiFi disabled by default in this example +# by default in this example CONFIG_BT_ENABLED=y -CONFIG_WIFI_ENABLED=n diff --git a/examples/bluetooth/gatt_security_client/Makefile b/examples/bluetooth/gatt_security_client/Makefile new file mode 100644 index 0000000000..551e25a044 --- /dev/null +++ b/examples/bluetooth/gatt_security_client/Makefile @@ -0,0 +1,10 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := sec_gattc_demo + +COMPONENT_ADD_INCLUDEDIRS := components/include + +include $(IDF_PATH)/make/project.mk diff --git a/examples/bluetooth/gatt_security_client/README.rst b/examples/bluetooth/gatt_security_client/README.rst new file mode 100644 index 0000000000..906f756bf9 --- /dev/null +++ b/examples/bluetooth/gatt_security_client/README.rst @@ -0,0 +1,8 @@ +ESP-IDF GATT SECURITY CLIENT DEMO +======================== + +This is the demo for user to use ESP BLE security API to connection with peer device & communication. +1.Should used the esp_ble_gap_set_security_param API to set the security parameter to the BLE stack in the init stage; +2.Used the esp_ble_set_encryption API to start encryption with peer device, if the peer device take the initiative encryption, should used the esp_ble_gap_security_rsp API to sent response to peer device when receive the ESP_GAP_BLE_SEC_REQ_EVT. +3.It will receive the ESP_GAP_BLE_AUTH_CMPL_EVT event when encryption finish will peer device. + diff --git a/examples/bluetooth/gatt_security_client/main/component.mk b/examples/bluetooth/gatt_security_client/main/component.mk new file mode 100644 index 0000000000..a98f634eae --- /dev/null +++ b/examples/bluetooth/gatt_security_client/main/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/bluetooth/gatt_security_client/main/example_ble_sec_gattc_demo.c b/examples/bluetooth/gatt_security_client/main/example_ble_sec_gattc_demo.c new file mode 100644 index 0000000000..aa2ce9dfe5 --- /dev/null +++ b/examples/bluetooth/gatt_security_client/main/example_ble_sec_gattc_demo.c @@ -0,0 +1,460 @@ +// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + + +/**************************************************************************** +* +* This file is for gatt_security_client demo. It can scan ble device, connect one device that needs to be encrypted. +* run gatt_security_server demo, the gatt_security_client demo will automatically connect the gatt_security_server, +* then paring and bonding. +* +****************************************************************************/ + +#include +#include +#include +#include +#include "nvs.h" +#include "nvs_flash.h" +#include "controller.h" + +#include "bt.h" +#include "esp_gap_ble_api.h" +#include "esp_gattc_api.h" +#include "esp_gatt_defs.h" +#include "esp_bt_main.h" + +#define GATTC_TAG "SEC_GATTC_DEMO" +#define REMOTE_SERVICE_UUID 0x1809 +#define REMOTE_NOTIFY_UUID 0x2A37 + +///Declare static functions +static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); +static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); +static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); + + + +static esp_gatt_srvc_id_t heart_rate_service_id = { + .id = { + .uuid = { + .len = ESP_UUID_LEN_16, + .uuid = {.uuid16 = REMOTE_SERVICE_UUID,}, + }, + .inst_id = 0, + }, + .is_primary = true, +}; + +static esp_bt_uuid_t remote_filter_service_uuid = { + .len = ESP_UUID_LEN_16, + .uuid = {.uuid16 = REMOTE_SERVICE_UUID,}, +}; + +static esp_gatt_id_t remote_notify_descr_id = { + .uuid = { + .len = ESP_UUID_LEN_16, + .uuid = {.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,}, + }, + .inst_id = 0, +}; + + +static bool connect = false; +static bool get_service = false; +static const char remote_device_name[] = "ESP_BLE_SECURITY"; + +static esp_ble_scan_params_t ble_scan_params = { + .scan_type = BLE_SCAN_TYPE_ACTIVE, + .own_addr_type = BLE_ADDR_TYPE_RANDOM, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_interval = 0x50, + .scan_window = 0x30 +}; + + +#define PROFILE_NUM 1 +#define PROFILE_A_APP_ID 0 + +struct gattc_profile_inst { + esp_gattc_cb_t gattc_cb; + uint16_t gattc_if; + uint16_t app_id; + uint16_t conn_id; + esp_bd_addr_t remote_bda; +}; + +/* One gatt-based profile one app_id and one gattc_if, this array will store the gattc_if returned by ESP_GATTS_REG_EVT */ +static struct gattc_profile_inst gl_profile_tab[PROFILE_NUM] = { + [PROFILE_A_APP_ID] = { + .gattc_cb = gattc_profile_event_handler, + .gattc_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ + }, +}; + +static char *esp_key_type_to_str(esp_ble_key_type_t key_type) +{ + char *key_str = NULL; + switch(key_type) { + case ESP_LE_KEY_NONE: + key_str = "ESP_LE_KEY_NONE"; + break; + case ESP_LE_KEY_PENC: + key_str = "ESP_LE_KEY_PENC"; + break; + case ESP_LE_KEY_PID: + key_str = "ESP_LE_KEY_PID"; + break; + case ESP_LE_KEY_PCSRK: + key_str = "ESP_LE_KEY_PCSRK"; + break; + case ESP_LE_KEY_PLK: + key_str = "ESP_LE_KEY_PLK"; + break; + case ESP_LE_KEY_LLK: + key_str = "ESP_LE_KEY_LLK"; + break; + case ESP_LE_KEY_LENC: + key_str = "ESP_LE_KEY_LENC"; + break; + case ESP_LE_KEY_LID: + key_str = "ESP_LE_KEY_LID"; + break; + case ESP_LE_KEY_LCSRK: + key_str = "ESP_LE_KEY_LCSRK"; + break; + default: + key_str = "INVALID BLE KEY TYPE"; + break; + + } + return key_str; +} + +static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) +{ + uint16_t conn_id = 0; + esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param; + + switch (event) { + case ESP_GATTC_REG_EVT: + ESP_LOGI(GATTC_TAG, "REG_EVT"); + esp_ble_gap_config_local_privacy(true); + break; + case ESP_GATTC_OPEN_EVT: + if (param->open.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "open failed, error status = %x", p_data->open.status); + break; + } + ESP_LOGI(GATTC_TAG, "open success"); + conn_id = p_data->open.conn_id; + gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->open.conn_id; + memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->open.remote_bda, sizeof(esp_bd_addr_t)); + ESP_LOGI(GATTC_TAG, "REMOTE BDA:"); + esp_log_buffer_hex(GATTC_TAG, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, sizeof(esp_bd_addr_t)); + esp_err_t mtu_ret = esp_ble_gattc_config_mtu (gattc_if, conn_id, 200); + if (mtu_ret){ + ESP_LOGE(GATTC_TAG, "config MTU error, error code = %x", mtu_ret); + } + break; + case ESP_GATTC_CFG_MTU_EVT: + if (param->cfg_mtu.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG,"config mtu failed, error status = %x", param->cfg_mtu.status); + } + ESP_LOGI(GATTC_TAG, "ESP_GATTC_CFG_MTU_EVT, Status %d, MTU %d, conn_id %d", param->cfg_mtu.status, param->cfg_mtu.mtu, param->cfg_mtu.conn_id); + esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid); + break; + case ESP_GATTC_SEARCH_RES_EVT: { + esp_gatt_srvc_id_t *srvc_id = &p_data->search_res.srvc_id; + conn_id = p_data->search_res.conn_id; + ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x", conn_id); + if (srvc_id->id.uuid.len == ESP_UUID_LEN_16 && srvc_id->id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) { + ESP_LOGI(GATTC_TAG, "UUID16: %x", srvc_id->id.uuid.uuid.uuid16); + get_service = true; + } + break; + } + case ESP_GATTC_SEARCH_CMPL_EVT: + if (p_data->search_cmpl.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "search service failed, error status = %x", p_data->search_cmpl.status); + break; + } + conn_id = p_data->search_cmpl.conn_id; + if (get_service){ + esp_ble_gattc_get_characteristic(gattc_if, conn_id, &heart_rate_service_id, NULL); + } + + break; + case ESP_GATTC_GET_CHAR_EVT: + if (p_data->get_char.status != ESP_GATT_OK) { + ESP_LOGE(GATTC_TAG, "get char failed, error status = %x", p_data->get_char.status); + break; + } + ESP_LOGI(GATTC_TAG, "GET CHAR: conn_id = %x, status %d", p_data->get_char.conn_id, p_data->get_char.status); + ESP_LOGI(GATTC_TAG, "GET CHAR: srvc_id = %04x, char_id = %04x", p_data->get_char.srvc_id.id.uuid.uuid.uuid16, p_data->get_char.char_id.uuid.uuid.uuid16); + + if (p_data->get_char.char_id.uuid.uuid.uuid16 == REMOTE_NOTIFY_UUID) { + ESP_LOGI(GATTC_TAG, "register notify"); + esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, &heart_rate_service_id, &p_data->get_char.char_id); + } + + esp_ble_gattc_get_characteristic(gattc_if, conn_id, &heart_rate_service_id, &p_data->get_char.char_id); + break; + case ESP_GATTC_REG_FOR_NOTIFY_EVT: { + if (p_data->reg_for_notify.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "reg for notify failed, error status = %x", p_data->reg_for_notify.status); + break; + } + + ESP_LOGI(GATTC_TAG, "REG FOR_NOTIFY: srvc_id = %04x, char_id = %04x", p_data->reg_for_notify.srvc_id.id.uuid.uuid.uuid16, p_data->reg_for_notify.char_id.uuid.uuid.uuid16); + uint16_t notify_en = 1; + esp_ble_gattc_write_char_descr( gattc_if, + conn_id, + &heart_rate_service_id, + &p_data->reg_for_notify.char_id, + &remote_notify_descr_id, + sizeof(notify_en), + (uint8_t *)¬ify_en, + ESP_GATT_WRITE_TYPE_RSP, + ESP_GATT_AUTH_REQ_NONE); + break; + } + case ESP_GATTC_NOTIFY_EVT: + ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive notify value:"); + esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len); + //write back + esp_ble_gattc_write_char(gattc_if, + gl_profile_tab[PROFILE_A_APP_ID].conn_id, + &heart_rate_service_id, + &p_data->notify.char_id, + p_data->notify.value_len, + p_data->notify.value, + ESP_GATT_WRITE_TYPE_RSP, + ESP_GATT_AUTH_REQ_NONE); + break; + case ESP_GATTC_WRITE_DESCR_EVT: + if (p_data->write.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "write descr failed, error status = %x", p_data->write.status); + break; + } + ESP_LOGI(GATTC_TAG, "write descr success"); + break; + case ESP_GATTC_SRVC_CHG_EVT: { + esp_bd_addr_t bda; + memcpy(bda, p_data->srvc_chg.remote_bda, sizeof(esp_bd_addr_t)); + ESP_LOGI(GATTC_TAG, "ESP_GATTC_SRVC_CHG_EVT, bd_addr:"); + esp_log_buffer_hex(GATTC_TAG, bda, sizeof(esp_bd_addr_t)); + break; + } + case ESP_GATTC_WRITE_CHAR_EVT: + if (p_data->write.status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "write char failed, error status = %x", p_data->write.status); + break; + } + ESP_LOGI(GATTC_TAG, "Write char success "); + break; + case ESP_GATTC_DISCONNECT_EVT: + ESP_LOGI(GATTC_TAG, "ESP_GATTC_DISCONNECT_EVT, status = %d", p_data->disconnect.status); + connect = false; + get_service = false; + break; + default: + break; + } +} + +static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + uint8_t *adv_name = NULL; + uint8_t adv_name_len = 0; + switch (event) { + case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT: + if (param->local_privacy_cmpl.status != ESP_BT_STATUS_SUCCESS){ + ESP_LOGE(GATTC_TAG, "config local privacy failed, error code =%x", param->local_privacy_cmpl.status); + break; + } + esp_err_t scan_ret = esp_ble_gap_set_scan_params(&ble_scan_params); + if (scan_ret){ + ESP_LOGE(GATTC_TAG, "set scan params error, error code = %x", scan_ret); + } + break; + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { + //the unit of the duration is second + uint32_t duration = 30; + esp_ble_gap_start_scanning(duration); + break; + } + case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: + //scan start complete event to indicate scan start successfully or failed + if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(GATTC_TAG, "scan start failed, error status = %x", param->scan_start_cmpl.status); + break; + } + ESP_LOGI(GATTC_TAG, "Scan start success"); + break; + case ESP_GAP_BLE_SEC_REQ_EVT: + /* send the positive(true) security response to the peer device to accept the security request. + If not accept the security request, should sent the security response with negative(false) accept value*/ + esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true); + break; + case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: ///the app will receive this evt when the IO has Output capability and the peer device IO has Input capability. + ///show the passkey number to the user to input it in the peer deivce. + ESP_LOGE(GATTC_TAG, "The passkey Notify number:%d", param->ble_security.key_notif.passkey); + break; + case ESP_GAP_BLE_KEY_EVT: + //shows the ble key info share with peer device to the user. + ESP_LOGI(GATTC_TAG, "key type = %s", esp_key_type_to_str(param->ble_security.ble_key.key_type)); + break; + case ESP_GAP_BLE_AUTH_CMPL_EVT: { + esp_bd_addr_t bd_addr; + memcpy(bd_addr, param->ble_security.auth_cmpl.bd_addr, sizeof(esp_bd_addr_t)); + ESP_LOGI(GATTC_TAG, "remote BD_ADDR: %08x%04x",\ + (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3], + (bd_addr[4] << 8) + bd_addr[5]); + ESP_LOGI(GATTC_TAG, "address type = %d", param->ble_security.auth_cmpl.addr_type); + ESP_LOGI(GATTC_TAG, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail"); + break; + } + case ESP_GAP_BLE_SCAN_RESULT_EVT: { + esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; + switch (scan_result->scan_rst.search_evt) { + case ESP_GAP_SEARCH_INQ_RES_EVT: + esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6); + ESP_LOGI(GATTC_TAG, "Searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len); + adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, + ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + ESP_LOGI(GATTC_TAG, "Searched Device Name Len %d", adv_name_len); + esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len); + ESP_LOGI(GATTC_TAG, "\n"); + if (adv_name != NULL) { + if (strlen(remote_device_name) == adv_name_len && strncmp((char *)adv_name, remote_device_name, adv_name_len) == 0) { + ESP_LOGI(GATTC_TAG, "searched device %s\n", remote_device_name); + if (connect == false) { + connect = true; + ESP_LOGI(GATTC_TAG, "connect to the remote device."); + esp_ble_gap_stop_scanning(); + esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, scan_result->scan_rst.bda, true); + } + } + } + break; + case ESP_GAP_SEARCH_INQ_CMPL_EVT: + break; + default: + break; + } + break; + } + + case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: + if (param->scan_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){ + ESP_LOGE(GATTC_TAG, "Scan stop failed, error status = %x", param->scan_stop_cmpl.status); + break; + } + ESP_LOGI(GATTC_TAG, "Stop scan successfully"); + break; + + default: + break; + } +} + +static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) +{ + ESP_LOGI(GATTC_TAG, "EVT %d, gattc if %d", event, gattc_if); + + /* If event is register event, store the gattc_if for each profile */ + if (event == ESP_GATTC_REG_EVT) { + if (param->reg.status == ESP_GATT_OK) { + gl_profile_tab[param->reg.app_id].gattc_if = gattc_if; + } else { + ESP_LOGI(GATTC_TAG, "Reg app failed, app_id %04x, status %d", + param->reg.app_id, + param->reg.status); + return; + } + } + + /* If the gattc_if equal to profile A, call profile A cb handler, + * so here call each profile's callback */ + do { + int idx; + for (idx = 0; idx < PROFILE_NUM; idx++) { + if (gattc_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */ + gattc_if == gl_profile_tab[idx].gattc_if) { + if (gl_profile_tab[idx].gattc_cb) { + gl_profile_tab[idx].gattc_cb(event, gattc_if, param); + } + } + } + } while (0); +} + +void app_main() +{ + // Initialize NVS. + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK( ret ); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s initialize controller failed, error code = %x\n", __func__, ret); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s enable controller failed, error code = %x\n", __func__, ret); + return; + } + + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s init bluetooth failed, error code = %x\n", __func__, ret); + return; + } + + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(GATTC_TAG, "%s enable bluetooth failed, error code = %x\n", __func__, ret); + return; + } + + //register the callback function to the gap module + ret = esp_ble_gap_register_callback(esp_gap_cb); + if (ret){ + ESP_LOGE(GATTC_TAG, "%s gap register error, error code = %x\n", __func__, ret); + return; + } + + //register the callback function to the gattc module + ret = esp_ble_gattc_register_callback(esp_gattc_cb); + if(ret){ + ESP_LOGE(GATTC_TAG, "%s gattc register error, error code = %x\n", __func__, ret); + return; + } + + ret = esp_ble_gattc_app_register(PROFILE_A_APP_ID); + if (ret){ + ESP_LOGE(GATTC_TAG, "%s gattc app register error, error code = %x\n", __func__, ret); + } + +} + diff --git a/examples/bluetooth/gatt_security_client/sdkconfig.defaults b/examples/bluetooth/gatt_security_client/sdkconfig.defaults new file mode 100644 index 0000000000..9d51df5ee5 --- /dev/null +++ b/examples/bluetooth/gatt_security_client/sdkconfig.defaults @@ -0,0 +1,4 @@ +# Override some defaults so BT stack is enabled +# and WiFi disabled by default in this example +CONFIG_BT_ENABLED=y +CONFIG_WIFI_ENABLED=n diff --git a/examples/bluetooth/gatt_security_server/main/example_ble_sec_gatts_demo.c b/examples/bluetooth/gatt_security_server/main/example_ble_sec_gatts_demo.c index 4b708f3ab2..67ec0aa2d0 100644 --- a/examples/bluetooth/gatt_security_server/main/example_ble_sec_gatts_demo.c +++ b/examples/bluetooth/gatt_security_server/main/example_ble_sec_gatts_demo.c @@ -261,6 +261,23 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail"); break; } + case ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT: { + ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT status = %d", param->remove_bond_dev_cmpl.status); + break; + } + case ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT: { + ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT status = %d", param->clear_bond_dev_cmpl.status); + break; + } + case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: { + ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT status = %d, num = %d", param->get_bond_dev_cmpl.status, param->get_bond_dev_cmpl.dev_num); + esp_ble_bond_dev_t *bond_dev = param->get_bond_dev_cmpl.bond_dev; + for(int i = 0; i < param->get_bond_dev_cmpl.dev_num; i++) { + ESP_LOGD(GATTS_TABLE_TAG, "mask = %x", bond_dev[i].bond_key.key_mask); + esp_log_buffer_hex(GATTS_TABLE_TAG, (void *)bond_dev[i].bd_addr, sizeof(esp_bd_addr_t)); + } + break; + } default: break; } diff --git a/examples/bluetooth/gatt_security_server/sdkconfig.defaults b/examples/bluetooth/gatt_security_server/sdkconfig.defaults index 9d51df5ee5..14f5546ffa 100644 --- a/examples/bluetooth/gatt_security_server/sdkconfig.defaults +++ b/examples/bluetooth/gatt_security_server/sdkconfig.defaults @@ -1,4 +1,3 @@ # Override some defaults so BT stack is enabled -# and WiFi disabled by default in this example +# by default in this example CONFIG_BT_ENABLED=y -CONFIG_WIFI_ENABLED=n diff --git a/examples/bluetooth/gatt_server/README.rst b/examples/bluetooth/gatt_server/README.rst index bbfd76626c..a4fa38d0aa 100644 --- a/examples/bluetooth/gatt_server/README.rst +++ b/examples/bluetooth/gatt_server/README.rst @@ -1,20 +1,8 @@ ESP-IDF GATT SERVER demo ======================== -This is the demo for user to use ESP_APIs to create a GATT Server. - -Options choose step: - 1. make menuconfig. - 2. enter menuconfig "Component config". - 3. enter menuconfig "Example 'GATT SERVER' Config". - 4. choose your options. - -UPDATE NOTE -=========== - -2017-01-19: - 1. Use New APIs to set raw advertising data and raw scan response data. - 2. Could use macro CONFIG_SET_RAW_ADV_DATA (should use menuconfig) to config use raw advertising/scan_response - or use structure do automatically config. The macro CONFIG_SET_RAW_ADV will effect both advertising data - and scan_response data. +This is the demo for user to use ESP_APIs to create a GATT Server.The demo can send adv data, +be connected by client. Run the gatt_client demo, the client demo will automatically connect +to the gatt_server demo. The client demo will enable gatt_server's notify after connection. +Then the two devices will exchange data. diff --git a/examples/bluetooth/gatt_server/main/gatts_demo.c b/examples/bluetooth/gatt_server/main/gatts_demo.c index a49e3f81c6..b6e15b9dde 100644 --- a/examples/bluetooth/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/gatt_server/main/gatts_demo.c @@ -1,4 +1,4 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,6 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. +/**************************************************************************** +* +* This file is for gatt server. It can send adv data, be connected by clent. +* Run the gatt_client demo, the client demo will automatically connect to the gatt_server demo. +* Client demo will enable gatt_server's notify after connection. Then two devices will exchange +* data. +* +****************************************************************************/ + + #include #include #include @@ -22,7 +32,6 @@ #include "esp_log.h" #include "nvs_flash.h" #include "bt.h" -#include "bta_api.h" #include "esp_gap_ble_api.h" #include "esp_gatts_api.h" @@ -34,7 +43,7 @@ #define GATTS_TAG "GATTS_DEMO" -///Declare the static function +///Declare the static function static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); @@ -56,13 +65,20 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i #define PREPARE_BUF_MAX_SIZE 1024 uint8_t char1_str[] = {0x11,0x22,0x33}; -esp_attr_value_t gatts_demo_char1_val = +esp_gatt_char_prop_t a_property = 0; +esp_gatt_char_prop_t b_property = 0; + +esp_attr_value_t gatts_demo_char1_val = { .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX, .attr_len = sizeof(char1_str), .attr_value = char1_str, }; +static uint8_t adv_config_done = 0; +#define adv_config_flag (1 << 0) +#define scan_rsp_config_flag (1 << 1) + #ifdef CONFIG_SET_RAW_ADV_DATA static uint8_t raw_adv_data[] = { 0x02, 0x01, 0x06, @@ -73,16 +89,19 @@ static uint8_t raw_scan_rsp_data[] = { 0x45, 0x4d, 0x4f }; #else -static uint8_t test_service_uuid128[32] = { + +static uint8_t adv_service_uuid128[32] = { /* LSB <--------------------------------------------------------------------------------> MSB */ //first uuid, 16bit, [12],[13] is the value - 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0x00, 0x00, + 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xEE, 0x00, 0x00, 0x00, //second uuid, 32bit, [12], [13], [14], [15] is the value - 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0xAB, 0xCD, + 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, }; +// The length of adv data must be less than 31 bytes //static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, 0x45, 0x56}; -static esp_ble_adv_data_t test_adv_data = { +//adv data +static esp_ble_adv_data_t adv_data = { .set_scan_rsp = false, .include_name = true, .include_txpower = true, @@ -94,12 +113,29 @@ static esp_ble_adv_data_t test_adv_data = { .service_data_len = 0, .p_service_data = NULL, .service_uuid_len = 32, - .p_service_uuid = test_service_uuid128, + .p_service_uuid = adv_service_uuid128, .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT), }; +// scan response data +static esp_ble_adv_data_t scan_rsp_data = { + .set_scan_rsp = true, + .include_name = true, + .include_txpower = true, + .min_interval = 0x20, + .max_interval = 0x40, + .appearance = 0x00, + .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, + .p_manufacturer_data = NULL, //&test_manufacturer[0], + .service_data_len = 0, + .p_service_data = NULL, + .service_uuid_len = 32, + .p_service_uuid = adv_service_uuid128, + .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT), +}; + #endif /* CONFIG_SET_RAW_ADV_DATA */ -static esp_ble_adv_params_t test_adv_params = { +static esp_ble_adv_params_t adv_params = { .adv_int_min = 0x20, .adv_int_max = 0x40, .adv_type = ADV_TYPE_IND, @@ -155,15 +191,33 @@ void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { switch (event) { - case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; +#ifdef CONFIG_SET_RAW_ADV_DATA case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); + adv_config_done &= (~adv_config_flag); + if (adv_config_done==0){ + esp_ble_gap_start_advertising(&adv_params); + } break; case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); + adv_config_done &= (~scan_rsp_config_flag); + if (adv_config_done==0){ + esp_ble_gap_start_advertising(&adv_params); + } break; +#else + case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: + adv_config_done &= (~adv_config_flag); + if (adv_config_done == 0){ + esp_ble_gap_start_advertising(&adv_params); + } + break; + case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: + adv_config_done &= (~scan_rsp_config_flag); + if (adv_config_done == 0){ + esp_ble_gap_start_advertising(&adv_params); + } + break; +#endif case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: //advertising start complete event to indicate advertising start successfully or failed if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { @@ -200,7 +254,7 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE*sizeof(uint8_t)); prepare_write_env->prepare_len = 0; if (prepare_write_env->prepare_buf == NULL) { - LOG_ERROR("Gatt_server prep no mem\n"); + ESP_LOGE(GATTS_TAG, "Gatt_server prep no mem\n"); status = ESP_GATT_NO_RESOURCES; } } else { @@ -219,7 +273,7 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len); esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp); if (response_err != ESP_OK){ - LOG_ERROR("Send response error\n"); + ESP_LOGE(GATTS_TAG, "Send response error\n"); } free(gatt_rsp); if (status != ESP_GATT_OK){ @@ -260,10 +314,30 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i esp_ble_gap_set_device_name(TEST_DEVICE_NAME); #ifdef CONFIG_SET_RAW_ADV_DATA - esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data)); - esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data)); + esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data)); + if (raw_adv_ret){ + ESP_LOGE(GATTS_TAG, "config raw adv data failed, error code = %x ", raw_adv_ret); + } + adv_config_done |= adv_config_flag; + esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data)); + if (raw_scan_ret){ + ESP_LOGE(GATTS_TAG, "config raw scan rsp data failed, error code = %x", raw_scan_ret); + } + adv_config_done |= scan_rsp_config_flag; #else - esp_ble_gap_config_adv_data(&test_adv_data); + //config adv data + esp_err_t ret = esp_ble_gap_config_adv_data(&adv_data); + if (ret){ + ESP_LOGE(GATTS_TAG, "config adv data failed, error code = %x", ret); + } + adv_config_done |= adv_config_flag; + //config scan response data + ret = esp_ble_gap_config_adv_data(&scan_rsp_data); + if (ret){ + ESP_LOGE(GATTS_TAG, "config scan response data failed, error code = %x", ret); + } + adv_config_done |= scan_rsp_config_flag; + #endif esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_A); break; @@ -282,8 +356,46 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i break; } case ESP_GATTS_WRITE_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, param->write.trans_id, param->write.handle); - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %08x\n", param->write.len, *(uint32_t *)param->write.value); + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d", param->write.conn_id, param->write.trans_id, param->write.handle); + if (!param->write.is_prep){ + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len); + esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len); + if (gl_profile_tab[PROFILE_A_APP_ID].descr_handle == param->write.handle && param->write.len == 2){ + uint16_t descr_value = param->write.value[1]<<8 | param->write.value[0]; + if (descr_value == 0x0001){ + if (a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY){ + ESP_LOGI(GATTS_TAG, "notify enable"); + uint8_t notify_data[15]; + for (int i = 0; i < sizeof(notify_data); ++i) + { + notify_data[i] = i%0xff; + } + //the size of notify_data[] need less than MTU size + esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle, + sizeof(notify_data), notify_data, false); + } + }else if (descr_value == 0x0002){ + if (a_property & ESP_GATT_CHAR_PROP_BIT_INDICATE){ + ESP_LOGI(GATTS_TAG, "indicate enable"); + uint8_t indicate_data[15]; + for (int i = 0; i < sizeof(indicate_data); ++i) + { + indicate_data[i] = i%0xff; + } + //the size of indicate_data[] need less than MTU size + esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle, + sizeof(indicate_data), indicate_data, true); + } + } + else if (descr_value == 0x0000){ + ESP_LOGI(GATTS_TAG, "notify/indicate disable "); + }else{ + ESP_LOGE(GATTS_TAG, "unknown descr value"); + esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len); + } + + } + } example_write_event_env(gatts_if, &a_prepare_write_env, param); break; } @@ -293,6 +405,8 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i example_exec_write_event_env(&a_prepare_write_env, param); break; case ESP_GATTS_MTU_EVT: + ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu); + break; case ESP_GATTS_CONF_EVT: case ESP_GATTS_UNREG_EVT: break; @@ -303,11 +417,14 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A; esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle); - - esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, - ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, - &gatts_demo_char1_val, NULL); + a_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY; + esp_err_t add_char_ret = esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, + a_property, + &gatts_demo_char1_val, NULL); + if (add_char_ret){ + ESP_LOGE(GATTS_TAG, "add char failed, error code =%x",add_char_ret); + } break; case ESP_GATTS_ADD_INCL_SRVC_EVT: break; @@ -320,17 +437,24 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle; gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; - esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char); + esp_err_t get_attr_ret = esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char); + if (get_attr_ret == ESP_FAIL){ + ESP_LOGE(GATTS_TAG, "ILLEGAL HANDLE"); + } ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length); for(int i = 0; i < length; i++){ ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n",i,prf_char[i]); } - esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); + esp_err_t add_descr_ret = esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); + if (add_descr_ret){ + ESP_LOGE(GATTS_TAG, "add char descr failed, error code =%x", add_descr_ret); + } break; } case ESP_GATTS_ADD_CHAR_DESCR_EVT: + gl_profile_tab[PROFILE_A_APP_ID].descr_handle = param->add_char.attr_handle; ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); break; @@ -350,7 +474,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i conn_params.max_int = 0x50; // max_int = 0x50*1.25ms = 100ms conn_params.min_int = 0x30; // min_int = 0x30*1.25ms = 60ms conn_params.timeout = 400; // timeout = 400*10ms = 4000ms - ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n", + ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d", param->connect.conn_id, param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2], param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5], @@ -361,7 +485,8 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i break; } case ESP_GATTS_DISCONNECT_EVT: - esp_ble_gap_start_advertising(&test_adv_params); + ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT"); + esp_ble_gap_start_advertising(&adv_params); break; case ESP_GATTS_OPEN_EVT: case ESP_GATTS_CANCEL_OPEN_EVT: @@ -400,7 +525,44 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i } case ESP_GATTS_WRITE_EVT: { ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, param->write.trans_id, param->write.handle); - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %08x\n", param->write.len, *(uint32_t *)param->write.value); + if (!param->write.is_prep){ + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len); + esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len); + if (gl_profile_tab[PROFILE_B_APP_ID].descr_handle == param->write.handle && param->write.len == 2){ + uint16_t descr_value= param->write.value[1]<<8 | param->write.value[0]; + if (descr_value == 0x0001){ + if (b_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY){ + ESP_LOGI(GATTS_TAG, "notify enable"); + uint8_t notify_data[15]; + for (int i = 0; i < sizeof(notify_data); ++i) + { + notify_data[i] = i%0xff; + } + //the size of notify_data[] need less than MTU size + esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_B_APP_ID].char_handle, + sizeof(notify_data), notify_data, false); + } + }else if (descr_value == 0x0002){ + if (b_property & ESP_GATT_CHAR_PROP_BIT_INDICATE){ + ESP_LOGI(GATTS_TAG, "indicate enable"); + uint8_t indicate_data[15]; + for (int i = 0; i < sizeof(indicate_data); ++i) + { + indicate_data[i] = i%0xff; + } + //the size of indicate_data[] need less than MTU size + esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_B_APP_ID].char_handle, + sizeof(indicate_data), indicate_data, true); + } + } + else if (descr_value == 0x0000){ + ESP_LOGI(GATTS_TAG, "notify/indicate disable "); + }else{ + ESP_LOGE(GATTS_TAG, "unknown value"); + } + + } + } example_write_event_env(gatts_if, &b_prepare_write_env, param); break; } @@ -410,6 +572,8 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i example_exec_write_event_env(&b_prepare_write_env, param); break; case ESP_GATTS_MTU_EVT: + ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu); + break; case ESP_GATTS_CONF_EVT: case ESP_GATTS_UNREG_EVT: break; @@ -420,11 +584,14 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i gl_profile_tab[PROFILE_B_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_B; esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle); - - esp_ble_gatts_add_char(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, - ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, - NULL, NULL); + b_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY; + esp_err_t add_char_ret =esp_ble_gatts_add_char( gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, + b_property, + NULL, NULL); + if (add_char_ret){ + ESP_LOGE(GATTS_TAG, "add char failed, error code =%x",add_char_ret); + } break; case ESP_GATTS_ADD_INCL_SRVC_EVT: break; @@ -440,6 +607,7 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i NULL, NULL); break; case ESP_GATTS_ADD_CHAR_DESCR_EVT: + gl_profile_tab[PROFILE_B_APP_ID].descr_handle = param->add_char.attr_handle; ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); break; @@ -452,7 +620,7 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i case ESP_GATTS_STOP_EVT: break; case ESP_GATTS_CONNECT_EVT: - ESP_LOGI(GATTS_TAG, "CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n", + ESP_LOGI(GATTS_TAG, "CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d", param->connect.conn_id, param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2], param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5], @@ -478,7 +646,7 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_ gl_profile_tab[param->reg.app_id].gatts_if = gatts_if; } else { ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d\n", - param->reg.app_id, + param->reg.app_id, param->reg.status); return; } @@ -534,10 +702,26 @@ void app_main() return; } - esp_ble_gatts_register_callback(gatts_event_handler); - esp_ble_gap_register_callback(gap_event_handler); - esp_ble_gatts_app_register(PROFILE_A_APP_ID); - esp_ble_gatts_app_register(PROFILE_B_APP_ID); + ret = esp_ble_gatts_register_callback(gatts_event_handler); + if (ret){ + ESP_LOGE(GATTS_TAG, "gatts register error, error code = %x", ret); + return; + } + ret = esp_ble_gap_register_callback(gap_event_handler); + if (ret){ + ESP_LOGE(GATTS_TAG, "gap register error, error code = %x", ret); + return; + } + ret = esp_ble_gatts_app_register(PROFILE_A_APP_ID); + if (ret){ + ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret); + return; + } + ret = esp_ble_gatts_app_register(PROFILE_B_APP_ID); + if (ret){ + ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret); + return; + } return; } diff --git a/examples/bluetooth/gatt_server/sdkconfig.defaults b/examples/bluetooth/gatt_server/sdkconfig.defaults index 9d51df5ee5..14f5546ffa 100644 --- a/examples/bluetooth/gatt_server/sdkconfig.defaults +++ b/examples/bluetooth/gatt_server/sdkconfig.defaults @@ -1,4 +1,3 @@ # Override some defaults so BT stack is enabled -# and WiFi disabled by default in this example +# by default in this example CONFIG_BT_ENABLED=y -CONFIG_WIFI_ENABLED=n