]> granicus.if.org Git - esp-idf/commitdiff
component bt:Added the create attribute table method to the new API
authorYulong <huangyulong@espressif.com>
Fri, 23 Dec 2016 16:28:47 +0000 (11:28 -0500)
committerTian Hao <tianhao@espressif.com>
Wed, 11 Jan 2017 08:57:19 +0000 (16:57 +0800)
37 files changed:
components/bt/bluedroid/api/esp_blufi_api.c
components/bt/bluedroid/api/esp_bt_main.c
components/bt/bluedroid/api/esp_gap_ble_api.c
components/bt/bluedroid/api/esp_gattc_api.c
components/bt/bluedroid/api/esp_gatts_api.c
components/bt/bluedroid/api/include/esp_gap_ble_api.h
components/bt/bluedroid/api/include/esp_gatt_defs.h
components/bt/bluedroid/api/include/esp_gatts_api.h
components/bt/bluedroid/bta/gatt/bta_gatts_act.c
components/bt/bluedroid/bta/gatt/bta_gatts_api.c
components/bt/bluedroid/bta/gatt/bta_gatts_main.c
components/bt/bluedroid/bta/include/bta_gatt_api.h
components/bt/bluedroid/bta/include/bta_gatts_int.h
components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c
components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c
components/bt/bluedroid/btc/profile/std/include/btc_gatts.h
components/bt/bluedroid/hci/packet_fragmenter.c
components/bt/bluedroid/stack/gap/gap_ble.c
components/bt/bluedroid/stack/gatt/gatt_api.c
components/bt/bluedroid/stack/gatt/gatt_attr.c
components/bt/bluedroid/stack/gatt/gatt_db.c
components/bt/bluedroid/stack/gatt/gatt_main.c
components/bt/bluedroid/stack/gatt/gatt_sr.c
components/bt/bluedroid/stack/gatt/gatt_utils.c
components/bt/bluedroid/stack/gatt/include/gatt_int.h
components/bt/bluedroid/stack/include/gatt_api.h
components/bt/bluedroid/stack/smp/smp_main.c
docs/api/esp_blufi.rst
docs/api/esp_gatt_defs.rst
docs/api/esp_gatts.rst
examples/14_gatt_server/main/gatts_demo.c
examples/30_gatt_server_table_create/Makefile [new file with mode: 0644]
examples/30_gatt_server_table_create/README.rst [new file with mode: 0644]
examples/30_gatt_server_table_create/main/component.mk [new file with mode: 0644]
examples/30_gatt_server_table_create/main/gatts_table_creat_demo.c [new file with mode: 0644]
examples/30_gatt_server_table_create/main/gatts_table_creat_demo.h [new file with mode: 0644]
examples/30_gatt_server_table_create/sdkconfig.defaults [new file with mode: 0644]

index 70f5c9ce8f37e098d571650bb4602b83c9e38484..00fbeffbc98575b7d9895089d37a548a0ea8523b 100644 (file)
@@ -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;
index 3093b56403da7831448fac165ee6a6d0c174f445..c9fe4fc060e97a96c99526a9d9ad572825d33835 100644 (file)
@@ -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;
     }
 }
 
index f9401d8c42c53276af58d8b320579ad7989e9107..56bedc4242190fd6d428d8f9c414d8d448613051 100644 (file)
@@ -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;
     }
index 8b9cc99e87ef5d877c8487107ecd0f98dfa7a06b..4f68d81cc0c24c3073d6dd3f37c844c950112225 100644 (file)
@@ -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;
index 71b5a4338c0cbd9be5cd8af9c0bad81a86d00340..f5ebe59a2d3d1afa88eb8af880dd72c9087a8f6c 100644 (file)
 
 #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);
 }
index f92143e6af859f5e2da391df34b4ee8994d353c0..1d27edb8812493fcaf964cc41c5d80aeb2762187 100644 (file)
@@ -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);
index 7b119a62cd1c4dd6a0e66aef6036d0ba63409b06..f8b2302111dbe56c79f6c4a2dd4504bf5ffaf393 100644 (file)
@@ -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
 }
index d0fc055a7fdf2d1c30b6fbab5b20e6f8219578f8..86a539597ac8695e78ac3c18f00f96e4fb9c6695 100644 (file)
@@ -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
  *
index 04bb3ee7cba7733362fb8692392acbe02cbeb617..9dd2ea4039e0c0506dd61003e0c684df82fa17a2 100644 (file)
@@ -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
index d54935120c1c71f89a339c365f665e6ff22d807d..58e226c839ebd823fcb493427d544b6e32607836 100644 (file)
@@ -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);
+}
 
 /*******************************************************************************
 **
index d59115d42de0d62225b4b3a9262a9a52b35b8632..4306709c8ca859505bb7213fd018d22becf461f0 100644 (file)
@@ -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;
     }
index d10ca46aeea79154cd09a74d9af5903686077ccf..f4c0e06f0789dd0ad42b141c1bf257930a69dac8 100644 (file)
@@ -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
index f934c4ac6a60c8887140ba261c2bdb04554367ba..0f9e689acea441ba538f16d529c18bac0c416262 100644 (file)
@@ -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);
index e88c775f5ff79759e3f8d01114b4676cf736932b..7866ca0f806a991d5e3792230b40567d0ec40ad8 100644 (file)
@@ -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;
index 9bc41d2ab1db6af0e8a33141dd09a87def29c8f9..255484fbc4bbc32624e49da407639b0d10c261c7 100644 (file)
 #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;
index 4ad276f3ecaf9ecf48d6ecd92ed0feabf7f21a80..caae44de44c6b6ed0b1ff9493d7796acde73d5cd 100644 (file)
@@ -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__ */
index bd46041c3b7c901e6696de1afef38fa12d44bd57..9294cb5bbbea9c19cc9790d39887b0f56d22f4b1 100644 (file)
@@ -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;
index b560fad6519a782c51394df350b842c705cdde4c..bf9ea08369f7e85ffd4ffd63e4fb6334f3379f73 100644 (file)
@@ -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++;
 
index c464508da9172eeff202332e9c4d6dd1ee0a7125..7a9d125a97440ba7e4cdcb0631fe6f4afe939df1 100644 (file)
@@ -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;
 }
 
index 49688283947caf73e6a1d2e6cc0fca45fa72a7ed..421b17cab7696f4cd146f5fc08f1094f7cee3183 100644 (file)
@@ -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);
 }
 
index 2e74c7d2dfb09311fe1cc16fc6506c33127ada23..b95934a8fa583e3f4762f494f378090395ddc556 100644 (file)
@@ -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;
         }
     }
index 8b40ed0e5197e6c2f8f418ced64a658d5a596b23..d7997a847fc742ee1808a5f8c1894e6be7d3f496 100644 (file)
@@ -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);
index 4846d4ad3e57b086c18e622c9f6b828999076d9d..6f21e8c45d1d7c2fb90db84339bf361270b259e3 100644 (file)
@@ -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:
index 7b55a097c9dae617424c583cc05bd9086857c9d4..09f4e8df2fae9149942842b71e6fd552fdfa8a31 100644 (file)
@@ -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;
     }
 
index 1ac8431b3b9862ac01ff250048f1eda2d07fdd50..c9622a24c1ded39449bcea35dac7cedcecdddf0a 100644 (file)
 #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);
index a365ca9deec4c1bec7a98b7096fa636db4e8d065..c460a65538774b6a56a90257e5fb0e2e243eefae 100644 (file)
@@ -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 */
 /*******************************************************************************/
index 85b232aea8aa5d82f7d9943f5d96c9aa1007b365..cad6427464f6c1d2043ff9eaa24798bb51fa6402 100644 (file)
@@ -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   },
index 9dd80851665d02ed2813e1abb78b3b0148e7763d..13432dc1542fcb3f7542321497d3b26b844f2d2f 100644 (file)
@@ -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
 -------------------
index 637acaab9902ba7b903e2c03a38897ba70fb2e61..9eeac6193ca56d742a6945779cfe8407b0ea7f4a 100644 (file)
@@ -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:
 
index fbaa1c236db830306e610269b5290122626e0129..9e3749df0ac45f7c838e51a3cdec8f9766c6cedd 100644 (file)
@@ -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
 
index 9b3b6cc802ad16fb8592d8e8a84e8cf6b9d24142..98feaa2240325de711b535e45053a692eef4eff5 100644 (file)
@@ -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",
diff --git a/examples/30_gatt_server_table_create/Makefile b/examples/30_gatt_server_table_create/Makefile
new file mode 100644 (file)
index 0000000..a6e41ff
--- /dev/null
@@ -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
+
diff --git a/examples/30_gatt_server_table_create/README.rst b/examples/30_gatt_server_table_create/README.rst
new file mode 100644 (file)
index 0000000..7a76399
--- /dev/null
@@ -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.
+
diff --git a/examples/30_gatt_server_table_create/main/component.mk b/examples/30_gatt_server_table_create/main/component.mk
new file mode 100644 (file)
index 0000000..79edf03
--- /dev/null
@@ -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.
+#
diff --git a/examples/30_gatt_server_table_create/main/gatts_table_creat_demo.c b/examples/30_gatt_server_table_create/main/gatts_table_creat_demo.c
new file mode 100644 (file)
index 0000000..f4511f6
--- /dev/null
@@ -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) 
+{\r
+    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;
+}
diff --git a/examples/30_gatt_server_table_create/main/gatts_table_creat_demo.h b/examples/30_gatt_server_table_create/main/gatts_table_creat_demo.h
new file mode 100644 (file)
index 0000000..ecce340
--- /dev/null
@@ -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;
diff --git a/examples/30_gatt_server_table_create/sdkconfig.defaults b/examples/30_gatt_server_table_create/sdkconfig.defaults
new file mode 100644 (file)
index 0000000..e435f38
--- /dev/null
@@ -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