diff --git a/components/bt/bluedroid/api/esp_gap_ble_api.c b/components/bt/bluedroid/api/esp_gap_ble_api.c index ccce399ae..6b4ba6801 100644 --- a/components/bt/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/bluedroid/api/esp_gap_ble_api.c @@ -20,13 +20,13 @@ #include "bt_trace.h" #include "btc_manage.h" #include "btc_gap_ble.h" +#include "btc_ble_storage.h" 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 +36,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 +61,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 +80,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 +95,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 +108,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 +122,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 +137,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 +152,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 +169,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 +185,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 +197,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 +223,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 +245,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 +269,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 +287,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 +303,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 +322,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 +340,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 +352,53 @@ 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); +} + +int esp_ble_get_bond_device_num(void) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + return btc_storage_get_num_ble_bond_devices(); +} + +esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_list) +{ + int ret; + int dev_num_total; + + if (dev_num == NULL || dev_list == NULL) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + dev_num_total = btc_storage_get_num_ble_bond_devices(); + if (*dev_num > dev_num_total) { + *dev_num = dev_num_total; + } + + ret = btc_storage_get_bonded_ble_devices_list(dev_list, *dev_num); + + return (ret == 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 b80966cd8..b58c408f8 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 802256f77..4d2a6f5f8 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 e2b9553b3..513d37ec4 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 { @@ -44,6 +50,7 @@ typedef enum { ESP_BT_STATUS_TIMEOUT, /* relate to BT_STATUS_TIMEOUT in bt_def.h */ ESP_BT_STATUS_PEER_LE_DATA_LEN_UNSUPPORTED, /* relate to BTM_PEER_LE_DATA_LEN_UNSUPPORTED in btm_api.h */ ESP_BT_STATUS_CONTROL_LE_DATA_LEN_UNSUPPORTED,/* relate to BTM_CONTROL_LE_DATA_LEN_UNSUPPORTED in btm_api.h */ + ESP_BT_STATUS_ERR_ILLEGAL_PARAMETER_FMT, /* relate to HCI_ERR_ILLEGAL_PARAMETER_FMT in hcidefs.h */ } esp_bt_status_t; @@ -107,6 +114,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 0492bd5d8..942a5499f 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,9 @@ 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_EVT_MAX, } esp_gap_ble_cb_event_t; /// Advertising data maximum length @@ -293,7 +296,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 +306,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 +316,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 +327,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 +337,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 +355,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 +367,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 +398,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 +407,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 +423,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 +435,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 +562,19 @@ 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 */ } esp_ble_gap_cb_param_t; /** @@ -814,6 +850,44 @@ 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 Get the device number from the security database list of peer device. +* It will return the device bonded number immediately. +* +* @return - >= 0 : bonded devices number. +* - < 0 : failed +* +*/ +int esp_ble_get_bond_device_num(void); + + +/** +* @brief Get the device from the security database list of peer device. +* It will return the device bonded information immediately. +* @param[inout] dev_num: Indicate the dev_list array(buffer) size as input. +* If dev_num is large enough, it means the actual number as output. +* Suggest that dev_num value equal to esp_ble_get_bond_device_num(). +* +* @param[out] dev_list: an array(buffer) of `esp_ble_bond_dev_t` type. Use for storing the bonded devices address. +* The dev_list should be allocated by who call this API. +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_list); + /** * @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 6e6f9396a..f28736e3b 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 6bbc370a7..d964ac9b9 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 39a5f06d3..a83a81d4f 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_act.c @@ -4517,13 +4517,6 @@ void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data) *******************************************************************************/ void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data) { - tACL_CONN *p_acl_cb = btm_bda_to_acl(p_data->ble_update_conn_params.bd_addr, BT_TRANSPORT_LE); - if (p_acl_cb == NULL) { - APPL_TRACE_ERROR("%s error: Invalid connection bd_addr.", __func__); - return; - } else { - p_acl_cb->update_conn_param_cb = p_data->ble_update_conn_params.update_conn_param_cb; - } if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr, p_data->ble_update_conn_params.min_int, p_data->ble_update_conn_params.max_int, @@ -4601,7 +4594,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 7ef088761..62e56eb60 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 @@ -1991,7 +1991,7 @@ void BTA_DmEnableScanFilter(UINT8 action, tBTA_DM_BLE_PF_STATUS_CBACK *p_cmpl_cb ** *******************************************************************************/ void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max_int, - UINT16 latency, UINT16 timeout, tBTA_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb) + UINT16 latency, UINT16 timeout) { tBTA_DM_API_UPDATE_CONN_PARAM *p_msg; @@ -2004,7 +2004,6 @@ void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max p_msg->max_int = max_int; p_msg->latency = latency; p_msg->timeout = timeout; - p_msg->update_conn_param_cb = update_conn_param_cb; bta_sys_sendmsg(p_msg); } } diff --git a/components/bt/bluedroid/bta/dm/bta_dm_int.h b/components/bt/bluedroid/bta/dm/bta_dm_int.h index 735778137..534d584fd 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 */ @@ -644,7 +645,6 @@ typedef struct { UINT16 max_int; UINT16 latency; UINT16 timeout; - tBTA_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb; } tBTA_DM_API_UPDATE_CONN_PARAM; #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE diff --git a/components/bt/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/bluedroid/bta/gatt/bta_gattc_act.c index 292b3dfaf..9be6d148e 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" @@ -860,9 +861,6 @@ void bta_gattc_set_discover_st(tBTA_GATTC_SERV *p_srcb) tBTA_GATTC_CB *p_cb = &bta_gattc_cb; UINT8 i; -#if BLE_INCLUDED == TRUE - L2CA_EnableUpdateBleConnParams(p_srcb->server_bda, FALSE); -#endif for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++) { if (p_cb->clcb[i].p_srcb == p_srcb) { p_cb->clcb[i].status = BTA_GATT_OK; @@ -992,11 +990,6 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d", p_clcb->bta_conn_id); -#if BLE_INCLUDED == TRUE - if (p_clcb->transport == BTA_TRANSPORT_LE) { - L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE); - } -#endif p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE; p_clcb->disc_active = FALSE; @@ -2410,7 +2403,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_gattc_cache.c b/components/bt/bluedroid/bta/gatt/bta_gattc_cache.c index b2d082da9..940f5ee66 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gattc_cache.c +++ b/components/bt/bluedroid/bta/gatt/bta_gattc_cache.c @@ -36,6 +36,7 @@ #include "bta_gattc_int.h" #include "btm_api.h" #include "btm_ble_api.h" +#include "l2c_api.h" #define LOG_TAG "bt_bta_gattc" // #include "osi/include/log.h" @@ -588,6 +589,13 @@ static void bta_gattc_explore_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb) #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE) bta_gattc_display_cache_server(p_srvc_cb->p_srvc_cache); #endif + //server discover end, update connection parameters +#if BLE_INCLUDED == TRUE + if (p_clcb->transport == BTA_TRANSPORT_LE) { + L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE); + } +#endif + /* save cache to NV */ p_clcb->p_srcb->state = BTA_GATTC_SERV_SAVE; bta_gattc_co_cache_open(p_srvc_cb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT, diff --git a/components/bt/bluedroid/bta/gatt/bta_gatts_act.c b/components/bt/bluedroid/bta/gatt/bta_gatts_act.c index 733976c0c..414b1e575 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 c56a9fa58..1e7940a85 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 f21803b1c..fb02175f6 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); /******************************************************************************* ** @@ -2208,7 +2210,7 @@ extern void BTA_BleDisableAdvInstance(UINT8 inst_id); ** *******************************************************************************/ extern void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, - UINT16 max_int, UINT16 latency, UINT16 timeout, tBTA_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb); + UINT16 max_int, UINT16 latency, UINT16 timeout); /******************************************************************************* ** diff --git a/components/bt/bluedroid/bta/include/bta_gatt_api.h b/components/bt/bluedroid/bta/include/bta_gatt_api.h index 349c7c6a2..e6dc5e8db 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 0f9e689ac..03920ddfd 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 1c885f4b5..538e97835 100644 --- a/components/bt/bluedroid/btc/core/btc_ble_storage.c +++ b/components/bt/bluedroid/btc/core/btc_ble_storage.c @@ -19,111 +19,591 @@ #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; - -/******************************************************************************* -** -** Function btc_storage_load_bonded_devices -** -** Description btc storage API - Loads all the bonded devices from NVRAM -** and adds to the BTA. -** Additionally, this API also invokes the adaper_properties_cb -** and remote_device_properties_cb for each of the bonded devices. -** -** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -bt_status_t btc_storage_load_bonded_ble_devices(void) +static void _btc_storage_save(void) { - bt_status_t status; - status = btc_in_fetch_bonded_ble_devices(1); - LOG_DEBUG("Storage load rslt %d\n", status); - return status; -} + const btc_config_section_iter_t *iter = btc_config_section_begin(); -bt_status_t btc_in_fetch_bonded_ble_devices(int add) -{ - btc_bonded_devices_t bonded_devices; - 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)) { + while (iter != btc_config_section_end()) { + //store the next iter, if remove section, then will not loss the point + + const char *section = btc_config_section_name(iter); + if (!string_is_bdaddr(section)) { + iter = btc_config_section_next(iter); 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; + if (!btc_config_exist(section, BTC_BLE_STORAGE_DEV_TYPE_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_ADDR_TYPE_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LINK_KEY_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_PENC_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_PID_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_LENC_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR)) { + iter = btc_config_section_next(iter); + btc_config_remove_section(section); + continue; } + + iter = btc_config_section_next(iter); + } + + btc_config_flush(); +} + +void btc_storage_save(void) +{ + btc_config_lock(); + _btc_storage_save(); + btc_config_unlock(); +} + +static 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) +{ + bdstr_t bdstr; + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + const char* name; + + switch (key_type) { + case BTM_LE_KEY_PENC: + name = BTC_BLE_STORAGE_LE_KEY_PENC_STR; + break; + case BTM_LE_KEY_PID: + name = BTC_BLE_STORAGE_LE_KEY_PID_STR; + break; + case BTM_LE_KEY_PCSRK: + name = BTC_BLE_STORAGE_LE_KEY_PCSRK_STR; + break; + case BTM_LE_KEY_LENC: + name = BTC_BLE_STORAGE_LE_KEY_LENC_STR; + break; + case BTM_LE_KEY_LCSRK: + name = BTC_BLE_STORAGE_LE_KEY_LCSRK_STR; + break; + case BTM_LE_KEY_LID: + name = BTC_BLE_STORAGE_LE_KEY_LID_STR; + break; + default: + return BT_STATUS_FAIL; + } + + int ret = btc_config_set_bin(bdstr, name, (const uint8_t *)key, key_length); + _btc_storage_save(); + return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; +} + +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) +{ + bt_status_t ret; + + btc_config_lock(); + ret = _btc_storage_add_ble_bonding_key(remote_bd_addr, key, key_type, key_length); + btc_config_unlock(); + + return ret; +} + +/******************************************************************************* +** +** Function btc_storage_get_ble_bonding_key +** +** Description +** +** Returns BT_STATUS_SUCCESS if the fetch was successful, +** BT_STATUS_FAIL otherwise +** +*******************************************************************************/ +static bt_status_t _btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, + uint8_t key_type, + char *key_value, + int key_length) +{ + bdstr_t bdstr; + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + const char* name; + switch (key_type) { + case BTM_LE_KEY_PENC: + name = BTC_BLE_STORAGE_LE_KEY_PENC_STR; + break; + case BTM_LE_KEY_PID: + name = BTC_BLE_STORAGE_LE_KEY_PID_STR; + break; + case BTM_LE_KEY_PCSRK: + name = BTC_BLE_STORAGE_LE_KEY_PCSRK_STR; + break; + case BTM_LE_KEY_LENC: + name = BTC_BLE_STORAGE_LE_KEY_LENC_STR; + break; + case BTM_LE_KEY_LCSRK: + name = BTC_BLE_STORAGE_LE_KEY_LCSRK_STR; + break; + case BTM_LE_KEY_LID: + name = BTC_BLE_STORAGE_LE_KEY_LID_STR; + default: + return BT_STATUS_FAIL; + } + size_t length = key_length; + int ret = btc_config_get_bin(bdstr, name, (uint8_t *)key_value, &length); + return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; + +} + +bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, + uint8_t key_type, + char *key_value, + int key_length) +{ + bt_status_t ret; + + btc_config_lock(); + ret = _btc_storage_get_ble_bonding_key(remote_bd_addr, key_type, key_value, key_length); + btc_config_unlock(); + + return ret; +} + +/******************************************************************************* +** +** Function btc_storage_remove_ble_bonding_keys +** +** Description btc storage API - Deletes the bonded device from NVRAM +** +** Returns BT_STATUS_SUCCESS if the deletion was successful, +** BT_STATUS_FAIL otherwise +** +*******************************************************************************/ +static bt_status_t _btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr) +{ + int ret = 1; + bdstr_t bdstr; + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + + BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr); + + if (btc_config_exist(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR)) { + ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR); + } + if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_PENC_STR)) { + ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_PENC_STR); + } + if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_PID_STR)) { + ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_PID_STR); + } + if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR)) { + ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR); + } + if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_LENC_STR)) { + ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_LENC_STR); + } + if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR)) { + ret &= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR); + } + //here don't remove section, because config_save will check it + _btc_storage_save(); + return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; +} + +bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr) +{ + bt_status_t ret; + + btc_config_lock(); + ret = _btc_storage_remove_ble_bonding_keys(remote_bd_addr); + btc_config_unlock(); + + return ret; +} + +/******************************************************************************* +** +** Function btc_storage_add_ble_local_key +** +** Description BTIF storage API - Adds the ble key to NVRAM +** +** Returns BT_STATUS_SUCCESS if the store was successful, +** BT_STATUS_FAIL otherwise +** +*******************************************************************************/ +static bt_status_t _btc_storage_add_ble_local_key(char *key, + uint8_t key_type, + uint8_t key_length) +{ + const char* name; + switch (key_type) { + case BTC_LE_LOCAL_KEY_IR: + name = BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR; + break; + case BTC_LE_LOCAL_KEY_IRK: + name = BTC_BLE_STORAGE_LE_LOCAL_KEY_IRK_STR; + break; + case BTC_LE_LOCAL_KEY_DHK: + name = BTC_BLE_STORAGE_LE_LOCAL_KEY_DHK_STR; + break; + case BTC_LE_LOCAL_KEY_ER: + name = BTC_BLE_STORAGE_LE_LOCAL_KEY_ER_STR; + break; + default: + return BT_STATUS_FAIL; + } + + int ret = btc_config_set_bin(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, name, (const uint8_t *)key, key_length); + _btc_storage_save(); + return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; +} + +bt_status_t btc_storage_add_ble_local_key(char *key, + uint8_t key_type, + uint8_t key_length) +{ + bt_status_t ret; + + btc_config_lock(); + ret = _btc_storage_add_ble_local_key(key, key_type, key_length); + btc_config_unlock(); + + return ret; +} + +/******************************************************************************* +** +** Function btc_storage_get_ble_local_key +** +** Description +** +** Returns BT_STATUS_SUCCESS if the fetch was successful, +** BT_STATUS_FAIL otherwise +** +*******************************************************************************/ +static bt_status_t _btc_storage_get_ble_local_key(uint8_t key_type, + char *key_value, + int key_length) +{ + const char* name; + switch (key_type) { + case BTC_LE_LOCAL_KEY_IR: + name = BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR; + break; + case BTC_LE_LOCAL_KEY_IRK: + name = BTC_BLE_STORAGE_LE_LOCAL_KEY_IRK_STR; + break; + case BTC_LE_LOCAL_KEY_DHK: + name = BTC_BLE_STORAGE_LE_LOCAL_KEY_DHK_STR; + break; + case BTC_LE_LOCAL_KEY_ER: + name = BTC_BLE_STORAGE_LE_LOCAL_KEY_ER_STR; + break; + default: + return BT_STATUS_FAIL; + } + size_t length = key_length; + + int ret = btc_config_get_bin(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, name, (uint8_t *)key_value, &length); + + return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; +} + +bt_status_t btc_storage_get_ble_local_key(uint8_t key_type, + char *key_value, + int key_length) +{ + bt_status_t ret; + + btc_config_lock(); + ret = _btc_storage_get_ble_local_key(key_type, key_value, key_length); + btc_config_unlock(); + + return ret; +} + +/******************************************************************************* +** +** Function btc_storage_remove_ble_local_keys +** +** Description BTC storage API - Deletes the bonded device from NVRAM +** +** Returns BT_STATUS_SUCCESS if the deletion was successful, +** BT_STATUS_FAIL otherwise +** +*******************************************************************************/ +static bt_status_t _btc_storage_remove_ble_local_keys(void) +{ + int ret = 1; + + if (btc_config_exist(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR)) { + ret &= btc_config_remove(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR); + } + if (btc_config_exist(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_IRK_STR)) { + ret &= btc_config_remove(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_IRK_STR); + } + if (btc_config_exist(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_DHK_STR)) { + ret &= btc_config_remove(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_DHK_STR); + } + if (btc_config_exist(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_ER_STR)) { + ret &= btc_config_remove(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, BTC_BLE_STORAGE_LE_LOCAL_KEY_ER_STR); + } + _btc_storage_save(); + + return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; +} + +bt_status_t btc_storage_remove_ble_local_keys(void) +{ + bt_status_t ret; + + btc_config_lock(); + ret = _btc_storage_remove_ble_local_keys(); + btc_config_unlock(); + + return ret; +} + +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 = BTC_BLE_STORAGE_LE_KEY_PENC_STR; + break; + case BTM_LE_KEY_PID: + key_type_str = BTC_BLE_STORAGE_LE_KEY_PID_STR; + break; + case BTM_LE_KEY_PCSRK: + key_type_str = BTC_BLE_STORAGE_LE_KEY_PCSRK_STR; + break; + case BTM_LE_KEY_LENC: + key_type_str = BTC_BLE_STORAGE_LE_KEY_LENC_STR; + break; + case BTM_LE_KEY_LCSRK: + key_type_str = BTC_BLE_STORAGE_LE_KEY_LCSRK_STR; + break; + case BTM_LE_KEY_LID: + key_type_str = BTC_BLE_STORAGE_LE_KEY_LID_STR; + default: + return false; + } + + return btc_compare_address_key_value(bdstr, key_type_str, key_value, 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) +{ + bool ret; + + btc_config_lock(); + ret = _btc_storage_compare_address_key_value(remote_bd_addr, key_type, key_value, key_length); + btc_config_unlock(); + + return ret; +} + +static bt_status_t _btc_storage_set_ble_dev_type(bt_bdaddr_t *bd_addr, bool flush) +{ + bool ret = 1; + bdstr_t bdstr; + uint32_t dev_type = 0; + + bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)); + + btc_config_get_int(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&dev_type); + ret = btc_config_set_int(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR, BT_DEVICE_TYPE_BLE|dev_type); + if (ret == false) { + return BT_STATUS_FAIL; + } + + if (flush) { + _btc_storage_save(); } return BT_STATUS_SUCCESS; } -void btc_dm_remove_ble_bonding_keys(void) +bt_status_t btc_storage_set_ble_dev_type(bt_bdaddr_t *bd_addr, bool flush) { - bt_bdaddr_t bd_addr; - LOG_DEBUG("%s\n",__func__); + bt_status_t ret; - bdcpy(bd_addr.address, pairing_cb.bd_addr); - btc_storage_remove_ble_bonding_keys(&bd_addr); + btc_config_lock(); + ret = _btc_storage_set_ble_dev_type(bd_addr, flush); + btc_config_unlock(); + + return ret; } -void btc_save_ble_bonding_keys(void) +static bool _btc_storage_get_ble_dev_type(bt_bdaddr_t *bd_addr) { - bt_bdaddr_t bd_addr; + bool ret = 1; + bdstr_t bdstr; + uint32_t dev_type = 0; - bdcpy(bd_addr.address, pairing_cb.bd_addr); - if (pairing_cb.ble.is_penc_key_rcvd) { - btc_storage_add_ble_bonding_key(&bd_addr, - (char *) &pairing_cb.ble.penc_key, - BTM_LE_KEY_PENC, - sizeof(tBTM_LE_PENC_KEYS)); + bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)); + + BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr); + + ret = btc_config_get_int(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&dev_type); + if (ret == false) { + return false; } - if (pairing_cb.ble.is_pid_key_rcvd) { - btc_storage_add_ble_bonding_key(&bd_addr, - (char *) &pairing_cb.ble.pid_key, - BTM_LE_KEY_PID, - sizeof(tBTM_LE_PID_KEYS)); - } - - - if (pairing_cb.ble.is_pcsrk_key_rcvd) { - btc_storage_add_ble_bonding_key(&bd_addr, - (char *) &pairing_cb.ble.pcsrk_key, - BTM_LE_KEY_PCSRK, - sizeof(tBTM_LE_PCSRK_KEYS)); - } - - - if (pairing_cb.ble.is_lenc_key_rcvd) { - btc_storage_add_ble_bonding_key(&bd_addr, - (char *) &pairing_cb.ble.lenc_key, - BTM_LE_KEY_LENC, - sizeof(tBTM_LE_LENC_KEYS)); - } - - if (pairing_cb.ble.is_lcsrk_key_rcvd) { - btc_storage_add_ble_bonding_key(&bd_addr, - (char *) &pairing_cb.ble.lcsrk_key, - BTM_LE_KEY_LCSRK, - sizeof(tBTM_LE_LCSRK_KEYS)); - } - - if (pairing_cb.ble.is_lidk_key_rcvd) { - btc_storage_add_ble_bonding_key(&bd_addr, - NULL, - BTM_LE_KEY_LID, - 0); - } + return (dev_type & BT_DEVICE_TYPE_BLE); } -static void btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bdaddr_t bd_addr, +bool btc_storage_get_ble_dev_type(bt_bdaddr_t *bd_addr) +{ + bt_status_t ret; + + btc_config_lock(); + ret = _btc_storage_get_ble_dev_type(bd_addr); + btc_config_unlock(); + + return ret; +} + + +static bt_status_t _btc_storage_remove_ble_dev_type(bt_bdaddr_t *remote_bd_addr, bool flush) +{ + bool ret = true; + bdstr_t bdstr; + uint32_t dev_type = 0; + + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + + BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr); + + ret = btc_config_get_int(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&dev_type); + if (ret == false) { + //cannot find the key, just return SUCCESS, indicate already removed + return BT_STATUS_SUCCESS; + } + + if (dev_type == BT_DEVICE_TYPE_DUMO) { + ret = btc_config_set_int(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR, BT_DEVICE_TYPE_BREDR); + } else if (dev_type == BT_DEVICE_TYPE_BLE) { + ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_DEV_TYPE_STR); + } + + if (ret == false) { + return BT_STATUS_FAIL; + } + + if (flush) { + _btc_storage_save(); + } + + return BT_STATUS_SUCCESS; +} + +bt_status_t btc_storage_remove_ble_dev_type(bt_bdaddr_t *remote_bd_addr, bool flush) +{ + bt_status_t ret; + + btc_config_lock(); + ret = _btc_storage_remove_ble_dev_type(remote_bd_addr, flush); + btc_config_unlock(); + + return ret; +} + +static bt_status_t _btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, uint8_t addr_type, bool flush) +{ + int ret; + bdstr_t bdstr; + + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t)); + ret = btc_config_set_int(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR, (int)addr_type); + if (ret == false) { + return BT_STATUS_FAIL; + } + + if (flush) { + _btc_storage_save(); + } + + return BT_STATUS_SUCCESS; +} + +bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, uint8_t addr_type, bool flush) +{ + bt_status_t ret; + + btc_config_lock(); + ret = _btc_storage_set_remote_addr_type(remote_bd_addr, addr_type, flush); + btc_config_unlock(); + + return ret; +} + +static bt_status_t _btc_storage_remove_remote_addr_type(bt_bdaddr_t *remote_bd_addr, bool flush) +{ + bool ret = true; + bdstr_t bdstr; + uint32_t dev_type = 0; + + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + + ret = btc_config_get_int(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR, (int *)&dev_type); + if (ret == false) { + //cannot find the key, just return SUCCESS, indicate already removed + return BT_STATUS_SUCCESS; + } + + ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR); + if (ret == false) { + return BT_STATUS_FAIL; + } + + if (flush) { + _btc_storage_save(); + } + + return BT_STATUS_SUCCESS; +} + +bt_status_t btc_storage_remove_remote_addr_type(bt_bdaddr_t *remote_bd_addr, bool flush) +{ + bt_status_t ret; + + btc_config_lock(); + ret = _btc_storage_remove_remote_addr_type(remote_bd_addr, flush); + btc_config_unlock(); + + return ret; +} + +static bt_status_t _btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr, + int*addr_type) +{ + bdstr_t bdstr; + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + int ret = btc_config_get_int(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR, addr_type); + return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; +} + +bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr, + int*addr_type) +{ + bt_status_t ret; + + btc_config_lock(); + ret = _btc_storage_get_remote_addr_type(remote_bd_addr, addr_type); + btc_config_unlock(); + + return ret; +} + +static void _btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bdaddr_t bd_addr, const uint8_t addr_type, const bool add_key, bool *device_added, bool *key_found) { assert(device_added); @@ -132,7 +612,9 @@ 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) { + bt_status_t ret = _btc_storage_get_ble_bonding_key(&bd_addr, key_type, buffer, key_len); + + if (ret == BT_STATUS_SUCCESS) { if (add_key) { BD_ADDR bta_bd_addr; bdcpy(bta_bd_addr, bd_addr.address); @@ -151,238 +633,16 @@ static void btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bda *key_found = true; } } - - -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) +static bt_status_t _btc_storage_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add) { - char bdstr[6] = {0}; - bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); - const char* name; - switch (key_type) { - case BTM_LE_KEY_PENC: - name = "LE_KEY_PENC"; - break; - case BTM_LE_KEY_PID: - name = "LE_KEY_PID"; - break; - case BTM_LE_KEY_PCSRK: - name = "LE_KEY_PCSRK"; - break; - case BTM_LE_KEY_LENC: - name = "LE_KEY_LENC"; - break; - case BTM_LE_KEY_LCSRK: - name = "LE_KEY_LCSRK"; - break; - case BTM_LE_KEY_LID: - name = "LE_KEY_LID"; - break; - default: - return BT_STATUS_FAIL; - } - - int ret = btc_config_set_bin(bdstr, name, (const uint8_t *)key, key_length); - btc_config_save(); - return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; -} - - -/******************************************************************************* -** -** Function btc_storage_get_ble_bonding_key -** -** Description -** -** Returns BT_STATUS_SUCCESS if the fetch was successful, -** BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, - uint8_t key_type, - char *key_value, - int key_length) -{ - char bdstr[6] = {0}; - bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); - const char* name; - switch (key_type) { - case BTM_LE_KEY_PENC: - name = "LE_KEY_PENC"; - break; - case BTM_LE_KEY_PID: - name = "LE_KEY_PID"; - break; - case BTM_LE_KEY_PCSRK: - name = "LE_KEY_PCSRK"; - break; - case BTM_LE_KEY_LENC: - name = "LE_KEY_LENC"; - break; - case BTM_LE_KEY_LCSRK: - name = "LE_KEY_LCSRK"; - break; - case BTM_LE_KEY_LID: - name = "LE_KEY_LID"; - default: - return BT_STATUS_FAIL; - } - size_t length = key_length; - int ret = btc_config_get_bin(bdstr, name, (uint8_t *)key_value, &length); - return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; - -} - -/******************************************************************************* -** -** Function btc_storage_remove_ble_bonding_keys -** -** Description btc storage API - Deletes the bonded device from NVRAM -** -** Returns BT_STATUS_SUCCESS if the deletion was successful, -** BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr) -{ - char bdstr[6] = {0}; - 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, "LE_KEY_PENC")) { - ret &= btc_config_remove(bdstr, "LE_KEY_PENC"); - } - if (btc_config_exist(bdstr, "LE_KEY_PID")) { - ret &= btc_config_remove(bdstr, "LE_KEY_PID"); - } - if (btc_config_exist(bdstr, "LE_KEY_PCSRK")) { - ret &= btc_config_remove(bdstr, "LE_KEY_PCSRK"); - } - if (btc_config_exist(bdstr, "LE_KEY_LENC")) { - ret &= btc_config_remove(bdstr, "LE_KEY_LENC"); - } - if (btc_config_exist(bdstr, "LE_KEY_LCSRK")) { - ret &= btc_config_remove(bdstr, "LE_KEY_LCSRK"); - } - btc_config_save(); - return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; -} - -/******************************************************************************* -** -** Function btc_storage_add_ble_local_key -** -** Description BTIF storage API - Adds the ble key to NVRAM -** -** Returns BT_STATUS_SUCCESS if the store was successful, -** BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -bt_status_t btc_storage_add_ble_local_key(char *key, - uint8_t key_type, - uint8_t key_length) -{ - const char* name; - switch (key_type) { - case BTC_LE_LOCAL_KEY_IR: - name = "LE_LOCAL_KEY_IR"; - break; - case BTC_LE_LOCAL_KEY_IRK: - name = "LE_LOCAL_KEY_IRK"; - break; - case BTC_LE_LOCAL_KEY_DHK: - name = "LE_LOCAL_KEY_DHK"; - break; - case BTC_LE_LOCAL_KEY_ER: - name = "LE_LOCAL_KEY_ER"; - break; - default: - return BT_STATUS_FAIL; - } - int ret = btc_config_set_bin("Adapter", name, (const uint8_t *)key, key_length); - btc_config_save(); - return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; -} - -/******************************************************************************* -** -** Function btc_storage_get_ble_local_key -** -** Description -** -** Returns BT_STATUS_SUCCESS if the fetch was successful, -** BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -bt_status_t btc_storage_get_ble_local_key(uint8_t key_type, - char *key_value, - int key_length) -{ - const char* name; - switch (key_type) { - case BTC_LE_LOCAL_KEY_IR: - name = "LE_LOCAL_KEY_IR"; - break; - case BTC_LE_LOCAL_KEY_IRK: - name = "LE_LOCAL_KEY_IRK"; - break; - case BTC_LE_LOCAL_KEY_DHK: - name = "LE_LOCAL_KEY_DHK"; - break; - case BTC_LE_LOCAL_KEY_ER: - name = "LE_LOCAL_KEY_ER"; - break; - default: - return BT_STATUS_FAIL; - } - size_t length = key_length; - int ret = btc_config_get_bin("Adapter", name, (uint8_t *)key_value, &length); - return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; -} - -/******************************************************************************* -** -** Function btc_storage_remove_ble_local_keys -** -** Description BTC storage API - Deletes the bonded device from NVRAM -** -** Returns BT_STATUS_SUCCESS if the deletion was successful, -** BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -bt_status_t btc_storage_remove_ble_local_keys(void) -{ - int ret = 1; - if (btc_config_exist("Adapter", "LE_LOCAL_KEY_IR")) { - ret &= btc_config_remove("Adapter", "LE_LOCAL_KEY_IR"); - } - if (btc_config_exist("Adapter", "LE_LOCAL_KEY_IRK")) { - ret &= btc_config_remove("Adapter", "LE_LOCAL_KEY_IRK"); - } - if (btc_config_exist("Adapter", "LE_LOCAL_KEY_DHK")) { - ret &= btc_config_remove("Adapter", "LE_LOCAL_KEY_DHK"); - } - if (btc_config_exist("Adapter", "LE_LOCAL_KEY_ER")) { - ret &= btc_config_remove("Adapter", "LE_LOCAL_KEY_ER"); - } - btc_config_save(); - return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; -} - - -bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, - btc_bonded_devices_t *p_bonded_devices) -{ - int device_type; + uint32_t device_type; int addr_type; bt_bdaddr_t bd_addr; BD_ADDR bta_bd_addr; 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_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type)) { LOG_ERROR("%s, device_type = %x", __func__, device_type); return BT_STATUS_FAIL; } @@ -390,27 +650,27 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, string_to_bdaddr(remote_bd_addr, &bd_addr); bdcpy(bta_bd_addr, bd_addr.address); - if (btc_storage_get_remote_addr_type(&bd_addr, &addr_type) != BT_STATUS_SUCCESS) { + if (_btc_storage_get_remote_addr_type(&bd_addr, &addr_type) != BT_STATUS_SUCCESS) { addr_type = BLE_ADDR_PUBLIC; - btc_storage_set_remote_addr_type(&bd_addr, BLE_ADDR_PUBLIC); + _btc_storage_set_remote_addr_type(&bd_addr, BLE_ADDR_PUBLIC, true); } - btc_read_le_key(BTM_LE_KEY_PENC, sizeof(tBTM_LE_PENC_KEYS), + _btc_read_le_key(BTM_LE_KEY_PENC, sizeof(tBTM_LE_PENC_KEYS), bd_addr, addr_type, add, &device_added, &key_found); - btc_read_le_key(BTM_LE_KEY_PID, sizeof(tBTM_LE_PID_KEYS), + _btc_read_le_key(BTM_LE_KEY_PID, sizeof(tBTM_LE_PID_KEYS), bd_addr, addr_type, add, &device_added, &key_found); - btc_read_le_key(BTM_LE_KEY_LID, sizeof(tBTM_LE_PID_KEYS), + _btc_read_le_key(BTM_LE_KEY_LID, sizeof(tBTM_LE_PID_KEYS), bd_addr, addr_type, add, &device_added, &key_found); - btc_read_le_key(BTM_LE_KEY_PCSRK, sizeof(tBTM_LE_PCSRK_KEYS), + _btc_read_le_key(BTM_LE_KEY_PCSRK, sizeof(tBTM_LE_PCSRK_KEYS), bd_addr, addr_type, add, &device_added, &key_found); - btc_read_le_key(BTM_LE_KEY_LENC, sizeof(tBTM_LE_LENC_KEYS), + _btc_read_le_key(BTM_LE_KEY_LENC, sizeof(tBTM_LE_LENC_KEYS), bd_addr, addr_type, add, &device_added, &key_found); - btc_read_le_key(BTM_LE_KEY_LCSRK, sizeof(tBTM_LE_LCSRK_KEYS), + _btc_read_le_key(BTM_LE_KEY_LCSRK, sizeof(tBTM_LE_LCSRK_KEYS), bd_addr, addr_type, add, &device_added, &key_found); if (key_found) { @@ -420,73 +680,120 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, return BT_STATUS_FAIL; } -bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, - uint8_t addr_type) +static bt_status_t btc_storage_in_fetch_bonded_ble_devices(int add) { - char bdstr[6] = {0}; - 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(); - return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; + bt_status_t status = BT_STATUS_FAIL; + uint32_t device_type = 0; + + btc_config_lock(); + 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_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) || + ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { + continue; + } + LOG_DEBUG("%s, name = %s", __func__, name); + if (_btc_storage_in_fetch_bonded_ble_device(name, add) != BT_STATUS_SUCCESS) { + LOG_DEBUG("Remote device:%s, no link key or ble key found", name); + } else { + status = BT_STATUS_SUCCESS; + } + } + btc_config_unlock(); + + return status; } /******************************************************************************* ** -** Function btc_storage_get_remote_addr_type +** Function btc_storage_load_bonded_devices ** -** Description btc storage API - Fetches the remote addr type +** Description btc storage API - Loads all the bonded devices from NVRAM +** and adds to the BTA. +** Additionally, this API also invokes the adaper_properties_cb +** and remote_device_properties_cb for each of the bonded devices. ** -** Returns BT_STATUS_SUCCESS if the fetch was successful, -** BT_STATUS_FAIL otherwise +** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise ** *******************************************************************************/ -bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr, - int*addr_type) +bt_status_t btc_storage_load_bonded_ble_devices(void) { - char bdstr[6] = {0}; - 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; + bt_status_t status; + status = btc_storage_in_fetch_bonded_ble_devices(1); + LOG_DEBUG("Storage load rslt %d\n", status); + return status; } - -void btc_dm_load_ble_local_keys(void) +bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num) { - memset(&ble_local_key_cb, 0, sizeof(btc_dm_local_key_cb_t)); + bt_bdaddr_t bd_addr; + uint32_t device_type = 0; + char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0}; - if (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_ER,(char*)&ble_local_key_cb.er[0], - BT_OCTET16_LEN)== BT_STATUS_SUCCESS) { - ble_local_key_cb.is_er_rcvd = TRUE; - LOG_DEBUG("%s BLE ER key loaded",__func__ ); - } + btc_config_lock(); + for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); + iter = btc_config_section_next(iter)) { - if ((btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_IR,(char*)&ble_local_key_cb.id_keys.ir[0], - BT_OCTET16_LEN)== BT_STATUS_SUCCESS )&& - (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_IRK, (char*)&ble_local_key_cb.id_keys.irk[0], - BT_OCTET16_LEN)== BT_STATUS_SUCCESS)&& - (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_DHK,(char*)&ble_local_key_cb.id_keys.dhk[0], - BT_OCTET16_LEN)== BT_STATUS_SUCCESS)) { - ble_local_key_cb.is_id_keys_rcvd = TRUE; - LOG_DEBUG("%s BLE ID keys loaded", __func__); - } + if (dev_num-- <= 0) { + break; + } -} -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) -{ - if (ble_local_key_cb.is_er_rcvd ) { - memcpy(&er[0], &ble_local_key_cb.er[0], sizeof(BT_OCTET16)); - *p_key_mask |= BTA_BLE_LOCAL_KEY_TYPE_ER; - } + const char *name = btc_config_section_name(iter); - if (ble_local_key_cb.is_id_keys_rcvd) { - memcpy(&p_id_keys->ir[0], &ble_local_key_cb.id_keys.ir[0], sizeof(BT_OCTET16)); - memcpy(&p_id_keys->irk[0], &ble_local_key_cb.id_keys.irk[0], sizeof(BT_OCTET16)); - memcpy(&p_id_keys->dhk[0], &ble_local_key_cb.id_keys.dhk[0], sizeof(BT_OCTET16)); - *p_key_mask |= BTA_BLE_LOCAL_KEY_TYPE_ID; + if (!string_is_bdaddr(name) || + !btc_config_get_int(name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) || + !(device_type & BT_DEVICE_TYPE_BLE)) { + continue; + } + + 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++; } - LOG_DEBUG("%s *p_key_mask=0x%02x",__func__, *p_key_mask); + btc_config_unlock(); + + return BT_STATUS_SUCCESS; } +int btc_storage_get_num_ble_bond_devices(void) +{ + int num_dev = 0; + uint32_t device_type = 0; + + btc_config_lock(); + 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_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) || + !(device_type & BT_DEVICE_TYPE_BLE)) { + continue; + } + + num_dev++; + } + btc_config_unlock(); + + return num_dev; +} #endif ///SMP_INCLUDED == TRUE diff --git a/components/bt/bluedroid/btc/core/btc_config.c b/components/bt/bluedroid/btc/core/btc_config.c index bd0bd0318..598405d13 100644 --- a/components/bt/bluedroid/btc/core/btc_config.c +++ b/components/bt/bluedroid/btc/core/btc_config.c @@ -31,53 +31,39 @@ 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); - -// TODO(zachoverflow): Move these two functions out, because they are too specific for this file -// {grumpy-cat/no, monty-python/you-make-me-sad} -bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type) -{ - if (p_device_type == NULL) { - return FALSE; - } - - bt_bdaddr_t bda; - bdcpy(bda.address, bd_addr); - - 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)) { - return FALSE; - } - - LOG_DEBUG("%s: Device [%s] type %d\n", __FUNCTION__, bd_addr_str, *p_device_type); - return TRUE; -} - -bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type) -{ - if (p_addr_type == NULL) { - return FALSE; - } - - bt_bdaddr_t bda; - bdcpy(bda.address, bd_addr); - - bdstr_t bd_addr_str; - bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str)); - - if (!btc_config_get_int(bd_addr_str, "AddrType", p_addr_type)) { - return FALSE; - } - - LOG_DEBUG("%s: Device [%s] address type %d\n", __FUNCTION__, bd_addr_str, *p_addr_type); - return TRUE; -} - +static void btc_key_value_to_string(uint8_t *key_vaule, char *value_str, int key_length); 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); + if ((status = config_has_key_in_section(config, key_type, value_str)) == true) { + config_remove_section(config, section); + } + 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 +79,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 +103,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; } @@ -142,11 +114,7 @@ bool btc_config_has_section(const char *section) assert(config != NULL); assert(section != NULL); - pthread_mutex_lock(&lock); - bool ret = config_has_section(config, section); - pthread_mutex_unlock(&lock); - - return ret; + return config_has_section(config, section); } bool btc_config_exist(const char *section, const char *key) @@ -155,11 +123,7 @@ bool btc_config_exist(const char *section, const char *key) assert(section != NULL); assert(key != NULL); - pthread_mutex_lock(&lock); - bool ret = config_has_key(config, section, key); - pthread_mutex_unlock(&lock); - - return ret; + return config_has_key(config, section, key); } bool btc_config_get_int(const char *section, const char *key, int *value) @@ -169,12 +133,10 @@ bool btc_config_get_int(const char *section, const char *key, int *value) assert(key != NULL); assert(value != NULL); - pthread_mutex_lock(&lock); bool ret = config_has_key(config, section, key); if (ret) { *value = config_get_int(config, section, key, *value); } - pthread_mutex_unlock(&lock); return ret; } @@ -185,9 +147,7 @@ bool btc_config_set_int(const char *section, const char *key, int value) assert(section != NULL); assert(key != NULL); - pthread_mutex_lock(&lock); config_set_int(config, section, key, value); - pthread_mutex_unlock(&lock); return true; } @@ -200,9 +160,7 @@ bool btc_config_get_str(const char *section, const char *key, char *value, int * assert(value != NULL); assert(size_bytes != NULL); - pthread_mutex_lock(&lock); const char *stored_value = config_get_string(config, section, key, NULL); - pthread_mutex_unlock(&lock); if (!stored_value) { return false; @@ -221,9 +179,7 @@ bool btc_config_set_str(const char *section, const char *key, const char *value) assert(key != NULL); assert(value != NULL); - pthread_mutex_lock(&lock); config_set_string(config, section, key, value, false); - pthread_mutex_unlock(&lock); return true; } @@ -236,9 +192,7 @@ bool btc_config_get_bin(const char *section, const char *key, uint8_t *value, si assert(value != NULL); assert(length != NULL); - pthread_mutex_lock(&lock); const char *value_str = config_get_string(config, section, key, NULL); - pthread_mutex_unlock(&lock); if (!value_str) { return false; @@ -269,9 +223,7 @@ size_t btc_config_get_bin_length(const char *section, const char *key) assert(section != NULL); assert(key != NULL); - pthread_mutex_lock(&lock); const char *value_str = config_get_string(config, section, key, NULL); - pthread_mutex_unlock(&lock); if (!value_str) { return 0; @@ -303,9 +255,7 @@ bool btc_config_set_bin(const char *section, const char *key, const uint8_t *val str[(i * 2) + 1] = lookup[value[i] & 0x0F]; } - pthread_mutex_lock(&lock); config_set_string(config, section, key, str, false); - pthread_mutex_unlock(&lock); osi_free(str); return true; @@ -337,103 +287,54 @@ const char *btc_config_section_name(const btc_config_section_iter_t *section) return config_section_name((const config_section_node_t *)section); } + + bool btc_config_remove(const char *section, const char *key) { assert(config != NULL); assert(section != NULL); assert(key != NULL); - pthread_mutex_lock(&lock); - bool ret = config_remove_key(config, section, key); - pthread_mutex_unlock(&lock); - - return ret; + return config_remove_key(config, section, key); } -void btc_config_save(void) +bool btc_config_remove_section(const char *section) { - assert(alarm_timer != NULL); assert(config != NULL); + assert(section != NULL); - osi_alarm_set(alarm_timer, CONFIG_SETTLE_PERIOD_MS); + return config_remove_section(config, section); } void btc_config_flush(void) { assert(config != NULL); - assert(alarm_timer != NULL); - osi_alarm_cancel(alarm_timer); - pthread_mutex_lock(&lock); config_save(config, CONFIG_FILE_PATH); - 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_lock(void) { - assert(config != NULL); - assert(alarm_timer != NULL); - - // Garbage collection process: the config file accumulates - // cached information about remote devices during regular - // inquiry scans. We remove some of these junk entries - // so the file doesn't grow indefinitely. We have to take care - // to make sure we don't remove information about bonded - // devices (hence the check for link keys). - static const size_t CACHE_MAX = 256; - const char *keys[CACHE_MAX]; - size_t num_keys = 0; - size_t total_candidates = 0; - pthread_mutex_lock(&lock); - for (const config_section_node_t *snode = config_section_begin(config); snode != config_section_end(config); snode = config_section_next(snode)) { - const char *section = config_section_name(snode); - if (!string_is_bdaddr(section)) { - continue; - } +} - if (config_has_key(config, section, "LinkKey") || - config_has_key(config, section, "LE_KEY_PENC") || - config_has_key(config, section, "LE_KEY_PID") || - config_has_key(config, section, "LE_KEY_PCSRK") || - config_has_key(config, section, "LE_KEY_LENC") || - config_has_key(config, section, "LE_KEY_LCSRK")) { - continue; - } - - if (num_keys < CACHE_MAX) { - keys[num_keys++] = section; - } - - ++total_candidates; - } - - if (total_candidates > CACHE_MAX * 2) - while (num_keys > 0) { - config_remove_section(config, keys[--num_keys]); - } - - config_save(config, CONFIG_FILE_PATH); +void btc_config_unlock(void) +{ pthread_mutex_unlock(&lock); } + diff --git a/components/bt/bluedroid/btc/core/btc_dm.c b/components/bt/bluedroid/btc/core/btc_dm.c index 1f98d17da..8699c0d6d 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" @@ -36,6 +37,11 @@ ** Static variables ******************************************************************************/ static tBTA_SERVICE_MASK btc_enabled_services = 0; +#if (SMP_INCLUDED == TRUE) +static btc_dm_pairing_cb_t pairing_cb; +static btc_dm_local_key_cb_t ble_local_key_cb; +#endif + /****************************************************************************** ** Static functions ******************************************************************************/ @@ -115,21 +121,138 @@ static void btc_disable_bluetooth_evt(void) } #if (SMP_INCLUDED == TRUE) +void btc_dm_load_ble_local_keys(void) +{ + memset(&ble_local_key_cb, 0, sizeof(btc_dm_local_key_cb_t)); + + if (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_ER,(char*)&ble_local_key_cb.er[0], + BT_OCTET16_LEN)== BT_STATUS_SUCCESS) { + ble_local_key_cb.is_er_rcvd = TRUE; + LOG_DEBUG("%s BLE ER key loaded",__func__ ); + } + + if ((btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_IR,(char*)&ble_local_key_cb.id_keys.ir[0], + BT_OCTET16_LEN)== BT_STATUS_SUCCESS )&& + (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_IRK, (char*)&ble_local_key_cb.id_keys.irk[0], + BT_OCTET16_LEN)== BT_STATUS_SUCCESS)&& + (btc_storage_get_ble_local_key(BTC_LE_LOCAL_KEY_DHK,(char*)&ble_local_key_cb.id_keys.dhk[0], + BT_OCTET16_LEN)== BT_STATUS_SUCCESS)) { + ble_local_key_cb.is_id_keys_rcvd = TRUE; + LOG_DEBUG("%s BLE ID keys loaded", __func__); + } + +} +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) +{ + if (ble_local_key_cb.is_er_rcvd ) { + memcpy(&er[0], &ble_local_key_cb.er[0], sizeof(BT_OCTET16)); + *p_key_mask |= BTA_BLE_LOCAL_KEY_TYPE_ER; + } + + if (ble_local_key_cb.is_id_keys_rcvd) { + memcpy(&p_id_keys->ir[0], &ble_local_key_cb.id_keys.ir[0], sizeof(BT_OCTET16)); + memcpy(&p_id_keys->irk[0], &ble_local_key_cb.id_keys.irk[0], sizeof(BT_OCTET16)); + memcpy(&p_id_keys->dhk[0], &ble_local_key_cb.id_keys.dhk[0], sizeof(BT_OCTET16)); + *p_key_mask |= BTA_BLE_LOCAL_KEY_TYPE_ID; + } + LOG_DEBUG("%s *p_key_mask=0x%02x",__func__, *p_key_mask); +} + + +static void btc_dm_remove_ble_bonding_keys(void) +{ + bt_bdaddr_t bd_addr; + LOG_DEBUG("%s\n",__func__); + + bdcpy(bd_addr.address, pairing_cb.bd_addr); + + btc_storage_remove_remote_addr_type(&bd_addr, false); + btc_storage_remove_ble_dev_type(&bd_addr, false); + btc_storage_remove_ble_bonding_keys(&bd_addr); +} + +static void btc_dm_save_ble_bonding_keys(void) +{ + bt_bdaddr_t bd_addr; + + bdcpy(bd_addr.address, pairing_cb.bd_addr); + + btc_storage_set_ble_dev_type(&bd_addr, false); + 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, + BTM_LE_KEY_PENC, + sizeof(tBTM_LE_PENC_KEYS)); + } + + if (pairing_cb.ble.is_pid_key_rcvd) { + btc_storage_add_ble_bonding_key(&bd_addr, + (char *) &pairing_cb.ble.pid_key, + BTM_LE_KEY_PID, + sizeof(tBTM_LE_PID_KEYS)); + } + + + if (pairing_cb.ble.is_pcsrk_key_rcvd) { + btc_storage_add_ble_bonding_key(&bd_addr, + (char *) &pairing_cb.ble.pcsrk_key, + BTM_LE_KEY_PCSRK, + sizeof(tBTM_LE_PCSRK_KEYS)); + } + + + if (pairing_cb.ble.is_lenc_key_rcvd) { + btc_storage_add_ble_bonding_key(&bd_addr, + (char *) &pairing_cb.ble.lenc_key, + BTM_LE_KEY_LENC, + sizeof(tBTM_LE_LENC_KEYS)); + } + + if (pairing_cb.ble.is_lcsrk_key_rcvd) { + btc_storage_add_ble_bonding_key(&bd_addr, + (char *) &pairing_cb.ble.lcsrk_key, + BTM_LE_KEY_LCSRK, + sizeof(tBTM_LE_LCSRK_KEYS)); + } + + if (pairing_cb.ble.is_lidk_key_rcvd) { + btc_storage_add_ble_bonding_key(&bd_addr, + NULL, + BTM_LE_KEY_LID, + 0); + } +} + 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); + btc_storage_set_remote_addr_type(&bdaddr, p_auth_cmpl->addr_type, true); } - - btc_save_ble_bonding_keys(); + /* 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_dm_save_ble_bonding_keys(); } else { /*Map the HCI fail reason to bt status */ switch (p_auth_cmpl->fail_reason) { @@ -310,8 +433,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 +458,22 @@ 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_dev_type(&bd_addr, false); + btc_storage_remove_remote_addr_type(&bd_addr, false); + 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 d251782e4..87892b846 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/core/btc_storage.c b/components/bt/bluedroid/btc/core/btc_storage.c index 4f18cbfc9..333b768af 100644 --- a/components/bt/bluedroid/btc/core/btc_storage.c +++ b/components/bt/bluedroid/btc/core/btc_storage.c @@ -43,11 +43,14 @@ bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr, bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); LOG_DEBUG("add to storage: Remote device:%s\n", bdstr); - int ret = btc_config_set_int(bdstr, "LinkKeyType", (int)key_type); - ret &= btc_config_set_int(bdstr, "PinLength", (int)pin_length); - ret &= btc_config_set_bin(bdstr, "LinkKey", link_key, sizeof(LINK_KEY)); + btc_config_lock(); + int ret = btc_config_set_int(bdstr, BTC_STORAGE_LINK_KEY_TYPE_STR, (int)key_type); + ret &= btc_config_set_int(bdstr, BTC_STORAGE_PIN_LENGTH_STR, (int)pin_length); + ret &= btc_config_set_bin(bdstr, BTC_STORAGE_LINK_KEY_STR, link_key, sizeof(LINK_KEY)); /* write bonded info immediately */ btc_config_flush(); + btc_config_unlock(); + LOG_DEBUG("Storage add rslt %d\n", ret); return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; } @@ -66,6 +69,7 @@ static bt_status_t btc_in_fetch_bonded_devices(int add) { BOOLEAN bt_linkkey_file_found = FALSE; + btc_config_lock(); 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)) { @@ -75,21 +79,19 @@ static bt_status_t btc_in_fetch_bonded_devices(int add) LOG_DEBUG("Remote device:%s\n", name); LINK_KEY link_key; size_t size = sizeof(link_key); - if (btc_config_get_bin(name, "LinkKey", link_key, &size)) { + if (btc_config_get_bin(name, BTC_STORAGE_LINK_KEY_STR, link_key, &size)) { int linkkey_type; - if (btc_config_get_int(name, "LinkKeyType", &linkkey_type)) { - //int pin_len; - //btc_config_get_int(name, "PinLength", &pin_len)) + if (btc_config_get_int(name, BTC_STORAGE_LINK_KEY_TYPE_STR, &linkkey_type)) { bt_bdaddr_t bd_addr; string_to_bdaddr(name, &bd_addr); if (add) { DEV_CLASS dev_class = {0, 0, 0}; int cod; int pin_length = 0; - if (btc_config_get_int(name, "DevClass", &cod)) { + if (btc_config_get_int(name, BTC_STORAGE_DEV_CLASS_STR, &cod)) { uint2devclass((UINT32)cod, dev_class); } - btc_config_get_int(name, "PinLength", &pin_length); + btc_config_get_int(name, BTC_STORAGE_PIN_LENGTH_STR, &pin_length); #if (SMP_INCLUDED == TRUE) BTA_DmAddDevice(bd_addr.address, dev_class, link_key, 0, 0, (UINT8)linkkey_type, 0, pin_length); @@ -104,6 +106,8 @@ static bt_status_t btc_in_fetch_bonded_devices(int add) LOG_DEBUG("Remote device:%s, no link key\n", name); } } + btc_config_unlock(); + return BT_STATUS_SUCCESS; } @@ -142,19 +146,22 @@ bt_status_t btc_storage_remove_bonded_device(bt_bdaddr_t *remote_bd_addr) { bdstr_t bdstr; bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + int ret = 1; LOG_DEBUG("Add to storage: Remote device:%s\n", bdstr); - int ret = 1; - if (btc_config_exist(bdstr, "LinkKeyType")) { - ret &= btc_config_remove(bdstr, "LinkKeyType"); + btc_config_lock(); + if (btc_config_exist(bdstr, BTC_STORAGE_LINK_KEY_TYPE_STR)) { + ret &= btc_config_remove(bdstr, BTC_STORAGE_LINK_KEY_TYPE_STR); } - if (btc_config_exist(bdstr, "PinLength")) { - ret &= btc_config_remove(bdstr, "PinLength"); + if (btc_config_exist(bdstr, BTC_STORAGE_PIN_LENGTH_STR)) { + ret &= btc_config_remove(bdstr, BTC_STORAGE_PIN_LENGTH_STR); } - if (btc_config_exist(bdstr, "LinkKey")) { - ret &= btc_config_remove(bdstr, "LinkKey"); + if (btc_config_exist(bdstr, BTC_STORAGE_LINK_KEY_STR)) { + ret &= btc_config_remove(bdstr, BTC_STORAGE_LINK_KEY_STR); } /* write bonded info immediately */ btc_config_flush(); + btc_config_unlock(); + return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; } diff --git a/components/bt/bluedroid/btc/core/btc_task.c b/components/bt/bluedroid/btc/core/btc_task.c index 51b9ea247..fc36a5639 100644 --- a/components/bt/bluedroid/btc/core/btc_task.c +++ b/components/bt/bluedroid/btc/core/btc_task.c @@ -141,7 +141,7 @@ int btc_init(void) { xBtcQueue = xQueueCreate(BTC_TASK_QUEUE_NUM, sizeof(btc_msg_t)); xTaskCreatePinnedToCore(btc_task, "Btc_task", BTC_TASK_STACK_SIZE, NULL, BTC_TASK_PRIO, &xBtcTaskHandle, 0); - + btc_gap_callback_init(); /* TODO: initial the profile_tab */ return BT_STATUS_SUCCESS; diff --git a/components/bt/bluedroid/btc/include/btc_ble_storage.h b/components/bt/bluedroid/btc/include/btc_ble_storage.h index 2884d6acf..0d4d43e7c 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) @@ -21,52 +23,25 @@ #define BTC_LE_LOCAL_KEY_DHK (1<<2) #define BTC_LE_LOCAL_KEY_ER (1<<3) +#define BTC_BLE_STORAGE_DEV_TYPE_STR "DevType" +#define BTC_BLE_STORAGE_ADDR_TYPE_STR "AddrType" +#define BTC_BLE_STORAGE_LINK_KEY_STR "LinkKey" +#define BTC_BLE_STORAGE_LE_KEY_PENC_STR "LE_KEY_PENC" +#define BTC_BLE_STORAGE_LE_KEY_PID_STR "LE_KEY_PID" +#define BTC_BLE_STORAGE_LE_KEY_PCSRK_STR "LE_KEY_PCSRK" +#define BTC_BLE_STORAGE_LE_KEY_LENC_STR "LE_KEY_LENC" +#define BTC_BLE_STORAGE_LE_KEY_LID_STR "LE_KEY_LID" +#define BTC_BLE_STORAGE_LE_KEY_LCSRK_STR "LE_KEY_LCSRK" + +#define BTC_BLE_STORAGE_LOCAL_ADAPTER_STR "Adapter" +#define BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR "LE_LOCAL_KEY_IR" +#define BTC_BLE_STORAGE_LE_LOCAL_KEY_IRK_STR "LE_LOCAL_KEY_IRK" +#define BTC_BLE_STORAGE_LE_LOCAL_KEY_DHK_STR "LE_LOCAL_KEY_DHK" +#define BTC_BLE_STORAGE_LE_LOCAL_KEY_ER_STR "LE_LOCAL_KEY_ER" + /************************************************************************************ ** Local type definitions ************************************************************************************/ -typedef struct -{ - uint32_t num_devices; - bt_bdaddr_t devices[BTM_SEC_MAX_DEVICE_RECORDS]; -} btc_bonded_devices_t; - -typedef struct -{ - bool is_penc_key_rcvd; - tBTM_LE_PENC_KEYS penc_key; /* received peer encryption key */ - bool is_pcsrk_key_rcvd; - tBTM_LE_PCSRK_KEYS pcsrk_key; /* received peer device SRK */ - bool is_pid_key_rcvd; - tBTM_LE_PID_KEYS pid_key; /* peer device ID key */ - bool is_lenc_key_rcvd; - tBTM_LE_LENC_KEYS lenc_key; /* local encryption reproduction keys LTK = = d1(ER,DIV,0)*/ - bool is_lcsrk_key_rcvd; - tBTM_LE_LCSRK_KEYS lcsrk_key; /* local device CSRK = d1(ER,DIV,1)*/ - bool is_lidk_key_rcvd; /* local identity key received */ -} btc_dm_ble_cb_t; - -typedef struct -{ - bt_bdaddr_t static_bdaddr; - BD_ADDR bd_addr; - btc_dm_ble_cb_t ble; -} btc_dm_pairing_cb_t; - -typedef struct -{ - uint8_t ir[BT_OCTET16_LEN]; - uint8_t irk[BT_OCTET16_LEN]; - uint8_t dhk[BT_OCTET16_LEN]; -}btc_dm_local_key_id_t; - -typedef struct -{ - bool is_er_rcvd; - uint8_t er[BT_OCTET16_LEN]; - bool is_id_keys_rcvd; - btc_dm_local_key_id_t id_keys; /* ID kyes */ -}btc_dm_local_key_cb_t; - typedef struct { BT_OCTET16 sp_c; @@ -75,50 +50,37 @@ typedef struct } btc_dm_oob_cb_t; -extern btc_dm_pairing_cb_t pairing_cb; -extern btc_dm_local_key_cb_t ble_local_key_cb; +void btc_storage_save(void); -bt_status_t btc_storage_load_bonded_ble_devices(void); +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); -bt_status_t btc_in_fetch_bonded_ble_devices(int add); - -void btc_dm_remove_ble_bonding_keys(void); - -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); - -void btc_save_ble_bonding_keys(void); - -bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add, - btc_bonded_devices_t *p_bonded_devices); - -bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, - uint8_t key_type, - char *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_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, uint8_t key_type, char *key_value, int key_length); bt_status_t btc_storage_remove_ble_bonding_keys(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); + +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_local_keys(void); -bt_status_t btc_storage_get_ble_local_key(uint8_t key_type, - char *key_value, - int key_len); +bt_status_t btc_storage_get_ble_local_key(uint8_t key_type, char *key_value, int key_len); -bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr, - int *addr_type); +bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr, int *addr_type); -bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, - uint8_t addr_type); +bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, uint8_t addr_type, bool flush); -void btc_dm_load_ble_local_keys(void); +bt_status_t btc_storage_remove_remote_addr_type(bt_bdaddr_t *remote_bd_addr, bool flush); -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 +bt_status_t btc_storage_set_ble_dev_type(bt_bdaddr_t *bd_addr, bool flush); + +bt_status_t btc_storage_remove_ble_dev_type(bt_bdaddr_t *remote_bd_addr, bool flush); + +bt_status_t btc_storage_load_bonded_ble_devices(void); + +bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num); + +int btc_storage_get_num_ble_bond_devices(void); + +#endif ///SMP_INCLUDED == TRUE +#endif ///__BTC_BLE_STORAGE_H__ diff --git a/components/bt/bluedroid/btc/include/btc_config.h b/components/bt/bluedroid/btc/include/btc_config.h index 1472cc83c..79f6137e8 100644 --- a/components/bt/bluedroid/btc/include/btc_config.h +++ b/components/bt/bluedroid/btc/include/btc_config.h @@ -35,6 +35,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); @@ -43,12 +44,15 @@ const btc_config_section_iter_t *btc_config_section_end(void); const btc_config_section_iter_t *btc_config_section_next(const btc_config_section_iter_t *section); const char *btc_config_section_name(const btc_config_section_iter_t *section); -void btc_config_save(void); void btc_config_flush(void); 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); +void btc_config_lock(void); +void btc_config_unlock(void); + #endif diff --git a/components/bt/bluedroid/btc/include/btc_dm.h b/components/bt/bluedroid/btc/include/btc_dm.h index e397d82b4..44f4d84c1 100644 --- a/components/bt/bluedroid/btc/include/btc_dm.h +++ b/components/bt/bluedroid/btc/include/btc_dm.h @@ -29,6 +29,45 @@ typedef union { tBTA_DM_SEC sec; } btc_dm_sec_args_t; +typedef struct +{ + bool is_penc_key_rcvd; + tBTM_LE_PENC_KEYS penc_key; /* received peer encryption key */ + bool is_pcsrk_key_rcvd; + tBTM_LE_PCSRK_KEYS pcsrk_key; /* received peer device SRK */ + bool is_pid_key_rcvd; + tBTM_LE_PID_KEYS pid_key; /* peer device ID key */ + bool is_lenc_key_rcvd; + tBTM_LE_LENC_KEYS lenc_key; /* local encryption reproduction keys LTK = = d1(ER,DIV,0)*/ + bool is_lcsrk_key_rcvd; + tBTM_LE_LCSRK_KEYS lcsrk_key; /* local device CSRK = d1(ER,DIV,1)*/ + bool is_lidk_key_rcvd; /* local identity key received */ +} btc_dm_ble_cb_t; + +typedef struct +{ + bt_bdaddr_t static_bdaddr; + BD_ADDR bd_addr; + btc_dm_ble_cb_t ble; +} btc_dm_pairing_cb_t; + +typedef struct +{ + uint8_t ir[BT_OCTET16_LEN]; + uint8_t irk[BT_OCTET16_LEN]; + uint8_t dhk[BT_OCTET16_LEN]; +} btc_dm_local_key_id_t; + +typedef struct +{ + bool is_er_rcvd; + uint8_t er[BT_OCTET16_LEN]; + bool is_id_keys_rcvd; + btc_dm_local_key_id_t id_keys; /* ID kyes */ +} btc_dm_local_key_cb_t; + + + // void btc_dm_call_handler(btc_msg_t *msg); void btc_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *data); void btc_dm_sec_cb_handler(btc_msg_t *msg); @@ -37,4 +76,11 @@ void btc_dm_sec_arg_deep_copy(btc_msg_t *msg, void *dst, void *src); bt_status_t btc_dm_enable_service(tBTA_SERVICE_ID service_id); bt_status_t btc_dm_disable_service(tBTA_SERVICE_ID service_id); +#if (SMP_INCLUDED == TRUE) +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 + #endif /* __BTC_DM_H__ */ diff --git a/components/bt/bluedroid/btc/include/btc_storage.h b/components/bt/bluedroid/btc/include/btc_storage.h index c2fb6ccbb..9e69b4139 100644 --- a/components/bt/bluedroid/btc/include/btc_storage.h +++ b/components/bt/bluedroid/btc/include/btc_storage.h @@ -19,6 +19,12 @@ #include "bt_defs.h" #include "bt_types.h" + +#define BTC_STORAGE_DEV_CLASS_STR "DevClass" +#define BTC_STORAGE_LINK_KEY_STR "LinkKey" /* same as the ble */ +#define BTC_STORAGE_LINK_KEY_TYPE_STR "LinkKeyType" +#define BTC_STORAGE_PIN_LENGTH_STR "PinLength" + /******************************************************************************* ** ** Function btc_storage_add_bonded_device 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 3863d5e3c..c9f2b4dd4 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,8 @@ #include "btc_gatt_util.h" #include "esp_bt_defs.h" #include "esp_gap_ble_api.h" +#include "btc_ble_storage.h" +#include "btc_dm.h" static tBTA_BLE_ADV_DATA gl_bta_adv_data; static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data; @@ -124,6 +126,9 @@ static esp_bt_status_t btc_hci_to_esp_status(uint8_t hci_status) case HCI_ERR_PARAM_OUT_OF_RANGE: esp_status = ESP_BT_STATUS_PARAM_OUT_OF_RANGE; break; + case HCI_ERR_ILLEGAL_PARAMETER_FMT: + esp_status = ESP_BT_STATUS_ERR_ILLEGAL_PARAMETER_FMT; + break; default: esp_status = ESP_BT_STATUS_FAIL; break; @@ -145,6 +150,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; @@ -618,7 +629,7 @@ static void btc_stop_scan_callback(tBTA_STATUS status) } } -void btc_update_conn_param_callback (UINT8 status, BD_ADDR bd_addr, +void btc_update_conn_param_callback (UINT8 status, BD_ADDR bd_addr, tBTM_LE_UPDATE_CONN_PRAMS *update_conn_params) { esp_ble_gap_cb_param_t param; @@ -661,6 +672,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) @@ -699,8 +727,7 @@ static void btc_ble_stop_advertising(tBTA_START_STOP_ADV_CMPL_CBACK *stop_adv_cb } static void btc_ble_update_conn_params(BD_ADDR bd_addr, uint16_t min_int, - uint16_t max_int, uint16_t latency, uint16_t timeout, - tBTA_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb) + uint16_t max_int, uint16_t latency, uint16_t timeout) { if (min_int > max_int) { min_int = max_int; @@ -711,7 +738,7 @@ static void btc_ble_update_conn_params(BD_ADDR bd_addr, uint16_t min_int, } BTA_DmBleUpdateConnectionParams(bd_addr, min_int, max_int, - latency, timeout, update_conn_param_cb); + latency, timeout); } static void btc_ble_set_pkt_data_len(BD_ADDR remote_device, uint16_t tx_data_length, tBTA_SET_PKT_DATA_LENGTH_CBACK *p_set_pkt_data_cback) @@ -733,16 +760,27 @@ static void btc_ble_set_rand_addr (BD_ADDR rand_addr) param.set_rand_addr_cmpl.status = ESP_BT_STATUS_SUCCESS; if (rand_addr != NULL) { - if((rand_addr[BD_ADDR_LEN - 1] & BT_STATIC_RAND_ADDR_MASK) - == BT_STATIC_RAND_ADDR_MASK) { + /* + A static address is a 48-bit randomly generated address and shall meet the following requirements: + • The two most significant bits of the address shall be equal to 1 + • All bits of the random part of the address shall not be equal to 1 + • All bits of the random part of the address shall not be equal to 0 + */ + BD_ADDR invalid_rand_addr_a, invalid_rand_addr_b; + memset(invalid_rand_addr_a, 0xff, sizeof(BD_ADDR)); + memset(invalid_rand_addr_b, 0x00, sizeof(BD_ADDR)); + invalid_rand_addr_b[BD_ADDR_LEN - 1] = invalid_rand_addr_b[BD_ADDR_LEN - 1] | BT_STATIC_RAND_ADDR_MASK; + if((rand_addr[BD_ADDR_LEN - 1] & BT_STATIC_RAND_ADDR_MASK) == BT_STATIC_RAND_ADDR_MASK + && memcmp(invalid_rand_addr_a, rand_addr, BD_ADDR_LEN) != 0 + && memcmp(invalid_rand_addr_b, rand_addr, BD_ADDR_LEN) != 0){ BTA_DmSetRandAddress(rand_addr); } else { param.set_rand_addr_cmpl.status = ESP_BT_STATUS_INVALID_STATIC_RAND_ADDR; - LOG_ERROR("Invalid randrom address, the high bit should be 0x11xx"); + LOG_ERROR("Invalid random address, the high bit should be 0b11, the random part shall not be to 1 or 0"); } } else { param.set_rand_addr_cmpl.status = ESP_BT_STATUS_INVALID_STATIC_RAND_ADDR; - LOG_ERROR("Invalid randrom addressm, the address value is NULL"); + LOG_ERROR("Invalid random addressm, the address value is NULL"); } msg.sig = BTC_SIG_API_CB; @@ -756,9 +794,9 @@ static void btc_ble_set_rand_addr (BD_ADDR rand_addr) } } -static void btc_ble_config_local_privacy(bool privacy_enable) +static void btc_ble_config_local_privacy(bool privacy_enable, tBTA_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback) { - BTA_DmBleConfigLocalPrivacy(privacy_enable); + BTA_DmBleConfigLocalPrivacy(privacy_enable, set_local_privacy_cback); } static void btc_ble_disconnect(BD_ADDR bd_addr) @@ -770,78 +808,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 +887,16 @@ 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) { + 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 +935,16 @@ 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) { + 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; @@ -987,8 +980,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) arg->conn_update_params.conn_params.min_int, arg->conn_update_params.conn_params.max_int, arg->conn_update_params.conn_params.latency, - arg->conn_update_params.conn_params.timeout, - btc_update_conn_param_callback); + arg->conn_update_params.conn_params.timeout); break; case BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN: btc_ble_set_pkt_data_len(arg->set_pkt_data_len.remote_device, arg->set_pkt_data_len.tx_data_length, btc_set_pkt_length_callback); @@ -1000,7 +992,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 +1070,12 @@ 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; + memcpy(bd_addr, arg->remove_bond_device.bd_addr, sizeof(BD_ADDR)); + BTA_DmRemoveDevice(bd_addr); + break; + } #endif ///SMP_INCLUDED == TRUE case BTC_GAP_BLE_DISCONNECT_EVT: btc_ble_disconnect(arg->disconnect.remote_device); @@ -1088,3 +1086,10 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) btc_gap_ble_arg_deep_free(msg); } +//register connection parameter update callback +void btc_gap_callback_init(void) +{ + BTM_BleRegiseterConnParamCallback(btc_update_conn_param_callback); + +} + 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 bfaa1cb7a..35c6094bf 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 78c2db022..6179226db 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,7 @@ 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_act_t; /* btc_ble_gap_args_t */ @@ -89,44 +90,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_callback_init(void); 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 35cf84c5b..00f73875c 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 d14123e82..574caed4b 100644 --- a/components/bt/bluedroid/btif/bta_dm_co.c +++ b/components/bt/bluedroid/btif/bta_dm_co.c @@ -22,7 +22,7 @@ #include "bta_sys.h" #include "bta_dm_co.h" #include "bta_dm_ci.h" -#include "btc_ble_storage.h" +#include "btc_dm.h" #if (defined(BTIF_INCLUDED) && BTIF_INCLUDED == TRUE) #include "bt_utils.h" #if (BTM_OOB_INCLUDED == TRUE) @@ -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 a7ed5bd3b..a426d69fe 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 dc617f6e5..28d53b23e 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 4f0e2cd8a..41f5ddb18 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 4f6c443a5..cfc963275 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 523137aa0..a632972a6 100644 --- a/components/bt/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/bluedroid/stack/btm/btm_ble_gap.c @@ -61,6 +61,7 @@ static tBTM_BLE_VSC_CB cmn_ble_vsc_cb; static tBTM_BLE_CTRL_FEATURES_CBACK *p_ctrl_le_feature_rd_cmpl_cback = NULL; #endif +tBTM_CallbackFunc conn_param_update_cb; /******************************************************************************* ** Local functions *******************************************************************************/ @@ -220,6 +221,19 @@ const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = { /* check LE combo state supported */ #define BTM_LE_STATES_SUPPORTED(x, y, z) ((x)[(z)] & (y)) +/******************************************************************************* +** +** Function BTM_BleRegiseterConnParamCallback +** +** Description register connection parameters update callback func +** +** Returns void +** +*******************************************************************************/ +void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb) +{ + conn_param_update_cb.update_conn_param_cb = update_conn_param_cb; +} /******************************************************************************* ** @@ -640,10 +654,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__); @@ -657,6 +677,10 @@ BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode) if (!privacy_mode) { /* if privacy disabled, always use public address */ p_cb->addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC; p_cb->privacy_mode = BTM_PRIVACY_NONE; + if (random_cb && random_cb->set_local_privacy_cback){ + (*random_cb->set_local_privacy_cback)(BTM_SET_PRIVACY_SUCCESS); + random_cb->set_local_privacy_cback = NULL; + } } else { /* privacy is turned on*/ /* always set host random address, used when privacy 1.1 or priavcy 1.2 is disabled */ p_cb->addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM; diff --git a/components/bt/bluedroid/stack/btu/btu_hcif.c b/components/bt/bluedroid/stack/btu/btu_hcif.c index 7d00f0b76..ba88eeb0e 100644 --- a/components/bt/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/bluedroid/stack/btu/btu_hcif.c @@ -126,6 +126,7 @@ static void btu_ble_ll_conn_complete_evt (UINT8 *p, UINT16 evt_len); static void btu_ble_process_adv_pkt (UINT8 *p); static void btu_ble_read_remote_feat_evt (UINT8 *p); static void btu_ble_ll_conn_param_upd_evt (UINT8 *p, UINT16 evt_len); +static void btu_ble_ll_get_conn_param_format_err_from_contoller (UINT8 status, UINT16 handle); #if (SMP_INCLUDED == TRUE) static void btu_ble_proc_ltk_req (UINT8 *p); static void btu_hcif_encryption_key_refresh_cmpl_evt (UINT8 *p); @@ -1130,6 +1131,14 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c case HCI_BLE_CREATE_LL_CONN: btm_ble_create_ll_conn_complete(status); break; + case HCI_BLE_UPD_LL_CONN_PARAMS: + if (p_cmd != NULL){ + p_cmd++; + STREAM_TO_UINT16 (handle, p_cmd); + btu_ble_ll_get_conn_param_format_err_from_contoller(status, handle); + } + break; + #endif #if BTM_SCO_INCLUDED == TRUE @@ -1758,6 +1767,14 @@ static void btu_ble_ll_conn_param_upd_evt (UINT8 *p, UINT16 evt_len) conn_latency, conn_timeout); } +static void btu_ble_ll_get_conn_param_format_err_from_contoller (UINT8 status, UINT16 handle) +{ + /* host send illegal connection parameters format, controller would send + back HCI_ERR_ILLEGAL_PARAMETER_FMT */ + l2cble_get_conn_param_format_err_from_contoller(status, handle); + +} + static void btu_ble_read_remote_feat_evt (UINT8 *p) { btm_ble_read_remote_features_complete(p); diff --git a/components/bt/bluedroid/stack/gatt/gatt_db.c b/components/bt/bluedroid/stack/gatt/gatt_db.c index 1fe69e004..26cb5845b 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 2976e497e..d4ee7b473 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 927812453..64849ea9e 100644 --- a/components/bt/bluedroid/stack/include/btm_ble_api.h +++ b/components/bt/bluedroid/stack/include/btm_ble_api.h @@ -164,12 +164,12 @@ typedef UINT8 tBTM_BLE_SFP; /* default connection interval min */ #ifndef BTM_BLE_CONN_INT_MIN_DEF -#define BTM_BLE_CONN_INT_MIN_DEF 24 /* recommended min: 30ms = 24 * 1.25 */ +#define BTM_BLE_CONN_INT_MIN_DEF 10 /* recommended min: 12.5ms = 10 * 1.25 */ #endif /* default connection interval max */ #ifndef BTM_BLE_CONN_INT_MAX_DEF -#define BTM_BLE_CONN_INT_MAX_DEF 40 /* recommended max: 50 ms = 56 * 1.25 */ +#define BTM_BLE_CONN_INT_MAX_DEF 12 /* recommended max: 15 ms = 12 * 1.25 */ #endif /* default slave latency */ @@ -861,6 +861,20 @@ tBTM_BLE_SCAN_SETUP_CBACK bta_ble_scan_setup_cb; extern "C" { #endif */ + +/******************************************************************************* +** +** Function BTM_BleRegiseterConnParamCallback +** +** Description register connection parameters update callback func +** +** Parameters: update_conn_param_cb +** +** Returns void +** +*******************************************************************************/ +void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb); + /******************************************************************************* ** ** Function BTM_SecAddBleDevice @@ -1596,7 +1610,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 055591d77..60684bdb3 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/components/bt/bluedroid/stack/include/btm_int.h b/components/bt/bluedroid/stack/include/btm_int.h index 4d263d572..0d37e0ddd 100644 --- a/components/bt/bluedroid/stack/include/btm_int.h +++ b/components/bt/bluedroid/stack/include/btm_int.h @@ -115,7 +115,6 @@ UINT8 conn_addr_type; /* local device address type for this co BD_ADDR active_remote_addr; /* remote address used on this connection */ UINT8 active_remote_addr_type; /* local device address type for this connection */ BD_FEATURES peer_le_features; /* Peer LE Used features mask for the device */ -tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb; tBTM_SET_PKT_DATA_LENGTH_CBACK *p_set_pkt_data_cback; tBTM_LE_SET_PKT_DATA_LENGTH_PARAMS data_length_params; #endif @@ -874,6 +873,12 @@ typedef struct { #endif } tBTM_CB; +typedef struct{ + //connection parameters update callback + tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb; +}tBTM_CallbackFunc; + +extern tBTM_CallbackFunc conn_param_update_cb; /* #ifdef __cplusplus extern "C" diff --git a/components/bt/bluedroid/stack/l2cap/include/l2c_int.h b/components/bt/bluedroid/stack/l2cap/include/l2c_int.h index b88659172..afc22b5c6 100644 --- a/components/bt/bluedroid/stack/l2cap/include/l2c_int.h +++ b/components/bt/bluedroid/stack/l2cap/include/l2c_int.h @@ -402,14 +402,24 @@ typedef struct t_l2c_linkcb { #define L2C_BLE_NEW_CONN_PARAM 0x2 /* new connection parameter to be set */ #define L2C_BLE_UPDATE_PENDING 0x4 /* waiting for connection update finished */ #define L2C_BLE_NOT_DEFAULT_PARAM 0x8 /* not using default connection parameters */ +#define L2C_BLE_UPDATE_PARAM_FULL 0x10 /* update connection parameters full, can not update */ UINT8 conn_update_mask; - - UINT16 min_interval; /* parameters as requested by peripheral */ - UINT16 max_interval; - UINT16 conn_int; - UINT16 latency; - UINT16 timeout; - + /* cache connection parameters that wait to update */ + UINT16 waiting_update_conn_min_interval; + UINT16 waiting_update_conn_max_interval; + UINT16 waiting_update_conn_latency; + UINT16 waiting_update_conn_timeout; + /* cache parameters that is being updated */ + UINT16 updating_conn_min_interval; + UINT16 updating_conn_max_interval; + bool updating_param_flag; + /* current connection parameters that current connection is using */ + UINT16 current_used_conn_interval; + UINT16 current_used_conn_latency; + UINT16 current_used_conn_timeout; + /* connection parameters update order: + waiting_update_conn_xx -> updating_conn_xx -> current_used_conn_xx + */ #endif #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) @@ -733,6 +743,7 @@ extern void l2cble_notify_le_connection (BD_ADDR bda); extern void l2c_ble_link_adjust_allocation (void); extern void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout); +extern void l2cble_get_conn_param_format_err_from_contoller(UINT8 status, UINT16 handle); #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) extern void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max, @@ -745,6 +756,7 @@ extern void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 f extern void l2c_send_update_conn_params_cb(tL2C_LCB *p_lcb, UINT8 status); extern void l2cble_process_data_length_change_event(UINT16 handle, UINT16 tx_data_len, UINT16 rx_data_len); +extern UINT32 CalConnectParamTimeout(tL2C_LCB *p_lcb); #endif extern void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb); diff --git a/components/bt/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/bluedroid/stack/l2cap/l2c_ble.c index f6f8319fc..3b051702e 100644 --- a/components/bt/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/bluedroid/stack/l2cap/l2c_ble.c @@ -117,14 +117,31 @@ BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_in return (FALSE); } - p_lcb->min_interval = min_int; - p_lcb->max_interval = max_int; - p_lcb->latency = latency; - p_lcb->timeout = timeout; + if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PARAM_FULL){ + UINT8 status = HCI_ERR_ILLEGAL_COMMAND; + L2CAP_TRACE_ERROR("There are two connection parameter requests that are being updated, please try later "); + if (conn_param_update_cb.update_conn_param_cb != NULL) { + tBTM_LE_UPDATE_CONN_PRAMS update_param; + update_param.max_conn_int = max_int; + update_param.min_conn_int = min_int; + update_param.conn_int = p_lcb->current_used_conn_interval; + update_param.slave_latency = p_lcb->current_used_conn_latency; + update_param.supervision_tout = p_lcb->current_used_conn_timeout; + (conn_param_update_cb.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param); + } + return (FALSE); + } + + p_lcb->waiting_update_conn_min_interval = min_int; + p_lcb->waiting_update_conn_max_interval = max_int; + p_lcb->waiting_update_conn_latency = latency; + p_lcb->waiting_update_conn_timeout = timeout; p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; if(l2cble_start_conn_update(p_lcb) == TRUE) { - btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, L2CAP_UPDATE_CONN_PARAM_TOUT); + UINT32 time = CalConnectParamTimeout(p_lcb); + btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time); + } return (TRUE); @@ -167,6 +184,10 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable) return (FALSE); } + if (p_lcb->current_used_conn_interval <= BTM_BLE_CONN_INT_MAX_DEF && (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0){ + return (FALSE); + } + if (enable) { p_lcb->conn_update_mask &= ~L2C_BLE_CONN_UPDATE_DISABLE; } else { @@ -174,7 +195,9 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable) } if (l2cble_start_conn_update(p_lcb) == TRUE) { - btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, L2CAP_UPDATE_CONN_PARAM_TOUT); + UINT32 time = CalConnectParamTimeout(p_lcb); + btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time); + } return (TRUE); @@ -304,10 +327,11 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, p_lcb->transport = BT_TRANSPORT_LE; /* update link parameter, set slave link as non-spec default upon link up */ - p_lcb->min_interval = p_lcb->max_interval = conn_interval; - p_lcb->timeout = conn_timeout; - p_lcb->latency = conn_latency; + p_lcb->waiting_update_conn_min_interval = p_lcb->waiting_update_conn_max_interval = p_lcb->current_used_conn_interval = conn_interval; + p_lcb->waiting_update_conn_timeout = p_lcb->current_used_conn_timeout = conn_timeout; + p_lcb->waiting_update_conn_latency = p_lcb->current_used_conn_latency = conn_latency; p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM; + p_lcb->updating_param_flag = false; /* If there are any preferred connection parameters, set them now */ if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) && @@ -326,10 +350,11 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int, p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout); - p_lcb->min_interval = p_dev_rec->conn_params.min_conn_int; - p_lcb->max_interval = p_dev_rec->conn_params.max_conn_int; - p_lcb->timeout = p_dev_rec->conn_params.supervision_tout; - p_lcb->latency = p_dev_rec->conn_params.slave_latency; + p_lcb->waiting_update_conn_min_interval = p_dev_rec->conn_params.min_conn_int; + p_lcb->waiting_update_conn_max_interval = p_dev_rec->conn_params.max_conn_int; + p_lcb->waiting_update_conn_timeout = p_dev_rec->conn_params.supervision_tout; + p_lcb->waiting_update_conn_latency = p_dev_rec->conn_params.slave_latency; + btsnd_hcic_ble_upd_ll_conn_params (handle, p_dev_rec->conn_params.min_conn_int, @@ -403,10 +428,11 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ p_lcb->transport = BT_TRANSPORT_LE; /* update link parameter, set slave link as non-spec default upon link up */ - p_lcb->min_interval = p_lcb->max_interval = conn_interval; - p_lcb->timeout = conn_timeout; - p_lcb->latency = conn_latency; + p_lcb->waiting_update_conn_min_interval = p_lcb->waiting_update_conn_max_interval = p_lcb->current_used_conn_interval = conn_interval; + p_lcb->waiting_update_conn_timeout = p_lcb->current_used_conn_timeout = conn_timeout; + p_lcb->waiting_update_conn_latency = p_lcb->current_used_conn_latency = conn_latency; p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM; + p_lcb->updating_param_flag = false; /* Tell BTM Acl management about the link */ p_dev_rec = btm_find_or_alloc_dev (bda); @@ -469,10 +495,10 @@ static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb) #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) && (BLE_SLAVE_UPD_CONN_PARAMS == TRUE) tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE); #endif /* defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) && (BLE_SLAVE_UPD_CONN_PARAMS == TRUE */ - UINT8 status; if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) { - L2CAP_TRACE_ERROR("%s, the last connection update command still pending.", __func__); + L2CAP_TRACE_WARNING("%s, the last connection update command still pending.", __func__); + p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PARAM_FULL; return FALSE; } @@ -482,7 +508,7 @@ static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb) up to what has been requested during connection establishement */ if (p_lcb->conn_update_mask & L2C_BLE_NOT_DEFAULT_PARAM && /* current connection interval is greater than default min */ - p_lcb->min_interval > BTM_BLE_CONN_INT_MIN) { + p_lcb->waiting_update_conn_min_interval > BTM_BLE_CONN_INT_MIN) { /* use 7.5 ms as fast connection parameter, 0 slave latency */ min_conn_int = max_conn_int = BTM_BLE_CONN_INT_MIN; slave_latency = BTM_BLE_CONN_SLAVE_LATENCY_DEF; @@ -500,15 +526,16 @@ static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb) } else { l2cu_send_peer_ble_par_req (p_lcb, min_conn_int, max_conn_int, slave_latency, supervision_tout); } + //cache save + p_lcb->updating_conn_min_interval = min_conn_int; + p_lcb->updating_conn_max_interval = max_conn_int; + p_lcb->updating_param_flag = true; + p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING; p_lcb->conn_update_mask &= ~L2C_BLE_NOT_DEFAULT_PARAM; p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; return TRUE; } else { - status = HCI_ERR_ILLEGAL_COMMAND; - L2CAP_TRACE_ERROR("%s, staus = %x, line = %d", __func__, status, __LINE__); - btu_stop_timer(&p_lcb->upda_con_timer); - l2c_send_update_conn_params_cb(p_lcb, status); return FALSE; } } else { @@ -521,18 +548,22 @@ static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb) HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features)) #endif ) { - btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->min_interval, - p_lcb->max_interval, p_lcb->latency, p_lcb->timeout, 0, 0); + btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->waiting_update_conn_min_interval, + p_lcb->waiting_update_conn_max_interval, p_lcb->waiting_update_conn_latency, p_lcb->waiting_update_conn_timeout, 0, 0); } else { - l2cu_send_peer_ble_par_req (p_lcb, p_lcb->min_interval, p_lcb->max_interval, - p_lcb->latency, p_lcb->timeout); + l2cu_send_peer_ble_par_req (p_lcb, p_lcb->waiting_update_conn_min_interval, p_lcb->waiting_update_conn_max_interval, + p_lcb->waiting_update_conn_latency, p_lcb->waiting_update_conn_timeout); } + //cache save + p_lcb->updating_conn_min_interval = p_lcb->waiting_update_conn_min_interval; + p_lcb->updating_conn_max_interval = p_lcb->waiting_update_conn_max_interval; + p_lcb->updating_param_flag = true; + p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING; p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM; p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM; return TRUE; } else { - btu_stop_timer(&p_lcb->upda_con_timer); return FALSE; } } @@ -553,36 +584,77 @@ void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_in { tL2C_LCB *p_lcb; - L2CAP_TRACE_DEBUG("l2cble_process_conn_update_evt"); /* See if we have a link control block for the remote device */ p_lcb = l2cu_find_lcb_by_handle(handle); if (!p_lcb) { L2CAP_TRACE_WARNING("l2cble_process_conn_update_evt: Invalid handle: %d", handle); return; } - - p_lcb->conn_int = conn_interval; - p_lcb->latency = conn_latency; - p_lcb->timeout = conn_timeout; - tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE); - p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING; - - if (status != HCI_SUCCESS) { + if (status == HCI_SUCCESS){ + p_lcb->current_used_conn_interval = conn_interval; + p_lcb->current_used_conn_latency = conn_latency; + p_lcb->current_used_conn_timeout = conn_timeout; + }else{ L2CAP_TRACE_WARNING("l2cble_process_conn_update_evt: Error status: %d", status); } - if (l2cble_start_conn_update(p_lcb) == TRUE) { - btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, L2CAP_UPDATE_CONN_PARAM_TOUT); - } + p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING; + p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL; - btu_stop_timer (&p_lcb->timer_entry); - - if (p_acl_cb->update_conn_param_cb != NULL) { + btu_stop_timer(&p_lcb->upda_con_timer); + + if (conn_param_update_cb.update_conn_param_cb != NULL) { l2c_send_update_conn_params_cb(p_lcb, status); } + if (l2cble_start_conn_update(p_lcb) == TRUE) { + UINT32 time = CalConnectParamTimeout(p_lcb); + btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time); + } + + btu_stop_timer (&p_lcb->timer_entry); + L2CAP_TRACE_DEBUG("l2cble_process_conn_update_evt: conn_update_mask=%d", p_lcb->conn_update_mask); } + +/******************************************************************************* +** +** Function l2cble_get_conn_param_format_err_from_contoller +** +** Description This function is called when host get illegal connection paramrters +** format status from controller +** +** Returns void +** +*******************************************************************************/ +void l2cble_get_conn_param_format_err_from_contoller (UINT8 status, UINT16 handle) +{ + tL2C_LCB *p_lcb; + + /* See if we have a link control block for the remote device */ + p_lcb = l2cu_find_lcb_by_handle(handle); + if (!p_lcb) { + L2CAP_TRACE_ERROR("%s: Invalid handle: %d", __FUNCTION__, handle); + return; + } + + p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING; + + btu_stop_timer (&p_lcb->upda_con_timer); + + if (conn_param_update_cb.update_conn_param_cb != NULL) { + l2c_send_update_conn_params_cb(p_lcb, status); + } + if ((p_lcb->conn_update_mask & L2C_BLE_UPDATE_PARAM_FULL) != 0){ + p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL; + if (l2cble_start_conn_update(p_lcb) == TRUE) { + UINT32 time = CalConnectParamTimeout(p_lcb); + btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time); + } + } + +} + /******************************************************************************* ** ** Function l2cble_process_sig_cmd @@ -630,32 +702,33 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) STREAM_TO_UINT16 (timeout, p); /* 0x000A - 0x0C80 */ /* If we are a master, the slave wants to update the parameters */ if (p_lcb->link_role == HCI_ROLE_MASTER) { - if (min_interval < BTM_BLE_CONN_INT_MIN_LIMIT) { - min_interval = BTM_BLE_CONN_INT_MIN_LIMIT; - } - if (min_interval < BTM_BLE_CONN_INT_MIN || min_interval > BTM_BLE_CONN_INT_MAX || max_interval < BTM_BLE_CONN_INT_MIN || max_interval > BTM_BLE_CONN_INT_MAX || latency > BTM_BLE_CONN_LATENCY_MAX || - /*(timeout >= max_interval && latency > (timeout * 10/(max_interval * 1.25) - 1)) ||*/ timeout < BTM_BLE_CONN_SUP_TOUT_MIN || timeout > BTM_BLE_CONN_SUP_TOUT_MAX || - timeout <= ((1 + latency)*max_interval*2) || + /* The supervision_timeout parameter defines the link supervision timeout for the connection. + The supervision_timeout in milliseconds shall be large than (1 + latency) * max_interval * 2, + where max_interval is given in milliseconds. (See [Vol 6] Part B, Section 4.5.2). + supervision_timeout (mult of 10ms); conn_interval (mult of 1.25ms) + (max_interval * 1.25 * 2) replaced by ((max_interval * 5) >> 1). + */ + ((timeout * 10) < ((1 + latency) *((max_interval * 5) >> 1))) || max_interval < min_interval) { l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_UNACCEPTABLE_PARAMS, id); - UINT8 status = HCI_ERR_PARAM_OUT_OF_RANGE; - l2c_send_update_conn_params_cb(p_lcb, status); + L2CAP_TRACE_ERROR("slave connection parameters update failed, the parameters are out of range"); } else { l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_OK, id); - p_lcb->min_interval = min_interval; - p_lcb->max_interval = max_interval; - p_lcb->latency = latency; - p_lcb->timeout = timeout; + p_lcb->waiting_update_conn_min_interval = min_interval; + p_lcb->waiting_update_conn_max_interval = max_interval; + p_lcb->waiting_update_conn_latency = latency; + p_lcb->waiting_update_conn_timeout = timeout; p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; if (l2cble_start_conn_update(p_lcb) == TRUE) { - btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, L2CAP_UPDATE_CONN_PARAM_TOUT); + UINT32 time = CalConnectParamTimeout(p_lcb); + btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time); } } } else { @@ -669,6 +742,8 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) UINT8 status = (result == 0) ? HCI_SUCCESS : HCI_ERR_PARAM_OUT_OF_RANGE; if (status != HCI_SUCCESS) { btu_stop_timer(&p_lcb->upda_con_timer); + p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING; + p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL; l2c_send_update_conn_params_cb(p_lcb, status); } break; @@ -945,10 +1020,7 @@ void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 i tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle (handle); if (p_lcb != NULL) { - p_lcb->min_interval = int_min; - p_lcb->max_interval = int_max; - p_lcb->latency = latency; - p_lcb->timeout = timeout; + /* if update is enabled, always accept connection parameter update */ if ((p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0) { p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING; @@ -1087,16 +1159,48 @@ void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 fix_cid, *******************************************************************************/ void l2c_send_update_conn_params_cb(tL2C_LCB *p_lcb, UINT8 status) { - tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE); - if (p_acl_cb != NULL && p_acl_cb->update_conn_param_cb != NULL) { + if (conn_param_update_cb.update_conn_param_cb != NULL) { tBTM_LE_UPDATE_CONN_PRAMS update_param; - update_param.max_conn_int = p_lcb->max_interval; - update_param.min_conn_int = p_lcb->min_interval; - update_param.conn_int = p_lcb->conn_int; - update_param.slave_latency = p_lcb->latency; - update_param.supervision_tout = p_lcb->timeout; - (p_acl_cb->update_conn_param_cb)(status, p_acl_cb->active_remote_addr, &update_param); + //if myself update the connection parameters + if (p_lcb->updating_param_flag){ + update_param.max_conn_int = p_lcb->updating_conn_max_interval; + update_param.min_conn_int = p_lcb->updating_conn_min_interval; + p_lcb->updating_param_flag = false; + }else{ + // remote device update the connection parameters + update_param.max_conn_int = update_param.min_conn_int = 0; + } + // current connection parameters + update_param.conn_int = p_lcb->current_used_conn_interval; + update_param.slave_latency = p_lcb->current_used_conn_latency; + update_param.supervision_tout = p_lcb->current_used_conn_timeout; + + (conn_param_update_cb.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param); } } +/******************************************************************************* +** +** Function CalConnectParamTimeout +** +** Description This function is called to calculate the connection parameter timeout. +** +** Returns timeout +** +*******************************************************************************/ +UINT32 CalConnectParamTimeout(tL2C_LCB *p_lcb) +{ + UINT32 timeout = 6; + if (p_lcb != NULL){ + //1.25 * conn_int *(1+ latency) *32 + timeout = (40 * ( 1 + p_lcb->current_used_conn_latency) * p_lcb->current_used_conn_interval + 500) / 1000; + if (timeout < 1){ + timeout = 1; + }else if (timeout > 120){ + timeout = 120; + } + } + return timeout; +} + #endif /* (BLE_INCLUDED == TRUE) */ diff --git a/components/bt/bluedroid/stack/l2cap/l2c_main.c b/components/bt/bluedroid/stack/l2cap/l2c_main.c index 3ed8a0d00..47e11cfb3 100644 --- a/components/bt/bluedroid/stack/l2cap/l2c_main.c +++ b/components/bt/bluedroid/stack/l2cap/l2c_main.c @@ -896,7 +896,12 @@ void l2c_process_timeout (TIMER_LIST_ENT *p_tle) break; case BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS: { UINT8 status = HCI_ERR_HOST_TIMEOUT; - l2c_send_update_conn_params_cb((tL2C_LCB *)p_tle->param, status); + tL2C_LCB *p_lcb = (tL2C_LCB *)p_tle->param; + if (p_lcb){ + p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING; + p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL; + } + l2c_send_update_conn_params_cb(p_lcb, status); break; } } diff --git a/examples/bluetooth/gatt_client/main/gattc_demo.c b/examples/bluetooth/gatt_client/main/gattc_demo.c index 8d7dcd37c..dc83d7f10 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,22 +293,28 @@ 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; + case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: + ESP_LOGI(GATTC_TAG, "update connetion params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + param->update_conn_params.status, + param->update_conn_params.min_int, + param->update_conn_params.max_int, + param->update_conn_params.conn_int, + param->update_conn_params.latency, + param->update_conn_params.timeout); break; - default: break; } @@ -359,8 +329,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 +351,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 +362,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 9d51df5ee..14f5546ff 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 000000000..551e25a04 --- /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 000000000..906f756bf --- /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 000000000..a98f634ea --- /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 000000000..aa2ce9dfe --- /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 000000000..9d51df5ee --- /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 4b708f3ab..6d880d9ce 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 @@ -1,11 +1,16 @@ -/* BLE Security example_ble_security_gatts_demo example - 2 - 3 This example code is in the Public Domain (or CC0 licensed, at your option.) - 4 - 5 Unless required by applicable law or agreed to in writing, this - 6 software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - 7 CONDITIONS OF ANY KIND, either express or implied. - 8 */ +// 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. #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -14,7 +19,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" @@ -33,7 +37,12 @@ #define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40 -uint8_t heart_str[] ={0x11,0x22,0x33}; +#define ADV_CONFIG_FLAG (1 << 0) +#define SCAN_RSP_CONFIG_FLAG (1 << 1) + +static uint8_t adv_config_done = 0; + +uint8_t heart_str[] = {0x11,0x22,0x33}; uint16_t heart_rate_handle_table[HRS_IDX_NB]; @@ -43,7 +52,7 @@ esp_attr_value_t gatts_demo_char1_val = .attr_len = sizeof(heart_str), .attr_value = heart_str, }; - +static uint8_t test_manufacturer[3]={'E', 'S', 'P'}; static uint8_t sec_service_uuid[16] = { /* LSB <--------------------------------------------------------------------------------> MSB */ @@ -51,10 +60,9 @@ static uint8_t sec_service_uuid[16] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x18, 0x0D, 0x00, 0x00, }; - +// config adv data static esp_ble_adv_data_t heart_rate_adv_config = { .set_scan_rsp = false, - .include_name = true, .include_txpower = true, .min_interval = 0x100, .max_interval = 0x100, @@ -67,12 +75,19 @@ static esp_ble_adv_data_t heart_rate_adv_config = { .p_service_uuid = sec_service_uuid, .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT), }; +// config scan response data +static esp_ble_adv_data_t heart_rate_scan_rsp_config = { + .set_scan_rsp = true, + .include_name = true, + .manufacturer_len = sizeof(test_manufacturer), + .p_manufacturer_data = test_manufacturer, +}; static esp_ble_adv_params_t heart_rate_adv_params = { .adv_int_min = 0x100, .adv_int_max = 0x100, .adv_type = ADV_TYPE_IND, - .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .own_addr_type = BLE_ADDR_TYPE_RANDOM, .channel_map = ADV_CHNL_ALL, .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, }; @@ -101,15 +116,9 @@ static struct gatts_profile_inst heart_rate_profile_tab[HEART_PROFILE_NUM] = { .gatts_cb = gatts_profile_event_handler, .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ }, - + }; -/* - * HTPT PROFILE ATTRIBUTES - **************************************************************************************** - */ - - /* * Heart Rate PROFILE ATTRIBUTES **************************************************************************************** @@ -224,19 +233,59 @@ static char *esp_key_type_to_str(esp_ble_key_type_t key_type) return key_str; } +static void show_bonded_devices(void) +{ + int dev_num = esp_ble_get_bond_device_num(); + + esp_ble_bond_dev_t *dev_list = (esp_ble_bond_dev_t *)malloc(sizeof(esp_ble_bond_dev_t) * dev_num); + esp_ble_get_bond_device_list(&dev_num, dev_list); + ESP_LOGI(GATTS_TABLE_TAG, "Bonded devices number : %d\n", dev_num); + + ESP_LOGI(GATTS_TABLE_TAG, "Bonded devices list : %d\n", dev_num); + for (int i = 0; i < dev_num; i++) { + esp_log_buffer_hex(GATTS_TABLE_TAG, (void *)dev_list[i].bd_addr, sizeof(esp_bd_addr_t)); + } + + free(dev_list); +} + +static void __attribute__((unused)) remove_all_bonded_devices(void) +{ + int dev_num = esp_ble_get_bond_device_num(); + + esp_ble_bond_dev_t *dev_list = (esp_ble_bond_dev_t *)malloc(sizeof(esp_ble_bond_dev_t) * dev_num); + esp_ble_get_bond_device_list(&dev_num, dev_list); + for (int i = 0; i < dev_num; i++) { + esp_ble_remove_bond_device(dev_list[i].bd_addr); + } + + free(dev_list); +} + static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { ESP_LOGV(GATTS_TABLE_TAG, "GAP_EVT, event %d\n", event); switch (event) { + 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(&heart_rate_adv_params); + } + break; case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&heart_rate_adv_params); + adv_config_done &= (~ADV_CONFIG_FLAG); + if (adv_config_done == 0){ + esp_ble_gap_start_advertising(&heart_rate_adv_params); + } break; 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) { - ESP_LOGE(GATTS_TABLE_TAG, "Advertising start failed\n"); + ESP_LOGE(GATTS_TABLE_TAG, "advertising start failed, error status = %x", param->adv_start_cmpl.status); + break; } + ESP_LOGI(GATTS_TABLE_TAG, "advertising 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. @@ -259,8 +308,38 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param (bd_addr[4] << 8) + bd_addr[5]); ESP_LOGI(GATTS_TABLE_TAG, "address type = %d", param->ble_security.auth_cmpl.addr_type); ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail"); + show_bonded_devices(); break; } + case ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT: { + ESP_LOGI(GATTS_TABLE_TAG, "ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT status = %d", param->remove_bond_dev_cmpl.status); + ESP_LOGI(GATTS_TABLE_TAG, "ESP_GAP_BLE_REMOVE_BOND_DEV"); + ESP_LOGI(GATTS_TABLE_TAG, "-----ESP_GAP_BLE_REMOVE_BOND_DEV----"); + esp_log_buffer_hex(GATTS_TABLE_TAG, (void *)param->remove_bond_dev_cmpl.bd_addr, sizeof(esp_bd_addr_t)); + ESP_LOGI(GATTS_TABLE_TAG, "------------------------------------"); + break; + } + case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT: + if (param->local_privacy_cmpl.status != ESP_BT_STATUS_SUCCESS){ + ESP_LOGE(GATTS_TABLE_TAG, "config local privacy failed, error status = %x", param->local_privacy_cmpl.status); + break; + } + + esp_err_t ret = esp_ble_gap_config_adv_data(&heart_rate_adv_config); + if (ret){ + ESP_LOGE(GATTS_TABLE_TAG, "config adv data failed, error code = %x", ret); + }else{ + adv_config_done |= ADV_CONFIG_FLAG; + } + + ret = esp_ble_gap_config_adv_data(&heart_rate_scan_rsp_config); + if (ret){ + ESP_LOGE(GATTS_TABLE_TAG, "config adv data failed, error code = %x", ret); + }else{ + adv_config_done |= SCAN_RSP_CONFIG_FLAG; + } + + break; default: break; } @@ -272,12 +351,10 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, ESP_LOGV(GATTS_TABLE_TAG, "event = %x\n",event); switch (event) { case ESP_GATTS_REG_EVT: - ESP_LOGD(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); esp_ble_gap_set_device_name(EXCAMPLE_DEVICE_NAME); - ESP_LOGD(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); - esp_ble_gap_config_adv_data(&heart_rate_adv_config); + //generate a resolvable random address + esp_ble_gap_config_local_privacy(true); - ESP_LOGD(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); esp_ble_gatts_create_attr_tab(heart_rate_gatt_db, gatts_if, HRS_IDX_NB, HEART_RATE_SVC_INST_ID); break; @@ -301,10 +378,12 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, case ESP_GATTS_STOP_EVT: break; case ESP_GATTS_CONNECT_EVT: + ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_CONNECT_EVT"); //start security connect with peer device when receive the connect event sent by the master. esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM); break; case ESP_GATTS_DISCONNECT_EVT: + ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_DISCONNECT_EVT"); ///start advertising again when missing the connect. esp_ble_gap_start_advertising(&heart_rate_adv_params); break; @@ -319,7 +398,7 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event, case ESP_GATTS_CONGEST_EVT: break; case ESP_GATTS_CREAT_ATTR_TAB_EVT: { - ESP_LOGD(GATTS_TABLE_TAG, "The number handle =%x\n",param->add_attr_tab.num_handle); + ESP_LOGI(GATTS_TABLE_TAG, "The number handle = %x",param->add_attr_tab.num_handle); if(param->add_attr_tab.num_handle == HRS_IDX_NB) { memcpy(heart_rate_handle_table, param->add_attr_tab.handles, sizeof(heart_rate_handle_table)); @@ -399,9 +478,21 @@ 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(ESP_HEART_RATE_APP_ID); + ret = esp_ble_gatts_register_callback(gatts_event_handler); + if (ret){ + ESP_LOGE(GATTS_TABLE_TAG, "gatts register error, error code = %x", ret); + return; + } + ret = esp_ble_gap_register_callback(gap_event_handler); + if (ret){ + ESP_LOGE(GATTS_TABLE_TAG, "gap register error, error code = %x", ret); + return; + } + ret = esp_ble_gatts_app_register(ESP_HEART_RATE_APP_ID); + if (ret){ + ESP_LOGE(GATTS_TABLE_TAG, "gatts app register error, error code = %x", ret); + return; + } /* set the security iocap & auth_req & key size & init key response key parameters to the stack*/ esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND; //bonding with peer device after authentication @@ -412,9 +503,19 @@ void app_main() esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t)); esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t)); esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t)); + /* If your BLE device act as a Slave, the init_key means you hope which types of key of the master should distribut to you, + and the response key means which key you can distribut to the Master; + If your BLE device act as a master, the response key means you hope which types of key of the slave should distribut to you, + and the init key means which key you can distribut to the slave. */ esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t)); esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t)); - + + /* Just show how to clear all the bonded devices + * Delay 30s, clear all the bonded devices + * + * vTaskDelay(30000 / portTICK_PERIOD_MS); + * remove_all_bonded_devices(); + */ } diff --git a/examples/bluetooth/gatt_security_server/sdkconfig.defaults b/examples/bluetooth/gatt_security_server/sdkconfig.defaults index 9d51df5ee..14f5546ff 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 bbfd76626..a4fa38d0a 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 a49e3f81c..2782c026d 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; @@ -347,10 +471,10 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t)); /* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */ conn_params.latency = 0; - conn_params.max_int = 0x50; // max_int = 0x50*1.25ms = 100ms - conn_params.min_int = 0x30; // min_int = 0x30*1.25ms = 60ms + conn_params.max_int = 0x20; // max_int = 0x20*1.25ms = 40ms + conn_params.min_int = 0x10; // min_int = 0x10*1.25ms = 20ms 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 9d51df5ee..14f5546ff 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