Esempio n. 1
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);
            }
        }
    }

}
Esempio n. 2
0
/*---------------------------------------------------------------------------
 *            HidCmgrCallback()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Called by connection manager with link state events.
 *
 * Return:    (See header file)
 *
 */
void HidCmgrCallback(CmgrHandler *Handler, CmgrEvent Event, BtStatus Status) 
{
    BtStatus ret;
    HidChannel *channel = ContainingRecord(Handler, HidChannel, cmgrHandler);
    kal_trace(BT_TRACE_G2_PROFILES,HIDCMGRCALLBACKx02X ,Event);
    switch (Event) {
    case CMEVENT_DATA_LINK_CON_CNF:
        if (channel == NULL)
        {
            kal_trace(BT_TRACE_G2_PROFILES,HID_NOT_THE_CONNECT_BD_ADDR);
            return;
        }

        if(channel->cmgrHandler.bdc == 0)
        {
            kal_trace(BT_TRACE_G2_PROFILES,HIDCHANNELCMGRHANDLERBDC0);
            return;
        }
		
        kal_trace(BT_TRACE_G2_PROFILES,HID_STATUSx02X ,Status);
        if (Status != BT_STATUS_SUCCESS) 
        {
            /* Indicate the query response failure to the application */
            HidClearConnection(channel, Status, 0);
            return;
        }
        else
        {
#ifdef __BT_4_0_BLE__
            kal_trace(BT_TRACE_BLE_PROFILES, HID_CMGRCALLBACK_DEVTYPE, channel->cmgrHandler.bdc->devType);
            if (channel->cmgrHandler.bdc->devType == BT_DEV_TYPE_LE)
            {
                ret = GattClientConnect(channel->cmgrHandler.remDev);
                Report(("[HID] GattClientConnect ret: %d", ret));
                /* Since HID Gatt callback will be called even if connection is existed, there is unnecessary
                to handle return success case here. */
/*
                if (ret == BT_STATUS_SUCCESS)
                {
                    ret = HidStartGattServiceQuery(channel);
                    if (ret != BT_STATUS_PENDING)
                    {
                        channel->flags &= ~CHNL_FLAG_SERVICE_QUERY;
                        HidAppCallback(channel, HIDEVENT_QUERY_CNF, ret,
                                       &channel->queryRsp, (U16)(sizeof(HidQueryRsp)));
                    }
                }
*/                
            }
            else
#endif
            {
                if (channel->flags & CHNL_FLAG_SERVICE_QUERY)
                {
                    HidStartServiceQuery(channel);
                }
                else
                {
                    kal_trace(BT_TRACE_G2_PROFILES,HID_START_L2CAP_CONNECTION);
                    /* Start the L2CAP connection */
                    if (L2CAP_ConnectReq(&HID(hidCtrlPsm), BT_PSM_HID_CTRL, 
                                          channel->cmgrHandler.remDev, 0, 
                                          &(channel->ctrlCid)) == BT_STATUS_PENDING) {
                        channel->state = HID_STATE_CONN_PENDING;
                        channel->flags |= CHNL_FLAG_INITIATOR;
                        break;
                    }
                }
            }
        }
        break;
	case CMEVENT_DATA_LINK_DIS:
	{
		HidClearConnection(channel, Status, 0);
		return;
	}
    default:
        break;
    }
}
Esempio n. 3
0
void HidSdpEventHandler(SdpQueryToken *sqt, U8 result, U8 attr_idx, U8 *attr_val)
{
    HidChannel     *channel = ContainingRecord(sqt, 
                                               HidChannel, sdpQueryToken);
    ReportDescriptorList* reportDescriptorList = NULL;
    HidParseData*	hpd ;
    kal_trace(BT_TRACE_G2_PROFILES,BT_HID_SDP_QUERY_CALLBACK_x02X ,result);

    switch (result) 
    {
        case BT_STATUS_SDP_CONT_STATE:
            kal_trace(BT_TRACE_G2_PROFILES,HID_SDP_SUCCESSFULLY);
            HidVerifySdpQueryRsp(channel, bt_hid_attr_id_list[attr_idx], attr_val, sqt->availValueLen, result);  
            break;

        case BT_STATUS_SUCCESS:
            HidVerifySdpQueryRsp(channel, bt_hid_attr_id_list[attr_idx], attr_val, sqt->availValueLen, result);
            if (channel->bSDPDiscPending)
            {
                HidClearConnection(channel, result, 0);
            }
            else 
            {
				hpd = (HidParseData*)hid_malloc(sizeof(HidParseData));
				Hid_Init_Parser(hpd);
                		channel->reportCons[0] = (HidReportConstructor*)hid_malloc(HID_REPORT_ID_MAX * sizeof(HidReportConstructor));
				btmtk_os_memset((U8*) channel->reportCons[0], 0, HID_REPORT_ID_MAX * sizeof(HidReportConstructor));

				reportDescriptorList = HidFindReportDescriptorByAddr(channel->cmgrHandler.remDev->bdAddr);
				
				if(reportDescriptorList != NULL )
				{		
					btmtk_os_memset(reportDescriptorList->BtAddr.addr, 0, 6);
					reportDescriptorList->inUse = FALSE;
					hid_free(reportDescriptorList->reportDescriptor);
					reportDescriptorList->reportDescriptorLength = 0;
				}
				
				HidCacheReportDescriptor(channel->cmgrHandler.remDev->bdAddr, channel->queryRsp.descriptorList, channel->queryRsp.descriptorLen);
				
        		if(HidAddDescriptor(channel) == BT_STATUS_SUCCESS)
        			bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor Successed!");
        		else
        			bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor failed!");   
                
				Hid_Free_Parser(hpd);
                channel->flags &= ~CHNL_FLAG_SERVICE_QUERY;
                HidSdpCallback(channel, result);
            }
            break;
		case BT_STATUS_NOSERVICES:
			{
				static const U8 HidDescriptorList[] = 
				{
				    HID_DESCRIPTOR
				};
				channel->queryRsp.descriptorLen = HID_DESCRIPTOR_LEN;
				channel->queryRsp.descriptorList = (U8*)hid_malloc(HID_DESCRIPTOR_LEN);
				btmtk_os_memset((U8*) channel->queryRsp.descriptorList, 0, HID_DESCRIPTOR_LEN);				
				btmtk_os_memcpy((U8*) channel->queryRsp.descriptorList, HidDescriptorList, HID_DESCRIPTOR_LEN);
				hpd = (HidParseData*)hid_malloc(sizeof(HidParseData));
				Hid_Init_Parser(hpd);
                		channel->reportCons[0] = (HidReportConstructor*)hid_malloc(HID_REPORT_ID_MAX * sizeof(HidReportConstructor));
				btmtk_os_memset((U8*) channel->reportCons[0], 0, HID_REPORT_ID_MAX * sizeof(HidReportConstructor));

                if(HidAddDescriptor(channel) == BT_STATUS_SUCCESS)
                    bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor Successed!");
                else
                    bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor failed!");
                
				Hid_Free_Parser(hpd);
                channel->flags &= ~CHNL_FLAG_SERVICE_QUERY;
                HidSdpCallback(channel, BT_STATUS_SUCCESS);
				break;
			}
        case BT_STATUS_CONNECTION_FAILED:
        case BT_STATUS_FAILED:
        default:
            channel->flags &= ~CHNL_FLAG_SERVICE_QUERY;
            HidClearConnection(channel, result, 0);
            break;
    }

}