/*--------------------------------------------------------------------------- * HidStateClosed() *--------------------------------------------------------------------------- * * Synopsis: Closed state for the HID channel. * * Return: void */ void HidStateClosed(HidChannel *Channel, L2capChannelId Cid, L2capCallbackParms *Parms) { kal_trace(BT_TRACE_G2_PROFILES,HIDSTATECLOSEDx02X ,Parms->event); if ((Parms->event == L2EVENT_CONNECT_IND) || (Parms->event == L2EVENT_CONNECT_AUTORIZED)) { //Channel->cmgrHandler.callback = HidCmgrCallback; 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); return; } Channel->state = HID_STATE_CONN_PENDING; HidAppCallback(Channel, HIDEVENT_OPEN_IND, BT_STATUS_SUCCESS, Channel->cmgrHandler.remDev, sizeof(BtRemoteDevice)); } else { /* Ignore any other events */ kal_trace(BT_TRACE_G2_PROFILES,HID_CHANNEL_CLOSED_STATE_RECEIVED_AN_UNEXPECTED_EVENT_x02X , Parms->event); } }
/*--------------------------------------------------------------------------- * HidSdpCallback() *--------------------------------------------------------------------------- * * Synopsis: Makes a callback to the application with query response. */ void HidSdpCallback(HidChannel *Channel, BtStatus Status) { /* Indicate the query response to the application */ HidAppCallback(Channel, HIDEVENT_QUERY_CNF, Status, &Channel->queryRsp, (U16)(sizeof(HidQueryRsp))); hid_free(Channel->queryRsp.descriptorList); btmtk_os_memset((U8 *)&Channel->queryRsp, 0, sizeof(Channel->queryRsp)); }
/*--------------------------------------------------------------------------- * 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); } }
/*--------------------------------------------------------------------------- * HidStateOpen() *--------------------------------------------------------------------------- * * Synopsis: Open state for the HID channel. * * Return: void */ void HidStateOpen(HidChannel *Channel, L2capChannelId Cid, L2capCallbackParms *Parms) { HidTransaction *trans = NULL; HidInterrupt *intr = NULL; U16 mtu; kal_trace(BT_TRACE_G2_PROFILES,HIDSTATEOPENx02X ,Parms->event); switch (Parms->event) { case L2EVENT_DISCON_IND: case L2EVENT_DISCONNECTED: Channel->state = HID_STATE_DISC_PENDING; if (!(Channel->flags & CHNL_FLAG_TERMINATOR)) { /* Call the application to indicate the connection is going down. L2capDiscReason provided in status*/ HidAppCallback(Channel, HIDEVENT_CLOSE_IND, Parms->status, Channel->cmgrHandler.remDev, sizeof(BtRemoteDevice)); } /* Connection is going down */ HidStateDiscPending(Channel, Cid, Parms); break; case L2EVENT_PACKET_HANDLED: kal_trace(BT_TRACE_G2_PROFILES,CIDxDCTRLCIDxD ,Cid,Channel->ctrlCid); if (Cid == Channel->ctrlCid) { trans = (HidTransaction *)Parms->ptrs.packet->ulpContext; kal_trace(BT_TRACE_G2_PROFILES,HIDSTATEOPEN1_PKT_RETURNED_WITH_TRANS_TYPExD ,trans->type); if (trans->flags & TRANS_FLAG_ERROR) { /* Ignore this event, transaction failed */ kal_trace(BT_TRACE_G2_PROFILES,HIDSTATEOPENPKT_RETURNED_WITH_ERR_FLAG); InsertTailList(&HID(packetPool), &Parms->ptrs.packet->node); break; } mtu = L2CAP_GetTxMtu(Channel->ctrlCid); } else { /* Interrupt channel */ intr = (HidInterrupt *)Parms->ptrs.packet->ulpContext; if (intr->flags & INTR_FLAG_ERROR) { /* Ignore this event, interrupt failed */ InsertTailList(&HID(packetPool), &Parms->ptrs.packet->node); break; } mtu = L2CAP_GetTxMtu(Channel->intrCid); } if (Parms->ptrs.packet->dataLen < mtu - 1) { /* A packet was handled, put it back in the pool */ /* Only return packet when no more data need to be sent */ InsertTailList(&HID(packetPool), &Parms->ptrs.packet->node); } /* See if there is more data to send */ if (Cid == Channel->ctrlCid) { /* Check for more data */ if (Parms->ptrs.packet->dataLen >= mtu -1) { /* More data to send, send another packet */ kal_trace(BT_TRACE_G2_PROFILES,HIDSTATEOPEN_SEND_MORE_DATA); //trans->flags &= ~TRANS_FLAG_START; if(!(trans->flags & TRANS_FLAG_SENT)) if (HidSendTransPacket(Channel, trans, Parms->ptrs.packet) != BT_STATUS_PENDING) { /* Complete the transaction with an error */ trans->flags |= TRANS_FLAG_ERROR; InsertTailList(&HID(packetPool), &Parms->ptrs.packet->node); /* Complete the transaction with an error, check for a new * transaction. */ HidCompleteTransaction(Channel, trans, BT_STATUS_FAILED); } } else { /* No more data to send in this transaction, complete this * transaction (if no response is expected) and see if there * is another transaction to start. */ trans->flags |= TRANS_FLAG_SENT; kal_trace(BT_TRACE_G2_PROFILES,HIDSTATEOPEN2_PKT_RETURNED_WITH_TRANS_TYPExD ,trans->type); switch (trans->type) { case HID_TRANS_CONTROL: case HID_TRANS_SET_REPORT_RSP: case HID_TRANS_SET_PROTOCOL_RSP: case HID_TRANS_SET_IDLE_RATE_RSP: case HID_TRANS_GET_REPORT_RSP: case HID_TRANS_GET_PROTOCOL_RSP: case HID_TRANS_GET_IDLE_RATE_RSP: //Add by stanley: 2007-0607 case HID_HANDSHAKE: kal_trace(BT_TRACE_G2_PROFILES,HIDCOMPLETETRANSACTION_WITH_TYPExD ,trans->type); HidCompleteTransaction(Channel, trans, BT_STATUS_SUCCESS); break; } } } else { /* Check for more data */ if (Parms->ptrs.packet->dataLen >= mtu -1) { /* More data to send, send another packet */ //intr->flags &= ~INTR_FLAG_START; if(!(intr->flags & INTR_FLAG_SENT)) if (HidSendIntrPacket(Channel, intr, Parms->ptrs.packet) != BT_STATUS_PENDING) { /* Complete the interrupt with an error */ intr->flags |= INTR_FLAG_ERROR; InsertTailList(&HID(packetPool), &Parms->ptrs.packet->node); /* Complete the interrupt with an error, check for a new * interrupt. */ HidCompleteInterrupt(Channel, intr, BT_STATUS_FAILED); } } else { /* No more data to send in this interrupt, complete this * interrupt. */ intr->flags |= INTR_FLAG_SENT; HidCompleteInterrupt(Channel, intr, BT_STATUS_SUCCESS); } } break; case L2EVENT_DATA_IND: if (Cid == Channel->ctrlCid) { //Assert(Channel !=0); if(Channel ==0){ bt_prompt_trace(MOD_BT,"[HID]channel ==0"); return; } /* A control channel request was received */ HidControlChannel(Channel, Cid, Parms); } else { //Assert(Channel !=0); if(Channel ==0){ bt_prompt_trace(MOD_BT,"[HID]channel ==0"); return; } /* Application data was received */ HidInterruptChannel(Channel, Cid, Parms); } break; default: /* Ignore any other events */ kal_trace(BT_TRACE_G2_PROFILES,HID_SERVER_OPEN_STATE_RECEIVED_AN_UNEXPECTED_EVENT_x02X , Parms->event); break; } }