Exemple #1
0
/*******************************************************************************
**
** Function         sdp_conn_originate
**
** Description      This function is called from the API to originate a
**                  connection.
**
** Returns          void
**
*******************************************************************************/
tCONN_CB *sdp_conn_originate (UINT8 *p_bd_addr)
{
    tCONN_CB              *p_ccb;
    UINT16                cid;

    /* Allocate a new CCB. Return if none available. */
    if ((p_ccb = sdpu_allocate_ccb()) == NULL) {
        SDP_TRACE_WARNING ("SDP - no spare CCB for orig\n");
        return (NULL);
    }

    SDP_TRACE_EVENT ("SDP - Originate started\n");

    /* We are the originator of this connection */
    p_ccb->con_flags |= SDP_FLAGS_IS_ORIG;

    /* Save the BD Address and Channel ID. */
    memcpy (&p_ccb->device_address[0], p_bd_addr, sizeof (BD_ADDR));

    /* Transition to the next appropriate state, waiting for connection confirm. */
    p_ccb->con_state = SDP_STATE_CONN_SETUP;

    cid = L2CA_ConnectReq (SDP_PSM, p_bd_addr);

    /* Check if L2CAP started the connection process */
    if (cid != 0) {
        p_ccb->connection_id = cid;

        return (p_ccb);
    } else {
        SDP_TRACE_WARNING ("SDP - Originate failed\n");
        sdpu_release_ccb (p_ccb);
        return (NULL);
    }
}
Exemple #2
0
/*******************************************************************************
**
** Function         avdt_ad_open_req
**
** Description      This function is called by a CCB or SCB to open a transport
**                  channel.  This function allocates and initializes a
**                  transport channel table entry.  The channel can be opened
**                  in two roles:  as an initiator or acceptor.  When opened
**                  as an initiator the function will start an L2CAP connection.
**                  When opened as an acceptor the function simply configures
**                  the table entry to listen for an incoming channel.
**
**
** Returns          Nothing.
**
*******************************************************************************/
void avdt_ad_open_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, UINT8 role)
{
    tAVDT_TC_TBL    *p_tbl;
    UINT16          lcid;

    if ((p_tbl = avdt_ad_tc_tbl_alloc(p_ccb)) == NULL) {
        AVDT_TRACE_ERROR("avdt_ad_open_req: Cannot allocate p_tbl");
        return;
    }


    p_tbl->tcid = avdt_ad_type_to_tcid(type, p_scb);
    AVDT_TRACE_DEBUG("avdt_ad_open_req: type: %d, role: %d, tcid:%d\n",
                     type, role, p_tbl->tcid);

    if (type == AVDT_CHAN_SIG) {
        /* if signaling, get mtu from registration control block */
        p_tbl->my_mtu = avdt_cb.rcb.ctrl_mtu;
        p_tbl->my_flush_to = L2CAP_DEFAULT_FLUSH_TO;
    } else {
        /* otherwise get mtu from scb */
        p_tbl->my_mtu = p_scb->cs.mtu;
        p_tbl->my_flush_to = p_scb->cs.flush_to;

        /* also set scb_hdl in rt_tbl */
        avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].scb_hdl = avdt_scb_to_hdl(p_scb);
        AVDT_TRACE_DEBUG("avdt_cb.ad.rt_tbl[%d][%d].scb_hdl = %d\n",
                         avdt_ccb_to_idx(p_ccb), p_tbl->tcid,
                         avdt_scb_to_hdl(p_scb));
    }

    /* if we're acceptor, we're done; just sit back and listen */
    if (role == AVDT_ACP) {
        p_tbl->state = AVDT_AD_ST_ACP;
    }
    /* else we're inititator, start the L2CAP connection */
    else {
        p_tbl->state = AVDT_AD_ST_CONN;

        /* call l2cap connect req */
        if ((lcid = L2CA_ConnectReq(AVDT_PSM, p_ccb->peer_addr)) != 0) {
            /* if connect req ok, store tcid in lcid table  */
            avdt_cb.ad.lcid_tbl[lcid - L2CAP_BASE_APPL_CID] = avdt_ad_tc_tbl_to_idx(p_tbl);
            AVDT_TRACE_DEBUG("avdt_cb.ad.lcid_tbl[%d] = %d\n",
                             (lcid - L2CAP_BASE_APPL_CID), avdt_ad_tc_tbl_to_idx(p_tbl));

            avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].lcid = lcid;
            AVDT_TRACE_DEBUG("avdt_cb.ad.rt_tbl[%d][%d].lcid = 0x%x\n",
                             avdt_ccb_to_idx(p_ccb), p_tbl->tcid,
                             lcid);
        } else {
            /* if connect req failed, call avdt_ad_tc_close_ind() */
            avdt_ad_tc_close_ind(p_tbl, 0);
        }
    }
}
Exemple #3
0
/*******************************************************************************
**
** Function         rfc_mx_sm_state_idle
**
** Description      This function handles events when the multiplexer is in
**                  IDLE state. This state exists when connection is being
**                  initially established.
**
** Returns          void
**
*******************************************************************************/
void rfc_mx_sm_state_idle (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
{
    RFCOMM_TRACE_EVENT1 ("rfc_mx_sm_state_idle - evt:%d", event);
    switch (event)
    {
    case RFC_MX_EVENT_START_REQ:

        /* Initialize L2CAP MTU */
        p_mcb->peer_l2cap_mtu = L2CAP_DEFAULT_MTU - RFCOMM_MIN_OFFSET - 1;

        if ((p_mcb->lcid = L2CA_ConnectReq (BT_PSM_RFCOMM, p_mcb->bd_addr)) == 0)
        {
            PORT_StartCnf (p_mcb, RFCOMM_ERROR);
            return;
        }
        /* Save entry for quicker access to mcb based on the LCID */
        rfc_save_lcid_mcb (p_mcb, p_mcb->lcid);

        p_mcb->state = RFC_MX_STATE_WAIT_CONN_CNF;
        return;

    case RFC_MX_EVENT_START_RSP:
    case RFC_MX_EVENT_CONN_CNF:
    case RFC_MX_EVENT_CONF_IND:
    case RFC_MX_EVENT_CONF_CNF:
        RFCOMM_TRACE_ERROR2 ("Mx error state %d event %d", p_mcb->state, event);
        return;

    case RFC_MX_EVENT_CONN_IND:

        rfc_timer_start (p_mcb, RFCOMM_CONN_TIMEOUT);
        L2CA_ConnectRsp (p_mcb->bd_addr, *((UINT8 *)p_data), p_mcb->lcid, L2CAP_CONN_OK, 0);

        rfc_mx_send_config_req (p_mcb);

        p_mcb->state = RFC_MX_STATE_CONFIGURE;
        return;

    case RFC_EVENT_SABME:
        break;

    case RFC_EVENT_UA:
    case RFC_EVENT_DM:
        return;

    case RFC_EVENT_DISC:
        rfc_send_dm (p_mcb, RFCOMM_MX_DLCI, TRUE);
        return;

    case RFC_EVENT_UIH:
        rfc_send_dm (p_mcb, RFCOMM_MX_DLCI, FALSE);
        return;
    }
    RFCOMM_TRACE_EVENT2 ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state);
}
static UINT16 L2cap_Connect(UINT16 psm, bt_bdaddr_t *bd_addr)
{

    BTIF_TRACE_DEBUG("L2cap_Connect:: %0x %0x %0x %0x %0x %0x", bd_addr->address[0],bd_addr->address[1],
                         bd_addr->address[2],bd_addr->address[3],bd_addr->address[4],bd_addr->address[5]);

    if (0 == (g_lcid = L2CA_ConnectReq (psm, bd_addr->address)))
    {
        BTIF_TRACE_DEBUG("Error:: L2CA_ConnectReq failed for psm %d", psm);
    }
    return g_lcid;
}
/*******************************************************************************
**
** Function         hidh_sec_check_complete_orig
**
** Description      This function checks to see if security procedures are being
**                  carried out or not..
**
** Returns          void
**
*******************************************************************************/
void hidh_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
{
    tHID_HOST_DEV_CTB *p_dev = (tHID_HOST_DEV_CTB *) p_ref_data;
    UINT8 dhandle;
#if (HID_HOST_MAX_CONN_RETRY > 0)
    UINT32 cb_res = HID_ERR_AUTH_FAILED;
#endif
    UINT32 reason;

    dhandle = ((UINT32)p_dev - (UINT32)&(hh_cb.devices[0]))/ sizeof(tHID_HOST_DEV_CTB);
    if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY )
    {
        HIDH_TRACE_EVENT0 ("HID-Host Originator security pass.");
        p_dev->conn.disc_reason = HID_SUCCESS;  /* Authentication passed. Reset disc_reason (from HID_ERR_AUTH_FAILED) */

        /* Check if L2CAP started the connection process for interrupt channel */
        if ((p_dev->conn.intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0)
        {
            HIDH_TRACE_WARNING0 ("HID-Host INTR Originate failed");
            reason = HID_L2CAP_REQ_FAIL ;
            hidh_conn_disconnect (dhandle);
            hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, reason, NULL ) ;
            return;
        }
        else
        {
            /* Transition to the next appropriate state, waiting for connection confirm on control channel. */
            p_dev->conn.conn_state = HID_CONN_STATE_CONNECTING_INTR;
        }
    }

    if( res != BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY )
    {
#if (HID_HOST_MAX_CONN_RETRY > 0)
        if( res == BTM_DEVICE_TIMEOUT )
        {
            if( p_dev->conn_tries <= HID_HOST_MAX_CONN_RETRY )
            {
                hidh_conn_retry (dhandle);
                return;
            }
            else
                cb_res = HID_L2CAP_CONN_FAIL | HCI_ERR_PAGE_TIMEOUT ;
        }
#endif
        p_dev->conn.disc_reason = HID_ERR_AUTH_FAILED;      /* Save reason for disconnecting */
        hidh_conn_disconnect(dhandle);
    }

}
/*******************************************************************************
**
** Function         sdp_conn_originate
**
** Description      This function is called from the API to originate a
**                  connection.
**
** Returns          void
**
*******************************************************************************/
tCONN_CB* sdp_conn_originate (UINT8 *p_bd_addr)
{
    tCONN_CB              *p_ccb;
    UINT16                cid;

    /* Allocate a new CCB. Return if none available. */
    if ((p_ccb = sdpu_allocate_ccb()) == NULL)
    {
        SDP_TRACE_WARNING0 ("SDP - no spare CCB for orig");
        return (NULL);
    }

    SDP_TRACE_EVENT0 ("SDP - Originate started");

    /* We are the originator of this connection */
    p_ccb->con_flags |= SDP_FLAGS_IS_ORIG;

    /* Save the BD Address and Channel ID. */
    memcpy (&p_ccb->device_address[0], p_bd_addr, sizeof (BD_ADDR));

    /* Transition to the next appropriate state, waiting for connection confirm. */
    p_ccb->con_state = SDP_STATE_CONN_SETUP;

// btla-specific ++
#ifndef ANDROID_APP_INCLUDED  /* Skip for Android: Do not need to set out_service for sdp, since sdp does not use sec. Prevents over-writing service_rec of a connection already in progress */
    BTM_SetOutService(p_bd_addr, BTM_SEC_SERVICE_SDP_SERVER, 0);
#endif
// btla-specific --

    cid = L2CA_ConnectReq (SDP_PSM, p_bd_addr);

    /* Check if L2CAP started the connection process */
    if (cid != 0)
    {
        p_ccb->connection_id = cid;

        return (p_ccb);
    }
    else
    {
        SDP_TRACE_WARNING0 ("SDP - Originate failed");
        sdpu_release_ccb (p_ccb);
        return (NULL);
    }
}
/*******************************************************************************
**
** Function         gatt_connect
**
** Description      This function is called to initiate a connection to a peer device.
**
** Parameter        rem_bda: remote device address to connect to.
**
** Returns          TRUE if connection is started, otherwise return FALSE.
**
*******************************************************************************/
BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb, tBT_TRANSPORT transport)
{
    BOOLEAN             gatt_ret = FALSE;

    if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN)
        gatt_set_ch_state(p_tcb, GATT_CH_CONN);

    if (transport == BT_TRANSPORT_LE)
    {
        p_tcb->att_lcid = L2CAP_ATT_CID;
        gatt_ret = L2CA_ConnectFixedChnl (L2CAP_ATT_CID, rem_bda);
    }
    else
    {
        if ((p_tcb->att_lcid = L2CA_ConnectReq(BT_PSM_ATT, rem_bda)) != 0)
            gatt_ret = TRUE;
    }

    return gatt_ret;
}
/*******************************************************************************
**
** Function         gatt_connect
**
** Description      This function is called to initiate a connection to a peer device.
**
** Parameter        rem_bda: remote device address to connect to.
**
** Returns          TRUE if connection is started, otherwise return FALSE.
**
*******************************************************************************/
BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb)
{
    BOOLEAN             gatt_ret = FALSE;

    if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN)
        gatt_set_ch_state(p_tcb, GATT_CH_CONN);

    /* select the physical link for GATT connection */
    if (BTM_UseLeLink(rem_bda))
    {
        p_tcb->att_lcid = L2CAP_ATT_CID;
        gatt_ret = L2CA_ConnectFixedChnl (L2CAP_ATT_CID, rem_bda);
    }
    else
    {
        if ((p_tcb->att_lcid = L2CA_ConnectReq(BT_PSM_ATT, rem_bda)) != 0)
            gatt_ret = TRUE;
    }

    return gatt_ret;
}
Exemple #9
0
/*******************************************************************************
**
** Function         gatt_connect
**
** Description      This function is called to initiate a connection to a peer device.
**
** Parameter        rem_bda: remote device address to connect to.
**
** Returns          TRUE if connection is started, otherwise return FALSE.
**
*******************************************************************************/
BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb)
{
    BOOLEAN             gatt_ret = TRUE;
    tBT_DEVICE_TYPE     dev_type;
    tBLE_ADDR_TYPE      addr_type;

    BTM_ReadDevInfo(rem_bda, &dev_type, &addr_type);

    gatt_set_ch_state(p_tcb, GATT_CH_CONN);

    if (dev_type == BT_DEVICE_TYPE_BLE)
    {
        p_tcb->att_lcid = L2CAP_ATT_CID;
        gatt_ret = L2CA_ConnectFixedChnl (L2CAP_ATT_CID, rem_bda);
    }
    else
    {
        if ((p_tcb->att_lcid = L2CA_ConnectReq(BT_PSM_ATT, rem_bda)) == 0)
            gatt_ret = FALSE;
    }

    return gatt_ret;
}
Exemple #10
0
/*******************************************************************************
**
** Function         hidh_l2cif_config_cfm
**
** Description      This function processes the L2CAP configuration confirmation
**                  event.
**
** Returns          void
**
*******************************************************************************/
static void hidh_l2cif_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
{
    UINT8 dhandle;
    tHID_CONN    *p_hcon = NULL;
    UINT32  reason;

    HIDH_TRACE_EVENT ("HID-Host Rcvd cfg cfm, CID: 0x%x  Result: %d", l2cap_cid, p_cfg->result);

    /* Find CCB based on CID */
    if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES )
        p_hcon = &hh_cb.devices[dhandle].conn;

    if (p_hcon == NULL)
    {
        HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid);
        return;
    }

    /* If configuration failed, disconnect the channel(s) */
    if (p_cfg->result != L2CAP_CFG_OK)
    {
        hidh_conn_disconnect (dhandle);
        reason = HID_L2CAP_CFG_FAIL | (UINT32) p_cfg->result ;
        HIDH_TRACE_WARNING ("HID-Host: l2cap config ind failed, reason = %d", reason);
        hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, reason, NULL ) ;
        return;
    }

    if (l2cap_cid == p_hcon->ctrl_cid)
    {
        p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE;
        if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) &&
           (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE))
        {
            /* Connect interrupt channel */
            p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;  /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */
            if ((p_hcon->intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0)
            {
                HIDH_TRACE_WARNING ("HID-Host INTR Originate failed");
                reason = HID_L2CAP_REQ_FAIL ;
                p_hcon->conn_state = HID_CONN_STATE_UNUSED;
                hidh_conn_disconnect (dhandle);
                HIDH_TRACE_WARNING ("HID-Host: l2cap config ind failed 2, reason = %d", reason);
                hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, reason, NULL ) ;
                return;
            }
            else
            {
                /* Transition to the next appropriate state, waiting for connection confirm on interrupt channel. */
                p_hcon->conn_state = HID_CONN_STATE_CONNECTING_INTR;
            }
        }
    }
    else
        p_hcon->conn_flags |= HID_CONN_FLAGS_MY_INTR_CFG_DONE;

    /* If all configuration is complete, change state and tell management we are up */
    if (((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) == HID_CONN_FLAGS_ALL_CONFIGURED)
     && (p_hcon->conn_state == HID_CONN_STATE_CONFIG))
    {
        p_hcon->conn_state = HID_CONN_STATE_CONNECTED;
        /* Reset disconnect reason to success, as connection successful */
        p_hcon->disc_reason = HID_SUCCESS;

        hh_cb.devices[dhandle].state = HID_DEV_CONNECTED;
        hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_OPEN, 0, NULL ) ;
    }
}
Exemple #11
0
void l2captester_handler(ilm_struct *ilm_ptr)
{
    char *string;
    bt_test_cmd_struct *test_msg;
		if (ilm_ptr->msg_id == MSG_ID_BT_TEST_CMD_REQ)    	
    {
        test_msg = ((bt_test_cmd_struct *)ilm_ptr->local_para_ptr);    
        string = (char *)test_msg->string;    
        if(strncmp(string, "init",4)==0)
        {
            l2capTesterInit();
        }
        else if(strncmp(string, "senddata",8)==0)
        {
            L2capSendData();
        }        
        else if(strncmp(string, "conn",4)==0)
        {
            U8 bd_addr[6];
            L2capConnectRequest parms;
            
            memset(bd_addr, 0, 6);
            if(!l2capTester_get_bdaddr_from_string(bd_addr, string+4))
            {
                return;
            }    		
            memcpy((U8 *)parms.bd_addr, (U8 *)bd_addr, 6);
            L2CA_ConnectReq(&parms);
        }    
        else if(strncmp(string, "disconn",7)==0)
        {
            L2capDisconnectRequest parms;
            parms.cid = L2CAPTS(cid);
            L2CA_DisconnectReq(&parms);
        }     
        else if(strncmp(string, "info",4)==0)
        {
            L2capInfoRequest parms;
            U8 bd_addr[6];
            
            memset(bd_addr, 0, 6);
            if(!l2capTester_get_bdaddr_from_string(bd_addr, string+4))
            {
                return;
            }    		
            memcpy((U8 *)parms.bd_addr, (U8 *)bd_addr, 6);
            parms.info_type = 0x0002;
            L2CA_InfoReq(&parms);
        }     
        else if(strncmp(string, "echo",4)==0)
        {
            L2capEchoRequest parms;
            U8 bd_addr[6];
            
            memset(bd_addr, 0, 6);
            if(!l2capTester_get_bdaddr_from_string(bd_addr, string+4))
            {
                return;
            }    		
            memcpy((U8 *)parms.bd_addr, (U8 *)bd_addr, 6);
            L2CA_EchoReq(&parms);
        }     
        else if(strncmp(string, "encry",5)==0)
        {
            bt_bm_write_authentication_mode_req_struct ptr;

            ptr.mode = BTBM_AUTHENTICATION_ENABLE_LEVEL3_ENCRYPT_ON;
            BTBMGapSetAuthenticationMode(TRUE, &ptr); 
        }             
#if L2CAP_NUM_GROUPS > 0
        else if(strncmp(string, "groupreq",8)==0)
        {
            L2capGroupAddr parms;
            U8 bd_addr[6];
            
            bt_trace(TRACE_GROUP_1,GROUP_ADD_REQUEST);
            memset(bd_addr, 0, 6);
            if(!l2capTester_get_bdaddr_from_string(bd_addr, string+8))
            {
                return;
            }    		
            memcpy((U8 *)parms.bd_addr, (U8 *)bd_addr, 6);
            L2CA_AddGroup(&parms);
        }   
        else if(strncmp(string, "grouprem",8)==0)
        {
            L2capGroupAddr parms;
            U8 bd_addr[6];
            
            bt_trace(TRACE_GROUP_1,GROUP_REMOVE_REQUEST);
            memset(bd_addr, 0, 6);
            if(!l2capTester_get_bdaddr_from_string(bd_addr, string+8))
            {
                return;
            }    		
            memcpy((U8 *)parms.bd_addr, (U8 *)bd_addr, 6);
            L2CA_RemoveGroup(&parms);
        }   
        else if(strncmp(string, "sendgroupdata",13)==0)
        {
            bt_trace(TRACE_GROUP_1,SEND_GROUP_DATA);
            L2CA_GroupDataReq();
        }
        else if(strncmp(string, "sendunidata",11)==0)
        {
            bt_trace(TRACE_GROUP_1,SEND_GROUP_DATA);
            L2CA_UniCastDataReq();
        }
        else if(strncmp(string, "setencry", 8)==0)
        {
            Report(("set encryption on"));
            BTBMGapSetEncryptionOn();        
        }
#endif
    }
}
Exemple #12
0
/*******************************************************************************
**
** Function         rfc_mx_sm_state_disc_wait_ua
**
** Description      This function handles events when the multiplexer sent
**                  DISC and is waiting for UA reply.
**
** Returns          void
**
*******************************************************************************/
void rfc_mx_sm_state_disc_wait_ua (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
{
    BT_HDR *p_buf;

    RFCOMM_TRACE_EVENT1 ("rfc_mx_sm_state_disc_wait_ua - evt:%d", event);
    switch (event)
    {
    case RFC_EVENT_UA:
    case RFC_EVENT_DM:
    case RFC_EVENT_TIMEOUT:
        L2CA_DisconnectReq (p_mcb->lcid);

        if (p_mcb->restart_required)
        {
            /* Start Request was received while disconnecting.  Execute it again */
            if ((p_mcb->lcid = L2CA_ConnectReq (BT_PSM_RFCOMM, p_mcb->bd_addr)) == 0)
            {
                PORT_StartCnf (p_mcb, RFCOMM_ERROR);
                return;
            }
            /* Save entry for quicker access to mcb based on the LCID */
            rfc_save_lcid_mcb (p_mcb, p_mcb->lcid);

            /* clean up before reuse it */
            while ((p_buf = (BT_HDR *)GKI_dequeue(&p_mcb->cmd_q)) != NULL)
                GKI_freebuf(p_buf);

            rfc_timer_start (p_mcb, RFC_MCB_INIT_INACT_TIMER);

            p_mcb->is_initiator     = TRUE;
            p_mcb->restart_required = FALSE;
            p_mcb->local_cfg_sent   = FALSE;
            p_mcb->peer_cfg_rcvd    = FALSE;

            p_mcb->state = RFC_MX_STATE_WAIT_CONN_CNF;
            return;
        }
        rfc_release_multiplexer_channel (p_mcb);
        return;

    case RFC_EVENT_DISC:
        rfc_send_ua (p_mcb, RFCOMM_MX_DLCI);
        return;

    case RFC_EVENT_UIH:
        GKI_freebuf (p_data);
        rfc_send_dm (p_mcb, RFCOMM_MX_DLCI, FALSE);
        return;

    case RFC_MX_EVENT_START_REQ:
        p_mcb->restart_required = TRUE;
        return;

    case RFC_MX_EVENT_DISC_IND:
        p_mcb->state = RFC_MX_STATE_IDLE;
        PORT_CloseInd (p_mcb);
        return;

    case RFC_MX_EVENT_CLOSE_REQ:
        return;

    case RFC_MX_EVENT_QOS_VIOLATION_IND:
        break;
    }
    RFCOMM_TRACE_EVENT2 ("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state);
}
Exemple #13
0
/*******************************************************************************
**
** Function         BNEP_Connect
**
** Description      This function creates a BNEP connection to a remote
**                  device.
**
** Parameters:      p_rem_addr  - BD_ADDR of the peer
**                  src_uuid    - source uuid for the connection
**                  dst_uuid    - destination uuid for the connection
**                  p_handle    - pointer to return the handle for the connection
**
** Returns          BNEP_SUCCESS                if connection started
**                  BNEP_NO_RESOURCES           if no resources
**
*******************************************************************************/
tBNEP_RESULT BNEP_Connect (BD_ADDR p_rem_bda,
                           tBT_UUID *src_uuid,
                           tBT_UUID *dst_uuid,
                           UINT16 *p_handle)
{
    UINT16          cid;
    tBNEP_CONN      *p_bcb = bnepu_find_bcb_by_bd_addr (p_rem_bda);

    BNEP_TRACE_API ("BNEP_Connect()  BDA: %02x-%02x-%02x-%02x-%02x-%02x",
                     p_rem_bda[0], p_rem_bda[1], p_rem_bda[2],
                     p_rem_bda[3], p_rem_bda[4], p_rem_bda[5]);

    if (!bnep_cb.profile_registered)
        return BNEP_WRONG_STATE;

    /* Both source and destination UUID lengths should be same */
    if (src_uuid->len != dst_uuid->len)
        return BNEP_CONN_FAILED_UUID_SIZE;

#if (!defined (BNEP_SUPPORTS_ALL_UUID_LENGTHS) || BNEP_SUPPORTS_ALL_UUID_LENGTHS == FALSE)
    if (src_uuid->len != 2)
        return BNEP_CONN_FAILED_UUID_SIZE;
#endif

    if (!p_bcb)
    {
        if ((p_bcb = bnepu_allocate_bcb (p_rem_bda)) == NULL)
            return (BNEP_NO_RESOURCES);
    }
    else if (p_bcb->con_state != BNEP_STATE_CONNECTED)
            return BNEP_WRONG_STATE;
    else
    {
        /* Backup current UUID values to restore if role change fails */
        memcpy ((UINT8 *)&(p_bcb->prv_src_uuid), (UINT8 *)&(p_bcb->src_uuid), sizeof (tBT_UUID));
        memcpy ((UINT8 *)&(p_bcb->prv_dst_uuid), (UINT8 *)&(p_bcb->dst_uuid), sizeof (tBT_UUID));
    }

    /* We are the originator of this connection */
    p_bcb->con_flags |= BNEP_FLAGS_IS_ORIG;

    memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)src_uuid, sizeof (tBT_UUID));
    memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)dst_uuid, sizeof (tBT_UUID));

    if (p_bcb->con_state == BNEP_STATE_CONNECTED)
    {
        /* Transition to the next appropriate state, waiting for connection confirm. */
        p_bcb->con_state = BNEP_STATE_SEC_CHECKING;

        BNEP_TRACE_API ("BNEP initiating security procedures for src uuid 0x%x",
            p_bcb->src_uuid.uu.uuid16);

#if (defined (BNEP_DO_AUTH_FOR_ROLE_SWITCH) && BNEP_DO_AUTH_FOR_ROLE_SWITCH == TRUE)
        btm_sec_mx_access_request (p_bcb->rem_bda, BT_PSM_BNEP, TRUE,
                                   BTM_SEC_PROTO_BNEP,
                                   bnep_get_uuid32(src_uuid),
                                   &bnep_sec_check_complete, p_bcb);
#else
        bnep_sec_check_complete (p_bcb->rem_bda, p_bcb, BTM_SUCCESS);
#endif

    }
    else
    {
        /* Transition to the next appropriate state, waiting for connection confirm. */
        p_bcb->con_state = BNEP_STATE_CONN_START;

        if ((cid = L2CA_ConnectReq (BT_PSM_BNEP, p_bcb->rem_bda)) != 0)
        {
            p_bcb->l2cap_cid = cid;

        }
        else
        {
            BNEP_TRACE_ERROR ("BNEP - Originate failed");
            if (bnep_cb.p_conn_state_cb)
                (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, BNEP_CONN_FAILED, FALSE);
            bnepu_release_bcb (p_bcb);
            return BNEP_CONN_FAILED;
        }

        /* Start timer waiting for connect */
        btu_start_timer (&p_bcb->conn_tle, BTU_TTYPE_BNEP, BNEP_CONN_TIMEOUT);
    }

    *p_handle = p_bcb->handle;
    return (BNEP_SUCCESS);
}
Exemple #14
0
/*******************************************************************************
**
** Function         hidh_l2cif_config_ind
**
** Description      This function processes the L2CAP configuration indication
**                  event.
**
** Returns          void
**
*******************************************************************************/
static void hidh_l2cif_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
{
    UINT8 dhandle;
    tHID_CONN    *p_hcon = NULL;
    UINT32  reason;

    /* Find CCB based on CID */
    if( (dhandle = find_conn_by_cid(l2cap_cid)) < HID_HOST_MAX_DEVICES )
    {
        p_hcon = &hh_cb.devices[dhandle].conn;
    }

    if (p_hcon == NULL)
    {
        HIDH_TRACE_WARNING ("HID-Host Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid);
        return;
    }

    HIDH_TRACE_EVENT ("HID-Host Rcvd cfg ind, sent cfg cfm, CID: 0x%x", l2cap_cid);

    /* Remember the remote MTU size */
    if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_HOST_MTU))
        p_hcon->rem_mtu_size = HID_HOST_MTU;
    else
        p_hcon->rem_mtu_size = p_cfg->mtu;

    /* For now, always accept configuration from the other side */
    p_cfg->flush_to_present = FALSE;
    p_cfg->mtu_present      = FALSE;
    p_cfg->result           = L2CAP_CFG_OK;

    L2CA_ConfigRsp (l2cap_cid, p_cfg);

    if (l2cap_cid == p_hcon->ctrl_cid)
    {
        p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE;
        if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) &&
           (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE))
        {
            /* Connect interrupt channel */
            p_hcon->disc_reason = HID_L2CAP_CONN_FAIL;	/* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */
            if ((p_hcon->intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0)
            {
                HIDH_TRACE_WARNING ("HID-Host INTR Originate failed");
                reason = HID_L2CAP_REQ_FAIL ;
                p_hcon->conn_state = HID_CONN_STATE_UNUSED;
                hidh_conn_disconnect (dhandle);
                hh_cb.callback( dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, reason, NULL ) ;
                return;
            }
            else
            {
                /* Transition to the next appropriate state, waiting for connection confirm on interrupt channel. */
                p_hcon->conn_state = HID_CONN_STATE_CONNECTING_INTR;
            }
        }
    }
    else
        p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_INTR_CFG_DONE;

    /* If all configuration is complete, change state and tell management we are up */
    if (((p_hcon->conn_flags & HID_CONN_FLAGS_ALL_CONFIGURED) == HID_CONN_FLAGS_ALL_CONFIGURED)
     && (p_hcon->conn_state == HID_CONN_STATE_CONFIG))
    {
        p_hcon->conn_state = HID_CONN_STATE_CONNECTED;
        /* Reset disconnect reason to success, as connection successful */
        p_hcon->disc_reason = HID_SUCCESS;

        hh_cb.devices[dhandle].state = HID_DEV_CONNECTED;
        hh_cb.callback( dhandle,  hh_cb.devices[dhandle].addr, HID_HDEV_EVT_OPEN, 0, NULL ) ;
    }
}