Exemple #1
0
/**
	Default handler for standard ('chapter 9') requests
	
	@param [in]		pSetup		The setup packet
	@param [in,out]	*piLen		Pointer to data length
	@param [in]		ppbData		Data buffer.

	@return TRUE if the request was handled successfully
 */
int USBHandleStandardRequest_FPV_usb_reqhdlr(TSetupPacket	*pSetup, int *piLen, unsigned char **ppbData)
{
	switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) {
	case REQTYPE_RECIP_DEVICE:		return HandleStdDeviceReq(pSetup, piLen, ppbData);
	case REQTYPE_RECIP_INTERFACE:	return HandleStdInterfaceReq(pSetup, piLen, ppbData);
	case REQTYPE_RECIP_ENDPOINT: 	return HandleStdEndPointReq(pSetup, piLen, ppbData);
	default: 						return FALSE;
	}
}
Exemple #2
0
/**
 * Default handler for standard ('chapter 9') requests
 *
 * If a custom request handler was installed, this handler is called first.
 *
 * @param [in]		pSetup		The setup packet
 * @param [in,out]	*piLen		Pointer to data length
 * @param [in]		ppbData		Data buffer.
 *
 * @return TRUE if the request was handled successfully
 */
uint8_t USBCTRL::HandleStandardRequest(TSetupPacket	*pSetup, int *piLen, uint8_t **ppbData) {
	// try the custom request handler first
	if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) {
		return TRUE;
	}

	switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) {
		case REQTYPE_RECIP_DEVICE:		return HandleStdDeviceReq(pSetup, piLen, ppbData);
		case REQTYPE_RECIP_INTERFACE:	return HandleStdInterfaceReq(pSetup, piLen, ppbData);
		case REQTYPE_RECIP_ENDPOINT: 	return HandleStdEndPointReq(pSetup, piLen, ppbData);
		default: 						return FALSE;
	}
}
Exemple #3
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);
				}
			}
		}
	}
}