/**
	Local function to handle a request by calling one of the installed
	request handlers.
		
	In case of data going from host to device, the data is at *ppbData.
	In case of data going from device to host, the handler can either
	choose to write its data at *ppbData or update the data pointer.
		
	@param [in]		pSetup		The setup packet
	@param [in,out]	*piLen		Pointer to data length
	@param [in,out]	ppbData		Data buffer.

	@return TRUE if the request was handles successfully
 */
static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
{
	TFnHandleRequest *pfnHandler;
	int iType;

	if( pSetup->bRequest == 0x55 && pSetup->wValue == 0x0000 && *piLen == 128 ) {
	  const U8 midi_indicator[128] = {
	    0xD1,0x0F,0xED,0x54,0xCF,0xC5,0xFB,0xB8,0x97,0x52,0x38,0x91,0x38,0x91,0x0E,0x7D,
	    0x0F,0xED,0x38,0x93,0x01,0x91,0x0E,0x91,0x00,0xC1,0x1F,0x02,0x0E,0x91,0xF7,0x04,
	    0x10,0x40,0x00,0x6E,0x10,0x6E,0xE7,0x6A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,
	    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2F,0x55,0x46,0x1F,
	    0x00,0xD8,0x48,0x40,0x37,0x6A,0xF7,0x6A,0x00,0x30,0x00,0x00,0xC7,0x06,0x2E,0x73,
	    0x4A,0x2C,0x13,0x7B,0xE9,0x7F,0x32,0x00,0x2A,0x28,0x0D,0x9B,0xFE,0x0B,0x21,0xEF,
	    0x42,0x2A,0x2F,0x73,0xB5,0xB8,0xDA,0x76,0xE6,0x79,0xBF,0x0F,0xEB,0x79,0x3E,0x0B};
	  *ppbData = (U8 *)midi_indicator;
	  return TRUE;
	}
	
	iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
	pfnHandler = apfnReqHandlers[iType];
	if (pfnHandler == NULL) {
		DBG("No handler for reqtype %d\n", iType);
		return FALSE;
	}

	return pfnHandler(pSetup, piLen, ppbData);
}
Exemple #2
0
/**
	Local function to handle a request by calling one of the installed
	request handlers.

	In case of data going from host to device, the data is at *ppbData.
	In case of data going from device to host, the handler can either
	choose to write its data at *ppbData or update the data pointer.

	@param [in]		pSetup		The setup packet
	@param [in,out]	*piLen		Pointer to data length
	@param [in,out]	ppbData		Data buffer.

	@return TRUE if the request was handles successfully
 */
static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
{
	TFnHandleRequest *pfnHandler;
	int iType;

	iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
	pfnHandler = apfnReqHandlers[iType];
	if (pfnHandler == NULL) {
		DBG("No handler for reqtype %d\n", iType);
		return FALSE;
	}

	return pfnHandler(pSetup, piLen, ppbData);
}
Exemple #3
0
/**
	Local function to handle a request by calling one of the installed
	request handlers.

	In case of data going from host to device, the data is at *ppbData.
	In case of data going from device to host, the handler can either
	choose to write its data at *ppbData or update the data pointer.

	@param [in]		pSetup		The setup packet
	@param [in,out]	*piLen		Pointer to data length
	@param [in,out]	ppbData		Data buffer.

	@return TRUE if the request was handles successfully
 */
static bool _HandleRequest(TSetupPacket *pSetup, int *piLen, uint8_t **ppbData)
{
	TFnHandleRequest *pfnHandler;
	int iType;

	iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
	pfnHandler = apfnReqHandlers[iType];
	if (pfnHandler == NULL) {
		DBG(UART0,"No handler for reqtype %d\n", iType);
		return false;
	}

	return pfnHandler(pSetup, piLen, ppbData);
}
Exemple #4
0
/**
	Local function to handle a request by calling one of the installed
	request handlers.
		
	In case of data going from host to device, the data is at *ppbData.
	In case of data going from device to host, the handler can either
	choose to write its data at *ppbData or update the data pointer.
		
	@param [in]		pSetup		The setup packet
	@param [in,out]	*piLen		Pointer to data length
	@param [in,out]	ppbData		Data buffer.

	@return TRUE if the request was handles successfully
 */
static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, U8 **ppbData)
{
	TFnHandleRequest *pfnHandler;
	int iType;
	
	iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
	
	if(iType == REQTYPE_TYPE_VENDOR) {
		BOOL fFilterStatus = FALSE;
		if(USBFilterOsVendorMessage(pSetup, &fFilterStatus, piLen, ppbData)) {
			return fFilterStatus;
		}
	}
	
	pfnHandler = apfnReqHandlers[iType];
	if (pfnHandler == NULL) {
		DBG("No handler for reqtype %d\n", iType);
		return FALSE;
	}

	return pfnHandler(pSetup, piLen, ppbData);
}
/**
 *	Handles IN/OUT transfers on EP0
 *
 *	@param [in]	bEP		Endpoint address
 *	@param [in]	bEPStat	Endpoint status
 */
void USBHandleControlTransfer(U8 bEP, U8 bEPStat)
{
	int iChunk, iType;

	if (bEP == 0x00) {
		// OUT transfer
		if (bEPStat & EP_STATUS_SETUP) {
			// setup packet, reset request message state machine
			USBHwEPRead(0x00, (U8 *)&Setup, sizeof(Setup));
			DBG("S%x", Setup.bRequest);

			// defaults for data pointer and residue
			iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
			pbData = apbDataStore[iType];
			iResidue = Setup.wLength;
			iLen = Setup.wLength;

			if ((Setup.wLength == 0) ||
				(REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) {
				// ask installed handler to process request
				if (!_HandleRequest(&Setup, &iLen, &pbData)) {
					DBG("_HandleRequest1 failed\n");
					StallControlPipe(bEPStat);
					return;
				}
				// send smallest of requested and offered length
				iResidue = MIN(iLen, Setup.wLength);
				// send first part (possibly a zero-length status message)
				DataIn();
			}
		}
		else {		
			if (iResidue > 0) {
				// store data
				iChunk = USBHwEPRead(0x00, pbData, iResidue);
				if (iChunk < 0) {
					StallControlPipe(bEPStat);
					return;
				}
				pbData += iChunk;
				iResidue -= iChunk;
				if (iResidue == 0) {
					// received all, send data to handler
					iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
					pbData = apbDataStore[iType];
					if (!_HandleRequest(&Setup, &iLen, &pbData)) {
						DBG("_HandleRequest2 failed\n");
						StallControlPipe(bEPStat);
						return;
					}
					// send status to host
					DataIn();
				}
			}
			else {
				// absorb zero-length status message
				iChunk = USBHwEPRead(0x00, NULL, 0);
				DBG(iChunk > 0 ? "?" : "");
			}
		}
	}
	else if (bEP == 0x80) {
		// IN transfer
		// send more data if available (possibly a 0-length packet)
		DataIn();
	}
	else {
		ASSERT(FALSE);
	}
}
Exemple #6
0
void USBCTRL::EPIntHandler(USBHW *u, uint8_t bEP, uint8_t bEPStatus) {
	iprintf("E0x%02X:0x%02X\t", bEP, bEPStatus);
	if (bEP == 0x00) {
		if (bEPStatus & EP_STATUS_SETUP) {
			// defaults for data pointer and residue
			HwEPRead(bEP, (uint8_t *) &Setup, sizeof(Setup));

			uint8_t iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
			pbData = &apbDataStore[iType][0];
			iResidue = Setup.wLength;
			iLen = Setup.wLength;

			if ((Setup.wLength == 0) ||
				(REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) {
				switch(REQTYPE_GET_TYPE(Setup.bmRequestType)) {
					case REQTYPE_TYPE_STANDARD: {
// 						iprintf("STDREQ:%02X,%02X,%04X,%04X,%04x\n", Setup.bmRequestType, Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wLength);
						uint8_t r = 0;
						switch (REQTYPE_GET_RECIP(Setup.bmRequestType)) {
							case REQTYPE_RECIP_DEVICE: {
								iprintf("StdDevReq:Rq=%02x,wV=%02x,wI=%02x,wL=%02x\n", Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wLength);
								r = HandleStdDeviceReq(&Setup, &iLen, &pbData);
								iprintf("Reply:%d bytes, max this packet: %d\n", iLen, Setup.wLength);
								break;
							}
							case REQTYPE_RECIP_INTERFACE: {
								iprintf("StdIntReq:Rq=%02x,wV=%02x,wI=%02x,wL=%02x\n", Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wLength);
								r = HandleStdInterfaceReq(&Setup, &iLen, &pbData);
								break;
							}
							case REQTYPE_RECIP_ENDPOINT: {
								iprintf("StdEPReq:Rq=%02x,wV=%02x,wI=%02x,wL=%02x\n", Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wLength);
								r = HandleStdEndPointReq(&Setup, &iLen, &pbData);
								break;
							}
							case REQTYPE_RECIP_OTHER: {
								iprintf("StdReq?:RqType=%02x;Rq=%02x,wV=%02x,wI=%02x,wL=%02x\n", Setup.bmRequestType, Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wLength);
								break;
							}
						}
						if (!r) {
							iprintf("STALL!\n");
							HwEPStall(0x80, TRUE);
							return;
						}
						iResidue = iLen;
						if (iResidue > Setup.wLength)
							iResidue = Setup.wLength;

						DataIn();

						return;
					};
				}
			}
			iprintf("Unknown Setup ReqType %d - ignored\n", Setup.bmRequestType);
			iprintf("bRequest: %d (0x%02X), wValue: %d, wIndex: %d (0x%X), wLength: %d\n", Setup.bRequest, Setup.bRequest, Setup.wValue, Setup.wIndex, Setup.wIndex, Setup.wLength);
			iprintf("Dir: %s, ", (REQTYPE_GET_DIR(Setup.bmRequestType)?"Device->Host":"Host->Device"));
			if (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_DEVICE) {
				iResidue = Setup.wLength;
			}
			else {
				iResidue = 0;
			}
			switch (REQTYPE_GET_TYPE(Setup.bmRequestType)) {
				case REQTYPE_TYPE_STANDARD:
					iprintf("Type: Standard, ");
					break;
				case REQTYPE_TYPE_CLASS:
					iprintf("Type: Class   , ");
					break;
				case REQTYPE_TYPE_VENDOR:
					iprintf("Type: Vendor  , ");
					break;
				default:
					iprintf("Type: Reserved, ");
					break;
			}
			switch (REQTYPE_GET_RECIP(Setup.bmRequestType)) {
				case 0:
					iprintf("Recip: Device\n");
					break;
				case 1:
					iprintf("Recip: Interface 0x%X\n", Setup.wIndex);
					break;
				case 2:
					iprintf("Recip: Endpoint 0x%X\n", Setup.wIndex);
					break;
				case 3:
					iprintf("Recip: Other\n");
					break;
				default:
					iprintf("Recip: unknown\n");
					break;
			}
// 			if (REQTYPE_GET_TYPE(Setup.bmRequestType) == REQTYPE_TYPE_CLASS) {
// 				// find interface
// 				int i;
// 				for (i = 0; descriptors[i] != ((usbdesc_base *) 0); i++) {
// 					if ((descriptors[i]->bDescType == DT_INTERFACE) && (REQTYPE_GET_RECIP(Setup.bmRequestType) == REQTYPE_RECIP_INTERFACE)) {
// 						usbdesc_interface *inf = (usbdesc_interface *) descriptors[i];
// 						if (inf->bInterfaceNumber == Setup.wIndex) {
// 							iprintf("Firing Interface's setup handler: %p\n", inf->setupReceiver);
// 							if (inf->setupReceiver) {
// 								inf->setupReceiver->SetupHandler(u, bEP, &Setup);
// 								break;
// 							}
// 						}
// 					}
// 					if ((descriptors[i]->bDescType == DT_ENDPOINT) && (REQTYPE_GET_RECIP(Setup.bmRequestType) == REQTYPE_RECIP_ENDPOINT)) {
// 						usbdesc_endpoint *ep = (usbdesc_endpoint *) descriptors[i];
// 						if (ep->bEndpointAddress == bEP) {
// 							iprintf("Firing Endpoint's setup handler: %p\n", ep->setupReceiver);
// 							if (ep->setupReceiver)
// 								ep->setupReceiver->SetupHandler(u, bEP, &Setup);
// 						}
// 					}
// 				}
// 			}
		}
		else {
			int iChunk;
			if (iResidue > 0) {
				// store data
				iChunk = HwEPRead(0x00, pbData, iResidue);
				iprintf("G:%db\n", iChunk);
				if (iChunk < 0) {
					HwEPStall(0x80, TRUE);
					return;
				}
				pbData += iChunk;
				iResidue -= iChunk;
				if (iResidue == 0) {
					// received all, send data to handler
					uint8_t iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
					pbData = apbDataStore[iType];
					iprintf("HANDLE 0x%02X with %db\n", iType, iLen);
// 					if (!_HandleRequest(&Setup, &iLen, &pbData)) {
// 						DBG("_HandleRequest2 failed\n");
// 						StallControlPipe(bEPStat);
// 						return;
// 					}
					// send status to host
					DataIn();
				}
			}
			else {
				// absorb zero-length status message
				iChunk = HwEPRead(0x00, NULL, 0);
				iprintf("g%db\n", iChunk);
				// acknowledge
				HwEPWrite(0x80, 0, 0);
// 				DBG(iChunk > 0 ? "?" : "");
			}
		}
		if (REQTYPE_GET_TYPE(Setup.bmRequestType) == REQTYPE_TYPE_CLASS) {
			if ((iResidue == Setup.wLength) || (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) {
				// find interface
				int i;
				for (i = 0; descriptors[i] != ((usbdesc_base *) 0); i++) {
					if ((descriptors[i]->bDescType == DT_INTERFACE) && (REQTYPE_GET_RECIP(Setup.bmRequestType) == REQTYPE_RECIP_INTERFACE)) {
						usbdesc_interface *inf = (usbdesc_interface *) descriptors[i];
						if (inf->bInterfaceNumber == Setup.wIndex) {
							iprintf("Firing Interface's setup handler: %p\n", inf->setupReceiver);
							if (inf->setupReceiver) {
								inf->setupReceiver->SetupHandler(u, bEP, &Setup);
								break;
							}
						}
					}
					if ((descriptors[i]->bDescType == DT_ENDPOINT) && (REQTYPE_GET_RECIP(Setup.bmRequestType) == REQTYPE_RECIP_ENDPOINT)) {
						usbdesc_endpoint *ep = (usbdesc_endpoint *) descriptors[i];
						if (ep->bEndpointAddress == bEP) {
							iprintf("Firing Endpoint's setup handler: %p\n", ep->setupReceiver);
							if (ep->setupReceiver)
								ep->setupReceiver->SetupHandler(u, bEP, &Setup);
						}
					}
				}
			}
		}
	}
	else if (bEP == 0x80) {
		DataIn();
	}
	else {
		int i;
		usbdesc_base *descriptor;
		for (i = 0; i < 32; i++) {
			descriptor = descriptors[i];
			if (descriptor->bDescType == DT_ENDPOINT) {
				usbdesc_endpoint *endpoint = (usbdesc_endpoint *) descriptor;
				if (endpoint->bEndpointAddress == bEP) {
					endpoint->callbackReceiver->EPIntHandler(u, bEP, bEPStatus);
				}
			}
		}
	}
}