Ejemplo n.º 1
0
U8 L2CA_DisconnectReq(L2capDisconnectRequest *parms)
{
    BtStatus status = BT_STATUS_SUCCESS;
    
    bt_trace(BT_TRACE_G1_PROTOCOL, BT_L2CAPTS_DISCONNECTREQ);
    status = L2CAP_DisconnectReq(parms->cid);
    return status;
}
Ejemplo n.º 2
0
/*---------------------------------------------------------------------------
 *            HidStateDiscPending()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Disconnect Pending state for the HID channel.
 *
 * Return:    void
 */
void HidStateDiscPending(HidChannel *Channel, L2capChannelId Cid, 
                             L2capCallbackParms *Parms)
{
    BtStatus status;
    
    kal_trace(BT_TRACE_G2_PROFILES,HIDSTATEDISCPENDINGx02X_CIDx02X ,Parms->event, Cid, Parms->status);    
    CMGR_HidNoRoleSwitch(0);        
    
    switch (Parms->event) 
    {
    case L2EVENT_DISCONNECTED:
        /* The connection is down, adjust the connection reference count */
        kal_trace(BT_TRACE_G2_PROFILES,HID_CHANNELCONCOUNTx02X ,Channel->conCount);
        if (Channel->conCount > 0) 
        {
            Channel->conCount--;
        }
        kal_trace(BT_TRACE_G2_PROFILES,CHANNELCTRLCIDx02XCHANNELINTRCIDx02X , Channel->ctrlCid, Channel->intrCid);
    
        if (Cid == Channel->ctrlCid) 
        {
            Channel->ctrlCid = 0;
        } 
        else 
        {
            Channel->intrCid = 0;
        }

        if (Channel->conCount > 0)
        {
            if (Channel->flags & CHNL_FLAG_TERMINATOR) 
            {
                kal_trace(BT_TRACE_G2_PROFILES,HID_TRY_TO_DISCONNECT_INTR_CHANNEL);
                /* First connection disconnect is complete, disconnect the 2nd */
                /* Disconnect control channel secondly */
                status = L2CAP_DisconnectReq(Channel->ctrlCid);
                kal_trace(BT_TRACE_G2_PROFILES,HID_L2CAP_DISCONNECT_REQ_CID_CIDx02X_STATUSx02X ,Channel->intrCid, status);
            }
        } 
        else if (Channel->state == HID_STATE_CONN_PENDING && 
                (Channel->ctrlCid != 0 || Channel->intrCid != 0))
        {
            /* This means the connection is still ongoing */
        }
        else 
        {
            kal_trace(BT_TRACE_G2_PROFILES,HIDCLEARCONNECTION);
            if (Channel->flags & CHNL_FLAG_SERVICE_QUERY)
            {
                /* if SDP query is not completed yet, not remove the connection until SDP query is done */
                Channel->bSDPDiscPending = TRUE;
            }
            else
            {
                /* Clear the connection structure and notify the application */
                HidClearConnection(Channel, BT_STATUS_SUCCESS, Parms->status);
            }
        }
    }

}
Ejemplo n.º 3
0
/*---------------------------------------------------------------------------
 *            HidStateConnPending()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Connection Pending state for the HID channel.
 *
 * Return:    void
 */
void HidStateConnPending(HidChannel *Channel, L2capChannelId Cid, 
                             L2capCallbackParms *Parms)
{
    //BtSniffInfo sniffInfo;
    BtStatus status;
    
    kal_trace(BT_TRACE_G2_PROFILES,HIDSTATECONNPENDINGx02X ,Parms->event);    
    switch (Parms->event) 
    {
    case L2EVENT_CONNECT_AUTORIZED:
        L2Cap_AuthorizeConnectRsp(Cid, TRUE);
        break;
    case L2EVENT_CONNECT_IND:
        /* A second connection was requested */
        status = L2CAP_ConnectRsp(Cid, L2CONN_ACCEPTED, 0);
        kal_trace(BT_TRACE_G2_PROFILES,L2CAP_CONNECTRSPx02X ,status);
        break;
    case L2EVENT_CONNECTED:
        /* A connection is up */
        //Assert(Channel->conCount < 2);
	if(Channel->conCount >= 2){
		bt_prompt_trace(MOD_BT,"[HID]Channel->conCount >= 2");
		return;
		}
        Channel->conCount++;
        CMGR_HidNoRoleSwitch(1);
        if (Channel->conCount == 2) 
        {
            /* Notify the application */
            Channel->state = HID_STATE_OPEN;
            HidAppCallback(Channel, HIDEVENT_OPEN, BT_STATUS_SUCCESS,
                           Channel->cmgrHandler.remDev, 
                           sizeof(BtRemoteDevice));

            /* Put it on the list of registered handlers */
            CMGR_SetDeviceAsMaster(&Channel->cmgrHandler);
//            CMGR_ActivateSniffTimer(&Channel->cmgrHandler);
        } 
        else if (Channel->flags & CHNL_FLAG_INITIATOR) 
        {
            /* The channel initiated the connection, establish the 
             * interrupt channel 
             */
            if (Channel->intrCid == Cid)
            {
                /* This means control channel has broken before
                    interrupt channel established */
                L2CAP_DisconnectReq(Cid);
                break;
            }
            if (L2CAP_ConnectReq(&HID(hidIntrPsm), BT_PSM_HID_INTR, 
                                 Channel->cmgrHandler.remDev, 0,
                                 &(Channel->intrCid)) != BT_STATUS_PENDING) 
             {
                /* Connect request failed, tear down the first connection */
                status = L2CAP_DisconnectReq(Channel->ctrlCid);
                kal_trace(BT_TRACE_G2_PROFILES,HID_L2CAP_DISCONNECT_REQ_CID_CIDx02X_STATUSx02X ,Channel->ctrlCid, status);
            }
        }
        break;
    case L2EVENT_DISCONNECTED:
        /* Connection is going down */
        CMGR_HidNoRoleSwitch(0);        
        HidStateDiscPending(Channel, Cid, Parms);
        break;
    default:
        /* Ignore any other events */
        kal_trace(BT_TRACE_G2_PROFILES,HID_CHANNEL_CONN_PENDING_STATE_RECEIVED_AN_UNEXPECTED_EVENT_x02X , Parms->event);
    }
}
Ejemplo n.º 4
0
/*---------------------------------------------------------------------------
 *            HidL2Callback()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  L2CAP callback function for the Channel.
 *
 * Return:    void
 */
void HidL2Callback(L2capChannelId Cid, L2capCallbackParms *Parms)
{
    HidChannel *channel;

    channel = HidFindChannelByCid(Cid, Parms->aclLink);
    kal_trace(BT_TRACE_G2_PROFILES,HIDPARMSEVENTx02X ,Parms->event);
    kal_trace(BT_TRACE_G2_PROFILES,HID_CID_x02X ,Cid);
    kal_trace(BT_TRACE_G2_PROFILES,HID_CHANNELx08X , channel);
    switch (Parms->event) 
    {
    case L2EVENT_CONNECT_AUTORIZED:
        if (channel == NULL) 
        {
            U8 searchType;
            if (Parms->owner.psm == &HID(hidCtrlPsm))
                searchType = HID_FIND_CTRL_CID;
            else
                searchType = HID_FIND_INTR_CID;

            channel = HidFindUnusedChannel(searchType, Parms->aclLink);
            if (channel == NULL)
            {
                if (!HidCheckValidConnect(searchType, Cid, Parms->aclLink))
                {
                    Parms->aclLink->discFlag = TRUE;
                    L2CAP_ConnectRsp(Cid, L2CONN_REJECT_NO_RESOURCES, 0);
                    break;
                }

                //  Get a new channel 
                channel = HidNewChannel();
                if (channel == NULL) 
                {
                    kal_trace(BT_TRACE_G2_PROFILES,CHANNEL_IS_0_RETURN);
                    /* No channel available, reject the request */
                    Parms->aclLink->discFlag = TRUE;
                    L2CAP_ConnectRsp(Cid, L2CONN_REJECT_NO_RESOURCES, 0);
                    break;
                }
                channel->cmgrHandler.remDev = Parms->aclLink;
            }
        }
        if (channel->conCount == 0)
        {
            /* Only create ACL link for the first L2CAP connection */
            if (CMGR_CreateDataLink(&channel->cmgrHandler, 
                                    &Parms->aclLink->bdAddr) != BT_STATUS_SUCCESS) 
            {
                /* Could not create a link to the ACL */
                (void)L2CAP_ConnectRsp(Cid, L2CONN_REJECT_NO_RESOURCES, 0);
                break;
            }
        }

        if (Parms->owner.psm == &HID(hidCtrlPsm)) 
            channel->ctrlCid = Cid;
        else 
            channel->intrCid = Cid;
        /* Call the state machine */
        if (channel != 0) 
        {
            kal_trace(BT_TRACE_G2_PROFILES,HID_A_SMAx02XBx02X ,channel->state,Cid);
            HID(hidState)[channel->state](channel, Cid, Parms);
        }
        else
            kal_trace(BT_TRACE_G2_PROFILES,HIDCHANNEL_0);
        break;
    case L2EVENT_CONNECT_IND:
#ifdef HID_AUTHORIZATION
        //Assert(channel !=0);
	if(channel ==0){
		bt_prompt_trace(MOD_BT,"[HID]channel ==0");
		return;
		}
        L2CAP_ConnectRsp(Cid, L2CONN_ACCEPTED, 0);
#else
        if (channel == 0) 
        {
            /* Get a new channel */
            if (Parms->owner.psm == &HID(hidCtrlPsm)) 
                channel = HidFindUnusedChannel(HID_FIND_CTRL_CID, Parms->aclLink);
            else 
                channel = HidFindUnusedChannel(HID_FIND_INTR_CID, Parms->aclLink);
        }

        if (channel == 0) 
        {
            /* No channel available, reject the request */
            L2CAP_ConnectRsp(Cid, L2CONN_REJECT_NO_RESOURCES, 0);
            break;
        }
        //Assert(channel !=0);
	if(channel ==0){
		bt_prompt_trace(MOD_BT,"[HID]channel ==0");
		return;
		}
        if (CMGR_CreateDataLink(&channel->cmgrHandler, 
                                &Parms->aclLink->bdAddr) != BT_STATUS_SUCCESS) 
       {
            /* Could not create a link to the ACL */
            (void)L2CAP_ConnectRsp(Cid, L2CONN_REJECT_NO_RESOURCES, 0);
            break;
        }        /* Drop through */    
        //Assert(channel !=0);
	if(channel ==0){
		bt_prompt_trace(MOD_BT,"[HID]channel ==0");
		return;
		}
        if (Parms->owner.psm == &HID(hidCtrlPsm)) 
            channel->ctrlCid = Cid;
        else 
            channel->intrCid = Cid;

        /* Call the state machine */
        if (channel != 0) 
        {
            kal_trace(BT_TRACE_G2_PROFILES,HID_B_SMAx02XBx02X ,channel->state,Cid);
            HID(hidState)[channel->state](channel, Cid, Parms);
        }
        else
            kal_trace(BT_TRACE_G2_PROFILES,HIDCHANNEL_0);

#endif
        break;
    case L2EVENT_CONNECTED:
        /* Save the channel ID for the channel being requested */
        if (channel == 0)
        {
            L2CAP_DisconnectReq(Cid);
            break;
        }
        
        if (Parms->owner.psm == &HID(hidCtrlPsm)) 
            channel->ctrlCid = Cid;
        else 
            channel->intrCid = Cid;

        /* Call the state machine */
        if (channel != 0) 
        {
            kal_trace(BT_TRACE_G2_PROFILES,HID_C_SMAx02XBx02X ,channel->state,Cid);
            HID(hidState)[channel->state](channel, Cid, Parms);
        }
        else
            kal_trace(BT_TRACE_G2_PROFILES,HIDCHANNEL_0);
        break;
    case L2EVENT_DISCONNECTED:
        CMGR_HidNoRoleSwitch(0);           
        if (channel != 0) 
        {
            kal_trace(BT_TRACE_G2_PROFILES,HID_D_SMAx02XBx02X ,channel->state,Cid);
            HID(hidState)[channel->state](channel, Cid, Parms);
        }
        else
        {
            kal_trace(BT_TRACE_G2_PROFILES,UNUSED_CHANNEL_0_IGNORE_IT);
        }
        break;
    default:
        /* Call the state machine */
        if (channel != 0) 
        {
            kal_trace(BT_TRACE_G2_PROFILES,HID_E_SMAx02XBx02X ,channel->state,Cid);
            HID(hidState)[channel->state](channel, Cid, Parms);
        }
        else
            kal_trace(BT_TRACE_G2_PROFILES,HIDCHANNEL_0);
        break;
    }
}
Ejemplo n.º 5
0
void bt_l2captester_handler(char *string){
    U32 ij = 0, j = 0, cid = 0;
    BtPacket *req = NULL;
    BtStatus status = BT_STATUS_FAILED;
    BOOL l_handled = FALSE;

    if( NULL == string ){
        return;
    }
    
    // "l2 config 42"
    if(strncmp(string, "l2", 2)==0){
        string +=2;
        while( *string == ' '  || string == NULL ){
            string++;
        }
        if(strncmp(string, "config", 6)==0){
            l_handled = TRUE;
            string += 6;

            cid = atoi(string);
            OS_Report("l2cap: config_req cid:%d", cid);

            req = L2Cap_GetSysPkt(FALSE);
            if( req != NULL ){
              status = L2CAP_SendConfigReq(cid, req, 0);
              OS_Report("l2cap: status:%d", status);
              if(status != BT_STATUS_PENDING){
                 L2Cap_ReturnSysPkt(req);
              }
            }else{
              OS_Report("l2cap: fail status:%d", status);
            }
        }
        else if(strncmp(string, "dump", 4)==0){
            l_handled = TRUE;
            string += 4;
            L2CAP_DumpChannel();
        }else if(strncmp(string, "sniff", 5)==0){
            // sniff the link
            
        }else if(strncmp(string, "unsni", 5)==0){
            // unsniff the link
            
        }else if(strncmp(string, "master", 5)==0){
            // change to local as master role
            l_handled = TRUE;
            string += 5;
            
        }else if(strncmp(string, "slave", 5)==0){
            // change to local as slave role
            l_handled = TRUE;
            string += 5;
            
        }else if(strncmp(string, "disc", 4)==0){
            l_handled = TRUE;
            string += 4;
            
            cid = atoi(string);
            OS_Report("l2cap: disc cid:%d", cid); 
            status = L2CAP_DisconnectReq(cid);
            OS_Report("l2cap: status:%d", status);
        }
            
    }else{
        OS_Report("l2cap: ignore !!! str:%s", string);
    }
    if( TRUE != l_handled  ){
        bt_l2captester_handler_help();
    }
}