Просмотр исходного кода

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

Yulong 9 лет назад
Родитель
Сommit
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)
 {
     if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
-	
+    
     if (callbacks == NULL) {
         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;
 
     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.pid = BTC_PID_BLUFI;
     msg.act = BTC_BLUFI_ACT_SEND_CFG_REPORT;
@@ -62,7 +62,7 @@ esp_err_t esp_blufi_profile_init(void)
     btc_msg_t msg;
 
     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;
@@ -77,9 +77,9 @@ esp_err_t esp_blufi_profile_deinit(void)
     btc_msg_t msg;
 
     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.pid = BTC_PID_BLUFI;
     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)
 {
     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 {
-	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)
 {
     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);
 }
@@ -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;
     
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     
     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;
     
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     
     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;
 
     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;
@@ -102,7 +102,7 @@ esp_err_t esp_ble_gap_stop_scanning(void)
     btc_msg_t msg;
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     
     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_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;
@@ -133,7 +133,7 @@ esp_err_t esp_ble_gap_stop_advertising(void)
     btc_msg_t msg;
 
     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     
     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;
 
     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;
@@ -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;
 
     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;
@@ -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;
 
     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;
@@ -204,7 +204,7 @@ esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable)
     btc_ble_gap_args_t arg;
 
     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;
@@ -221,9 +221,9 @@ esp_err_t esp_ble_gap_set_device_name(const char *name)
     btc_ble_gap_args_t arg;
 
     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) {
         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)
 {
     if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
-	
+    
     if (callback == NULL) {
         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;
 
     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) {
         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;
 
     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;
@@ -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;
 
     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.pid = BTC_PID_GATTC;
     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;
 
     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;
@@ -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;
 
     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)) {
@@ -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;
 
     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;
@@ -163,7 +163,7 @@ esp_err_t esp_ble_gattc_get_characteristic(esp_gatt_if_t gattc_if,
     btc_ble_gattc_args_t arg;
 
     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;
@@ -192,9 +192,9 @@ esp_err_t esp_ble_gattc_get_descriptor(esp_gatt_if_t gattc_if,
     btc_ble_gattc_args_t arg;
 
     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.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;
 
     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;
@@ -253,7 +253,7 @@ esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
     btc_ble_gattc_args_t arg;
 
     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;
@@ -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;
 
     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;
@@ -299,14 +299,14 @@ esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if,
                                     esp_gatt_id_t *char_id,
                                     uint16_t value_len,
                                     uint8_t *value,
-									esp_gatt_write_type_t write_type,
+                                    esp_gatt_write_type_t write_type,
                                     esp_gatt_auth_req_t auth_req)
 {
     btc_msg_t msg;
     btc_ble_gattc_args_t arg;
 
     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;
@@ -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,
                                         uint16_t value_len,
                                         uint8_t *value,
-                                		esp_gatt_write_type_t write_type,
+                                        esp_gatt_write_type_t write_type,
                                         esp_gatt_auth_req_t auth_req)
 {
     btc_msg_t msg;
     btc_ble_gattc_args_t arg;
 
     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.pid = BTC_PID_GATTC;
     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;
 
     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;
@@ -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;
 
     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;
@@ -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;
 
     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;
@@ -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;
 
     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;

+ 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))
 
+
 esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback)
 {
     if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
-	return ESP_ERR_INVALID_STATE;
+        return ESP_ERR_INVALID_STATE;
     }
     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;
 
     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) {
@@ -59,9 +60,9 @@ esp_err_t esp_ble_gatts_app_unregister(esp_gatt_if_t gatts_if)
     btc_ble_gatts_args_t arg;
 
     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.pid = BTC_PID_GATTS;
     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;
 
     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;
@@ -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);
 }
 
+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)
 {
@@ -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;
 
     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;
@@ -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_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_ble_gatts_args_t arg;
 
     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.pid = BTC_PID_GATTS;
     msg.act = BTC_GATTS_ACT_ADD_CHAR;
     arg.add_char.service_handle = service_handle;
     arg.add_char.perm = perm;
     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));
 
-    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_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_ble_gatts_args_t arg;
 
     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.pid = BTC_PID_GATTS;
     msg.act = BTC_GATTS_ACT_ADD_CHAR_DESCR;
     arg.add_descr.service_handle = service_handle;
     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));
 
-    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)
@@ -159,7 +203,7 @@ esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle)
     btc_ble_gatts_args_t arg;
 
     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;
@@ -176,7 +220,7 @@ esp_err_t esp_ble_gatts_start_service(uint16_t service_handle)
     btc_ble_gatts_args_t arg;
 
     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;
@@ -193,9 +237,9 @@ esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle)
     btc_ble_gatts_args_t arg;
 
     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.pid = BTC_PID_GATTS;
     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;
 
     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;
@@ -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 = 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,
@@ -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;
 
     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;
@@ -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.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)
@@ -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;
 
     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;
@@ -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;
     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)
@@ -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;
 
     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.pid = BTC_PID_GATTS;
     msg.act = BTC_GATTS_ACT_CLOSE;
     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
 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;
 
 /// 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)
 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;
 
 /// Advertising mode
@@ -109,37 +111,37 @@ typedef enum {
 
 /// Advertising parameters
 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;
 
 /// Advertising data content, according to "Supplement to the Bluetooth Core Specification"
 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;
 
 /// Own BD address source of the device
@@ -160,53 +162,53 @@ typedef enum {
 
 /// Ble scan type 
 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;
 
 /// Ble scan filter type
 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 : 
-												  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 :
-												  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 :
-												  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;
 
 /// Ble scan parameters
 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;
 
 /// Connection update parameters
 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;
 
 /// Sub Event of ESP_GAP_BLE_SCAN_RESULT_EVT
@@ -225,11 +227,11 @@ typedef enum {
  *        result is scan response or advertising data or other
  */
 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;
 
 /**
@@ -240,34 +242,34 @@ typedef union {
      * @brief ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
      */
     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
      */
     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
      */
     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
      */
     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;
 
 /**
@@ -440,7 +442,8 @@ esp_err_t esp_ble_gap_set_device_name(const char *name);
  * @param[in]       type   - finding ADV data 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);

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

@@ -22,106 +22,141 @@ extern "C" {
 #endif
 
 /// 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
  */
-#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 */
-#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 */
-#define ESP_GATT_UUID_GATT_SRV_CHGD          0x2A05
+#define ESP_GATT_UUID_GATT_SRV_CHGD                 0x2A05
 
 /* 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 */
-#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 */
-#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 */
-#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 */
-#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 */
-#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 */
-#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 */
-#define ESP_GATT_UUID_BATTERY_LEVEL          0x2A19
+#define ESP_GATT_UUID_BATTERY_LEVEL                 0x2A19
 
 /* 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 */
-#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 */
-#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 */
-#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
 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;
 
 /**
@@ -178,23 +213,23 @@ typedef enum {
  * @brief Gatt Connection reason 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;
 
 /**
  * @brief Gatt id, include uuid and instance id
  */
 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;
 
 /**
@@ -202,19 +237,19 @@ typedef struct {
  *        (uuid and instance id) and primary flag
  */
 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;
 
 /**
  * @brief Gatt authentication request type
  */
 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;
 
 /**
@@ -246,32 +281,109 @@ typedef enum {
 /// GATT maximum attribute length
 #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 
 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;
 
 /// GATT remote read request response type
 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;
 
 /**
   * @brief Gatt write type
   */
 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;
 
 #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
 }

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

@@ -25,29 +25,31 @@ extern "C" {
 
 /// GATT Server callback function events
 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;
 
 /**
@@ -58,64 +60,64 @@ typedef union {
      * @brief ESP_GATTS_REG_EVT
      */
     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
      */
     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
      */
     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
      */
     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
      */
     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
      */
     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
@@ -125,81 +127,81 @@ typedef union {
      * @brief ESP_GATTS_CREATE_EVT
      */
     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
      */
     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
      */
     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
      */
     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
      */
     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
      */
     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
      */
     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
      */
     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
      */
     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
@@ -217,17 +219,38 @@ typedef union {
      * @brief ESP_GATTS_CONGEST_EVT
      */
     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
      */
     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;
 
 /**
@@ -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);
 
 
-
+/**
+ * @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
  *                  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]       perm      : Characteristic value declaration attribute permission.
  * @param[in]       property  : Characteristic Properties
+ * @param[in]       char_val    : Characteristic value 
+ * @param[in]       control : attribute response control byte
  *
  * @return
  *                  - 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_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.
  * @param[in]       perm: descriptor access permission.
  * @param[in]       descr_uuid: descriptor UUID.
- *
+ * @param[in]       char_descr_val  : Characteristic descriptor value 
+ * @param[in]       control : attribute response control byte
  * @return
  *                  - ESP_OK : success
  *                  - other  : failed
  *
  */
 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);
 
 
+/**
+ * @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
  *

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

@@ -34,7 +34,6 @@
 #include "bta_gatts_int.h"
 #include "bta_gatts_co.h"
 #include "btm_ble_api.h"
-// #include "btif/include/btif_debug_conn.h"
 #include <string.h>
 
 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;
     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,
                                       &p_msg->api_add_char.char_uuid,
                                       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.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
     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);
     }
 }
+
 /*******************************************************************************
 **
 ** 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];
     UINT16          attr_id = 0;
     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,
                                       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.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

+ 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,
-                                  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;
-
+    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) {
         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->perm = perm;
         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) {
             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,
                                   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;
-    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) {
         memset(p_buf, 0, len);
@@ -269,10 +291,19 @@ void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
         if (p_descr_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);
     }
     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:
         bta_gatts_send_rsp(p_cb, (tBTA_GATTS_DATA *) p_msg);
         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:
         bta_gatts_listen(p_cb, (tBTA_GATTS_DATA *) p_msg);
         break;
-
-
     case BTA_GATTS_API_ADD_INCL_SRVC_EVT:
     case BTA_GATTS_API_ADD_CHAR_EVT:
     case BTA_GATTS_API_ADD_DESCR_EVT:
     case BTA_GATTS_API_DEL_SRVC_EVT:
     case BTA_GATTS_API_START_SRVC_EVT:
     case BTA_GATTS_API_STOP_SRVC_EVT:
-
         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);
 
         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);
         } else {
-            APPL_TRACE_ERROR("service not created");
+            APPL_TRACE_ERROR("service not created\n");
         }
         break;
-
     default:
         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 */
-#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;
 
@@ -151,7 +151,7 @@ typedef tGATT_IF tBTA_GATTC_IF;
 
 typedef struct {
     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;
     INT8                exp;
     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
 */
 #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;
 
 /* Characteristic Aggregate Format attribute value
@@ -367,8 +367,8 @@ typedef struct {
 // btla-specific --
 
 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;
 
 typedef union {
@@ -395,7 +395,6 @@ typedef void (tBTA_GATTC_ENB_CBACK)(tBTA_GATT_STATUS status);
 /* Client callback function */
 typedef void (tBTA_GATTC_CBACK)(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
 
-
 /* GATT Server Data Structure */
 /* Server callback function events */
 #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_LISTEN_EVT                            19
 #define BTA_GATTS_CONGEST_EVT                           20
+#define BTA_GATTS_SET_ATTR_VAL_EVT                      21
 
 typedef UINT8  tBTA_GATTS_EVT;
 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_MITM GATT_PERM_WRITE_SIGNED_MITM /* bit 8 -  0x0100 */
 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_IF    0
 
 /* 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;
 
 #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_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
 typedef UINT8 tBTA_GATT_TRANSPORT;
 
@@ -539,6 +541,13 @@ typedef struct {
 // btla-specific --
 } 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 {
     tBTA_GATTS_IF       server_if;
     UINT16              service_id;
@@ -566,17 +575,18 @@ typedef struct {
 
 /* GATTS callback data */
 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;
 
 /* GATTS enable callback function */
@@ -1193,8 +1203,9 @@ extern void BTA_GATTS_AddIncludeService(UINT16 service_id, UINT16 included_servi
 ** 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,
-        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);
 
 
+
+/*******************************************************************************
+**
+** 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

+ 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_STOP_SRVC_EVT,
     BTA_GATTS_API_RSP_EVT,
+    BTA_GATTS_API_SET_ATTR_VAL_EVT,
     BTA_GATTS_API_OPEN_EVT,
     BTA_GATTS_API_CANCEL_OPEN_EVT,
     BTA_GATTS_API_CLOSE_EVT,
@@ -91,19 +92,21 @@ typedef struct {
     tBT_UUID                char_uuid;
     tBTA_GATT_PERM          perm;
     tBTA_GATT_CHAR_PROP     property;
-
+    tBTA_GATTS_ATTR_CONTROL control;
+    tBTA_GATT_ATTR_VAL      attr_val;
 } tBTA_GATTS_API_ADD_CHAR;
 
 typedef struct {
     BT_HDR                  hdr;
     UINT16                  included_service_id;
-
 } tBTA_GATTS_API_ADD_INCL_SRVC;
 
 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;
 
 typedef struct {
@@ -121,6 +124,12 @@ typedef struct {
     tBTA_GATTS_RSP      *p_rsp;
 } tBTA_GATTS_API_RSP;
 
+typedef struct{
+    BT_HDR              hdr;
+    UINT16 length;
+    UINT8 *value;
+}tBTA_GATTS_API_SET_ATTR_VAL;
+
 typedef struct {
     BT_HDR                  hdr;
     tBTA_GATT_TRANSPORT     transport;
@@ -156,6 +165,7 @@ typedef union {
     tBTA_GATTS_API_START            api_start;
     tBTA_GATTS_API_INDICATION       api_indicate;
     tBTA_GATTS_API_RSP              api_rsp;
+    tBTA_GATTS_API_SET_ATTR_VAL     api_set_val;
     tBTA_GATTS_API_OPEN             api_open;
     tBTA_GATTS_API_CANCEL_OPEN      api_cancel_open;
 
@@ -169,7 +179,7 @@ typedef struct {
     BOOLEAN             in_use;
     tBT_UUID            app_uuid;
     tBTA_GATTS_CBACK    *p_cback;
-    tBTA_GATTS_IF        gatt_if;
+    tBTA_GATTS_IF       gatt_if;
 } tBTA_GATTS_RCB;
 
 /* 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_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
 extern void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
+extern void bta_gatts_set_attr_value(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
+extern void bta_gatts_get_attr_value(UINT16 attr_handle, UINT16 *length, UINT8 **value);
 extern void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
 extern void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
 extern void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);

+ 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;
 
     LOG_DEBUG("blufi profile cb event = %x\n", event);
+
     switch (event) {
     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);
@@ -187,7 +188,8 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
         //add the frist blufi characteristic --> write characteristic
         BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_p2e,
                                     (GATT_PERM_WRITE),
-                                    (GATT_CHAR_PROP_BIT_WRITE));
+                                    (GATT_CHAR_PROP_BIT_WRITE),
+                                    NULL, NULL);
         break;
     case BTA_GATTS_ADD_CHAR_EVT:
         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,
                                         (GATT_PERM_READ),
-                                        (GATT_PERM_READ | GATT_CHAR_PROP_BIT_NOTIFY));
+                                        (GATT_PERM_READ | GATT_CHAR_PROP_BIT_NOTIFY),
+                                        NULL, NULL);
             break;
          case BLUFI_CHAR_E2P_UUID:  /* ESP32 to Phone */
             blufi_env.handle_char_e2p = p_data->add_result.attr_id;
 
             BTA_GATTS_AddCharDescriptor (blufi_env.handle_srvc,
                                          (GATT_PERM_READ | GATT_PERM_WRITE),
-                                         &blufi_descr_uuid_e2p);
+                                         &blufi_descr_uuid_e2p,
+                                         NULL, NULL);
             break;
          default:
             break;

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

@@ -20,17 +20,30 @@
 #include "btc_manage.h"
 #include "btc_gatts.h"
 #include "btc_gatt_util.h"
-
+#include "future.h"
+#include "btc_main.h"
 #include "esp_gatts_api.h"
 
 #define A2C_GATTS_EVT(_bta_event) (_bta_event) //BTA TO BTC 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)
 {
     esp_gatts_cb_t btc_gatts_cb = (esp_gatts_cb_t)btc_profile_cb_get(BTC_PID_GATTS);
     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;
+    
+    }
+    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:
         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)
 {
@@ -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);
         }
         break;
-
     default:
         break;
     }
@@ -148,11 +367,43 @@ static void btc_gatts_inter_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
 {
     bt_status_t status;
     btc_msg_t msg;
-
+    
     msg.sig = BTC_SIG_API_CB;
     msg.pid = BTC_PID_GATTS;
     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,
                                   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);
         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:
         BTA_GATTS_DeleteService(arg->delete_srvc.service_handle);
         break;
@@ -204,13 +461,17 @@ void btc_gatts_call_handler(btc_msg_t *msg)
         btc_to_bta_uuid(&uuid, &arg->add_char.char_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;
     }
     case BTC_GATTS_ACT_ADD_CHAR_DESCR: {
         tBT_UUID 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;
     }
     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);
         break;
     }
+    case BTC_GATTS_ACT_SET_ATTR_VALUE:
+    
+    break;
     case BTC_GATTS_ACT_OPEN: {
         // Ensure device is in inquiry database
         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.id.inst_id = p_data->create.svc_instance;
         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);
         break;
     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;
         param.del.status = p_data->srvc_oper.status;
         param.del.service_handle = p_data->srvc_oper.service_id;
+
         btc_gatts_cb_to_app(ESP_GATTS_DELETE_EVT, gatts_if, &param);
         break;
     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);
         break;
     case BTA_GATTS_OPEN_EVT:
-    // do nothing
+        // do nothing
     case BTA_GATTS_CANCEL_OPEN_EVT:
-    // do nothing
+        // do nothing
     case BTA_GATTS_CLOSE_EVT:
-    // do nothing
+        // do nothing
     case BTA_GATTS_LISTEN_EVT:
         // do nothing
         break;
@@ -438,6 +704,13 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
         param.congest.congested = p_data->congest.congested;
         btc_gatts_cb_to_app(ESP_GATTS_CONGEST_EVT, gatts_if, &param);
         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:
         // do nothing
         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_UNREGISTER,
     BTC_GATTS_ACT_CREATE_SERVICE,
+    BTC_GATTS_ACT_CREATE_ATTR_TAB,
     BTC_GATTS_ACT_DELETE_SERVICE,
     BTC_GATTS_ACT_START_SERVICE,
     BTC_GATTS_ACT_STOP_SERVICE,
@@ -32,6 +33,7 @@ typedef enum {
     BTC_GATTS_ACT_ADD_CHAR_DESCR,
     BTC_GATTS_ACT_SEND_INDICATE,
     BTC_GATTS_ACT_SEND_RESPONSE,
+    BTC_GATTS_ACT_SET_ATTR_VALUE,
     BTC_GATTS_ACT_OPEN,
     BTC_GATTS_ACT_CLOSE,
 } btc_gatts_act_t;
@@ -42,46 +44,67 @@ typedef union {
     struct app_reg_args {
         uint16_t app_id;
     } app_reg;
+
     //BTC_GATTS_ACT_APP_UNREGISTER,
     struct app_unreg_args {
         esp_gatt_if_t gatts_if;
     } app_unreg;
+
     //BTC_GATTS_ACT_CREATE_SERVICE,
     struct create_srvc_args {
         esp_gatt_if_t gatts_if;
         esp_gatt_srvc_id_t service_id;
         uint16_t num_handle;
     } 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,
     struct delete_srvc_args {
         uint16_t service_handle;
     } delete_srvc;
+
     //BTC_GATTS_ACT_START_SERVICE,
     struct start_srvc_args {
         uint16_t service_handle;
     } start_srvc;
+
     //BTC_GATTS_ACT_STOP_SERVICE,
     struct stop_srvc_args {
         uint16_t service_handle;
     } stop_srvc;
+
     //BTC_GATTS_ACT_ADD_INCLUDE_SERVICE,
     struct add_incl_srvc_args {
         uint16_t service_handle;
         uint16_t included_service_handle;
     } add_incl_srvc;
+
     //BTC_GATTS_ACT_ADD_CHAR,
     struct add_char_args {
         uint16_t service_handle;
         esp_bt_uuid_t char_uuid;
         esp_gatt_perm_t perm;
         esp_gatt_char_prop_t property;
+        esp_attr_control_t attr_control;
+        esp_attr_value_t char_val;
     } add_char;
+
     //BTC_GATTS_ACT_ADD_CHAR_DESCR,
     struct add_descr_args {
-        uint16_t service_handle;
+        uint16_t  service_handle;
         esp_bt_uuid_t descr_uuid;
         esp_gatt_perm_t perm;
+        esp_attr_control_t attr_control;
+        esp_attr_value_t descr_val;
     } add_descr;
+
     //BTC_GATTS_ACT_SEND_INDICATE,
     struct send_indicate_args {
         uint16_t conn_id;
@@ -90,6 +113,7 @@ typedef union {
         uint16_t value_len;
         uint8_t *value;
     } send_ind;
+
     //BTC_GATTS_ACT_SEND_RESPONSE,
     struct send_rsp_args {
         uint16_t conn_id;
@@ -97,21 +121,32 @@ typedef union {
         esp_gatt_status_t status;
         esp_gatt_rsp_t *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,
     struct open_args {
         esp_gatt_if_t gatts_if;
         esp_bd_addr_t remote_bda;
         bool is_direct;
     } open;
+
     //BTC_GATTS_ACT_CLOSE,
     struct close_args {
         uint16_t conn_id;
     } close;
+
 } btc_ble_gatts_args_t;
 
 
 void btc_gatts_call_handler(btc_msg_t *msg);
 void btc_gatts_cb_handler(btc_msg_t *msg);
 void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
+void btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value);
+
 
 #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("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);
-                //buffer_allocator->free(partial_packet);
-                //LOG_ERROR("+++++++++++++++++++\n");
+               
+              
             }
 
             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.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 ++;
 
     /* add Icon characteristic
@@ -401,7 +402,8 @@ void gap_attr_db_init(void)
     p_db_attr->handle = GATTS_AddCharacteristic(service_handle,
                         &uuid,
                         GATT_PERM_READ,
-                        GATT_CHAR_PROP_BIT_READ);
+                        GATT_CHAR_PROP_BIT_READ,
+                        NULL, NULL);
     p_db_attr ++;
 
 #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,
                         &uuid,
                         GATT_PERM_READ,
-                        GATT_CHAR_PROP_BIT_READ);
+                        GATT_CHAR_PROP_BIT_READ,
+                        NULL, NULL);
     p_db_attr ++;
 #endif
 
@@ -424,7 +427,8 @@ void gap_attr_db_init(void)
     uuid.len = LEN_UUID_16;
     uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_CENTRAL_ADDR_RESOL;
     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++;
 

+ 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;
 
 
-    GATT_TRACE_API ("GATTS_CreateService" );
+    GATT_TRACE_API ("GATTS_CreateService\n" );
 
     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);
     }
 
@@ -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) {
         s_hdl = p_list->asgn_range.s_handle;
-        GATT_TRACE_DEBUG ("Service already been created!!");
+        GATT_TRACE_DEBUG ("Service already been created!!\n");
     } else {
         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;
@@ -184,13 +184,13 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
 
         /* check for space */
         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);
         }
 
         if ( (p_list = gatt_alloc_hdl_buffer()) == NULL) {
             /* No free entry */
-            GATT_TRACE_ERROR ("GATTS_ReserveHandles: no free handle blocks");
+            GATT_TRACE_ERROR ("GATTS_ReserveHandles: no free handle blocks\n");
             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 */
             if ( (p_buf = gatt_add_pending_new_srv_start(&p_list->asgn_range)) == NULL) {
                 /* 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) {
                     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);
             }
 
-            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)) {
-        GATT_TRACE_ERROR ("GATTS_ReserveHandles: service DB initialization failed");
+        GATT_TRACE_ERROR ("GATTS_ReserveHandles: service DB initialization failed\n");
         if (p_list) {
             gatt_remove_an_item_from_list(p_list_info, 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);
     }
 
-    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);
 }
 
@@ -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,
-                                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;
 
     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;
     }
     /* data validity checking */
     if (  ((property & GATT_CHAR_PROP_BIT_AUTH) && !(perm & GATT_WRITE_SIGNED_PERM)) ||
             ((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 gatts_add_characteristic(&p_decl->svc_db,
                                     perm,
                                     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,
                                 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;
 
@@ -353,7 +349,8 @@ UINT16 GATTS_AddCharDescriptor (UINT16 service_handle,
 
     return gatts_add_char_descr(&p_decl->svc_db,
                                 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_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->type,  p_sreg->service_instance,
                       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_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);
 
     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;
     }
 
     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);
 
         return (GATT_WRONG_STATE);
@@ -696,6 +693,69 @@ tGATT_STATUS GATTS_SendRsp (UINT16 conn_id,  UINT32 trans_id,
     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 */
 /*******************************************************************************/
@@ -1132,7 +1192,7 @@ tGATT_IF GATT_Register (tBT_UUID *p_app_uuid128, tGATT_CBACK *p_cb_info)
             break;
         }
     }
-    GATT_TRACE_API ("allocated gatt_if=%d", gatt_if);
+    GATT_TRACE_API ("allocated gatt_if=%d\n", 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);
 
     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
     */
     uuid.uu.uuid16 = gatt_cb.gattp_attr.uuid = GATT_UUID_GATT_SRV_CHGD;
     gatt_cb.gattp_attr.service_change = 0;
     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
     */
     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);
 }
 

+ 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);
 
     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;
     }
 
-    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 */
     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)
 {
     if (!p_db || !p_db->p_attr_list) {
-        GATT_TRACE_ERROR("service DB empty");
+        GATT_TRACE_ERROR("service DB empty\n");
 
         return NULL;
     } else {
@@ -127,28 +127,28 @@ static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr,
     }
 
     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;
     }
 
     if ((perm & GATT_READ_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED) &&
             !(sec_flag & BTM_SEC_FLAG_ENCRYPTED)) {
-        GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION");
+        GATT_TRACE_ERROR( "GATT_INSUF_AUTHENTICATION\n");
         return GATT_INSUF_AUTHENTICATION;
     }
 
     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;
     }
 
     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;
     }
 
     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;
     }
 
@@ -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_SRVR_CONFIG:
         case GATT_UUID_CHAR_PRESENT_FORMAT:
-            GATT_TRACE_ERROR("GATT_NOT_LONG");
+            GATT_TRACE_ERROR("GATT_NOT_LONG\n");
             return GATT_NOT_LONG;
 
         default:
@@ -206,7 +206,7 @@ static tGATT_STATUS read_attr_value (void *p_attr,
     tGATT_STATUS    status;
     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->permission,
                      sec_flag,
@@ -268,7 +268,22 @@ static tGATT_STATUS read_attr_value (void *p_attr,
             status = GATT_SUCCESS;
         }
     } 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;
@@ -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);
 
-                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);
 
                     /* 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,
                                  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;
     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 (!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.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;
     }
@@ -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,
-                             tBT_UUID      *p_descr_uuid)
+                             tBT_UUID  *p_descr_uuid,  tGATT_ATTR_VAL *attr_val, tGATTS_ATTR_CONTROL *control)
 {
     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 */
-    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.");
         return 0;
     } 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;
     }
 }
 
+
+/*******************************************************************************
+**
+** 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 */
 /*******************************************************************************/
@@ -617,6 +851,41 @@ tGATT_STATUS gatts_read_attr_value_by_handle(tGATT_TCB *p_tcb,
     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
@@ -661,6 +930,8 @@ tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db,
 
     return status;
 }
+
+
 /*******************************************************************************
 **
 ** 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);
 
     if (p_uuid == NULL) {
-        GATT_TRACE_ERROR("illegal UUID");
+        GATT_TRACE_ERROR("illegal UUID\n");
         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);
     }
 
-    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) {
-        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);
         return NULL;
     }
 
     if (p_db->mem_free < len) {
         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;
         }
     }
@@ -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) {
-        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);
     } 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);
     } 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->permission);
     }
     return (void *)p_attr16;
 }
 
+
+
 /*******************************************************************************
 **
 ** 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 (!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;
         }
     }

+ 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);
 
         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));
         }
     }
@@ -906,10 +906,10 @@ void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf)
                 }
             }
         } 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 {
-        GATT_TRACE_ERROR ("invalid data length, ignore");
+        GATT_TRACE_ERROR ("invalid data length, ignore\n");
     }
 
     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;
     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);
 
@@ -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) {
                 p_tcb->sr_cmd.p_rsp_msg = attp_build_sr_msg (p_tcb, (UINT8)(op_code + 1), (tGATT_SR_MSG *)p_msg);
             } 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_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;
 }
@@ -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_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);
 
@@ -871,7 +871,7 @@ static void gatts_process_mtu_req (tGATT_TCB *p_tcb, UINT16 len, UINT8 *p_data)
 **                  - discover characteristic by UUID
 **                  - 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)
@@ -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;
 
     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_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);
 
@@ -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 ((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;
         } 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;
         }
     }
-    if (reason != GATT_SUCCESS) {
+    if (reason != GATT_SUCCESS && reason != GATT_STACK_RSP) {
         if (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,
                               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));
 
+    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) {
     case GATT_REQ_PREPARE_WRITE:
         sr_data.write_req.is_prep = TRUE;
         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;
     /* fall through */
     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:
         if (op_code == GATT_REQ_WRITE || op_code == GATT_REQ_PREPARE_WRITE) {
             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.len = len;
         if (len != 0 && p != NULL) {
             memcpy (sr_data.write_req.value, p, len);
+	     
         }
         break;
     }
@@ -1035,18 +1053,26 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
                                           sec_flag,
                                           key_size);
 
+    p_msg->len += len;
     if (status == GATT_SUCCESS) {
         if ((trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle)) != 0) {
             p_sreg = &gatt_cb.sr_reg[i_rcb];
             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,
                                       trans_id,
                                       GATTS_REQ_TYPE_WRITE,
                                       &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 {
-            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 */
         }
     }
@@ -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,
                                    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);
     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;
     } 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;
     }
 
-    if (reason != GATT_SUCCESS) {
+    if (reason != GATT_SUCCESS && reason != GATT_PENDING) {
         if (p_msg) {
             GKI_freebuf(p_msg);
         }
 
         /* 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);
         }
     } else {
@@ -1149,7 +1175,7 @@ void gatts_process_attribute_req (tGATT_TCB *p_tcb, UINT8 op_code,
     tGATT_ATTR16    *p_attr;
 
     if (len < 2) {
-        GATT_TRACE_ERROR("Illegal PDU length, discard request");
+        GATT_TRACE_ERROR("Illegal PDU length, discard request\n");
         status = GATT_INVALID_PDU;
     } else {
         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
     gatt_cb.handle = handle;
     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);
 
@@ -1350,24 +1376,24 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code,
         /* otherwise, ignore the pkt */
     } else {
         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);
             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);
             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 */
             gatts_process_read_by_type_req(p_tcb, op_code, len, p_data);
             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_WRITE: /* write char/char descriptor value */
+        case GATT_REQ_WRITE: 					/* write char/char descriptor value */
         case GATT_CMD_WRITE:
         case GATT_SIGN_CMD_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;
 }
+
+/*******************************************************************************
+**
+** 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
@@ -1476,7 +1504,7 @@ tGATT_REG *gatt_get_regcb (tGATT_IF gatt_if)
     p_reg = &gatt_cb.cl_rcb[ii - 1];
 
     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;
     }
 

+ 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_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 */
 #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_EXE_WRITE         (0x00000001 << 11)
 #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 */
 
@@ -154,7 +157,7 @@ typedef union {
     tBT_UUID                uuid;               /* service declaration */
     tGATT_CHAR_DECL         char_decl;          /* characteristic declaration */
     tGATT_INCL_SRVC         incl_handle;        /* included service */
-
+    tGATT_ATTR_VAL          attr_val;
 } tGATT_ATTR_VALUE;
 
 /* Attribute UUID type
@@ -167,50 +170,49 @@ typedef UINT8   tGATT_ATTR_UUID_TYPE;
 /* 16 bits UUID Attribute in server database
 */
 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;
 
 /* 32 bits UUID Attribute in server database
 */
 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;
 
 
 /* 128 bits UUID Attribute in server database
 */
 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;
 
 /* Service Database definition
 */
 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;
 
 /* Data Structure used for GATT server                                        */
@@ -218,14 +220,14 @@ typedef struct {
 /* A service registration information record consists of beginning and ending */
 /* attribute handle, service UUID and a set of GATT server callback.          */
 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 */
-    UINT32          sdp_handle; /* primamry service SDP handle */
+    UINT32          sdp_handle;         /* primamry service SDP handle */
     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;
 } tGATT_SR_REG;
 
@@ -340,7 +342,7 @@ typedef struct {
     tGATT_CH_STATE  ch_state;
     UINT8           ch_flags;
 
-    tGATT_IF         app_hold_link[GATT_MAX_APPS];
+    tGATT_IF        app_hold_link[GATT_MAX_APPS];
 
     /* server needs */
     /* server response data */
@@ -350,13 +352,13 @@ typedef struct {
 
     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;
     UINT8           tcb_idx;
@@ -579,6 +581,7 @@ extern BOOLEAN gatt_cl_send_next_cmd_inq(tGATT_TCB *p_tcb);
 /* 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_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 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);
@@ -664,12 +667,27 @@ extern void gatt_set_sec_act(tGATT_TCB *p_tcb, tGATT_SEC_ACTION sec_act);
 /* 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 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,
         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,
         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,
         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);

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

@@ -63,6 +63,8 @@
 #define  GATT_ENCRYPED_NO_MITM               0x8d
 #define  GATT_NOT_ENCRYPTED                  0x8e
 #define  GATT_CONGESTED                      0x8f
+#define  GATT_STACK_RSP                      0x90
+#define  GATT_APP_RSP                        0x91
 
 /* 0xE0 ~ 0xFC reserved for future use */
 #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
 */
 #ifndef GATT_MAX_MTU_SIZE
-#define GATT_MAX_MTU_SIZE     517
+#define GATT_MAX_MTU_SIZE                   517
 #endif
 
 /* max legth of an attribute value
 */
 #ifndef GATT_MAX_ATTR_LEN
-#define GATT_MAX_ATTR_LEN     600
+#define GATT_MAX_ATTR_LEN                   600
 #endif
 
 /* default GATT MTU size over LE link
 */
-#define GATT_DEF_BLE_MTU_SIZE       23
+#define GATT_DEF_BLE_MTU_SIZE               23
 
 /* invalid connection ID
 */
-#define GATT_INVALID_CONN_ID        0xFFFF
+#define GATT_INVALID_CONN_ID                0xFFFF
 
 #ifndef GATT_CL_MAX_LCB
-#define GATT_CL_MAX_LCB     12 // 22
+#define GATT_CL_MAX_LCB                     12 // 22
 #endif
 
 #ifndef GATT_MAX_SCCB
-#define GATT_MAX_SCCB       10
+#define GATT_MAX_SCCB                       10
 #endif
 
 
 /* GATT notification caching timer, default to be three seconds
 */
 #ifndef GATTC_NOTIF_TIMEOUT
-#define GATTC_NOTIF_TIMEOUT   3
+#define GATTC_NOTIF_TIMEOUT                 3
 #endif
 
 /*****************************************************************************
@@ -155,22 +157,22 @@ typedef UINT16 tGATT_DISCONN_REASON;
 
 /* 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;
 
 #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 | \
@@ -312,6 +314,16 @@ typedef struct {
     UINT8           value[GATT_MAX_ATTR_LEN];  /* the actual attribute 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
 */
 typedef union {
@@ -740,8 +752,9 @@ extern UINT16 GATTS_AddIncludeService (UINT16 service_handle,
 **                  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,
-                                       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);
 
 
+/*******************************************************************************
+**
+** 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 */
 /*******************************************************************************/

+ 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] = {
     /* 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   */
-    /* 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   },
     /* 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   },

+ 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.
 Use should concern these things: 
 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
 -------------------

+ 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_REFRESH
 .. 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_IF_NONE
 
@@ -106,6 +108,27 @@ Enumerations
 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
     :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
     :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
     :members:
 
@@ -101,6 +104,9 @@ Structures
 .. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_rsp_evt_param
     :members:
 
+.. doxygenstruct:: esp_ble_gatts_cb_param_t::gatts_set_attr_val_evt_param
+    :members:
+
 
 Functions
 ^^^^^^^^^
@@ -109,6 +115,7 @@ Functions
 .. doxygenfunction:: esp_ble_gatts_app_register
 .. doxygenfunction:: esp_ble_gatts_app_unregister
 .. 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_char
 .. doxygenfunction:: esp_ble_gatts_add_char_descr
@@ -117,6 +124,8 @@ Functions
 .. doxygenfunction:: esp_ble_gatts_stop_service
 .. doxygenfunction:: esp_ble_gatts_send_indicate
 .. 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_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_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] = {
     /* LSB <--------------------------------------------------------------------------------> MSB */
     //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_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;
     case ESP_GATTS_ADD_INCL_SRVC_EVT:
         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].descr_uuid.len = ESP_UUID_LEN_16;
         gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
+        esp_ble_gatts_get_attr_value(param->add_char.attr_handle,  &length, &prf_char);
+
+        ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length);
+        for(int i = 0; i < length; i++){
+            ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n",i,prf_char[i]);
+        }
         esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid,
-                                     ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE);
+                                     ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
         break;
+    }
     case ESP_GATTS_ADD_CHAR_DESCR_EVT:
         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);
@@ -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_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;
     case ESP_GATTS_ADD_INCL_SRVC_EVT:
         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.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_GATT_PERM_READ | ESP_GATT_PERM_WRITE);
+                                     ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
+                                     NULL, NULL);
         break;
     case ESP_GATTS_ADD_CHAR_DESCR_EVT:
         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