component/bt : support remove bonded device

1. add feature of remove bonded devices.
2. fix SMP key size bug
3. fix privacy bug
4. fix gatt set value bug
5. add gatt security client demo
6. change gatt server/gatt client demo
This commit is contained in:
Tian Hao 2017-09-08 18:42:19 +08:00 committed by zhiweijian
parent 00b5f82c41
commit 4fd437d466
48 changed files with 1688 additions and 616 deletions

View file

@ -24,9 +24,8 @@
esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback)
{
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_GAP_BLE, callback) == 0 ? ESP_OK : ESP_FAIL);
}
@ -36,10 +35,8 @@ esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data)
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (adv_data == NULL) {
return ESP_ERR_INVALID_ARG;
}
@ -63,10 +60,8 @@ esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params)
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (scan_params == NULL) {
return ESP_ERR_INVALID_ARG;
}
@ -84,9 +79,7 @@ esp_err_t esp_ble_gap_start_scanning(uint32_t duration)
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
@ -101,10 +94,8 @@ esp_err_t esp_ble_gap_stop_scanning(void)
{
btc_msg_t msg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_ACT_STOP_SCAN;
@ -116,10 +107,8 @@ esp_err_t esp_ble_gap_start_advertising(esp_ble_adv_params_t *adv_params)
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_ACT_START_ADV;
@ -132,10 +121,8 @@ esp_err_t esp_ble_gap_stop_advertising(void)
{
btc_msg_t msg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_ACT_STOP_ADV;
@ -149,10 +136,8 @@ esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params)
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_ACT_UPDATE_CONN_PARAM;
@ -166,10 +151,8 @@ esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN;
@ -185,10 +168,8 @@ esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr)
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_ACT_SET_RAND_ADDRESS;
@ -203,10 +184,8 @@ esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable)
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY;
@ -217,6 +196,8 @@ esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable)
esp_err_t esp_ble_gap_set_device_name(const char *name)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return esp_bt_dev_set_device_name(name);
}
@ -241,9 +222,7 @@ esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_l
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (raw_data == NULL
|| (raw_data_len <= 0 || raw_data_len > ESP_BLE_ADV_DATA_LEN_MAX)) {
@ -265,9 +244,7 @@ esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_d
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (raw_data == NULL
|| (raw_data_len <= 0 || raw_data_len > ESP_BLE_SCAN_RSP_DATA_LEN_MAX)) {
@ -291,6 +268,8 @@ esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type,
btc_msg_t msg;
btc_ble_gap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_SET_SECURITY_PARAM_EVT;
@ -307,6 +286,8 @@ esp_err_t esp_ble_set_encryption(esp_bd_addr_t bd_addr, esp_ble_sec_act_t sec_ac
btc_msg_t msg;
btc_ble_gap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_SET_ENCRYPTION_EVT;
@ -321,6 +302,9 @@ esp_err_t esp_ble_gap_security_rsp(esp_bd_addr_t bd_addr, bool accept)
{
btc_msg_t msg;
btc_ble_gap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_SECURITY_RSP_EVT;
@ -337,6 +321,8 @@ esp_err_t esp_ble_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t pas
btc_msg_t msg;
btc_ble_gap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_PASSKEY_REPLY_EVT;
@ -353,6 +339,8 @@ esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
btc_msg_t msg;
btc_ble_gap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_CONFIRM_REPLY_EVT;
@ -363,14 +351,47 @@ esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr)
{
btc_msg_t msg;
btc_ble_gap_args_t arg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_REMOVE_BOND_DEV_EVT;
memcpy(arg.remove_bond_device.bd_addr, bd_addr, ESP_BD_ADDR_LEN);
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_clear_bond_device_list(void)
{
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_CLEAR_BOND_DEV_EVT;
return (btc_transfer_context(&msg, NULL, 0, NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_get_bond_device_list(void)
{
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_GET_BOND_DEV_EVT;
return (btc_transfer_context(&msg, NULL, 0, NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device)
{
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;

View file

@ -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;

View file

@ -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;

View file

@ -22,6 +22,12 @@
extern "C" {
#endif
#define ESP_BLUEDROID_STATUS_CHECK(status) \
if (esp_bluedroid_get_status() != (status)) { \
return ESP_ERR_INVALID_STATE; \
}
/* relate to BT_STATUS_xxx in bt_def.h */
/// Status Return Value
typedef enum {
@ -107,6 +113,7 @@ typedef enum {
#define ESP_BLE_CSR_KEY_MASK (1 << 2) /* relate to BTM_BLE_CSR_KEY_MASK in btm_api.h */
/// Used to exchange the link key(this key just used in the BLE & BR/EDR coexist mode) in the init key & response key
#define ESP_BLE_LINK_KEY_MASK (1 << 3) /* relate to BTM_BLE_LINK_KEY_MASK in btm_api.h */
typedef uint8_t esp_ble_key_mask_t; /* the key mask type */
/// Minimum of the application id
#define ESP_APP_ID_MIN 0x0000

View file

@ -93,6 +93,11 @@ typedef enum {
ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT, /*!< When set the static rand address complete, the event comes */
ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT, /*!< When update connection parameters complete, the event comes */
ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT, /*!< When set pkt lenght complete, the event comes */
ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT, /*!< When Enable/disable privacy on the local device complete, the event comes */
ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT, /*!< When remove the bond device complete, the event comes */
ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT, /*!< When clear the bond device clear complete, the event comes */
ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT, /*!< When get the bond device list complete, the event comes */
ESP_GAP_BLE_EVT_MAX,
} esp_gap_ble_cb_event_t;
/// Advertising data maximum length
@ -293,7 +298,7 @@ typedef struct
uint16_t ediv; /*!< The ediv value*/
uint8_t sec_level; /*!< The security level of the security link*/
uint8_t key_size; /*!< The key size(7~16) of the security link*/
}esp_ble_penc_keys_t; /*!< The key type*/
} esp_ble_penc_keys_t; /*!< The key type*/
/**
* @brief BLE CSRK keys
@ -303,7 +308,7 @@ typedef struct
uint32_t counter; /*!< The counter */
esp_bt_octet16_t csrk; /*!< The csrk key */
uint8_t sec_level; /*!< The security level */
}esp_ble_pcsrk_keys_t; /*!< The pcsrk key type */
} esp_ble_pcsrk_keys_t; /*!< The pcsrk key type */
/**
* @brief BLE pid keys
@ -313,7 +318,7 @@ typedef struct
esp_bt_octet16_t irk; /*!< The irk value */
esp_ble_addr_type_t addr_type; /*!< The address type */
esp_bd_addr_t static_addr; /*!< The static address */
}esp_ble_pid_keys_t; /*!< The pid key type */
} esp_ble_pid_keys_t; /*!< The pid key type */
/**
* @brief BLE Encryption reproduction keys
@ -324,7 +329,7 @@ typedef struct
uint16_t div; /*!< The div value */
uint8_t key_size; /*!< The key size of the security link */
uint8_t sec_level; /*!< The security level of the security link */
}esp_ble_lenc_keys_t; /*!< The key type */
} esp_ble_lenc_keys_t; /*!< The key type */
/**
* @brief BLE SRK keys
@ -334,8 +339,8 @@ typedef struct
uint32_t counter; /*!< The counter value */
uint16_t div; /*!< The div value */
uint8_t sec_level; /*!< The security level of the security link */
esp_bt_octet16_t csrk; /*!< The csrk key value */
}esp_ble_lcsrk_keys; /*!< The csrk key type */
esp_bt_octet16_t csrk; /*!< The csrk key value */
} esp_ble_lcsrk_keys; /*!< The csrk key type */
/**
* @brief Structure associated with ESP_KEY_NOTIF_EVT
@ -352,7 +357,7 @@ typedef struct
typedef struct
{
esp_bd_addr_t bd_addr; /*!< peer address */
}esp_ble_sec_req_t; /*!< BLE security request type*/
} esp_ble_sec_req_t; /*!< BLE security request type*/
/**
* @brief union type of the security key value
@ -364,7 +369,27 @@ typedef union
esp_ble_pid_keys_t pid_key; /*!< peer device ID key */
esp_ble_lenc_keys_t lenc_key; /*!< local encryption reproduction keys LTK = = d1(ER,DIV,0)*/
esp_ble_lcsrk_keys lcsrk_key; /*!< local device CSRK = d1(ER,DIV,1)*/
}esp_ble_key_value_t; /*!< ble key value type*/
} esp_ble_key_value_t; /*!< ble key value type*/
/**
* @brief struct type of the bond key informatuon value
*/
typedef struct
{
esp_ble_key_mask_t key_mask; /*!< the key mask to indicate witch key is present */
esp_ble_penc_keys_t penc_key; /*!< received peer encryption key */
esp_ble_pcsrk_keys_t pcsrk_key; /*!< received peer device SRK */
esp_ble_pid_keys_t pid_key; /*!< peer device ID key */
} esp_ble_bond_key_info_t; /*!< ble bond key information value type */
/**
* @brief struct type of the bond device value
*/
typedef struct
{
esp_bd_addr_t bd_addr; /*!< peer address */
esp_ble_bond_key_info_t bond_key; /*!< the bond key information */
} esp_ble_bond_dev_t; /*!< the ble bond device type */
/**
@ -375,7 +400,7 @@ typedef struct
esp_bd_addr_t bd_addr; /*!< peer address */
esp_ble_key_type_t key_type; /*!< key type of the security link */
esp_ble_key_value_t p_key_value; /*!< the pointer to the key value */
}esp_ble_key_t; /*!< the union to the ble key value type*/
} esp_ble_key_t; /*!< the union to the ble key value type*/
/**
* @brief structure type of the ble local id keys value
@ -384,7 +409,7 @@ typedef struct {
esp_bt_octet16_t ir; /*!< the 16 bits of the ir value */
esp_bt_octet16_t irk; /*!< the 16 bits of the ir key value */
esp_bt_octet16_t dhk; /*!< the 16 bits of the dh key value */
}esp_ble_local_id_keys_t; /*!< the structure of the ble local id keys value type*/
} esp_ble_local_id_keys_t; /*!< the structure of the ble local id keys value type*/
/**
@ -400,7 +425,7 @@ typedef struct
uint8_t fail_reason; /*!< The HCI reason/error code for when success=FALSE */
esp_ble_addr_type_t addr_type; /*!< Peer device address type */
esp_bt_dev_type_t dev_type; /*!< Device type */
}esp_ble_auth_cmpl_t; /*!< The ble authentication complite cb type */
} esp_ble_auth_cmpl_t; /*!< The ble authentication complite cb type */
/**
* @brief union associated with ble security
@ -412,7 +437,7 @@ typedef union
esp_ble_key_t ble_key; /*!< BLE SMP keys used when pairing */
esp_ble_local_id_keys_t ble_id_keys; /*!< BLE IR event */
esp_ble_auth_cmpl_t auth_cmpl; /*!< Authentication complete indication. */
}esp_ble_sec_t; /*!< Ble secutity type */
} esp_ble_sec_t; /*!< Ble secutity type */
/// Sub Event of ESP_GAP_BLE_SCAN_RESULT_EVT
typedef enum {
@ -539,6 +564,33 @@ typedef union {
esp_bt_status_t status; /*!< Indicate the set pkt data length operation success status */
esp_ble_pkt_data_length_params_t params; /*!< pkt data length value */
} pkt_data_lenth_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT
*/
struct ble_local_privacy_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate the set local privacy operation success status */
} local_privacy_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT
*/
struct ble_remove_bond_dev_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate the remove bond device operation success status */
esp_bd_addr_t bd_addr; /*!< The device address which has been remove from the bond list */
}remove_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT
*/
struct ble_clear_bond_dev_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate the clear bond device operation success status */
}clear_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT
*/
struct ble_get_bond_dev_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate the get bond device operation success status */
uint8_t dev_num; /*!< Indicate the get number device in the bond list */
esp_ble_bond_dev_t *bond_dev; /*!< the pointer to the bond device Structure */
}get_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT */
} esp_ble_gap_cb_param_t;
/**
@ -814,6 +866,38 @@ esp_err_t esp_ble_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t pas
*/
esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept);
/**
* @brief Removes a device from the security database list of
* peer device. It manages unpairing event while connected.
*
* @param[in] bd_addr : BD address of the peer device
*
* @return - ESP_OK : success
* - other : failed
*
*/
esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr);
/**
* @brief Removes all of the device from the security database list of
* peer device. It manages unpairing event while connected.
*
* @return - ESP_OK : success
* - other : failed
*
*/
esp_err_t esp_ble_clear_bond_device_list(void);
/**
* @brief Get the device from the security database list of peer device.
* It will return the device bonded information from the ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT event.
*
* @return - ESP_OK : success
* - other : failed
*
*/
esp_err_t esp_ble_get_bond_device_list(void);
/**
* @brief This function is to disconnect the physical connection of the peer device
*

View file

@ -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);

View file

@ -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);
/**

View file

@ -4601,7 +4601,7 @@ void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data)
*******************************************************************************/
void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data)
{
BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable);
BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable, p_data->ble_local_privacy.set_local_privacy_cback);
}
#endif

View file

@ -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

View file

@ -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 */

View file

@ -33,6 +33,7 @@
#include "bta_gattc_int.h"
#include "l2c_api.h"
#include "l2c_int.h"
#include "gatt_int.h"
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
#include "bta_hh_int.h"
@ -2410,7 +2411,12 @@ tBTA_GATTC_FIND_SERVICE_CB bta_gattc_register_service_change_notify(UINT16 conn_
ccc_value.len = 2;
ccc_value.value[0] = GATT_CLT_CONFIG_INDICATION;
ccc_value.auth_req = GATT_AUTH_REQ_NONE;
write_status = GATTC_Write (conn_id, GATT_WRITE, &ccc_value);
if (gatt_is_clcb_allocated(conn_id)) {
APPL_TRACE_DEBUG("%s, GATTC_Write GATT_BUSY conn_id = %d", __func__, conn_id);
write_status = GATT_BUSY;
} else {
write_status = GATTC_Write (conn_id, GATT_WRITE, &ccc_value);
}
if (write_status != GATT_SUCCESS) {
start_find_ccc_timer = TRUE;
result = SERVICE_CHANGE_WRITE_CCC_FAILED;

View file

@ -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);
}
/*******************************************************************************

View file

@ -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);
}
/*******************************************************************************

View file

@ -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);
/*******************************************************************************
**

View file

@ -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);
/*******************************************************************************
**

View file

@ -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);

View file

@ -19,11 +19,14 @@
#include "bdaddr.h"
#include "btc_ble_storage.h"
#include "bta_gatts_co.h"
#include "btc_util.h"
#if (SMP_INCLUDED == TRUE)
btc_dm_pairing_cb_t pairing_cb;
btc_dm_local_key_cb_t ble_local_key_cb;
btc_bonded_devices_t bonded_devices;
/*******************************************************************************
**
@ -47,18 +50,63 @@ bt_status_t btc_storage_load_bonded_ble_devices(void)
bt_status_t btc_in_fetch_bonded_ble_devices(int add)
{
btc_bonded_devices_t bonded_devices;
bt_status_t status = BT_STATUS_FAIL;
int device_type = 0;
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
iter = btc_config_section_next(iter)) {
const char *name = btc_config_section_name(iter);
if (!string_is_bdaddr(name)) {
if (!string_is_bdaddr(name) ||
!btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) ||
((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
continue;
}
LOG_DEBUG("%s, name = %s", __func__, name);
if (btc_in_fetch_bonded_ble_device(name, add, &bonded_devices) != BT_STATUS_SUCCESS) {
LOG_DEBUG("Remote device:%s, no link key or ble key found", name);
} else {
status = BT_STATUS_SUCCESS;
}
}
return status;
}
bt_status_t btc_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev)
{
bt_bdaddr_t bd_addr;
int device_type = 0;
char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0};
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
iter = btc_config_section_next(iter)) {
const char *name = btc_config_section_name(iter);
if (!string_is_bdaddr(name) ||
!btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) ||
((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
continue;
}
if (!(btc_in_fetch_bonded_ble_device(name, add, &bonded_devices)) ) {
LOG_DEBUG("Remote device:%s, no link key or ble key found", name);
return BT_STATUS_FAIL;
string_to_bdaddr(name, &bd_addr);
memcpy(bond_dev->bd_addr, bd_addr.address, sizeof(bt_bdaddr_t));
//resolve the peer device long term key
if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PENC, buffer, sizeof(tBTM_LE_PENC_KEYS))
== BT_STATUS_SUCCESS) {
bond_dev->bond_key.key_mask |= ESP_BLE_ENC_KEY_MASK;
memcpy(&bond_dev->bond_key.penc_key, buffer, sizeof(tBTM_LE_PENC_KEYS));
}
//resolve the peer device csrk
if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PCSRK, buffer, sizeof(tBTM_LE_PCSRK_KEYS))
== BT_STATUS_SUCCESS) {
bond_dev->bond_key.key_mask |= ESP_BLE_CSR_KEY_MASK;
memcpy(&bond_dev->bond_key.pcsrk_key, buffer, sizeof(tBTM_LE_PCSRK_KEYS));
}
//resolve the peer device irk
if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PID, buffer, sizeof(tBTM_LE_PID_KEYS))
== BT_STATUS_SUCCESS) {
bond_dev->bond_key.key_mask |= ESP_BLE_ID_KEY_MASK;
memcpy(&bond_dev->bond_key.pid_key, buffer, sizeof(tBTM_LE_PID_KEYS));
}
//serch for the next bond device
bond_dev++;
}
return BT_STATUS_SUCCESS;
@ -78,6 +126,10 @@ void btc_save_ble_bonding_keys(void)
bt_bdaddr_t bd_addr;
bdcpy(bd_addr.address, pairing_cb.bd_addr);
bdstr_t bdstr;
bdaddr_to_string(&bd_addr, bdstr, sizeof(bdstr));
btc_config_set_int(bdstr, BTC_LE_DEV_TYPE, BT_DEVICE_TYPE_BLE);
LOG_DEBUG("%s, penc = %d, pid = %d", __func__, pairing_cb.ble.is_penc_key_rcvd, pairing_cb.ble.is_pid_key_rcvd);
if (pairing_cb.ble.is_penc_key_rcvd) {
btc_storage_add_ble_bonding_key(&bd_addr,
(char *) &pairing_cb.ble.penc_key,
@ -131,7 +183,6 @@ static void btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bda
char buffer[100];
memset(buffer, 0, sizeof(buffer));
if (btc_storage_get_ble_bonding_key(&bd_addr, key_type, buffer, key_len) == BT_STATUS_SUCCESS) {
if (add_key) {
BD_ADDR bta_bd_addr;
@ -152,13 +203,12 @@ static void btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bda
}
}
bt_status_t btc_storage_add_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
char *key,
uint8_t key_type,
uint8_t key_length)
{
char bdstr[6] = {0};
bdstr_t bdstr;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
const char* name;
switch (key_type) {
@ -205,7 +255,7 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
char *key_value,
int key_length)
{
char bdstr[6] = {0};
bdstr_t bdstr;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
const char* name;
switch (key_type) {
@ -235,6 +285,38 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
}
bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr,
uint8_t key_type, void *key_value, int key_length)
{
bdstr_t bdstr;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
char *key_type_str;
switch (key_type) {
case BTM_LE_KEY_PENC:
key_type_str = "LE_KEY_PENC";
break;
case BTM_LE_KEY_PID:
key_type_str = "LE_KEY_PID";
break;
case BTM_LE_KEY_PCSRK:
key_type_str = "LE_KEY_PCSRK";
break;
case BTM_LE_KEY_LENC:
key_type_str = "LE_KEY_LENC";
break;
case BTM_LE_KEY_LCSRK:
key_type_str = "LE_KEY_LCSRK";
break;
case BTM_LE_KEY_LID:
key_type_str = "LE_KEY_LID";
default:
return false;
}
return btc_compare_address_key_value(bdstr, key_type_str, key_value, key_length);
}
/*******************************************************************************
**
** Function btc_storage_remove_ble_bonding_keys
@ -247,10 +329,13 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
*******************************************************************************/
bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr)
{
char bdstr[6] = {0};
bdstr_t bdstr;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr);
int ret = 1;
if (btc_config_exist(bdstr, BTC_LE_DEV_TYPE)) {
ret &= btc_config_remove(bdstr, BTC_LE_DEV_TYPE);
}
if (btc_config_exist(bdstr, "LE_KEY_PENC")) {
ret &= btc_config_remove(bdstr, "LE_KEY_PENC");
}
@ -266,10 +351,48 @@ bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr)
if (btc_config_exist(bdstr, "LE_KEY_LCSRK")) {
ret &= btc_config_remove(bdstr, "LE_KEY_LCSRK");
}
//remove the address information after delete the ble key.
ret = btc_config_remove_section(bdstr);
btc_config_save();
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
bt_status_t btc_storage_clear_bond_devices(void)
{
bt_bdaddr_t bd_addr;
int device_type = 0;
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
iter = btc_config_section_next(iter)) {
const char *name = btc_config_section_name(iter);
if (!string_is_bdaddr(name) &&
!btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) &&
((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
continue;
}
string_to_bdaddr(name, &bd_addr);
//remove the ble bonding keys from the config and then save the config to the flash
if (btc_storage_remove_ble_bonding_keys(&bd_addr) != BT_STATUS_SUCCESS) {
LOG_ERROR("%s, remove bonding key faild", __func__);
return BT_STATUS_FAIL;
}
// the bonded_devices Structure record the devices which has been added to the BTM layer global variable
for (int i = 0; i < bonded_devices.num_devices; i++) {
//if the address is equal to the record device address, remove it from the BTM layer global variable
if (!memcmp(bd_addr.address, bonded_devices.devices[i].address, sizeof(bt_bdaddr_t))) {
BD_ADDR bta_addr;
memcpy(bta_addr, bd_addr.address, sizeof(BD_ADDR));
if(BTA_DmRemoveDevice(bta_addr) != BTA_SUCCESS) {
LOG_ERROR("%s, remove device faild", __func__);
return BT_STATUS_FAIL;
}
}
}
}
return BT_STATUS_SUCCESS;
}
/*******************************************************************************
**
** Function btc_storage_add_ble_local_key
@ -382,7 +505,7 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add,
bool device_added = false;
bool key_found = false;
if (!btc_config_get_int(remote_bd_addr, "AddrType", &device_type)) {
if (!btc_config_get_int(remote_bd_addr, BTC_LE_DEV_TYPE, &device_type)) {
LOG_ERROR("%s, device_type = %x", __func__, device_type);
return BT_STATUS_FAIL;
}
@ -413,6 +536,13 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add,
btc_read_le_key(BTM_LE_KEY_LCSRK, sizeof(tBTM_LE_LCSRK_KEYS),
bd_addr, addr_type, add, &device_added, &key_found);
// Fill in the bonded devices
if (device_added)
{
memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++],
&bd_addr, sizeof(bt_bdaddr_t));
}
if (key_found) {
return BT_STATUS_SUCCESS;
}
@ -423,7 +553,7 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add,
bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
uint8_t addr_type)
{
char bdstr[6] = {0};
bdstr_t bdstr;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bt_bdaddr_t));
int ret = btc_config_set_int(bdstr, "AddrType", (int)addr_type);
btc_config_save();
@ -443,12 +573,30 @@ bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
int*addr_type)
{
char bdstr[6] = {0};
bdstr_t bdstr;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
int ret = btc_config_get_int(bdstr, "AddrType", addr_type);
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
int btc_storage_get_num_ble_bond_devices(void)
{
int num_dev = 0;
int device_type = 0;
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
iter = btc_config_section_next(iter)) {
const char *name = btc_config_section_name(iter);
if (!string_is_bdaddr(name) &&
!btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) &&
device_type != BT_DEVICE_TYPE_BLE) {
continue;
}
num_dev++;
}
return num_dev;
}
void btc_dm_load_ble_local_keys(void)
{

View file

@ -31,7 +31,7 @@
static const char *CONFIG_FILE_PATH = "bt_config.conf";
static const period_ms_t CONFIG_SETTLE_PERIOD_MS = 3000;
static void timer_config_save(void *data);
static void btc_key_value_to_string(uint8_t *key_vaule, char *value_str, int key_length);
// TODO(zachoverflow): Move these two functions out, because they are too specific for this file
// {grumpy-cat/no, monty-python/you-make-me-sad}
@ -47,7 +47,7 @@ bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type)
bdstr_t bd_addr_str;
bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str));
if (!btc_config_get_int(bd_addr_str, "DevType", p_device_type)) {
if (!btc_config_get_int(bd_addr_str, BTC_LE_DEV_TYPE, p_device_type)) {
return FALSE;
}
@ -77,7 +77,38 @@ bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type)
static pthread_mutex_t lock; // protects operations on |config|.
static config_t *config;
static osi_alarm_t *alarm_timer;
bool btc_compare_address_key_value(const char *section, char *key_type, void *key_value, int key_length)
{
assert(key_value != NULL);
bool status = false;
char value_str[100] = {0};
if(key_length > sizeof(value_str)/2) {
return false;
}
btc_key_value_to_string((uint8_t *)key_value, value_str, key_length);
pthread_mutex_lock(&lock);
if ((status = config_has_key_in_section(config, key_type, value_str)) == true) {
config_remove_section(config, section);
}
pthread_mutex_unlock(&lock);
return status;
}
static void btc_key_value_to_string(uint8_t *key_vaule, char *value_str, int key_length)
{
const char *lookup = "0123456789abcdef";
assert(key_vaule != NULL);
assert(value_str != NULL);
for (size_t i = 0; i < key_length; ++i) {
value_str[(i * 2) + 0] = lookup[(key_vaule[i] >> 4) & 0x0F];
value_str[(i * 2) + 1] = lookup[key_vaule[i] & 0x0F];
}
return;
}
// Module lifecycle functions
@ -93,27 +124,15 @@ bool btc_config_init(void)
goto error;
}
}
if (config_save(config, CONFIG_FILE_PATH)) {
// unlink(LEGACY_CONFIG_FILE_PATH);
}
// TODO(sharvil): use a non-wake alarm for this once we have
// API support for it. There's no need to wake the system to
// write back to disk.
alarm_timer = osi_alarm_new("btc_config", timer_config_save, NULL, CONFIG_SETTLE_PERIOD_MS);
if (!alarm_timer) {
LOG_ERROR("%s unable to create alarm.\n", __func__);
goto error;
}
return true;
error:;
osi_alarm_free(alarm_timer);
config_free(config);
pthread_mutex_destroy(&lock);
alarm_timer = NULL;
config = NULL;
LOG_ERROR("%s failed\n", __func__);
return false;
@ -129,10 +148,8 @@ bool btc_config_clean_up(void)
{
btc_config_flush();
osi_alarm_free(alarm_timer);
config_free(config);
pthread_mutex_destroy(&lock);
alarm_timer = NULL;
config = NULL;
return true;
}
@ -350,51 +367,21 @@ bool btc_config_remove(const char *section, const char *key)
return ret;
}
void btc_config_save(void)
{
assert(alarm_timer != NULL);
assert(config != NULL);
osi_alarm_set(alarm_timer, CONFIG_SETTLE_PERIOD_MS);
}
void btc_config_flush(void)
bool btc_config_remove_section(const char *section)
{
assert(config != NULL);
assert(alarm_timer != NULL);
osi_alarm_cancel(alarm_timer);
assert(section != NULL);
pthread_mutex_lock(&lock);
config_save(config, CONFIG_FILE_PATH);
bool ret = config_remove_section(config, section);
pthread_mutex_unlock(&lock);
}
int btc_config_clear(void)
{
assert(config != NULL);
assert(alarm_timer != NULL);
osi_alarm_cancel(alarm_timer);
pthread_mutex_lock(&lock);
config_free(config);
config = config_new_empty();
if (config == NULL) {
pthread_mutex_unlock(&lock);
return false;
}
int ret = config_save(config, CONFIG_FILE_PATH);
pthread_mutex_unlock(&lock);
return ret;
}
static void timer_config_save(UNUSED_ATTR void *data)
void btc_config_save(void)
{
assert(config != NULL);
assert(alarm_timer != NULL);
assert(config != NULL);
// Garbage collection process: the config file accumulates
// cached information about remote devices during regular
// inquiry scans. We remove some of these junk entries
@ -433,7 +420,33 @@ static void timer_config_save(UNUSED_ATTR void *data)
while (num_keys > 0) {
config_remove_section(config, keys[--num_keys]);
}
config_save(config, CONFIG_FILE_PATH);
pthread_mutex_unlock(&lock);
}
void btc_config_flush(void)
{
assert(config != NULL);
pthread_mutex_lock(&lock);
config_save(config, CONFIG_FILE_PATH);
pthread_mutex_unlock(&lock);
}
int btc_config_clear(void)
{
assert(config != NULL);
pthread_mutex_lock(&lock);
config_free(config);
config = config_new_empty();
if (config == NULL) {
pthread_mutex_unlock(&lock);
return false;
}
int ret = config_save(config, CONFIG_FILE_PATH);
pthread_mutex_unlock(&lock);
return ret;
}

View file

@ -23,6 +23,7 @@
#include "btc_storage.h"
#include "btc_ble_storage.h"
#include "esp_gap_ble_api.h"
#include "btm_int.h"
#include "bta_api.h"
#include "bta_gatt_api.h"
@ -118,17 +119,30 @@ static void btc_disable_bluetooth_evt(void)
static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
{
/* Save link key, if not temporary */
LOG_DEBUG("%s, status = %d", __func__, p_auth_cmpl->success);
bt_status_t status = BT_STATUS_FAIL;
int addr_type;
bt_bdaddr_t bdaddr;
bdcpy(bdaddr.address, p_auth_cmpl->bd_addr);
bdcpy(pairing_cb.bd_addr, p_auth_cmpl->bd_addr);
if (p_auth_cmpl->success) {
status = BT_STATUS_SUCCESS;
int addr_type;
bt_bdaddr_t bdaddr;
bdcpy(bdaddr.address, p_auth_cmpl->bd_addr);
bdcpy(pairing_cb.bd_addr, p_auth_cmpl->bd_addr);
LOG_DEBUG ("%s, - p_auth_cmpl->bd_addr: %08x%04x", __func__,
(p_auth_cmpl->bd_addr[0] << 24) + (p_auth_cmpl->bd_addr[1] << 16) + (p_auth_cmpl->bd_addr[2] << 8) + p_auth_cmpl->bd_addr[3],
(p_auth_cmpl->bd_addr[4] << 8) + p_auth_cmpl->bd_addr[5]);
LOG_DEBUG ("%s, - pairing_cb.bd_addr: %08x%04x", __func__,
(pairing_cb.bd_addr[0] << 24) + (pairing_cb.bd_addr[1] << 16) + (pairing_cb.bd_addr[2] << 8) + pairing_cb.bd_addr[3],
(pairing_cb.bd_addr[4] << 8) + pairing_cb.bd_addr[5]);
if (btc_storage_get_remote_addr_type(&bdaddr, &addr_type) != BT_STATUS_SUCCESS) {
btc_storage_set_remote_addr_type(&bdaddr, p_auth_cmpl->addr_type);
}
/* check the irk has been save in the flash or not, if the irk has already save, means that the peer device has bonding
before. */
if(pairing_cb.ble.is_pid_key_rcvd) {
btc_storage_compare_address_key_value(&bdaddr, BTM_LE_KEY_PID,
(void *)&pairing_cb.ble.pid_key, sizeof(tBTM_LE_PID_KEYS));
}
btc_save_ble_bonding_keys();
} else {
/*Map the HCI fail reason to bt status */
@ -310,8 +324,8 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
btc_clear_services_mask();
btc_storage_load_bonded_devices();
#if (SMP_INCLUDED == TRUE)
//load the ble local key whitch has been store in the flash
btc_dm_load_ble_local_keys();
//load the bonding device to the btm layer
btc_storage_load_bonded_ble_devices();
#endif ///SMP_INCLUDED == TRUE
btc_enable_bluetooth_evt(p_data->enable.status);
break;
@ -335,8 +349,20 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
case BTA_DM_BOND_CANCEL_CMPL_EVT:
case BTA_DM_SP_CFM_REQ_EVT:
case BTA_DM_SP_KEY_NOTIF_EVT:
case BTA_DM_DEV_UNPAIRED_EVT:
break;
case BTA_DM_DEV_UNPAIRED_EVT: {
bt_bdaddr_t bd_addr;
rsp_app = true;
LOG_ERROR("BTA_DM_DEV_UNPAIRED_EVT");
memcpy(bd_addr.address, p_data->link_down.bd_addr, sizeof(BD_ADDR));
btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN);
//remove the bonded key in the config and nvs flash.
//btc_storage_remove_ble_bonding_keys(&bd_addr);
ble_msg.act = ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT;
param.remove_bond_dev_cmpl.status = (p_data->link_down.status == HCI_SUCCESS) ? ESP_BT_STATUS_SUCCESS : ESP_BT_STATUS_FAIL;
memcpy(param.remove_bond_dev_cmpl.bd_addr, p_data->link_down.bd_addr, sizeof(BD_ADDR));
break;
}
case BTA_DM_BUSY_LEVEL_EVT:
case BTA_DM_LINK_UP_EVT:
case BTA_DM_LINK_DOWN_EVT:

View file

@ -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) */
}

View file

@ -11,9 +11,11 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __BTC_BLE_STORAGE_H__
#define __BTC_BLE_STORAGE_H__
#include "bt_types.h"
#include "bt_target.h"
#include "esp_gap_ble_api.h"
#if (SMP_INCLUDED == TRUE)
#define BTC_LE_LOCAL_KEY_IR (1<<0)
@ -77,9 +79,12 @@ typedef struct
extern btc_dm_pairing_cb_t pairing_cb;
extern btc_dm_local_key_cb_t ble_local_key_cb;
extern btc_bonded_devices_t bonded_devices;
bt_status_t btc_storage_load_bonded_ble_devices(void);
bt_status_t btc_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev);
bt_status_t btc_in_fetch_bonded_ble_devices(int add);
void btc_dm_remove_ble_bonding_keys(void);
@ -89,6 +94,9 @@ bt_status_t btc_storage_add_ble_bonding_key( bt_bdaddr_t *remote_bd_addr,
uint8_t key_type,
uint8_t key_length);
bool btc_compare_le_key_value(const uint8_t key_type, const size_t key_len, const tBTA_LE_KEY_VALUE *key_vaule,
bt_bdaddr_t bd_addr);
void btc_save_ble_bonding_keys(void);
bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add,
@ -99,12 +107,16 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
char *key_value,
int key_length);
bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr,
uint8_t key_type, void *key_value, int key_length);
bt_status_t btc_storage_add_ble_local_key(char *key,
uint8_t key_type,
uint8_t key_length);
bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr);
bt_status_t btc_storage_clear_bond_devices(void);
bt_status_t btc_storage_remove_ble_local_keys(void);
bt_status_t btc_storage_get_ble_local_key(uint8_t key_type,
@ -114,6 +126,8 @@ bt_status_t btc_storage_get_ble_local_key(uint8_t key_type,
bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
int *addr_type);
int btc_storage_get_num_ble_bond_devices(void);
bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
uint8_t addr_type);
@ -121,4 +135,5 @@ void btc_dm_load_ble_local_keys(void);
void btc_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er,
tBTA_BLE_LOCAL_ID_KEYS *p_id_keys);
#endif ///SMP_INCLUDED == TRUE
#endif ///SMP_INCLUDED == TRUE
#endif ///__BTC_BLE_STORAGE_H__

View file

@ -20,6 +20,8 @@
#include "bt_types.h"
#define BTC_LE_DEV_TYPE "DevType"
typedef struct btc_config_section_iter_t btc_config_section_iter_t;
bool btc_config_init(void);
@ -35,6 +37,7 @@ bool btc_config_set_str(const char *section, const char *key, const char *value)
bool btc_config_get_bin(const char *section, const char *key, uint8_t *value, size_t *length);
bool btc_config_set_bin(const char *section, const char *key, const uint8_t *value, size_t length);
bool btc_config_remove(const char *section, const char *key);
bool btc_config_remove_section(const char *section);
size_t btc_config_get_bin_length(const char *section, const char *key);
@ -49,6 +52,7 @@ int btc_config_clear(void);
// TODO(zachoverflow): Eww...we need to move these out. These are peer specific, not config general.
bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type);
bool btc_compare_address_key_value(const char *section, char *key_type, void *key_value, int key_length);
bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type);
#endif

View file

@ -24,6 +24,7 @@
#include "btc_gatt_util.h"
#include "esp_bt_defs.h"
#include "esp_gap_ble_api.h"
#include "btc_ble_storage.h"
static tBTA_BLE_ADV_DATA gl_bta_adv_data;
static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data;
@ -145,6 +146,12 @@ static esp_bt_status_t btc_btm_status_to_esp_status (uint8_t btm_status)
case BTM_CONTROL_LE_DATA_LEN_UNSUPPORTED:
esp_status = ESP_BT_STATUS_CONTROL_LE_DATA_LEN_UNSUPPORTED;
break;
case BTM_SET_PRIVACY_SUCCESS:
esp_status = ESP_BT_STATUS_SUCCESS;
break;
case BTM_SET_PRIVACY_FAIL:
esp_status = ESP_BT_STATUS_FAIL;
break;
default:
esp_status = ESP_BT_STATUS_FAIL;
break;
@ -661,6 +668,23 @@ static void btc_set_pkt_length_callback(UINT8 status, tBTM_LE_SET_PKT_DATA_LENGT
}
}
static void btc_set_local_privacy_callback(UINT8 status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT;
param.local_privacy_cmpl.status = btc_btm_status_to_esp_status(status);
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
#if (SMP_INCLUDED == TRUE)
static void btc_set_encryption_callback(BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS enc_status)
@ -756,9 +780,74 @@ static void btc_ble_set_rand_addr (BD_ADDR rand_addr)
}
}
static void btc_ble_config_local_privacy(bool privacy_enable)
#if (SMP_INCLUDED)
static void btc_ble_remove_bond_device(esp_bt_status_t status)
{
BTA_DmBleConfigLocalPrivacy(privacy_enable);
int ret;
esp_ble_gap_cb_param_t param;
btc_msg_t msg;
param.remove_bond_dev_cmpl.status = status;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed", __func__);
}
}
static void btc_ble_clear_bond_device(void)
{
int ret;
esp_ble_gap_cb_param_t param;
btc_msg_t msg;
ret = btc_storage_clear_bond_devices();
param.clear_bond_dev_cmpl.status = ret;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed", __func__);
}
}
static void btc_ble_get_bond_device_list(void)
{
int ret;
esp_ble_gap_cb_param_t param;
esp_ble_bond_dev_t *bond_dev;
btc_msg_t msg;
int num_dev = btc_storage_get_num_ble_bond_devices();
bond_dev = GKI_getbuf(sizeof(esp_ble_bond_dev_t)*num_dev);
param.get_bond_dev_cmpl.status = btc_get_bonded_ble_devices_list(bond_dev);
param.get_bond_dev_cmpl.dev_num = num_dev;
param.get_bond_dev_cmpl.bond_dev = bond_dev;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT;
ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), btc_gap_ble_cb_deep_copy);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed", __func__);
}
// release the buffer after used.
GKI_freebuf((void *)bond_dev);
}
#endif /* #if (SMP_INCLUDED) */
static void btc_ble_config_local_privacy(bool privacy_enable, tBTA_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback)
{
BTA_DmBleConfigLocalPrivacy(privacy_enable, set_local_privacy_cback);
}
static void btc_ble_disconnect(BD_ADDR bd_addr)
@ -770,78 +859,14 @@ void btc_gap_ble_cb_handler(btc_msg_t *msg)
{
esp_ble_gap_cb_param_t *param = (esp_ble_gap_cb_param_t *)msg->arg;
switch (msg->act) {
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT, param);
break;
case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT :
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT, param);
break;
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT, param);
break;
case ESP_GAP_BLE_SCAN_RESULT_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RESULT_EVT, param);
break;
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT, param);
break;
case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT, param);
break;
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_START_COMPLETE_EVT, param);
break;
case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_START_COMPLETE_EVT, param);
break;
case ESP_GAP_BLE_AUTH_CMPL_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_AUTH_CMPL_EVT, param);
break;
case ESP_GAP_BLE_KEY_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_KEY_EVT, param);
break;
btc_gap_ble_cb_to_app(ESP_GAP_BLE_KEY_EVT, param);
case ESP_GAP_BLE_SEC_REQ_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SEC_REQ_EVT, param);
break;
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_PASSKEY_NOTIF_EVT, param);
break;
case ESP_GAP_BLE_PASSKEY_REQ_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_PASSKEY_REQ_EVT, param);
break;
case ESP_GAP_BLE_OOB_REQ_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_OOB_REQ_EVT, param);
break;
case ESP_GAP_BLE_LOCAL_IR_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_LOCAL_IR_EVT, param);
break;
case ESP_GAP_BLE_LOCAL_ER_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_LOCAL_ER_EVT, param);
break;
case ESP_GAP_BLE_NC_REQ_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_NC_REQ_EVT, param);
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT, param);
break;
case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT, param);
break;
case ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT, param);
break;
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT, param);
break;
case ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT, param);
break;
default:
break;
if (msg->act < ESP_GAP_BLE_EVT_MAX) {
btc_gap_ble_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, unknow msg->act = %d", __func__, msg->act);
}
btc_gap_ble_cb_deep_free(msg);
}
void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
@ -913,7 +938,31 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
}
}
static void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
switch (msg->act) {
case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: {
esp_ble_gap_cb_param_t *src = (esp_ble_gap_cb_param_t *)p_src;
esp_ble_gap_cb_param_t *dst = (esp_ble_gap_cb_param_t *)p_dest;
uint16_t length = 0;
if (src->get_bond_dev_cmpl.bond_dev) {
length = (src->get_bond_dev_cmpl.dev_num)*sizeof(esp_ble_bond_dev_t);
dst->get_bond_dev_cmpl.bond_dev = GKI_getbuf(length);
if (dst->get_bond_dev_cmpl.bond_dev != NULL) {
memcpy(dst->get_bond_dev_cmpl.bond_dev, src->get_bond_dev_cmpl.bond_dev, length);
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
}
break;
}
default:
LOG_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act);
break;
}
}
void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
{
LOG_DEBUG("%s \n", __func__);
switch (msg->act) {
@ -952,6 +1001,23 @@ static void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
}
}
void btc_gap_ble_cb_deep_free(btc_msg_t *msg)
{
LOG_DEBUG("%s", __func__);
switch (msg->act) {
case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: {
esp_ble_bond_dev_t *bond_dev = ((esp_ble_gap_cb_param_t *)msg->arg)->get_bond_dev_cmpl.bond_dev;
if (bond_dev) {
GKI_freebuf((void *)bond_dev);
}
break;
}
default:
LOG_DEBUG("Unhandled deep free %d", msg->act);
break;
}
}
void btc_gap_ble_call_handler(btc_msg_t *msg)
{
btc_ble_gap_args_t *arg = (btc_ble_gap_args_t *)msg->arg;
@ -1000,7 +1066,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
break;
}
case BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY:
btc_ble_config_local_privacy(arg->cfg_local_privacy.privacy_enable);
btc_ble_config_local_privacy(arg->cfg_local_privacy.privacy_enable, btc_set_local_privacy_callback);
break;
case BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW:
btc_ble_set_adv_data_raw(arg->cfg_adv_data_raw.raw_adv,
@ -1078,6 +1144,26 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
BTA_DmBleConfirmReply(bd_addr, arg->enc_comfirm_replay.accept);
break;
}
case BTC_GAP_BLE_REMOVE_BOND_DEV_EVT: {
BD_ADDR bd_addr;
bt_bdaddr_t bt_addr;
memcpy(bd_addr, arg->remove_bond_device.bd_addr, sizeof(BD_ADDR));
memcpy(bt_addr.address, arg->remove_bond_device.bd_addr, sizeof(bt_bdaddr_t));
LOG_DEBUG("BTC_GAP_BLE_REMOVE_BOND_DEV_EVT");
if (btc_storage_remove_ble_bonding_keys(&bt_addr) == BT_STATUS_SUCCESS) {
BTA_DmRemoveDevice(bd_addr);
} else {
LOG_ERROR("remove device failed: the address[%x:%x:%x:%x:%x:%x] didn't in the bonding list", bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
btc_ble_remove_bond_device(ESP_BT_STATUS_FAIL);
}
break;
}
case BTC_GAP_BLE_CLEAR_BOND_DEV_EVT:
btc_ble_clear_bond_device();
break;
case BTC_GAP_BLE_GET_BOND_DEV_EVT:
btc_ble_get_bond_device_list();
break;
#endif ///SMP_INCLUDED == TRUE
case BTC_GAP_BLE_DISCONNECT_EVT:
btc_ble_disconnect(arg->disconnect.remote_device);

View file

@ -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);
}

View file

@ -40,6 +40,9 @@ typedef enum {
BTC_GAP_BLE_PASSKEY_REPLY_EVT,
BTC_GAP_BLE_CONFIRM_REPLY_EVT,
BTC_GAP_BLE_DISCONNECT_EVT,
BTC_GAP_BLE_REMOVE_BOND_DEV_EVT,
BTC_GAP_BLE_CLEAR_BOND_DEV_EVT,
BTC_GAP_BLE_GET_BOND_DEV_EVT,
} btc_gap_ble_act_t;
/* btc_ble_gap_args_t */
@ -89,44 +92,50 @@ typedef union {
uint8_t *raw_scan_rsp;
uint32_t raw_scan_rsp_len;
} cfg_scan_rsp_data_raw;
//BTC_GAP_BLE_SET_ENCRYPTION_EVT
struct set_encryption_args {
esp_bd_addr_t bd_addr;
esp_ble_sec_act_t sec_act;
} set_encryption;
//BTC_GAP_BLE_SET_SECURITY_PARAM_EVT
struct set_security_param_args {
esp_ble_sm_param_t param_type;
uint8_t len;
uint8_t *value;
} set_security_param;
//BTC_GAP_BLE_SECURITY_RSP_EVT
struct enc_rsp_args {
esp_bd_addr_t bd_addr;
bool accept;
} sec_rsp;
//BTC_GAP_BLE_PASSKEY_REPLY_EVT
struct enc_passkey_reply_args {
esp_bd_addr_t bd_addr;
bool accept;
uint32_t passkey;
} enc_passkey_replay;
//BTC_GAP_BLE_CONFIRM_REPLY_EVT
struct enc_comfirm_reply_args {
esp_bd_addr_t bd_addr;
bool accept;
} enc_comfirm_replay;
//BTC_GAP_BLE_DISCONNECT_EVT
struct disconnect_args {
esp_bd_addr_t remote_device;
} disconnect;
//BTC_GAP_BLE_REMOVE_BOND_DEV_EVT
struct remove_bond_device_args {
esp_bd_addr_t bd_addr;
} remove_bond_device;
} btc_ble_gap_args_t;
void btc_gap_ble_call_handler(btc_msg_t *msg);
void btc_gap_ble_cb_handler(btc_msg_t *msg);
void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_gap_ble_arg_deep_free(btc_msg_t *msg);
void btc_gap_ble_cb_deep_free(btc_msg_t *msg);
void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
#endif /* __BTC_GAP_BLE_H__ */

View file

@ -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__ */

View file

@ -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);

View file

@ -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*/

View file

@ -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;

View file

@ -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

View file

@ -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;
}
}
}
/*******************************************************************************

View file

@ -640,10 +640,16 @@ void BTM_BleEnableMixedPrivacyMode(BOOLEAN mixed_on)
** Returns BOOLEAN privacy mode set success; otherwise failed.
**
*******************************************************************************/
BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode)
BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode, tBTM_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback)
{
#if BLE_PRIVACY_SPT == TRUE
tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
tBTM_LE_RANDOM_CB *random_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
if (random_cb){
random_cb->set_local_privacy_cback = set_local_privacy_cback;
}else{
BTM_TRACE_ERROR("%s,random_cb = NULL", __func__);
}
BTM_TRACE_EVENT ("%s\n", __func__);

View file

@ -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;

View file

@ -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;

View file

@ -1596,7 +1596,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start);
**
*******************************************************************************/
//extern
BOOLEAN BTM_BleConfigPrivacy(BOOLEAN enable);
BOOLEAN BTM_BleConfigPrivacy(BOOLEAN enable, tBTM_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cabck);
/*******************************************************************************
**

View file

@ -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

View file

@ -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,
&notify_descr_id,
sizeof(notify_en),
(uint8_t *)&notify_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,
&notify_descr_id,
sizeof(notify_en),
(uint8_t *)&notify_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,
&notify_descr_id,
sizeof(notify_en),
(uint8_t *)&notify_en,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
break;
}
case ESP_GATTC_NOTIFY_EVT:
ESP_LOGI(GATTC_TAG, "NOTIFY: len %d, value %08x", p_data->notify.value_len, *(uint32_t *)p_data->notify.value);
break;
case ESP_GATTC_WRITE_DESCR_EVT:
ESP_LOGI(GATTC_TAG, "WRITE: status %d", p_data->write.status);
case ESP_GATTC_DISCONNECT_EVT:
connect = false;
get_server = false;
ESP_LOGI(GATTC_TAG, "ESP_GATTC_DISCONNECT_EVT, status = %d", p_data->disconnect.status);
break;
default:
break;
@ -292,29 +254,31 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
//scan start complete event to indicate scan start successfully or failed
if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
ESP_LOGE(GATTC_TAG, "Scan start failed");
ESP_LOGE(GATTC_TAG, "scan start failed, error status = %x", param->scan_start_cmpl.status);
break;
}
ESP_LOGI(GATTC_TAG, "scan start success");
break;
case ESP_GAP_BLE_SCAN_RESULT_EVT: {
esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param;
switch (scan_result->scan_rst.search_evt) {
case ESP_GAP_SEARCH_INQ_RES_EVT:
esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6);
ESP_LOGI(GATTC_TAG, "Searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len);
ESP_LOGI(GATTC_TAG, "searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len);
adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv,
ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len);
ESP_LOGI(GATTC_TAG, "Searched Device Name Len %d", adv_name_len);
ESP_LOGI(GATTC_TAG, "searched Device Name Len %d", adv_name_len);
esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len);
ESP_LOGI(GATTC_TAG, "\n");
if (adv_name != NULL) {
if (strlen(device_name) == adv_name_len && strncmp((char *)adv_name, device_name, adv_name_len) == 0) {
ESP_LOGI(GATTC_TAG, "Searched device %s\n", device_name);
if (strlen(remote_device_name) == adv_name_len && strncmp((char *)adv_name, remote_device_name, adv_name_len) == 0) {
ESP_LOGI(GATTC_TAG, "searched device %s\n", remote_device_name);
if (connect == false) {
connect = true;
ESP_LOGI(GATTC_TAG, "Connect to the remote device.");
ESP_LOGI(GATTC_TAG, "connect to the remote device.");
esp_ble_gap_stop_scanning();
esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, scan_result->scan_rst.bda, true);
esp_ble_gattc_open(gl_profile_tab[PROFILE_B_APP_ID].gattc_if, scan_result->scan_rst.bda, true);
}
}
}
@ -329,20 +293,18 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
if (param->scan_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){
ESP_LOGE(GATTC_TAG, "Scan stop failed");
}
else {
ESP_LOGI(GATTC_TAG, "Stop scan successfully");
ESP_LOGE(GATTC_TAG, "scan stop failed, error status = %x", param->scan_stop_cmpl.status);
break;
}
ESP_LOGI(GATTC_TAG, "stop scan successfully");
break;
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){
ESP_LOGE(GATTC_TAG, "Adv stop failed");
}
else {
ESP_LOGI(GATTC_TAG, "Stop adv successfully");
ESP_LOGE(GATTC_TAG, "adv stop failed, error status = %x", param->adv_stop_cmpl.status);
break;
}
ESP_LOGI(GATTC_TAG, "stop adv successfully");
break;
default:
@ -359,8 +321,8 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp
if (param->reg.status == ESP_GATT_OK) {
gl_profile_tab[param->reg.app_id].gattc_if = gattc_if;
} else {
ESP_LOGI(GATTC_TAG, "Reg app failed, app_id %04x, status %d",
param->reg.app_id,
ESP_LOGI(GATTC_TAG, "reg app failed, app_id %04x, status %d",
param->reg.app_id,
param->reg.status);
return;
}
@ -381,34 +343,6 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp
} while (0);
}
void ble_client_appRegister(void)
{
esp_err_t status;
ESP_LOGI(GATTC_TAG, "register callback");
//register the scan callback function to the gap module
if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) {
ESP_LOGE(GATTC_TAG, "gap register error, error code = %x", status);
return;
}
//register the callback function to the gattc module
if ((status = esp_ble_gattc_register_callback(esp_gattc_cb)) != ESP_OK) {
ESP_LOGE(GATTC_TAG, "gattc register error, error code = %x", status);
return;
}
esp_ble_gattc_app_register(PROFILE_A_APP_ID);
esp_ble_gattc_app_register(PROFILE_B_APP_ID);
}
void gattc_client_test(void)
{
esp_bluedroid_init();
esp_bluedroid_enable();
ble_client_appRegister();
}
void app_main()
{
// Initialize NVS.
@ -420,9 +354,48 @@ void app_main()
ESP_ERROR_CHECK( ret );
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
esp_bt_controller_init(&bt_cfg);
esp_bt_controller_enable(ESP_BT_MODE_BTDM);
ret = esp_bt_controller_init(&bt_cfg);
if (ret) {
ESP_LOGE(GATTC_TAG, "%s initialize controller failed, error code = %x\n", __func__, ret);
return;
}
ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM);
if (ret) {
ESP_LOGE(GATTC_TAG, "%s enable controller failed, error code = %x\n", __func__, ret);
return;
}
ret = esp_bluedroid_init();
if (ret) {
ESP_LOGE(GATTC_TAG, "%s init bluetooth failed, error code = %x\n", __func__, ret);
return;
}
ret = esp_bluedroid_enable();
if (ret) {
ESP_LOGE(GATTC_TAG, "%s enable bluetooth failed, error code = %x\n", __func__, ret);
return;
}
//register the callback function to the gap module
ret = esp_ble_gap_register_callback(esp_gap_cb);
if (ret){
ESP_LOGE(GATTC_TAG, "%s gap register failed, error code = %x\n", __func__, ret);
return;
}
//register the callback function to the gattc module
ret = esp_ble_gattc_register_callback(esp_gattc_cb);
if(ret){
ESP_LOGE(GATTC_TAG, "%s gattc register failed, error code = %x\n", __func__, ret);
return;
}
ret = esp_ble_gattc_app_register(PROFILE_A_APP_ID);
if (ret){
ESP_LOGE(GATTC_TAG, "%s gattc app register failed, error code = %x\n", __func__, ret);
}
gattc_client_test();
}

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View file

@ -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 <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#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 *)&notify_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);
}
}

View file

@ -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

View file

@ -261,6 +261,23 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param
ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail");
break;
}
case ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT: {
ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT status = %d", param->remove_bond_dev_cmpl.status);
break;
}
case ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT: {
ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT status = %d", param->clear_bond_dev_cmpl.status);
break;
}
case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: {
ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT status = %d, num = %d", param->get_bond_dev_cmpl.status, param->get_bond_dev_cmpl.dev_num);
esp_ble_bond_dev_t *bond_dev = param->get_bond_dev_cmpl.bond_dev;
for(int i = 0; i < param->get_bond_dev_cmpl.dev_num; i++) {
ESP_LOGD(GATTS_TABLE_TAG, "mask = %x", bond_dev[i].bond_key.key_mask);
esp_log_buffer_hex(GATTS_TABLE_TAG, (void *)bond_dev[i].bd_addr, sizeof(esp_bd_addr_t));
}
break;
}
default:
break;
}

View file

@ -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

View file

@ -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.

View file

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -22,7 +32,6 @@
#include "esp_log.h"
#include "nvs_flash.h"
#include "bt.h"
#include "bta_api.h"
#include "esp_gap_ble_api.h"
#include "esp_gatts_api.h"
@ -34,7 +43,7 @@
#define GATTS_TAG "GATTS_DEMO"
///Declare the static function
///Declare the static function
static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
@ -56,13 +65,20 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
#define PREPARE_BUF_MAX_SIZE 1024
uint8_t char1_str[] = {0x11,0x22,0x33};
esp_attr_value_t gatts_demo_char1_val =
esp_gatt_char_prop_t a_property = 0;
esp_gatt_char_prop_t b_property = 0;
esp_attr_value_t gatts_demo_char1_val =
{
.attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX,
.attr_len = sizeof(char1_str),
.attr_value = char1_str,
};
static uint8_t adv_config_done = 0;
#define adv_config_flag (1 << 0)
#define scan_rsp_config_flag (1 << 1)
#ifdef CONFIG_SET_RAW_ADV_DATA
static uint8_t raw_adv_data[] = {
0x02, 0x01, 0x06,
@ -73,16 +89,19 @@ static uint8_t raw_scan_rsp_data[] = {
0x45, 0x4d, 0x4f
};
#else
static uint8_t test_service_uuid128[32] = {
static uint8_t adv_service_uuid128[32] = {
/* LSB <--------------------------------------------------------------------------------> MSB */
//first uuid, 16bit, [12],[13] is the value
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0x00, 0x00,
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xEE, 0x00, 0x00, 0x00,
//second uuid, 32bit, [12], [13], [14], [15] is the value
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0xAB, 0xCD,
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
};
// The length of adv data must be less than 31 bytes
//static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, 0x45, 0x56};
static esp_ble_adv_data_t test_adv_data = {
//adv data
static esp_ble_adv_data_t adv_data = {
.set_scan_rsp = false,
.include_name = true,
.include_txpower = true,
@ -94,12 +113,29 @@ static esp_ble_adv_data_t test_adv_data = {
.service_data_len = 0,
.p_service_data = NULL,
.service_uuid_len = 32,
.p_service_uuid = test_service_uuid128,
.p_service_uuid = adv_service_uuid128,
.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
};
// scan response data
static esp_ble_adv_data_t scan_rsp_data = {
.set_scan_rsp = true,
.include_name = true,
.include_txpower = true,
.min_interval = 0x20,
.max_interval = 0x40,
.appearance = 0x00,
.manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN,
.p_manufacturer_data = NULL, //&test_manufacturer[0],
.service_data_len = 0,
.p_service_data = NULL,
.service_uuid_len = 32,
.p_service_uuid = adv_service_uuid128,
.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
};
#endif /* CONFIG_SET_RAW_ADV_DATA */
static esp_ble_adv_params_t test_adv_params = {
static esp_ble_adv_params_t adv_params = {
.adv_int_min = 0x20,
.adv_int_max = 0x40,
.adv_type = ADV_TYPE_IND,
@ -155,15 +191,33 @@ void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
switch (event) {
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
esp_ble_gap_start_advertising(&test_adv_params);
break;
#ifdef CONFIG_SET_RAW_ADV_DATA
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
esp_ble_gap_start_advertising(&test_adv_params);
adv_config_done &= (~adv_config_flag);
if (adv_config_done==0){
esp_ble_gap_start_advertising(&adv_params);
}
break;
case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
esp_ble_gap_start_advertising(&test_adv_params);
adv_config_done &= (~scan_rsp_config_flag);
if (adv_config_done==0){
esp_ble_gap_start_advertising(&adv_params);
}
break;
#else
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
adv_config_done &= (~adv_config_flag);
if (adv_config_done == 0){
esp_ble_gap_start_advertising(&adv_params);
}
break;
case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
adv_config_done &= (~scan_rsp_config_flag);
if (adv_config_done == 0){
esp_ble_gap_start_advertising(&adv_params);
}
break;
#endif
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
//advertising start complete event to indicate advertising start successfully or failed
if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
@ -200,7 +254,7 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare
prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE*sizeof(uint8_t));
prepare_write_env->prepare_len = 0;
if (prepare_write_env->prepare_buf == NULL) {
LOG_ERROR("Gatt_server prep no mem\n");
ESP_LOGE(GATTS_TAG, "Gatt_server prep no mem\n");
status = ESP_GATT_NO_RESOURCES;
}
} else {
@ -219,7 +273,7 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare
memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp);
if (response_err != ESP_OK){
LOG_ERROR("Send response error\n");
ESP_LOGE(GATTS_TAG, "Send response error\n");
}
free(gatt_rsp);
if (status != ESP_GATT_OK){
@ -260,10 +314,30 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
esp_ble_gap_set_device_name(TEST_DEVICE_NAME);
#ifdef CONFIG_SET_RAW_ADV_DATA
esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data));
esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data));
esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data));
if (raw_adv_ret){
ESP_LOGE(GATTS_TAG, "config raw adv data failed, error code = %x ", raw_adv_ret);
}
adv_config_done |= adv_config_flag;
esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data));
if (raw_scan_ret){
ESP_LOGE(GATTS_TAG, "config raw scan rsp data failed, error code = %x", raw_scan_ret);
}
adv_config_done |= scan_rsp_config_flag;
#else
esp_ble_gap_config_adv_data(&test_adv_data);
//config adv data
esp_err_t ret = esp_ble_gap_config_adv_data(&adv_data);
if (ret){
ESP_LOGE(GATTS_TAG, "config adv data failed, error code = %x", ret);
}
adv_config_done |= adv_config_flag;
//config scan response data
ret = esp_ble_gap_config_adv_data(&scan_rsp_data);
if (ret){
ESP_LOGE(GATTS_TAG, "config scan response data failed, error code = %x", ret);
}
adv_config_done |= scan_rsp_config_flag;
#endif
esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_A);
break;
@ -282,8 +356,46 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
break;
}
case ESP_GATTS_WRITE_EVT: {
ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, param->write.trans_id, param->write.handle);
ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %08x\n", param->write.len, *(uint32_t *)param->write.value);
ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d", param->write.conn_id, param->write.trans_id, param->write.handle);
if (!param->write.is_prep){
ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len);
esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len);
if (gl_profile_tab[PROFILE_A_APP_ID].descr_handle == param->write.handle && param->write.len == 2){
uint16_t descr_value = param->write.value[1]<<8 | param->write.value[0];
if (descr_value == 0x0001){
if (a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY){
ESP_LOGI(GATTS_TAG, "notify enable");
uint8_t notify_data[15];
for (int i = 0; i < sizeof(notify_data); ++i)
{
notify_data[i] = i%0xff;
}
//the size of notify_data[] need less than MTU size
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
sizeof(notify_data), notify_data, false);
}
}else if (descr_value == 0x0002){
if (a_property & ESP_GATT_CHAR_PROP_BIT_INDICATE){
ESP_LOGI(GATTS_TAG, "indicate enable");
uint8_t indicate_data[15];
for (int i = 0; i < sizeof(indicate_data); ++i)
{
indicate_data[i] = i%0xff;
}
//the size of indicate_data[] need less than MTU size
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
sizeof(indicate_data), indicate_data, true);
}
}
else if (descr_value == 0x0000){
ESP_LOGI(GATTS_TAG, "notify/indicate disable ");
}else{
ESP_LOGE(GATTS_TAG, "unknown descr value");
esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len);
}
}
}
example_write_event_env(gatts_if, &a_prepare_write_env, param);
break;
}
@ -293,6 +405,8 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
example_exec_write_event_env(&a_prepare_write_env, param);
break;
case ESP_GATTS_MTU_EVT:
ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
break;
case ESP_GATTS_CONF_EVT:
case ESP_GATTS_UNREG_EVT:
break;
@ -303,11 +417,14 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A;
esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle);
esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY,
&gatts_demo_char1_val, NULL);
a_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
esp_err_t add_char_ret = esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
a_property,
&gatts_demo_char1_val, NULL);
if (add_char_ret){
ESP_LOGE(GATTS_TAG, "add char failed, error code =%x",add_char_ret);
}
break;
case ESP_GATTS_ADD_INCL_SRVC_EVT:
break;
@ -320,17 +437,24 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle;
gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16;
gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char);
esp_err_t get_attr_ret = esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char);
if (get_attr_ret == ESP_FAIL){
ESP_LOGE(GATTS_TAG, "ILLEGAL HANDLE");
}
ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length);
for(int i = 0; i < length; i++){
ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n",i,prf_char[i]);
}
esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
esp_err_t add_descr_ret = esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
if (add_descr_ret){
ESP_LOGE(GATTS_TAG, "add char descr failed, error code =%x", add_descr_ret);
}
break;
}
case ESP_GATTS_ADD_CHAR_DESCR_EVT:
gl_profile_tab[PROFILE_A_APP_ID].descr_handle = param->add_char.attr_handle;
ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",
param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
break;
@ -350,7 +474,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
conn_params.max_int = 0x50; // max_int = 0x50*1.25ms = 100ms
conn_params.min_int = 0x30; // min_int = 0x30*1.25ms = 60ms
conn_params.timeout = 400; // timeout = 400*10ms = 4000ms
ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n",
ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d",
param->connect.conn_id,
param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2],
param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5],
@ -361,7 +485,8 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
break;
}
case ESP_GATTS_DISCONNECT_EVT:
esp_ble_gap_start_advertising(&test_adv_params);
ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT");
esp_ble_gap_start_advertising(&adv_params);
break;
case ESP_GATTS_OPEN_EVT:
case ESP_GATTS_CANCEL_OPEN_EVT:
@ -400,7 +525,44 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
}
case ESP_GATTS_WRITE_EVT: {
ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, param->write.trans_id, param->write.handle);
ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %08x\n", param->write.len, *(uint32_t *)param->write.value);
if (!param->write.is_prep){
ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len);
esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len);
if (gl_profile_tab[PROFILE_B_APP_ID].descr_handle == param->write.handle && param->write.len == 2){
uint16_t descr_value= param->write.value[1]<<8 | param->write.value[0];
if (descr_value == 0x0001){
if (b_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY){
ESP_LOGI(GATTS_TAG, "notify enable");
uint8_t notify_data[15];
for (int i = 0; i < sizeof(notify_data); ++i)
{
notify_data[i] = i%0xff;
}
//the size of notify_data[] need less than MTU size
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_B_APP_ID].char_handle,
sizeof(notify_data), notify_data, false);
}
}else if (descr_value == 0x0002){
if (b_property & ESP_GATT_CHAR_PROP_BIT_INDICATE){
ESP_LOGI(GATTS_TAG, "indicate enable");
uint8_t indicate_data[15];
for (int i = 0; i < sizeof(indicate_data); ++i)
{
indicate_data[i] = i%0xff;
}
//the size of indicate_data[] need less than MTU size
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_B_APP_ID].char_handle,
sizeof(indicate_data), indicate_data, true);
}
}
else if (descr_value == 0x0000){
ESP_LOGI(GATTS_TAG, "notify/indicate disable ");
}else{
ESP_LOGE(GATTS_TAG, "unknown value");
}
}
}
example_write_event_env(gatts_if, &b_prepare_write_env, param);
break;
}
@ -410,6 +572,8 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
example_exec_write_event_env(&b_prepare_write_env, param);
break;
case ESP_GATTS_MTU_EVT:
ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
break;
case ESP_GATTS_CONF_EVT:
case ESP_GATTS_UNREG_EVT:
break;
@ -420,11 +584,14 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
gl_profile_tab[PROFILE_B_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_B;
esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle);
esp_ble_gatts_add_char(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY,
NULL, NULL);
b_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
esp_err_t add_char_ret =esp_ble_gatts_add_char( gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
b_property,
NULL, NULL);
if (add_char_ret){
ESP_LOGE(GATTS_TAG, "add char failed, error code =%x",add_char_ret);
}
break;
case ESP_GATTS_ADD_INCL_SRVC_EVT:
break;
@ -440,6 +607,7 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
NULL, NULL);
break;
case ESP_GATTS_ADD_CHAR_DESCR_EVT:
gl_profile_tab[PROFILE_B_APP_ID].descr_handle = param->add_char.attr_handle;
ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",
param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
break;
@ -452,7 +620,7 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
case ESP_GATTS_STOP_EVT:
break;
case ESP_GATTS_CONNECT_EVT:
ESP_LOGI(GATTS_TAG, "CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n",
ESP_LOGI(GATTS_TAG, "CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d",
param->connect.conn_id,
param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2],
param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5],
@ -478,7 +646,7 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_
gl_profile_tab[param->reg.app_id].gatts_if = gatts_if;
} else {
ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d\n",
param->reg.app_id,
param->reg.app_id,
param->reg.status);
return;
}
@ -534,10 +702,26 @@ void app_main()
return;
}
esp_ble_gatts_register_callback(gatts_event_handler);
esp_ble_gap_register_callback(gap_event_handler);
esp_ble_gatts_app_register(PROFILE_A_APP_ID);
esp_ble_gatts_app_register(PROFILE_B_APP_ID);
ret = esp_ble_gatts_register_callback(gatts_event_handler);
if (ret){
ESP_LOGE(GATTS_TAG, "gatts register error, error code = %x", ret);
return;
}
ret = esp_ble_gap_register_callback(gap_event_handler);
if (ret){
ESP_LOGE(GATTS_TAG, "gap register error, error code = %x", ret);
return;
}
ret = esp_ble_gatts_app_register(PROFILE_A_APP_ID);
if (ret){
ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret);
return;
}
ret = esp_ble_gatts_app_register(PROFILE_B_APP_ID);
if (ret){
ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret);
return;
}
return;
}

View file

@ -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