Ejemplo n.º 1
0
/*******************************************************************************
**
** Function         SMP_SecurityGrant
**
** Description      This function is called to grant security process.
**
** Parameters       bd_addr - peer device bd address.
**                  res     - result of the operation SMP_SUCCESS if success.
**                            Otherwise, SMP_REPEATED_ATTEMPTS is too many attempts.
**
** Returns          None
**
*******************************************************************************/
void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
{
    SMP_TRACE_EVENT ("SMP_SecurityGrant ");

    if (smp_cb.smp_over_br) {
        if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP ||
                smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
                memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN)) {
            return;
        }

        /* clear the SMP_SEC_REQUEST_EVT event after get grant */
        /* avoid generating duplicate pair request */
        smp_cb.cb_evt = 0;
        smp_br_state_machine_event(&smp_cb, SMP_BR_API_SEC_GRANT_EVT, &res);
        return;
    }

    if (smp_cb.state != SMP_STATE_WAIT_APP_RSP ||
            smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
            memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN)) {
        return;
    }
    /* clear the SMP_SEC_REQUEST_EVT event after get grant */
    /* avoid generate duplicate pair request */
    smp_cb.cb_evt = 0;
    smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res);
}
Ejemplo n.º 2
0
/*******************************************************************************
**
** Function         SMP_BR_PairWith
**
** Description      This function is called to start a SMP pairing over BR/EDR.
**                  Device support one SMP pairing at one time.
**
** Parameters       bd_addr - peer device bd address.
**
** Returns          SMP_STARTED if pairing started, otherwise reason for failure.
**
*******************************************************************************/
tSMP_STATUS SMP_BR_PairWith (BD_ADDR bd_addr)
{
    tSMP_CB   *p_cb = &smp_cb;
    UINT8     status = SMP_PAIR_INTERNAL_ERR;

    SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
                     __func__, p_cb->state, p_cb->br_state, p_cb->flags);

    if (p_cb->state != SMP_STATE_IDLE ||
            p_cb->smp_over_br ||
            p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) {
        /* pending security on going, reject this one */
        return SMP_BUSY;
    }

    p_cb->role = HCI_ROLE_MASTER;
    p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
    p_cb->smp_over_br = TRUE;

    memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);

    if (!L2CA_ConnectFixedChnl (L2CAP_SMP_BR_CID, bd_addr, BLE_ADDR_UNKNOWN_TYPE)) {
        SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __FUNCTION__);
        smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
        return status;
    }

    return SMP_STARTED;
}
Ejemplo n.º 3
0
/*******************************************************************************
**
** Function         smp_br_connect_callback
**
** Description      This callback function is called by L2CAP to indicate that
**                  SMP BR channel is
**                      connected (conn = TRUE)/disconnected (conn = FALSE).
**
*******************************************************************************/
static void smp_br_connect_callback(UINT16 channel, BD_ADDR bd_addr, BOOLEAN connected,
                                    UINT16 reason, tBT_TRANSPORT transport)
{
    tSMP_CB *p_cb = &smp_cb;
    tSMP_INT_DATA int_data;

    SMP_TRACE_EVENT ("%s", __func__);

    if (transport != BT_TRANSPORT_BR_EDR)
    {
        SMP_TRACE_WARNING("%s is called on unexpected transport %d",
                           __func__, transport);
        return;
    }

    if (!(memcmp(bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) == 0))
        return;

    SMP_TRACE_EVENT ("%s for pairing BDA: %08x%04x  Event: %s",
                     __func__,
                     (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8) + bd_addr[3],
                     (bd_addr[4]<<8)+bd_addr[5],
                     (connected) ? "connected" : "disconnected");

    if (connected)
    {
        if(!p_cb->connect_initialized)
        {
            p_cb->connect_initialized = TRUE;
            /* initialize local i/r key to be default keys */
            p_cb->local_r_key = p_cb->local_i_key =  SMP_BR_SEC_DEFAULT_KEY;
            p_cb->loc_auth_req = p_cb->peer_auth_req = 0;
            p_cb->cb_evt = SMP_BR_KEYS_REQ_EVT;
            smp_br_state_machine_event(p_cb, SMP_BR_L2CAP_CONN_EVT, NULL);
        }
    }
    else
    {
        int_data.reason = reason;
        /* Disconnected while doing security */
        smp_br_state_machine_event(p_cb, SMP_BR_L2CAP_DISCONN_EVT, &int_data);
    }
}
Ejemplo n.º 4
0
/*******************************************************************************
**
** Function         smp_br_data_received
**
** Description      This function is called when data is received from L2CAP on
**                  SMP BR channel.
**
** Returns          void
**
*******************************************************************************/
static void smp_br_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf)
{
    tSMP_CB *p_cb = &smp_cb;
    UINT8   *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
    UINT8   cmd ;
    SMP_TRACE_EVENT ("SMDBG l2c %s", __func__);

    STREAM_TO_UINT8(cmd, p);

    /* sanity check */
    if ((SMP_OPCODE_MAX < cmd) || (SMP_OPCODE_MIN > cmd))
    {
        SMP_TRACE_WARNING( "Ignore received command with RESERVED code 0x%02x", cmd);
        GKI_freebuf(p_buf);
        return;
    }

    /* reject the pairing request if there is an on-going SMP pairing */
    if (SMP_OPCODE_PAIRING_REQ == cmd)
    {
        if ((p_cb->state == SMP_STATE_IDLE) && (p_cb->br_state == SMP_BR_STATE_IDLE))
        {
            p_cb->role = HCI_ROLE_SLAVE;
            p_cb->smp_over_br = TRUE;
            memcpy(&p_cb->pairing_bda[0], bd_addr, BD_ADDR_LEN);
        }
        else if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN))
        {
            GKI_freebuf (p_buf);
            smp_reject_unexpected_pairing_command(bd_addr);
            return;
        }
        /* else, out of state pairing request received, passed into State Machine */
    }

    if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN) == 0)
    {
        btu_stop_timer (&p_cb->rsp_timer_ent);
        btu_start_timer (&p_cb->rsp_timer_ent, BTU_TTYPE_SMP_PAIRING_CMD,
                             SMP_WAIT_FOR_RSP_TOUT);

        p_cb->rcvd_cmd_code = cmd;
        p_cb->rcvd_cmd_len = (UINT8) p_buf->len;
        smp_br_state_machine_event(p_cb, cmd, p);
    }

    GKI_freebuf (p_buf);
}
Ejemplo n.º 5
0
/*******************************************************************************
**
** Function         smp_tx_complete_callback
**
** Description      SMP channel tx complete callback
**
*******************************************************************************/
static void smp_tx_complete_callback (UINT16 cid, UINT16 num_pkt)
{
    tSMP_CB *p_cb = &smp_cb;

    if (p_cb->total_tx_unacked >= num_pkt)
        p_cb->total_tx_unacked -= num_pkt;
    else
        SMP_TRACE_ERROR("Unexpected %s: num_pkt = %d", __func__,num_pkt);

    UINT8 reason = SMP_SUCCESS;
    if (p_cb->total_tx_unacked == 0 && p_cb->wait_for_authorization_complete)
    {
        if (cid == L2CAP_SMP_CID)
            smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
        else
            smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &reason);
    }
}