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

Commit 2f970b66 authored by tturney's avatar tturney
Browse files

Fix PAN and AV role switch war

Bug: 23740164
Change-Id: Ib26a64b624c711443201adc4fde6b041ecb0dde1
parent 96f842eb
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3689,7 +3689,8 @@ static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
                  versions are stored in a blacklist and role switch with these devices are
                  delayed to avoid the collision with link encryption setup */

                    if (delay_role_switch == FALSE)
                    if (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_SLAVE_ROLE_ONLY &&
                            delay_role_switch == FALSE)
                    {
                        BTM_SwitchRole (bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
                                        HCI_ROLE_MASTER, NULL);
+9 −3
Original line number Diff line number Diff line
@@ -86,7 +86,11 @@ const tBTA_DM_CFG bta_dm_cfg =
#define BTA_AV_ROLE BTA_MASTER_ROLE_PREF
#endif

#define BTA_DM_NUM_RM_ENTRY    4
#ifndef BTA_PANU_ROLE
/* By default, AV role (backward BTA_MASTER_ROLE_PREF) */
#define BTA_PANU_ROLE BTA_SLAVE_ROLE_ONLY
#endif
#define BTA_DM_NUM_RM_ENTRY    6

/* appids for PAN used by insight sample application
   these have to be same as defined in btui_int.h */
@@ -100,8 +104,10 @@ const tBTA_DM_CFG bta_dm_cfg =
const tBTA_DM_RM bta_dm_rm_cfg[] =
{
    {BTA_ID_SYS, BTA_DM_NUM_RM_ENTRY, BTA_DM_SCATTERNET},
    {BTA_ID_PAN, BTUI_PAN_ID_NAP, BTA_MASTER_ROLE_ONLY},
    {BTA_ID_PAN, BTUI_PAN_ID_GN, BTA_MASTER_ROLE_ONLY},
    {BTA_ID_PAN, BTUI_PAN_ID_NAP, BTA_ANY_ROLE},
    {BTA_ID_PAN, BTUI_PAN_ID_GN, BTA_ANY_ROLE},
    {BTA_ID_PAN, BTA_APP_ID_PAN_MULTI, BTA_MASTER_ROLE_ONLY},
    {BTA_ID_PAN, BTUI_PAN_ID_PANU, BTA_PANU_ROLE},
    {BTA_ID_HH,  BTA_ALL_APP_ID, BTA_HH_ROLE},
    {BTA_ID_AV,  BTA_ALL_APP_ID, BTA_AV_ROLE}
};
+2 −0
Original line number Diff line number Diff line
@@ -181,6 +181,7 @@ typedef UINT16 tBTA_SEC;
/* Ignore for Discoverable, Connectable only for LE modes */
#define BTA_DM_LE_IGNORE           0xFF00

#define BTA_APP_ID_PAN_MULTI    0xFE    /* app id for pan multiple connection */
#define BTA_ALL_APP_ID          0xFF

/* Discoverable Modes */
@@ -248,6 +249,7 @@ typedef UINT8 tBTA_AUTH_RESP;
#define BTA_ANY_ROLE          0x00
#define BTA_MASTER_ROLE_PREF  0x01
#define BTA_MASTER_ROLE_ONLY  0x02
#define BTA_SLAVE_ROLE_ONLY   0x03     /* Used for PANU only, skip role switch to master */

typedef UINT8 tBTA_PREF_ROLES;

+59 −0
Original line number Diff line number Diff line
@@ -293,6 +293,53 @@ static void bta_pan_mfilt_ind_cback(UINT16 handle, BOOLEAN indication,tBNEP_RESU



/*******************************************************************************
**
** Function         bta_pan_has_multiple_connections
**
** Description      Check whether there are multiple GN/NAP connections to
**                  different devices
**
**
** Returns          BOOLEAN
**
*******************************************************************************/
static BOOLEAN bta_pan_has_multiple_connections(UINT8 app_id)
{
    tBTA_PAN_SCB *p_scb = NULL;
    BOOLEAN     found = FALSE;
    BD_ADDR     bd_addr;

    for (UINT8 index = 0; index < BTA_PAN_NUM_CONN; index++)
    {
        p_scb = &bta_pan_cb.scb[index];
        if (p_scb->in_use == TRUE && app_id == p_scb->app_id)
        {
            /* save temp bd_addr */
            bdcpy(bd_addr, p_scb->bd_addr);
            found = TRUE;
            break;
        }
    }

    /* If cannot find a match then there is no connection at all */
    if (found == FALSE)
        return FALSE;

    /* Find whether there is another connection with different device other than PANU.
        Could be same service or different service */
    for (UINT8 index = 0; index < BTA_PAN_NUM_CONN; index++)
    {
        p_scb = &bta_pan_cb.scb[index];
        if (p_scb->in_use == TRUE && p_scb->app_id != bta_pan_cb.app_id[0] &&
                bdcmp(bd_addr, p_scb->bd_addr))
        {
            return TRUE;
        }
    }
    return FALSE;
}

/*******************************************************************************
**
** Function         bta_pan_enable
@@ -565,6 +612,18 @@ void bta_pan_conn_open(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
        data.status = BTA_PAN_FAIL;
    }

    p_scb->pan_flow_enable = TRUE;
    p_scb->app_flow_enable = TRUE;

    /* If app_id is NAP/GN, check whether there are multiple connections.
       If there are, provide a special app_id to dm to enforce master role only. */
    if ((p_scb->app_id == bta_pan_cb.app_id[1] || p_scb->app_id == bta_pan_cb.app_id[2]) &&
            bta_pan_has_multiple_connections(p_scb->app_id))
    {
        p_scb->app_id = BTA_APP_ID_PAN_MULTI;
    }

    bta_sys_conn_open(BTA_ID_PAN, p_scb->app_id, p_scb->bd_addr);
    bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, (tBTA_PAN *)&data);