/*
	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
	Control transfer handler.

	This module handles control transfers and is normally installed on the
	endpoint 0 callback.

	Control transfers can be of the following type:
	0 Standard;
	1 Class;
	2 Vendor;
	3 Reserved.

	A callback can be installed for each of these control transfers using
	USBRegisterRequestHandler.
	When an OUT request arrives, data is collected in the data store provided
	with the USBRegisterRequestHandler call. When the transfer is done, the
	callback is called.
	When an IN request arrives, the callback is called immediately to either
	put the control transfer data in the data store, or to get a pointer to
	control transfer data. The data is then packetised and sent to the host.
*/

#include "usbdebug.h"

#include "usbstruct.h"
#include "usbapi.h"



#define	MAX_CONTROL_SIZE	128	/**< maximum total size of control transfer data */
#define	MAX_REQ_HANDLERS	4	/**< standard, class, vendor, reserved */

static TSetupPacket		Setup;	/**< setup packet */

static unsigned char				*pbData;	/**< pointer to data buffer */
static int				iResidue;	/**< remaining bytes in buffer */
static int				iLen;		/**< total length of control transfer */

/** Array of installed request handler callbacks */
static TFnHandleRequest *apfnReqHandlers[4] = {NULL, NULL, NULL, NULL};
/** Array of installed request data pointers */
static unsigned char				*apbDataStore[4] = {NULL, NULL, NULL, NULL};

/**
	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, unsigned char **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);
}


/**
	Local function to stall the control endpoint

	@param [in]	bEPStat	Endpoint status
 */
static void StallControlPipe(unsigned char bEPStat)
{
	unsigned char	*pb;
	int	i;

	( void ) bEPStat;
	USBHwEPStall(0x80, TRUE);

// dump setup packet
	DBG("STALL on [");
	pb = (unsigned char *)&Setup;
	for (i = 0; i < 8; i++) {
		DBG(" %02x", *pb++);
	}
	DBG("] stat=%x\n", bEPStat);
}


/**
	Sends next chunk of data (possibly 0 bytes) to host
 */
static void DataIn(void)
{
	int iChunk;

	if( MAX_PACKET_SIZE0 < iResidue )
	{
		iChunk = MAX_PACKET_SIZE0;
	}
	else
	{
		iChunk = iResidue;
	}

	USBHwEPWrite(0x80, pbData, iChunk);
	pbData += iChunk;
	iResidue -= iChunk;
}


/**
 *	Handles IN/OUT transfers on EP0
 *
 *	@param [in]	bEP		Endpoint address
 *	@param [in]	bEPStat	Endpoint status
 */
void USBHandleControlTransfer(unsigned char bEP, unsigned char bEPStat)
{
	int iChunk, iType;

	if (bEP == 0x00) {
		// OUT transfer
		if (bEPStat & EP_STATUS_SETUP) {
			// setup packet, reset request message state machine
			USBHwEPRead(0x00, (unsigned char *)&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
				if( iLen < Setup.wLength )
				{
					iResidue = iLen;
				}
				else
				{
					iResidue = 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);
	}
}


/**
	Registers a callback for handling requests

	@param [in]	iType			Type of request, e.g. REQTYPE_TYPE_STANDARD
	@param [in]	*pfnHandler		Callback function pointer
	@param [in]	*pbDataStore	Data storage area for this type of request
 */
void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, unsigned char *pbDataStore)
{
	ASSERT(iType >= 0);
	ASSERT(iType < 4);
	apfnReqHandlers[iType] = pfnHandler;
	apbDataStore[iType] = pbDataStore;
}

