#define USB_APPLICATION_INTERFACESWITCH_C
#include "core/config.h"
#include "usbapp/usb_application_interfaceswitch.h"
#include "usb/usb_bridge.h"
#include "usb/usb_config.h"
#include "usbd_vendor.h"
#include "my_assert.h"
#if CONFIG_NFMBASECLASS
#include "app/nfm/nfm_base.h"
#else
#error This feature can not be implemented without CONFIG_NFMBASECLASS
#endif

#define  PROTO_REQ_INTERFACE_SWITCH       0xBF   // переключить интерфейс на USBTMC

static int8_t fInterfaceSwitchAppInit();
static int8_t fInterfaceSwitchAppDeInit();
static void   fInterfaceSwitchAppReset();
static bool   fInterfaceSwitchAppSetup( const tUSBSetupPacket_t * pSetup, bool bFirstStage, bool success );
static size_t fInterfaceSwitchAppControlRx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining );
static size_t fInterfaceSwitchAppControlTx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining );

const sUSBAppEntry_Control_t usbapplication_ACM_planarproto_interfaceswitch = {

     .fUsbInit     = fInterfaceSwitchAppInit,
     .fUsbDeInit   = fInterfaceSwitchAppDeInit,
     .fUsbSetup    = fInterfaceSwitchAppSetup,
     .fUsbCtlEpRx  = fInterfaceSwitchAppControlRx,
     .fUsbCtlEpTx  = fInterfaceSwitchAppControlTx,
     .fResetEvent  = fInterfaceSwitchAppReset,
};

static int8_t fInterfaceSwitchAppInit()
{
    #if !CONFIG_USB_USBTMC_ENABLE
    my_assert(false); // USBTMC is not enabled in configuration
    #endif
    return 0;
}

static int8_t fInterfaceSwitchAppDeInit()
{
    return 0;
}

static void fInterfaceSwitchAppReset()
{

}

static bool fInterfaceSwitchAppSetup( const tUSBSetupPacket_t * pSetup, bool bFirstStage, bool success )
{
    switch( pSetup->bRequest )
    {
        case PROTO_REQ_INTERFACE_SWITCH:
        {
             #if !CONFIG_USB_OVERRIDE_IFACE_VENDOR             
             return true; // request supported, pass to the TX stage
             #endif
        }
        break;
    }

    return false;
}

static size_t fInterfaceSwitchAppControlRx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining )
{
    return 0;
}

static size_t fInterfaceSwitchAppControlTx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining )
{
    switch( pSetup->bRequest )
    {
        case PROTO_REQ_INTERFACE_SWITCH: // read the raw lowlevel control code
        {
             uint8_t status = 0;
             #if CONFIG_USB_USBTMC_ENABLE
             #if !CONFIG_USB_OVERRIDE_IFACE_VENDOR
             bool rc = NFMClass->methods.usbInterface.setInterface( eNFM_IfaceUSBTMC );
             #if CONFIG_REBOOT_FEATURE
             if( rc ) RebootRequest();
             #endif
             status = ((rc)?'\1':'\0');
             #endif
             #endif
             if( 0 == idx && sizeof(uint8_t) == bytesRemaining )
             {
                 usb_push_transfer( tx, &status, sizeof( status ) );
             }
        }
        break;
    }

    return usb_count_transfer( tx );
}
