/*
	LPCUSB, an USB device driver for LPC microcontrollers	
	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

	1. Redistributions of source code must retain the above copyright
	   notice, this list of conditions and the following disclaimer.
	2. Redistributions in binary form must reproduce the above copyright
	   notice, this list of conditions and the following disclaimer in the
	   documentation and/or other materials provided with the distribution.
	3. The name of the author may not be used to endorse or promote products
	   derived from this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


/** @file
	Standard request handler.
	
	This modules handles the 'chapter 9' processing, specifically the
	standard device requests in table 9-3 from the universal serial bus
	specification revision 2.0
	
	Specific types of devices may specify additional requests (for example
	HID devices add a GET_DESCRIPTOR request for interfaces), but they
	will not be part of this module.

	@todo some requests have to return a request error if device not configured:
	@todo GET_INTERFACE, GET_STATUS, SET_INTERFACE, SYNCH_FRAME
	@todo this applies to the following if endpoint != 0:
	@todo SET_FEATURE, GET_FEATURE 
*/

#include "usbdebug.h"
#include "usbstruct.h"
#include "usbapi.h"

#define MAX_DESC_HANDLERS	4		/**< device, interface, endpoint, other */


/* general descriptor field offsets */
#define DESC_bLength					0	/**< length offset */
#define DESC_bDescriptorType			1	/**< descriptor type offset */	

/* config descriptor field offsets */
#define CONF_DESC_wTotalLength			2	/**< total length offset */
#define CONF_DESC_bConfigurationValue	5	/**< configuration value offset */	
#define CONF_DESC_bmAttributes			7	/**< configuration characteristics */

/* interface descriptor field offsets */
#define INTF_DESC_bAlternateSetting		3	/**< alternate setting offset */

/* endpoint descriptor field offsets */
#define ENDP_DESC_bEndpointAddress		2	/**< endpoint address offset */
#define ENDP_DESC_wMaxPacketSize		4	/**< maximum packet size offset */


/** Currently selected configuration */
static unsigned char				bConfiguration = 0;
/** Installed custom request handler */
static TFnHandleRequest	*pfnHandleCustomReq = NULL;
/** Pointer to registered descriptors */
static const unsigned char			*pabDescrip = NULL;


/**
	Registers a pointer to a descriptor block containing all descriptors
	for the device.

	@param [in]	pabDescriptors	The descriptor byte array
 */
void USBRegisterDescriptors(const unsigned char *pabDescriptors)
{
	pabDescrip = pabDescriptors;
}


/**
	Parses the list of installed USB descriptors and attempts to find
	the specified USB descriptor.
		
	@param [in]		wTypeIndex	Type and index of the descriptor
	@param [in]		wLangID		Language ID of the descriptor (currently unused)
	@param [out]	*piLen		Descriptor length
	@param [out]	*ppbData	Descriptor data
	
	@return TRUE if the descriptor was found, FALSE otherwise
 */
BOOL USBGetDescriptor(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData)
{
	unsigned char	bType, bIndex;
	unsigned char	*pab;
	int iCurIndex;
	
	ASSERT(pabDescrip != NULL);

	bType = GET_DESC_TYPE(wTypeIndex);
	bIndex = GET_DESC_INDEX(wTypeIndex);
	
	pab = (unsigned char *)pabDescrip;
	iCurIndex = 0;
	
	while (pab[DESC_bLength] != 0) {
		if (pab[DESC_bDescriptorType] == bType) {
			if (iCurIndex == bIndex) {
				// set data pointer
				*ppbData = pab;
				// get length from structure
				if (bType == DESC_CONFIGURATION) {
					// configuration descriptor is an exception, length is at offset 2 and 3
					*piLen =	(pab[CONF_DESC_wTotalLength]) |
								(pab[CONF_DESC_wTotalLength + 1] << 8);
				}
				else {
					// normally length is at offset 0
					*piLen = pab[DESC_bLength];
				}
				return TRUE;
			}
			iCurIndex++;
		}
		// skip to next descriptor
		pab += pab[DESC_bLength];
	}
	// nothing found
	DBG("Desc %x not found!\n", wTypeIndex);
	return FALSE;
}


/**
	Configures the device according to the specified configuration index and
	alternate setting by parsing the installed USB descriptor list.
	A configuration index of 0 unconfigures the device.
		
	@param [in]		bConfigIndex	Configuration index
	@param [in]		bAltSetting		Alternate setting number
	
	@todo function always returns TRUE, add stricter checking?
	
	@return TRUE if successfully configured, FALSE otherwise
 */
static BOOL USBSetConfiguration(unsigned char bConfigIndex, unsigned char bAltSetting)
{
	unsigned char	*pab;
	unsigned char	bCurConfig, bCurAltSetting;
	unsigned char	bEP;
	unsigned short	wMaxPktSize;
	
	ASSERT(pabDescrip != NULL);

	if (bConfigIndex == 0) {
		// unconfigure device
		USBHwConfigDevice(FALSE);
	}
	else {
		// configure endpoints for this configuration/altsetting
		pab = (unsigned char *)pabDescrip;
		bCurConfig = 0xFF;
		bCurAltSetting = 0xFF;

		while (pab[DESC_bLength] != 0) {

			switch (pab[DESC_bDescriptorType]) {

			case DESC_CONFIGURATION:
				// remember current configuration index
				bCurConfig = pab[CONF_DESC_bConfigurationValue];
				break;

			case DESC_INTERFACE:
				// remember current alternate setting
				bCurAltSetting = pab[INTF_DESC_bAlternateSetting];
				break;

			case DESC_ENDPOINT:
				if ((bCurConfig == bConfigIndex) &&
					(bCurAltSetting == bAltSetting)) {
					// endpoint found for desired config and alternate setting
					bEP = pab[ENDP_DESC_bEndpointAddress];
					wMaxPktSize = 	(pab[ENDP_DESC_wMaxPacketSize]) |
									(pab[ENDP_DESC_wMaxPacketSize + 1] << 8);
					// configure endpoint
					USBHwEPConfig(bEP, wMaxPktSize);
				}
				break;

			default:
				break;
			}
			// skip to next descriptor
			pab += pab[DESC_bLength];
		}
		
		// configure device
		USBHwConfigDevice(TRUE);
	}

	return TRUE;
}


/**
	Local function to handle a standard device request
		
	@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 handled successfully
 */
static BOOL HandleStdDeviceReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
{
	unsigned char	*pbData = *ppbData;

	switch (pSetup->bRequest) {
	
	case REQ_GET_STATUS:
		// bit 0: self-powered
		// bit 1: remote wakeup = not supported
		pbData[0] = 0;
		pbData[1] = 0;
		*piLen = 2;
		break;
		
	case REQ_SET_ADDRESS:
		USBHwSetAddress(pSetup->wValue);
		break;

	case REQ_GET_DESCRIPTOR:
		DBG("D%x", pSetup->wValue);
		return USBGetDescriptor(pSetup->wValue, pSetup->wIndex, piLen, ppbData);

	case REQ_GET_CONFIGURATION:
		// indicate if we are configured
		pbData[0] = bConfiguration;
		*piLen = 1;
		break;

	case REQ_SET_CONFIGURATION:
		if (!USBSetConfiguration(pSetup->wValue & 0xFF, 0)) {
			DBG("USBSetConfiguration failed!\n");
			return FALSE;
		}
		// configuration successful, update current configuration
		bConfiguration = pSetup->wValue & 0xFF;	
		break;

	case REQ_CLEAR_FEATURE:
	case REQ_SET_FEATURE:
		if (pSetup->wValue == FEA_REMOTE_WAKEUP) {
			// put DEVICE_REMOTE_WAKEUP code here
		}
		if (pSetup->wValue == FEA_TEST_MODE) {
			// put TEST_MODE code here
		}
		return FALSE;

	case REQ_SET_DESCRIPTOR:
		DBG("Device req %d not implemented\n", pSetup->bRequest);
		return FALSE;

	default:
		DBG("Illegal device req %d\n", pSetup->bRequest);
		return FALSE;
	}
	
	return TRUE;
}


/**
	Local function to handle a standard interface request
		
	@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
 */
static BOOL HandleStdInterfaceReq(TSetupPacket	*pSetup, int *piLen, unsigned char **ppbData)
{
	unsigned char	*pbData = *ppbData;

	switch (pSetup->bRequest) {

	case REQ_GET_STATUS:
		// no bits specified
		pbData[0] = 0;
		pbData[1] = 0;
		*piLen = 2;
		break;

	case REQ_CLEAR_FEATURE:
	case REQ_SET_FEATURE:
		// not defined for interface
		return FALSE;
	
	case REQ_GET_INTERFACE:	// TODO use bNumInterfaces
        // there is only one interface, return n-1 (= 0)
		pbData[0] = 0;
		*piLen = 1;
		break;
	
	case REQ_SET_INTERFACE:	// TODO use bNumInterfaces
		// there is only one interface (= 0)
		if (pSetup->wValue != 0) {
			return FALSE;
		}
		*piLen = 0;
		break;

	default:
		DBG("Illegal interface req %d\n", pSetup->bRequest);
		return FALSE;
	}

	return TRUE;
}


/**
	Local function to handle a standard endpoint request
		
	@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
 */
static BOOL HandleStdEndPointReq(TSetupPacket	*pSetup, int *piLen, unsigned char **ppbData)
{
	unsigned char	*pbData = *ppbData;

	switch (pSetup->bRequest) {
	case REQ_GET_STATUS:
		// bit 0 = endpointed halted or not
		pbData[0] = (USBHwEPGetStatus(pSetup->wIndex) & EP_STATUS_STALLED) ? 1 : 0;
		pbData[1] = 0;
		*piLen = 2;
		break;
		
	case REQ_CLEAR_FEATURE:
		if (pSetup->wValue == FEA_ENDPOINT_HALT) {
			// clear HALT by unstalling
			USBHwEPStall(pSetup->wIndex, FALSE);
			break;
		}
		// only ENDPOINT_HALT defined for endpoints
		return FALSE;
	
	case REQ_SET_FEATURE:
		if (pSetup->wValue == FEA_ENDPOINT_HALT) {
			// set HALT by stalling
			USBHwEPStall(pSetup->wIndex, TRUE);
			break;
		}
		// only ENDPOINT_HALT defined for endpoints
		return FALSE;

	case REQ_SYNCH_FRAME:
		DBG("EP req %d not implemented\n", pSetup->bRequest);
		return FALSE;

	default:
		DBG("Illegal EP req %d\n", pSetup->bRequest);
		return FALSE;
	}
	
	return TRUE;
}


/**
	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
 */
BOOL USBHandleStandardRequest(TSetupPacket	*pSetup, int *piLen, unsigned char **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;
	}
}


/**
	Registers a callback for custom device requests
	
	In USBHandleStandardRequest, the custom request handler gets a first
	chance at handling the request before it is handed over to the 'chapter 9'
	request handler.
	
	This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR
	request is sent to an interface, which is not covered by the 'chapter 9'
	specification.
		
	@param [in]	pfnHandler	Callback function pointer
 */
void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler)
{
	pfnHandleCustomReq = pfnHandler;
}

