Exemplo n.º 1
0
/* 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();
		}
	}
}
Exemplo n.º 2
0
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);
}