From 9fb188a1d98fabec28d923c2db87961c2b9fa01e Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Tue, 18 Sep 2018 16:20:13 +0800 Subject: [PATCH] Component/bt: add gatts send service change indication API --- components/bt/Kconfig | 26 +++++++ components/bt/bluedroid/api/esp_gatts_api.c | 21 ++++++ .../bluedroid/api/include/api/esp_gatts_api.h | 72 ++++++++++++------- .../bt/bluedroid/bta/gatt/bta_gatts_act.c | 30 ++++++++ .../bt/bluedroid/bta/gatt/bta_gatts_api.c | 17 +++++ .../bt/bluedroid/bta/gatt/bta_gatts_main.c | 3 + .../bta/gatt/include/bta_gatts_int.h | 11 ++- .../bluedroid/bta/include/bta/bta_gatt_api.h | 19 +++++ .../btc/profile/std/gatt/btc_gatts.c | 12 +++- .../btc/profile/std/include/btc_gatts.h | 7 ++ .../common/include/common/bt_target.h | 6 ++ components/bt/bluedroid/stack/gatt/gatt_api.c | 53 +++++++++++++- .../bt/bluedroid/stack/gatt/gatt_attr.c | 12 ++++ .../bt/bluedroid/stack/gatt/gatt_main.c | 21 +++--- .../bluedroid/stack/gatt/include/gatt_int.h | 5 +- .../bluedroid/stack/include/stack/gatt_api.h | 13 +++- 16 files changed, 288 insertions(+), 40 deletions(-) diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 90857abee2..93b8fe298d 100644 --- a/components/bt/Kconfig +++ b/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) diff --git a/components/bt/bluedroid/api/esp_gatts_api.c b/components/bt/bluedroid/api/esp_gatts_api.c index d40f2ac09a..2b3b0ba807 100644 --- a/components/bt/bluedroid/api/esp_gatts_api.c +++ b/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) { diff --git a/components/bt/bluedroid/api/include/api/esp_gatts_api.h b/components/bt/bluedroid/api/include/api/esp_gatts_api.h index d25d297806..3a5ad9eaa9 100644 --- a/components/bt/bluedroid/api/include/api/esp_gatts_api.h +++ b/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 diff --git a/components/bt/bluedroid/bta/gatt/bta_gatts_act.c b/components/bt/bluedroid/bta/gatt/bta_gatts_act.c index cf3bb5dbd2..e7c50c4eab 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gatts_act.c +++ b/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 diff --git a/components/bt/bluedroid/bta/gatt/bta_gatts_api.c b/components/bt/bluedroid/bta/gatt/bta_gatts_api.c index 2985da2e20..87e559ab72 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gatts_api.c +++ b/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 diff --git a/components/bt/bluedroid/bta/gatt/bta_gatts_main.c b/components/bt/bluedroid/bta/gatt/bta_gatts_main.c index 3401c2bba1..993b384d7d 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gatts_main.c +++ b/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; } diff --git a/components/bt/bluedroid/bta/gatt/include/bta_gatts_int.h b/components/bt/bluedroid/bta/gatt/include/bta_gatts_int.h index 7f92ec8cb6..49b2bf63b3 100644 --- a/components/bt/bluedroid/bta/gatt/include/bta_gatts_int.h +++ b/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); diff --git a/components/bt/bluedroid/bta/include/bta/bta_gatt_api.h b/components/bt/bluedroid/bta/include/bta/bta_gatt_api.h index 9e59917518..bc0539c152 100644 --- a/components/bt/bluedroid/bta/include/bta/bta_gatt_api.h +++ b/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 diff --git a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c b/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c index bfe9cc04ea..b4ed4fa334 100644 --- a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c +++ b/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, ¶m); 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, ¶m); + break; case BTA_GATTS_LISTEN_EVT: // do nothing break; diff --git a/components/bt/bluedroid/btc/profile/std/include/btc_gatts.h b/components/bt/bluedroid/btc/profile/std/include/btc_gatts.h index e4b57589d5..cad973a8a6 100644 --- a/components/bt/bluedroid/btc/profile/std/include/btc_gatts.h +++ b/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; diff --git a/components/bt/bluedroid/common/include/common/bt_target.h b/components/bt/bluedroid/common/include/common/bt_target.h index 331ff20e46..638119e897 100644 --- a/components/bt/bluedroid/common/include/common/bt_target.h +++ b/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 diff --git a/components/bt/bluedroid/stack/gatt/gatt_api.c b/components/bt/bluedroid/stack/gatt/gatt_api.c index 10f66db4b6..cbc37e3aa3 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_api.c +++ b/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; +} /******************************************************************************* ** diff --git a/components/bt/bluedroid/stack/gatt/gatt_attr.c b/components/bt/bluedroid/stack/gatt/gatt_attr.c index 90505ad031..51c331f9fd 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_attr.c +++ b/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 */ diff --git a/components/bt/bluedroid/stack/gatt/gatt_main.c b/components/bt/bluedroid/stack/gatt/gatt_main.c index add39455fe..aaec11d40a 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_main.c +++ b/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) { diff --git a/components/bt/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/bluedroid/stack/gatt/include/gatt_int.h index ffbf8540fd..2b770a7f20 100644 --- a/components/bt/bluedroid/stack/gatt/include/gatt_int.h +++ b/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); diff --git a/components/bt/bluedroid/stack/include/stack/gatt_api.h b/components/bt/bluedroid/stack/include/stack/gatt_api.h index 24a186ae71..b2cecb0578 100644 --- a/components/bt/bluedroid/stack/include/stack/gatt_api.h +++ b/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); /******************************************************************************* **