فهرست منبع

component bt:Added the create attribute table method to the new API

Yulong 9 سال پیش
والد
کامیت
d512d6100c
37فایلهای تغییر یافته به همراه2361 افزوده شده و 672 حذف شده
  1. 7 7
      components/bt/bluedroid/api/esp_blufi_api.c
  2. 6 6
      components/bt/bluedroid/api/esp_bt_main.c
  3. 14 14
      components/bt/bluedroid/api/esp_gap_ble_api.c
  4. 25 25
      components/bt/bluedroid/api/esp_gattc_api.c
  5. 98 26
      components/bt/bluedroid/api/esp_gatts_api.c
  6. 114 111
      components/bt/bluedroid/api/include/esp_gap_ble_api.h
  7. 202 90
      components/bt/bluedroid/api/include/esp_gatt_defs.h
  8. 174 102
      components/bt/bluedroid/api/include/esp_gatts_api.h
  9. 58 3
      components/bt/bluedroid/bta/gatt/bta_gatts_act.c
  10. 60 6
      components/bt/bluedroid/bta/gatt/bta_gatts_api.c
  11. 7 6
      components/bt/bluedroid/bta/gatt/bta_gatts_main.c
  12. 109 65
      components/bt/bluedroid/bta/include/bta_gatt_api.h
  13. 18 6
      components/bt/bluedroid/bta/include/bta_gatts_int.h
  14. 7 3
      components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c
  15. 282 9
      components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c
  16. 36 1
      components/bt/bluedroid/btc/profile/std/include/btc_gatts.h
  17. 3 6
      components/bt/bluedroid/hci/packet_fragmenter.c
  18. 8 4
      components/bt/bluedroid/stack/gap/gap_ble.c
  19. 86 26
      components/bt/bluedroid/stack/gatt/gatt_api.c
  20. 7 4
      components/bt/bluedroid/stack/gatt/gatt_attr.c
  21. 303 30
      components/bt/bluedroid/stack/gatt/gatt_db.c
  22. 3 3
      components/bt/bluedroid/stack/gatt/gatt_main.c
  23. 61 35
      components/bt/bluedroid/stack/gatt/gatt_sr.c
  24. 29 1
      components/bt/bluedroid/stack/gatt/gatt_utils.c
  25. 69 51
      components/bt/bluedroid/stack/gatt/include/gatt_int.h
  26. 69 22
      components/bt/bluedroid/stack/include/gatt_api.h
  27. 1 1
      components/bt/bluedroid/stack/smp/smp_main.c
  28. 1 2
      docs/api/esp_blufi.rst
  29. 23 0
      docs/api/esp_gatt_defs.rst
  30. 9 0
      docs/api/esp_gatts.rst
  31. 32 7
      examples/14_gatt_server/main/gatts_demo.c
  32. 11 0
      examples/30_gatt_server_table_create/Makefile
  33. 10 0
      examples/30_gatt_server_table_create/README.rst
  34. 8 0
      examples/30_gatt_server_table_create/main/component.mk
  35. 340 0
      examples/30_gatt_server_table_create/main/gatts_table_creat_demo.c
  36. 57 0
      examples/30_gatt_server_table_create/main/gatts_table_creat_demo.h
  37. 14 0
      examples/30_gatt_server_table_create/sdkconfig.defaults

+ 7 - 7
components/bt/bluedroid/api/esp_blufi_api.c

@@ -25,9 +25,9 @@
 esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks)
 esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks)
 {
 {
     if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
     if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     if (callbacks == NULL) {
     if (callbacks == NULL) {
         return ESP_FAIL;
         return ESP_FAIL;
     }
     }
@@ -42,9 +42,9 @@ esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn
     btc_blufi_args_t arg;
     btc_blufi_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
     msg.pid = BTC_PID_BLUFI;
     msg.pid = BTC_PID_BLUFI;
     msg.act = BTC_BLUFI_ACT_SEND_CFG_REPORT;
     msg.act = BTC_BLUFI_ACT_SEND_CFG_REPORT;
@@ -62,7 +62,7 @@ esp_err_t esp_blufi_profile_init(void)
     btc_msg_t msg;
     btc_msg_t msg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -77,9 +77,9 @@ esp_err_t esp_blufi_profile_deinit(void)
     btc_msg_t msg;
     btc_msg_t msg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
     msg.pid = BTC_PID_BLUFI;
     msg.pid = BTC_PID_BLUFI;
     msg.act = BTC_BLUFI_ACT_DEINIT;
     msg.act = BTC_BLUFI_ACT_DEINIT;

+ 6 - 6
components/bt/bluedroid/api/esp_bt_main.c

@@ -24,13 +24,13 @@ static bool esp_already_init = false;
 esp_bluedroid_status_t esp_bluedroid_get_status(void)
 esp_bluedroid_status_t esp_bluedroid_get_status(void)
 {
 {
     if (esp_already_init) {
     if (esp_already_init) {
-	if (esp_already_enable) {
-	    return ESP_BLUEDROID_STATUS_ENABLED;
-	} else {
-	    return ESP_BLUEDROID_STATUS_INITIALIZED;
-	}
+        if (esp_already_enable) {
+            return ESP_BLUEDROID_STATUS_ENABLED;
+        } else {
+            return ESP_BLUEDROID_STATUS_INITIALIZED;
+        }
     } else {
     } else {
-	return ESP_BLUEDROID_STATUS_UNINITIALIZED;
+        return ESP_BLUEDROID_STATUS_UNINITIALIZED;
     }
     }
 }
 }
 
 

+ 14 - 14
components/bt/bluedroid/api/esp_gap_ble_api.c

@@ -25,7 +25,7 @@
 esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback)
 esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback)
 {
 {
     if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
     if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     return (btc_profile_cb_set(BTC_PID_GAP_BLE, callback) == 0 ? ESP_OK : ESP_FAIL);
     return (btc_profile_cb_set(BTC_PID_GAP_BLE, callback) == 0 ? ESP_OK : ESP_FAIL);
 }
 }
@@ -37,7 +37,7 @@ esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data)
     btc_ble_gap_args_t arg;
     btc_ble_gap_args_t arg;
     
     
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     if (adv_data == NULL) {
     if (adv_data == NULL) {
@@ -64,7 +64,7 @@ esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params)
     btc_ble_gap_args_t arg;
     btc_ble_gap_args_t arg;
     
     
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     if (scan_params == NULL) {
     if (scan_params == NULL) {
@@ -85,7 +85,7 @@ esp_err_t esp_ble_gap_start_scanning(uint32_t duration)
     btc_ble_gap_args_t arg;
     btc_ble_gap_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
 
 
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -102,7 +102,7 @@ esp_err_t esp_ble_gap_stop_scanning(void)
     btc_msg_t msg;
     btc_msg_t msg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -116,8 +116,8 @@ esp_err_t esp_ble_gap_start_advertising(esp_ble_adv_params_t *adv_params)
     btc_msg_t msg;
     btc_msg_t msg;
     btc_ble_gap_args_t arg;
     btc_ble_gap_args_t arg;
 
 
-    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {	    
-	return ESP_ERR_INVALID_STATE;
+    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {       
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -133,7 +133,7 @@ esp_err_t esp_ble_gap_stop_advertising(void)
     btc_msg_t msg;
     btc_msg_t msg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -150,7 +150,7 @@ esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params)
     btc_ble_gap_args_t arg;
     btc_ble_gap_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -167,7 +167,7 @@ esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_
     btc_ble_gap_args_t arg;
     btc_ble_gap_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {    
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {    
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -186,7 +186,7 @@ esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr)
     btc_ble_gap_args_t arg;
     btc_ble_gap_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -204,7 +204,7 @@ esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable)
     btc_ble_gap_args_t arg;
     btc_ble_gap_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -221,9 +221,9 @@ esp_err_t esp_ble_gap_set_device_name(const char *name)
     btc_ble_gap_args_t arg;
     btc_ble_gap_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     if (strlen(name) > ESP_GAP_DEVICE_NAME_MAX) {
     if (strlen(name) > ESP_GAP_DEVICE_NAME_MAX) {
         return ESP_ERR_INVALID_ARG;
         return ESP_ERR_INVALID_ARG;
     }
     }

+ 25 - 25
components/bt/bluedroid/api/esp_gattc_api.c

@@ -23,9 +23,9 @@
 esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback)
 esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback)
 {
 {
     if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
     if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     if (callback == NULL) {
     if (callback == NULL) {
         return ESP_FAIL;
         return ESP_FAIL;
     }
     }
@@ -40,9 +40,9 @@ esp_err_t esp_ble_gattc_app_register(uint16_t app_id)
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     if (app_id > ESP_APP_ID_MAX) {
     if (app_id > ESP_APP_ID_MAX) {
         return ESP_ERR_INVALID_ARG;
         return ESP_ERR_INVALID_ARG;
     }
     }
@@ -61,7 +61,7 @@ esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gattc_if)
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -78,9 +78,9 @@ esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, b
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
     msg.pid = BTC_PID_GATTC;
     msg.pid = BTC_PID_GATTC;
     msg.act = BTC_GATTC_ACT_OPEN;
     msg.act = BTC_GATTC_ACT_OPEN;
@@ -97,7 +97,7 @@ esp_err_t esp_ble_gattc_close (esp_gatt_if_t gattc_if, uint16_t conn_id)
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -114,7 +114,7 @@ esp_err_t esp_ble_gattc_config_mtu (esp_gatt_if_t gattc_if, uint16_t conn_id, ui
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     if ((mtu < ESP_GATT_DEF_BLE_MTU_SIZE) || (mtu > ESP_GATT_MAX_MTU_SIZE)) {
     if ((mtu < ESP_GATT_DEF_BLE_MTU_SIZE) || (mtu > ESP_GATT_MAX_MTU_SIZE)) {
@@ -136,7 +136,7 @@ esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id,
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -163,7 +163,7 @@ esp_err_t esp_ble_gattc_get_characteristic(esp_gatt_if_t gattc_if,
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -192,9 +192,9 @@ esp_err_t esp_ble_gattc_get_descriptor(esp_gatt_if_t gattc_if,
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
     msg.pid = BTC_PID_GATTC;
     msg.pid = BTC_PID_GATTC;
 
 
@@ -223,7 +223,7 @@ esp_err_t esp_ble_gattc_get_included_service(esp_gatt_if_t gattc_if,
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -253,7 +253,7 @@ esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -278,7 +278,7 @@ esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if,
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -299,14 +299,14 @@ esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if,
                                     esp_gatt_id_t *char_id,
                                     esp_gatt_id_t *char_id,
                                     uint16_t value_len,
                                     uint16_t value_len,
                                     uint8_t *value,
                                     uint8_t *value,
-									esp_gatt_write_type_t write_type,
+                                    esp_gatt_write_type_t write_type,
                                     esp_gatt_auth_req_t auth_req)
                                     esp_gatt_auth_req_t auth_req)
 {
 {
     btc_msg_t msg;
     btc_msg_t msg;
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -330,16 +330,16 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
                                         esp_gatt_id_t *descr_id,
                                         esp_gatt_id_t *descr_id,
                                         uint16_t value_len,
                                         uint16_t value_len,
                                         uint8_t *value,
                                         uint8_t *value,
-                                		esp_gatt_write_type_t write_type,
+                                        esp_gatt_write_type_t write_type,
                                         esp_gatt_auth_req_t auth_req)
                                         esp_gatt_auth_req_t auth_req)
 {
 {
     btc_msg_t msg;
     btc_msg_t msg;
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
     msg.pid = BTC_PID_GATTC;
     msg.pid = BTC_PID_GATTC;
     msg.act = BTC_GATTC_ACT_WRITE_CHAR_DESCR;
     msg.act = BTC_GATTC_ACT_WRITE_CHAR_DESCR;
@@ -369,7 +369,7 @@ esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -392,7 +392,7 @@ esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id,
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -413,7 +413,7 @@ esp_gatt_status_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if,
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -436,7 +436,7 @@ esp_gatt_status_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if,
     btc_ble_gattc_args_t arg;
     btc_ble_gattc_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;

+ 98 - 26
components/bt/bluedroid/api/esp_gatts_api.c

@@ -22,10 +22,11 @@
 
 
 #define COPY_TO_GATTS_ARGS(_gatt_args, _arg, _arg_type) memcpy(_gatt_args, _arg, sizeof(_arg_type))
 #define COPY_TO_GATTS_ARGS(_gatt_args, _arg, _arg_type) memcpy(_gatt_args, _arg, sizeof(_arg_type))
 
 
+
 esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback)
 esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback)
 {
 {
     if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
     if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     return (btc_profile_cb_set(BTC_PID_GATTS, callback) == 0 ? ESP_OK : ESP_FAIL);
     return (btc_profile_cb_set(BTC_PID_GATTS, callback) == 0 ? ESP_OK : ESP_FAIL);
 }
 }
@@ -36,7 +37,7 @@ esp_err_t esp_ble_gatts_app_register(uint16_t app_id)
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     //if (app_id < ESP_APP_ID_MIN || app_id > ESP_APP_ID_MAX) {
     //if (app_id < ESP_APP_ID_MIN || app_id > ESP_APP_ID_MAX) {
@@ -59,9 +60,9 @@ esp_err_t esp_ble_gatts_app_unregister(esp_gatt_if_t gatts_if)
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
     msg.pid = BTC_PID_GATTS;
     msg.pid = BTC_PID_GATTS;
     msg.act = BTC_GATTS_ACT_APP_UNREGISTER;
     msg.act = BTC_GATTS_ACT_APP_UNREGISTER;
@@ -77,7 +78,7 @@ esp_err_t esp_ble_gatts_create_service(esp_gatt_if_t gatts_if,
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -90,6 +91,26 @@ esp_err_t esp_ble_gatts_create_service(esp_gatt_if_t gatts_if,
     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
     return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 }
 
 
+esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db,
+                                        esp_gatt_if_t gatts_if,
+                                        uint8_t max_nb_attr,
+                                        uint8_t srvc_inst_id)
+{
+    btc_msg_t msg;
+    btc_ble_gatts_args_t arg;
+
+    msg.sig = BTC_SIG_API_CALL;
+    msg.pid = BTC_PID_GATTS;
+    msg.act = BTC_GATTS_ACT_CREATE_ATTR_TAB;
+    arg.create_attr_tab.gatts_if = gatts_if;
+    arg.create_attr_tab.max_nb_attr = max_nb_attr;
+    arg.create_attr_tab.srvc_inst_id = srvc_inst_id;
+    arg.create_attr_tab.gatts_attr_db = (esp_gatts_attr_db_t *)gatts_attr_db;
+
+    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy)
+            == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
 
 
 esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t included_service_handle)
 esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t included_service_handle)
 {
 {
@@ -97,7 +118,7 @@ esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t i
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -111,46 +132,69 @@ esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t i
 
 
 
 
 esp_err_t esp_ble_gatts_add_char(uint16_t service_handle,  esp_bt_uuid_t  *char_uuid,
 esp_err_t esp_ble_gatts_add_char(uint16_t service_handle,  esp_bt_uuid_t  *char_uuid,
-                                 esp_gatt_perm_t perm, esp_gatt_char_prop_t property)
+                                 esp_gatt_perm_t perm, esp_gatt_char_prop_t property, esp_attr_value_t *char_val,
+                                 esp_attr_control_t *control)
 {
 {
     btc_msg_t msg;
     btc_msg_t msg;
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+
+    memset(&arg, 0, sizeof(btc_ble_gatts_args_t));
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
     msg.pid = BTC_PID_GATTS;
     msg.pid = BTC_PID_GATTS;
     msg.act = BTC_GATTS_ACT_ADD_CHAR;
     msg.act = BTC_GATTS_ACT_ADD_CHAR;
     arg.add_char.service_handle = service_handle;
     arg.add_char.service_handle = service_handle;
     arg.add_char.perm = perm;
     arg.add_char.perm = perm;
     arg.add_char.property = property;
     arg.add_char.property = property;
+    if (char_val != NULL) {
+        arg.add_char.char_val.attr_max_len = char_val->attr_max_len;
+        arg.add_char.char_val.attr_len = char_val->attr_len;
+        arg.add_char.char_val.attr_value = char_val->attr_value;
+    }
+
+    if (control != NULL) {
+        arg.add_char.attr_control.auto_rsp = control->auto_rsp;
+    }
     memcpy(&arg.add_char.char_uuid, char_uuid, sizeof(esp_bt_uuid_t));
     memcpy(&arg.add_char.char_uuid, char_uuid, sizeof(esp_bt_uuid_t));
 
 
-    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 }
 
 
 
 
 esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
 esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
                                         esp_bt_uuid_t   *descr_uuid,
                                         esp_bt_uuid_t   *descr_uuid,
-                                        esp_gatt_perm_t perm)
+                                        esp_gatt_perm_t perm, esp_attr_value_t *char_descr_val,
+                                        esp_attr_control_t *control)
 {
 {
     btc_msg_t msg;
     btc_msg_t msg;
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
+    memset(&arg, 0, sizeof(btc_ble_gatts_args_t));
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
     msg.pid = BTC_PID_GATTS;
     msg.pid = BTC_PID_GATTS;
     msg.act = BTC_GATTS_ACT_ADD_CHAR_DESCR;
     msg.act = BTC_GATTS_ACT_ADD_CHAR_DESCR;
     arg.add_descr.service_handle = service_handle;
     arg.add_descr.service_handle = service_handle;
     arg.add_descr.perm = perm;
     arg.add_descr.perm = perm;
+
+    if (char_descr_val != NULL) {
+        arg.add_descr.descr_val.attr_max_len = char_descr_val->attr_max_len;
+        arg.add_descr.descr_val.attr_len = char_descr_val->attr_len;
+        arg.add_descr.descr_val.attr_value = char_descr_val->attr_value;
+    }
+
+    if (control != NULL) {
+        arg.add_descr.attr_control.auto_rsp = control->auto_rsp;
+    }
     memcpy(&arg.add_descr.descr_uuid, descr_uuid, sizeof(esp_bt_uuid_t));
     memcpy(&arg.add_descr.descr_uuid, descr_uuid, sizeof(esp_bt_uuid_t));
 
 
-    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 }
 
 
 esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle)
 esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle)
@@ -159,7 +203,7 @@ esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle)
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -176,7 +220,7 @@ esp_err_t esp_ble_gatts_start_service(uint16_t service_handle)
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -193,9 +237,9 @@ esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle)
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
     msg.pid = BTC_PID_GATTS;
     msg.pid = BTC_PID_GATTS;
     msg.act = BTC_GATTS_ACT_STOP_SERVICE;
     msg.act = BTC_GATTS_ACT_STOP_SERVICE;
@@ -212,7 +256,7 @@ esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id,
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -224,7 +268,8 @@ esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id,
     arg.send_ind.value_len = value_len;
     arg.send_ind.value_len = value_len;
     arg.send_ind.value = value;
     arg.send_ind.value = value;
 
 
-    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t),
+                                 btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 }
 
 
 esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id, uint32_t trans_id,
 esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id, uint32_t trans_id,
@@ -234,7 +279,7 @@ esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id,
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -245,7 +290,32 @@ esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id,
     arg.send_rsp.status = status;
     arg.send_rsp.status = status;
     arg.send_rsp.rsp = rsp;
     arg.send_rsp.rsp = rsp;
 
 
-    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t),
+                                 btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, const uint8_t *value)
+{
+    btc_msg_t msg;
+    btc_ble_gatts_args_t arg;
+
+    msg.sig = BTC_SIG_API_CALL;
+    msg.pid = BTC_PID_GATTS;
+    msg.act = BTC_GATTS_ACT_SET_ATTR_VALUE;
+    arg.set_attr_val.length = length;
+    arg.set_attr_val.value  = (uint8_t *)value;
+
+    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t),
+                                 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)
+{
+    if (attr_handle == ESP_GATT_ILLEGAL_HANDLE) {
+        return ESP_FAIL;
+    }
+    btc_gatts_get_attr_value(attr_handle, length, (uint8_t **)value);
+    return ESP_OK;
 }
 }
 
 
 esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, bool is_direct)
 esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, bool is_direct)
@@ -254,7 +324,7 @@ esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, b
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
     
     
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
@@ -264,7 +334,8 @@ esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, b
     arg.open.is_direct = is_direct;
     arg.open.is_direct = is_direct;
     memcpy(&arg.open.remote_bda, remote_bda, sizeof(esp_bd_addr_t));
     memcpy(&arg.open.remote_bda, remote_bda, sizeof(esp_bd_addr_t));
 
 
-    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL)
+            == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 }
 
 
 esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id)
 esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id)
@@ -273,13 +344,14 @@ esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id)
     btc_ble_gatts_args_t arg;
     btc_ble_gatts_args_t arg;
 
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     }
-	
+    
     msg.sig = BTC_SIG_API_CALL;
     msg.sig = BTC_SIG_API_CALL;
     msg.pid = BTC_PID_GATTS;
     msg.pid = BTC_PID_GATTS;
     msg.act = BTC_GATTS_ACT_CLOSE;
     msg.act = BTC_GATTS_ACT_CLOSE;
     arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
     arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
 
 
-    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL)
+            == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 }

+ 114 - 111
components/bt/bluedroid/api/include/esp_gap_ble_api.h

@@ -40,42 +40,44 @@ extern "C" {
 
 
 /// GAP BLE callback event type
 /// GAP BLE callback event type
 typedef enum {
 typedef enum {
-	ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT        = 0,		/*!< When advertising data set complete, the event comes */
-	ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT ,			/*!< When scan response data set complete, the event comes */
-	ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT,				/*!< When scan parameters set complete, the event comes */
-	ESP_GAP_BLE_SCAN_RESULT_EVT,							/*!< When one scan result ready, the event comes each time */
+    ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT        = 0,       /*!< When advertising data set complete, the event comes */
+    ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT,             /*!< When scan response data set complete, the event comes */
+    ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT,                /*!< When scan parameters set complete, the event comes */
+    ESP_GAP_BLE_SCAN_RESULT_EVT,                            /*!< When one scan result ready, the event comes each time */
 } esp_gap_ble_cb_event_t;
 } esp_gap_ble_cb_event_t;
 
 
 /// Advertising data maximum length
 /// Advertising data maximum length
-#define ESP_BLE_ADV_DATA_LEN_MAX        31
+#define ESP_BLE_ADV_DATA_LEN_MAX               31
+/// Scan response data maximum length
+#define ESP_BLE_SCAN_RSP_DATA_LEN_MAX          31
 
 
 /// The type of advertising data(not adv_type)
 /// The type of advertising data(not adv_type)
 typedef enum {
 typedef enum {
-	ESP_BLE_AD_TYPE_FLAG                     = 0x01,
-	ESP_BLE_AD_TYPE_16SRV_PART               = 0x02,
-	ESP_BLE_AD_TYPE_16SRV_CMPL               = 0x03,
-	ESP_BLE_AD_TYPE_32SRV_PART               = 0x04,
-	ESP_BLE_AD_TYPE_32SRV_CMPL               = 0x05,
-	ESP_BLE_AD_TYPE_128SRV_PART              = 0x06,
-	ESP_BLE_AD_TYPE_128SRV_CMPL              = 0x07,
-	ESP_BLE_AD_TYPE_NAME_SHORT               = 0x08,
-	ESP_BLE_AD_TYPE_NAME_CMPL                = 0x09,
-	ESP_BLE_AD_TYPE_TX_PWR                   = 0x0A,
-	ESP_BLE_AD_TYPE_DEV_CLASS                = 0x0D,
-	ESP_BLE_AD_TYPE_SM_TK                    = 0x10,
-	ESP_BLE_AD_TYPE_SM_OOB_FLAG              = 0x11,
-	ESP_BLE_AD_TYPE_INT_RANGE                = 0x12,
-	ESP_BLE_AD_TYPE_SOL_SRV_UUID             = 0x14,
-	ESP_BLE_AD_TYPE_128SOL_SRV_UUID          = 0x15,
-	ESP_BLE_AD_TYPE_SERVICE_DATA             = 0x16,
-	ESP_BLE_AD_TYPE_PUBLIC_TARGET            = 0x17,
-	ESP_BLE_AD_TYPE_RANDOM_TARGET            = 0x18,
-	ESP_BLE_AD_TYPE_APPEARANCE               = 0x19,
-	ESP_BLE_AD_TYPE_ADV_INT                  = 0x1A,
-	ESP_BLE_AD_TYPE_32SOL_SRV_UUID           = 0x1B,
-	ESP_BLE_AD_TYPE_32SERVICE_DATA           = 0x1C,
-	ESP_BLE_AD_TYPE_128SERVICE_DATA          = 0x1D,
-	ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE    = 0xFF,
+    ESP_BLE_AD_TYPE_FLAG                     = 0x01,
+    ESP_BLE_AD_TYPE_16SRV_PART               = 0x02,
+    ESP_BLE_AD_TYPE_16SRV_CMPL               = 0x03,
+    ESP_BLE_AD_TYPE_32SRV_PART               = 0x04,
+    ESP_BLE_AD_TYPE_32SRV_CMPL               = 0x05,
+    ESP_BLE_AD_TYPE_128SRV_PART              = 0x06,
+    ESP_BLE_AD_TYPE_128SRV_CMPL              = 0x07,
+    ESP_BLE_AD_TYPE_NAME_SHORT               = 0x08,
+    ESP_BLE_AD_TYPE_NAME_CMPL                = 0x09,
+    ESP_BLE_AD_TYPE_TX_PWR                   = 0x0A,
+    ESP_BLE_AD_TYPE_DEV_CLASS                = 0x0D,
+    ESP_BLE_AD_TYPE_SM_TK                    = 0x10,
+    ESP_BLE_AD_TYPE_SM_OOB_FLAG              = 0x11,
+    ESP_BLE_AD_TYPE_INT_RANGE                = 0x12,
+    ESP_BLE_AD_TYPE_SOL_SRV_UUID             = 0x14,
+    ESP_BLE_AD_TYPE_128SOL_SRV_UUID          = 0x15,
+    ESP_BLE_AD_TYPE_SERVICE_DATA             = 0x16,
+    ESP_BLE_AD_TYPE_PUBLIC_TARGET            = 0x17,
+    ESP_BLE_AD_TYPE_RANDOM_TARGET            = 0x18,
+    ESP_BLE_AD_TYPE_APPEARANCE               = 0x19,
+    ESP_BLE_AD_TYPE_ADV_INT                  = 0x1A,
+    ESP_BLE_AD_TYPE_32SOL_SRV_UUID           = 0x1B,
+    ESP_BLE_AD_TYPE_32SERVICE_DATA           = 0x1C,
+    ESP_BLE_AD_TYPE_128SERVICE_DATA          = 0x1D,
+    ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE    = 0xFF,
 } esp_ble_adv_data_type;
 } esp_ble_adv_data_type;
 
 
 /// Advertising mode
 /// Advertising mode
@@ -109,37 +111,37 @@ typedef enum {
 
 
 /// Advertising parameters
 /// Advertising parameters
 typedef struct {
 typedef struct {
-    uint16_t                adv_int_min;		/*!< Minimum advertising interval for
-												  undirected and low duty cycle directed advertising.
- 												  Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
-												  Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec */
-    uint16_t                adv_int_max;		/*!< Maximum advertising interval for
-												  undirected and low duty cycle directed advertising.
- 												  Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
-												  Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec Advertising max interval */
-    esp_ble_adv_type_t      adv_type;			/*!< Advertising type */
-    esp_ble_addr_type_t     own_addr_type;		/*!< Owner bluetooth device address type */
-    esp_bd_addr_t           peer_addr;			/*!< Peer device bluetooth device address */
-    esp_ble_addr_type_t     peer_addr_type;		/*!< Peer device bluetooth device address type */
-    esp_ble_adv_channel_t   channel_map;		/*!< Advertising channel map */
-    esp_ble_adv_filter_t    adv_filter_policy;	/*!< Advertising filter policy */
+    uint16_t                adv_int_min;        /*!< Minimum advertising interval for
+                                                  undirected and low duty cycle directed advertising.
+                                                  Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
+                                                  Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec */
+    uint16_t                adv_int_max;        /*!< Maximum advertising interval for
+                                                  undirected and low duty cycle directed advertising.
+                                                  Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
+                                                  Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec Advertising max interval */
+    esp_ble_adv_type_t      adv_type;           /*!< Advertising type */
+    esp_ble_addr_type_t     own_addr_type;      /*!< Owner bluetooth device address type */
+    esp_bd_addr_t           peer_addr;          /*!< Peer device bluetooth device address */
+    esp_ble_addr_type_t     peer_addr_type;     /*!< Peer device bluetooth device address type */
+    esp_ble_adv_channel_t   channel_map;        /*!< Advertising channel map */
+    esp_ble_adv_filter_t    adv_filter_policy;  /*!< Advertising filter policy */
 } esp_ble_adv_params_t;
 } esp_ble_adv_params_t;
 
 
 /// Advertising data content, according to "Supplement to the Bluetooth Core Specification"
 /// Advertising data content, according to "Supplement to the Bluetooth Core Specification"
 typedef struct {
 typedef struct {
-    bool                    set_scan_rsp;			/*!< Set this advertising data as scan response or not*/
-    bool                    include_name;			/*!< Advertising data include device name or not */
-    bool                    include_txpower;		/*!< Advertising data include TX power */
-    int                     min_interval;			/*!< Advertising data show advertising min interval */
-    int                     max_interval;			/*!< Advertising data show advertising max interval */
-    int                     appearance;				/*!< External appearance of device */
-    uint16_t                manufacturer_len;		/*!< Manufacturer data length */
-    uint8_t                 *p_manufacturer_data;	/*!< Manufacturer data point */
-    uint16_t                service_data_len;		/*!< Service data length */
-    uint8_t                 *p_service_data;		/*!< Service data point */
-    uint16_t                service_uuid_len;		/*!< Service uuid length */
-    uint8_t                 *p_service_uuid;		/*!< Service uuid array point */
-    uint8_t                 flag;					/*!< Advertising flag of discovery mode, see BLE_ADV_DATA_FLAG detail */
+    bool                    set_scan_rsp;           /*!< Set this advertising data as scan response or not*/
+    bool                    include_name;           /*!< Advertising data include device name or not */
+    bool                    include_txpower;        /*!< Advertising data include TX power */
+    int                     min_interval;           /*!< Advertising data show advertising min interval */
+    int                     max_interval;           /*!< Advertising data show advertising max interval */
+    int                     appearance;             /*!< External appearance of device */
+    uint16_t                manufacturer_len;       /*!< Manufacturer data length */
+    uint8_t                 *p_manufacturer_data;   /*!< Manufacturer data point */
+    uint16_t                service_data_len;       /*!< Service data length */
+    uint8_t                 *p_service_data;        /*!< Service data point */
+    uint16_t                service_uuid_len;       /*!< Service uuid length */
+    uint8_t                 *p_service_uuid;        /*!< Service uuid array point */
+    uint8_t                 flag;                   /*!< Advertising flag of discovery mode, see BLE_ADV_DATA_FLAG detail */
 } esp_ble_adv_data_t;
 } esp_ble_adv_data_t;
 
 
 /// Own BD address source of the device
 /// Own BD address source of the device
@@ -160,53 +162,53 @@ typedef enum {
 
 
 /// Ble scan type 
 /// Ble scan type 
 typedef enum {
 typedef enum {
-    BLE_SCAN_TYPE_PASSIVE   =   0x0,			/*!< Passive scan */
-    BLE_SCAN_TYPE_ACTIVE    =   0x1,			/*!< Active scan */
+    BLE_SCAN_TYPE_PASSIVE   =   0x0,            /*!< Passive scan */
+    BLE_SCAN_TYPE_ACTIVE    =   0x1,            /*!< Active scan */
 } esp_ble_scan_type_t;
 } esp_ble_scan_type_t;
 
 
 /// Ble scan filter type
 /// Ble scan filter type
 typedef enum {
 typedef enum {
-    BLE_SCAN_FILTER_ALLOW_ALL           = 0x0,	/*!< Accept all :
-												  1. advertisement packets except directed advertising packets not addressed to this device (default). */
+    BLE_SCAN_FILTER_ALLOW_ALL           = 0x0,  /*!< Accept all :
+                                                  1. advertisement packets except directed advertising packets not addressed to this device (default). */
     BLE_SCAN_FILTER_ALLOW_ONLY_WLST     = 0x1,  /*!< Accept only : 
     BLE_SCAN_FILTER_ALLOW_ONLY_WLST     = 0x1,  /*!< Accept only : 
-												  1. advertisement packets from devices where the advertiser’s address is in the White list.
-												  2. Directed advertising packets which are not addressed for this device shall be ignored. */
+                                                  1. advertisement packets from devices where the advertiser’s address is in the White list.
+                                                  2. Directed advertising packets which are not addressed for this device shall be ignored. */
     BLE_SCAN_FILTER_ALLOW_UND_RPA_DIR   = 0x2,  /*!< Accept all :
     BLE_SCAN_FILTER_ALLOW_UND_RPA_DIR   = 0x2,  /*!< Accept all :
-												  1. undirected advertisement packets, and
-												  2. directed advertising packets where the initiator address is a resolvable private address, and
-												  3. directed advertising packets addressed to this device. */
+                                                  1. undirected advertisement packets, and
+                                                  2. directed advertising packets where the initiator address is a resolvable private address, and
+                                                  3. directed advertising packets addressed to this device. */
     BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR = 0x3,  /*!< Accept all :
     BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR = 0x3,  /*!< Accept all :
-												  1. advertisement packets from devices where the advertiser’s address is in the White list, and
-												  2. directed advertising packets where the initiator address is a resolvable private address, and
-												  3. directed advertising packets addressed to this device.*/
+                                                  1. advertisement packets from devices where the advertiser’s address is in the White list, and
+                                                  2. directed advertising packets where the initiator address is a resolvable private address, and
+                                                  3. directed advertising packets addressed to this device.*/
 } esp_ble_scan_filter_t;
 } esp_ble_scan_filter_t;
 
 
 /// Ble scan parameters
 /// Ble scan parameters
 typedef struct {
 typedef struct {
-    esp_ble_scan_type_t     scan_type;				/*!< Scan type */
-    esp_ble_addr_type_t     own_addr_type;			/*!< Owner address type */
-    esp_ble_scan_filter_t   scan_filter_policy;		/*!< Scan filter policy */
-    uint16_t                scan_interval;			/*!< Scan interval. This is defined as the time interval from
-													  when the Controller started its last LE scan until it begins the subsequent LE scan.
-													  Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
-													  Time = N * 0.625 msec
-													  Time Range: 2.5 msec to 10.24 seconds*/
-    uint16_t                scan_window;			/*!< Scan window. The duration of the LE scan. LE_Scan_Window
-													  shall be less than or equal to LE_Scan_Interval
-													  Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
-													  Time = N * 0.625 msec
-													  Time Range: 2.5 msec to 10240 msec */
+    esp_ble_scan_type_t     scan_type;              /*!< Scan type */
+    esp_ble_addr_type_t     own_addr_type;          /*!< Owner address type */
+    esp_ble_scan_filter_t   scan_filter_policy;     /*!< Scan filter policy */
+    uint16_t                scan_interval;          /*!< Scan interval. This is defined as the time interval from
+                                                      when the Controller started its last LE scan until it begins the subsequent LE scan.
+                                                      Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
+                                                      Time = N * 0.625 msec
+                                                      Time Range: 2.5 msec to 10.24 seconds*/
+    uint16_t                scan_window;            /*!< Scan window. The duration of the LE scan. LE_Scan_Window
+                                                      shall be less than or equal to LE_Scan_Interval
+                                                      Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
+                                                      Time = N * 0.625 msec
+                                                      Time Range: 2.5 msec to 10240 msec */
 } esp_ble_scan_params_t;
 } esp_ble_scan_params_t;
 
 
 /// Connection update parameters
 /// Connection update parameters
 typedef struct {
 typedef struct {
-    esp_bd_addr_t bda;								/*!< Bluetooth device address */
-    uint16_t min_int;								/*!< Min connection interval */
-    uint16_t max_int;								/*!< Max connection interval */
-    uint16_t latency;								/*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */
-    uint16_t timeout;								/*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80.
-													  Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec
-													  Time Range: 100 msec to 32 seconds */
+    esp_bd_addr_t bda;                              /*!< Bluetooth device address */
+    uint16_t min_int;                               /*!< Min connection interval */
+    uint16_t max_int;                               /*!< Max connection interval */
+    uint16_t latency;                               /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */
+    uint16_t timeout;                               /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80.
+                                                      Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec
+                                                      Time Range: 100 msec to 32 seconds */
 } esp_ble_conn_update_params_t;
 } esp_ble_conn_update_params_t;
 
 
 /// Sub Event of ESP_GAP_BLE_SCAN_RESULT_EVT
 /// Sub Event of ESP_GAP_BLE_SCAN_RESULT_EVT
@@ -225,11 +227,11 @@ typedef enum {
  *        result is scan response or advertising data or other
  *        result is scan response or advertising data or other
  */
  */
 typedef enum {
 typedef enum {
-	ESP_BLE_EVT_CONN_ADV         = 0x00,		/*!< Connectable undirected advertising (ADV_IND) */
-	ESP_BLE_EVT_CONN_DIR_ADV     = 0x01, 		/*!< Connectable directed advertising (ADV_DIRECT_IND) */
-	ESP_BLE_EVT_DISC_ADV         = 0x02,		/*!< Scannable undirected advertising (ADV_SCAN_IND) */
-	ESP_BLE_EVT_NON_CONN_ADV     = 0x03,		/*!< Non connectable undirected advertising (ADV_NONCONN_IND) */
-	ESP_BLE_EVT_SCAN_RSP         = 0x04,		/*!< Scan Response (SCAN_RSP) */
+    ESP_BLE_EVT_CONN_ADV         = 0x00,        /*!< Connectable undirected advertising (ADV_IND) */
+    ESP_BLE_EVT_CONN_DIR_ADV     = 0x01,        /*!< Connectable directed advertising (ADV_DIRECT_IND) */
+    ESP_BLE_EVT_DISC_ADV         = 0x02,        /*!< Scannable undirected advertising (ADV_SCAN_IND) */
+    ESP_BLE_EVT_NON_CONN_ADV     = 0x03,        /*!< Non connectable undirected advertising (ADV_NONCONN_IND) */
+    ESP_BLE_EVT_SCAN_RSP         = 0x04,        /*!< Scan Response (SCAN_RSP) */
 } esp_ble_evt_type_t;
 } esp_ble_evt_type_t;
 
 
 /**
 /**
@@ -240,34 +242,34 @@ typedef union {
      * @brief ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
      * @brief ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
      */
      */
     struct ble_adv_data_cmpl_evt_param {
     struct ble_adv_data_cmpl_evt_param {
-        esp_bt_status_t status;						/*!< Indicate the set advertising data operation success status */
-    } adv_data_cmpl;								/*!< Event parameter of ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT */ 
+        esp_bt_status_t status;                     /*!< Indicate the set advertising data operation success status */
+    } adv_data_cmpl;                                /*!< Event parameter of ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT */ 
     /**
     /**
      * @brief ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT
      * @brief ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT
      */
      */
     struct ble_scan_rsp_data_cmpl_evt_param {
     struct ble_scan_rsp_data_cmpl_evt_param {
-        esp_bt_status_t status;						/*!< Indicate the set scan response data operation success status */
-    } scan_rsp_data_cmpl;							/*!< Event parameter of ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT */
+        esp_bt_status_t status;                     /*!< Indicate the set scan response data operation success status */
+    } scan_rsp_data_cmpl;                           /*!< Event parameter of ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT */
     /**
     /**
      * @brief ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT
      * @brief ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT
      */
      */
     struct ble_scan_param_cmpl_evt_param {
     struct ble_scan_param_cmpl_evt_param {
-        esp_bt_status_t status;						/*!< Indicate the set scan param operation success status */
-    } scan_param_cmpl;								/*!< Event parameter of ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT */
+        esp_bt_status_t status;                     /*!< Indicate the set scan param operation success status */
+    } scan_param_cmpl;                              /*!< Event parameter of ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT */
     /**
     /**
      * @brief ESP_GAP_BLE_SCAN_RESULT_EVT
      * @brief ESP_GAP_BLE_SCAN_RESULT_EVT
      */
      */
     struct ble_scan_result_evt_param {
     struct ble_scan_result_evt_param {
-        esp_gap_search_evt_t search_evt;			/*!< Search event type */
-        esp_bd_addr_t bda;							/*!< Bluetooth device address which has been searched */
-        esp_bt_dev_type_t dev_type;					/*!< Device type */
-        esp_ble_addr_type_t ble_addr_type;			/*!< Ble device address type */
-		esp_ble_evt_type_t ble_evt_type;			/*!< Ble scan result event type */
-        int rssi;									/*!< Searched device's RSSI */
-        uint8_t  ble_adv[ESP_BLE_ADV_DATA_LEN_MAX]; /*!< Received EIR */
-        int flag;									/*!< Advertising data flag bit */
-        int num_resps;								/*!< Scan result number */
-    } scan_rst;										/*!< Event parameter of ESP_GAP_BLE_SCAN_RESULT_EVT */
+        esp_gap_search_evt_t search_evt;            /*!< Search event type */
+        esp_bd_addr_t bda;                          /*!< Bluetooth device address which has been searched */
+        esp_bt_dev_type_t dev_type;                 /*!< Device type */
+        esp_ble_addr_type_t ble_addr_type;          /*!< Ble device address type */
+        esp_ble_evt_type_t ble_evt_type;            /*!< Ble scan result event type */
+        int rssi;                                   /*!< Searched device's RSSI */
+        uint8_t  ble_adv[ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX];     /*!< Received EIR */
+        int flag;                                   /*!< Advertising data flag bit */
+        int num_resps;                              /*!< Scan result number */
+    } scan_rst;                                     /*!< Event parameter of ESP_GAP_BLE_SCAN_RESULT_EVT */
 } esp_ble_gap_cb_param_t;
 } esp_ble_gap_cb_param_t;
 
 
 /**
 /**
@@ -440,7 +442,8 @@ esp_err_t esp_ble_gap_set_device_name(const char *name);
  * @param[in]       type   - finding ADV data type
  * @param[in]       type   - finding ADV data type
  * @param[out]      length - return the length of ADV data not including type
  * @param[out]      length - return the length of ADV data not including type
  *
  *
- * @return          pointer of ADV data
+ * @return          - ESP_OK : success
+ *                  - other  : failed
  *
  *
  */
  */
 uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length);
 uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length);

+ 202 - 90
components/bt/bluedroid/api/include/esp_gatt_defs.h

@@ -22,106 +22,141 @@ extern "C" {
 #endif
 #endif
 
 
 /// GATT INVALID UUID
 /// GATT INVALID UUID
-#define ESP_GATT_ILLEGAL_UUID                0
+#define ESP_GATT_ILLEGAL_UUID               0
+/// GATT INVALID HANDLE
+#define ESP_GATT_ILLEGAL_HANDLE             0
+/// GATT attribute max handle
+#define ESP_GATT_ATTR_HANDLE_MAX            100
+
 
 
 /**@{
 /**@{
  * All "ESP_GATT_UUID_xxx" is attribute types
  * All "ESP_GATT_UUID_xxx" is attribute types
  */
  */
-#define ESP_GATT_UUID_PRI_SERVICE            0x2800
-#define ESP_GATT_UUID_SEC_SERVICE            0x2801
-#define ESP_GATT_UUID_INCLUDE_SERVICE        0x2802
-#define ESP_GATT_UUID_CHAR_DECLARE           0x2803      /*  Characteristic Declaration*/
-
-#define ESP_GATT_UUID_CHAR_EXT_PROP          0x2900      /*  Characteristic Extended Properties */
-#define ESP_GATT_UUID_CHAR_DESCRIPTION       0x2901      /*  Characteristic User Description*/
-#define ESP_GATT_UUID_CHAR_CLIENT_CONFIG     0x2902      /*  Client Characteristic Configuration */
-#define ESP_GATT_UUID_CHAR_SRVR_CONFIG       0x2903      /*  Server Characteristic Configuration */
-#define ESP_GATT_UUID_CHAR_PRESENT_FORMAT    0x2904      /*  Characteristic Presentation Format*/
-#define ESP_GATT_UUID_CHAR_AGG_FORMAT        0x2905      /*  Characteristic Aggregate Format*/
-#define ESP_GATT_UUID_CHAR_VALID_RANGE       0x2906      /*  Characteristic Valid Range */
-#define ESP_GATT_UUID_EXT_RPT_REF_DESCR      0x2907
-#define ESP_GATT_UUID_RPT_REF_DESCR          0x2908
+#define ESP_GATT_UUID_IMMEDIATE_ALERT_SVC           0x1802          /*  Immediate alert Service*/
+#define ESP_GATT_UUID_LINK_LOSS_SVC                 0x1803          /*  Link Loss Service*/                             
+#define ESP_GATT_UUID_TX_POWER_SVC                  0x1804          /*  TX Power Service*/
+#define ESP_GATT_UUID_CURRENT_TIME_SVC              0x1805          /*  Current Time Service Service*/
+#define ESP_GATT_UUID_REF_TIME_UPDATE_SVC           0x1806          /*  Reference Time Update Service*/
+#define ESP_GATT_UUID_NEXT_DST_CHANGE_SVC           0x1807          /*  Next DST Change Service*/
+#define ESP_GATT_UUID_GLUCOSE_SVC                   0x1808          /*  Glucose Service*/
+#define ESP_GATT_UUID_HEALTH_THERMOM_SVC            0x1809          /*  Health Thermometer Service*/
+#define ESP_GATT_UUID_DEVICE_INFO_SVC               0x180A          /*  Device Information Service*/
+#define ESP_GATT_UUID_HEART_RATE_SVC                0x180D          /*  Heart Rate Service*/
+#define ESP_GATT_UUID_PHONE_ALERT_STATUS_SVC        0x180E          /* Phone Alert Status Service*/
+#define ESP_GATT_UUID_BATTERY_SERVICE_SVC           0x180F          /* Battery Service*/
+#define ESP_GATT_UUID_BLOOD_PRESSURE_SVC            0x1810          /* Blood Pressure Service*/
+#define ESP_GATT_UUID_ALERT_NTF_SVC                 0x1811          /* Alert Notification Service*/
+#define ESP_GATT_UUID_HID_SVC                       0x1812          /* HID Service*/
+#define ESP_GATT_UUID_SCAN_PARAMETERS_SVC           0x1813          /* Scan Parameters Service*/
+#define ESP_GATT_UUID_RUNNING_SPEED_CADENCE_SVC     0x1814          /* Running Speed and Cadence Service*/
+#define ESP_GATT_UUID_CYCLING_SPEED_CADENCE_SVC     0x1816          /* Cycling Speed and Cadence Service*/
+#define ESP_GATT_UUID_CYCLING_POWER_SVC             0x1818          /* Cycling Power Service*/
+#define ESP_GATT_UUID_LOCATION_AND_NAVIGATION_SVC   0x1819          /* Location and Navigation Service*/
+#define ESP_GATT_UUID_USER_DATA_SVC                 0x181C          /* User Data Service*/
+#define ESP_GATT_UUID_WEIGHT_SCALE_SVC              0x181D          /* Weight Scale Service*/
+
+#define ESP_GATT_UUID_PRI_SERVICE                   0x2800
+#define ESP_GATT_UUID_SEC_SERVICE                   0x2801
+#define ESP_GATT_UUID_INCLUDE_SERVICE               0x2802
+#define ESP_GATT_UUID_CHAR_DECLARE                  0x2803          /*  Characteristic Declaration*/
+
+#define ESP_GATT_UUID_CHAR_EXT_PROP                 0x2900          /*  Characteristic Extended Properties */
+#define ESP_GATT_UUID_CHAR_DESCRIPTION              0x2901          /*  Characteristic User Description*/
+#define ESP_GATT_UUID_CHAR_CLIENT_CONFIG            0x2902          /*  Client Characteristic Configuration */
+#define ESP_GATT_UUID_CHAR_SRVR_CONFIG              0x2903          /*  Server Characteristic Configuration */
+#define ESP_GATT_UUID_CHAR_PRESENT_FORMAT           0x2904          /*  Characteristic Presentation Format*/
+#define ESP_GATT_UUID_CHAR_AGG_FORMAT               0x2905          /*  Characteristic Aggregate Format*/
+#define ESP_GATT_UUID_CHAR_VALID_RANGE              0x2906          /*  Characteristic Valid Range */
+#define ESP_GATT_UUID_EXT_RPT_REF_DESCR             0x2907
+#define ESP_GATT_UUID_RPT_REF_DESCR                 0x2908
 
 
 /* GAP Profile Attributes */
 /* GAP Profile Attributes */
-#define ESP_GATT_UUID_GAP_DEVICE_NAME        0x2A00
-#define ESP_GATT_UUID_GAP_ICON               0x2A01
-#define ESP_GATT_UUID_GAP_PREF_CONN_PARAM    0x2A04
-#define ESP_GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6
+#define ESP_GATT_UUID_GAP_DEVICE_NAME               0x2A00
+#define ESP_GATT_UUID_GAP_ICON                      0x2A01
+#define ESP_GATT_UUID_GAP_PREF_CONN_PARAM           0x2A04
+#define ESP_GATT_UUID_GAP_CENTRAL_ADDR_RESOL        0x2AA6
 
 
 /* Attribute Profile Attribute UUID */
 /* Attribute Profile Attribute UUID */
-#define ESP_GATT_UUID_GATT_SRV_CHGD          0x2A05
+#define ESP_GATT_UUID_GATT_SRV_CHGD                 0x2A05
 
 
 /* Link ESP_Loss Service */
 /* Link ESP_Loss Service */
-#define ESP_GATT_UUID_ALERT_LEVEL            0x2A06      /* Alert Level */
-#define ESP_GATT_UUID_TX_POWER_LEVEL         0x2A07      /* TX power level */
+#define ESP_GATT_UUID_ALERT_LEVEL                   0x2A06          /* Alert Level */
+#define ESP_GATT_UUID_TX_POWER_LEVEL                0x2A07          /* TX power level */
 
 
 /* Current Time Service */
 /* Current Time Service */
-#define ESP_GATT_UUID_CURRENT_TIME           0x2A2B      /* Current Time */
-#define ESP_GATT_UUID_LOCAL_TIME_INFO        0x2A0F      /* Local time info */
-#define ESP_GATT_UUID_REF_TIME_INFO          0x2A14      /* reference time information */
+#define ESP_GATT_UUID_CURRENT_TIME                  0x2A2B          /* Current Time */
+#define ESP_GATT_UUID_LOCAL_TIME_INFO               0x2A0F          /* Local time info */
+#define ESP_GATT_UUID_REF_TIME_INFO                 0x2A14          /* reference time information */
 
 
 /* Network availability Profile */
 /* Network availability Profile */
-#define ESP_GATT_UUID_NW_STATUS              0x2A18      /* network availability status */
-#define ESP_GATT_UUID_NW_TRIGGER             0x2A1A      /* Network availability trigger */
+#define ESP_GATT_UUID_NW_STATUS                     0x2A18          /* network availability status */
+#define ESP_GATT_UUID_NW_TRIGGER                    0x2A1A          /* Network availability trigger */
 
 
 /* Phone alert */
 /* Phone alert */
-#define ESP_GATT_UUID_ALERT_STATUS           0x2A3F    /* alert status */
-#define ESP_GATT_UUID_RINGER_CP              0x2A40    /* ringer control point */
-#define ESP_GATT_UUID_RINGER_SETTING         0x2A41    /* ringer setting */
+#define ESP_GATT_UUID_ALERT_STATUS                  0x2A3F          /* alert status */
+#define ESP_GATT_UUID_RINGER_CP                     0x2A40          /* ringer control point */
+#define ESP_GATT_UUID_RINGER_SETTING                0x2A41          /* ringer setting */
 
 
 /* Glucose Service */
 /* Glucose Service */
-#define ESP_GATT_UUID_GM_MEASUREMENT         0x2A18
-#define ESP_GATT_UUID_GM_CONTEXT             0x2A34
-#define ESP_GATT_UUID_GM_CONTROL_POINT       0x2A52
-#define ESP_GATT_UUID_GM_FEATURE             0x2A51
+#define ESP_GATT_UUID_GM_MEASUREMENT                0x2A18
+#define ESP_GATT_UUID_GM_CONTEXT                    0x2A34
+#define ESP_GATT_UUID_GM_CONTROL_POINT              0x2A52
+#define ESP_GATT_UUID_GM_FEATURE                    0x2A51
 
 
 /* device information characteristic */
 /* device information characteristic */
-#define ESP_GATT_UUID_SYSTEM_ID              0x2A23
-#define ESP_GATT_UUID_MODEL_NUMBER_STR       0x2A24
-#define ESP_GATT_UUID_SERIAL_NUMBER_STR      0x2A25
-#define ESP_GATT_UUID_FW_VERSION_STR         0x2A26
-#define ESP_GATT_UUID_HW_VERSION_STR         0x2A27
-#define ESP_GATT_UUID_SW_VERSION_STR         0x2A28
-#define ESP_GATT_UUID_MANU_NAME              0x2A29
-#define ESP_GATT_UUID_IEEE_DATA              0x2A2A
-#define ESP_GATT_UUID_PNP_ID                 0x2A50
+#define ESP_GATT_UUID_SYSTEM_ID                     0x2A23
+#define ESP_GATT_UUID_MODEL_NUMBER_STR              0x2A24
+#define ESP_GATT_UUID_SERIAL_NUMBER_STR             0x2A25
+#define ESP_GATT_UUID_FW_VERSION_STR                0x2A26
+#define ESP_GATT_UUID_HW_VERSION_STR                0x2A27
+#define ESP_GATT_UUID_SW_VERSION_STR                0x2A28
+#define ESP_GATT_UUID_MANU_NAME                     0x2A29
+#define ESP_GATT_UUID_IEEE_DATA                     0x2A2A
+#define ESP_GATT_UUID_PNP_ID                        0x2A50
 
 
 /* HID characteristics */
 /* HID characteristics */
-#define ESP_GATT_UUID_HID_INFORMATION        0x2A4A
-#define ESP_GATT_UUID_HID_REPORT_MAP         0x2A4B
-#define ESP_GATT_UUID_HID_CONTROL_POINT      0x2A4C
-#define ESP_GATT_UUID_HID_REPORT             0x2A4D
-#define ESP_GATT_UUID_HID_PROTO_MODE         0x2A4E
-#define ESP_GATT_UUID_HID_BT_KB_INPUT        0x2A22
-#define ESP_GATT_UUID_HID_BT_KB_OUTPUT       0x2A32
-#define ESP_GATT_UUID_HID_BT_MOUSE_INPUT     0x2A33
+#define ESP_GATT_UUID_HID_INFORMATION               0x2A4A
+#define ESP_GATT_UUID_HID_REPORT_MAP                0x2A4B
+#define ESP_GATT_UUID_HID_CONTROL_POINT             0x2A4C
+#define ESP_GATT_UUID_HID_REPORT                    0x2A4D
+#define ESP_GATT_UUID_HID_PROTO_MODE                0x2A4E
+#define ESP_GATT_UUID_HID_BT_KB_INPUT               0x2A22
+#define ESP_GATT_UUID_HID_BT_KB_OUTPUT              0x2A32
+#define ESP_GATT_UUID_HID_BT_MOUSE_INPUT            0x2A33
+
+ /// Heart Rate Measurement
+#define    ESP_GATT_HEART_RATE_MEAS                 0x2A37
+/// Body Sensor Location
+#define    ESP_GATT_BODY_SENSOR_LOCATION            0x2A38
+/// Heart Rate Control Point
+#define    ESP_GATT_HEART_RATE_CNTL_POINT           0x2A39
 
 
 /* Battery Service characteristics */
 /* Battery Service characteristics */
-#define ESP_GATT_UUID_BATTERY_LEVEL          0x2A19
+#define ESP_GATT_UUID_BATTERY_LEVEL                 0x2A19
 
 
 /* Sensor Service */
 /* Sensor Service */
-#define ESP_GATT_UUID_SC_CONTROL_POINT       0x2A55
-#define ESP_GATT_UUID_SENSOR_LOCATION        0x2A5D
+#define ESP_GATT_UUID_SC_CONTROL_POINT              0x2A55
+#define ESP_GATT_UUID_SENSOR_LOCATION               0x2A5D
 
 
 /* Runners speed and cadence service */
 /* Runners speed and cadence service */
-#define ESP_GATT_UUID_RSC_MEASUREMENT        0x2A53
-#define ESP_GATT_UUID_RSC_FEATURE            0x2A54
+#define ESP_GATT_UUID_RSC_MEASUREMENT               0x2A53
+#define ESP_GATT_UUID_RSC_FEATURE                   0x2A54
 
 
 /* Cycling speed and cadence service */
 /* Cycling speed and cadence service */
-#define ESP_GATT_UUID_CSC_MEASUREMENT        0x2A5B
-#define ESP_GATT_UUID_CSC_FEATURE            0x2A5C
+#define ESP_GATT_UUID_CSC_MEASUREMENT               0x2A5B
+#define ESP_GATT_UUID_CSC_FEATURE                   0x2A5C
 
 
 /* Scan ESP_Parameter characteristics */
 /* Scan ESP_Parameter characteristics */
-#define ESP_GATT_UUID_SCAN_INT_WINDOW        0x2A4F
-#define ESP_GATT_UUID_SCAN_REFRESH           0x2A31
+#define ESP_GATT_UUID_SCAN_INT_WINDOW               0x2A4F
+#define ESP_GATT_UUID_SCAN_REFRESH                  0x2A31
 /**
 /**
  * @}
  * @}
  */
  */
 
 
 /// Attribute write data type from the client
 /// Attribute write data type from the client
 typedef enum {
 typedef enum {
-	ESP_GATT_PREP_WRITE_CANCEL    = 0x00,		/*!< Prepare write cancel */
-	ESP_GATT_PREP_WRITE_EXEC      = 0x01,		/*!< Prepare write execute */
+    ESP_GATT_PREP_WRITE_CANCEL    = 0x00,       /*!< Prepare write cancel */
+    ESP_GATT_PREP_WRITE_EXEC      = 0x01,       /*!< Prepare write execute */
 } esp_gatt_prep_write_type;
 } esp_gatt_prep_write_type;
 
 
 /**
 /**
@@ -178,23 +213,23 @@ typedef enum {
  * @brief Gatt Connection reason enum
  * @brief Gatt Connection reason enum
  */
  */
 typedef enum {
 typedef enum {
-    ESP_GATT_CONN_UNKNOWN = 0,						/*!< Gatt connection unknown */
-    ESP_GATT_CONN_L2C_FAILURE = 1,					/*!< General L2cap failure  */
-    ESP_GATT_CONN_TIMEOUT = 0x08,					/*!< Connection timeout  */
-    ESP_GATT_CONN_TERMINATE_PEER_USER = 0x13,		/*!< Connection terminate by peer user  */
-    ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16,		/*!< Connectionterminated by local host */
-    ESP_GATT_CONN_FAIL_ESTABLISH = 0x3e,			/*!< Connection fail to establish  */
-    ESP_GATT_CONN_LMP_TIMEOUT = 0x22,				/*!< Connection fail for LMP response tout */
-    ESP_GATT_CONN_CONN_CANCEL = 0x0100,				/*!< L2CAP connection cancelled  */
-    ESP_GATT_CONN_NONE = 0x0101						/*!< No connection to cancel  */
+    ESP_GATT_CONN_UNKNOWN = 0,                      /*!< Gatt connection unknown */
+    ESP_GATT_CONN_L2C_FAILURE = 1,                  /*!< General L2cap failure  */
+    ESP_GATT_CONN_TIMEOUT = 0x08,                   /*!< Connection timeout  */
+    ESP_GATT_CONN_TERMINATE_PEER_USER = 0x13,       /*!< Connection terminate by peer user  */
+    ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16,      /*!< Connectionterminated by local host */
+    ESP_GATT_CONN_FAIL_ESTABLISH = 0x3e,            /*!< Connection fail to establish  */
+    ESP_GATT_CONN_LMP_TIMEOUT = 0x22,               /*!< Connection fail for LMP response tout */
+    ESP_GATT_CONN_CONN_CANCEL = 0x0100,             /*!< L2CAP connection cancelled  */
+    ESP_GATT_CONN_NONE = 0x0101                     /*!< No connection to cancel  */
 } esp_gatt_conn_reason_t;
 } esp_gatt_conn_reason_t;
 
 
 /**
 /**
  * @brief Gatt id, include uuid and instance id
  * @brief Gatt id, include uuid and instance id
  */
  */
 typedef struct {
 typedef struct {
-    esp_bt_uuid_t   uuid;					/*!< UUID */
-    uint8_t         inst_id;				/*!< Instance id */
+    esp_bt_uuid_t   uuid;                   /*!< UUID */
+    uint8_t         inst_id;                /*!< Instance id */
 } __attribute__((packed)) esp_gatt_id_t;
 } __attribute__((packed)) esp_gatt_id_t;
 
 
 /**
 /**
@@ -202,19 +237,19 @@ typedef struct {
  *        (uuid and instance id) and primary flag
  *        (uuid and instance id) and primary flag
  */
  */
 typedef struct {
 typedef struct {
-    esp_gatt_id_t   id;						/*!< Gatt id, include uuid and instance */
-    bool            is_primary;				/*!< This service is primary or not */
+    esp_gatt_id_t   id;                     /*!< Gatt id, include uuid and instance */
+    bool            is_primary;             /*!< This service is primary or not */
 } __attribute__((packed)) esp_gatt_srvc_id_t;
 } __attribute__((packed)) esp_gatt_srvc_id_t;
 
 
 /**
 /**
  * @brief Gatt authentication request type
  * @brief Gatt authentication request type
  */
  */
 typedef enum {
 typedef enum {
-    ESP_GATT_AUTH_REQ_NONE              	= 0,
-    ESP_GATT_AUTH_REQ_NO_MITM           	= 1,   /* unauthenticated encryption */
-    ESP_GATT_AUTH_REQ_MITM              	= 2,   /* authenticated encryption */
-    ESP_GATT_AUTH_REQ_SIGNED_NO_MITM    	= 3,
-    ESP_GATT_AUTH_REQ_SIGNED_MITM       	= 4,
+    ESP_GATT_AUTH_REQ_NONE                  = 0,
+    ESP_GATT_AUTH_REQ_NO_MITM               = 1,   /* unauthenticated encryption */
+    ESP_GATT_AUTH_REQ_MITM                  = 2,   /* authenticated encryption */
+    ESP_GATT_AUTH_REQ_SIGNED_NO_MITM        = 3,
+    ESP_GATT_AUTH_REQ_SIGNED_MITM           = 4,
 } esp_gatt_auth_req_t;
 } esp_gatt_auth_req_t;
 
 
 /**
 /**
@@ -246,32 +281,109 @@ typedef enum {
 /// GATT maximum attribute length
 /// GATT maximum attribute length
 #define ESP_GATT_MAX_ATTR_LEN   600 //as same as GATT_MAX_ATTR_LEN
 #define ESP_GATT_MAX_ATTR_LEN   600 //as same as GATT_MAX_ATTR_LEN
 
 
+
+/**
+ * @brief Attribute description (used to create database)
+ */
+ typedef struct
+ {
+     esp_bt_uuid_t uuid;                    /*!< Element UUID */                                            
+     uint16_t perm;                     /*!< Attribute permission */        
+     uint16_t max_length;               /*!< Maximum length of the element*/    
+     uint16_t length;                   /*!< Current length of the element*/    
+     uint8_t* value;                        /*!< Element value array*/  
+ }esp_attr_desc_t;
+
+
+/**
+ * @brief attribute auto respose flag
+ */
+typedef struct
+{
+#define ESP_GATT_RSP_BY_APP             0
+#define ESP_GATT_AUTO_RSP               1
+    uint8_t auto_rsp;           /*!< need the app response to the client if need_rsp set to 1*/  
+}esp_attr_control_t;
+
+
+/**
+ * @brief attribute type added to the gatt server database
+ */
+typedef struct
+{
+    esp_attr_control_t      attr_control;       /*!< The attribue control type*/
+    esp_attr_desc_t         att_desc;       /*!< The attribue type*/
+}esp_gatts_attr_db_t;
+
+
+/**
+  * @brief set the attribute value type
+  */
+typedef struct
+{
+    uint16_t attr_max_len;                      /*!<  attribute max value length */     
+    uint16_t attr_len;                          /*!<  attribute current value length */ 
+    uint8_t *attr_value;                        /*!<  the pointer to attribute value */
+}esp_attr_value_t;
+
+
+/**
+  * @brief Gatt  include service entry element
+  */
+typedef struct 
+{
+    uint16_t start_hdl;                             /*!< Gatt  start handle value of included service */
+    uint16_t end_hdl;                               /*!< Gatt  end handle value of included service */
+    uint16_t uuid;                                  /*!< Gatt  attribute value UUID of included service */
+}esp_gatts_incl_svc_desc_t;                 /*!< Gatt  include service entry element */
+
+/**
+  * @brief Gatt  include 128 bit service entry element
+  */
+typedef struct 
+{
+    uint16_t start_hdl;                             /*!< Gatt  start handle value of included 128 bit service */
+    uint16_t end_hdl;                               /*!< Gatt  end handle value of included 128 bit service */
+}esp_gatts_incl128_svc_desc_t;              /*!< Gatt  include 128 bit service entry element */
+
+
+/**
+  * @brief Gatt  characteristic  entry element
+  */
+typedef struct 
+{
+    uint8_t prop;                                   /*!< Gatt attribute properties */
+    uint16_t attr_hdl;                              /*!< Gatt attribute handle */
+    esp_bt_uuid_t attr_uuid;                            /*!< Gatt attribute uuid typedle */
+}esp_gatts_char_desc_t;                     /*!< Gatt characteristic value descriptor */
+
+
 /// Gatt attribute value 
 /// Gatt attribute value 
 typedef struct {
 typedef struct {
-    uint8_t           value[ESP_GATT_MAX_ATTR_LEN];			/*!< Gatt attribute value */
-    uint16_t          handle;								/*!< Gatt attribute handle */
-    uint16_t          offset;								/*!< Gatt attribute value offset */
-    uint16_t          len;									/*!< Gatt attribute value length */
-    uint8_t           auth_req;								/*!< Gatt authentication request */
+    uint8_t           value[ESP_GATT_MAX_ATTR_LEN];         /*!< Gatt attribute value */
+    uint16_t          handle;                               /*!< Gatt attribute handle */
+    uint16_t          offset;                               /*!< Gatt attribute value offset */
+    uint16_t          len;                                  /*!< Gatt attribute value length */
+    uint8_t           auth_req;                             /*!< Gatt authentication request */
 } esp_gatt_value_t;
 } esp_gatt_value_t;
 
 
 /// GATT remote read request response type
 /// GATT remote read request response type
 typedef union {
 typedef union {
-    esp_gatt_value_t attr_value;							/*!< Gatt attribute structure */
-    uint16_t            handle;								/*!< Gatt attribute handle */
+    esp_gatt_value_t attr_value;                            /*!< Gatt attribute structure */
+    uint16_t            handle;                             /*!< Gatt attribute handle */
 } esp_gatt_rsp_t;
 } esp_gatt_rsp_t;
 
 
 /**
 /**
   * @brief Gatt write type
   * @brief Gatt write type
   */
   */
 typedef enum {
 typedef enum {
-	ESP_GATT_WRITE_TYPE_NO_RSP	=	1,						/*!< Gatt write attribute need no response */
-	ESP_GATT_WRITE_TYPE_RSP,								/*!< Gatt write attribute need remote response */
+    ESP_GATT_WRITE_TYPE_NO_RSP  =   1,                      /*!< Gatt write attribute need no response */
+    ESP_GATT_WRITE_TYPE_RSP,                                /*!< Gatt write attribute need remote response */
 } esp_gatt_write_type_t;
 } esp_gatt_write_type_t;
 
 
 #define ESP_GATT_IF_NONE    0xff                            /*!< If callback report gattc_if/gatts_if as this macro, means this event is not correspond to any app */
 #define ESP_GATT_IF_NONE    0xff                            /*!< If callback report gattc_if/gatts_if as this macro, means this event is not correspond to any app */
 
 
-typedef uint8_t    esp_gatt_if_t;							/*!< Gatt interface type, different application on GATT client use different gatt_if */
+typedef uint8_t    esp_gatt_if_t;                           /*!< Gatt interface type, different application on GATT client use different gatt_if */
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 174 - 102
components/bt/bluedroid/api/include/esp_gatts_api.h

@@ -25,29 +25,31 @@ extern "C" {
 
 
 /// GATT Server callback function events
 /// GATT Server callback function events
 typedef enum {
 typedef enum {
-	ESP_GATTS_REG_EVT                = 0,		/*!< When register application id, the event comes */
-	ESP_GATTS_READ_EVT               = 1,		/*!< When gatt client request read operation, the event comes */
-	ESP_GATTS_WRITE_EVT              = 2,		/*!< When gatt client request write operation, the event comes */
-	ESP_GATTS_EXEC_WRITE_EVT         = 3,		/*!< When gatt client request execute write, the event comes */
-	ESP_GATTS_MTU_EVT                = 4,		/*!< When set mtu complete, the event comes */
-	ESP_GATTS_CONF_EVT               = 5,		/*!< When receive confirm, the event comes */
-	ESP_GATTS_UNREG_EVT              = 6,		/*!< When unregister application id, the event comes */
-	ESP_GATTS_CREATE_EVT             = 7,		/*!< When create service complete, the event comes */
-	ESP_GATTS_ADD_INCL_SRVC_EVT      = 8,		/*!< When add included service complete, the event comes */
-	ESP_GATTS_ADD_CHAR_EVT           = 9,		/*!< When add characteristic complete, the event comes */
-	ESP_GATTS_ADD_CHAR_DESCR_EVT     = 10,		/*!< When add descriptor complete, the event comes */
-	ESP_GATTS_DELETE_EVT             = 11,		/*!< When delete service complete, the event comes */
-	ESP_GATTS_START_EVT              = 12,		/*!< When start service complete, the event comes */
-	ESP_GATTS_STOP_EVT               = 13,		/*!< When stop service complete, the event comes */
-	ESP_GATTS_CONNECT_EVT            = 14,		/*!< When gatt client connect, the event comes */
-	ESP_GATTS_DISCONNECT_EVT         = 15,		/*!< When gatt client disconnect, the event comes */
-	ESP_GATTS_OPEN_EVT               = 16,		/*!< When connect to peer, the event comes */
-	ESP_GATTS_CANCEL_OPEN_EVT        = 17,		/*!< When disconnect from peer, the event comes */
-	ESP_GATTS_CLOSE_EVT              = 18,		/*!< When gatt server close, the event comes */
-	ESP_GATTS_LISTEN_EVT             = 19,		/*!< When gatt listen to be connected the event comes */
-	ESP_GATTS_CONGEST_EVT            = 20,		/*!< When congest happen, the event comes */
-	/* following is extra event */
-	ESP_GATTS_RESPONSE_EVT           = 21,		/*!< When gatt send response complete, the event comes */
+    ESP_GATTS_REG_EVT                = 0,       /*!< When register application id, the event comes */
+    ESP_GATTS_READ_EVT               = 1,       /*!< When gatt client request read operation, the event comes */
+    ESP_GATTS_WRITE_EVT              = 2,       /*!< When gatt client request write operation, the event comes */
+    ESP_GATTS_EXEC_WRITE_EVT         = 3,       /*!< When gatt client request execute write, the event comes */
+    ESP_GATTS_MTU_EVT                = 4,       /*!< When set mtu complete, the event comes */
+    ESP_GATTS_CONF_EVT               = 5,       /*!< When receive confirm, the event comes */
+    ESP_GATTS_UNREG_EVT              = 6,       /*!< When unregister application id, the event comes */
+    ESP_GATTS_CREATE_EVT             = 7,       /*!< When create service complete, the event comes */
+    ESP_GATTS_ADD_INCL_SRVC_EVT      = 8,       /*!< When add included service complete, the event comes */
+    ESP_GATTS_ADD_CHAR_EVT           = 9,       /*!< When add characteristic complete, the event comes */
+    ESP_GATTS_ADD_CHAR_DESCR_EVT     = 10,      /*!< When add descriptor complete, the event comes */
+    ESP_GATTS_DELETE_EVT             = 11,      /*!< When delete service complete, the event comes */
+    ESP_GATTS_START_EVT              = 12,      /*!< When start service complete, the event comes */
+    ESP_GATTS_STOP_EVT               = 13,      /*!< When stop service complete, the event comes */
+    ESP_GATTS_CONNECT_EVT            = 14,      /*!< When gatt client connect, the event comes */
+    ESP_GATTS_DISCONNECT_EVT         = 15,      /*!< When gatt client disconnect, the event comes */
+    ESP_GATTS_OPEN_EVT               = 16,      /*!< When connect to peer, the event comes */
+    ESP_GATTS_CANCEL_OPEN_EVT        = 17,      /*!< When disconnect from peer, the event comes */
+    ESP_GATTS_CLOSE_EVT              = 18,      /*!< When gatt server close, the event comes */
+    ESP_GATTS_LISTEN_EVT             = 19,      /*!< When gatt listen to be connected the event comes */
+    ESP_GATTS_CONGEST_EVT            = 20,      /*!< When congest happen, the event comes */
+    /* following is extra event */
+    ESP_GATTS_RESPONSE_EVT           = 21,      /*!< When gatt send response complete, the event comes */
+    ESP_GATTS_CREAT_ATTR_TAB_EVT     = 22,
+    ESP_GATTS_SET_ATTR_VAL_EVT       = 23,
 } esp_gatts_cb_event_t;
 } esp_gatts_cb_event_t;
 
 
 /**
 /**
@@ -58,64 +60,64 @@ typedef union {
      * @brief ESP_GATTS_REG_EVT
      * @brief ESP_GATTS_REG_EVT
      */
      */
     struct gatts_reg_evt_param {
     struct gatts_reg_evt_param {
-        esp_gatt_status_t status;						/*!< Operation status */
-        uint16_t app_id;				/*!< Application id which input in register API */
-    } reg;								/*!< Gatt server callback param of ESP_GATTS_REG_EVT */
+        esp_gatt_status_t status;       /*!< Operation status */
+        uint16_t app_id;                /*!< Application id which input in register API */
+    } reg;                              /*!< Gatt server callback param of ESP_GATTS_REG_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_READ_EVT
      * @brief ESP_GATTS_READ_EVT
      */
      */
     struct gatts_read_evt_param {
     struct gatts_read_evt_param {
-        uint16_t conn_id;				/*!< Connection id */
-        uint32_t trans_id;				/*!< Transfer id */
-        esp_bd_addr_t bda;				/*!< The bluetooth device address which been read */
-        uint16_t handle;				/*!< The attribute handle */
-        uint16_t offset;				/*!< Offset of the value, if the value is too long */
-        bool is_long;					/*!< The value is too long or not */
-    } read;								/*!< Gatt server callback param of ESP_GATTS_READ_EVT */
+        uint16_t conn_id;               /*!< Connection id */
+        uint32_t trans_id;              /*!< Transfer id */
+        esp_bd_addr_t bda;              /*!< The bluetooth device address which been read */
+        uint16_t handle;                /*!< The attribute handle */
+        uint16_t offset;                /*!< Offset of the value, if the value is too long */
+        bool is_long;                   /*!< The value is too long or not */
+    } read;                             /*!< Gatt server callback param of ESP_GATTS_READ_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_WRITE_EVT
      * @brief ESP_GATTS_WRITE_EVT
      */
      */
     struct gatts_write_evt_param {
     struct gatts_write_evt_param {
-        uint16_t conn_id;				/*!< Connection id */
-        uint32_t trans_id;				/*!< Transfer id */
-        esp_bd_addr_t bda;				/*!< The bluetooth device address which been written */
-        uint16_t handle;				/*!< The attribute handle */
-        uint16_t offset;				/*!< Offset of the value, if the value is too long */
-        bool need_rsp;					/*!< The write operation need to do response */
-        bool is_prep;					/*!< This write operation is prepare write */
-        uint16_t len;					/*!< The write attribute value length */
-        uint8_t *value;					/*!< The write attribute value */
-    } write;							/*!< Gatt server callback param of ESP_GATTS_WRITE_EVT */
+        uint16_t conn_id;               /*!< Connection id */
+        uint32_t trans_id;              /*!< Transfer id */
+        esp_bd_addr_t bda;              /*!< The bluetooth device address which been written */
+        uint16_t handle;                /*!< The attribute handle */
+        uint16_t offset;                /*!< Offset of the value, if the value is too long */
+        bool need_rsp;                  /*!< The write operation need to do response */
+        bool is_prep;                   /*!< This write operation is prepare write */
+        uint16_t len;                   /*!< The write attribute value length */
+        uint8_t *value;                 /*!< The write attribute value */
+    } write;                            /*!< Gatt server callback param of ESP_GATTS_WRITE_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_EXEC_WRITE_EVT
      * @brief ESP_GATTS_EXEC_WRITE_EVT
      */
      */
     struct gatts_exec_write_evt_param {
     struct gatts_exec_write_evt_param {
-        uint16_t conn_id;				/*!< Connection id */
-        uint32_t trans_id;				/*!< Transfer id */
-        esp_bd_addr_t bda;				/*!< The bluetooth device address which been written */
-#define ESP_GATT_PREP_WRITE_CANCEL   0x00
-#define ESP_GATT_PREP_WRITE_EXEC     0x01
-        uint8_t exec_write_flag;		/*!< Execute write flag */
-    } exec_write;						/*!< Gatt server callback param of ESP_GATTS_EXEC_WRITE_EVT */
+        uint16_t conn_id;               /*!< Connection id */
+        uint32_t trans_id;              /*!< Transfer id */
+        esp_bd_addr_t bda;              /*!< The bluetooth device address which been written */
+#define ESP_GATT_PREP_WRITE_CANCEL 0x00 /*!< Prepare write flag to indicate cancel prepare write */
+#define ESP_GATT_PREP_WRITE_EXEC   0x01 /*!< Prepare write flag to indicate execute prepare write */
+        uint8_t exec_write_flag;        /*!< Execute write flag */
+    } exec_write;                       /*!< Gatt server callback param of ESP_GATTS_EXEC_WRITE_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_MTU_EVT
      * @brief ESP_GATTS_MTU_EVT
      */
      */
     struct gatts_mtu_evt_param {
     struct gatts_mtu_evt_param {
-        uint16_t conn_id;				/*!< Connection id */
-        uint16_t mtu;					/*!< MTU size */
-    } mtu;								/*!< Gatt server callback param of ESP_GATTS_MTU_EVT */
+        uint16_t conn_id;               /*!< Connection id */
+        uint16_t mtu;                   /*!< MTU size */
+    } mtu;                              /*!< Gatt server callback param of ESP_GATTS_MTU_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_CONF_EVT
      * @brief ESP_GATTS_CONF_EVT
      */
      */
     struct gatts_conf_evt_param {
     struct gatts_conf_evt_param {
-        esp_gatt_status_t status;		/*!< Operation status */
-        uint16_t conn_id;				/*!< Connection id */
-    } conf;								/*!< Gatt server callback param of ESP_GATTS_CONF_EVT (confirm) */
+        esp_gatt_status_t status;       /*!< Operation status */
+        uint16_t conn_id;               /*!< Connection id */
+    } conf;                             /*!< Gatt server callback param of ESP_GATTS_CONF_EVT (confirm) */
 
 
     /**
     /**
      * @brief ESP_GATTS_UNREG_EVT
      * @brief ESP_GATTS_UNREG_EVT
@@ -125,81 +127,81 @@ typedef union {
      * @brief ESP_GATTS_CREATE_EVT
      * @brief ESP_GATTS_CREATE_EVT
      */
      */
     struct gatts_create_evt_param {
     struct gatts_create_evt_param {
-        esp_gatt_status_t status;		/*!< Operation status */
-        uint16_t service_handle; 		/*!< Service attribute handle */
-        esp_gatt_srvc_id_t service_id;	/*!< Service id, include service uuid and other information */
-    } create;							/*!< Gatt server callback param of ESP_GATTS_CREATE_EVT */
+        esp_gatt_status_t status;       /*!< Operation status */
+        uint16_t service_handle;        /*!< Service attribute handle */
+        esp_gatt_srvc_id_t service_id;  /*!< Service id, include service uuid and other information */
+    } create;                           /*!< Gatt server callback param of ESP_GATTS_CREATE_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_ADD_INCL_SRVC_EVT
      * @brief ESP_GATTS_ADD_INCL_SRVC_EVT
      */
      */
     struct gatts_add_incl_srvc_evt_param {
     struct gatts_add_incl_srvc_evt_param {
-        esp_gatt_status_t status;		/*!< Operation status */
-        uint16_t attr_handle;			/*!< Included service attribute handle */
-        uint16_t service_handle;		/*!< Service attribute handle */
-    } add_incl_srvc;					/*!< Gatt server callback param of ESP_GATTS_ADD_INCL_SRVC_EVT */
+        esp_gatt_status_t status;       /*!< Operation status */
+        uint16_t attr_handle;           /*!< Included service attribute handle */
+        uint16_t service_handle;        /*!< Service attribute handle */
+    } add_incl_srvc;                    /*!< Gatt server callback param of ESP_GATTS_ADD_INCL_SRVC_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_ADD_CHAR_EVT
      * @brief ESP_GATTS_ADD_CHAR_EVT
      */
      */
     struct gatts_add_char_evt_param {
     struct gatts_add_char_evt_param {
-        esp_gatt_status_t status;		/*!< Operation status */
-        uint16_t attr_handle;			/*!< Characteristic attribute handle */
-        uint16_t service_handle;		/*!< Service attribute handle */
-        esp_bt_uuid_t char_uuid;		/*!< Characteristic uuid */
-    } add_char;							/*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_EVT */
+        esp_gatt_status_t status;       /*!< Operation status */
+        uint16_t attr_handle;           /*!< Characteristic attribute handle */
+        uint16_t service_handle;        /*!< Service attribute handle */
+        esp_bt_uuid_t char_uuid;        /*!< Characteristic uuid */
+    } add_char;                         /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_ADD_CHAR_DESCR_EVT
      * @brief ESP_GATTS_ADD_CHAR_DESCR_EVT
      */
      */
     struct gatts_add_char_descr_evt_param {
     struct gatts_add_char_descr_evt_param {
-        esp_gatt_status_t status;		/*!< Operation status */
-        uint16_t attr_handle;			/*!< Descriptor attribute handle */
-        uint16_t service_handle;		/*!< Service attribute handle */
-        esp_bt_uuid_t char_uuid;		/*!< Characteristic uuid */
-    } add_char_descr;					/*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_DESCR_EVT */
+        esp_gatt_status_t status;       /*!< Operation status */
+        uint16_t attr_handle;           /*!< Descriptor attribute handle */
+        uint16_t service_handle;        /*!< Service attribute handle */
+        esp_bt_uuid_t char_uuid;        /*!< Characteristic uuid */
+    } add_char_descr;                   /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_DESCR_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_DELETE_EVT
      * @brief ESP_GATTS_DELETE_EVT
      */
      */
     struct gatts_delete_evt_param {
     struct gatts_delete_evt_param {
-        esp_gatt_status_t status;		/*!< Operation status */
-        uint16_t service_handle;		/*!< Service attribute handle */
-    } del;								/*!< Gatt server callback param of ESP_GATTS_DELETE_EVT */
+        esp_gatt_status_t status;       /*!< Operation status */
+        uint16_t service_handle;        /*!< Service attribute handle */
+    } del;                              /*!< Gatt server callback param of ESP_GATTS_DELETE_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_START_EVT
      * @brief ESP_GATTS_START_EVT
      */
      */
     struct gatts_start_evt_param {
     struct gatts_start_evt_param {
-        esp_gatt_status_t status;		/*!< Operation status */
-        uint16_t service_handle;		/*!< Service attribute handle */
-    } start;							/*!< Gatt server callback param of ESP_GATTS_START_EVT */
+        esp_gatt_status_t status;       /*!< Operation status */
+        uint16_t service_handle;        /*!< Service attribute handle */
+    } start;                            /*!< Gatt server callback param of ESP_GATTS_START_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_STOP_EVT
      * @brief ESP_GATTS_STOP_EVT
      */
      */
     struct gatts_stop_evt_param {
     struct gatts_stop_evt_param {
-        esp_gatt_status_t status;		/*!< Operation status */
-        uint16_t service_handle;		/*!< Service attribute handle */
-    } stop;								/*!< Gatt server callback param of ESP_GATTS_STOP_EVT */
+        esp_gatt_status_t status;       /*!< Operation status */
+        uint16_t service_handle;        /*!< Service attribute handle */
+    } stop;                             /*!< Gatt server callback param of ESP_GATTS_STOP_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_CONNECT_EVT
      * @brief ESP_GATTS_CONNECT_EVT
      */
      */
     struct gatts_connect_evt_param {
     struct gatts_connect_evt_param {
-        uint16_t conn_id;				/*!< Connection id */
-        esp_bd_addr_t remote_bda;		/*!< Remote bluetooth device address */
-        bool is_connected;				/*!< Indicate it is connected or not */
-    } connect;							/*!< Gatt server callback param of ESP_GATTS_CONNECT_EVT */
+        uint16_t conn_id;               /*!< Connection id */
+        esp_bd_addr_t remote_bda;       /*!< Remote bluetooth device address */
+        bool is_connected;              /*!< Indicate it is connected or not */
+    } connect;                          /*!< Gatt server callback param of ESP_GATTS_CONNECT_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_DISCONNECT_EVT
      * @brief ESP_GATTS_DISCONNECT_EVT
      */
      */
     struct gatts_disconnect_evt_param {
     struct gatts_disconnect_evt_param {
-        uint16_t conn_id;				/*!< Connection id */
-        esp_bd_addr_t remote_bda;		/*!< Remote bluetooth device address */
-        bool is_connected;				/*!< Indicate it is connected or not */
-    } disconnect;						/*!< Gatt server callback param of ESP_GATTS_DISCONNECT_EVT */
+        uint16_t conn_id;               /*!< Connection id */
+        esp_bd_addr_t remote_bda;       /*!< Remote bluetooth device address */
+        bool is_connected;              /*!< Indicate it is connected or not */
+    } disconnect;                       /*!< Gatt server callback param of ESP_GATTS_DISCONNECT_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_OPEN_EVT
      * @brief ESP_GATTS_OPEN_EVT
@@ -217,17 +219,38 @@ typedef union {
      * @brief ESP_GATTS_CONGEST_EVT
      * @brief ESP_GATTS_CONGEST_EVT
      */
      */
     struct gatts_congest_evt_param {
     struct gatts_congest_evt_param {
-        uint16_t conn_id;				/*!< Connection id */
-        bool congested;					/*!< Congested or not */
-    } congest;							/*!< Gatt server callback param of ESP_GATTS_CONGEST_EVT */
+        uint16_t conn_id;               /*!< Connection id */
+        bool congested;                 /*!< Congested or not */
+    } congest;                          /*!< Gatt server callback param of ESP_GATTS_CONGEST_EVT */
 
 
     /**
     /**
      * @brief ESP_GATTS_RESPONSE_EVT
      * @brief ESP_GATTS_RESPONSE_EVT
      */
      */
     struct gatts_rsp_evt_param {
     struct gatts_rsp_evt_param {
-        esp_gatt_status_t status;						/*!< Operation status */
-        uint16_t handle;				/*!< Attribute handle which send response */
-    } rsp;								/*!< Gatt server callback param of ESP_GATTS_RESPONSE_EVT */
+        esp_gatt_status_t status;                       /*!< Operation status */
+        uint16_t handle;                /*!< Attribute handle which send response */
+    } rsp;                              /*!< Gatt server callback param of ESP_GATTS_RESPONSE_EVT */
+
+    /**
+     * @brief ESP_GATTS_CREAT_ATTR_TAB_EVT
+     */
+    struct gatts_add_attr_tab_evt_param{
+        esp_gatt_status_t status;       /*!< Operation status */
+        esp_bt_uuid_t svc_uuid;         /*!< Service uuid type */
+        uint16_t num_handle;            /*!< The number of the attribute handle to be added to the gatts database */
+        uint16_t *handles;              /*!< The number to the handles */
+    } add_attr_tab;                     /*!< Gatt server callback param of ESP_GATTS_CREAT_ATTR_TAB_EVT */
+
+
+   /**
+    * @brief ESP_GATTS_SET_ATTR_VAL_EVT
+    */
+    struct gatts_set_attr_val_evt_param{
+        uint16_t srvc_handle;           /*!< The service handle */
+        uint16_t attr_handle;           /*!< The attribute  handle */
+        esp_gatt_status_t status;       /*!< Operation status*/
+    } set_attr_val;                     /*!< Gatt server callback param of ESP_GATTS_SET_ATTR_VAL_EVT */
+
 } esp_ble_gatts_cb_param_t;
 } esp_ble_gatts_cb_param_t;
 
 
 /**
 /**
@@ -294,7 +317,22 @@ esp_err_t esp_ble_gatts_create_service(esp_gatt_if_t gatts_if,
                                        esp_gatt_srvc_id_t *service_id, uint16_t num_handle);
                                        esp_gatt_srvc_id_t *service_id, uint16_t num_handle);
 
 
 
 
-
+/**
+ * @brief               Create a service attribute tab. 
+ * @param[in]       gatts_attr_db: the pointer to the service attr tab
+ * @param[in]       gatts_if: GATT server access interface
+ * @param[in]       max_nb_attr: the number of attribute to be added to the service database.
+ * @param[in]       srvc_inst_id: the instance id of the service
+ *
+ * @return
+ *                  - ESP_OK : success
+ *                  - other  : failed
+ *
+ */
+esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db, 
+                                            esp_gatt_if_t gatts_if,
+                                            uint8_t max_nb_attr,
+                                            uint8_t srvc_inst_id);
 /**
 /**
  * @brief           This function is called to add an included service. After included
  * @brief           This function is called to add an included service. After included
  *                  service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT
  *                  service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT
@@ -321,6 +359,8 @@ esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t i
  * @param[in]       char_uuid : Characteristic UUID.
  * @param[in]       char_uuid : Characteristic UUID.
  * @param[in]       perm      : Characteristic value declaration attribute permission.
  * @param[in]       perm      : Characteristic value declaration attribute permission.
  * @param[in]       property  : Characteristic Properties
  * @param[in]       property  : Characteristic Properties
+ * @param[in]       char_val    : Characteristic value 
+ * @param[in]       control : attribute response control byte
  *
  *
  * @return
  * @return
  *                  - ESP_OK : success
  *                  - ESP_OK : success
@@ -328,7 +368,8 @@ esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t i
  *
  *
  */
  */
 esp_err_t esp_ble_gatts_add_char(uint16_t service_handle,  esp_bt_uuid_t  *char_uuid,
 esp_err_t esp_ble_gatts_add_char(uint16_t service_handle,  esp_bt_uuid_t  *char_uuid,
-                                 esp_gatt_perm_t perm, esp_gatt_char_prop_t property);
+                                 esp_gatt_perm_t perm, esp_gatt_char_prop_t property, esp_attr_value_t *char_val,
+                                 esp_attr_control_t *control);
 
 
 
 
 /**
 /**
@@ -340,15 +381,17 @@ esp_err_t esp_ble_gatts_add_char(uint16_t service_handle,  esp_bt_uuid_t  *char_
  *                              be added.
  *                              be added.
  * @param[in]       perm: descriptor access permission.
  * @param[in]       perm: descriptor access permission.
  * @param[in]       descr_uuid: descriptor UUID.
  * @param[in]       descr_uuid: descriptor UUID.
- *
+ * @param[in]       char_descr_val  : Characteristic descriptor value 
+ * @param[in]       control : attribute response control byte
  * @return
  * @return
  *                  - ESP_OK : success
  *                  - ESP_OK : success
  *                  - other  : failed
  *                  - other  : failed
  *
  *
  */
  */
 esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
 esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
-                                        esp_bt_uuid_t  *descr_uuid,
-                                        esp_gatt_perm_t perm);
+                                        esp_bt_uuid_t   *descr_uuid,
+                                        esp_gatt_perm_t perm, esp_attr_value_t *char_descr_val,
+                                        esp_attr_control_t *control);
 
 
 
 
 
 
@@ -432,6 +475,35 @@ esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id,
                                       esp_gatt_status_t status, esp_gatt_rsp_t *rsp);
                                       esp_gatt_status_t status, esp_gatt_rsp_t *rsp);
 
 
 
 
+/**
+ * @brief           This function is called to set the attribute value by the application
+ *
+ * @param[in]       attr_handle: the attribute handle which to be set
+ * @param[in]       length: the value length
+ * @param[in]       value: the pointer to the attribute value
+ *
+ * @return
+ *                  - ESP_OK : success
+ *                  - other  : failed
+ *
+ */
+esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, const uint8_t *value);
+
+/**
+ * @brief       Retrieve attribute value
+ *
+ * @param[in]   attr_handle: Attribute handle.
+ * @param[out]  length: pointer to the attribute value length
+ * @param[out]  value:  Pointer to attribute value payload, the value cannot be modified by user
+ *
+ * @return
+ *                  - ESP_OK : success
+ *                  - other  : failed
+ *
+ */
+esp_err_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value);
+
+
 /**
 /**
  * @brief           Open a direct open connection or add a background auto connection
  * @brief           Open a direct open connection or add a background auto connection
  *
  *

+ 58 - 3
components/bt/bluedroid/bta/gatt/bta_gatts_act.c

@@ -34,7 +34,6 @@
 #include "bta_gatts_int.h"
 #include "bta_gatts_int.h"
 #include "bta_gatts_co.h"
 #include "bta_gatts_co.h"
 #include "btm_ble_api.h"
 #include "btm_ble_api.h"
-// #include "btif/include/btif_debug_conn.h"
 #include <string.h>
 #include <string.h>
 
 
 static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
 static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
@@ -404,10 +403,20 @@ void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
     UINT16          attr_id = 0;
     UINT16          attr_id = 0;
     tBTA_GATTS      cb_data;
     tBTA_GATTS      cb_data;
 
 
+    tGATT_ATTR_VAL *p_attr_val = NULL;
+    tGATTS_ATTR_CONTROL *p_control = NULL;
+
+    if (p_msg->api_add_char_descr.attr_val.attr_max_len != 0) {
+        p_attr_val = &p_msg->api_add_char_descr.attr_val;
+    }
+
+    if (p_msg->api_add_char_descr.control.auto_rsp != 0) {
+        p_control = &p_msg->api_add_char_descr.control;
+    }
     attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
     attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
                                       &p_msg->api_add_char.char_uuid,
                                       &p_msg->api_add_char.char_uuid,
                                       p_msg->api_add_char.perm,
                                       p_msg->api_add_char.perm,
-                                      p_msg->api_add_char.property);
+                                      p_msg->api_add_char.property, p_attr_val, p_control);
     cb_data.add_result.server_if = p_rcb->gatt_if;
     cb_data.add_result.server_if = p_rcb->gatt_if;
     cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
     cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
     cb_data.add_result.attr_id = attr_id;
     cb_data.add_result.attr_id = attr_id;
@@ -425,6 +434,7 @@ void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
         (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
         (*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
     }
     }
 }
 }
+
 /*******************************************************************************
 /*******************************************************************************
 **
 **
 ** Function         bta_gatts_add_char_descr
 ** Function         bta_gatts_add_char_descr
@@ -439,10 +449,20 @@ void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_
     tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
     tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
     UINT16          attr_id = 0;
     UINT16          attr_id = 0;
     tBTA_GATTS      cb_data;
     tBTA_GATTS      cb_data;
+    tGATT_ATTR_VAL *p_attr_val = NULL;
+    tGATTS_ATTR_CONTROL *p_control = NULL;
+
+    if (p_msg->api_add_char_descr.attr_val.attr_max_len != 0) {
+        p_attr_val = &p_msg->api_add_char_descr.attr_val;
+    }
 
 
+    if (p_msg->api_add_char_descr.control.auto_rsp != 0) {
+        p_control = &p_msg->api_add_char_descr.control;
+    }
     attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific,
     attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific,
                                       p_msg->api_add_char_descr.perm,
                                       p_msg->api_add_char_descr.perm,
-                                      &p_msg->api_add_char_descr.descr_uuid);
+                                      &p_msg->api_add_char_descr.descr_uuid, p_attr_val,
+                                      p_control);
 
 
     cb_data.add_result.server_if = p_rcb->gatt_if;
     cb_data.add_result.server_if = p_rcb->gatt_if;
     cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
     cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
@@ -462,6 +482,41 @@ void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_
     }
     }
 
 
 }
 }
+
+/*******************************************************************************
+**
+** Function         bta_gatts_add_char_descr
+**
+** Description      action function to add characteristic descriptor.
+**
+** Returns          none.
+**
+*******************************************************************************/
+void bta_gatts_set_attr_value(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
+{
+    tBTA_GATTS_RCB  *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
+    UINT16          attr_id = 0;
+    tBTA_GATTS      cb_data;
+    tBTA_GATT_STATUS gatts_status;
+    gatts_status = GATTS_SetAttributeValue(p_msg->api_add_char_descr.hdr.layer_specific,
+                                           p_msg->api_set_val.length,
+                                           p_msg->api_set_val.value);
+
+    cb_data.attr_val.server_if = p_rcb->gatt_if;
+    cb_data.attr_val.service_id = p_msg->api_set_val.hdr.layer_specific;
+    cb_data.attr_val.attr_id = attr_id;
+    cb_data.attr_val.status = gatts_status;
+
+    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)
+{
+    GATTS_GetAttributeValue(attr_handle, length, value);
+}
+
 /*******************************************************************************
 /*******************************************************************************
 **
 **
 ** Function         bta_gatts_delete_service
 ** Function         bta_gatts_delete_service

+ 60 - 6
components/bt/bluedroid/bta/gatt/bta_gatts_api.c

@@ -215,10 +215,14 @@ void BTA_GATTS_AddIncludeService(UINT16 service_id, UINT16 included_service_id)
 **
 **
 *******************************************************************************/
 *******************************************************************************/
 void BTA_GATTS_AddCharacteristic (UINT16 service_id,  tBT_UUID  *p_char_uuid,
 void BTA_GATTS_AddCharacteristic (UINT16 service_id,  tBT_UUID  *p_char_uuid,
-                                  tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property)
+                                  tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property, tGATT_ATTR_VAL *attr_val, 
+                                  tBTA_GATTS_ATTR_CONTROL *control)
 {
 {
     tBTA_GATTS_API_ADD_CHAR  *p_buf;
     tBTA_GATTS_API_ADD_CHAR  *p_buf;
-
+    UINT16 len = 0;
+    if(attr_val != NULL){
+        len = attr_val->attr_len;
+    }
     if ((p_buf = (tBTA_GATTS_API_ADD_CHAR *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_CHAR))) != NULL) {
     if ((p_buf = (tBTA_GATTS_API_ADD_CHAR *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_CHAR))) != NULL) {
         memset(p_buf, 0, sizeof(tBTA_GATTS_API_ADD_CHAR));
         memset(p_buf, 0, sizeof(tBTA_GATTS_API_ADD_CHAR));
 
 
@@ -226,6 +230,19 @@ void BTA_GATTS_AddCharacteristic (UINT16 service_id,  tBT_UUID  *p_char_uuid,
         p_buf->hdr.layer_specific = service_id;
         p_buf->hdr.layer_specific = service_id;
         p_buf->perm = perm;
         p_buf->perm = perm;
         p_buf->property = property;
         p_buf->property = property;
+        if(control !=NULL){
+            p_buf->control.auto_rsp = control->auto_rsp;
+        }
+        if(attr_val != NULL){
+            APPL_TRACE_DEBUG("!!!!!!attr_val->attr_len = %x\n",attr_val->attr_len);
+            APPL_TRACE_DEBUG("!!!!!!!attr_val->attr_max_len = %x\n",attr_val->attr_max_len);
+            p_buf->attr_val.attr_len = attr_val->attr_len;
+            p_buf->attr_val.attr_max_len = attr_val->attr_max_len;
+            p_buf->attr_val.attr_val = (uint8_t *)GKI_getbuf(len);
+            if(p_buf->attr_val.attr_val != NULL){
+                memcpy(p_buf->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
+            }
+        }
 
 
         if (p_char_uuid) {
         if (p_char_uuid) {
             memcpy(&p_buf->char_uuid, p_char_uuid, sizeof(tBT_UUID));
             memcpy(&p_buf->char_uuid, p_char_uuid, sizeof(tBT_UUID));
@@ -253,11 +270,16 @@ void BTA_GATTS_AddCharacteristic (UINT16 service_id,  tBT_UUID  *p_char_uuid,
 *******************************************************************************/
 *******************************************************************************/
 void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
 void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
                                   tBTA_GATT_PERM perm,
                                   tBTA_GATT_PERM perm,
-                                  tBT_UUID   *p_descr_uuid)
+                                  tBT_UUID   *p_descr_uuid, tBTA_GATT_ATTR_VAL *attr_val, 
+                                  tBTA_GATTS_ATTR_CONTROL *control)
 {
 {
     tBTA_GATTS_API_ADD_DESCR  *p_buf;
     tBTA_GATTS_API_ADD_DESCR  *p_buf;
-    UINT16  len = sizeof(tBTA_GATTS_API_ADD_DESCR);
-
+    UINT16  len = 0;
+    if(attr_val != NULL) {
+        len = sizeof(tBTA_GATTS_API_ADD_DESCR) + attr_val->attr_len;
+    } else {
+        len = sizeof(tBTA_GATTS_API_ADD_DESCR);
+    }
 
 
     if ((p_buf = (tBTA_GATTS_API_ADD_DESCR *) GKI_getbuf(len)) != NULL) {
     if ((p_buf = (tBTA_GATTS_API_ADD_DESCR *) GKI_getbuf(len)) != NULL) {
         memset(p_buf, 0, len);
         memset(p_buf, 0, len);
@@ -269,10 +291,19 @@ void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
         if (p_descr_uuid) {
         if (p_descr_uuid) {
             memcpy(&p_buf->descr_uuid, p_descr_uuid, sizeof(tBT_UUID));
             memcpy(&p_buf->descr_uuid, p_descr_uuid, sizeof(tBT_UUID));
         }
         }
+
+        if(attr_val->attr_len != 0) {
+            p_buf->attr_val.attr_len = attr_val->attr_len;
+            p_buf->attr_val.attr_max_len= attr_val->attr_max_len;
+            memcpy(p_buf->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
+        }
+
+        if(control != NULL) {
+            p_buf->control.auto_rsp = control->auto_rsp;
+        }
         bta_sys_sendmsg(p_buf);
         bta_sys_sendmsg(p_buf);
     }
     }
     return;
     return;
-
 }
 }
 
 
 /*******************************************************************************
 /*******************************************************************************
@@ -433,6 +464,29 @@ void BTA_GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id,
 }
 }
 
 
 
 
+void BTA_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value)
+{
+    tBTA_GATTS_API_SET_ATTR_VAL *p_buf;
+    if((p_buf = (tBTA_GATTS_API_SET_ATTR_VAL *)GKI_getbuf(
+                    sizeof(tBTA_GATTS_API_SET_ATTR_VAL))) != NULL){
+        p_buf->hdr.event = BTA_GATTS_API_SET_ATTR_VAL_EVT;
+        p_buf->hdr.layer_specific = attr_handle;
+        p_buf->length = length;
+        if(value != NULL){
+            if((p_buf->value = (UINT8 *)GKI_getbuf(length)) != NULL){
+                memcpy(p_buf->value, value, length);
+            }
+        }
+
+        bta_sys_sendmsg(p_buf);
+    }
+
+}
+
+void BTA_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value)
+{
+    bta_gatts_get_attr_value(attr_handle, length, value);
+}
 
 
 /*******************************************************************************
 /*******************************************************************************
 **
 **

+ 7 - 6
components/bt/bluedroid/bta/gatt/bta_gatts_main.c

@@ -104,29 +104,30 @@ BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg)
     case BTA_GATTS_API_RSP_EVT:
     case BTA_GATTS_API_RSP_EVT:
         bta_gatts_send_rsp(p_cb, (tBTA_GATTS_DATA *) p_msg);
         bta_gatts_send_rsp(p_cb, (tBTA_GATTS_DATA *) p_msg);
         break;
         break;
-
+    case BTA_GATTS_API_SET_ATTR_VAL_EVT:{
+        UINT16 attr_id = ((tBTA_GATTS_DATA *) p_msg)->api_set_val.hdr.layer_specific;
+        p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id(p_cb, attr_id);
+        bta_gatts_set_attr_value(p_srvc_cb, (tBTA_GATTS_DATA *) p_msg);
+        break;
+    }
     case BTA_GATTS_API_LISTEN_EVT:
     case BTA_GATTS_API_LISTEN_EVT:
         bta_gatts_listen(p_cb, (tBTA_GATTS_DATA *) p_msg);
         bta_gatts_listen(p_cb, (tBTA_GATTS_DATA *) p_msg);
         break;
         break;
-
-
     case BTA_GATTS_API_ADD_INCL_SRVC_EVT:
     case BTA_GATTS_API_ADD_INCL_SRVC_EVT:
     case BTA_GATTS_API_ADD_CHAR_EVT:
     case BTA_GATTS_API_ADD_CHAR_EVT:
     case BTA_GATTS_API_ADD_DESCR_EVT:
     case BTA_GATTS_API_ADD_DESCR_EVT:
     case BTA_GATTS_API_DEL_SRVC_EVT:
     case BTA_GATTS_API_DEL_SRVC_EVT:
     case BTA_GATTS_API_START_SRVC_EVT:
     case BTA_GATTS_API_START_SRVC_EVT:
     case BTA_GATTS_API_STOP_SRVC_EVT:
     case BTA_GATTS_API_STOP_SRVC_EVT:
-
         p_srvc_cb = bta_gatts_find_srvc_cb_by_srvc_id(p_cb,
         p_srvc_cb = bta_gatts_find_srvc_cb_by_srvc_id(p_cb,
                     ((tBTA_GATTS_DATA *)p_msg)->api_add_incl_srvc.hdr.layer_specific);
                     ((tBTA_GATTS_DATA *)p_msg)->api_add_incl_srvc.hdr.layer_specific);
 
 
         if (p_srvc_cb != NULL) {
         if (p_srvc_cb != NULL) {
             bta_gatts_srvc_build_act[p_msg->event - BTA_GATTS_API_ADD_INCL_SRVC_EVT](p_srvc_cb, (tBTA_GATTS_DATA *) p_msg);
             bta_gatts_srvc_build_act[p_msg->event - BTA_GATTS_API_ADD_INCL_SRVC_EVT](p_srvc_cb, (tBTA_GATTS_DATA *) p_msg);
         } else {
         } else {
-            APPL_TRACE_ERROR("service not created");
+            APPL_TRACE_ERROR("service not created\n");
         }
         }
         break;
         break;
-
     default:
     default:
         break;
         break;
     }
     }

+ 109 - 65
components/bt/bluedroid/bta/include/bta_gatt_api.h

@@ -109,41 +109,41 @@ typedef UINT8 tBTA_GATT_STATUS;
 
 
 
 
 /* Client callback function events */
 /* Client callback function events */
-#define BTA_GATTC_REG_EVT           0   /* GATT client is registered. */
-#define BTA_GATTC_DEREG_EVT         1   /* GATT client deregistered event */
-#define BTA_GATTC_OPEN_EVT          2   /* GATTC open request status  event */
-#define BTA_GATTC_READ_CHAR_EVT     3   /* GATT read characteristic event */
-#define BTA_GATTC_WRITE_CHAR_EVT    4   /* GATT write characteristic or char descriptor event */
-#define BTA_GATTC_CLOSE_EVT         5   /* GATTC  close request status event */
-#define BTA_GATTC_SEARCH_CMPL_EVT   6   /* GATT discovery complete event */
-#define BTA_GATTC_SEARCH_RES_EVT    7   /* GATT discovery result event */
-#define BTA_GATTC_READ_DESCR_EVT    8   /* GATT read characterisitc descriptor event */
-#define BTA_GATTC_WRITE_DESCR_EVT   9   /* GATT write characteristic descriptor event */
-#define BTA_GATTC_NOTIF_EVT         10  /* GATT attribute notification event */
-#define BTA_GATTC_PREP_WRITE_EVT    11  /* GATT prepare write  event */
-#define BTA_GATTC_EXEC_EVT          12  /* execute write complete event */
-#define BTA_GATTC_ACL_EVT           13  /* ACL up event */
-#define BTA_GATTC_CANCEL_OPEN_EVT   14  /* cancel open event */
-#define BTA_GATTC_SRVC_CHG_EVT      15  /* service change event */
-#define BTA_GATTC_LISTEN_EVT        16  /* listen event */
-#define BTA_GATTC_ENC_CMPL_CB_EVT   17  /* encryption complete callback event */
-#define BTA_GATTC_CFG_MTU_EVT       18  /* configure MTU complete event */
-#define BTA_GATTC_ADV_DATA_EVT      19  /* ADV data event */
-#define BTA_GATTC_MULT_ADV_ENB_EVT  20  /* Enable Multi ADV event */
-#define BTA_GATTC_MULT_ADV_UPD_EVT  21  /* Update parameter event */
-#define BTA_GATTC_MULT_ADV_DATA_EVT 22  /* Multi ADV data event */
-#define BTA_GATTC_MULT_ADV_DIS_EVT  23  /* Disable Multi ADV event */
-#define BTA_GATTC_CONGEST_EVT       24  /* Congestion event */
-#define BTA_GATTC_BTH_SCAN_ENB_EVT  25 /* Enable batch scan event */
-#define BTA_GATTC_BTH_SCAN_CFG_EVT  26 /* Config storage event */
-#define BTA_GATTC_BTH_SCAN_RD_EVT   27 /* Batch scan reports read event */
-#define BTA_GATTC_BTH_SCAN_THR_EVT  28 /* Batch scan threshold event */
-#define BTA_GATTC_BTH_SCAN_PARAM_EVT 29 /* Batch scan param event */
-#define BTA_GATTC_BTH_SCAN_DIS_EVT  30 /* Disable batch scan event */
-#define BTA_GATTC_SCAN_FLT_CFG_EVT  31 /* Scan filter config event */
-#define BTA_GATTC_SCAN_FLT_PARAM_EVT 32 /* Param filter event */
-#define BTA_GATTC_SCAN_FLT_STATUS_EVT 33 /* Filter status event */
-#define BTA_GATTC_ADV_VSC_EVT         34 /* ADV VSC event */
+#define BTA_GATTC_REG_EVT               0   /* GATT client is registered. */
+#define BTA_GATTC_DEREG_EVT             1   /* GATT client deregistered event */
+#define BTA_GATTC_OPEN_EVT              2   /* GATTC open request status  event */
+#define BTA_GATTC_READ_CHAR_EVT         3   /* GATT read characteristic event */
+#define BTA_GATTC_WRITE_CHAR_EVT        4   /* GATT write characteristic or char descriptor event */
+#define BTA_GATTC_CLOSE_EVT             5   /* GATTC  close request status event */
+#define BTA_GATTC_SEARCH_CMPL_EVT       6   /* GATT discovery complete event */
+#define BTA_GATTC_SEARCH_RES_EVT        7   /* GATT discovery result event */
+#define BTA_GATTC_READ_DESCR_EVT        8   /* GATT read characterisitc descriptor event */
+#define BTA_GATTC_WRITE_DESCR_EVT       9   /* GATT write characteristic descriptor event */
+#define BTA_GATTC_NOTIF_EVT             10  /* GATT attribute notification event */
+#define BTA_GATTC_PREP_WRITE_EVT        11  /* GATT prepare write  event */
+#define BTA_GATTC_EXEC_EVT              12  /* execute write complete event */
+#define BTA_GATTC_ACL_EVT               13  /* ACL up event */
+#define BTA_GATTC_CANCEL_OPEN_EVT       14  /* cancel open event */
+#define BTA_GATTC_SRVC_CHG_EVT          15  /* service change event */
+#define BTA_GATTC_LISTEN_EVT            16  /* listen event */
+#define BTA_GATTC_ENC_CMPL_CB_EVT       17  /* encryption complete callback event */
+#define BTA_GATTC_CFG_MTU_EVT           18  /* configure MTU complete event */
+#define BTA_GATTC_ADV_DATA_EVT          19  /* ADV data event */
+#define BTA_GATTC_MULT_ADV_ENB_EVT      20  /* Enable Multi ADV event */
+#define BTA_GATTC_MULT_ADV_UPD_EVT      21  /* Update parameter event */
+#define BTA_GATTC_MULT_ADV_DATA_EVT     22  /* Multi ADV data event */
+#define BTA_GATTC_MULT_ADV_DIS_EVT      23  /* Disable Multi ADV event */
+#define BTA_GATTC_CONGEST_EVT           24  /* Congestion event */
+#define BTA_GATTC_BTH_SCAN_ENB_EVT      25 /* Enable batch scan event */
+#define BTA_GATTC_BTH_SCAN_CFG_EVT      26 /* Config storage event */
+#define BTA_GATTC_BTH_SCAN_RD_EVT       27 /* Batch scan reports read event */
+#define BTA_GATTC_BTH_SCAN_THR_EVT      28 /* Batch scan threshold event */
+#define BTA_GATTC_BTH_SCAN_PARAM_EVT    29 /* Batch scan param event */
+#define BTA_GATTC_BTH_SCAN_DIS_EVT      30 /* Disable batch scan event */
+#define BTA_GATTC_SCAN_FLT_CFG_EVT      31 /* Scan filter config event */
+#define BTA_GATTC_SCAN_FLT_PARAM_EVT    32 /* Param filter event */
+#define BTA_GATTC_SCAN_FLT_STATUS_EVT   33 /* Filter status event */
+#define BTA_GATTC_ADV_VSC_EVT           34 /* ADV VSC event */
 
 
 typedef UINT8 tBTA_GATTC_EVT;
 typedef UINT8 tBTA_GATTC_EVT;
 
 
@@ -151,7 +151,7 @@ typedef tGATT_IF tBTA_GATTC_IF;
 
 
 typedef struct {
 typedef struct {
     UINT16              unit;       /* as UUIUD defined by SIG */
     UINT16              unit;       /* as UUIUD defined by SIG */
-    UINT16              descr;       /* as UUID as defined by SIG */
+    UINT16              descr;      /* as UUID as defined by SIG */
     tGATT_FORMAT        format;
     tGATT_FORMAT        format;
     INT8                exp;
     INT8                exp;
     UINT8               name_spc;   /* The name space of the description */
     UINT8               name_spc;   /* The name space of the description */
@@ -165,7 +165,7 @@ typedef UINT16  tBTA_GATT_CLT_CHAR_CONFIG;
 /* characteristic descriptor: server configuration value
 /* characteristic descriptor: server configuration value
 */
 */
 #define BTA_GATT_SVR_CONFIG_NONE            GATT_SVR_CONFIG_NONE            /* 0x0000 */
 #define BTA_GATT_SVR_CONFIG_NONE            GATT_SVR_CONFIG_NONE            /* 0x0000 */
-#define BTA_GATT_SVR_CONFIG_BROADCAST       GATT_SVR_CONFIG_BROADCAST       /*  0x0001 */
+#define BTA_GATT_SVR_CONFIG_BROADCAST       GATT_SVR_CONFIG_BROADCAST       /* 0x0001 */
 typedef UINT16  tBTA_GATT_SVR_CHAR_CONFIG;
 typedef UINT16  tBTA_GATT_SVR_CHAR_CONFIG;
 
 
 /* Characteristic Aggregate Format attribute value
 /* Characteristic Aggregate Format attribute value
@@ -367,8 +367,8 @@ typedef struct {
 // btla-specific --
 // btla-specific --
 
 
 typedef struct {
 typedef struct {
-    tBTA_GATTC_IF       client_if;
-    BD_ADDR             remote_bda;
+    tBTA_GATTC_IF           client_if;
+    BD_ADDR                 remote_bda;
 } tBTA_GATTC_ENC_CMPL_CB;
 } tBTA_GATTC_ENC_CMPL_CB;
 
 
 typedef union {
 typedef union {
@@ -395,7 +395,6 @@ typedef void (tBTA_GATTC_ENB_CBACK)(tBTA_GATT_STATUS status);
 /* Client callback function */
 /* Client callback function */
 typedef void (tBTA_GATTC_CBACK)(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
 typedef void (tBTA_GATTC_CBACK)(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
 
 
-
 /* GATT Server Data Structure */
 /* GATT Server Data Structure */
 /* Server callback function events */
 /* Server callback function events */
 #define BTA_GATTS_REG_EVT                               0
 #define BTA_GATTS_REG_EVT                               0
@@ -419,6 +418,7 @@ typedef void (tBTA_GATTC_CBACK)(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
 #define BTA_GATTS_CLOSE_EVT                             18
 #define BTA_GATTS_CLOSE_EVT                             18
 #define BTA_GATTS_LISTEN_EVT                            19
 #define BTA_GATTS_LISTEN_EVT                            19
 #define BTA_GATTS_CONGEST_EVT                           20
 #define BTA_GATTS_CONGEST_EVT                           20
+#define BTA_GATTS_SET_ATTR_VAL_EVT                      21
 
 
 typedef UINT8  tBTA_GATTS_EVT;
 typedef UINT8  tBTA_GATTS_EVT;
 typedef tGATT_IF tBTA_GATTS_IF;
 typedef tGATT_IF tBTA_GATTS_IF;
@@ -434,20 +434,22 @@ typedef tGATT_IF tBTA_GATTS_IF;
 #define BTA_GATT_PERM_WRITE_SIGNED      GATT_PERM_WRITE_SIGNED      /* bit 7 -  0x0080 */
 #define BTA_GATT_PERM_WRITE_SIGNED      GATT_PERM_WRITE_SIGNED      /* bit 7 -  0x0080 */
 #define BTA_GATT_PERM_WRITE_SIGNED_MITM GATT_PERM_WRITE_SIGNED_MITM /* bit 8 -  0x0100 */
 #define BTA_GATT_PERM_WRITE_SIGNED_MITM GATT_PERM_WRITE_SIGNED_MITM /* bit 8 -  0x0100 */
 typedef UINT16 tBTA_GATT_PERM;
 typedef UINT16 tBTA_GATT_PERM;
+typedef tGATT_ATTR_VAL tBTA_GATT_ATTR_VAL;
+typedef tGATTS_ATTR_CONTROL tBTA_GATTS_ATTR_CONTROL;
 
 
 #define BTA_GATTS_INVALID_APP   0xff
 #define BTA_GATTS_INVALID_APP   0xff
 
 
 #define BTA_GATTS_INVALID_IF    0
 #define BTA_GATTS_INVALID_IF    0
 
 
 /* definition of characteristic properties */
 /* definition of characteristic properties */
-#define BTA_GATT_CHAR_PROP_BIT_BROADCAST    GATT_CHAR_PROP_BIT_BROADCAST    /* 0x01 */
-#define BTA_GATT_CHAR_PROP_BIT_READ         GATT_CHAR_PROP_BIT_READ    /* 0x02 */
-#define BTA_GATT_CHAR_PROP_BIT_WRITE_NR     GATT_CHAR_PROP_BIT_WRITE_NR    /* 0x04 */
-#define BTA_GATT_CHAR_PROP_BIT_WRITE        GATT_CHAR_PROP_BIT_WRITE       /* 0x08 */
-#define BTA_GATT_CHAR_PROP_BIT_NOTIFY       GATT_CHAR_PROP_BIT_NOTIFY      /* 0x10 */
-#define BTA_GATT_CHAR_PROP_BIT_INDICATE     GATT_CHAR_PROP_BIT_INDICATE    /* 0x20 */
-#define BTA_GATT_CHAR_PROP_BIT_AUTH         GATT_CHAR_PROP_BIT_AUTH        /* 0x40 */
-#define BTA_GATT_CHAR_PROP_BIT_EXT_PROP     GATT_CHAR_PROP_BIT_EXT_PROP    /* 0x80 */
+#define BTA_GATT_CHAR_PROP_BIT_BROADCAST        GATT_CHAR_PROP_BIT_BROADCAST    /* 0x01 */
+#define BTA_GATT_CHAR_PROP_BIT_READ             GATT_CHAR_PROP_BIT_READ         /* 0x02 */
+#define BTA_GATT_CHAR_PROP_BIT_WRITE_NR         GATT_CHAR_PROP_BIT_WRITE_NR     /* 0x04 */
+#define BTA_GATT_CHAR_PROP_BIT_WRITE            GATT_CHAR_PROP_BIT_WRITE        /* 0x08 */
+#define BTA_GATT_CHAR_PROP_BIT_NOTIFY           GATT_CHAR_PROP_BIT_NOTIFY       /* 0x10 */
+#define BTA_GATT_CHAR_PROP_BIT_INDICATE         GATT_CHAR_PROP_BIT_INDICATE     /* 0x20 */
+#define BTA_GATT_CHAR_PROP_BIT_AUTH             GATT_CHAR_PROP_BIT_AUTH         /* 0x40 */
+#define BTA_GATT_CHAR_PROP_BIT_EXT_PROP         GATT_CHAR_PROP_BIT_EXT_PROP     /* 0x80 */
 typedef UINT8 tBTA_GATT_CHAR_PROP;
 typedef UINT8 tBTA_GATT_CHAR_PROP;
 
 
 #ifndef BTA_GATTC_CHAR_DESCR_MAX
 #ifndef BTA_GATTC_CHAR_DESCR_MAX
@@ -476,8 +478,8 @@ typedef tGATTS_SRV_CHG     tBTA_GATTS_SRV_CHG;
 typedef tGATTS_SRV_CHG_REQ tBTA_GATTS_SRV_CHG_REQ;
 typedef tGATTS_SRV_CHG_REQ tBTA_GATTS_SRV_CHG_REQ;
 typedef tGATTS_SRV_CHG_RSP tBTA_GATTS_SRV_CHG_RSP;
 typedef tGATTS_SRV_CHG_RSP tBTA_GATTS_SRV_CHG_RSP;
 
 
-#define BTA_GATT_TRANSPORT_LE       GATT_TRANSPORT_LE
-#define BTA_GATT_TRANSPORT_BR_EDR   GATT_TRANSPORT_BR_EDR
+#define BTA_GATT_TRANSPORT_LE           GATT_TRANSPORT_LE
+#define BTA_GATT_TRANSPORT_BR_EDR       GATT_TRANSPORT_BR_EDR
 #define BTA_GATT_TRANSPORT_LE_BR_EDR    GATT_TRANSPORT_LE_BR_EDR
 #define BTA_GATT_TRANSPORT_LE_BR_EDR    GATT_TRANSPORT_LE_BR_EDR
 typedef UINT8 tBTA_GATT_TRANSPORT;
 typedef UINT8 tBTA_GATT_TRANSPORT;
 
 
@@ -539,6 +541,13 @@ typedef struct {
 // btla-specific --
 // btla-specific --
 } tBTA_GATTS_ADD_RESULT;
 } tBTA_GATTS_ADD_RESULT;
 
 
+typedef struct{
+    tBTA_GATTS_IF       server_if;
+    UINT16              service_id;
+    UINT16              attr_id;
+    tBTA_GATT_STATUS    status;
+}tBAT_GATTS_ATTR_VAL_RESULT;
+
 typedef struct {
 typedef struct {
     tBTA_GATTS_IF       server_if;
     tBTA_GATTS_IF       server_if;
     UINT16              service_id;
     UINT16              service_id;
@@ -566,17 +575,18 @@ typedef struct {
 
 
 /* GATTS callback data */
 /* GATTS callback data */
 typedef union {
 typedef union {
-    tBTA_GATTS_REG_OPER     reg_oper;
-    tBTA_GATTS_CREATE       create;
-    tBTA_GATTS_SRVC_OPER    srvc_oper;
-    tBTA_GATT_STATUS        status;      /* BTA_GATTS_LISTEN_EVT */
-    tBTA_GATTS_ADD_RESULT   add_result;  /* add included service: BTA_GATTS_ADD_INCL_SRVC_EVT
-                                           add char : BTA_GATTS_ADD_CHAR_EVT
-                                           add char descriptor: BTA_GATTS_ADD_CHAR_DESCR_EVT */
-    tBTA_GATTS_REQ          req_data;
-    tBTA_GATTS_CONN         conn;       /* BTA_GATTS_CONN_EVT */
-    tBTA_GATTS_CONGEST      congest;    /* BTA_GATTS_CONGEST_EVT callback data */
-    tBTA_GATTS_CONF         confirm;    /* BTA_GATTS_CONF_EVT callback data */
+    tBTA_GATTS_REG_OPER         reg_oper;
+    tBTA_GATTS_CREATE           create;
+    tBTA_GATTS_SRVC_OPER        srvc_oper;
+    tBTA_GATT_STATUS            status;         /* BTA_GATTS_LISTEN_EVT */
+    tBTA_GATTS_ADD_RESULT       add_result;     /* add included service: BTA_GATTS_ADD_INCL_SRVC_EVT
+                                                add char : BTA_GATTS_ADD_CHAR_EVT
+                                                add char descriptor: BTA_GATTS_ADD_CHAR_DESCR_EVT */
+    tBAT_GATTS_ATTR_VAL_RESULT  attr_val;
+    tBTA_GATTS_REQ              req_data;
+    tBTA_GATTS_CONN             conn;           /* BTA_GATTS_CONN_EVT */
+    tBTA_GATTS_CONGEST          congest;        /* BTA_GATTS_CONGEST_EVT callback data */
+    tBTA_GATTS_CONF             confirm;        /* BTA_GATTS_CONF_EVT callback data */
 } tBTA_GATTS;
 } tBTA_GATTS;
 
 
 /* GATTS enable callback function */
 /* GATTS enable callback function */
@@ -1193,8 +1203,9 @@ extern void BTA_GATTS_AddIncludeService(UINT16 service_id, UINT16 included_servi
 ** Returns          None
 ** Returns          None
 **
 **
 *******************************************************************************/
 *******************************************************************************/
-extern void BTA_GATTS_AddCharacteristic (UINT16 service_id,  tBT_UUID   *p_char_uuid,
-        tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property);
+extern void BTA_GATTS_AddCharacteristic (UINT16 service_id,  tBT_UUID  *p_char_uuid,
+                                  tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property, tGATT_ATTR_VAL *attr_val, 
+                                  tBTA_GATTS_ATTR_CONTROL *control);
 
 
 /*******************************************************************************
 /*******************************************************************************
 **
 **
@@ -1214,8 +1225,9 @@ extern void BTA_GATTS_AddCharacteristic (UINT16 service_id,  tBT_UUID   *p_char_
 **
 **
 *******************************************************************************/
 *******************************************************************************/
 extern void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
 extern void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
-        tBTA_GATT_PERM perm,
-        tBT_UUID   *p_descr_uuid);
+                                  tBTA_GATT_PERM perm,
+                                  tBT_UUID   *p_descr_uuid, tBTA_GATT_ATTR_VAL *attr_val, 
+                                  tBTA_GATTS_ATTR_CONTROL *control);
 
 
 /*******************************************************************************
 /*******************************************************************************
 **
 **
@@ -1296,6 +1308,38 @@ extern void BTA_GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id,
                                tBTA_GATT_STATUS status, tBTA_GATTS_RSP *p_msg);
                                tBTA_GATT_STATUS status, tBTA_GATTS_RSP *p_msg);
 
 
 
 
+
+/*******************************************************************************
+**
+** Function         BTA_SetAttributeValue
+**
+** Description      This function is called to set the attribute value in the gatt database
+**
+** Parameters   attr_handle - the attribute value handle.
+**                      length - the value length which has been set to the attribute.
+**                      value - the pointer to the value
+**
+** Returns          None
+**
+*******************************************************************************/
+extern void BTA_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value);
+
+
+/*******************************************************************************
+**
+** Function         BTA_GetAttributeValue
+**
+** Description      This function is called to get the attribute value in the gatt database
+**
+** Parameters   attr_handle - the attribute value handle.
+**                      length - the value length which has been set to the attribute.
+**                      value - the pointer to the value
+**
+** Returns          None
+**
+*******************************************************************************/
+extern void BTA_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value);
+
 /*******************************************************************************
 /*******************************************************************************
 **
 **
 ** Function         BTA_GATTS_Open
 ** Function         BTA_GATTS_Open

+ 18 - 6
components/bt/bluedroid/bta/include/bta_gatts_int.h

@@ -48,6 +48,7 @@ enum {
     BTA_GATTS_API_START_SRVC_EVT,
     BTA_GATTS_API_START_SRVC_EVT,
     BTA_GATTS_API_STOP_SRVC_EVT,
     BTA_GATTS_API_STOP_SRVC_EVT,
     BTA_GATTS_API_RSP_EVT,
     BTA_GATTS_API_RSP_EVT,
+    BTA_GATTS_API_SET_ATTR_VAL_EVT,
     BTA_GATTS_API_OPEN_EVT,
     BTA_GATTS_API_OPEN_EVT,
     BTA_GATTS_API_CANCEL_OPEN_EVT,
     BTA_GATTS_API_CANCEL_OPEN_EVT,
     BTA_GATTS_API_CLOSE_EVT,
     BTA_GATTS_API_CLOSE_EVT,
@@ -91,19 +92,21 @@ typedef struct {
     tBT_UUID                char_uuid;
     tBT_UUID                char_uuid;
     tBTA_GATT_PERM          perm;
     tBTA_GATT_PERM          perm;
     tBTA_GATT_CHAR_PROP     property;
     tBTA_GATT_CHAR_PROP     property;
-
+    tBTA_GATTS_ATTR_CONTROL control;
+    tBTA_GATT_ATTR_VAL      attr_val;
 } tBTA_GATTS_API_ADD_CHAR;
 } tBTA_GATTS_API_ADD_CHAR;
 
 
 typedef struct {
 typedef struct {
     BT_HDR                  hdr;
     BT_HDR                  hdr;
     UINT16                  included_service_id;
     UINT16                  included_service_id;
-
 } tBTA_GATTS_API_ADD_INCL_SRVC;
 } tBTA_GATTS_API_ADD_INCL_SRVC;
 
 
 typedef struct {
 typedef struct {
-    BT_HDR                      hdr;
-    tBT_UUID                    descr_uuid;
-    tBTA_GATT_PERM              perm;
+    BT_HDR                  hdr;
+    tBT_UUID                descr_uuid;
+    tBTA_GATT_PERM          perm;
+    tBTA_GATTS_ATTR_CONTROL control;
+    tBTA_GATT_ATTR_VAL      attr_val;
 } tBTA_GATTS_API_ADD_DESCR;
 } tBTA_GATTS_API_ADD_DESCR;
 
 
 typedef struct {
 typedef struct {
@@ -121,6 +124,12 @@ typedef struct {
     tBTA_GATTS_RSP      *p_rsp;
     tBTA_GATTS_RSP      *p_rsp;
 } tBTA_GATTS_API_RSP;
 } tBTA_GATTS_API_RSP;
 
 
+typedef struct{
+    BT_HDR              hdr;
+    UINT16 length;
+    UINT8 *value;
+}tBTA_GATTS_API_SET_ATTR_VAL;
+
 typedef struct {
 typedef struct {
     BT_HDR                  hdr;
     BT_HDR                  hdr;
     tBTA_GATT_TRANSPORT     transport;
     tBTA_GATT_TRANSPORT     transport;
@@ -156,6 +165,7 @@ typedef union {
     tBTA_GATTS_API_START            api_start;
     tBTA_GATTS_API_START            api_start;
     tBTA_GATTS_API_INDICATION       api_indicate;
     tBTA_GATTS_API_INDICATION       api_indicate;
     tBTA_GATTS_API_RSP              api_rsp;
     tBTA_GATTS_API_RSP              api_rsp;
+    tBTA_GATTS_API_SET_ATTR_VAL     api_set_val;
     tBTA_GATTS_API_OPEN             api_open;
     tBTA_GATTS_API_OPEN             api_open;
     tBTA_GATTS_API_CANCEL_OPEN      api_cancel_open;
     tBTA_GATTS_API_CANCEL_OPEN      api_cancel_open;
 
 
@@ -169,7 +179,7 @@ typedef struct {
     BOOLEAN             in_use;
     BOOLEAN             in_use;
     tBT_UUID            app_uuid;
     tBT_UUID            app_uuid;
     tBTA_GATTS_CBACK    *p_cback;
     tBTA_GATTS_CBACK    *p_cback;
-    tBTA_GATTS_IF        gatt_if;
+    tBTA_GATTS_IF       gatt_if;
 } tBTA_GATTS_RCB;
 } tBTA_GATTS_RCB;
 
 
 /* service registration control block */
 /* service registration control block */
@@ -219,6 +229,8 @@ extern void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
 extern void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
 extern void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
 extern void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
 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_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 void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
 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_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);
 extern void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);

+ 7 - 3
components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c

@@ -88,6 +88,7 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
     tBTA_GATTS_RSP rsp;
     tBTA_GATTS_RSP rsp;
 
 
     LOG_DEBUG("blufi profile cb event = %x\n", event);
     LOG_DEBUG("blufi profile cb event = %x\n", event);
+
     switch (event) {
     switch (event) {
     case BTA_GATTS_REG_EVT:
     case BTA_GATTS_REG_EVT:
         LOG_DEBUG("REG: status %d, app_uuid %04x, gatt_if %d\n", p_data->reg_oper.status, p_data->reg_oper.uuid.uu.uuid16, p_data->reg_oper.server_if);
         LOG_DEBUG("REG: status %d, app_uuid %04x, gatt_if %d\n", p_data->reg_oper.status, p_data->reg_oper.uuid.uu.uuid16, p_data->reg_oper.server_if);
@@ -187,7 +188,8 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
         //add the frist blufi characteristic --> write characteristic
         //add the frist blufi characteristic --> write characteristic
         BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_p2e,
         BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_p2e,
                                     (GATT_PERM_WRITE),
                                     (GATT_PERM_WRITE),
-                                    (GATT_CHAR_PROP_BIT_WRITE));
+                                    (GATT_CHAR_PROP_BIT_WRITE),
+                                    NULL, NULL);
         break;
         break;
     case BTA_GATTS_ADD_CHAR_EVT:
     case BTA_GATTS_ADD_CHAR_EVT:
         switch (p_data->add_result.char_uuid.uu.uuid16) {
         switch (p_data->add_result.char_uuid.uu.uuid16) {
@@ -196,14 +198,16 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
 
 
             BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_e2p,
             BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_e2p,
                                         (GATT_PERM_READ),
                                         (GATT_PERM_READ),
-                                        (GATT_PERM_READ | GATT_CHAR_PROP_BIT_NOTIFY));
+                                        (GATT_PERM_READ | GATT_CHAR_PROP_BIT_NOTIFY),
+                                        NULL, NULL);
             break;
             break;
          case BLUFI_CHAR_E2P_UUID:  /* ESP32 to Phone */
          case BLUFI_CHAR_E2P_UUID:  /* ESP32 to Phone */
             blufi_env.handle_char_e2p = p_data->add_result.attr_id;
             blufi_env.handle_char_e2p = p_data->add_result.attr_id;
 
 
             BTA_GATTS_AddCharDescriptor (blufi_env.handle_srvc,
             BTA_GATTS_AddCharDescriptor (blufi_env.handle_srvc,
                                          (GATT_PERM_READ | GATT_PERM_WRITE),
                                          (GATT_PERM_READ | GATT_PERM_WRITE),
-                                         &blufi_descr_uuid_e2p);
+                                         &blufi_descr_uuid_e2p,
+                                         NULL, NULL);
             break;
             break;
          default:
          default:
             break;
             break;

+ 282 - 9
components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c

@@ -20,17 +20,30 @@
 #include "btc_manage.h"
 #include "btc_manage.h"
 #include "btc_gatts.h"
 #include "btc_gatts.h"
 #include "btc_gatt_util.h"
 #include "btc_gatt_util.h"
-
+#include "future.h"
+#include "btc_main.h"
 #include "esp_gatts_api.h"
 #include "esp_gatts_api.h"
 
 
 #define A2C_GATTS_EVT(_bta_event) (_bta_event) //BTA TO BTC EVT
 #define A2C_GATTS_EVT(_bta_event) (_bta_event) //BTA TO BTC EVT
 #define C2A_GATTS_EVT(_btc_event) (_btc_event) //BTC TO BTA EVT
 #define C2A_GATTS_EVT(_btc_event) (_btc_event) //BTC TO BTA EVT
 
 
+typedef struct {
+    future_t *complete_future;
+    uint16_t svc_start_hdl;
+    esp_bt_uuid_t svc_uuid;
+    bool        is_tab_creat_svc;
+    uint8_t   num_handle;
+    uint8_t   handle_idx;
+    uint16_t handles[ESP_GATT_ATTR_HANDLE_MAX];
+} esp_btc_creat_tab_t;
+
+static esp_btc_creat_tab_t btc_creat_tab_env;
+
 static inline void btc_gatts_cb_to_app(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
 static inline void btc_gatts_cb_to_app(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
 {
 {
     esp_gatts_cb_t btc_gatts_cb = (esp_gatts_cb_t)btc_profile_cb_get(BTC_PID_GATTS);
     esp_gatts_cb_t btc_gatts_cb = (esp_gatts_cb_t)btc_profile_cb_get(BTC_PID_GATTS);
     if (btc_gatts_cb) {
     if (btc_gatts_cb) {
-	btc_gatts_cb(event, gatts_if, param);
+        btc_gatts_cb(event, gatts_if, param);
     }
     }
 }
 }
 
 
@@ -59,6 +72,56 @@ void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
             }
             }
         }
         }
         break;
         break;
+    
+    }
+    case BTC_GATTS_ACT_ADD_CHAR:{
+        if (src->add_char.char_val.attr_value != NULL){
+            dst->add_char.char_val.attr_value = (uint8_t *)GKI_getbuf(src->add_char.char_val.attr_len);
+            if(dst->add_char.char_val.attr_value != NULL){
+                memcpy(dst->add_char.char_val.attr_value, src->add_char.char_val.attr_value, 
+                        src->add_char.char_val.attr_len);
+            }else{
+                LOG_ERROR("%s %d no mem\n", __func__, msg->act);
+            }
+        }
+        break;
+    }
+    case BTC_GATTS_ACT_ADD_CHAR_DESCR:{
+        if(src->add_descr.descr_val.attr_value != NULL){
+            dst->add_descr.descr_val.attr_value = (uint8_t *)GKI_getbuf(src->add_descr.descr_val.attr_len);
+            if(dst->add_descr.descr_val.attr_value != NULL){
+                memcpy(dst->add_descr.descr_val.attr_value, src->add_descr.descr_val.attr_value,
+                        src->add_descr.descr_val.attr_len);
+            }else{
+                LOG_ERROR("%s %d no mem\n", __func__, msg->act);
+            }
+        }
+        break;
+    }
+    case BTC_GATTS_ACT_CREATE_ATTR_TAB:{
+        uint8_t num_attr = src->create_attr_tab.max_nb_attr;
+        if(src->create_attr_tab.gatts_attr_db != NULL){
+            dst->create_attr_tab.gatts_attr_db = (esp_gatts_attr_db_t *)GKI_getbuf(sizeof(esp_gatts_attr_db_t)*num_attr);
+            if(dst->create_attr_tab.gatts_attr_db != NULL){
+                memcpy(dst->create_attr_tab.gatts_attr_db, src->create_attr_tab.gatts_attr_db,
+                        sizeof(esp_gatts_attr_db_t)*num_attr);
+            }else{
+                LOG_ERROR("%s %d no mem\n",__func__, msg->act);
+            }
+        }
+        break;
+    }
+   case BTC_GATTS_ACT_SET_ATTR_VALUE:{
+        uint8_t len = src->set_attr_val.length;
+        if(src->set_attr_val.value){
+            dst->set_attr_val.value = (uint8_t *)GKI_getbuf(len);
+            if(dst->set_attr_val.value != NULL){
+                memcpy(dst->set_attr_val.value, src->set_attr_val.value, len);
+            }else{
+                LOG_ERROR("%s %d no mem\n",__func__, msg->act);
+            }
+        }
+        break;
     }
     }
     default:
     default:
         LOG_DEBUG("%s Unhandled deep copy %d\n", __func__, msg->act);
         LOG_DEBUG("%s Unhandled deep copy %d\n", __func__, msg->act);
@@ -91,6 +154,163 @@ void btc_gatts_arg_deep_free(btc_msg_t *msg)
 
 
 }
 }
 
 
+static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db, 
+                                                        esp_gatt_if_t gatts_if,
+                                                        uint8_t max_nb_attr,
+                                                        uint8_t srvc_inst_id)
+{
+    uint16_t uuid = 0;
+    future_t *future_p;
+    esp_ble_gatts_cb_param_t param;
+
+    //set the attribute table create service flag to ture 
+    btc_creat_tab_env.is_tab_creat_svc = true;
+    btc_creat_tab_env.num_handle = max_nb_attr;
+    for(int i = 0; i < max_nb_attr; i++){
+        if(gatts_attr_db[i].att_desc.uuid.len == ESP_UUID_LEN_16){
+            uuid = gatts_attr_db[i].att_desc.uuid.uuid.uuid16;
+        }
+        future_p = future_new();
+        if (future_p == NULL) {
+                LOG_ERROR("%s failed:no mem\n", __func__);
+                return ;
+            }
+        btc_creat_tab_env.complete_future = future_p;
+        btc_creat_tab_env.handle_idx = i;
+        switch(uuid)
+        {
+            case ESP_GATT_UUID_PRI_SERVICE:{
+                tBTA_GATT_SRVC_ID srvc_id;
+                esp_gatt_srvc_id_t        esp_srvc_id;
+
+                esp_srvc_id.id.inst_id = srvc_inst_id;
+                memcpy(&esp_srvc_id.id.uuid, &gatts_attr_db[i].att_desc.uuid, sizeof(esp_bt_uuid_t));
+                    btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
+                BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid, 
+                                        srvc_inst_id, max_nb_attr, true);
+                
+                 if (future_await(future_p) == FUTURE_FAIL) {
+                        LOG_ERROR("%s failed\n", __func__);
+                        return;
+                        }
+                    break;
+            }
+            case ESP_GATT_UUID_SEC_SERVICE:{
+                tBTA_GATT_SRVC_ID srvc_id;
+                esp_gatt_srvc_id_t        esp_srvc_id;
+
+                esp_srvc_id.id.inst_id = srvc_inst_id;
+                memcpy(&esp_srvc_id.id.uuid, &gatts_attr_db[i].att_desc.uuid, sizeof(esp_bt_uuid_t));
+                    btc_to_bta_srvc_id(&srvc_id, &esp_srvc_id);
+                BTA_GATTS_CreateService(gatts_if, &srvc_id.id.uuid, 
+                                        srvc_inst_id, max_nb_attr, false);
+                if (future_await(future_p) == FUTURE_FAIL) {
+                        LOG_ERROR("%s failed\n", __func__);
+                        return;
+                        }
+                break;
+            }
+            case ESP_GATT_UUID_INCLUDE_SERVICE:{
+                esp_gatts_incl_svc_desc_t *incl_svc_desc = (esp_gatts_incl_svc_desc_t *)gatts_attr_db[i].att_desc.value;
+                
+                if(incl_svc_desc!= NULL){
+                    if(btc_creat_tab_env.svc_start_hdl != 0){
+                        BTA_GATTS_AddIncludeService(btc_creat_tab_env.svc_start_hdl, 
+                            incl_svc_desc->start_hdl);
+                        
+                        if (future_await(future_p) == FUTURE_FAIL) {
+                                LOG_ERROR("%s failed\n", __func__);
+                                return;
+                            }
+                    }
+                }
+                break;
+            }
+            case ESP_GATT_UUID_CHAR_DECLARE:{
+                uint16_t svc_hal = 0;
+                tBT_UUID bta_char_uuid;
+                tGATT_ATTR_VAL attr_val;
+                tBTA_GATT_PERM perm;
+                tBTA_GATTS_ATTR_CONTROL control;
+
+                if(btc_creat_tab_env.svc_start_hdl != 0){
+                    svc_hal = btc_creat_tab_env.svc_start_hdl;
+                     esp_gatts_char_desc_t *char_desc = (esp_gatts_char_desc_t *)gatts_attr_db[i].att_desc.value;
+                    if(char_desc != NULL){
+                        perm = gatts_attr_db[i+1].att_desc.perm;
+                        attr_val.attr_len = gatts_attr_db[i+1].att_desc.length;
+                        attr_val.attr_max_len = gatts_attr_db[i+1].att_desc.max_length;
+                        btc_to_bta_uuid(&bta_char_uuid, &char_desc->attr_uuid);
+                        attr_val.attr_val = gatts_attr_db[i+1].att_desc.value;
+                        control.auto_rsp = gatts_attr_db[i+1].attr_control.auto_rsp;
+                        BTA_GATTS_AddCharacteristic (svc_hal, &bta_char_uuid,
+                                         perm, char_desc->prop, &attr_val, &control);
+
+                        if (future_await(future_p) == FUTURE_FAIL) {
+                                LOG_ERROR("%s failed\n", __func__);
+                                return;
+                                }
+                        }
+                }
+            
+                break;
+            }
+            case ESP_GATT_UUID_CHAR_EXT_PROP:               
+            case ESP_GATT_UUID_CHAR_DESCRIPTION:
+            case ESP_GATT_UUID_CHAR_CLIENT_CONFIG:
+            case ESP_GATT_UUID_CHAR_SRVR_CONFIG:
+            case ESP_GATT_UUID_CHAR_PRESENT_FORMAT:
+            case ESP_GATT_UUID_CHAR_AGG_FORMAT:
+            case ESP_GATT_UUID_CHAR_VALID_RANGE:
+            case ESP_GATT_UUID_EXT_RPT_REF_DESCR:
+            case ESP_GATT_UUID_RPT_REF_DESCR:{
+                uint16_t svc_hal = btc_creat_tab_env.svc_start_hdl;
+                tBT_UUID bta_char_uuid;
+                tGATT_ATTR_VAL attr_val;
+                tBTA_GATT_PERM perm = gatts_attr_db[i].att_desc.perm;
+                tBTA_GATTS_ATTR_CONTROL control;
+
+                if(svc_hal != 0){
+                    attr_val.attr_len = gatts_attr_db[i].att_desc.length;
+                    attr_val.attr_max_len = gatts_attr_db[i].att_desc.max_length;
+                    attr_val.attr_val = gatts_attr_db[i].att_desc.value;
+                    btc_to_bta_uuid(&bta_char_uuid, &gatts_attr_db[i].att_desc.uuid);
+                    control.auto_rsp = gatts_attr_db[i].attr_control.auto_rsp;
+                    BTA_GATTS_AddCharDescriptor(svc_hal, perm, &bta_char_uuid, &attr_val, &control);
+        
+                    if (future_await(future_p) == FUTURE_FAIL) {
+                        LOG_ERROR("%s failed\n", __func__);
+                        return;
+                        }
+                }
+                break;
+            }
+            default:
+                break;
+        }
+
+        
+    }
+
+    param.add_attr_tab.status = ESP_GATT_OK;
+    param.add_attr_tab.num_handle = max_nb_attr;
+    param.add_attr_tab.handles = btc_creat_tab_env.handles;
+    memcpy(&param.add_attr_tab.svc_uuid, &btc_creat_tab_env.svc_uuid, sizeof(esp_bt_uuid_t));
+
+    btc_gatts_cb_to_app(ESP_GATTS_CREAT_ATTR_TAB_EVT, gatts_if, &param);        
+    //reset the env after sent the data to app
+    memset(&btc_creat_tab_env, 0, sizeof(esp_btc_creat_tab_t));
+
+    //release the flag vaule to false after finish the service created.
+    btc_creat_tab_env.is_tab_creat_svc = false;
+}
+
+void btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value)
+{
+    
+    BTA_GetAttributeValue(attr_handle, length, value);
+}
+
 
 
 static void btc_gatts_cb_param_copy_req(btc_msg_t *msg, void *p_dest, void *p_src)
 static void btc_gatts_cb_param_copy_req(btc_msg_t *msg, void *p_dest, void *p_src)
 {
 {
@@ -137,7 +357,6 @@ static void btc_gatts_cb_param_copy_free(btc_msg_t *msg, tBTA_GATTS *p_data)
             GKI_freebuf(p_data->req_data.p_data);
             GKI_freebuf(p_data->req_data.p_data);
         }
         }
         break;
         break;
-
     default:
     default:
         break;
         break;
     }
     }
@@ -148,11 +367,43 @@ static void btc_gatts_inter_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
 {
 {
     bt_status_t status;
     bt_status_t status;
     btc_msg_t msg;
     btc_msg_t msg;
-
+    
     msg.sig = BTC_SIG_API_CB;
     msg.sig = BTC_SIG_API_CB;
     msg.pid = BTC_PID_GATTS;
     msg.pid = BTC_PID_GATTS;
     msg.act = event;
     msg.act = event;
+    if(btc_creat_tab_env.is_tab_creat_svc && btc_creat_tab_env.complete_future){
+        switch(event){
+            case BTA_GATTS_CREATE_EVT:{
+                //save the service handle to the btc module after used 
+                //the attribute table method to creat a service
+                bta_to_btc_uuid(&btc_creat_tab_env.svc_uuid, &p_data->create.uuid);
+                uint8_t index = btc_creat_tab_env.handle_idx;
+                btc_creat_tab_env.svc_start_hdl = p_data->create.service_id;
+                btc_creat_tab_env.handles[index] = p_data->create.service_id;
+                break;
+            }
+            case BTA_GATTS_ADD_INCL_SRVC_EVT:{
+                uint8_t index = btc_creat_tab_env.handle_idx;
+                btc_creat_tab_env.handles[index] = p_data->add_result.attr_id;
+                break;
+            }
+            case BTA_GATTS_ADD_CHAR_EVT:{
+                uint8_t index = btc_creat_tab_env.handle_idx;
+                btc_creat_tab_env.handles[index] = p_data->add_result.attr_id - 1;
+                btc_creat_tab_env.handles[index+1] = p_data->add_result.attr_id;
+                break;
+            }
+            case BTA_GATTS_ADD_CHAR_DESCR_EVT:{
+                uint8_t index = btc_creat_tab_env.handle_idx;
+                btc_creat_tab_env.handles[index] = p_data->add_result.attr_id;
+                break;
+            }
+            default:
+                break;
 
 
+        }
+        future_ready(btc_creat_tab_env.complete_future, FUTURE_SUCCESS);
+    }
     status = btc_transfer_context(&msg, p_data,
     status = btc_transfer_context(&msg, p_data,
                                   sizeof(tBTA_GATTS), btc_gatts_cb_param_copy_req);
                                   sizeof(tBTA_GATTS), btc_gatts_cb_param_copy_req);
 
 
@@ -187,6 +438,12 @@ void btc_gatts_call_handler(btc_msg_t *msg)
                                 srvc_id.is_primary);
                                 srvc_id.is_primary);
         break;
         break;
     }
     }
+   case BTC_GATTS_ACT_CREATE_ATTR_TAB:
+    btc_gatts_act_create_attr_tab(arg->create_attr_tab.gatts_attr_db,
+                                         arg->create_attr_tab.gatts_if,
+                                         arg->create_attr_tab.max_nb_attr,
+                                         arg->create_attr_tab.srvc_inst_id);
+    break;
     case BTC_GATTS_ACT_DELETE_SERVICE:
     case BTC_GATTS_ACT_DELETE_SERVICE:
         BTA_GATTS_DeleteService(arg->delete_srvc.service_handle);
         BTA_GATTS_DeleteService(arg->delete_srvc.service_handle);
         break;
         break;
@@ -204,13 +461,17 @@ void btc_gatts_call_handler(btc_msg_t *msg)
         btc_to_bta_uuid(&uuid, &arg->add_char.char_uuid);
         btc_to_bta_uuid(&uuid, &arg->add_char.char_uuid);
 
 
         BTA_GATTS_AddCharacteristic(arg->add_char.service_handle, &uuid,
         BTA_GATTS_AddCharacteristic(arg->add_char.service_handle, &uuid,
-                                    arg->add_char.perm, arg->add_char.property);
+                                    arg->add_char.perm, arg->add_char.property, 
+                                    (tGATT_ATTR_VAL *)&arg->add_char.char_val,
+                                    (tBTA_GATTS_ATTR_CONTROL *)&arg->add_char.attr_control);
         break;
         break;
     }
     }
     case BTC_GATTS_ACT_ADD_CHAR_DESCR: {
     case BTC_GATTS_ACT_ADD_CHAR_DESCR: {
         tBT_UUID uuid;
         tBT_UUID uuid;
         btc_to_bta_uuid(&uuid, &arg->add_descr.descr_uuid);
         btc_to_bta_uuid(&uuid, &arg->add_descr.descr_uuid);
-        BTA_GATTS_AddCharDescriptor(arg->add_descr.service_handle, arg->add_descr.perm, &uuid);
+        BTA_GATTS_AddCharDescriptor(arg->add_descr.service_handle, arg->add_descr.perm, &uuid,
+                                   (tBTA_GATT_ATTR_VAL *)&arg->add_descr.descr_val, 
+                                   (tBTA_GATTS_ATTR_CONTROL *)&arg->add_descr.attr_control);
         break;
         break;
     }
     }
     case BTC_GATTS_ACT_SEND_INDICATE:
     case BTC_GATTS_ACT_SEND_INDICATE:
@@ -236,6 +497,9 @@ void btc_gatts_call_handler(btc_msg_t *msg)
         btc_gatts_cb_to_app(ESP_GATTS_RESPONSE_EVT, BTC_GATT_GET_GATT_IF(arg->send_rsp.conn_id), &param);
         btc_gatts_cb_to_app(ESP_GATTS_RESPONSE_EVT, BTC_GATT_GET_GATT_IF(arg->send_rsp.conn_id), &param);
         break;
         break;
     }
     }
+    case BTC_GATTS_ACT_SET_ATTR_VALUE:
+    
+    break;
     case BTC_GATTS_ACT_OPEN: {
     case BTC_GATTS_ACT_OPEN: {
         // Ensure device is in inquiry database
         // Ensure device is in inquiry database
         tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
         tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
@@ -359,6 +623,7 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
         param.create.service_id.is_primary = p_data->create.is_primary;
         param.create.service_id.is_primary = p_data->create.is_primary;
         param.create.service_id.id.inst_id = p_data->create.svc_instance;
         param.create.service_id.id.inst_id = p_data->create.svc_instance;
         bta_to_btc_uuid(&param.create.service_id.id.uuid, &p_data->create.uuid);
         bta_to_btc_uuid(&param.create.service_id.id.uuid, &p_data->create.uuid);
+
         btc_gatts_cb_to_app(ESP_GATTS_CREATE_EVT, gatts_if, &param);
         btc_gatts_cb_to_app(ESP_GATTS_CREATE_EVT, gatts_if, &param);
         break;
         break;
     case BTA_GATTS_ADD_INCL_SRVC_EVT:
     case BTA_GATTS_ADD_INCL_SRVC_EVT:
@@ -391,6 +656,7 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
         gatts_if = p_data->srvc_oper.server_if;
         gatts_if = p_data->srvc_oper.server_if;
         param.del.status = p_data->srvc_oper.status;
         param.del.status = p_data->srvc_oper.status;
         param.del.service_handle = p_data->srvc_oper.service_id;
         param.del.service_handle = p_data->srvc_oper.service_id;
+
         btc_gatts_cb_to_app(ESP_GATTS_DELETE_EVT, gatts_if, &param);
         btc_gatts_cb_to_app(ESP_GATTS_DELETE_EVT, gatts_if, &param);
         break;
         break;
     case BTA_GATTS_START_EVT:
     case BTA_GATTS_START_EVT:
@@ -424,11 +690,11 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
         btc_gatts_cb_to_app(ESP_GATTS_DISCONNECT_EVT, gatts_if, &param);
         btc_gatts_cb_to_app(ESP_GATTS_DISCONNECT_EVT, gatts_if, &param);
         break;
         break;
     case BTA_GATTS_OPEN_EVT:
     case BTA_GATTS_OPEN_EVT:
-    // do nothing
+        // do nothing
     case BTA_GATTS_CANCEL_OPEN_EVT:
     case BTA_GATTS_CANCEL_OPEN_EVT:
-    // do nothing
+        // do nothing
     case BTA_GATTS_CLOSE_EVT:
     case BTA_GATTS_CLOSE_EVT:
-    // do nothing
+        // do nothing
     case BTA_GATTS_LISTEN_EVT:
     case BTA_GATTS_LISTEN_EVT:
         // do nothing
         // do nothing
         break;
         break;
@@ -438,6 +704,13 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
         param.congest.congested = p_data->congest.congested;
         param.congest.congested = p_data->congest.congested;
         btc_gatts_cb_to_app(ESP_GATTS_CONGEST_EVT, gatts_if, &param);
         btc_gatts_cb_to_app(ESP_GATTS_CONGEST_EVT, gatts_if, &param);
         break;
         break;
+    case BTA_GATTS_SET_ATTR_VAL_EVT:
+        gatts_if = p_data->attr_val.server_if;
+        param.set_attr_val.srvc_handle = p_data->attr_val.service_id;
+        param.set_attr_val.attr_handle = p_data->attr_val.attr_id;
+        param.set_attr_val.status = p_data->attr_val.status;
+        btc_gatts_cb_to_app(ESP_GATTS_SET_ATTR_VAL_EVT, gatts_if, &param);
+        break;
     default:
     default:
         // do nothing
         // do nothing
         break;
         break;

+ 36 - 1
components/bt/bluedroid/btc/profile/std/include/btc_gatts.h

@@ -24,6 +24,7 @@ typedef enum {
     BTC_GATTS_ACT_APP_REGISTER = 0,
     BTC_GATTS_ACT_APP_REGISTER = 0,
     BTC_GATTS_ACT_APP_UNREGISTER,
     BTC_GATTS_ACT_APP_UNREGISTER,
     BTC_GATTS_ACT_CREATE_SERVICE,
     BTC_GATTS_ACT_CREATE_SERVICE,
+    BTC_GATTS_ACT_CREATE_ATTR_TAB,
     BTC_GATTS_ACT_DELETE_SERVICE,
     BTC_GATTS_ACT_DELETE_SERVICE,
     BTC_GATTS_ACT_START_SERVICE,
     BTC_GATTS_ACT_START_SERVICE,
     BTC_GATTS_ACT_STOP_SERVICE,
     BTC_GATTS_ACT_STOP_SERVICE,
@@ -32,6 +33,7 @@ typedef enum {
     BTC_GATTS_ACT_ADD_CHAR_DESCR,
     BTC_GATTS_ACT_ADD_CHAR_DESCR,
     BTC_GATTS_ACT_SEND_INDICATE,
     BTC_GATTS_ACT_SEND_INDICATE,
     BTC_GATTS_ACT_SEND_RESPONSE,
     BTC_GATTS_ACT_SEND_RESPONSE,
+    BTC_GATTS_ACT_SET_ATTR_VALUE,
     BTC_GATTS_ACT_OPEN,
     BTC_GATTS_ACT_OPEN,
     BTC_GATTS_ACT_CLOSE,
     BTC_GATTS_ACT_CLOSE,
 } btc_gatts_act_t;
 } btc_gatts_act_t;
@@ -42,46 +44,67 @@ typedef union {
     struct app_reg_args {
     struct app_reg_args {
         uint16_t app_id;
         uint16_t app_id;
     } app_reg;
     } app_reg;
+
     //BTC_GATTS_ACT_APP_UNREGISTER,
     //BTC_GATTS_ACT_APP_UNREGISTER,
     struct app_unreg_args {
     struct app_unreg_args {
         esp_gatt_if_t gatts_if;
         esp_gatt_if_t gatts_if;
     } app_unreg;
     } app_unreg;
+
     //BTC_GATTS_ACT_CREATE_SERVICE,
     //BTC_GATTS_ACT_CREATE_SERVICE,
     struct create_srvc_args {
     struct create_srvc_args {
         esp_gatt_if_t gatts_if;
         esp_gatt_if_t gatts_if;
         esp_gatt_srvc_id_t service_id;
         esp_gatt_srvc_id_t service_id;
         uint16_t num_handle;
         uint16_t num_handle;
     } create_srvc;
     } create_srvc;
+
+    //BTC_GATTS_ACT_CREATE_ATTR_TAB
+    struct create_attr_tab_args{
+        esp_gatt_if_t gatts_if;
+        uint8_t srvc_inst_id;
+        uint8_t max_nb_attr;
+        esp_gatts_attr_db_t *gatts_attr_db;
+    }create_attr_tab;
+
     //BTC_GATTS_ACT_DELETE_SERVICE,
     //BTC_GATTS_ACT_DELETE_SERVICE,
     struct delete_srvc_args {
     struct delete_srvc_args {
         uint16_t service_handle;
         uint16_t service_handle;
     } delete_srvc;
     } delete_srvc;
+
     //BTC_GATTS_ACT_START_SERVICE,
     //BTC_GATTS_ACT_START_SERVICE,
     struct start_srvc_args {
     struct start_srvc_args {
         uint16_t service_handle;
         uint16_t service_handle;
     } start_srvc;
     } start_srvc;
+
     //BTC_GATTS_ACT_STOP_SERVICE,
     //BTC_GATTS_ACT_STOP_SERVICE,
     struct stop_srvc_args {
     struct stop_srvc_args {
         uint16_t service_handle;
         uint16_t service_handle;
     } stop_srvc;
     } stop_srvc;
+
     //BTC_GATTS_ACT_ADD_INCLUDE_SERVICE,
     //BTC_GATTS_ACT_ADD_INCLUDE_SERVICE,
     struct add_incl_srvc_args {
     struct add_incl_srvc_args {
         uint16_t service_handle;
         uint16_t service_handle;
         uint16_t included_service_handle;
         uint16_t included_service_handle;
     } add_incl_srvc;
     } add_incl_srvc;
+
     //BTC_GATTS_ACT_ADD_CHAR,
     //BTC_GATTS_ACT_ADD_CHAR,
     struct add_char_args {
     struct add_char_args {
         uint16_t service_handle;
         uint16_t service_handle;
         esp_bt_uuid_t char_uuid;
         esp_bt_uuid_t char_uuid;
         esp_gatt_perm_t perm;
         esp_gatt_perm_t perm;
         esp_gatt_char_prop_t property;
         esp_gatt_char_prop_t property;
+        esp_attr_control_t attr_control;
+        esp_attr_value_t char_val;
     } add_char;
     } add_char;
+
     //BTC_GATTS_ACT_ADD_CHAR_DESCR,
     //BTC_GATTS_ACT_ADD_CHAR_DESCR,
     struct add_descr_args {
     struct add_descr_args {
-        uint16_t service_handle;
+        uint16_t  service_handle;
         esp_bt_uuid_t descr_uuid;
         esp_bt_uuid_t descr_uuid;
         esp_gatt_perm_t perm;
         esp_gatt_perm_t perm;
+        esp_attr_control_t attr_control;
+        esp_attr_value_t descr_val;
     } add_descr;
     } add_descr;
+
     //BTC_GATTS_ACT_SEND_INDICATE,
     //BTC_GATTS_ACT_SEND_INDICATE,
     struct send_indicate_args {
     struct send_indicate_args {
         uint16_t conn_id;
         uint16_t conn_id;
@@ -90,6 +113,7 @@ typedef union {
         uint16_t value_len;
         uint16_t value_len;
         uint8_t *value;
         uint8_t *value;
     } send_ind;
     } send_ind;
+
     //BTC_GATTS_ACT_SEND_RESPONSE,
     //BTC_GATTS_ACT_SEND_RESPONSE,
     struct send_rsp_args {
     struct send_rsp_args {
         uint16_t conn_id;
         uint16_t conn_id;
@@ -97,21 +121,32 @@ typedef union {
         esp_gatt_status_t status;
         esp_gatt_status_t status;
         esp_gatt_rsp_t *rsp;
         esp_gatt_rsp_t *rsp;
     } send_rsp;
     } send_rsp;
+
+    //BTC_GATTS_SET_ATTR_VALUE
+    struct set_attr_val_args{
+        uint16_t length;
+        uint8_t *value;
+    } set_attr_val;
+
     //BTC_GATTS_ACT_OPEN,
     //BTC_GATTS_ACT_OPEN,
     struct open_args {
     struct open_args {
         esp_gatt_if_t gatts_if;
         esp_gatt_if_t gatts_if;
         esp_bd_addr_t remote_bda;
         esp_bd_addr_t remote_bda;
         bool is_direct;
         bool is_direct;
     } open;
     } open;
+
     //BTC_GATTS_ACT_CLOSE,
     //BTC_GATTS_ACT_CLOSE,
     struct close_args {
     struct close_args {
         uint16_t conn_id;
         uint16_t conn_id;
     } close;
     } close;
+
 } btc_ble_gatts_args_t;
 } btc_ble_gatts_args_t;
 
 
 
 
 void btc_gatts_call_handler(btc_msg_t *msg);
 void btc_gatts_call_handler(btc_msg_t *msg);
 void btc_gatts_cb_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_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);
+
 
 
 #endif /* __BTC_GATTS_H__ */
 #endif /* __BTC_GATTS_H__ */

+ 3 - 6
components/bt/bluedroid/hci/packet_fragmenter.c

@@ -150,13 +150,10 @@ static void reassemble_and_dispatch(BT_HDR *packet)
                 LOG_DEBUG("%s found unfinished packet for handle with start packet. Dropping old.\n", __func__);
                 LOG_DEBUG("%s found unfinished packet for handle with start packet. Dropping old.\n", __func__);
                 LOG_DEBUG("partial_packet->len = %x, offset = %x\n", partial_packet->len, partial_packet->len);
                 LOG_DEBUG("partial_packet->len = %x, offset = %x\n", partial_packet->len, partial_packet->len);
 
 
-                //for (int i = 0; i < partial_packet->len; i++) {
-                //    LOG_ERROR("%x", partial_packet->data[i]);
-                //}
-                //LOG_ERROR("\n");
+               
                 hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
                 hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
-                //buffer_allocator->free(partial_packet);
-                //LOG_ERROR("+++++++++++++++++++\n");
+               
+              
             }
             }
 
 
             uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;
             uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;

+ 8 - 4
components/bt/bluedroid/stack/gap/gap_ble.c

@@ -392,7 +392,8 @@ void gap_attr_db_init(void)
     */
     */
     uuid.len = LEN_UUID_16;
     uuid.len = LEN_UUID_16;
     uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_DEVICE_NAME;
     uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_DEVICE_NAME;
-    p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ);
+    p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ,
+											NULL, NULL);
     p_db_attr ++;
     p_db_attr ++;
 
 
     /* add Icon characteristic
     /* add Icon characteristic
@@ -401,7 +402,8 @@ void gap_attr_db_init(void)
     p_db_attr->handle = GATTS_AddCharacteristic(service_handle,
     p_db_attr->handle = GATTS_AddCharacteristic(service_handle,
                         &uuid,
                         &uuid,
                         GATT_PERM_READ,
                         GATT_PERM_READ,
-                        GATT_CHAR_PROP_BIT_READ);
+                        GATT_CHAR_PROP_BIT_READ,
+                        NULL, NULL);
     p_db_attr ++;
     p_db_attr ++;
 
 
 #if ((defined BTM_PERIPHERAL_ENABLED) && (BTM_PERIPHERAL_ENABLED == TRUE))
 #if ((defined BTM_PERIPHERAL_ENABLED) && (BTM_PERIPHERAL_ENABLED == TRUE))
@@ -416,7 +418,8 @@ void gap_attr_db_init(void)
     p_db_attr->handle = GATTS_AddCharacteristic(service_handle,
     p_db_attr->handle = GATTS_AddCharacteristic(service_handle,
                         &uuid,
                         &uuid,
                         GATT_PERM_READ,
                         GATT_PERM_READ,
-                        GATT_CHAR_PROP_BIT_READ);
+                        GATT_CHAR_PROP_BIT_READ,
+                        NULL, NULL);
     p_db_attr ++;
     p_db_attr ++;
 #endif
 #endif
 
 
@@ -424,7 +427,8 @@ void gap_attr_db_init(void)
     uuid.len = LEN_UUID_16;
     uuid.len = LEN_UUID_16;
     uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_CENTRAL_ADDR_RESOL;
     uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_CENTRAL_ADDR_RESOL;
     p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid,
     p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid,
-                        GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ);
+                        GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ,
+                        NULL, NULL);
     p_db_attr->attr_value.addr_resolution = 0;
     p_db_attr->attr_value.addr_resolution = 0;
     p_db_attr++;
     p_db_attr++;
 
 

+ 86 - 26
components/bt/bluedroid/stack/gatt/gatt_api.c

@@ -151,10 +151,10 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
     tBT_UUID     *p_app_uuid128;
     tBT_UUID     *p_app_uuid128;
 
 
 
 
-    GATT_TRACE_API ("GATTS_CreateService" );
+    GATT_TRACE_API ("GATTS_CreateService\n" );
 
 
     if (p_reg == NULL) {
     if (p_reg == NULL) {
-        GATT_TRACE_ERROR ("Inavlid gatt_if=%d", gatt_if);
+        GATT_TRACE_ERROR ("Inavlid gatt_if=%d\n", gatt_if);
         return (0);
         return (0);
     }
     }
 
 
@@ -162,7 +162,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
 
 
     if ((p_list = gatt_find_hdl_buffer_by_app_id(p_app_uuid128, p_svc_uuid, svc_inst)) != NULL) {
     if ((p_list = gatt_find_hdl_buffer_by_app_id(p_app_uuid128, p_svc_uuid, svc_inst)) != NULL) {
         s_hdl = p_list->asgn_range.s_handle;
         s_hdl = p_list->asgn_range.s_handle;
-        GATT_TRACE_DEBUG ("Service already been created!!");
+        GATT_TRACE_DEBUG ("Service already been created!!\n");
     } else {
     } else {
         if ( (p_svc_uuid->len == LEN_UUID_16) && (p_svc_uuid->uu.uuid16 == UUID_SERVCLASS_GATT_SERVER)) {
         if ( (p_svc_uuid->len == LEN_UUID_16) && (p_svc_uuid->uu.uuid16 == UUID_SERVCLASS_GATT_SERVER)) {
             s_hdl =  gatt_cb.hdl_cfg.gatt_start_hdl;
             s_hdl =  gatt_cb.hdl_cfg.gatt_start_hdl;
@@ -184,13 +184,13 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
 
 
         /* check for space */
         /* check for space */
         if (num_handles > (0xFFFF - s_hdl + 1)) {
         if (num_handles > (0xFFFF - s_hdl + 1)) {
-            GATT_TRACE_ERROR ("GATTS_ReserveHandles: no handles, s_hdl: %u  needed: %u", s_hdl, num_handles);
+            GATT_TRACE_ERROR ("GATTS_ReserveHandles: no handles, s_hdl: %u  needed: %u\n", s_hdl, num_handles);
             return (0);
             return (0);
         }
         }
 
 
         if ( (p_list = gatt_alloc_hdl_buffer()) == NULL) {
         if ( (p_list = gatt_alloc_hdl_buffer()) == NULL) {
             /* No free entry */
             /* No free entry */
-            GATT_TRACE_ERROR ("GATTS_ReserveHandles: no free handle blocks");
+            GATT_TRACE_ERROR ("GATTS_ReserveHandles: no free handle blocks\n");
             return (0);
             return (0);
         }
         }
 
 
@@ -210,7 +210,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
             /* add a pending new  service change item to the list */
             /* add a pending new  service change item to the list */
             if ( (p_buf = gatt_add_pending_new_srv_start(&p_list->asgn_range)) == NULL) {
             if ( (p_buf = gatt_add_pending_new_srv_start(&p_list->asgn_range)) == NULL) {
                 /* No free entry */
                 /* No free entry */
-                GATT_TRACE_ERROR ("gatt_add_pending_new_srv_start: no free blocks");
+                GATT_TRACE_ERROR ("gatt_add_pending_new_srv_start: no free blocks\n");
 
 
                 if (p_list) {
                 if (p_list) {
                     gatt_remove_an_item_from_list(p_list_info, p_list);
                     gatt_remove_an_item_from_list(p_list_info, p_list);
@@ -219,12 +219,12 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
                 return (0);
                 return (0);
             }
             }
 
 
-            GATT_TRACE_DEBUG ("Add a new srv chg item");
+            GATT_TRACE_DEBUG ("Add a new srv chg item\n");
         }
         }
     }
     }
 
 
     if (!gatts_init_service_db(&p_list->svc_db, p_svc_uuid, is_pri, s_hdl , num_handles)) {
     if (!gatts_init_service_db(&p_list->svc_db, p_svc_uuid, is_pri, s_hdl , num_handles)) {
-        GATT_TRACE_ERROR ("GATTS_ReserveHandles: service DB initialization failed");
+        GATT_TRACE_ERROR ("GATTS_ReserveHandles: service DB initialization failed\n");
         if (p_list) {
         if (p_list) {
             gatt_remove_an_item_from_list(p_list_info, p_list);
             gatt_remove_an_item_from_list(p_list_info, p_list);
             gatt_free_hdl_buffer(p_list);
             gatt_free_hdl_buffer(p_list);
@@ -236,12 +236,6 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
         return (0);
         return (0);
     }
     }
 
 
-    GATT_TRACE_DEBUG ("GATTS_CreateService(success): handles needed:%u s_hdl=%u e_hdl=%u %s[%x] is_primary=%d",
-                      num_handles, p_list->asgn_range.s_handle , p_list->asgn_range.e_handle,
-                      ((p_list->asgn_range.svc_uuid.len == 2) ? "uuid16" : "uuid128" ),
-                      p_list->asgn_range.svc_uuid.uu.uuid16,
-                      p_list->asgn_range.is_primary);
-
     return (s_hdl);
     return (s_hdl);
 }
 }
 
 
@@ -295,25 +289,27 @@ UINT16 GATTS_AddIncludeService (UINT16 service_handle, UINT16 include_svc_handle
 **
 **
 *******************************************************************************/
 *******************************************************************************/
 UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid,
 UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid,
-                                tGATT_PERM perm, tGATT_CHAR_PROP property)
+                                tGATT_PERM perm, tGATT_CHAR_PROP property, 
+                                tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
 {
 {
     tGATT_HDL_LIST_ELEM  *p_decl;
     tGATT_HDL_LIST_ELEM  *p_decl;
 
 
     if ((p_decl = gatt_find_hdl_buffer_by_handle(service_handle)) == NULL) {
     if ((p_decl = gatt_find_hdl_buffer_by_handle(service_handle)) == NULL) {
-        GATT_TRACE_DEBUG("Service not created");
+        GATT_TRACE_DEBUG("Service not created\n");
         return 0;
         return 0;
     }
     }
     /* data validity checking */
     /* data validity checking */
     if (  ((property & GATT_CHAR_PROP_BIT_AUTH) && !(perm & GATT_WRITE_SIGNED_PERM)) ||
     if (  ((property & GATT_CHAR_PROP_BIT_AUTH) && !(perm & GATT_WRITE_SIGNED_PERM)) ||
             ((perm & GATT_WRITE_SIGNED_PERM) && !(property & GATT_CHAR_PROP_BIT_AUTH)) ) {
             ((perm & GATT_WRITE_SIGNED_PERM) && !(property & GATT_CHAR_PROP_BIT_AUTH)) ) {
-        GATT_TRACE_DEBUG("Invalid configuration property=0x%x perm=0x%x ", property, perm);
+        GATT_TRACE_DEBUG("Invalid configuration property=0x%x perm=0x%x\n ", property, perm);
         return 0;
         return 0;
     }
     }
 
 
     return gatts_add_characteristic(&p_decl->svc_db,
     return gatts_add_characteristic(&p_decl->svc_db,
                                     perm,
                                     perm,
                                     property,
                                     property,
-                                    p_char_uuid);
+                                    p_char_uuid, 
+                                    attr_val, control);
 }
 }
 /*******************************************************************************
 /*******************************************************************************
 **
 **
@@ -336,7 +332,7 @@ UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid,
 *******************************************************************************/
 *******************************************************************************/
 UINT16 GATTS_AddCharDescriptor (UINT16 service_handle,
 UINT16 GATTS_AddCharDescriptor (UINT16 service_handle,
                                 tGATT_PERM perm,
                                 tGATT_PERM perm,
-                                tBT_UUID   *p_descr_uuid)
+                                tBT_UUID   *p_descr_uuid, tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
 {
 {
     tGATT_HDL_LIST_ELEM  *p_decl;
     tGATT_HDL_LIST_ELEM  *p_decl;
 
 
@@ -353,7 +349,8 @@ UINT16 GATTS_AddCharDescriptor (UINT16 service_handle,
 
 
     return gatts_add_char_descr(&p_decl->svc_db,
     return gatts_add_char_descr(&p_decl->svc_db,
                                 perm,
                                 perm,
-                                p_descr_uuid);
+                                p_descr_uuid,
+                                attr_val, control);
 
 
 }
 }
 /*******************************************************************************
 /*******************************************************************************
@@ -493,9 +490,9 @@ tGATT_STATUS GATTS_StartService (tGATT_IF gatt_if, UINT16 service_handle,
 
 
     gatt_add_a_srv_to_list(&gatt_cb.srv_list_info, &gatt_cb.srv_list[i_sreg]);
     gatt_add_a_srv_to_list(&gatt_cb.srv_list_info, &gatt_cb.srv_list[i_sreg]);
 
 
-    GATT_TRACE_DEBUG ("allocated i_sreg=%d ", i_sreg);
+    GATT_TRACE_DEBUG ("allocated i_sreg=%d\n", i_sreg);
 
 
-    GATT_TRACE_DEBUG ("s_hdl=%d e_hdl=%d type=0x%x svc_inst=%d sdp_hdl=0x%x",
+    GATT_TRACE_DEBUG ("s_hdl=%d e_hdl=%d type=0x%x svc_inst=%d sdp_hdl=0x%x\n",
                       p_sreg->s_hdl, p_sreg->e_hdl,
                       p_sreg->s_hdl, p_sreg->e_hdl,
                       p_sreg->type,  p_sreg->service_instance,
                       p_sreg->type,  p_sreg->service_instance,
                       p_sreg->sdp_handle);
                       p_sreg->sdp_handle);
@@ -676,16 +673,16 @@ tGATT_STATUS GATTS_SendRsp (UINT16 conn_id,  UINT32 trans_id,
     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
     tGATT_TCB       *p_tcb = gatt_get_tcb_by_idx(tcb_idx);
     tGATT_TCB       *p_tcb = gatt_get_tcb_by_idx(tcb_idx);
 
 
-    GATT_TRACE_API ("GATTS_SendRsp: conn_id: %u  trans_id: %u  Status: 0x%04x",
+    GATT_TRACE_API ("GATTS_SendRsp: conn_id: %u  trans_id: %u  Status: 0x%04x\n",
                     conn_id, trans_id, status);
                     conn_id, trans_id, status);
 
 
     if ( (p_reg == NULL) || (p_tcb == NULL)) {
     if ( (p_reg == NULL) || (p_tcb == NULL)) {
-        GATT_TRACE_ERROR ("GATTS_SendRsp Unknown  conn_id: %u ", conn_id);
+        GATT_TRACE_ERROR ("GATTS_SendRsp Unknown  conn_id: %u\n", conn_id);
         return (tGATT_STATUS) GATT_INVALID_CONN_ID;
         return (tGATT_STATUS) GATT_INVALID_CONN_ID;
     }
     }
 
 
     if (p_tcb->sr_cmd.trans_id != trans_id) {
     if (p_tcb->sr_cmd.trans_id != trans_id) {
-        GATT_TRACE_ERROR ("GATTS_SendRsp conn_id: %u  waiting for op_code = %02x",
+        GATT_TRACE_ERROR ("GATTS_SendRsp conn_id: %u  waiting for op_code = %02x\n",
                           conn_id, p_tcb->sr_cmd.op_code);
                           conn_id, p_tcb->sr_cmd.op_code);
 
 
         return (GATT_WRONG_STATE);
         return (GATT_WRONG_STATE);
@@ -696,6 +693,69 @@ tGATT_STATUS GATTS_SendRsp (UINT16 conn_id,  UINT32 trans_id,
     return cmd_sent;
     return cmd_sent;
 }
 }
 
 
+
+/*******************************************************************************
+**
+** Function         GATTS_SetAttributeValue
+**
+** Description      This function sends to set the attribute value .
+**
+** Parameter        attr_handle:the attribute handle
+**                  length: the attribute length
+**                  value: the value to be set to the attribute in the database
+**
+** Returns          GATT_SUCCESS if successfully sent; otherwise error code.
+**
+*******************************************************************************/
+tGATT_STATUS GATTS_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value)
+{
+    tGATT_STATUS status;
+    tGATT_HDL_LIST_ELEM  *p_decl = NULL;
+
+    GATT_TRACE_DEBUG("GATTS_SetAttributeValue: attr_handle: %u  length: %u \n",
+                    attr_handle, length);
+
+    if ((p_decl = gatt_find_hdl_buffer_by_attr_handle(attr_handle)) == NULL) {
+        GATT_TRACE_DEBUG("Service not created\n"); 
+        return GATT_INVALID_HANDLE;
+    }
+
+    status =  gatts_set_attribute_value(&p_decl->svc_db, attr_handle, length, value);
+    return status;
+
+}
+
+
+/*******************************************************************************
+**
+** Function         GATTS_GetAttributeValue
+**
+** Description      This function sends to set the attribute value .
+**
+** Parameter        attr_handle: the attribute handle
+**                  length:the attribute value length in the database
+**                  value: the attribute value out put
+**
+** Returns          GATT_SUCCESS if successfully sent; otherwise error code.
+**
+*******************************************************************************/
+tGATT_STATUS GATTS_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value)
+{
+     tGATT_STATUS status;
+     tGATT_HDL_LIST_ELEM  *p_decl;
+
+     GATT_TRACE_DEBUG("GATTS_GetAttributeValue: attr_handle: %u\n",
+                    attr_handle);
+
+     if ((p_decl = gatt_find_hdl_buffer_by_attr_handle(attr_handle)) == NULL) {
+         GATT_TRACE_ERROR("Service not created\n"); 
+         return GATT_INVALID_HANDLE;
+     }
+
+     status =  gatts_get_attribute_value(&p_decl->svc_db, attr_handle, length, value);
+     return status;
+}
+
 /*******************************************************************************/
 /*******************************************************************************/
 /* GATT Profile Srvr Functions */
 /* GATT Profile Srvr Functions */
 /*******************************************************************************/
 /*******************************************************************************/
@@ -1132,7 +1192,7 @@ tGATT_IF GATT_Register (tBT_UUID *p_app_uuid128, tGATT_CBACK *p_cb_info)
             break;
             break;
         }
         }
     }
     }
-    GATT_TRACE_API ("allocated gatt_if=%d", gatt_if);
+    GATT_TRACE_API ("allocated gatt_if=%d\n", gatt_if);
     return gatt_if;
     return gatt_if;
 }
 }
 
 

+ 7 - 4
components/bt/bluedroid/stack/gatt/gatt_attr.c

@@ -279,21 +279,24 @@ void gatt_profile_db_init (void)
     GATT_StartIf(gatt_cb.gatt_if);
     GATT_StartIf(gatt_cb.gatt_if);
 
 
     service_handle = GATTS_CreateService (gatt_cb.gatt_if , &uuid, 0, GATTP_MAX_ATTR_NUM, TRUE);
     service_handle = GATTS_CreateService (gatt_cb.gatt_if , &uuid, 0, GATTP_MAX_ATTR_NUM, TRUE);
+    GATT_TRACE_ERROR ("GATTS_CreateService:  handle of service handle%x", service_handle);
+	
     /* add Service Changed characteristic
     /* add Service Changed characteristic
     */
     */
     uuid.uu.uuid16 = gatt_cb.gattp_attr.uuid = GATT_UUID_GATT_SRV_CHGD;
     uuid.uu.uuid16 = gatt_cb.gattp_attr.uuid = GATT_UUID_GATT_SRV_CHGD;
     gatt_cb.gattp_attr.service_change = 0;
     gatt_cb.gattp_attr.service_change = 0;
     gatt_cb.gattp_attr.handle   =
     gatt_cb.gattp_attr.handle   =
-        gatt_cb.handle_of_h_r       = GATTS_AddCharacteristic(service_handle, &uuid, 0, GATT_CHAR_PROP_BIT_INDICATE);
+    gatt_cb.handle_of_h_r       = GATTS_AddCharacteristic(service_handle, &uuid, 0, GATT_CHAR_PROP_BIT_INDICATE,
+    												    NULL, NULL);
 
 
-    GATT_TRACE_DEBUG ("gatt_profile_db_init:  handle of service changed%d",
-                      gatt_cb.handle_of_h_r  );
+    GATT_TRACE_DEBUG ("gatt_profile_db_init:  handle of service changed%d\n",
+                      gatt_cb.handle_of_h_r);
 
 
     /* start service
     /* start service
     */
     */
     status = GATTS_StartService (gatt_cb.gatt_if, service_handle, GATTP_TRANSPORT_SUPPORTED );
     status = GATTS_StartService (gatt_cb.gatt_if, service_handle, GATTP_TRANSPORT_SUPPORTED );
 
 
-    GATT_TRACE_DEBUG ("gatt_profile_db_init:  gatt_if=%d   start status%d",
+    GATT_TRACE_DEBUG ("gatt_profile_db_init:  gatt_if=%d   start status%d\n",
                       gatt_cb.gatt_if,  status);
                       gatt_cb.gatt_if,  status);
 }
 }
 
 

+ 303 - 30
components/bt/bluedroid/stack/gatt/gatt_db.c

@@ -65,12 +65,12 @@ BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service,  BOOLEAN
     GKI_init_q(&p_db->svc_buffer);
     GKI_init_q(&p_db->svc_buffer);
 
 
     if (!allocate_svc_db_buf(p_db)) {
     if (!allocate_svc_db_buf(p_db)) {
-        GATT_TRACE_ERROR("gatts_init_service_db failed, no resources");
+        GATT_TRACE_ERROR("gatts_init_service_db failed, no resources\n");
         return FALSE;
         return FALSE;
     }
     }
 
 
-    GATT_TRACE_DEBUG("gatts_init_service_db");
-    GATT_TRACE_DEBUG("s_hdl = %d num_handle = %d", s_hdl, num_handle );
+    GATT_TRACE_DEBUG("gatts_init_service_db\n");
+    GATT_TRACE_DEBUG("s_hdl = %d num_handle = %d\n", s_hdl, num_handle );
 
 
     /* update service database information */
     /* update service database information */
     p_db->next_handle   = s_hdl;
     p_db->next_handle   = s_hdl;
@@ -94,7 +94,7 @@ BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service,  BOOLEAN
 tBT_UUID *gatts_get_service_uuid (tGATT_SVC_DB *p_db)
 tBT_UUID *gatts_get_service_uuid (tGATT_SVC_DB *p_db)
 {
 {
     if (!p_db || !p_db->p_attr_list) {
     if (!p_db || !p_db->p_attr_list) {
-        GATT_TRACE_ERROR("service DB empty");
+        GATT_TRACE_ERROR("service DB empty\n");
 
 
         return NULL;
         return NULL;
     } else {
     } else {
@@ -127,28 +127,28 @@ static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr,
     }
     }
 
 
     if (!(perm & GATT_READ_ALLOWED)) {
     if (!(perm & GATT_READ_ALLOWED)) {
-        GATT_TRACE_ERROR( "GATT_READ_NOT_PERMIT");
+        GATT_TRACE_ERROR( "GATT_READ_NOT_PERMIT\n");
         return GATT_READ_NOT_PERMIT;
         return GATT_READ_NOT_PERMIT;
     }
     }
 
 
     if ((perm & GATT_READ_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED) &&
     if ((perm & GATT_READ_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED) &&
             !(sec_flag & BTM_SEC_FLAG_ENCRYPTED)) {
             !(sec_flag & BTM_SEC_FLAG_ENCRYPTED)) {
-        GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION");
+        GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION\n");
         return GATT_INSUF_AUTHENTICATION;
         return GATT_INSUF_AUTHENTICATION;
     }
     }
 
 
     if ((perm & GATT_READ_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) {
     if ((perm & GATT_READ_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) {
-        GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION: MITM Required");
+        GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION: MITM Required\n");
         return GATT_INSUF_AUTHENTICATION;
         return GATT_INSUF_AUTHENTICATION;
     }
     }
 
 
     if ((perm & GATT_READ_ENCRYPTED_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) {
     if ((perm & GATT_READ_ENCRYPTED_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) {
-        GATT_TRACE_ERROR( "GATT_INSUF_ENCRYPTION");
+        GATT_TRACE_ERROR( "GATT_INSUF_ENCRYPTION\n");
         return GATT_INSUF_ENCRYPTION;
         return GATT_INSUF_ENCRYPTION;
     }
     }
 
 
     if ( (perm & GATT_READ_ENCRYPTED_REQUIRED) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size)) {
     if ( (perm & GATT_READ_ENCRYPTED_REQUIRED) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size)) {
-        GATT_TRACE_ERROR( "GATT_INSUF_KEY_SIZE");
+        GATT_TRACE_ERROR( "GATT_INSUF_KEY_SIZE\n");
         return GATT_INSUF_KEY_SIZE;
         return GATT_INSUF_KEY_SIZE;
     }
     }
 
 
@@ -163,7 +163,7 @@ static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr,
         case GATT_UUID_CHAR_CLIENT_CONFIG:
         case GATT_UUID_CHAR_CLIENT_CONFIG:
         case GATT_UUID_CHAR_SRVR_CONFIG:
         case GATT_UUID_CHAR_SRVR_CONFIG:
         case GATT_UUID_CHAR_PRESENT_FORMAT:
         case GATT_UUID_CHAR_PRESENT_FORMAT:
-            GATT_TRACE_ERROR("GATT_NOT_LONG");
+            GATT_TRACE_ERROR("GATT_NOT_LONG\n");
             return GATT_NOT_LONG;
             return GATT_NOT_LONG;
 
 
         default:
         default:
@@ -206,7 +206,7 @@ static tGATT_STATUS read_attr_value (void *p_attr,
     tGATT_STATUS    status;
     tGATT_STATUS    status;
     tGATT_ATTR16    *p_attr16  = (tGATT_ATTR16 *)p_attr;
     tGATT_ATTR16    *p_attr16  = (tGATT_ATTR16 *)p_attr;
 
 
-    GATT_TRACE_DEBUG("read_attr_value uuid=0x%04x perm=0x%0x sec_flag=0x%x offset=%d read_long=%d",
+    GATT_TRACE_DEBUG("read_attr_value uuid=0x%04x perm=0x%0x sec_flag=0x%x offset=%d read_long=%d\n",
                      p_attr16->uuid,
                      p_attr16->uuid,
                      p_attr16->permission,
                      p_attr16->permission,
                      sec_flag,
                      sec_flag,
@@ -268,7 +268,22 @@ static tGATT_STATUS read_attr_value (void *p_attr,
             status = GATT_SUCCESS;
             status = GATT_SUCCESS;
         }
         }
     } else { /* characteristic description or characteristic value */
     } else { /* characteristic description or characteristic value */
-        status = GATT_PENDING;
+        if (p_attr16->control.auto_rsp == GATT_RSP_BY_STACK) {
+            GATT_TRACE_DEBUG("before characteristic description or characteristic value\n");
+            if (p_attr16->p_value != NULL && p_attr16->p_value->attr_val.attr_val != NULL) {
+                uint8_t *value = p_attr16->p_value->attr_val.attr_val + offset;
+                GATT_TRACE_DEBUG("after characteristic description or characteristic value\n");
+                if (mtu >= p_attr16->p_value->attr_val.attr_len) {
+                    ARRAY_TO_STREAM(p, value, p_attr16->p_value->attr_val.attr_len);
+                } else {
+                    ARRAY_TO_STREAM(p, value, mtu);
+                }
+            }
+            status = GATT_STACK_RSP;
+
+        } else {
+            status = GATT_PENDING;
+        }
     }
     }
 
 
     *p_len = len;
     *p_len = len;
@@ -341,7 +356,7 @@ tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB   *p_tcb,
 
 
                 status = read_attr_value ((void *)p_attr, 0, &p, FALSE, (UINT16)(*p_len - 2), &len, sec_flag, key_size);
                 status = read_attr_value ((void *)p_attr, 0, &p, FALSE, (UINT16)(*p_len - 2), &len, sec_flag, key_size);
 
 
-                if (status == GATT_PENDING) {
+                if (status == GATT_PENDING || status == GATT_STACK_RSP) {
                     status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id);
                     status = gatts_send_app_read_request(p_tcb, op_code, p_attr->handle, 0, trans_id);
 
 
                     /* one callback at a time */
                     /* one callback at a time */
@@ -445,12 +460,12 @@ UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e
 *******************************************************************************/
 *******************************************************************************/
 UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
 UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
                                  tGATT_CHAR_PROP property,
                                  tGATT_CHAR_PROP property,
-                                 tBT_UUID *p_char_uuid)
+                                 tBT_UUID *p_char_uuid, tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
 {
 {
     tGATT_ATTR16     *p_char_decl, *p_char_val;
     tGATT_ATTR16     *p_char_decl, *p_char_val;
     tBT_UUID        uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}};
     tBT_UUID        uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}};
 
 
-    GATT_TRACE_DEBUG("gatts_add_characteristic perm=0x%0x property=0x%0x", perm, property);
+    GATT_TRACE_DEBUG("gatts_add_characteristic perm=0x%0x property=0x%0x\n", perm, property);
 
 
     if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL) {
     if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL) {
         if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL))) {
         if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL))) {
@@ -467,8 +482,30 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
 
 
         p_char_decl->p_value->char_decl.property = property;
         p_char_decl->p_value->char_decl.property = property;
         p_char_decl->p_value->char_decl.char_val_handle  = p_char_val->handle;
         p_char_decl->p_value->char_decl.char_val_handle  = p_char_val->handle;
+        if (control != NULL) {
+            p_char_val->control.auto_rsp  =  control->auto_rsp;
+        } else {
+            p_char_val->control.auto_rsp = GATT_RSP_DEFAULT;
 
 
-        p_char_val->p_value = NULL;
+        }
+
+        if (attr_val  != NULL) {
+            if (!copy_extra_byte_in_db(p_db, (void **)&p_char_val->p_value, sizeof(tGATT_ATTR_VAL))) {
+                deallocate_attr_in_db(p_db, p_char_val);
+                return 0;
+            }
+            GATT_TRACE_DEBUG("attr_val->attr_len = %x, attr_val->attr_max_len = %x\n", attr_val->attr_len, attr_val->attr_max_len);
+            GATT_TRACE_DEBUG("attribute handle = %x\n", p_char_val->handle);
+            p_char_val->p_value->attr_val.attr_len = attr_val->attr_len;
+            p_char_val->p_value->attr_val.attr_max_len = attr_val->attr_max_len;
+            p_char_val->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len);
+            if (p_char_val->p_value->attr_val.attr_val != NULL) {
+                GATT_TRACE_DEBUG("attribute value not NULL");
+                memcpy(p_char_val->p_value->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
+            }
+        } else {
+            p_char_val->p_value = NULL;
+        }
 
 
         return p_char_val->handle;
         return p_char_val->handle;
     }
     }
@@ -542,24 +579,221 @@ UINT8 gatt_convertchar_descr_type(tBT_UUID *p_descr_uuid)
 **
 **
 *******************************************************************************/
 *******************************************************************************/
 UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
 UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
-                             tBT_UUID      *p_descr_uuid)
+                             tBT_UUID  *p_descr_uuid,  tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
 {
 {
     tGATT_ATTR16    *p_char_dscptr;
     tGATT_ATTR16    *p_char_dscptr;
 
 
-    GATT_TRACE_DEBUG("gatts_add_char_descr uuid=0x%04x", p_descr_uuid->uu.uuid16);
+    GATT_TRACE_DEBUG("gatts_add_char_descr uuid=0x%04x\n", p_descr_uuid->uu.uuid16);
 
 
     /* Add characteristic descriptors */
     /* Add characteristic descriptors */
-    if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db,
-                         p_descr_uuid,
-                         perm))
-            == NULL) {
+    if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, p_descr_uuid, perm)) == NULL) {
         GATT_TRACE_DEBUG("gatts_add_char_descr Fail for adding char descriptors.");
         GATT_TRACE_DEBUG("gatts_add_char_descr Fail for adding char descriptors.");
         return 0;
         return 0;
     } else {
     } else {
+        if (control != NULL) {
+            p_char_dscptr->control.auto_rsp = control->auto_rsp;
+        }
+        if (attr_val != NULL) {
+            if (!copy_extra_byte_in_db(p_db, (void **)&p_char_dscptr->p_value, sizeof(tGATT_ATTR_VAL))) {
+                deallocate_attr_in_db(p_db, p_char_dscptr);
+                return 0;
+            }
+            p_char_dscptr->p_value->attr_val.attr_len = attr_val->attr_len;
+            p_char_dscptr->p_value->attr_val.attr_max_len  = attr_val->attr_max_len;
+            if (attr_val->attr_val != NULL) {
+                p_char_dscptr->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len);
+                if (p_char_dscptr->p_value->attr_val.attr_val != NULL) {
+                    memset(p_char_dscptr->p_value->attr_val.attr_val, 0, attr_val->attr_max_len);
+                    memcpy(p_char_dscptr->p_value->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
+                }
+            }
+        }
         return p_char_dscptr->handle;
         return p_char_dscptr->handle;
     }
     }
 }
 }
 
 
+
+/*******************************************************************************
+**
+** Function         gatts_set_attribute_value
+**
+** Description      This function add the attribute value in the database
+**
+** Parameter        p_db: database pointer.
+**                      attr_handle: the attribute handle
+**                      length: the attribute value length
+**                      value: the pointer to the data to be set to the attribute value in the database
+**
+** Returns          Status of the operation.
+**
+*******************************************************************************/
+tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
+                                       UINT16 length, UINT8 *value)
+{
+    tGATT_ATTR16  *p_cur, *p_next;
+
+    if (p_db == NULL) {
+        GATT_TRACE_DEBUG("gatts_set_attribute_value Fail:p_db is NULL.\n");
+        return GATT_INVALID_PDU;
+    }
+    if (p_db->p_attr_list == NULL) {
+        GATT_TRACE_DEBUG("gatts_set_attribute_value Fail:p_db->p_attr_list is NULL.\n");
+        return GATT_INVALID_PDU;
+    }
+
+    p_cur    =  (tGATT_ATTR16 *) p_db->p_attr_list;
+    p_next  = (tGATT_ATTR16 *) p_cur->p_next;
+
+
+    for (; p_cur != NULL; p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next) {
+        if (p_cur->handle == attr_handle) {
+            if (p_cur->uuid_type == GATT_ATTR_UUID_TYPE_16) {
+                switch (p_cur->uuid) {
+                case GATT_UUID_CHAR_DECLARE:
+                case GATT_UUID_INCLUDE_SERVICE:
+                    return GATT_NOT_FOUND;
+                default:
+                    if (p_cur->p_value->attr_val.attr_max_len < length) {
+                        GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length");
+                    } else {
+                        memcpy(p_cur->p_value->attr_val.attr_val, value, length);
+                        p_cur->p_value->attr_val.attr_len = length;
+                    }
+                    break;
+                }
+            } else {
+                if (p_cur->p_value->attr_val.attr_max_len < length) {
+                    GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length");
+                } else {
+                    memcpy(p_cur->p_value->attr_val.attr_val, value, length);
+                    p_cur->p_value->attr_val.attr_len = length;
+                }
+            }
+            break;
+        }
+    }
+
+    return GATT_SUCCESS;
+}
+
+
+/*******************************************************************************
+**
+** Function         gatts_get_attribute_value
+**
+** Description      This function get the attribute value in the database
+**
+** Parameter        p_db: database pointer.
+**                      attr_handle: the attribute handle
+**                      length: the attribute value length
+**                      value: the pointer to the data to be get to the attribute value in the database
+**
+** Returns          Status of the operation.
+**
+*******************************************************************************/
+tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
+                                       UINT16 *length, UINT8 **value)
+{
+    tGATT_ATTR16  *p_cur, *p_next;
+    GATT_TRACE_DEBUG("***********%s*************\n", __func__);
+    GATT_TRACE_DEBUG("attr_handle = %x\n", attr_handle);
+    if (p_db == NULL) {
+        GATT_TRACE_ERROR("gatts_get_attribute_value Fail:p_db is NULL.\n");
+        return GATT_INVALID_PDU;
+    }
+    if (p_db->p_attr_list == NULL) {
+        GATT_TRACE_ERROR("gatts_get_attribute_value Fail:p_db->p_attr_list is NULL.\n");
+        return GATT_INVALID_PDU;
+    }
+
+    p_cur    =  (tGATT_ATTR16 *) p_db->p_attr_list;
+    p_next  = (tGATT_ATTR16 *) p_cur->p_next;
+
+
+    for (; p_cur != NULL; p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next) {
+        LOG_ERROR("p_ur->handle = %x\n", p_cur->handle);
+        if (p_cur->handle == attr_handle) {
+
+            if (p_cur->uuid_type == GATT_ATTR_UUID_TYPE_16) {
+                switch (p_cur->uuid) {
+                case GATT_UUID_CHAR_DECLARE:
+                case GATT_UUID_INCLUDE_SERVICE:
+                    break;
+                default:
+                    if (p_cur->p_value->attr_val.attr_len != 0) {
+                        *length = p_cur->p_value->attr_val.attr_len;
+                        *value = p_cur->p_value->attr_val.attr_val;
+                        return GATT_SUCCESS;
+                    } else {
+                        GATT_TRACE_ERROR("gatts_get_attribute_vaule failt:the value length is 0");
+                        return GATT_INVALID_ATTR_LEN;
+                    }
+                    break;
+                }
+            } else {
+                if (p_cur->p_value->attr_val.attr_len != 0) {
+                    *length = p_cur->p_value->attr_val.attr_len;
+                    *value = p_cur->p_value->attr_val.attr_val;
+                    return GATT_SUCCESS;
+                } else {
+                    GATT_TRACE_ERROR("gatts_get_attribute_vaule failt:the value length is 0");
+                    return GATT_INVALID_ATTR_LEN;
+                }
+
+            }
+
+            break;
+
+        }
+
+
+    }
+
+    return GATT_SUCCESS;
+}
+
+BOOLEAN gatts_is_auto_response(UINT16 attr_handle)
+{
+    tGATT_HDL_LIST_ELEM  *p_decl = NULL;
+    BOOLEAN rsp = FALSE;
+    tGATT_SVC_DB *p_db = NULL;
+    if ((p_decl = gatt_find_hdl_buffer_by_attr_handle(attr_handle)) == NULL) {
+        GATT_TRACE_DEBUG("Service not created\n");
+        return rsp;
+    }
+
+    p_db = &p_decl->svc_db;
+
+    tGATT_ATTR16  *p_cur, *p_next;
+
+    if (p_db == NULL) {
+        GATT_TRACE_DEBUG("gatts_get_attribute_value Fail:p_db is NULL.\n");
+        return rsp;
+    }
+    if (p_db->p_attr_list == NULL) {
+        GATT_TRACE_DEBUG("gatts_get_attribute_value Fail:p_db->p_attr_list is NULL.\n");
+        return rsp;
+    }
+
+    p_cur    =  (tGATT_ATTR16 *) p_db->p_attr_list;
+    p_next  = (tGATT_ATTR16 *) p_cur->p_next;
+
+    for (; p_cur != NULL && p_next != NULL;
+            p_cur = p_next, p_next = (tGATT_ATTR16 *)p_next->p_next) {
+        if (p_cur->handle == attr_handle) {
+            if (p_cur->p_value != NULL && p_cur->control.auto_rsp == GATT_RSP_BY_STACK) {
+                rsp = true;
+                return rsp;
+            }
+
+        }
+
+    }
+
+    return rsp;
+
+}
+
 /*******************************************************************************/
 /*******************************************************************************/
 /* Service Attribute Database Query Utility Functions */
 /* Service Attribute Database Query Utility Functions */
 /*******************************************************************************/
 /*******************************************************************************/
@@ -617,6 +851,41 @@ tGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb,
     return status;
     return status;
 }
 }
 
 
+tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db,
+        UINT16 handle, UINT16 offset,
+        UINT8 *p_value, UINT16 len)
+{
+    tGATT_STATUS status = GATT_NOT_FOUND;
+    tGATT_ATTR16  *p_attr;
+
+    if (p_db && p_db->p_attr_list) {
+        p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
+
+        while (p_attr && handle >= p_attr->handle) {
+            if (p_attr->handle == handle ) {
+                if (p_attr->control.auto_rsp == GATT_RSP_BY_APP) {
+                    return GATT_APP_RSP;
+                }
+
+                if (p_attr->p_value != NULL && (p_attr->p_value->attr_val.attr_max_len >
+                                                offset + len)) {
+                    memcpy(p_attr->p_value->attr_val.attr_val + offset, p_value, len);
+                    p_attr->p_value->attr_val.attr_len = len + offset;
+                    return GATT_SUCCESS;
+                } else {
+                    return GATT_NOT_LONG;
+                }
+            }
+
+            p_attr = (tGATT_ATTR16 *)p_attr->p_next;
+
+        }
+
+    }
+
+    return status;
+}
+
 /*******************************************************************************
 /*******************************************************************************
 **
 **
 ** Function         gatts_read_attr_perm_check
 ** Function         gatts_read_attr_perm_check
@@ -661,6 +930,8 @@ tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db,
 
 
     return status;
     return status;
 }
 }
+
+
 /*******************************************************************************
 /*******************************************************************************
 **
 **
 ** Function         gatts_write_attr_perm_check
 ** Function         gatts_write_attr_perm_check
@@ -835,7 +1106,7 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PER
     UINT16      len = sizeof(tGATT_ATTR128);
     UINT16      len = sizeof(tGATT_ATTR128);
 
 
     if (p_uuid == NULL) {
     if (p_uuid == NULL) {
-        GATT_TRACE_ERROR("illegal UUID");
+        GATT_TRACE_ERROR("illegal UUID\n");
         return NULL;
         return NULL;
     }
     }
 
 
@@ -845,17 +1116,17 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PER
         len = sizeof(tGATT_ATTR32);
         len = sizeof(tGATT_ATTR32);
     }
     }
 
 
-    GATT_TRACE_DEBUG("allocate attr %d bytes ", len);
+    GATT_TRACE_DEBUG("allocate attr %d bytes\n", len);
 
 
     if (p_db->end_handle <= p_db->next_handle) {
     if (p_db->end_handle <= p_db->next_handle) {
-        GATT_TRACE_DEBUG("handle space full. handle_max = %d next_handle = %d",
+        GATT_TRACE_DEBUG("handle space full. handle_max = %d next_handle = %d\n",
                          p_db->end_handle, p_db->next_handle);
                          p_db->end_handle, p_db->next_handle);
         return NULL;
         return NULL;
     }
     }
 
 
     if (p_db->mem_free < len) {
     if (p_db->mem_free < len) {
         if (!allocate_svc_db_buf(p_db)) {
         if (!allocate_svc_db_buf(p_db)) {
-            GATT_TRACE_ERROR("allocate_attr_in_db failed, no resources");
+            GATT_TRACE_ERROR("allocate_attr_in_db failed, no resources\n");
             return NULL;
             return NULL;
         }
         }
     }
     }
@@ -896,19 +1167,21 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PER
     }
     }
 
 
     if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) {
     if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) {
-        GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x ",
+        GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x\n",
                          p_attr16->handle, p_attr16->uuid, p_attr16->permission);
                          p_attr16->handle, p_attr16->uuid, p_attr16->permission);
     } else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32) {
     } else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32) {
-        GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x ",
+        GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x\n",
                          p_attr32->handle, p_attr32->uuid, p_attr32->permission);
                          p_attr32->handle, p_attr32->uuid, p_attr32->permission);
     } else {
     } else {
-        GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x ",
+        GATT_TRACE_DEBUG("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x\n",
                          p_attr128->handle, p_attr128->uuid[0], p_attr128->uuid[1],
                          p_attr128->handle, p_attr128->uuid[0], p_attr128->uuid[1],
                          p_attr128->permission);
                          p_attr128->permission);
     }
     }
     return (void *)p_attr16;
     return (void *)p_attr16;
 }
 }
 
 
+
+
 /*******************************************************************************
 /*******************************************************************************
 **
 **
 ** Function         deallocate_attr_in_db
 ** Function         deallocate_attr_in_db
@@ -974,7 +1247,7 @@ static BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 le
 
 
     if (p_db->mem_free < len) {
     if (p_db->mem_free < len) {
         if (!allocate_svc_db_buf(p_db)) {
         if (!allocate_svc_db_buf(p_db)) {
-            GATT_TRACE_ERROR("copy_extra_byte_in_db failed, no resources");
+            GATT_TRACE_ERROR("copy_extra_byte_in_db failed, no resources\n");
             return FALSE;
             return FALSE;
         }
         }
     }
     }

+ 3 - 3
components/bt/bluedroid/stack/gatt/gatt_main.c

@@ -508,7 +508,7 @@ static void gatt_le_data_ind (UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf)
         GKI_freebuf (p_buf);
         GKI_freebuf (p_buf);
 
 
         if (p_tcb != NULL) {
         if (p_tcb != NULL) {
-            GATT_TRACE_WARNING ("ATT - Ignored L2CAP data while in state: %d",
+            GATT_TRACE_WARNING ("ATT - Ignored L2CAP data while in state: %d\n",
                                 gatt_get_ch_state(p_tcb));
                                 gatt_get_ch_state(p_tcb));
         }
         }
     }
     }
@@ -906,10 +906,10 @@ void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf)
                 }
                 }
             }
             }
         } else {
         } else {
-            GATT_TRACE_ERROR ("ATT - Rcvd L2CAP data, unknown cmd: 0x%x", op_code);
+            GATT_TRACE_ERROR ("ATT - Rcvd L2CAP data, unknown cmd: 0x%x\n", op_code);
         }
         }
     } else {
     } else {
-        GATT_TRACE_ERROR ("invalid data length, ignore");
+        GATT_TRACE_ERROR ("invalid data length, ignore\n");
     }
     }
 
 
     GKI_freebuf (p_buf);
     GKI_freebuf (p_buf);

+ 61 - 35
components/bt/bluedroid/stack/gatt/gatt_sr.c

@@ -239,7 +239,7 @@ tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if,
     tGATT_STATUS    ret_code = GATT_SUCCESS;
     tGATT_STATUS    ret_code = GATT_SUCCESS;
     UNUSED(trans_id);
     UNUSED(trans_id);
 
 
-    GATT_TRACE_DEBUG("gatt_sr_process_app_rsp gatt_if=%d", gatt_if);
+    GATT_TRACE_DEBUG("gatt_sr_process_app_rsp gatt_if=%d\n", gatt_if);
 
 
     gatt_sr_update_cback_cnt(p_tcb, gatt_if, FALSE, FALSE);
     gatt_sr_update_cback_cnt(p_tcb, gatt_if, FALSE, FALSE);
 
 
@@ -264,7 +264,7 @@ tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if,
             if (p_tcb->sr_cmd.p_rsp_msg == NULL) {
             if (p_tcb->sr_cmd.p_rsp_msg == NULL) {
                 p_tcb->sr_cmd.p_rsp_msg = attp_build_sr_msg (p_tcb, (UINT8)(op_code + 1), (tGATT_SR_MSG *)p_msg);
                 p_tcb->sr_cmd.p_rsp_msg = attp_build_sr_msg (p_tcb, (UINT8)(op_code + 1), (tGATT_SR_MSG *)p_msg);
             } else {
             } else {
-                GATT_TRACE_ERROR("Exception!!! already has respond message");
+                GATT_TRACE_ERROR("Exception!!! already has respond message\n");
             }
             }
         }
         }
     }
     }
@@ -279,7 +279,7 @@ tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if,
         gatt_dequeue_sr_cmd(p_tcb);
         gatt_dequeue_sr_cmd(p_tcb);
     }
     }
 
 
-    GATT_TRACE_DEBUG("gatt_sr_process_app_rsp ret_code=%d", ret_code);
+    GATT_TRACE_DEBUG("gatt_sr_process_app_rsp ret_code=%d\n", ret_code);
 
 
     return ret_code;
     return ret_code;
 }
 }
@@ -371,7 +371,7 @@ void gatt_process_read_multi_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U
 
 
 #if GATT_CONFORMANCE_TESTING == TRUE
 #if GATT_CONFORMANCE_TESTING == TRUE
     if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
     if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
-        GATT_TRACE_DEBUG("Conformance tst: forced err rspvofr ReadMultiple: error status=%d", gatt_cb.err_status);
+        GATT_TRACE_DEBUG("Conformance tst: forced err rspvofr ReadMultiple: error status=%d\n", gatt_cb.err_status);
 
 
         STREAM_TO_UINT16(handle, p);
         STREAM_TO_UINT16(handle, p);
 
 
@@ -871,7 +871,7 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data)
 **                  - discover characteristic by UUID
 **                  - discover characteristic by UUID
 **                  - relationship discovery
 **                  - relationship discovery
 **
 **
-** Returns          void
+** Returns          void 
 **
 **
 *******************************************************************************/
 *******************************************************************************/
 void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data)
 void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data)
@@ -889,10 +889,10 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
     tGATT_SRV_LIST_ELEM  *p_srv = NULL;
     tGATT_SRV_LIST_ELEM  *p_srv = NULL;
 
 
     reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl);
     reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl);
-
+    GATT_TRACE_DEBUG("%s, op_code =%x, len = %x\n", __func__, op_code, len);
 #if GATT_CONFORMANCE_TESTING == TRUE
 #if GATT_CONFORMANCE_TESTING == TRUE
     if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
     if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
-        GATT_TRACE_DEBUG("Conformance tst: forced err rsp for ReadByType: error status=%d", gatt_cb.err_status);
+        GATT_TRACE_DEBUG("Conformance tst: forced err rsp for ReadByType: error status=%d\n", gatt_cb.err_status);
 
 
         gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, s_hdl, FALSE);
         gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, s_hdl, FALSE);
 
 
@@ -902,7 +902,7 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
 
 
     if (reason == GATT_SUCCESS) {
     if (reason == GATT_SUCCESS) {
         if ((p_msg =  (BT_HDR *)GKI_getbuf(msg_len)) == NULL) {
         if ((p_msg =  (BT_HDR *)GKI_getbuf(msg_len)) == NULL) {
-            GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.");
+            GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.\n");
 
 
             reason = GATT_NO_RESOURCES;
             reason = GATT_NO_RESOURCES;
         } else {
         } else {
@@ -959,7 +959,7 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
             p_msg->offset   = L2CAP_MIN_OFFSET;
             p_msg->offset   = L2CAP_MIN_OFFSET;
         }
         }
     }
     }
-    if (reason != GATT_SUCCESS) {
+    if (reason != GATT_SUCCESS && reason != GATT_STACK_RSP) {
         if (p_msg) {
         if (p_msg) {
             GKI_freebuf(p_msg);
             GKI_freebuf(p_msg);
         }
         }
@@ -987,19 +987,32 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
 void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
 void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
                               UINT8 op_code, UINT16 len, UINT8 *p_data)
                               UINT8 op_code, UINT16 len, UINT8 *p_data)
 {
 {
-    tGATTS_DATA     sr_data;
-    UINT32          trans_id;
-    tGATT_STATUS    status;
-    UINT8           sec_flag, key_size, *p = p_data;
-    tGATT_SR_REG    *p_sreg;
-    UINT16          conn_id;
-
+    UINT16          		buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
+    tGATTS_DATA     	sr_data;
+    UINT32          		trans_id;
+    tGATT_STATUS    	status;
+    UINT8           		sec_flag, key_size, *p = p_data, *p_m;
+    tGATT_SR_REG    	*p_sreg;
+    UINT16          		conn_id, offset = 0;
+    BT_HDR          		*p_msg = NULL;
     memset(&sr_data, 0, sizeof(tGATTS_DATA));
     memset(&sr_data, 0, sizeof(tGATTS_DATA));
 
 
+    if ((p_msg =  (BT_HDR *)GKI_getbuf(buf_len)) == NULL) {
+        GATT_TRACE_ERROR("gatts_process_write_req failed. no resources.\n");
+    }
+
+    memset(p_msg, 0, buf_len);
+    p_m = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET;
+    *p_m ++ = op_code + 1;
+    p_msg->len = 1;
+    buf_len = p_tcb->payload_size - 1;
+    
     switch (op_code) {
     switch (op_code) {
     case GATT_REQ_PREPARE_WRITE:
     case GATT_REQ_PREPARE_WRITE:
         sr_data.write_req.is_prep = TRUE;
         sr_data.write_req.is_prep = TRUE;
         STREAM_TO_UINT16(sr_data.write_req.offset, p);
         STREAM_TO_UINT16(sr_data.write_req.offset, p);
+	    UINT16_TO_STREAM(p_m, sr_data.write_req.is_prep);
+	    offset = sr_data.write_req.offset;
         len -= 2;
         len -= 2;
     /* fall through */
     /* fall through */
     case GATT_SIGN_CMD_WRITE:
     case GATT_SIGN_CMD_WRITE:
@@ -1012,11 +1025,16 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
     case GATT_REQ_WRITE:
     case GATT_REQ_WRITE:
         if (op_code == GATT_REQ_WRITE || op_code == GATT_REQ_PREPARE_WRITE) {
         if (op_code == GATT_REQ_WRITE || op_code == GATT_REQ_PREPARE_WRITE) {
             sr_data.write_req.need_rsp = TRUE;
             sr_data.write_req.need_rsp = TRUE;
+	     if(op_code == GATT_REQ_PREPARE_WRITE){
+			memcpy(p_m, p, len);
+			p_msg->len += len;
+		 }
         }
         }
         sr_data.write_req.handle = handle;
         sr_data.write_req.handle = handle;
         sr_data.write_req.len = len;
         sr_data.write_req.len = len;
         if (len != 0 && p != NULL) {
         if (len != 0 && p != NULL) {
             memcpy (sr_data.write_req.value, p, len);
             memcpy (sr_data.write_req.value, p, len);
+	     
         }
         }
         break;
         break;
     }
     }
@@ -1035,18 +1053,26 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
                                           sec_flag,
                                           sec_flag,
                                           key_size);
                                           key_size);
 
 
+    p_msg->len += len;
     if (status == GATT_SUCCESS) {
     if (status == GATT_SUCCESS) {
         if ((trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle)) != 0) {
         if ((trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle)) != 0) {
             p_sreg = &gatt_cb.sr_reg[i_rcb];
             p_sreg = &gatt_cb.sr_reg[i_rcb];
             conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if);
             conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if);
+	     status = gatts_write_attr_value_by_handle(gatt_cb.sr_reg[i_rcb].p_db,
+		 							    handle, offset, p, len);
             gatt_sr_send_req_callback(conn_id,
             gatt_sr_send_req_callback(conn_id,
                                       trans_id,
                                       trans_id,
                                       GATTS_REQ_TYPE_WRITE,
                                       GATTS_REQ_TYPE_WRITE,
                                       &sr_data);
                                       &sr_data);
-
-            status = GATT_PENDING;
+		
+		if(status == GATT_SUCCESS){
+			attp_send_sr_msg(p_tcb, p_msg);
+		}else if(status == GATT_NOT_LONG){
+			gatt_send_error_rsp (p_tcb, status, op_code, handle, FALSE);
+		}
+             status = GATT_PENDING;
         } else {
         } else {
-            GATT_TRACE_ERROR("max pending command, send error");
+            GATT_TRACE_ERROR("max pending command, send error\n");
             status = GATT_BUSY; /* max pending command, application error */
             status = GATT_BUSY; /* max pending command, application error */
         }
         }
     }
     }
@@ -1072,15 +1098,15 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
 static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 op_code,
 static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 op_code,
                                    UINT16 handle, UINT16 len, UINT8 *p_data)
                                    UINT16 handle, UINT16 len, UINT8 *p_data)
 {
 {
-    UINT16          buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
-    tGATT_STATUS    reason;
-    BT_HDR          *p_msg = NULL;
-    UINT8           sec_flag, key_size, *p;
-    UINT16          offset = 0, value_len = 0;
+    UINT16       buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
+    tGATT_STATUS reason;
+    BT_HDR       *p_msg = NULL;
+    UINT8        sec_flag, key_size, *p;
+    UINT16       offset = 0, value_len = 0;
 
 
     UNUSED (len);
     UNUSED (len);
     if ((p_msg =  (BT_HDR *)GKI_getbuf(buf_len)) == NULL) {
     if ((p_msg =  (BT_HDR *)GKI_getbuf(buf_len)) == NULL) {
-        GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.");
+        GATT_TRACE_ERROR("gatts_process_find_info failed. no resources.\n");
 
 
         reason = GATT_NO_RESOURCES;
         reason = GATT_NO_RESOURCES;
     } else {
     } else {
@@ -1114,13 +1140,13 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8
         p_msg->len += value_len;
         p_msg->len += value_len;
     }
     }
 
 
-    if (reason != GATT_SUCCESS) {
+    if (reason != GATT_SUCCESS && reason != GATT_PENDING) {
         if (p_msg) {
         if (p_msg) {
             GKI_freebuf(p_msg);
             GKI_freebuf(p_msg);
         }
         }
 
 
         /* in theroy BUSY is not possible(should already been checked), protected check */
         /* in theroy BUSY is not possible(should already been checked), protected check */
-        if (reason != GATT_PENDING && reason != GATT_BUSY) {
+        if (reason != GATT_BUSY) {
             gatt_send_error_rsp (p_tcb, reason, op_code, handle, FALSE);
             gatt_send_error_rsp (p_tcb, reason, op_code, handle, FALSE);
         }
         }
     } else {
     } else {
@@ -1149,7 +1175,7 @@ void gatts_process_attribute_req (tGATT_TCB *p_tcb, UINT8 op_code,
     tGATT_ATTR16    *p_attr;
     tGATT_ATTR16    *p_attr;
 
 
     if (len < 2) {
     if (len < 2) {
-        GATT_TRACE_ERROR("Illegal PDU length, discard request");
+        GATT_TRACE_ERROR("Illegal PDU length, discard request\n");
         status = GATT_INVALID_PDU;
         status = GATT_INVALID_PDU;
     } else {
     } else {
         STREAM_TO_UINT16(handle, p);
         STREAM_TO_UINT16(handle, p);
@@ -1159,7 +1185,7 @@ void gatts_process_attribute_req (tGATT_TCB *p_tcb, UINT8 op_code,
 #if GATT_CONFORMANCE_TESTING == TRUE
 #if GATT_CONFORMANCE_TESTING == TRUE
     gatt_cb.handle = handle;
     gatt_cb.handle = handle;
     if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
     if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
-        GATT_TRACE_DEBUG("Conformance tst: forced err rsp: error status=%d", gatt_cb.err_status);
+        GATT_TRACE_DEBUG("Conformance tst: forced err rsp: error status=%d\n", gatt_cb.err_status);
 
 
         gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, handle, FALSE);
         gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, handle, FALSE);
 
 
@@ -1350,24 +1376,24 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code,
         /* otherwise, ignore the pkt */
         /* otherwise, ignore the pkt */
     } else {
     } else {
         switch (op_code) {
         switch (op_code) {
-        case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */
-        case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */
+        case GATT_REQ_READ_BY_GRP_TYPE: 		/* discover primary services */
+        case GATT_REQ_FIND_TYPE_VALUE: 			/* discover service by UUID */
             gatts_process_primary_service_req (p_tcb, op_code, len, p_data);
             gatts_process_primary_service_req (p_tcb, op_code, len, p_data);
             break;
             break;
 
 
-        case GATT_REQ_FIND_INFO:/* discover char descrptor */
+        case GATT_REQ_FIND_INFO:				/* discover char descrptor */
             gatts_process_find_info(p_tcb, op_code, len, p_data);
             gatts_process_find_info(p_tcb, op_code, len, p_data);
             break;
             break;
 
 
-        case GATT_REQ_READ_BY_TYPE: /* read characteristic value, char descriptor value */
+        case GATT_REQ_READ_BY_TYPE: 			/* read characteristic value, char descriptor value */
             /* discover characteristic, discover char by UUID */
             /* discover characteristic, discover char by UUID */
             gatts_process_read_by_type_req(p_tcb, op_code, len, p_data);
             gatts_process_read_by_type_req(p_tcb, op_code, len, p_data);
             break;
             break;
 
 
 
 
-        case GATT_REQ_READ: /* read char/char descriptor value */
+        case GATT_REQ_READ: 					/* read char/char descriptor value */
         case GATT_REQ_READ_BLOB:
         case GATT_REQ_READ_BLOB:
-        case GATT_REQ_WRITE: /* write char/char descriptor value */
+        case GATT_REQ_WRITE: 					/* write char/char descriptor value */
         case GATT_CMD_WRITE:
         case GATT_CMD_WRITE:
         case GATT_SIGN_CMD_WRITE:
         case GATT_SIGN_CMD_WRITE:
         case GATT_REQ_PREPARE_WRITE:
         case GATT_REQ_PREPARE_WRITE:

+ 29 - 1
components/bt/bluedroid/stack/gatt/gatt_utils.c

@@ -318,6 +318,34 @@ tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle)
     }
     }
     return NULL;
     return NULL;
 }
 }
+
+/*******************************************************************************
+**
+** Function     gatt_find_hdl_buffer_by_attr_handle
+**
+** Description  Find handle range buffer by attribute handle.
+**
+** Returns    Pointer to the buffer, NULL no buffer available
+**
+*******************************************************************************/
+tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_attr_handle(UINT16 attr_handle)
+{
+    tGATT_HDL_LIST_INFO *p_list_info = &gatt_cb.hdl_list_info;
+    tGATT_HDL_LIST_ELEM      *p_list = NULL;
+
+    p_list = p_list_info->p_first;
+
+    while (p_list != NULL) {
+        if (p_list->in_use && (p_list->asgn_range.s_handle <= attr_handle) 
+			&& (p_list->asgn_range.e_handle >= attr_handle)) {
+            return (p_list);
+        }
+        p_list = p_list->p_next;
+    }
+    return NULL;
+}
+
+
 /*******************************************************************************
 /*******************************************************************************
 **
 **
 ** Function     gatt_find_hdl_buffer_by_app_id
 ** Function     gatt_find_hdl_buffer_by_app_id
@@ -1476,7 +1504,7 @@ tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if)
     p_reg = &gatt_cb.cl_rcb[ii - 1];
     p_reg = &gatt_cb.cl_rcb[ii - 1];
 
 
     if (!p_reg->in_use) {
     if (!p_reg->in_use) {
-        GATT_TRACE_WARNING("gatt_if found but not in use.");
+        GATT_TRACE_WARNING("gatt_if found but not in use.\n");
         return NULL;
         return NULL;
     }
     }
 
 

+ 69 - 51
components/bt/bluedroid/stack/gatt/include/gatt_int.h

@@ -35,7 +35,10 @@
 #define GATT_GET_GATT_IF(conn_id)  ((tGATT_IF)((UINT8) (conn_id)))
 #define GATT_GET_GATT_IF(conn_id)  ((tGATT_IF)((UINT8) (conn_id)))
 
 
 #define GATT_GET_SR_REG_PTR(index) (&gatt_cb.sr_reg[(UINT8) (index)]);
 #define GATT_GET_SR_REG_PTR(index) (&gatt_cb.sr_reg[(UINT8) (index)]);
-#define GATT_TRANS_ID_MAX                   0x0fffffff      /* 4 MSB is reserved */
+#define GATT_TRANS_ID_MAX          0x0fffffff      /* 4 MSB is reserved */
+#define GATT_RSP_BY_APP            0x00
+#define GATT_RSP_BY_STACK          0x01
+#define GATT_RSP_DEFAULT           GATT_RSP_BY_APP          //need to rsp by the app.
 
 
 /* security action for GATT write and read request */
 /* security action for GATT write and read request */
 #define GATT_SEC_NONE              0
 #define GATT_SEC_NONE              0
@@ -61,16 +64,16 @@ typedef UINT8 tGATT_SEC_ACTION;
 #define GATT_ATTR_OP_SPT_PREP_WRITE        (0x00000001 << 10)
 #define GATT_ATTR_OP_SPT_PREP_WRITE        (0x00000001 << 10)
 #define GATT_ATTR_OP_SPT_EXE_WRITE         (0x00000001 << 11)
 #define GATT_ATTR_OP_SPT_EXE_WRITE         (0x00000001 << 11)
 #define GATT_ATTR_OP_SPT_HDL_VALUE_CONF    (0x00000001 << 12)
 #define GATT_ATTR_OP_SPT_HDL_VALUE_CONF    (0x00000001 << 12)
-#define GATT_ATTR_OP_SP_SIGN_WRITE        (0x00000001 << 13)
+#define GATT_ATTR_OP_SP_SIGN_WRITE         (0x00000001 << 13)
 
 
-#define GATT_INDEX_INVALID  0xff
+#define GATT_INDEX_INVALID      0xff
 
 
-#define GATT_PENDING_REQ_NONE    0
+#define GATT_PENDING_REQ_NONE   0
 
 
 
 
-#define GATT_WRITE_CMD_MASK  0xc0  /*0x1100-0000*/
-#define GATT_AUTH_SIGN_MASK  0x80  /*0x1000-0000*/
-#define GATT_AUTH_SIGN_LEN   12
+#define GATT_WRITE_CMD_MASK     0xc0  /*0x1100-0000*/
+#define GATT_AUTH_SIGN_MASK     0x80  /*0x1000-0000*/
+#define GATT_AUTH_SIGN_LEN      12
 
 
 #define GATT_HDR_SIZE           3 /* 1B opcode + 2B handle */
 #define GATT_HDR_SIZE           3 /* 1B opcode + 2B handle */
 
 
@@ -154,7 +157,7 @@ typedef union {
     tBT_UUID                uuid;               /* service declaration */
     tBT_UUID                uuid;               /* service declaration */
     tGATT_CHAR_DECL         char_decl;          /* characteristic declaration */
     tGATT_CHAR_DECL         char_decl;          /* characteristic declaration */
     tGATT_INCL_SRVC         incl_handle;        /* included service */
     tGATT_INCL_SRVC         incl_handle;        /* included service */
-
+    tGATT_ATTR_VAL          attr_val;
 } tGATT_ATTR_VALUE;
 } tGATT_ATTR_VALUE;
 
 
 /* Attribute UUID type
 /* Attribute UUID type
@@ -167,50 +170,49 @@ typedef UINT8   tGATT_ATTR_UUID_TYPE;
 /* 16 bits UUID Attribute in server database
 /* 16 bits UUID Attribute in server database
 */
 */
 typedef struct {
 typedef struct {
-    void                                *p_next;  /* pointer to the next attribute,
-                                                    either tGATT_ATTR16 or tGATT_ATTR128 */
-    tGATT_ATTR_VALUE                    *p_value;
-    tGATT_ATTR_UUID_TYPE                uuid_type;
-    tGATT_PERM                          permission;
-    UINT16                              handle;
-    UINT16                              uuid;
+    void                    *p_next;  /* pointer to the next attribute, either tGATT_ATTR16 or tGATT_ATTR128 */
+    tGATT_ATTR_VALUE        *p_value;
+    tGATT_ATTR_UUID_TYPE    uuid_type;
+    tGATT_PERM              permission;
+    tGATTS_ATTR_CONTROL     control;
+    UINT16                  handle;
+    UINT16                  uuid;
 } tGATT_ATTR16;
 } tGATT_ATTR16;
 
 
 /* 32 bits UUID Attribute in server database
 /* 32 bits UUID Attribute in server database
 */
 */
 typedef struct {
 typedef struct {
-    void                                *p_next;  /* pointer to the next attribute,
-                                                    either tGATT_ATTR16, tGATT_ATTR32 or tGATT_ATTR128 */
-    tGATT_ATTR_VALUE                    *p_value;
-    tGATT_ATTR_UUID_TYPE                uuid_type;
-    tGATT_PERM                          permission;
-    UINT16                              handle;
-    UINT32                              uuid;
+    void                    *p_next;  /* pointer to the next attribute, either tGATT_ATTR16, tGATT_ATTR32 or tGATT_ATTR128 */
+    tGATT_ATTR_VALUE        *p_value;
+    tGATT_ATTR_UUID_TYPE    uuid_type;
+    tGATT_PERM              permission;
+    tGATTS_ATTR_CONTROL     control;
+    UINT16                  handle;
+    UINT32                  uuid;
 } tGATT_ATTR32;
 } tGATT_ATTR32;
 
 
 
 
 /* 128 bits UUID Attribute in server database
 /* 128 bits UUID Attribute in server database
 */
 */
 typedef struct {
 typedef struct {
-    void                                *p_next;  /* pointer to the next attribute,
-                                                    either tGATT_ATTR16 or tGATT_ATTR128 */
-    tGATT_ATTR_VALUE                    *p_value;
-    tGATT_ATTR_UUID_TYPE                uuid_type;
-    tGATT_PERM                          permission;
-    UINT16                              handle;
-    UINT8                               uuid[LEN_UUID_128];
+    void                    *p_next;  /* pointer to the next attribute, either tGATT_ATTR16 or tGATT_ATTR128 */
+    tGATT_ATTR_VALUE        *p_value;
+    tGATT_ATTR_UUID_TYPE    uuid_type;
+    tGATT_PERM              permission;
+    tGATTS_ATTR_CONTROL     control;
+    UINT16                  handle;
+    UINT8                   uuid[LEN_UUID_128];
 } tGATT_ATTR128;
 } tGATT_ATTR128;
 
 
 /* Service Database definition
 /* Service Database definition
 */
 */
 typedef struct {
 typedef struct {
-    void            *p_attr_list;               /* pointer to the first attribute,
-                                                  either tGATT_ATTR16 or tGATT_ATTR128 */
-    UINT8           *p_free_mem;                /* Pointer to free memory       */
-    BUFFER_Q        svc_buffer;                 /* buffer queue used for service database */
-    UINT32          mem_free;                   /* Memory still available       */
-    UINT16          end_handle;                 /* Last handle number           */
-    UINT16          next_handle;                /* Next usable handle value     */
+    void            *p_attr_list;       /* pointer to the first attribute, either tGATT_ATTR16 or tGATT_ATTR128 */
+    UINT8           *p_free_mem;        /* Pointer to free memory       */
+    BUFFER_Q        svc_buffer;         /* buffer queue used for service database */
+    UINT32          mem_free;           /* Memory still available       */
+    UINT16          end_handle;         /* Last handle number           */
+    UINT16          next_handle;        /* Next usable handle value     */
 } tGATT_SVC_DB;
 } tGATT_SVC_DB;
 
 
 /* Data Structure used for GATT server                                        */
 /* Data Structure used for GATT server                                        */
@@ -218,14 +220,14 @@ typedef struct {
 /* A service registration information record consists of beginning and ending */
 /* A service registration information record consists of beginning and ending */
 /* attribute handle, service UUID and a set of GATT server callback.          */
 /* attribute handle, service UUID and a set of GATT server callback.          */
 typedef struct {
 typedef struct {
-    tGATT_SVC_DB    *p_db;      /* pointer to the service database */
+    tGATT_SVC_DB    *p_db;              /* pointer to the service database */
     tBT_UUID        app_uuid;           /* applicatino UUID */
     tBT_UUID        app_uuid;           /* applicatino UUID */
-    UINT32          sdp_handle; /* primamry service SDP handle */
+    UINT32          sdp_handle;         /* primamry service SDP handle */
     UINT16          service_instance;   /* service instance number */
     UINT16          service_instance;   /* service instance number */
-    UINT16          type;       /* service type UUID, primary or secondary */
-    UINT16          s_hdl;      /* service starting handle */
-    UINT16          e_hdl;      /* service ending handle */
-    tGATT_IF        gatt_if;    /* this service is belong to which application */
+    UINT16          type;               /* service type UUID, primary or secondary */
+    UINT16          s_hdl;              /* service starting handle */
+    UINT16          e_hdl;              /* service ending handle */
+    tGATT_IF        gatt_if;            /* this service is belong to which application */
     BOOLEAN         in_use;
     BOOLEAN         in_use;
 } tGATT_SR_REG;
 } tGATT_SR_REG;
 
 
@@ -340,7 +342,7 @@ typedef struct {
     tGATT_CH_STATE  ch_state;
     tGATT_CH_STATE  ch_state;
     UINT8           ch_flags;
     UINT8           ch_flags;
 
 
-    tGATT_IF         app_hold_link[GATT_MAX_APPS];
+    tGATT_IF        app_hold_link[GATT_MAX_APPS];
 
 
     /* server needs */
     /* server needs */
     /* server response data */
     /* server response data */
@@ -350,13 +352,13 @@ typedef struct {
 
 
     TIMER_LIST_ENT  conf_timer_ent;     /* peer confirm to indication timer */
     TIMER_LIST_ENT  conf_timer_ent;     /* peer confirm to indication timer */
 
 
-    UINT8            prep_cnt[GATT_MAX_APPS];
-    UINT8            ind_count;
+    UINT8           prep_cnt[GATT_MAX_APPS];
+    UINT8           ind_count;
 
 
-    tGATT_CMD_Q       cl_cmd_q[GATT_CL_MAX_LCB];
-    TIMER_LIST_ENT    ind_ack_timer_ent;    /* local app confirm to indication timer */
-    UINT8             pending_cl_req;
-    UINT8             next_slot_inq;    /* index of next available slot in queue */
+    tGATT_CMD_Q     cl_cmd_q[GATT_CL_MAX_LCB];
+    TIMER_LIST_ENT  ind_ack_timer_ent;    /* local app confirm to indication timer */
+    UINT8           pending_cl_req;
+    UINT8           next_slot_inq;    /* index of next available slot in queue */
 
 
     BOOLEAN         in_use;
     BOOLEAN         in_use;
     UINT8           tcb_idx;
     UINT8           tcb_idx;
@@ -579,6 +581,7 @@ extern BOOLEAN gatt_cl_send_next_cmd_inq(tGATT_TCB *p_tcb);
 /* reserved handle list */
 /* reserved handle list */
 extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst);
 extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst);
 extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle);
 extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle);
+extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_attr_handle(UINT16 attr_handle);
 extern tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void);
 extern tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void);
 extern void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p);
 extern void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p);
 extern BOOLEAN gatt_is_last_attribute(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_start, tBT_UUID value);
 extern BOOLEAN gatt_is_last_attribute(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_start, tBT_UUID value);
@@ -664,12 +667,27 @@ extern void gatt_set_sec_act(tGATT_TCB *p_tcb, tGATT_SEC_ACTION sec_act);
 /* gatt_db.c */
 /* gatt_db.c */
 extern BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle);
 extern BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle);
 extern UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e_handle, tBT_UUID service);
 extern UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e_handle, tBT_UUID service);
-extern UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, tGATT_CHAR_PROP property, tBT_UUID *p_char_uuid);
-extern UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, tBT_UUID *p_dscp_uuid);
+extern UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
+                                                        tGATT_CHAR_PROP property,
+                                                        tBT_UUID *p_char_uuid, tGATT_ATTR_VAL *attr_val, 
+                                                        tGATTS_ATTR_CONTROL *control);
+extern UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, 
+                                         tBT_UUID *p_dscp_uuid, tGATT_ATTR_VAL *attr_val,
+                                         tGATTS_ATTR_CONTROL *control);
+
+extern tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, 
+                                    UINT16 length, UINT8 *value);
+
+extern tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, 
+                                    UINT16 *length, UINT8 **value);
+extern BOOLEAN gatts_is_auto_response(UINT16 attr_handle);
 extern tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb, tGATT_SVC_DB *p_db, UINT8 op_code, BT_HDR *p_rsp, UINT16 s_handle,
 extern tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb, tGATT_SVC_DB *p_db, UINT8 op_code, BT_HDR *p_rsp, UINT16 s_handle,
         UINT16 e_handle, tBT_UUID type, UINT16 *p_len, tGATT_SEC_FLAG sec_flag, UINT8 key_size, UINT32 trans_id, UINT16 *p_cur_handle);
         UINT16 e_handle, tBT_UUID type, UINT16 *p_len, tGATT_SEC_FLAG sec_flag, UINT8 key_size, UINT32 trans_id, UINT16 *p_cur_handle);
 extern tGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb, tGATT_SVC_DB *p_db, UINT8 op_code, UINT16 handle, UINT16 offset,
 extern tGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb, tGATT_SVC_DB *p_db, UINT8 op_code, UINT16 handle, UINT16 offset,
         UINT8 *p_value, UINT16 *p_len, UINT16 mtu, tGATT_SEC_FLAG sec_flag, UINT8 key_size, UINT32 trans_id);
         UINT8 *p_value, UINT16 *p_len, UINT16 mtu, tGATT_SEC_FLAG sec_flag, UINT8 key_size, UINT32 trans_id);
+extern tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db,
+                                                            UINT16 handle, UINT16 offset,
+                                                            UINT8 *p_value, UINT16 len);
 extern tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, UINT16 handle, UINT16 offset, UINT8 *p_data,
 extern tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, UINT16 handle, UINT16 offset, UINT8 *p_data,
         UINT16 len, tGATT_SEC_FLAG sec_flag, UINT8 key_size);
         UINT16 len, tGATT_SEC_FLAG sec_flag, UINT8 key_size);
 extern tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db, BOOLEAN is_long, UINT16 handle, tGATT_SEC_FLAG sec_flag, UINT8 key_size);
 extern tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db, BOOLEAN is_long, UINT16 handle, tGATT_SEC_FLAG sec_flag, UINT8 key_size);

+ 69 - 22
components/bt/bluedroid/stack/include/gatt_api.h

@@ -63,6 +63,8 @@
 #define  GATT_ENCRYPED_NO_MITM               0x8d
 #define  GATT_ENCRYPED_NO_MITM               0x8d
 #define  GATT_NOT_ENCRYPTED                  0x8e
 #define  GATT_NOT_ENCRYPTED                  0x8e
 #define  GATT_CONGESTED                      0x8f
 #define  GATT_CONGESTED                      0x8f
+#define  GATT_STACK_RSP                      0x90
+#define  GATT_APP_RSP                        0x91
 
 
 /* 0xE0 ~ 0xFC reserved for future use */
 /* 0xE0 ~ 0xFC reserved for future use */
 #define  GATT_CCC_CFG_ERR                    0xFD /* Client Characteristic Configuration Descriptor Improperly Configured */
 #define  GATT_CCC_CFG_ERR                    0xFD /* Client Characteristic Configuration Descriptor Improperly Configured */
@@ -117,36 +119,36 @@ typedef UINT16 tGATT_DISCONN_REASON;
 /* MAX GATT MTU size
 /* MAX GATT MTU size
 */
 */
 #ifndef GATT_MAX_MTU_SIZE
 #ifndef GATT_MAX_MTU_SIZE
-#define GATT_MAX_MTU_SIZE     517
+#define GATT_MAX_MTU_SIZE                   517
 #endif
 #endif
 
 
 /* max legth of an attribute value
 /* max legth of an attribute value
 */
 */
 #ifndef GATT_MAX_ATTR_LEN
 #ifndef GATT_MAX_ATTR_LEN
-#define GATT_MAX_ATTR_LEN     600
+#define GATT_MAX_ATTR_LEN                   600
 #endif
 #endif
 
 
 /* default GATT MTU size over LE link
 /* default GATT MTU size over LE link
 */
 */
-#define GATT_DEF_BLE_MTU_SIZE       23
+#define GATT_DEF_BLE_MTU_SIZE               23
 
 
 /* invalid connection ID
 /* invalid connection ID
 */
 */
-#define GATT_INVALID_CONN_ID        0xFFFF
+#define GATT_INVALID_CONN_ID                0xFFFF
 
 
 #ifndef GATT_CL_MAX_LCB
 #ifndef GATT_CL_MAX_LCB
-#define GATT_CL_MAX_LCB     12 // 22
+#define GATT_CL_MAX_LCB                     12 // 22
 #endif
 #endif
 
 
 #ifndef GATT_MAX_SCCB
 #ifndef GATT_MAX_SCCB
-#define GATT_MAX_SCCB       10
+#define GATT_MAX_SCCB                       10
 #endif
 #endif
 
 
 
 
 /* GATT notification caching timer, default to be three seconds
 /* GATT notification caching timer, default to be three seconds
 */
 */
 #ifndef GATTC_NOTIF_TIMEOUT
 #ifndef GATTC_NOTIF_TIMEOUT
-#define GATTC_NOTIF_TIMEOUT   3
+#define GATTC_NOTIF_TIMEOUT                 3
 #endif
 #endif
 
 
 /*****************************************************************************
 /*****************************************************************************
@@ -155,22 +157,22 @@ typedef UINT16 tGATT_DISCONN_REASON;
 
 
 /* Attribute permissions
 /* Attribute permissions
 */
 */
-#define GATT_PERM_READ              (1 << 0) /* bit 0 */
-#define GATT_PERM_READ_ENCRYPTED    (1 << 1) /* bit 1 */
-#define GATT_PERM_READ_ENC_MITM     (1 << 2) /* bit 2 */
-#define GATT_PERM_WRITE             (1 << 4) /* bit 4 */
-#define GATT_PERM_WRITE_ENCRYPTED   (1 << 5) /* bit 5 */
-#define GATT_PERM_WRITE_ENC_MITM    (1 << 6) /* bit 6 */
-#define GATT_PERM_WRITE_SIGNED      (1 << 7) /* bit 7 */
-#define GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /* bit 8 */
+#define GATT_PERM_READ                      (1 << 0) /* bit 0 */
+#define GATT_PERM_READ_ENCRYPTED            (1 << 1) /* bit 1 */
+#define GATT_PERM_READ_ENC_MITM             (1 << 2) /* bit 2 */
+#define GATT_PERM_WRITE                     (1 << 4) /* bit 4 */
+#define GATT_PERM_WRITE_ENCRYPTED           (1 << 5) /* bit 5 */
+#define GATT_PERM_WRITE_ENC_MITM            (1 << 6) /* bit 6 */
+#define GATT_PERM_WRITE_SIGNED              (1 << 7) /* bit 7 */
+#define GATT_PERM_WRITE_SIGNED_MITM         (1 << 8) /* bit 8 */
 typedef UINT16 tGATT_PERM;
 typedef UINT16 tGATT_PERM;
 
 
 #define GATT_ENCRYPT_KEY_SIZE_MASK  (0xF000) /* the MS nibble of tGATT_PERM; key size 7=0; size 16=9 */
 #define GATT_ENCRYPT_KEY_SIZE_MASK  (0xF000) /* the MS nibble of tGATT_PERM; key size 7=0; size 16=9 */
 
 
-#define GATT_READ_ALLOWED           (GATT_PERM_READ | GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
-#define GATT_READ_AUTH_REQUIRED     (GATT_PERM_READ_ENCRYPTED)
-#define GATT_READ_MITM_REQUIRED     (GATT_PERM_READ_ENC_MITM)
-#define GATT_READ_ENCRYPTED_REQUIRED   (GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
+#define GATT_READ_ALLOWED                   (GATT_PERM_READ | GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
+#define GATT_READ_AUTH_REQUIRED             (GATT_PERM_READ_ENCRYPTED)
+#define GATT_READ_MITM_REQUIRED             (GATT_PERM_READ_ENC_MITM)
+#define GATT_READ_ENCRYPTED_REQUIRED        (GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
 
 
 
 
 #define GATT_WRITE_ALLOWED          (GATT_PERM_WRITE | GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE_ENC_MITM | \
 #define GATT_WRITE_ALLOWED          (GATT_PERM_WRITE | GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE_ENC_MITM | \
@@ -312,6 +314,16 @@ typedef struct {
     UINT8           value[GATT_MAX_ATTR_LEN];  /* the actual attribute value */
     UINT8           value[GATT_MAX_ATTR_LEN];  /* the actual attribute value */
 } tGATT_VALUE;
 } tGATT_VALUE;
 
 
+typedef struct{
+    UINT16  attr_max_len;
+    UINT16  attr_len;
+    UINT8   *attr_val;
+}tGATT_ATTR_VAL;
+
+typedef struct{
+    uint8_t auto_rsp;
+}tGATTS_ATTR_CONTROL;
+
 /* Union of the event data which is used in the server respond API to carry the server response information
 /* Union of the event data which is used in the server respond API to carry the server response information
 */
 */
 typedef union {
 typedef union {
@@ -740,8 +752,9 @@ extern UINT16 GATTS_AddIncludeService (UINT16 service_handle,
 **                  characteristic failed.
 **                  characteristic failed.
 **
 **
 *******************************************************************************/
 *******************************************************************************/
-extern UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *char_uuid,
-                                       tGATT_PERM perm, tGATT_CHAR_PROP property);
+extern UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *p_char_uuid,
+                                tGATT_PERM perm, tGATT_CHAR_PROP property, 
+                                tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control);
 
 
 /*******************************************************************************
 /*******************************************************************************
 **
 **
@@ -763,7 +776,8 @@ extern UINT16 GATTS_AddCharacteristic (UINT16 service_handle, tBT_UUID *char_uui
 **
 **
 *******************************************************************************/
 *******************************************************************************/
 extern UINT16 GATTS_AddCharDescriptor (UINT16 service_handle, tGATT_PERM perm,
 extern UINT16 GATTS_AddCharDescriptor (UINT16 service_handle, tGATT_PERM perm,
-                                       tBT_UUID *p_descr_uuid);
+                                                                tBT_UUID   *p_descr_uuid, tGATT_ATTR_VAL *attr_val,
+                                                                tGATTS_ATTR_CONTROL *control);
 
 
 /*******************************************************************************
 /*******************************************************************************
 **
 **
@@ -866,6 +880,39 @@ extern  tGATT_STATUS GATTS_SendRsp (UINT16 conn_id,  UINT32 trans_id,
                                     tGATT_STATUS status, tGATTS_RSP *p_msg);
                                     tGATT_STATUS status, tGATTS_RSP *p_msg);
 
 
 
 
+/*******************************************************************************
+**
+** Function         GATTS_SetAttributeValue
+**
+** Description      This function sends to set the attribute value .
+**
+** Parameter        attr_handle:the attribute handle
+**                      length: the attribute length
+**                      value: the value to be set to the attribute in the database
+**
+** Returns          GATT_SUCCESS if sucessfully sent; otherwise error code.
+**
+*******************************************************************************/
+tGATT_STATUS GATTS_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value);
+
+
+/*******************************************************************************
+**
+** Function         GATTS_GetAttributeValue
+**
+** Description      This function sends to set the attribute value .
+**
+** Parameter        attr_handle: the attribute handle
+**                      length:the attribute value length in the database
+**                      value: the attribute value out put
+**
+** Returns          GATT_SUCCESS if sucessfully sent; otherwise error code.
+**
+*******************************************************************************/
+tGATT_STATUS GATTS_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value);
+
+
+
 /*******************************************************************************/
 /*******************************************************************************/
 /* GATT Profile Client Functions */
 /* GATT Profile Client Functions */
 /*******************************************************************************/
 /*******************************************************************************/

+ 1 - 1
components/bt/bluedroid/stack/smp/smp_main.c

@@ -419,7 +419,7 @@ static const UINT8 smp_master_create_local_sec_conn_oob_data[][SMP_SM_NUM_COLS]
 static const UINT8 smp_slave_entry_map[][SMP_STATE_MAX] = {
 static const UINT8 smp_slave_entry_map[][SMP_STATE_MAX] = {
     /* state name:             Idle WaitApp SecReq Pair   Wait Confirm Rand PublKey SCPhs1  Wait  Wait  SCPhs2  Wait   DHKChk Enc   Bond  CrLocSc
     /* state name:             Idle WaitApp SecReq Pair   Wait Confirm Rand PublKey SCPhs1  Wait  Wait  SCPhs2  Wait   DHKChk Enc   Bond  CrLocSc
                                      Rsp    Pend   ReqRsp Cfm               Exch    Strt    Cmtm  Nonce Strt    DHKChk        Pend  Pend  OobData   */
                                      Rsp    Pend   ReqRsp Cfm               Exch    Strt    Cmtm  Nonce Strt    DHKChk        Pend  Pend  OobData   */
-    /* PAIR_REQ             */{ 2,    1,     1,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
+    /* PAIR_REQ             */{ 2,    0,     1,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
     /* PAIR_RSP             */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
     /* PAIR_RSP             */{ 0,    0,     0,      0,     0,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
     /* CONFIRM              */{ 0,    4,     0,      1,     1,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
     /* CONFIRM              */{ 0,    4,     0,      1,     1,   0,    0,   0,      0,      0,    0,    0,      0,     0,     0,    0,     0   },
     /* RAND                 */{ 0,    0,     0,      0,     0,   1,    2,   0,      0,      0,    1,    0,      0,     0,     0,    0,     0   },
     /* RAND                 */{ 0,    0,     0,      0,     0,   1,    2,   0,      0,      0,    1,    0,      0,     0,     0,    0,     0   },

+ 1 - 2
docs/api/esp_blufi.rst

@@ -6,8 +6,7 @@ Overview
 BLUFI is a profile based GATT to config ESP32 WIFI to connect/disconnect AP or setup a softap and etc.
 BLUFI is a profile based GATT to config ESP32 WIFI to connect/disconnect AP or setup a softap and etc.
 Use should concern these things: 
 Use should concern these things: 
 1. The event sent from profile. Then you need to do something as the event indicate.
 1. The event sent from profile. Then you need to do something as the event indicate.
-2. Security reference. You can write your own Security functions such as symmetrical encryption/decryption and checksum functions.
-Even you can define the "Key Exchange/Negotiation" procedure.
+2. Security reference. You can write your own Security functions such as symmetrical encryption/decryption and checksum functions. Even you can define the "Key Exchange/Negotiation" procedure.
 
 
 Application Example
 Application Example
 -------------------
 -------------------

+ 23 - 0
docs/api/esp_gatt_defs.rst

@@ -84,6 +84,8 @@ Macros
 .. doxygendefine:: ESP_GATT_UUID_SCAN_INT_WINDOW
 .. doxygendefine:: ESP_GATT_UUID_SCAN_INT_WINDOW
 .. doxygendefine:: ESP_GATT_UUID_SCAN_REFRESH
 .. doxygendefine:: ESP_GATT_UUID_SCAN_REFRESH
 .. doxygendefine:: ESP_GATT_ILLEGAL_UUID
 .. doxygendefine:: ESP_GATT_ILLEGAL_UUID
+.. doxygendefine:: ESP_GATT_ILLEGAL_HANDLE
+.. doxygendefine:: ESP_GATT_ATTR_HANDLE_MAX
 .. doxygendefine:: ESP_GATT_MAX_ATTR_LEN
 .. doxygendefine:: ESP_GATT_MAX_ATTR_LEN
 .. doxygendefine:: ESP_GATT_IF_NONE
 .. doxygendefine:: ESP_GATT_IF_NONE
 
 
@@ -106,6 +108,27 @@ Enumerations
 Structures
 Structures
 ^^^^^^^^^^
 ^^^^^^^^^^
 
 
+.. doxygenstruct:: esp_attr_desc_t
+    :members:
+
+.. doxygenstruct:: esp_attr_control_t
+    :members:
+
+.. doxygenstruct:: esp_gatts_attr_db_t
+    :members:
+
+.. doxygenstruct:: esp_attr_value_t
+    :members:
+
+.. doxygenstruct:: esp_gatts_incl_svc_desc_t
+    :members:
+
+.. doxygenstruct:: esp_gatts_incl128_svc_desc_t
+    :members:
+
+.. doxygenstruct:: esp_gatts_char_desc_t
+    :members:
+
 .. doxygenstruct:: esp_gatt_value_t
 .. doxygenstruct:: esp_gatt_value_t
     :members:
     :members:
 
 

+ 9 - 0
docs/api/esp_gatts.rst

@@ -80,6 +80,9 @@ Structures
 .. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_add_char_descr_evt_param
 .. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_add_char_descr_evt_param
     :members:
     :members:
 
 
+.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_add_attr_tab_evt_param
+    :members:
+
 .. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_delete_evt_param
 .. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_delete_evt_param
     :members:
     :members:
 
 
@@ -101,6 +104,9 @@ Structures
 .. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_rsp_evt_param
 .. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_rsp_evt_param
     :members:
     :members:
 
 
+.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_set_attr_val_evt_param
+    :members:
+
 
 
 Functions
 Functions
 ^^^^^^^^^
 ^^^^^^^^^
@@ -109,6 +115,7 @@ Functions
 .. doxygenfunction:: esp_ble_gatts_app_register
 .. doxygenfunction:: esp_ble_gatts_app_register
 .. doxygenfunction:: esp_ble_gatts_app_unregister
 .. doxygenfunction:: esp_ble_gatts_app_unregister
 .. doxygenfunction:: esp_ble_gatts_create_service
 .. doxygenfunction:: esp_ble_gatts_create_service
+.. doxygenfunction:: esp_ble_gatts_create_attr_tab
 .. doxygenfunction:: esp_ble_gatts_add_included_service
 .. doxygenfunction:: esp_ble_gatts_add_included_service
 .. doxygenfunction:: esp_ble_gatts_add_char
 .. doxygenfunction:: esp_ble_gatts_add_char
 .. doxygenfunction:: esp_ble_gatts_add_char_descr
 .. doxygenfunction:: esp_ble_gatts_add_char_descr
@@ -117,6 +124,8 @@ Functions
 .. doxygenfunction:: esp_ble_gatts_stop_service
 .. doxygenfunction:: esp_ble_gatts_stop_service
 .. doxygenfunction:: esp_ble_gatts_send_indicate
 .. doxygenfunction:: esp_ble_gatts_send_indicate
 .. doxygenfunction:: esp_ble_gatts_send_response
 .. doxygenfunction:: esp_ble_gatts_send_response
+.. doxygenfunction:: esp_ble_gatts_set_attr_value
+.. doxygenfunction:: esp_ble_gatts_get_attr_value
 .. doxygenfunction:: esp_ble_gatts_open
 .. doxygenfunction:: esp_ble_gatts_open
 .. doxygenfunction:: esp_ble_gatts_close
 .. doxygenfunction:: esp_ble_gatts_close
 
 

+ 32 - 7
examples/14_gatt_server/main/gatts_demo.c

@@ -48,6 +48,19 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
 
 
 #define TEST_DEVICE_NAME            "ESP_GATTS_DEMO"
 #define TEST_DEVICE_NAME            "ESP_GATTS_DEMO"
 #define TEST_MANUFACTURER_DATA_LEN  17
 #define TEST_MANUFACTURER_DATA_LEN  17
+
+#define GATTS_DEMO_CHAR_VAL_LEN_MAX		0x40
+
+uint8_t char1_str[] ={0x11,0x22,0x33};
+
+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 test_service_uuid128[32] = {
 static uint8_t test_service_uuid128[32] = {
     /* LSB <--------------------------------------------------------------------------------> MSB */
     /* LSB <--------------------------------------------------------------------------------> MSB */
     //first uuid, 16bit, [12],[13] is the value
     //first uuid, 16bit, [12],[13] is the value
@@ -175,20 +188,30 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
 
 
         esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid,
         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_PERM_READ | ESP_GATT_PERM_WRITE,
-                               ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY);
+                               ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, 
+                               &gatts_demo_char1_val, NULL);
         break;
         break;
     case ESP_GATTS_ADD_INCL_SRVC_EVT:
     case ESP_GATTS_ADD_INCL_SRVC_EVT:
         break;
         break;
-    case ESP_GATTS_ADD_CHAR_EVT:
-        ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d,  attr_handle %d, service_handle %d\n",
-                 param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
+    case ESP_GATTS_ADD_CHAR_EVT: {
+	    uint16_t length = 0;
+        const uint8_t *prf_char;
 
 
+        ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d,  attr_handle %d, service_handle %d\n",
+                param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
         gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle;
         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.len = ESP_UUID_LEN_16;
         gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
         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_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_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);
+                                     ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
         break;
         break;
+    }
     case ESP_GATTS_ADD_CHAR_DESCR_EVT:
     case ESP_GATTS_ADD_CHAR_DESCR_EVT:
         ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",
         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);
                  param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
@@ -269,7 +292,8 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
 
 
         esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid,
         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_PERM_READ | ESP_GATT_PERM_WRITE,
-                               ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY);
+                               ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY,
+                               NULL, NULL);
         break;
         break;
     case ESP_GATTS_ADD_INCL_SRVC_EVT:
     case ESP_GATTS_ADD_INCL_SRVC_EVT:
         break;
         break;
@@ -281,7 +305,8 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
         gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16;
         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;
         gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
         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_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);
+                                     ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
+                                     NULL, NULL);
         break;
         break;
     case ESP_GATTS_ADD_CHAR_DESCR_EVT:
     case ESP_GATTS_ADD_CHAR_DESCR_EVT:
         ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",
         ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",

+ 11 - 0
examples/30_gatt_server_table_create/Makefile

@@ -0,0 +1,11 @@
+#
+# This is a project Makefile. It is assumed the directory this Makefile resides in is a
+# project subdirectory.
+#
+
+PROJECT_NAME := gatt_server_table_creat_demo
+
+COMPONENT_ADD_INCLUDEDIRS := components/include
+
+include $(IDF_PATH)/make/project.mk
+

+ 10 - 0
examples/30_gatt_server_table_create/README.rst

@@ -0,0 +1,10 @@
+ESP-IDF GATT SERVER create attribute table demo
+===============================================
+
+This is the demo for user to use ESP_APIs to create a GATT Server attribute table.
+The table is easy to use to create GATT server service database without use each "attribute create" functions.
+Actually, there are two way to create server service and characteristics.
+One is use the esp_gatts_create_service or esp_ble_gatts_add_char and etc.
+The other way is use esp_ble_gatts_create_attr_tab.
+The important things: the two ways cannot use in the same service, but can use in different service.
+

+ 8 - 0
examples/30_gatt_server_table_create/main/component.mk

@@ -0,0 +1,8 @@
+#
+# Main Makefile. This is basically the same as a component makefile.
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, 
+# this will take the sources in the src/ directory, compile them and link them into 
+# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
+# please read the ESP-IDF documents if you need to do this.
+#

+ 340 - 0
examples/30_gatt_server_table_create/main/gatts_table_creat_demo.c

@@ -0,0 +1,340 @@
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/event_groups.h"
+#include "esp_system.h"
+#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"
+#include "esp_bt_defs.h"
+#include "esp_bt_main.h"
+#include "esp_bt_main.h"
+#include "gatts_table_creat_demo.h"
+
+
+#define HEART_PROFILE_NUM 			    1
+#define HEART_PROFILE_APP_IDX 			0
+#define ESP_HEART_RATE_APP_ID			0x55
+#define SAMPLE_DEVICE_NAME              "ESP_HEART_RATE"
+#define SAMPLE_MANUFACTURER_DATA_LEN    17
+#define HEART_RATE_SVC_INST_ID	    	0
+
+#define GATTS_DEMO_CHAR_VAL_LEN_MAX		0x40
+
+uint8_t char1_str[] ={0x11,0x22,0x33};
+
+uint16_t heart_rate_handle_table[HRS_IDX_NB];
+
+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 heart_rate_service_uuid[16] = {
+    /* LSB <--------------------------------------------------------------------------------> MSB */
+    //first uuid, 16bit, [12],[13] is the value
+    0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x18, 0x0D, 0x00, 0x00,
+};
+
+
+static esp_ble_adv_data_t heart_rate_adv_config = {
+    .set_scan_rsp = false,
+    .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 = heart_rate_service_uuid,
+    .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
+};
+
+static esp_ble_adv_params_t heart_rate_adv_params = {
+    .adv_int_min        = 0x20,
+    .adv_int_max        = 0x40,
+    .adv_type           = ADV_TYPE_IND,
+    .own_addr_type      = BLE_ADDR_TYPE_PUBLIC,
+    //.peer_addr            =
+    //.peer_addr_type       =
+    .channel_map        = ADV_CHNL_ALL,
+    .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
+};
+
+struct gatts_profile_inst {
+    esp_gatts_cb_t gatts_cb;
+    uint16_t gatts_if;
+    uint16_t app_id;
+    uint16_t conn_id;
+    uint16_t service_handle;
+    esp_gatt_srvc_id_t service_id;
+    uint16_t char_handle;
+    esp_bt_uuid_t char_uuid;
+    esp_gatt_perm_t perm;
+    esp_gatt_char_prop_t property;
+    uint16_t descr_handle;
+    esp_bt_uuid_t descr_uuid;
+};
+
+static void gatts_profile_event_handler(esp_gatts_cb_event_t event, 
+					esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
+
+/* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */
+static struct gatts_profile_inst heart_rate_profile_tab[HEART_PROFILE_NUM] = {
+    [HEART_PROFILE_APP_IDX] = {
+        .gatts_cb = gatts_profile_event_handler,
+        .gatts_if = ESP_GATT_IF_NONE,       /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
+    },
+    
+};
+
+/*
+ * HTPT PROFILE ATTRIBUTES
+ ****************************************************************************************
+ */
+
+/// Full HRS Database Description - Used to add attributes into the database
+const esp_gatts_attr_db_t heart_rate_gatt_db[HRS_IDX_NB] =
+{
+    // Heart Rate Service Declaration
+    [HRS_IDX_SVC]                      	=  {{ESP_GATT_AUTO_RSP}, {
+    									{ESP_UUID_LEN_16, {ESP_GATT_UUID_PRI_SERVICE}}, 
+    									ESP_GATT_PERM_READ,
+    									sizeof(heart_rate_svc),
+                                         			sizeof(heart_rate_svc), (uint8_t *)&heart_rate_svc}},
+
+    // Heart Rate Measurement Characteristic Declaration
+    [HRS_IDX_HR_MEAS_CHAR]            = {{ESP_GATT_AUTO_RSP}, {
+    									{ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_DECLARE}}, 
+    									ESP_GATT_PERM_READ,
+    									sizeof(heart_rate_meas_char),
+                                         			sizeof(heart_rate_meas_char), (uint8_t *)&heart_rate_meas_char}},
+    // Heart Rate Measurement Characteristic Value
+    [HRS_IDX_HR_MEAS_VAL]             	=   {{ESP_GATT_AUTO_RSP}, {
+    									{ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_MEAS}}, 
+    									ESP_GATT_PERM_READ,
+    									HRPS_HT_MEAS_MAX_LEN,
+                                         			0, NULL}},
+
+    // Heart Rate Measurement Characteristic - Client Characteristic Configuration Descriptor
+    [HRS_IDX_HR_MEAS_NTF_CFG]     	=    {{ESP_GATT_AUTO_RSP}, {
+    									{ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_SRVR_CONFIG}}, 
+    									ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE,
+    									sizeof(uint16_t),
+                                         			0, NULL}},
+
+    // Body Sensor Location Characteristic Declaration
+    [HRS_IDX_BOBY_SENSOR_LOC_CHAR]  = {{ESP_GATT_AUTO_RSP}, {
+    									{ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_DECLARE}}, 
+    									ESP_GATT_PERM_READ,
+    									sizeof(heart_rate_body_sensor_loc_char),
+                                         			sizeof(heart_rate_body_sensor_loc_char), (uint8_t *)&heart_rate_body_sensor_loc_char}},
+
+    // Body Sensor Location Characteristic Value
+    [HRS_IDX_BOBY_SENSOR_LOC_VAL]   = {{ESP_GATT_AUTO_RSP}, {
+    									{ESP_UUID_LEN_16, {ESP_GATT_BODY_SENSOR_LOCATION}}, 
+    									ESP_GATT_PERM_READ,
+    									sizeof(uint8_t),
+                                         			0, NULL}},
+
+    // Heart Rate Control Point Characteristic Declaration
+    [HRS_IDX_HR_CTNL_PT_CHAR]          = {{ESP_GATT_AUTO_RSP}, {
+    									{ESP_UUID_LEN_16, {ESP_GATT_UUID_CHAR_DECLARE}}, 
+    									ESP_GATT_PERM_READ,
+    									sizeof(heart_rate_cntl_point_char),
+                                         			sizeof(heart_rate_cntl_point_char), (uint8_t *)&heart_rate_cntl_point_char}},
+                                         			
+    // Heart Rate Control Point Characteristic Value
+    [HRS_IDX_HR_CTNL_PT_VAL]             = {{ESP_GATT_AUTO_RSP}, {
+    									{ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_CNTL_POINT}}, 
+    									ESP_GATT_PERM_WRITE,
+    									sizeof(uint8_t),
+                                         			0, NULL}},  
+};
+
+/*
+ *  Heart Rate PROFILE ATTRIBUTES
+ ****************************************************************************************
+ */
+
+/// Heart Rate Sensor Service
+const uint16_t heart_rate_svc = ESP_GATT_UUID_HEART_RATE_SVC;
+
+/// Heart Rate Sensor Service - Heart Rate Measurement Characteristic
+const esp_gatts_char_desc_t heart_rate_meas_char = 
+{
+	.prop = ESP_GATT_CHAR_PROP_BIT_NOTIFY,
+	.attr_hdl = 0,
+	.attr_uuid = {ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_MEAS}},
+};
+
+/// Heart Rate Sensor Service -Body Sensor Location characteristic
+const esp_gatts_char_desc_t heart_rate_body_sensor_loc_char = 
+{
+	.prop = ESP_GATT_CHAR_PROP_BIT_READ,
+	.attr_hdl = 0,
+	.attr_uuid = {ESP_UUID_LEN_16, {ESP_GATT_BODY_SENSOR_LOCATION}},
+};
+
+/// Heart Rate Sensor Service - Heart Rate Control Point characteristic
+const esp_gatts_char_desc_t heart_rate_cntl_point_char = 
+{
+	.prop = ESP_GATT_CHAR_PROP_BIT_WRITE,
+	.attr_hdl = 0,
+	.attr_uuid = {ESP_UUID_LEN_16, {ESP_GATT_HEART_RATE_CNTL_POINT}},
+};
+
+static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
+{
+    LOG_ERROR("GAP_EVT, event %d\n", event);
+
+    switch (event) {
+    case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
+        esp_ble_gap_start_advertising(&heart_rate_adv_params);
+        break;
+    default:
+        break;
+    }
+}
+
+static void gatts_profile_event_handler(esp_gatts_cb_event_t event, 
+										   esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) 
+{
+    LOG_ERROR("event = %x\n",event);
+    switch (event) {
+    	case ESP_GATTS_REG_EVT:
+		LOG_INFO("%s %d\n", __func__, __LINE__);
+        	esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME);
+        	LOG_INFO("%s %d\n", __func__, __LINE__);
+       	esp_ble_gap_config_adv_data(&heart_rate_adv_config);
+
+        	LOG_INFO("%s %d\n", __func__, __LINE__);
+		esp_ble_gatts_create_attr_tab(heart_rate_gatt_db, gatts_if, 
+								HRS_IDX_NB, HEART_RATE_SVC_INST_ID);
+       	break;
+    	case ESP_GATTS_READ_EVT:
+       
+       	 break;
+    	case ESP_GATTS_WRITE_EVT: 
+      	 	break;
+    	case ESP_GATTS_EXEC_WRITE_EVT:
+		break;
+    	case ESP_GATTS_MTU_EVT:
+		break;
+   	 case ESP_GATTS_CONF_EVT:
+		break;
+    	case ESP_GATTS_UNREG_EVT:
+        	break;
+    	case ESP_GATTS_DELETE_EVT:
+        	break;
+    	case ESP_GATTS_START_EVT:
+        	break;
+    	case ESP_GATTS_STOP_EVT:
+        	break;
+    	case ESP_GATTS_CONNECT_EVT:
+        	break;
+    	case ESP_GATTS_DISCONNECT_EVT:
+		break;
+    	case ESP_GATTS_OPEN_EVT:
+		break;
+    	case ESP_GATTS_CANCEL_OPEN_EVT:
+		break;
+    	case ESP_GATTS_CLOSE_EVT:
+		break;
+    	case ESP_GATTS_LISTEN_EVT:
+		break;
+    	case ESP_GATTS_CONGEST_EVT:
+		break;
+    case ESP_GATTS_CREAT_ATTR_TAB_EVT:{
+		LOG_ERROR("The number handle =%x\n",param->add_attr_tab.num_handle);
+		if(param->add_attr_tab.num_handle == HRS_IDX_NB){			
+			memcpy(heart_rate_handle_table, param->add_attr_tab.handles, 
+					sizeof(heart_rate_handle_table));
+			esp_ble_gatts_start_service(heart_rate_handle_table[HRS_IDX_SVC]);
+		}
+
+		break;
+	}
+		
+    default:
+        break;
+    }
+}
+
+
+static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, 
+									esp_ble_gatts_cb_param_t *param)
+{
+    LOG_INFO("EVT %d, gatts if %d\n", event, gatts_if);
+
+    /* If event is register event, store the gatts_if for each profile */
+    if (event == ESP_GATTS_REG_EVT) {
+        if (param->reg.status == ESP_GATT_OK) {
+            heart_rate_profile_tab[HEART_PROFILE_APP_IDX].gatts_if = gatts_if;
+        } else {
+            LOG_INFO("Reg app failed, app_id %04x, status %d\n",
+                    param->reg.app_id, 
+                    param->reg.status);
+            return;
+        }
+    }
+	
+    do {
+        int idx;
+        for (idx = 0; idx < HEART_PROFILE_NUM; idx++) {
+            if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
+                    gatts_if == heart_rate_profile_tab[idx].gatts_if) {
+                if (heart_rate_profile_tab[idx].gatts_cb) {
+                    heart_rate_profile_tab[idx].gatts_cb(event, gatts_if, param);
+                }
+            }
+        }
+    } while (0);
+}
+
+void app_main()
+{
+    esp_err_t ret;
+
+    esp_bt_controller_init();
+    LOG_INFO("%s init bluetooth\n", __func__);
+    ret = esp_bluedroid_init();
+    if (ret) {
+        LOG_ERROR("%s init bluetooth failed\n", __func__);
+        return;
+    }
+    ret = esp_bluedroid_enable();
+    if (ret) {
+        LOG_ERROR("%s enable bluetooth failed\n", __func__);
+        return;
+    }
+
+    esp_ble_gatts_register_callback(gatts_event_handler);
+    esp_ble_gap_register_callback(gap_event_handler);
+    esp_ble_gatts_app_register(ESP_HEART_RATE_APP_ID);
+    return;
+}

+ 57 - 0
examples/30_gatt_server_table_create/main/gatts_table_creat_demo.h

@@ -0,0 +1,57 @@
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * DEFINES
+ ****************************************************************************************
+ */
+
+#define HRPS_HT_MEAS_MAX_LEN            (13)
+
+#define HRPS_MANDATORY_MASK             (0x0F)
+#define HRPS_BODY_SENSOR_LOC_MASK       (0x30)
+#define HRPS_HR_CTNL_PT_MASK            (0xC0)
+
+
+///Attributes State Machine
+enum
+{
+    HRS_IDX_SVC,
+
+    HRS_IDX_HR_MEAS_CHAR,
+    HRS_IDX_HR_MEAS_VAL,
+    HRS_IDX_HR_MEAS_NTF_CFG,
+
+    HRS_IDX_BOBY_SENSOR_LOC_CHAR,
+    HRS_IDX_BOBY_SENSOR_LOC_VAL,
+
+    HRS_IDX_HR_CTNL_PT_CHAR,
+    HRS_IDX_HR_CTNL_PT_VAL,
+
+    HRS_IDX_NB,
+};
+
+
+extern const esp_gatts_attr_db_t heart_rate_gatt_db[HRS_IDX_NB];
+/// Heart Rate Sensor Service - only one instance for now
+extern const uint16_t heart_rate_svc;
+
+extern const esp_gatts_char_desc_t heart_rate_meas_char;
+extern const esp_gatts_char_desc_t heart_rate_body_sensor_loc_char;
+extern const esp_gatts_char_desc_t heart_rate_cntl_point_char;

+ 14 - 0
examples/30_gatt_server_table_create/sdkconfig.defaults

@@ -0,0 +1,14 @@
+# Override some defaults so BT stack is enabled
+# in this example
+
+#
+# BT config
+#
+CONFIG_BT_ENABLED=y
+
+#
+# ESP32-specific config
+#
+CONFIG_ESP32_ENABLE_STACK_BT=y
+# CONFIG_ESP32_ENABLE_STACK_NONE is not set
+CONFIG_MEMMAP_BT=y