// -----------------------------------------------------------------------------
// USB Library "usblib"
// Target:  for lpc17xx
// Author:  Sychov A.
// Date:    12/10/2018
// Version: 1.0
// -----------------------------------------------------------------------------
// File:    USB-descriptors utility functions header
// Version: 1.0
// -----------------------------------------------------------------------------

#ifndef __USB_DESC_STRUCTS_H__
#define __USB_DESC_STRUCTS_H__

    #if !defined(__USER_USB_HEADER__) && !defined(__CORE_USB_HEADER__) && !defined(_USB_DESCR_C_)
    #warning Do not include 'usb_descr.h' header directly. The 'usb.h' should be used instead.
    #endif

    #include <string.h> // NULL  
    #include "uboot/usb_config.h"
    #include "uboot/usb_spec.h"
    #include "uboot/usb_transfers.h"
    
    typedef struct
    {                           
        sUSBTransfer_t *        pTransfer;    // user-defined user-created transfer object
        void *                  pBuf;         // user-created buffer for transfer object, size = EP-size
    }
    sUsrUsbEndpointService_t;

    // User Usb Endpoint Descriptor
    typedef struct
    {
        const sUSBEndpointDescriptor_t      * pUsbEpDesc;
        #if USB_WRAP_ENDPOINTS > 0
        const sUsrUsbEndpointService_t      * pUsbEpSvc;
        #else
        const void                          * pUsbEpSvc;
        #endif
    }
    sUsrUsbEndpoint_t;

    // User Usb Interface Descriptor
    typedef struct 
    {
        const sUSBInterfaceDescriptor_t     * pUsbIntDesc;        // pointer to USB INTERFACE DESCRIPTOR
        const sUsrUsbEndpoint_t             * pUsbEpDescList;     // pointer to USB ENDPOINT DESCRIPTORs list
    }                  
    sUsrUsbInterface_t;

    // User Usb Configuration Descriptor
    typedef struct 
    {
        const sUSBConfigurationDescriptor_t * pUsbConfDesc;       // pointer to USB CONFIGURATION DESCRIPTOR
        const sUsrUsbInterface_t            * pUsbIntDescList;    // pointer to User Usb Interface list
    }
    sUsrUsbConfiguration_t;
    
    // User Usb String
    typedef struct
    {
        const uint8_t * pUsbStrDesc;  // pointer to USB STRING DESCRIPTOR       
        uint16_t langId;              // lang ID for this string descriptor
    }
    sUsrUsbString_t;

    // User Usb Device Descriptor    
    typedef struct
    {
         const sUSBDeviceDescriptor_t  * pUsbDevDesc;        // pointer to sUSBDeviceDescriptor_t
         const sUsrUsbConfiguration_t  * pUsrUsbConfigList;  // pointer to User Usb Configuration list
         const sUsrUsbString_t         * pUsrUsbStringList;  // pointer to User Usb Strings list
    }
    sUsrUsbDevice_t;

    extern const sUsrUsbDevice_t UserUsbDevice_Default;

    // usb_search_interface()
    // Searches specified interface in the specified configuration
    // @conf - the configuration to search in
    // @bInterfaceNumber - interface number to search
    // @altSetting - alternate setting value to match to
    // Returns the interface pointer if found, and NULL otherwise
    const sUsrUsbConfiguration_t * usb_search_configuration( const sUsrUsbDevice_t * pUserUsbDevice, uint8_t bConfigurationValue );

    // usb_search_configuration_byIndex()
    // Retireves the configuration by specified index
    // @pUserUsbDevice - full device configuration set
    // @index - configuration index
    // Returns the configuration pointer if found, and NULL otherwise
    const sUsrUsbConfiguration_t * usb_search_configuration_byIndex( const sUsrUsbDevice_t * pUserUsbDevice, size_t index );


    // usb_search_interface()
    // Searches specified interface in the specified configuration
    // @conf - the configuration to search in
    // @bInterfaceNumber - interface number to search
    // @altSetting - alternate setting value to match to
    // Returns the interface pointer if found, and NULL otherwise
    const sUsrUsbInterface_t * usb_search_interface( const sUsrUsbConfiguration_t * conf, uint8_t bInterfaceNumber, uint8_t altSetting );

    // usb_search_interface()
    // Searches specified string in the string descriptors list
    // @pUserUsbDevice - full device configuration set
    // @iString - string index
    // @lang - string language ID
    // Returns the string descriptor pointer if found, and NULL otherwise
    const sUsrUsbString_t * usb_search_string( const sUsrUsbDevice_t * pUserUsbDevice, size_t iString, uint16_t lang );
#endif