/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_COMMON_CLASS_H
#define __USB_COMMON_CLASS_H

#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include  "usbd_ioreq.h"
#include  "usb/usb_hooks.h"
#include  "usb/usb_config.h"
#include  "core/config.h"
#include  "drivers/usb/class/common/class_common.h"


// RECREATE_CONTROL_TRANSFER_OBJ
// Re-create transfer object for each transaction (=1), or keep old object (=0)
#define RECREATE_CONTROL_TRANSFER_OBJ            1

// DATAIN_INITIATESEND_REQUIRED
// Set to 1 if the hardware does not support NAK interrupt for IN endpoints,
// so to send data it is required to initiate the first packet send by application
#define DATAIN_INITIATESEND_REQUIRED             1

/*---------------------------------------------------------------------*/
/*  VENDOR definitions                                                 */
/*---------------------------------------------------------------------*/
 
typedef struct _USBD_COMMON_Itf
{
  fUsbInit_t          fUsbInit;
  fUsbDeInit_t        fUsbDeInit;  
  fUsbSetupRx_t       fUsbSetup;        // optional
  fUsbCtlEpRx_t       fUsbCtlEpRx;      // optional
  fUsbCtlEpTx_t       fUsbCtlEpTx;      // optional  
  fUsbBusReset_t      fResetEvent;      // optional, OK
  fUsbSuspendEvent_t  fSuspendEvent;    // optional, Not impleneded in STM32 driver (see HAL_PCD_SuspendCallback)
  fUsbSetIface_t      fSetIface;        // optional, OK (SET_INTERFACE request)
  fUsbClrIface_t      fClrIface;        // optional, OK (CLR_INTERFACE request)
  fUsbGetIface_t      fGetIface;        // optional, OK (GET_INTERFACE request)
  fUsbDataRx_t        fDataRxHandler;   // optional ( endpoints I/O )
  fUsbDataTx_t        fDataTxHandler;   // optional ( endpoints I/O )
  fUsbDataErr_t       fDataErrHandler;  // optional ( endpoints I/O )

}USBD_COMMON_ItfTypeDef;


// USBD_COMMON_EP0_RxReady
// This function is called when a packet via CONTROL protocol had been received from host
// This function continues the transmitting
uint8_t  USBD_COMMON_EP0_RxReady (USBD_HandleTypeDef *pdev, sUSBTransfer_t * rx, size_t * pnBytesRollback );

// USBD_COMMON_EP0_TxSent()
// This function is called when at least one packet via CONTROL protocol had been sent to the host
// This function continues the transmitting
uint8_t  USBD_COMMON_EP0_TxSent (USBD_HandleTypeDef *pdev, sUSBTransfer_t * tx, size_t * pnBytesRollback );

// USBD_COMMON_Setup_DataProcess()
// Handler for specific vendor or class requests
// @pdev, @pUserIface, @req and @transf MUST BE NON-NULL!
// Do not call if @req->wLength is zero
uint8_t USBD_COMMON_Setup_DataProcess( USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req, sUSBTransfer_t * transf );


// USBD_COMMON_DataInProcess
// Process DataIN events for Bulk and Interrupt endpoints
uint8_t USBD_COMMON_DataInProcess( USBD_HandleTypeDef *pdev, uint8_t epnum, sUSBTransfer_t * transf );

// USBD_USBTMC_DataIn_ZeroSend
// Queue zero packet in EP IN
uint8_t USBD_COMMON_DataIn_ZeroSend( USBD_HandleTypeDef *pdev, uint8_t epnum );

// USBD_COMMON_DataIn_BeginSend
// Initiates the first packet sending 
// @bTxAlreadyPrepared - if the TX-transfer is already prepared to transmission, do not reset transfer, do not call TX-handler
uint8_t USBD_COMMON_DataIn_BeginSend( USBD_HandleTypeDef *pdev, uint8_t epnum, sUSBTransfer_t * transf, bool bTxAlreadyPrepared );

// USBD_COMMON_DataOutProcess
// Process DataOUT events for Bulk and Interrupt endpoints
uint8_t USBD_COMMON_DataOutProcess( USBD_HandleTypeDef *pdev, uint8_t epnum, sUSBTransfer_t * transf, bool ShortPacketReceived );

// USBD_COMMON_DataOutBegin
// Prepare the EP for next OUT (receive) transaction
uint8_t USBD_COMMON_DataOutBegin( USBD_HandleTypeDef  *pdev, uint8_t epnum, sUSBTransfer_t * transf );


#if USBD_CONSTSUBCLASS_IFACE
uint8_t  USBD_COMMON_RegisterInterface  (USBD_HandleTypeDef   *pdev, 
                                const USBD_COMMON_ItfTypeDef *fops);
#else   
uint8_t  USBD_COMMON_RegisterInterface  (USBD_HandleTypeDef   *pdev, 
                                      USBD_COMMON_ItfTypeDef *fops);
#endif


#ifdef __cplusplus
}
#endif

#endif  /* __USB_COMMON_CLASS_H */
