]> granicus.if.org Git - esp-idf/commitdiff
Component/bt: add gatts send service change indication API
authorzhiweijian <zhiweijian@espressif.com>
Tue, 18 Sep 2018 08:20:13 +0000 (16:20 +0800)
committerbot <bot@espressif.com>
Tue, 25 Sep 2018 08:26:55 +0000 (08:26 +0000)
16 files changed:
components/bt/Kconfig
components/bt/bluedroid/api/esp_gatts_api.c
components/bt/bluedroid/api/include/api/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/gatt/include/bta_gatts_int.h
components/bt/bluedroid/bta/include/bta/bta_gatt_api.h
components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c
components/bt/bluedroid/btc/profile/std/include/btc_gatts.h
components/bt/bluedroid/common/include/common/bt_target.h
components/bt/bluedroid/stack/gatt/gatt_api.c
components/bt/bluedroid/stack/gatt/gatt_attr.c
components/bt/bluedroid/stack/gatt/gatt_main.c
components/bt/bluedroid/stack/gatt/include/gatt_int.h
components/bt/bluedroid/stack/include/stack/gatt_api.h

index 90857abee284c3cd4f11cf2bdfbaccf839c3d012..93b8fe298db9b4a1e38215cce730a8aa4cd2686b 100644 (file)
@@ -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)
index d40f2ac09a51c608c7d39caad532bcd6e0c84b66..2b3b0ba807d30d7ff7a1193e5bd8e460edb64101 100644 (file)
@@ -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)
 {
index d25d297806b7617366b2958015d4605da4ee2249..3a5ad9eaa95c3edfbd7721a6cabad147df9c9c21 100644 (file)
@@ -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
index cf3bb5dbd298d41e4dad4c34b214687a2491f8f5..e7c50c4eab7b8ad8972de08f47fa91e8ba981c41 100644 (file)
@@ -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
index 2985da2e20bbeeb82d972a10c79e02558102cfd2..87e559ab725b9c0f62f529fed800826684b241ec 100644 (file)
@@ -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
index 3401c2bba19d415015544618057ed6ce225df403..993b384d7d30a3e9131541fc61cd613887f296dc 100644 (file)
@@ -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;
     }
index 7f92ec8cb66cdbddb0e58c4a8abeb158ff4a7f05..49b2bf63b36ec40138a4ed54d9506fb389a4107c 100644 (file)
@@ -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);
index 9e59917518545fc120c3cbca60166bd199e68d0b..bc0539c1525b4fdd6d38fef0178c4e5499cd2b7d 100644 (file)
@@ -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
index bfe9cc04ea34d36df42b205d7ebcb8ab8b1600d7..b4ed4fa334ef7da01715becf15878cde58d8bcc2 100644 (file)
@@ -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;
index e4b57589d51062068b6a9eb470726c94b3988a3f..cad973a8a6e8e3b1d9d08cb3dff54c16af205e48 100644 (file)
@@ -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;
 
 
index 331ff20e46b285a5c714b67200aaa38b116a9a16..638119e897079c2609704896de45504a742f9ef6 100644 (file)
 #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
index 10f66db4b6bd131e8354d81aaf117fad41ec1fbe..cbc37e3aa3c88c73ce4c9a61c8e156c65ec2fa4b 100644 (file)
@@ -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;
+}
 
 /*******************************************************************************
 **
index 90505ad031e8dda254f8bda89d6109c2daedb1cb..51c331f9fd4d1595f6808057bdf668c4f2bd749b 100644 (file)
@@ -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
     */
index add39455fe4c44b97213e4dd943e9eb1b8d58e08..aaec11d40acb1cc99df4e01a2a54ba730e3f80eb 100644 (file)
@@ -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) {
index ffbf8540fdae7cadefd58fb955cd0e1f70fc2dc9..2b770a7f207aeb9a71b01339c0ed9bd7ea9bb780 100644 (file)
@@ -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);
 
index 24a186ae710f74cb14465ac4afee68e042dcb8b5..b2cecb0578008d716739ef9656e067e8e2233d7b 100644 (file)
@@ -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);
 
 /*******************************************************************************
 **