Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17ac1b6a authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Don't unregister notifications for unmodified services

Change-Id: Ie02dd72a2d4a423ab532ec84a4d588ab83f3e22b
parent fc35a1a1
Loading
Loading
Loading
Loading
+16 −4
Original line number Original line Diff line number Diff line
@@ -1938,7 +1938,7 @@ BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
                                       tBTA_GATTC_SERV     *p_srcb,
                                       tBTA_GATTC_SERV     *p_srcb,
                                       tBTA_GATTC_CLCB      *p_clcb,
                                       tBTA_GATTC_CLCB      *p_clcb,
                                       tBTA_GATTC_NOTIFY    *p_notify,
                                       tBTA_GATTC_NOTIFY    *p_notify,
                                       UINT16 handle)
                                       tGATT_VALUE *att_value)
{
{
    tBT_UUID        gattp_uuid, srvc_chg_uuid;
    tBT_UUID        gattp_uuid, srvc_chg_uuid;
    BOOLEAN         processed = FALSE;
    BOOLEAN         processed = FALSE;
@@ -1953,11 +1953,23 @@ BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
    if (bta_gattc_uuid_compare(&p_notify->char_id.srvc_id.id.uuid, &gattp_uuid, TRUE) &&
    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))
        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;
        processed = TRUE;
        /* mark service handle change pending */
        /* mark service handle change pending */
        p_srcb->srvc_hdl_chg = TRUE;
        p_srcb->srvc_hdl_chg = TRUE;
        /* clear up all notification/indication registration */
        /* 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 */
        /* service change indication all received, do discovery update */
        if ( ++ p_srcb->update_count == bta_gattc_num_reg_app())
        if ( ++ p_srcb->update_count == bta_gattc_num_reg_app())
        {
        {
@@ -1977,7 +1989,7 @@ BOOLEAN bta_gattc_process_srvc_chg_ind(UINT16 conn_id,
                }
                }
            }
            }
            /* send confirmation here if this is an indication, it should always be */
            /* 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 connection available, refresh cache by doing discovery now */
            if (p_clcb != NULL)
            if (p_clcb != NULL)
@@ -2074,7 +2086,7 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL
                            &notify.descr_type))
                            &notify.descr_type))
    {
    {
        /* if non-service change indication/notification, forward to application */
        /* if non-service change indication/notification, forward to application */
        if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, &notify, handle))
        if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, &notify, &p_data->att_value))
        {
        {
            /* if app registered for the notification */
            /* if app registered for the notification */
            if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, &notify))
            if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, &notify))
+3 −1
Original line number Original line Diff line number Diff line
@@ -78,6 +78,8 @@ enum
};
};
typedef UINT16 tBTA_GATTC_INT_EVT;
typedef UINT16 tBTA_GATTC_INT_EVT;


#define BTA_GATTC_SERVICE_CHANGED_LEN    4

/* max client application GATTC can support */
/* max client application GATTC can support */
#ifndef     BTA_GATTC_CL_MAX
#ifndef     BTA_GATTC_CL_MAX
#define     BTA_GATTC_CL_MAX    32
#define     BTA_GATTC_CL_MAX    32
@@ -525,7 +527,7 @@ extern tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb, tBT
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_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 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 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 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_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);
extern BOOLEAN bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID *p_src, tBTA_GATT_SRVC_ID *p_tar);
+19 −12
Original line number Original line Diff line number Diff line
@@ -589,33 +589,40 @@ BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV
**
**
** Function         bta_gattc_clear_notif_registration
** 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.
** 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;
    BD_ADDR             remote_bda;
    tBTA_GATTC_IF       gatt_if;
    tBTA_GATTC_IF       gatt_if;
    tBTA_GATTC_RCB      *p_clrcb ;
    tBTA_GATTC_RCB      *p_clrcb ;
    UINT8       i;
    UINT8       i;
    tGATT_TRANSPORT     transport;
    tGATT_TRANSPORT     transport;
    UINT16              handle;


    if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport))
    if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
    {
        if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL) {
        if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL)
            for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
        {
            for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
            {
                if (p_clrcb->notif_reg[i].in_use &&
                if (p_clrcb->notif_reg[i].in_use &&
                    !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
                    !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))

                    /* 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));
                        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");
        APPL_TRACE_ERROR("can not clear indication/notif registration for unknown app");
    }
    }
    return;
    return;