コード例 #1
0
ファイル: btm_ble_addr.c プロジェクト: jchunhua163/esp-idf-zh
/*******************************************************************************
**
** Function         btm_ble_refresh_peer_resolvable_private_addr
**
** Description      This function refresh the currently used resolvable remote private address into security
**                  database and set active connection address.
**
*******************************************************************************/
void btm_ble_refresh_peer_resolvable_private_addr(BD_ADDR pseudo_bda, BD_ADDR rpa,
        UINT8 rra_type)
{
#if BLE_PRIVACY_SPT == TRUE
    UINT8 rra_dummy = FALSE;
    BD_ADDR dummy_bda = {0};

    if (memcmp(dummy_bda, rpa, BD_ADDR_LEN) == 0) {
        rra_dummy = TRUE;
    }

    /* update security record here, in adv event or connection complete process */
    tBTM_SEC_DEV_REC *p_sec_rec = btm_find_dev(pseudo_bda);
    if (p_sec_rec != NULL) {
        memcpy(p_sec_rec->ble.cur_rand_addr, rpa, BD_ADDR_LEN);

        /* unknown, if dummy address, set to static */
        if (rra_type == BTM_BLE_ADDR_PSEUDO) {
            p_sec_rec->ble.active_addr_type = rra_dummy ? BTM_BLE_ADDR_STATIC : BTM_BLE_ADDR_RRA;
        } else {
            p_sec_rec->ble.active_addr_type = rra_type;
        }
    } else {
        BTM_TRACE_ERROR("No matching known device in record");
        return;
    }

    BTM_TRACE_DEBUG("%s: active_addr_type: %d ",
                    __func__, p_sec_rec->ble.active_addr_type);

    /* connection refresh remote address */
    tACL_CONN *p_acl = btm_bda_to_acl(p_sec_rec->bd_addr, BT_TRANSPORT_LE);
    if (p_acl == NULL) {
        p_acl = btm_bda_to_acl(p_sec_rec->ble.pseudo_addr, BT_TRANSPORT_LE);
    }

    if (p_acl != NULL) {
        if (rra_type == BTM_BLE_ADDR_PSEUDO) {
            /* use static address, resolvable_private_addr is empty */
            if (rra_dummy) {
                p_acl->active_remote_addr_type = p_sec_rec->ble.static_addr_type;
                memcpy(p_acl->active_remote_addr, p_sec_rec->ble.static_addr, BD_ADDR_LEN);
            } else {
                p_acl->active_remote_addr_type = BLE_ADDR_RANDOM;
                memcpy(p_acl->active_remote_addr, rpa, BD_ADDR_LEN);
            }
        } else {
            p_acl->active_remote_addr_type = rra_type;
            memcpy(p_acl->active_remote_addr, rpa, BD_ADDR_LEN);
        }

        BTM_TRACE_DEBUG("p_acl->active_remote_addr_type: %d ", p_acl->active_remote_addr_type);
        BTM_TRACE_DEBUG("%s conn_addr: %02x:%02x:%02x:%02x:%02x:%02x",
                        __func__, p_acl->active_remote_addr[0], p_acl->active_remote_addr[1],
                        p_acl->active_remote_addr[2], p_acl->active_remote_addr[3],
                        p_acl->active_remote_addr[4], p_acl->active_remote_addr[5]);
    }
#endif
}
コード例 #2
0
/*******************************************************************************
**
** Function l2cble_notify_le_connection
**
** Description This function notifiy the l2cap connection to the app layer
**
** Returns none
**
*******************************************************************************/
void l2cble_notify_le_connection (BD_ADDR bda)
{
    tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
    tACL_CONN *p_acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE) ;

    if (p_lcb != NULL && p_acl != NULL && p_lcb->link_state != LST_CONNECTED)
    {
        /* update link status */
        btm_establish_continue(p_acl);
        /* update l2cap link status and send callback */
        p_lcb->link_state = LST_CONNECTED;
        l2cu_process_fixed_chnl_resp (p_lcb);
    }
}
コード例 #3
0
/*******************************************************************************
**
** Function         btm_ble_refresh_rra
**
** Description      This function refresh the currently used RRA into security
**                  database and set active connection address.
**
*******************************************************************************/
void btm_ble_refresh_rra(BD_ADDR static_bda, BD_ADDR rra)
{
#if BLE_PRIVACY_SPT == TRUE
    tBTM_SEC_DEV_REC    *p_sec_rec = btm_find_dev_by_public_static_addr(static_bda);
    tACL_CONN           *p_acl = btm_bda_to_acl (p_sec_rec->bd_addr, BT_TRANSPORT_LE);
    UINT8               rra_dummy = FALSE;
    BD_ADDR             dummy_bda = {0};

    BTM_TRACE_ERROR("btm_ble_refresh_rra");

    if (memcmp(dummy_bda, rra, BD_ADDR_LEN) == 0)
        rra_dummy = TRUE;

    /* connection refresh RRA */
    if (p_acl != NULL /* && memcmp(p_acl->active_remote_addr, dummy_bda, BD_ADDR_LEN) == 0 */)
    {
        /* use static address, rra is empty */
        if (rra_dummy && p_sec_rec != NULL)
        {
            p_acl->active_remote_addr_type = p_sec_rec->ble.static_addr_type;
            memcpy(p_acl->active_remote_addr, p_sec_rec->ble.static_addr, BD_ADDR_LEN);
        }
        else
        {
            p_acl->active_remote_addr_type = BLE_ADDR_RANDOM;
            memcpy(p_acl->active_remote_addr, rra, BD_ADDR_LEN);
        }
    }
    /* update security record here, in adv event or connection complete process */
    if (p_sec_rec != NULL)
    {
        memcpy(p_sec_rec->ble.cur_rand_addr, rra, BD_ADDR_LEN);
        p_sec_rec->ble.active_addr_type = rra_dummy ? BTM_BLE_ADDR_STATIC: BTM_BLE_ADDR_RRA;
    }
    else
    {
        BTM_TRACE_ERROR("No matching known device in record");
    }
#endif
}
コード例 #4
0
ファイル: btm_ble_addr.c プロジェクト: jchunhua163/esp-idf-zh
/*******************************************************************************
**
** Function         btm_ble_refresh_local_resolvable_private_addr
**
** Description      This function refresh the currently used resolvable private address for the
**                  active link to the remote device
**
*******************************************************************************/
void btm_ble_refresh_local_resolvable_private_addr(BD_ADDR pseudo_addr,
        BD_ADDR local_rpa)
{
#if BLE_PRIVACY_SPT == TRUE
    tACL_CONN *p = btm_bda_to_acl(pseudo_addr, BT_TRANSPORT_LE);
    BD_ADDR     dummy_bda = {0};

    if (p != NULL) {
        if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
            p->conn_addr_type = BLE_ADDR_RANDOM;
            if (memcmp(local_rpa, dummy_bda, BD_ADDR_LEN)) {
                memcpy(p->conn_addr, local_rpa, BD_ADDR_LEN);
            } else {
                memcpy(p->conn_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, BD_ADDR_LEN);
            }
        } else {
            p->conn_addr_type = BLE_ADDR_PUBLIC;
            memcpy(p->conn_addr, &controller_get_interface()->get_address()->address, BD_ADDR_LEN);
        }
    }
#endif
}
コード例 #5
0
/*******************************************************************************
**
**  Function        L2CA_UpdateBleConnParams
**
**  Description     Update BLE connection parameters.
**
**  Parameters:     BD Address of remote
**
**  Return value:   TRUE if update started
**
*******************************************************************************/
BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int,
                                            UINT16 latency, UINT16 timeout)
{
    tL2C_LCB            *p_lcb;
    tACL_CONN           *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE);

    /* See if we have a link control block for the remote device */
    p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);

    /* If we don't have one, create one and accept the connection. */
    if (!p_lcb || !p_acl_cb)
    {
        L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x",
                              (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
                              (rem_bda[4]<<8)+rem_bda[5]);
        return(FALSE);
    }

    if (p_lcb->transport != BT_TRANSPORT_LE)
    {
        L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE",
                              (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
                              (rem_bda[4]<<8)+rem_bda[5]);
        return(FALSE);
    }

    p_lcb->min_interval = min_int;
    p_lcb->max_interval = max_int;
    p_lcb->latency = latency;
    p_lcb->timeout = timeout;
    p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;

    l2cble_start_conn_update(p_lcb);

    return(TRUE);
}
/*******************************************************************************
**
** Function         bta_dm_pm_cback
**
** Description      Conn change callback from sys for low power management
**
**
** Returns          void
**
*******************************************************************************/
static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
{

    UINT8 i,j;
    UINT16 policy_setting;
    tBTM_STATUS btm_status;
    tBTM_VERSION_INFO vers;
    UINT8 *p = NULL;
#if (BTM_SSR_INCLUDED == TRUE)
    int               index = BTA_DM_PM_SSR0;
#endif
    tBTA_DM_PEER_DEVICE *p_dev;
    tACL_CONN   *p_dev_rec;

    APPL_TRACE_DEBUG("bta_dm_pm_cback: st(%d), id(%d), app(%d)", status, id, app_id);

    btm_status = BTM_ReadLocalVersion (&vers);
    p_dev = bta_dm_find_peer_device(peer_addr);
    p_dev_rec = btm_bda_to_acl(peer_addr, BT_TRANSPORT_BR_EDR);
    /* Disable/Enable sniff policy on the SCO link if sco Up/Down. Will be removed in 2.2*/
    if ((p_dev) &&
        ((status == BTA_SYS_SCO_OPEN) || (status == BTA_SYS_SCO_CLOSE)) )
    {
        if ((btm_status == BTM_SUCCESS) &&
            (((vers.manufacturer ==  LMP_COMPID_BROADCOM) &&
            (vers.hci_version < HCI_PROTO_VERSION_2_0)) || (p_dev_rec && (p_dev_rec->lmp_version < 2))))
        {
            if (p_dev_rec)
            APPL_TRACE_DEBUG("bta_dm_pm_cback:disable sniff for rmt lmp ver:%d",p_dev_rec->lmp_version);
            bta_dm_pm_set_sniff_policy(p_dev, (status == BTA_SYS_SCO_OPEN));
        }
    }

    /* find if there is an power mode entry for the service */
    for(i=1; i<=p_bta_dm_pm_cfg[0].app_id; i++)
    {

        if((p_bta_dm_pm_cfg[i].id == id)
            && ((p_bta_dm_pm_cfg[i].app_id == BTA_ALL_APP_ID ) || (p_bta_dm_pm_cfg[i].app_id == app_id )))
            break;

    }

    /* if no entries are there for the app_id and subystem in p_bta_dm_pm_spec*/
    if(i> p_bta_dm_pm_cfg[0].app_id)
        return;

    /*p_dev = bta_dm_find_peer_device(peer_addr);*/

#if (BTM_SSR_INCLUDED == TRUE)
    /* set SSR parameters on SYS CONN OPEN */
    if((BTA_SYS_CONN_OPEN == status) && p_dev && (p_dev->info & BTA_DM_DI_USE_SSR))
    {
        index = p_bta_dm_pm_spec[p_bta_dm_pm_cfg[i].spec_idx].ssr;
    }
#endif

    /* if no action for the event */
    if(p_bta_dm_pm_spec[p_bta_dm_pm_cfg[i].spec_idx].actn_tbl[status][0].power_mode == BTA_DM_PM_NO_ACTION)
    {
#if (BTM_SSR_INCLUDED == TRUE)
        if(BTA_DM_PM_SSR0 == index) /* and do not need to set SSR, return. */
#endif
        return;
    }

    for(j=0; j<bta_dm_conn_srvcs.count ; j++)
    {
        /* check if an entry already present */
        if((bta_dm_conn_srvcs.conn_srvc[j].id == id)
            && (bta_dm_conn_srvcs.conn_srvc[j].app_id == app_id )
            && !bdcmp(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr, peer_addr))
            break;

    }

        /* if subsystem has no more preference on the power mode remove
       the cb */
    if(p_bta_dm_pm_spec[p_bta_dm_pm_cfg[i].spec_idx].actn_tbl[status][0].power_mode == BTA_DM_PM_NO_PREF)
    {

        if(j != bta_dm_conn_srvcs.count)
        {
            bta_dm_conn_srvcs.count--;

            APPL_TRACE_DEBUG("Removed power mode entry for service id = %d, count = %d",
                               p_bta_dm_pm_cfg[i].id, bta_dm_conn_srvcs.count);

            for(; j<bta_dm_conn_srvcs.count ; j++)
            {

                memcpy(&bta_dm_conn_srvcs.conn_srvc[j], &bta_dm_conn_srvcs.conn_srvc[j+1], sizeof(bta_dm_conn_srvcs.conn_srvc[j]));

            }
        }
        else
        {
            APPL_TRACE_WARNING("bta_dm_act no entry for connected service cbs");
            return;
        }
    }
    else if(j == bta_dm_conn_srvcs.count )
    {
        /* check if we have more connected service that cbs */
        if(bta_dm_conn_srvcs.count == BTA_DM_NUM_CONN_SRVS)
        {
            APPL_TRACE_WARNING("bta_dm_act no more connected service cbs");
            return;
        }

        /* fill in a new cb */
        bta_dm_conn_srvcs.conn_srvc[j].id = id;
        bta_dm_conn_srvcs.conn_srvc[j].app_id = app_id;
        bdcpy(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr, peer_addr);

        APPL_TRACE_WARNING("new conn_srvc id:%d, app_id:%d", id, app_id);

        bta_dm_conn_srvcs.count++;
        bta_dm_conn_srvcs.conn_srvc[j].state = status;

        APPL_TRACE_WARNING("new conn_srvc id:%d, app_id:%d count:%d", id, app_id,
                             bta_dm_conn_srvcs.count);
    }
    else
    {
        /* no service is added or removed. only updating status. */
        bta_dm_conn_srvcs.conn_srvc[j].state = status;
    }

    /* stop timer */
    bta_dm_pm_stop_timer(peer_addr);

    if(p_dev)
    {
        p_dev->pm_mode_attempted = 0;
        p_dev->pm_mode_failed = 0;
    }

#if (BTM_SSR_INCLUDED == TRUE)
    if(p_bta_dm_ssr_spec[index].max_lat
#if (defined BTA_HH_INCLUDED && BTA_HH_INCLUDED == TRUE)
       || index == BTA_DM_PM_SSR_HH
#endif
       )
    {
       /* If HID connection open is received and SCO is already active.
        This will handle the case where HID connects when SCO already active */
        if ((status == BTA_SYS_CONN_OPEN) && (id == BTA_ID_HH) && bta_dm_pm_is_sco_active())
        {
            APPL_TRACE_DEBUG("bta_dm_pm_cback: SCO is Active, disabling SSR on HID link")
            APPL_TRACE_WARNING("HID Dev address: %02x:%02x:%02x:%02x:%02x:%02x", peer_addr[0],
                peer_addr[1], peer_addr[2], peer_addr[3], peer_addr[4], peer_addr[5]);
            BTM_SetSsrParams(peer_addr, 0, 0, 0);
        }
        else
        {
            bta_dm_pm_ssr(peer_addr);
        }
    }
    else
    {
        if( ((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
            ((NULL != (p = BTM_ReadRemoteFeatures (peer_addr))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p))
            && (index == BTA_DM_PM_SSR0) )
        {
            if (status == BTA_SYS_SCO_OPEN)
            {
                APPL_TRACE_DEBUG("bta_dm_pm_cback: SCO is open, reset SSR to zero");
                BTM_SetSsrParams (peer_addr, 0,0,0 );
            }
            else if (status == BTA_SYS_SCO_CLOSE)
            {
                APPL_TRACE_DEBUG("bta_dm_pm_cback: SCO is close, back to old SSR");
                bta_dm_pm_ssr(peer_addr);
            }
        }
    }

    /* If SCO up/down event is received, then enable/disable SSR on active HID link */
    if (btm_status == BTM_SUCCESS && (status == BTA_SYS_SCO_OPEN || status == BTA_SYS_SCO_CLOSE))
    {
        BOOLEAN bScoActive = (status == BTA_SYS_SCO_OPEN);

        APPL_TRACE_DEBUG("bta_dm_pm_cback: bta_dm_pm_hid_check with bScoActive = %d", bScoActive);
        bta_dm_pm_hid_check(bScoActive);
    }
#endif

    bta_dm_pm_set_mode(peer_addr, FALSE);
}
コード例 #7
0
/*******************************************************************************
**
**  Function        l2cble_start_conn_update
**
**  Description     start BLE connection parameter update process based on status
**
**  Parameters:     lcb : l2cap link control block
**
**  Return value:   none
**
*******************************************************************************/
static void l2cble_start_conn_update (tL2C_LCB *p_lcb)
{
    UINT16 min_conn_int, max_conn_int, slave_latency, supervision_tout;
    tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
    tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE);

    if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) return;

    if (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE)
    {
        /* application requests to disable parameters update.
           If parameters are already updated, lets set them
           up to what has been requested during connection establishement */
        if (p_lcb->conn_update_mask & L2C_BLE_NOT_DEFAULT_PARAM &&
            /* current connection interval is greater than default min */
            p_lcb->min_interval > BTM_BLE_CONN_INT_MIN)
        {
            /* use 7.5 ms as fast connection parameter, 0 slave latency */
            min_conn_int = max_conn_int = BTM_BLE_CONN_INT_MIN;
            slave_latency = BTM_BLE_CONN_SLAVE_LATENCY_DEF;
            supervision_tout = BTM_BLE_CONN_TIMEOUT_DEF;

            /* if both side 4.1, or we are master device, send HCI command */
            if (p_lcb->link_role == HCI_ROLE_MASTER
#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
                || (HCI_LE_CONN_PARAM_REQ_SUPPORTED(controller_get_interface()->get_features_ble()->as_array) &&
                    HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features))
#endif
                 )
            {
                btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, min_conn_int, max_conn_int,
                                                  slave_latency, supervision_tout, 0, 0);
                p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
            }
            else
            {
                l2cu_send_peer_ble_par_req (p_lcb, min_conn_int, max_conn_int, slave_latency, supervision_tout);
            }
            p_lcb->conn_update_mask &= ~L2C_BLE_NOT_DEFAULT_PARAM;
            p_lcb->conn_update_mask |=  L2C_BLE_NEW_CONN_PARAM;
         }
    }
    else
    {
        /* application allows to do update, if we were delaying one do it now */
        if (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM)
        {
             /* if both side 4.1, or we are master device, send HCI command */
            if (p_lcb->link_role == HCI_ROLE_MASTER
#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
                || (HCI_LE_CONN_PARAM_REQ_SUPPORTED(controller_get_interface()->get_features_ble()->as_array) &&
                    HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features))
#endif
                 )
            {
                btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->min_interval,
                    p_lcb->max_interval, p_lcb->latency, p_lcb->timeout, 0, 0);
                p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
            }
            else
            {
                l2cu_send_peer_ble_par_req (p_lcb, p_lcb->min_interval, p_lcb->max_interval,
                                            p_lcb->latency, p_lcb->timeout);
            }
            p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM;
            p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM;
        }
    }
}