Przeglądaj źródła

Component/bt: add gatts send service change indication API

zhiweijian 7 lat temu
rodzic
commit
9fb188a1d9

+ 26 - 0
components/bt/Kconfig

@@ -349,6 +349,32 @@ config GATTS_ENABLE
     help
         This option can be disabled when the app work only on gatt client mode
 
+choice GATTS_SEND_SERVICE_CHANGE_MODE
+    prompt "GATTS Service Change Mode"
+    default GATTS_SEND_SERVICE_CHANGE_AUTO
+    depends on GATTS_ENABLE
+    help
+        Service change indication mode for GATT Server.
+
+config GATTS_SEND_SERVICE_CHANGE_MANUAL
+    bool "GATTS manually send service change indication"
+    help
+        Manually send service change indication through API esp_ble_gatts_send_service_change_indication()
+
+config GATTS_SEND_SERVICE_CHANGE_AUTO
+    bool "GATTS automatically send service change indication"
+    help
+        Let Bluedroid handle the service change indication internally
+
+endchoice
+
+config GATTS_SEND_SERVICE_CHANGE_MODE
+    int
+    depends on GATTS_ENABLE
+    default 0 if GATTS_SEND_SERVICE_CHANGE_AUTO
+    default 1 if GATTS_SEND_SERVICE_CHANGE_MANUAL
+    default 0
+
 config GATTC_ENABLE
     bool "Include GATT client module(GATTC)"
     depends on BLUEDROID_ENABLED && (BTDM_CONTROLLER_MODE_BTDM || BTDM_CONTROLLER_MODE_BLE_ONLY)

+ 21 - 0
components/bt/bluedroid/api/esp_gatts_api.c

@@ -361,6 +361,27 @@ esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id)
             == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 
+esp_err_t esp_ble_gatts_send_service_change_indication(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda)
+{
+    btc_msg_t msg;
+    btc_ble_gatts_args_t arg;
+
+    ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
+    
+    msg.sig = BTC_SIG_API_CALL;
+    msg.pid = BTC_PID_GATTS;
+    msg.act = BTC_GATTS_ACT_SEND_SERVICE_CHANGE;
+    arg.send_service_change.gatts_if = gatts_if;
+    if(remote_bda) {
+        memcpy(&arg.send_service_change.remote_bda, remote_bda, sizeof(esp_bd_addr_t));   
+    } else {
+        memset(arg.send_service_change.remote_bda, 0, 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);
+}
 
 static esp_err_t esp_ble_gatts_add_char_desc_param_check(esp_attr_value_t *char_val, esp_attr_control_t *control)
 {

+ 48 - 24
components/bt/bluedroid/api/include/api/esp_gatts_api.h

@@ -25,31 +25,32 @@ 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 */
+    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_RESPONSE_EVT            = 21,      /*!< When gatt send response complete, the event comes */
+    ESP_GATTS_CREAT_ATTR_TAB_EVT      = 22,      /*!< When gatt create table complete, the event comes */
+    ESP_GATTS_SET_ATTR_VAL_EVT        = 23,      /*!< When gatt set attr value complete, the event comes */
+    ESP_GATTS_SEND_SERVICE_CHANGE_EVT = 24,      /*!< When gatt send service change indication complete, the event comes */
 } esp_gatts_cb_event_t;
 
 /**
@@ -267,6 +268,13 @@ typedef union {
         esp_gatt_status_t status;       /*!< Operation status*/
     } set_attr_val;                     /*!< Gatt server callback param of ESP_GATTS_SET_ATTR_VAL_EVT */
 
+    /**
+    * @brief ESP_GATTS_SEND_SERVICE_CHANGE_EVT
+    */
+    struct gatts_send_service_change_evt_param{
+        esp_gatt_status_t status;       /*!< Operation status*/
+    } service_change;                    /*!< Gatt server callback param of ESP_GATTS_SEND_SERVICE_CHANGE_EVT */
+
 } esp_ble_gatts_cb_param_t;
 
 /**
@@ -550,6 +558,22 @@ esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, b
  */
 esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id);
 
+/**
+ * @brief           Send service change indication
+ *
+ * @param[in]       gatts_if: GATT server access interface
+ * @param[in]       remote_bda: remote device bluetooth device address.
+ *                  If remote_bda is NULL then it will send service change
+ *                  indication to all the connected devices and if not then
+ *                  to a specific device
+ *
+ * @return
+ *                  - ESP_OK : success
+ *                  - other  : failed
+ *
+ */
+esp_err_t esp_ble_gatts_send_service_change_indication(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda);
+
 #ifdef __cplusplus
 }
 #endif

+ 30 - 0
components/bt/bluedroid/bta/gatt/bta_gatts_act.c

@@ -829,6 +829,36 @@ void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
     }
 
 }
+
+/*******************************************************************************
+**
+** Function         bta_gatts_send_service_change_indication
+**
+** Description      gatts send service change indication
+**
+** Returns          none.
+**
+*******************************************************************************/
+void bta_gatts_send_service_change_indication (tBTA_GATTS_DATA *p_msg)
+{
+    tBTA_GATTS_RCB     *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_send_service_change.server_if);
+    tBTA_GATTS_SERVICE_CHANGE    service_change;
+    tBTA_GATT_STATUS status = BTA_GATT_OK;
+    UINT16 addr[BD_ADDR_LEN] = {0};
+    if(memcmp(p_msg->api_send_service_change.remote_bda, addr, BD_ADDR_LEN) != 0) {
+        BD_ADDR bd_addr;
+        memcpy(bd_addr, p_msg->api_send_service_change.remote_bda, BD_ADDR_LEN);
+        status = GATT_SendServiceChangeIndication(bd_addr);
+    } else {
+        status = GATT_SendServiceChangeIndication(NULL);    
+    }
+    if (p_rcb && p_rcb->p_cback) {
+        service_change.status = status;
+        service_change.server_if = p_msg->api_send_service_change.server_if;
+        (*p_rcb->p_cback)(BTA_GATTS_SEND_SERVICE_CHANGE_EVT,  (tBTA_GATTS *)&service_change);
+    }   
+}
+
 /*******************************************************************************
 **
 ** Function         bta_gatts_listen

+ 17 - 0
components/bt/bluedroid/bta/gatt/bta_gatts_api.c

@@ -581,6 +581,23 @@ void BTA_GATTS_Close(UINT16 conn_id)
     return;
 
 }
+
+void BTA_GATTS_SendServiceChangeIndication(tBTA_GATTS_IF server_if, BD_ADDR remote_bda)
+{
+    tBTA_GATTS_API_SEND_SERVICE_CHANGE  *p_buf;
+
+    if ((p_buf = (tBTA_GATTS_API_SEND_SERVICE_CHANGE *) osi_malloc(sizeof(tBTA_GATTS_API_SEND_SERVICE_CHANGE))) != NULL) {
+        memset(p_buf, 0, sizeof(tBTA_GATTS_API_SEND_SERVICE_CHANGE));
+        p_buf->hdr.event = BTA_GATTS_API_SEND_SERVICE_CHANGE_EVT;
+        p_buf->server_if = server_if;
+        memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
+        
+        bta_sys_sendmsg(p_buf);
+    }
+    return;
+
+}
+
 /*******************************************************************************
 **
 ** Function         BTA_GATTS_Listen

+ 3 - 0
components/bt/bluedroid/bta/gatt/bta_gatts_main.c

@@ -130,6 +130,9 @@ BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg)
             APPL_TRACE_ERROR("service not created\n");
         }
         break;
+    case BTA_GATTS_API_SEND_SERVICE_CHANGE_EVT:
+        bta_gatts_send_service_change_indication((tBTA_GATTS_DATA *) p_msg);
+        break;
     default:
         break;
     }

+ 10 - 1
components/bt/bluedroid/bta/gatt/include/bta_gatts_int.h

@@ -52,7 +52,8 @@ enum {
     BTA_GATTS_API_CANCEL_OPEN_EVT,
     BTA_GATTS_API_CLOSE_EVT,
     BTA_GATTS_API_LISTEN_EVT,
-    BTA_GATTS_API_DISABLE_EVT
+    BTA_GATTS_API_DISABLE_EVT,
+    BTA_GATTS_API_SEND_SERVICE_CHANGE_EVT
 };
 typedef UINT16 tBTA_GATTS_INT_EVT;
 
@@ -153,6 +154,12 @@ typedef struct {
     BOOLEAN                 start;
 } tBTA_GATTS_API_LISTEN;
 
+typedef struct {
+    BT_HDR                  hdr;
+    tBTA_GATTS_IF           server_if;
+    BD_ADDR                 remote_bda;
+} tBTA_GATTS_API_SEND_SERVICE_CHANGE;
+
 typedef union {
     BT_HDR                          hdr;
     tBTA_GATTS_API_REG              api_reg;
@@ -171,6 +178,7 @@ typedef union {
     tBTA_GATTS_INT_START_IF         int_start_if;
     /* if peripheral role is supported */
     tBTA_GATTS_API_LISTEN           api_listen;
+    tBTA_GATTS_API_SEND_SERVICE_CHANGE api_send_service_change;
 } tBTA_GATTS_DATA;
 
 /* application registration control block */
@@ -242,6 +250,7 @@ extern void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
 extern void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
 extern void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
 extern void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
+extern void bta_gatts_send_service_change_indication (tBTA_GATTS_DATA *p_msg);
 
 extern BOOLEAN bta_gatts_uuid_compare(tBT_UUID tar, tBT_UUID src);
 extern tBTA_GATTS_RCB *bta_gatts_find_app_rcb_by_app_if(tBTA_GATTS_IF server_if);

+ 19 - 0
components/bt/bluedroid/bta/include/bta/bta_gatt_api.h

@@ -463,6 +463,7 @@ typedef void (tBTA_GATTC_CBACK)(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
 #define BTA_GATTS_LISTEN_EVT                            19
 #define BTA_GATTS_CONGEST_EVT                           20
 #define BTA_GATTS_SET_ATTR_VAL_EVT                      23
+#define BTA_GATTS_SEND_SERVICE_CHANGE_EVT               24
 
 typedef UINT8  tBTA_GATTS_EVT;
 typedef tGATT_IF tBTA_GATTS_IF;
@@ -618,6 +619,11 @@ typedef struct {
     UINT16              conn_id;    /* connection ID */
 } tBTA_GATTS_CLOSE;
 
+typedef struct {
+    tBTA_GATT_STATUS    status;
+    tBTA_GATTS_IF       server_if;
+} tBTA_GATTS_SERVICE_CHANGE;
+
 typedef struct {
     tBTA_GATT_STATUS    status;
     tBTA_GATTS_IF       server_if;
@@ -644,6 +650,7 @@ typedef union {
     tBTA_GATTS_CLOSE            close;          /* BTA_GATTS_CLOSE_EVT callback data */
     tBTA_GATTS_OPEN             open;           /* BTA_GATTS_OPEN_EVT callback data */
     tBTA_GATTS_CANCEL_OPEN      cancel_open;    /* tBTA_GATTS_CANCEL_OPEN callback data */
+    tBTA_GATTS_SERVICE_CHANGE   service_change;
 
 } tBTA_GATTS;
 
@@ -1454,6 +1461,18 @@ extern void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BO
 *******************************************************************************/
 extern void BTA_GATTS_Close(UINT16 conn_id);
 
+/*******************************************************************************
+**
+** Function         BTA_GATTS_SendServiceChangeIndication
+**
+** Description     send a service change indication.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void BTA_GATTS_SendServiceChangeIndication(tBTA_GATTS_IF server_if, BD_ADDR remote_bda);
+
 /*******************************************************************************
 **
 ** Function         BTA_GATTS_Listen

+ 11 - 1
components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c

@@ -714,6 +714,12 @@ void btc_gatts_call_handler(btc_msg_t *msg)
         }
 
         break;
+    case BTC_GATTS_ACT_SEND_SERVICE_CHANGE: {
+        BD_ADDR remote_bda;
+        memcpy(remote_bda, arg->send_service_change.remote_bda, BD_ADDR_LEN);
+        BTA_GATTS_SendServiceChangeIndication(arg->send_service_change.gatts_if, remote_bda);
+        break;
+    }
     default:
         break;
     }
@@ -897,7 +903,11 @@ void btc_gatts_cb_handler(btc_msg_t *msg)
 
         btc_gatts_cb_to_app(BTA_GATTS_CLOSE_EVT, gatts_if, &param);
         break;
-
+    case BTA_GATTS_SEND_SERVICE_CHANGE_EVT:
+        gatts_if = p_data->service_change.server_if;
+        param.service_change.status = p_data->service_change.status;
+        btc_gatts_cb_to_app(ESP_GATTS_SEND_SERVICE_CHANGE_EVT, gatts_if, &param);
+        break;
     case BTA_GATTS_LISTEN_EVT:
         // do nothing
         break;

+ 7 - 0
components/bt/bluedroid/btc/profile/std/include/btc_gatts.h

@@ -36,6 +36,7 @@ typedef enum {
     BTC_GATTS_ACT_SET_ATTR_VALUE,
     BTC_GATTS_ACT_OPEN,
     BTC_GATTS_ACT_CLOSE,
+    BTC_GATTS_ACT_SEND_SERVICE_CHANGE,
 } btc_gatts_act_t;
 
 /* btc_ble_gatts_args_t */
@@ -141,6 +142,12 @@ typedef union {
         uint16_t conn_id;
     } close;
 
+    //BTC_GATTS_ACT_SEND_SERVICE_CHANGE,
+    struct send_service_change_args {
+        esp_gatt_if_t gatts_if;
+        esp_bd_addr_t remote_bda;
+    } send_service_change;
+
 } btc_ble_gatts_args_t;
 
 

+ 6 - 0
components/bt/bluedroid/common/include/common/bt_target.h

@@ -318,6 +318,12 @@
 #define SCAN_QUEUE_CONGEST_CHECK  CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK
 #endif
 
+#ifndef CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE
+#define GATTS_SEND_SERVICE_CHANGE_MODE GATTS_SEND_SERVICE_CHANGE_AUTO
+#else
+#define GATTS_SEND_SERVICE_CHANGE_MODE CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE
+#endif
+
 /* This feature is used to eanble interleaved scan*/
 #ifndef BTA_HOST_INTERLEAVE_SEARCH
 #define BTA_HOST_INTERLEAVE_SEARCH FALSE//FALSE

+ 51 - 2
components/bt/bluedroid/stack/gatt/gatt_api.c

@@ -398,7 +398,9 @@ BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, UINT16 svc_
         GATT_TRACE_DEBUG ("Delete a new service changed item - the service has not yet started");
         osi_free(fixed_queue_try_remove_from_queue(gatt_cb.pending_new_srv_start_q, p_buf));
     } else {
-        gatt_proc_srv_chg();
+        if (GATTS_SEND_SERVICE_CHANGE_MODE == GATTS_SEND_SERVICE_CHANGE_AUTO) {
+            gatt_proc_srv_chg();
+        }
     }
 
     if ((i_sreg = gatt_sr_find_i_rcb_by_app_id (p_app_uuid128,
@@ -508,7 +510,9 @@ tGATT_STATUS GATTS_StartService (tGATT_IF gatt_if, UINT16 service_handle,
     if ( (p_buf = gatt_sr_is_new_srv_chg(&p_list->asgn_range.app_uuid128,
                                          &p_list->asgn_range.svc_uuid,
                                          p_list->asgn_range.svc_inst)) != NULL) {
-        gatt_proc_srv_chg();
+        if (GATTS_SEND_SERVICE_CHANGE_MODE == GATTS_SEND_SERVICE_CHANGE_AUTO) {
+            gatt_proc_srv_chg();
+        }
         /* remove the new service element after the srv changed processing is completed*/
 
         osi_free(fixed_queue_try_remove_from_queue(gatt_cb.pending_new_srv_start_q, p_buf));
@@ -1468,6 +1472,51 @@ tGATT_STATUS GATT_Disconnect (UINT16 conn_id)
     return ret;
 }
 
+/*******************************************************************************
+**
+** Function         GATT_SendServiceChangeIndication
+**
+** Description      This function is to send a service change indication
+**
+** Parameters       bd_addr: peer device address.
+**
+** Returns          None.
+**
+*******************************************************************************/
+tGATT_STATUS GATT_SendServiceChangeIndication (BD_ADDR bd_addr)
+{
+    UINT8               start_idx, found_idx;
+    BOOLEAN             srv_chg_ind_pending = FALSE;
+    tGATT_TCB           *p_tcb;
+    tBT_TRANSPORT      transport;
+    tGATT_STATUS status = GATT_NOT_FOUND;
+    if (GATTS_SEND_SERVICE_CHANGE_MODE == GATTS_SEND_SERVICE_CHANGE_AUTO) {
+        status = GATT_WRONG_STATE;
+        GATT_TRACE_ERROR ("%s can't send service change indication manually, please configure the option through menuconfig", __func__);
+        return status;
+    }
+
+    if(bd_addr) {
+         status = gatt_send_srv_chg_ind(bd_addr);
+    } else {
+        start_idx = 0;
+        BD_ADDR addr;
+        while (gatt_find_the_connected_bda(start_idx, addr, &found_idx, &transport)) {
+            p_tcb = &gatt_cb.tcb[found_idx];
+            srv_chg_ind_pending = gatt_is_srv_chg_ind_pending(p_tcb);
+
+            if (!srv_chg_ind_pending) {
+                status = gatt_send_srv_chg_ind(addr);    
+            } else {
+                status = GATT_BUSY;
+                GATT_TRACE_DEBUG("discard srv chg - already has one in the queue");
+            }
+            start_idx = ++found_idx;
+        }
+    }
+
+    return status;
+}
 
 /*******************************************************************************
 **

+ 12 - 0
components/bt/bluedroid/stack/gatt/gatt_attr.c

@@ -303,6 +303,18 @@ void gatt_profile_db_init (void)
 
     GATT_TRACE_DEBUG ("gatt_profile_db_init:  handle of service changed%d\n",
                       gatt_cb.handle_of_h_r);
+    
+    tBT_UUID descr_uuid = {LEN_UUID_16, {GATT_UUID_CHAR_CLIENT_CONFIG}};
+    uint8_t ccc_value[2] ={ 0x00, 0x00};
+    tGATTS_ATTR_CONTROL control ={1};
+
+    tGATT_ATTR_VAL  attr_val = {
+        .attr_max_len = sizeof(UINT16),
+        .attr_len = sizeof(UINT16),
+        .attr_val = ccc_value,
+    };
+
+    GATTS_AddCharDescriptor (service_handle, GATT_PERM_READ | GATT_PERM_WRITE , &descr_uuid, &attr_val, &control);
 
     /* start service
     */

+ 11 - 10
components/bt/bluedroid/stack/gatt/gatt_main.c

@@ -1022,35 +1022,36 @@ void gatt_add_a_bonded_dev_for_srv_chg (BD_ADDR bda)
 **
 ** Function         gatt_send_srv_chg_ind
 **
-** Description      This function is called to send a service chnaged indication to
+** Description      This function is called to send a service changed indication to
 **                  the specified bd address
 **
-** Returns          void
+** Returns          GATT_SUCCESS if sucessfully sent; otherwise error code
 **
 *******************************************************************************/
 #if (GATTS_INCLUDED == TRUE)
-void gatt_send_srv_chg_ind (BD_ADDR peer_bda)
+tGATT_STATUS gatt_send_srv_chg_ind (BD_ADDR peer_bda)
 {
     UINT8   handle_range[GATT_SIZE_OF_SRV_CHG_HNDL_RANGE];
     UINT8   *p = handle_range;
     UINT16  conn_id;
-
+    tGATT_STATUS  status = GATT_ERROR;
     GATT_TRACE_DEBUG("gatt_send_srv_chg_ind");
 
     if (gatt_cb.handle_of_h_r) {
         if ((conn_id = gatt_profile_find_conn_id_by_bd_addr(peer_bda)) != GATT_INVALID_CONN_ID) {
             UINT16_TO_STREAM (p, 1);
             UINT16_TO_STREAM (p, 0xFFFF);
-            GATTS_HandleValueIndication (conn_id,
+            status = GATTS_HandleValueIndication (conn_id,
                                          gatt_cb.handle_of_h_r,
                                          GATT_SIZE_OF_SRV_CHG_HNDL_RANGE,
                                          handle_range);
         } else {
-            GATT_TRACE_ERROR("Unable to find conn_id for  %08x%04x ",
-                             (peer_bda[0] << 24) + (peer_bda[1] << 16) + (peer_bda[2] << 8) + peer_bda[3],
-                             (peer_bda[4] << 8) + peer_bda[5] );
+            status = GATT_NOT_FOUND;
+            GATT_TRACE_ERROR("Unable to find conn_id for  %02x%02x%02x%02x%02x%02x ",
+                             peer_bda[0], peer_bda[1],  peer_bda[2], peer_bda[3], peer_bda[4], peer_bda[5]);
         }
     }
+    return status;
 }
 
 
@@ -1058,7 +1059,7 @@ void gatt_send_srv_chg_ind (BD_ADDR peer_bda)
 **
 ** Function         gatt_chk_srv_chg
 **
-** Description      Check sending service chnaged Indication is required or not
+** Description      Check sending service changed Indication is required or not
 **                  if required then send the Indication
 **
 ** Returns          void
@@ -1142,7 +1143,7 @@ void gatt_proc_srv_chg (void)
         gatt_set_srv_chg();
         start_idx = 0;
         while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) {
-            p_tcb = &gatt_cb.tcb[found_idx];;
+            p_tcb = &gatt_cb.tcb[found_idx];
             srv_chg_ind_pending  = gatt_is_srv_chg_ind_pending(p_tcb);
 
             if (!srv_chg_ind_pending) {

+ 4 - 1
components/bt/bluedroid/stack/gatt/include/gatt_int.h

@@ -102,6 +102,9 @@ typedef UINT8 tGATT_SEC_FLAG;
 #define GATT_INFO_TYPE_PAIR_16      0x01
 #define GATT_INFO_TYPE_PAIR_128     0x02
 
+#define GATTS_SEND_SERVICE_CHANGE_AUTO   0
+#define GATTS_SEND_SERVICE_CHANGE_MANUAL 1
+
 /*  GATT client FIND_TYPE_VALUE_Request data */
 typedef struct {
     tBT_UUID        uuid;           /* type of attribute to be found */
@@ -582,7 +585,7 @@ extern void gatt_set_ch_state(tGATT_TCB *p_tcb, tGATT_CH_STATE ch_state);
 extern tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB *p_tcb);
 extern void gatt_init_srv_chg(void);
 extern void gatt_proc_srv_chg (void);
-extern void gatt_send_srv_chg_ind (BD_ADDR peer_bda);
+extern tGATT_STATUS gatt_send_srv_chg_ind (BD_ADDR peer_bda);
 extern void gatt_chk_srv_chg(tGATTS_SRV_CHG *p_srv_chg_clt);
 extern void gatt_add_a_bonded_dev_for_srv_chg (BD_ADDR bda);
 

+ 12 - 1
components/bt/bluedroid/stack/include/stack/gatt_api.h

@@ -1141,7 +1141,18 @@ extern BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr,
 *******************************************************************************/
 extern tGATT_STATUS GATT_Disconnect (UINT16 conn_id);
 
-
+/*******************************************************************************
+**
+** Function         GATT_SendServiceChangeIndication
+**
+** Description      This function is to send a service change indication
+**
+** Parameters       bd_addr: peer device address.
+**
+** Returns          status.
+**
+*******************************************************************************/
+extern tGATT_STATUS GATT_SendServiceChangeIndication (BD_ADDR bd_addr);
 
 /*******************************************************************************
 **