/* process an incomming control message from the host */ LOCAL void HTCControlSvcProcessMsg(HTC_ENDPOINT_ID EndpointID, adf_nbuf_t hdr_buf, adf_nbuf_t pBuffers, void *arg) { A_BOOL setupComplete = FALSE; a_uint8_t *anbdata; a_uint32_t anblen; HTC_CONTEXT *pHTC = (HTC_CONTEXT *)arg; HTC_UNKNOWN_MSG *pMsg; adf_os_assert(hdr_buf == ADF_NBUF_NULL); /* we assume buffers are aligned such that we can access the message * parameters directly*/ adf_nbuf_peek_header(pBuffers, &anbdata, &anblen); pMsg = (HTC_UNKNOWN_MSG *)anbdata; /* we cannot handle fragmented messages across buffers */ switch ( adf_os_ntohs(pMsg->MessageID) ) { case HTC_MSG_CONNECT_SERVICE_ID: HTCProcessConnectMsg(pHTC, (HTC_CONNECT_SERVICE_MSG *)pMsg); break; case HTC_MSG_CONFIG_PIPE_ID: HTCProcessConfigPipeMsg(pHTC, (HTC_CONFIG_PIPE_MSG *)pMsg); break; case HTC_MSG_SETUP_COMPLETE_ID: /* the host has indicated that it has completed all setup tasks and we can now let the services take over to run the rest of the application */ setupComplete = TRUE; /* can't get this more than once */ break; default: ; } if (pHTC->StateFlags & HTC_STATE_SETUP_COMPLETE) { /* recycle buffer only if we are fully running */ HTC_ReturnBuffers(pHTC, ENDPOINT0,pBuffers); } else { /* supply some head-room again */ adf_nbuf_push_head(pBuffers, HTC_HDR_LENGTH); /* otherwise return the packet back to mbox */ HIF_return_recv_buf(pHTC->hifHandle, pHTC->Endpoints[EndpointID].UpLinkPipeID, pBuffers); } if (setupComplete) { /* mark that setup has completed */ pHTC->StateFlags |= HTC_STATE_SETUP_COMPLETE; if (pHTC->SetupCompleteCb != NULL) { pHTC->SetupCompleteCb(); } } }
static void WMIRecvMessageHandler(HTC_ENDPOINT_ID EndPt, adf_nbuf_t hdr_buf, adf_nbuf_t pHTCBuf, void *arg) { void *pContext; WMI_SVC_CONTEXT *pWMI = (WMI_SVC_CONTEXT *)arg; WMI_DISPATCH_TABLE *pCurrentTable; WMI_DISPATCH_ENTRY*pCurrentEntry; WMI_CMD_HANDLER pCmdHandler; A_UINT8* pCmdBuffer; int i; A_UINT16 cmd; A_UINT16 seq; int length; a_uint8_t *anbdata; a_uint32_t anblen; WMI_CMD_HDR *cmdHdr; adf_os_assert(hdr_buf == ADF_NBUF_NULL); do { length = adf_nbuf_len(pHTCBuf); if (length < sizeof(WMI_CMD_HDR)) { break; } adf_nbuf_peek_header(pHTCBuf, &anbdata, &anblen); pCurrentTable = pWMI->pDispatchHead; length = length - sizeof(WMI_CMD_HDR); cmdHdr = (WMI_CMD_HDR *)anbdata; cmd = adf_os_ntohs(cmdHdr->commandId); seq = adf_os_ntohs(cmdHdr->seqNo); pCmdBuffer = anbdata + sizeof(WMI_CMD_HDR); pCmdHandler = NULL; while (pCurrentTable != NULL) { pContext = pCurrentTable->pContext; pCurrentEntry = pCurrentTable->pTable; /* scan table entries */ for (i = 0; i < pCurrentTable->NumberOfEntries; i++, pCurrentEntry++) { if (pCurrentEntry->CmdID == cmd) { /* found a match */ pCmdHandler = pCurrentEntry->pCmdHandler; /* optionally check length */ if ((pCurrentEntry->CheckLength != 0) && (length < pCurrentEntry->CheckLength)) { /* do not process command */ pCmdHandler = NULL; } /* end search */ break; } } if (pCmdHandler != NULL) { /* found a handler */ break; } /* scan next table */ pCurrentTable = pCurrentTable->pNext; } if (NULL == pCmdHandler) { break; } /* if we get here, we have a command handler to dispatch */ /* call dispatch function */ pCmdHandler(pContext, cmd, seq, pCmdBuffer, length); } while (FALSE); /* Invalidate the buffer (including HTC header). Note : we only need to invalidate up to the portion * that was used (cache invalidate will also round up to the nearest cache line). * The rest of the buffer should still be coherent. * */ HTC_ReturnBuffers(pWMI->HtcHandle, EndPt, pHTCBuf); }