tBTA_GATTC_SERV *p_srcb,
tBTA_GATTC_CLCB *p_clcb,
tBTA_GATTC_NOTIFY *p_notify,
- UINT16 handle)
+ tGATT_VALUE *att_value)
{
tBT_UUID gattp_uuid, srvc_chg_uuid;
BOOLEAN processed = FALSE;
if (bta_gattc_uuid_compare(&p_notify->char_id.srvc_id.id.uuid, &gattp_uuid, TRUE) &&
bta_gattc_uuid_compare(&p_notify->char_id.char_id.uuid, &srvc_chg_uuid, TRUE))
{
+ if (att_value->len != BTA_GATTC_SERVICE_CHANGED_LEN) {
+ APPL_TRACE_ERROR("%s: received malformed service changed indication, skipping", __func__);
+ return FALSE;
+ }
+
+ UINT8 *p = att_value->value;
+ UINT16 s_handle = ((UINT16)(*(p )) + (((UINT16)(*(p + 1))) << 8));
+ UINT16 e_handle = ((UINT16)(*(p + 2)) + (((UINT16)(*(p + 3))) << 8));
+
+ APPL_TRACE_ERROR("%s: service changed s_handle:0x%04x e_handle:0x%04x",
+ __func__, s_handle, e_handle);
+
processed = TRUE;
/* mark service handle change pending */
p_srcb->srvc_hdl_chg = TRUE;
/* clear up all notification/indication registration */
- bta_gattc_clear_notif_registration(conn_id);
+ bta_gattc_clear_notif_registration(p_srcb, conn_id, s_handle, e_handle);
/* service change indication all received, do discovery update */
if ( ++ p_srcb->update_count == bta_gattc_num_reg_app())
{
}
}
/* send confirmation here if this is an indication, it should always be */
- GATTC_SendHandleValueConfirm(conn_id, handle);
+ GATTC_SendHandleValueConfirm(conn_id, att_value->handle);
/* if connection available, refresh cache by doing discovery now */
if (p_clcb != NULL)
¬ify.descr_type))
{
/* if non-service change indication/notification, forward to application */
- if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify, handle))
+ if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify, &p_data->att_value))
{
/* if app registered for the notification */
if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify))
};
typedef UINT16 tBTA_GATTC_INT_EVT;
+#define BTA_GATTC_SERVICE_CHANGED_LEN 4
+
/* max client application GATTC can support */
#ifndef BTA_GATTC_CL_MAX
#define BTA_GATTC_CL_MAX 32
extern BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda, BOOLEAN add, BOOLEAN is_listen);
extern BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR remote_bda, UINT8 role);
extern UINT8 bta_gattc_num_reg_app(void);
-extern void bta_gattc_clear_notif_registration(UINT16 conn_id);
+extern void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV *p_srcb, UINT16 conn_id, UINT16 start_handle, UINT16 end_handle);
extern tBTA_GATTC_SERV * bta_gattc_find_srvr_cache(BD_ADDR bda);
extern BOOLEAN bta_gattc_charid_compare(tBTA_GATTC_CHAR_ID *p_src, tBTA_GATTC_CHAR_ID *p_tar);
extern BOOLEAN bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID *p_src, tBTA_GATT_SRVC_ID *p_tar);
**
** Function bta_gattc_clear_notif_registration
**
-** Description clear up the notification registration information by BD_ADDR.
+** Description Clear up the notification registration information by BD_ADDR.
+** Where handle is between start_handle and end_handle, and
+** start_handle and end_handle are boundaries of service
+** containing characteristic.
**
** Returns None.
**
*******************************************************************************/
-void bta_gattc_clear_notif_registration(UINT16 conn_id)
+void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV *p_srcb, UINT16 conn_id,
+ UINT16 start_handle, UINT16 end_handle)
{
BD_ADDR remote_bda;
tBTA_GATTC_IF gatt_if;
tBTA_GATTC_RCB *p_clrcb ;
UINT8 i;
tGATT_TRANSPORT transport;
+ UINT16 handle;
- if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport))
- {
- if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL)
- {
- for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
- {
+ if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
+ if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL) {
+ for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
if (p_clrcb->notif_reg[i].in_use &&
!bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
- memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
+
+ /* It's enough to get service or characteristic handle, as
+ * clear boundaries are always around service.
+ */
+ handle = bta_gattc_id2handle(p_srcb, &p_clrcb->notif_reg[i].char_id.srvc_id,
+ &p_clrcb->notif_reg[i].char_id.char_id, NULL);
+ if (handle >= start_handle && handle <= end_handle)
+ memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
}
}
- }
- else
- {
+ } else {
APPL_TRACE_ERROR("can not clear indication/notif registration for unknown app");
}
return;