예제 #1
0
파일: smp_l2c.c 프로젝트: morrey/bt_bcm
/*******************************************************************************
**
** Function         smp_connect_callback
**
** Description      This callback function is called by L2CAP to indicate that
**                  SMP channel is
**                      connected (conn = TRUE)/disconnected (conn = FALSE).
**
*******************************************************************************/
static void smp_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;
    BD_ADDR dummy_bda = {0};

    SMP_TRACE_EVENT ("SMDBG l2c %s", __FUNCTION__);

    if (transport == BT_TRANSPORT_BR_EDR || memcmp(bd_addr, dummy_bda, BD_ADDR_LEN) == 0)
        return;

    if (memcmp(bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) == 0)
    {
        SMP_TRACE_EVENT ("%s()  for pairing BDA: %08x%04x  Event: %s",
                        __FUNCTION__,
                        (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;
                /* initiating connection established */
                p_cb->role = L2CA_GetBleConnRole(bd_addr);

                /* initialize local i/r key to be default keys */
                p_cb->local_r_key = p_cb->local_i_key =  SMP_SEC_DEFAULT_KEY;
                p_cb->loc_auth_req = p_cb->peer_auth_req = SMP_DEFAULT_AUTH_REQ;
                p_cb->cb_evt = SMP_IO_CAP_REQ_EVT;
                smp_sm_event(p_cb, SMP_L2CAP_CONN_EVT, NULL);
            }
        }
        else
        {
            int_data.reason = reason;
            /* Disconnected while doing security */
            smp_sm_event(p_cb, SMP_L2CAP_DISCONN_EVT, &int_data);
        }
    }
}
예제 #2
0
/*******************************************************************************
**
** Function         gatt_le_connect_cback
**
** Description      This callback function is called by L2CAP to indicate that
**                  the ATT fixed channel for LE is
**                      connected (conn = TRUE)/disconnected (conn = FALSE).
**
*******************************************************************************/
static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason)
{

    tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr);

    BOOLEAN                 check_srv_chg = FALSE;
    tGATTS_SRV_CHG          *p_srv_chg_clt=NULL;
    BOOLEAN                 is_bg_conn = FALSE;


    GATT_TRACE_DEBUG3 ("GATT   ATT protocol channel with BDA: %08x%04x is %s",
                       (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 ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr)) != NULL)
    {
        check_srv_chg = TRUE;
    }
    else
    {
        if (btm_sec_is_a_bonded_dev(bd_addr))
            gatt_add_a_bonded_dev_for_srv_chg(bd_addr);
    }

    if (connected)
    {
        GATT_TRACE_DEBUG1("connected is TRUE reason=%d",reason );
        /* BR/EDR lik, ignore this callback */
        if (reason == 0)
            return;

        /* do we have a channel initiating a connection? */
        if (p_tcb)
        {
            if (check_srv_chg)
                gatt_chk_srv_chg (p_srv_chg_clt);
            /* we are initiating connection */
            if ( gatt_get_ch_state(p_tcb) == GATT_CH_CONN)
            {
                /* send callback */
                gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
                p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE;

                gatt_send_conn_cback(FALSE, p_tcb);
            }
            else /* there was an exisiting link, ignore the callback */
            {
                GATT_TRACE_ERROR0("connection already up, ignore it");
                return;
            }
        }
        /* this is incoming connection or background connection callback */
        else
        {
            if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr)) != NULL)
            {
                p_tcb->att_lcid = L2CAP_ATT_CID;

                gatt_set_ch_state(p_tcb, GATT_CH_OPEN);

                p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE;
                if (L2CA_GetBleConnRole(p_tcb->peer_bda)== HCI_ROLE_MASTER)
                {
                    is_bg_conn = TRUE;
                }
                gatt_send_conn_cback (is_bg_conn, p_tcb);
                if (check_srv_chg)
                {
                    gatt_chk_srv_chg (p_srv_chg_clt);
                }
            }
            else
            {
                GATT_TRACE_ERROR0("CCB max out, no rsources");
            }
        }
    }
    else
    {
        gatt_cleanup_upon_disc(bd_addr, reason);
        GATT_TRACE_DEBUG0 ("ATT disconnected");
    }
}
예제 #3
0
파일: smp_l2c.c 프로젝트: morrey/bt_bcm
/*******************************************************************************
**
** Function         smp_data_received
**
** Description      This function is called when data is received from L2CAP on
**                  SMP channel.
**
**
** Returns          void
**
*******************************************************************************/
static void smp_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", __FUNCTION__);

    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 || SMP_OPCODE_SEC_REQ == cmd)
    {
        if ((p_cb->state == SMP_STATE_IDLE) && (p_cb->br_state == SMP_BR_STATE_IDLE) &&
            !(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD))
        {
            p_cb->role = L2CA_GetBleConnRole(bd_addr);
            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/security request received, passed into SM */
    }

    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);

        if (cmd == SMP_OPCODE_CONFIRM)
        {
            SMP_TRACE_DEBUG ("in %s cmd = 0x%02x, peer_auth_req = 0x%02x,"
                              "loc_auth_req = 0x%02x",
                              __FUNCTION__, cmd, p_cb->peer_auth_req, p_cb->loc_auth_req);

            if ((p_cb->peer_auth_req  & SMP_SC_SUPPORT_BIT) &&
                (p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT))
            {
                cmd = SMP_OPCODE_PAIR_COMMITM;
            }
        }

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

    GKI_freebuf (p_buf);
}