/*
 * SPDX-FileCopyrightText: Copyright (c) 2019 Ha Thach (tinyusb.org)
 * SPDX-License-Identifier: MIT
 *
 * This file is part of the TinyUSB stack.
 */

#include "tusb_option.h"

#if CFG_TUD_ENABLED

#include "device/dcd.h"
#include "tusb.h"
#include "common/tusb_private.h"

#include "device/usbd.h"
#include "device/usbd_pvt.h"

//--------------------------------------------------------------------+
// USBD Configuration
//--------------------------------------------------------------------+
#ifndef CFG_TUD_TASK_QUEUE_SZ
  #define CFG_TUD_TASK_QUEUE_SZ   16
#endif

//--------------------------------------------------------------------+
// Weak stubs: invoked if no strong implementation is available
//--------------------------------------------------------------------+
TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
  (void) rhport; (void) eventid; (void) in_isr;
}

TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count) {
  (void) frame_count;
}

TU_ATTR_WEAK uint8_t const* tud_descriptor_bos_cb(void) {
  return NULL;
}

TU_ATTR_WEAK uint8_t const* tud_descriptor_device_qualifier_cb(void) {
  return NULL;
}

TU_ATTR_WEAK uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) {
  (void) index;
  return NULL;
}

TU_ATTR_WEAK void tud_mount_cb(void) {
}

TU_ATTR_WEAK void tud_umount_cb(void) {
}

TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en) {
  (void) remote_wakeup_en;
}

TU_ATTR_WEAK void tud_resume_cb(void) {
}

TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) {
  (void) rhport; (void) stage; (void) request;
  return false;
}

TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) {
  (void) rhport;
  return false;
}

TU_ATTR_WEAK void dcd_connect(uint8_t rhport) {
  (void) rhport;
}

TU_ATTR_WEAK void dcd_disconnect(uint8_t rhport) {
  (void) rhport;
}

TU_ATTR_WEAK bool dcd_dcache_clean(const void* addr, uint32_t data_size) {
  (void) addr; (void) data_size;
  return true;
}

TU_ATTR_WEAK bool dcd_dcache_invalidate(const void* addr, uint32_t data_size) {
  (void) addr; (void) data_size;
  return true;
}

TU_ATTR_WEAK bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) {
  (void) addr; (void) data_size;
  return true;
}

//--------------------------------------------------------------------+
// Device Data
//--------------------------------------------------------------------+

// Per-control-transfer state: populated at process_setup_received() entry,
// consumed asynchronously by usbd_control_xfer_cb() when the EP0 transfer completes.
typedef struct {
  tusb_control_request_t request;
  uint8_t* buffer;
  uint16_t data_len;
  uint16_t total_xferred;
  usbd_control_xfer_cb_t complete_cb;
} usbd_control_xfer_t;

typedef struct {
  usbd_control_xfer_t ctrl_xfer;

  // Note: these may share an enum state
  volatile uint8_t connected;
  volatile uint8_t addressed;
  volatile uint8_t suspended;

  union {
    struct TU_ATTR_PACKED {
      uint8_t self_powered     : 1; // configuration descriptor's attribute;
      uint8_t remote_wakeup_en : 1; // enable/disable by host
    };
    uint8_t dev_state_bm;
  };

  uint8_t          cfg_num; // current active configuration (0x00 is not configured)
  uint8_t          speed;
  volatile uint8_t sof_consumer;

  uint8_t itf2drv[CFG_TUD_INTERFACE_MAX];   // map interface number to driver (0xff is invalid)
  uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each

  volatile uint8_t ep_status[CFG_TUD_ENDPPOINT_MAX][2];
} usbd_device_t;

static usbd_device_t    _usbd_dev;
static volatile uint8_t _usbd_queued_setup;

CFG_TUD_MEM_SECTION static struct {
  TUD_EPBUF_DEF(buf, CFG_TUD_ENDPOINT0_BUFSIZE);
} _ctrl_epbuf;

//--------------------------------------------------------------------+
// Class Driver
//--------------------------------------------------------------------+
  #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
    #define DRIVER_NAME(_name) _name
  #else
    #define DRIVER_NAME(_name) NULL
  #endif

// Built-in class drivers
static const usbd_class_driver_t _usbd_driver[] = {
  #if CFG_TUD_CDC
    {
        .name             = DRIVER_NAME("CDC"),
        .init             = cdcd_init,
        .deinit           = cdcd_deinit,
        .reset            = cdcd_reset,
        .open             = cdcd_open,
        .control_xfer_cb  = cdcd_control_xfer_cb,
        .xfer_cb          = cdcd_xfer_cb,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_MSC
    {
        .name             = DRIVER_NAME("MSC"),
        .init             = mscd_init,
        .deinit           = NULL,
        .reset            = mscd_reset,
        .open             = mscd_open,
        .control_xfer_cb  = mscd_control_xfer_cb,
        .xfer_cb          = mscd_xfer_cb,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_HID
    {
        .name             = DRIVER_NAME("HID"),
        .init             = hidd_init,
        .deinit           = hidd_deinit,
        .reset            = hidd_reset,
        .open             = hidd_open,
        .control_xfer_cb  = hidd_control_xfer_cb,
        .xfer_cb          = hidd_xfer_cb,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_AUDIO
    {
        .name             = DRIVER_NAME("AUDIO"),
        .init             = audiod_init,
        .deinit           = audiod_deinit,
        .reset            = audiod_reset,
        .open             = audiod_open,
        .control_xfer_cb  = audiod_control_xfer_cb,
        .xfer_cb          = audiod_xfer_cb,
        .xfer_isr         = audiod_xfer_isr,
        .sof              = audiod_sof_isr
    },
    #endif

    #if CFG_TUD_VIDEO
    {
        .name             = DRIVER_NAME("VIDEO"),
        .init             = videod_init,
        .deinit           = videod_deinit,
        .reset            = videod_reset,
        .open             = videod_open,
        .control_xfer_cb  = videod_control_xfer_cb,
        .xfer_cb          = videod_xfer_cb,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_MIDI
    {
        .name             = DRIVER_NAME("MIDI"),
        .init             = midid_init,
        .deinit           = midid_deinit,
        .open             = midid_open,
        .reset            = midid_reset,
        .control_xfer_cb  = midid_control_xfer_cb,
        .xfer_cb          = midid_xfer_cb,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_MIDI2
    {
        .name             = DRIVER_NAME("MIDI2"),
        .init             = midi2d_init,
        .deinit           = midi2d_deinit,
        .open             = midi2d_open,
        .reset            = midi2d_reset,
        .control_xfer_cb  = midi2d_control_xfer_cb,
        .xfer_cb          = midi2d_xfer_cb,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_VENDOR
    {
        .name             = DRIVER_NAME("VENDOR"),
        .init             = vendord_init,
        .deinit           = vendord_deinit,
        .reset            = vendord_reset,
        .open             = vendord_open,
        .control_xfer_cb  = vendord_control_xfer_cb,
        .xfer_cb          = vendord_xfer_cb,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_USBTMC
    {
        .name             = DRIVER_NAME("TMC"),
        .init             = usbtmcd_init_cb,
        .deinit           = usbtmcd_deinit,
        .reset            = usbtmcd_reset_cb,
        .open             = usbtmcd_open_cb,
        .control_xfer_cb  = usbtmcd_control_xfer_cb,
        .xfer_cb          = usbtmcd_xfer_cb,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_DFU_RUNTIME
    {
        .name             = DRIVER_NAME("DFU-RUNTIME"),
        .init             = dfu_rtd_init,
        .deinit           = dfu_rtd_deinit,
        .reset            = dfu_rtd_reset,
        .open             = dfu_rtd_open,
        .control_xfer_cb  = dfu_rtd_control_xfer_cb,
        .xfer_cb          = NULL,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_DFU
    {
        .name             = DRIVER_NAME("DFU"),
        .init             = dfu_moded_init,
        .deinit           = dfu_moded_deinit,
        .reset            = dfu_moded_reset,
        .open             = dfu_moded_open,
        .control_xfer_cb  = dfu_moded_control_xfer_cb,
        .xfer_cb          = NULL,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM
    {
        .name             = DRIVER_NAME("NET"),
        .init             = netd_init,
        .deinit           = netd_deinit,
        .reset            = netd_reset,
        .open             = netd_open,
        .control_xfer_cb  = netd_control_xfer_cb,
        .xfer_cb          = netd_xfer_cb,
        .xfer_isr         = NULL,
        .sof              = NULL,
    },
    #endif

    #if CFG_TUD_BTH
    {
        .name             = DRIVER_NAME("BTH"),
        .init             = btd_init,
        .deinit           = btd_deinit,
        .reset            = btd_reset,
        .open             = btd_open,
        .control_xfer_cb  = btd_control_xfer_cb,
        .xfer_cb          = btd_xfer_cb,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_MTP
    {
        .name             = DRIVER_NAME("MTP"),
        .init             = mtpd_init,
        .deinit           = mtpd_deinit,
        .reset            = mtpd_reset,
        .open             = mtpd_open,
        .control_xfer_cb  = mtpd_control_xfer_cb,
        .xfer_cb          = mtpd_xfer_cb,
        .xfer_isr         = NULL,
        .sof              = NULL
    },
    #endif

    #if CFG_TUD_PRINTER
    {
        .name             = DRIVER_NAME("PRINTER"),
        .init             = printerd_init,
        .deinit           = printerd_deinit,
        .reset            = printerd_reset,
        .open             = printerd_open,
        .control_xfer_cb  = printerd_control_xfer_cb,
        .xfer_cb          = printerd_xfer_cb,
        .sof              = NULL
    },
    #endif
};

// Additional class drivers implemented by application
static const usbd_class_driver_t *_app_driver = NULL;
static const uint8_t _builtin_driver_count    = TU_ARRAY_SIZE(_usbd_driver);
static uint8_t              _app_driver_count = 0;

#define TOTAL_DRIVER_COUNT    ((uint8_t) (_app_driver_count + _builtin_driver_count))

// virtually joins built-in and application drivers together.
// Application is positioned first to allow overwriting built-in ones.
TU_ATTR_ALWAYS_INLINE static inline usbd_class_driver_t const * get_driver(uint8_t drvid) {
  usbd_class_driver_t const *driver = NULL;
  if (drvid < _app_driver_count) {
    // Application drivers
    driver = &_app_driver[drvid];
  } else{
    drvid -= _app_driver_count;
    if (_builtin_driver_count > 0 && drvid < _builtin_driver_count) {
      driver = &_usbd_driver[drvid];
    }
  }

  return driver;
}

//--------------------------------------------------------------------+
// DCD Event
//--------------------------------------------------------------------+
enum {
  RHPORT_INVALID = 0xFFu
};
static uint8_t _usbd_rhport = RHPORT_INVALID;

static OSAL_SPINLOCK_DEF(_usbd_spin, usbd_int_set);

// Event queue: usbd_int_set() is used as mutex in OS NONE config
OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t);
static osal_queue_t _usbd_q;

// Mutex for claiming endpoint
#if OSAL_MUTEX_REQUIRED
  static osal_mutex_def_t _ubsd_mutexdef;
  static osal_mutex_t _usbd_mutex;
#else
  #define _usbd_mutex   NULL
#endif

TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) {
  TU_ASSERT(osal_queue_send(_usbd_q, event, in_isr));
  tud_event_hook_cb(event->rhport, event->event_id, in_isr);
  return true;
}

//--------------------------------------------------------------------+
// Prototypes
//--------------------------------------------------------------------+
static bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
static bool process_setup_received(uint8_t rhport, tusb_control_request_t const * p_request);
static bool process_get_status(uint8_t rhport, tusb_control_request_t const * request, uint16_t status);
static bool process_set_config(uint8_t rhport, uint8_t cfg_num);
static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request);

#if CFG_TUD_TEST_MODE
static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) {
  TU_VERIFY(CONTROL_STAGE_ACK == stage);
  uint8_t const selector = tu_u16_high(request->wIndex);
  TU_LOG_USBD("    Enter Test Mode (test selector index: %d)\r\n", selector);
  dcd_enter_test_mode(rhport, (tusb_feature_test_mode_t) selector);
  return true;
}
#endif

//--------------------------------------------------------------------+
// Weak stubs: invoked if no strong implementation is available
//--------------------------------------------------------------------+
TU_ATTR_WEAK usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) {
  *driver_count = 0;
  return NULL;
}

TU_ATTR_WEAK bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) {
  (void) rhport; (void) ep_addr; (void) ff; (void) total_bytes; (void) is_isr;
  return false;
}

TU_ATTR_WEAK bool dcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) {
  (void) rhport; (void) cfg_id; (void) cfg_param;
  return false;
}

//--------------------------------------------------------------------+
// Debug
//--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
static char const *const _usbd_event_str[DCD_EVENT_COUNT] = {
    "Invalid",
    "Bus Reset",
    "Unplugged",
    "SOF",
    "Suspend",
    "Resume",
    "Setup Received",
    "Xfer Complete",
    "Func Call"
};

#endif

//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+
tusb_speed_t tud_speed_get(void) {
  return (tusb_speed_t) _usbd_dev.speed;
}

bool tud_connected(void) {
  return _usbd_dev.connected;
}

bool tud_mounted(void) {
  return _usbd_dev.cfg_num ? true : false;
}

bool tud_suspended(void) {
  return _usbd_dev.suspended;
}

bool tud_remote_wakeup(void) {
  // only wake up host if this feature is enabled and we are suspended
  TU_VERIFY(_usbd_dev.suspended && _usbd_dev.remote_wakeup_en);
  dcd_remote_wakeup(_usbd_rhport);
  return true;
}

bool tud_disconnect(void) {
  dcd_disconnect(_usbd_rhport);
  return true;
}

bool tud_connect(void) {
  dcd_connect(_usbd_rhport);
  return true;
}

void tud_sof_cb_enable(bool en) {
  usbd_sof_enable(_usbd_rhport, SOF_CONSUMER_USER, en);
}

bool tud_inited(void) {
  return _usbd_rhport != RHPORT_INVALID;
}

bool tud_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) {
  return dcd_configure(rhport, cfg_id, cfg_param);
}

bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
  if (tud_inited()) {
    return true; // skip if already initialized
  }
  TU_ASSERT(rh_init);
 #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
  char const* speed_str = 0;
  switch (rh_init->speed) {
    case TUSB_SPEED_HIGH:
      speed_str = "High";
    break;
    case TUSB_SPEED_FULL:
      speed_str = "Full";
    break;
    case TUSB_SPEED_LOW:
      speed_str = "Low";
    break;
    case TUSB_SPEED_AUTO:
      speed_str = "Auto";
    break;
  default:
    break;
  }
  TU_LOG_USBD("USBD init on controller %u, speed = %s\r\n", rhport, speed_str);
  TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t));
  TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(dcd_event_t));
  TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t));
  TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_edpt_stream_t));
#endif

  tu_varclr(&_usbd_dev);
  _usbd_queued_setup = 0;

  osal_spin_init(&_usbd_spin);

#if OSAL_MUTEX_REQUIRED
  // Init device mutex
  _usbd_mutex = osal_mutex_create(&_ubsd_mutexdef);
  TU_ASSERT(_usbd_mutex);
#endif

  // Init device queue & task
  _usbd_q = osal_queue_create(&_usbd_qdef);
  TU_ASSERT(_usbd_q);

  // Get application driver if available
  _app_driver = usbd_app_driver_get_cb(&_app_driver_count);
  TU_ASSERT(_app_driver_count + _builtin_driver_count <= UINT8_MAX);

  // Init class drivers
  for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
    usbd_class_driver_t const* driver = get_driver(i);
    TU_ASSERT(driver && driver->init);
    TU_LOG_USBD("%s init\r\n", driver->name);
    driver->init();
  }

  _usbd_rhport = rhport;

  // Init device controller driver
  TU_ASSERT(dcd_init(rhport, rh_init));
  dcd_int_enable(rhport);

  return true;
}

bool tud_deinit(uint8_t rhport) {
  if (!tud_inited()) {
    return true; // skip if not initialized
  }

  TU_LOG_USBD("USBD deinit on controller %u\r\n", rhport);

  const uint8_t cfg_num = _usbd_dev.cfg_num;

  // Deinit device controller driver
  dcd_int_disable(rhport);
  dcd_disconnect(rhport);
  TU_ASSERT(dcd_deinit(rhport));

  // Deinit class drivers
  for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
    usbd_class_driver_t const* driver = get_driver(i);
    if(driver && driver->deinit) {
      TU_LOG_USBD("%s deinit\r\n", driver->name);
      driver->deinit();
    }
  }

  tu_varclr(&_usbd_dev); // Clear device data

  // Deinit device queue & task
  osal_queue_delete(_usbd_q);
  _usbd_q = NULL;

#if OSAL_MUTEX_REQUIRED
  // TODO make sure there is no task waiting on this mutex
  osal_mutex_delete(_usbd_mutex);
  _usbd_mutex = NULL;
#endif

  osal_spin_deinit(&_usbd_spin);

  _usbd_rhport = RHPORT_INVALID;

  if (cfg_num > 0) {
    tud_umount_cb();
  }

  return true;
}

static void configuration_reset(uint8_t rhport) {
  for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
    usbd_class_driver_t const* driver = get_driver(i);
    TU_ASSERT(driver,);
    driver->reset(rhport);
  }

  tu_varclr(&_usbd_dev);
  (void)memset(_usbd_dev.itf2drv, TUSB_INDEX_INVALID_8, sizeof(_usbd_dev.itf2drv)); // invalid mapping
  (void)memset(_usbd_dev.ep2drv, TUSB_INDEX_INVALID_8, sizeof(_usbd_dev.ep2drv));   // invalid mapping
}

static void usbd_reset(uint8_t rhport) {
  configuration_reset(rhport);
  // discard any pre-reset SETUP still counted: a stale count skips post-reset SETUPs
  _usbd_queued_setup = 0;
}

bool tud_task_event_ready(void) {
  TU_VERIFY(tud_inited()); // Skip if stack is not initialized
  return !osal_queue_empty(_usbd_q);
}

//--------------------------------------------------------------------+
// USBD Task
//--------------------------------------------------------------------+
/* USB Device Driver task
 * This top level thread manages all device controller event and delegates events to class-specific drivers.
 * This should be called periodically within the mainloop or rtos thread.
 *
    int main(void) {
      application_init();
      tusb_init(0, TUSB_ROLE_DEVICE);

      while(1) { // the mainloop
        application_code();
        tud_task(); // tinyusb device task
      }
    }
 */
void tud_task_ext(uint32_t timeout_ms, bool in_isr) {
  (void) in_isr; // not implemented yet

  // Skip if stack is not initialized
  if (!tud_inited()) {
    return;
  }

  // Loop until there are no more events in the queue or CFG_TUD_TASK_EVENTS_PER_RUN is reached
  for (unsigned epr = 0;; epr++) {
#if CFG_TUD_TASK_EVENTS_PER_RUN > 0
    if (epr >= CFG_TUD_TASK_EVENTS_PER_RUN) {
      TU_LOG_USBD("USBD event limit (" TU_XSTRING(CFG_TUD_TASK_EVENTS_PER_RUN) ") reached\r\n");
      break;
    }
#endif
    dcd_event_t event;
    if (!osal_queue_receive(_usbd_q, &event, timeout_ms)) {
      return;
    }

#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
    if (event.event_id == DCD_EVENT_SETUP_RECEIVED) {
      TU_LOG_USBD("\r\n"); // extra line for setup
    }
    TU_LOG_USBD("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
#endif

    switch (event.event_id) {
      case DCD_EVENT_BUS_RESET:
        TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]);
        usbd_reset(event.rhport);
        _usbd_dev.speed = event.bus_reset.speed;
        break;

      case DCD_EVENT_UNPLUGGED:
        TU_LOG_USBD("\r\n");
        usbd_reset(event.rhport);
        tud_umount_cb();
        break;

      case DCD_EVENT_SETUP_RECEIVED:
        if (_usbd_queued_setup == 0) {
          break;
        }
        _usbd_queued_setup--;
        TU_LOG_BUF(CFG_TUD_LOG_LEVEL, &event.setup_received, 8);
        if (_usbd_queued_setup != 0) {
          TU_LOG_USBD("  Skipped since there is other SETUP in queue\r\n");
          break;
        }

        // Mark as connected after receiving 1st setup packet.
        // But it is easier to set it every time instead of wasting time to check then set
        _usbd_dev.connected = 1;

        // reset ep state
        _usbd_dev.ep_status[0][TUSB_DIR_OUT] = 0;
        _usbd_dev.ep_status[0][TUSB_DIR_IN] = 0;

        // Process control request
        if (!process_setup_received(event.rhport, &event.setup_received)) {
          TU_LOG_USBD("  Stall EP0\r\n");
          // Failed -> stall both control endpoint IN and OUT
          dcd_edpt_stall(event.rhport, TU_EP0_OUT);
          dcd_edpt_stall(event.rhport, TU_EP0_IN);
        }
        break;

      case DCD_EVENT_XFER_COMPLETE: {
        // Invoke the class callback associated with the endpoint address
        uint8_t const ep_addr = event.xfer_complete.ep_addr;
        uint8_t const epnum = tu_edpt_number(ep_addr);
        uint8_t const ep_dir = tu_edpt_dir(ep_addr);

        TU_LOG_USBD("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len);

        // Clear busy + claimed
        _usbd_dev.ep_status[epnum][ep_dir] &= (uint8_t) ~(TU_EDPT_STATE_BUSY | TU_EDPT_STATE_CLAIMED);

        if (0 == epnum) {
          usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
        } else {
          usbd_class_driver_t const* driver = get_driver(_usbd_dev.ep2drv[epnum][ep_dir]);
          TU_ASSERT(driver,);

          TU_LOG_USBD("  %s xfer callback\r\n", driver->name);
          driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
        }
        break;
      }

      case DCD_EVENT_SUSPEND:
        // NOTE: When plugging/unplugging device, the D+/D- state are unstable and
        // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ), which result in a series of event
        // e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected
        if (_usbd_dev.connected) {
          TU_LOG_USBD(": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en);
          tud_suspend_cb(_usbd_dev.remote_wakeup_en);
        } else {
          TU_LOG_USBD(" Skipped\r\n");
        }
        break;

      case DCD_EVENT_RESUME:
        if (_usbd_dev.connected) {
          TU_LOG_USBD("\r\n");
          tud_resume_cb();
        } else {
          TU_LOG_USBD(" Skipped\r\n");
        }
        break;

      case USBD_EVENT_FUNC_CALL:
        TU_LOG_USBD("\r\n");
        if (event.func_call.func != NULL) {
          event.func_call.func(event.func_call.param);
        }
        break;

      case DCD_EVENT_SOF:
        if (tu_bit_test(_usbd_dev.sof_consumer, SOF_CONSUMER_USER)) {
          TU_LOG_USBD("\r\n");
          tud_sof_cb(event.sof.frame_count);
        }
      break;

      default:
        TU_BREAKPOINT();
        break;
    }

    // allow to exit tud_task() if there is no event in the next run
    timeout_ms = 0;
  }
}

//--------------------------------------------------------------------+
// Control Endpoint
//--------------------------------------------------------------------+

// Weak hook: invoked when the control transfer's status stage completes
TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t* request) {
  (void) rhport;
  (void) request;
}

uint8_t* usbd_get_ctrl_buf(void) {
  return _ctrl_epbuf.buf;
}

// Endpoint used for the Status stage of a control transfer.
// Per USB 2.0 §9.3.1, when wLength == 0 the Direction bit is ignored and the Status
// stage is always IN. Otherwise the Status stage is opposite of the Data stage direction.
TU_ATTR_ALWAYS_INLINE static inline uint8_t status_stage_ep(const tusb_control_request_t* request) {
  return (request->wLength != 0 && request->bmRequestType_bit.direction) ? TU_EP0_OUT : TU_EP0_IN;
}

// Queue ZLP status transaction
TU_ATTR_ALWAYS_INLINE static inline bool status_stage_xact(uint8_t rhport, uint8_t ep_status) {
  return usbd_edpt_xfer(rhport, ep_status, NULL, 0, false);
}

// Queue a transaction in Data Stage. Each transaction has up to Endpoint0's max
// packet size. This function can also transfer a zero-length packet.
static bool data_stage_xact(uint8_t rhport) {
  usbd_control_xfer_t* const ctrl_xfer = &_usbd_dev.ctrl_xfer;
  const uint16_t xact_len = tu_min16(ctrl_xfer->data_len - ctrl_xfer->total_xferred, CFG_TUD_ENDPOINT0_BUFSIZE);
  uint8_t ep_addr = TU_EP0_OUT;

  if (ctrl_xfer->request.bmRequestType_bit.direction == TUSB_DIR_IN) {
    ep_addr = TU_EP0_IN;
    if (0u != xact_len && ctrl_xfer->buffer != _ctrl_epbuf.buf) {
      TU_VERIFY(0 == tu_memcpy_s(_ctrl_epbuf.buf, CFG_TUD_ENDPOINT0_BUFSIZE, ctrl_xfer->buffer, xact_len));
    }
  }

  return usbd_edpt_xfer(rhport, ep_addr, xact_len ? _ctrl_epbuf.buf : NULL, xact_len, false);
}

// Status phase
bool tud_control_status(uint8_t rhport, const tusb_control_request_t* request) {
  // _usbd_dev.ctrl_xfer fields are pre-initialized at process_setup_received entry
  (void) request;
  return status_stage_xact(rhport, status_stage_ep(&_usbd_dev.ctrl_xfer.request));
}

// Transmit data to/from the control endpoint. If wLength is zero, a status packet is sent instead.
bool tud_control_xfer(uint8_t rhport, const tusb_control_request_t* request, void* buffer, uint16_t len) {
  // _usbd_dev.ctrl_xfer.request and reset fields are pre-initialized at process_setup_received entry
  (void) request;
  usbd_control_xfer_t* const ctrl_xfer = &_usbd_dev.ctrl_xfer;
  ctrl_xfer->buffer = (uint8_t*) buffer;
  ctrl_xfer->data_len = tu_min16(len, ctrl_xfer->request.wLength);

  if (ctrl_xfer->request.wLength > 0U) {
    if (ctrl_xfer->data_len > 0U) {
      TU_ASSERT(buffer);
    }
    TU_ASSERT(data_stage_xact(rhport));
  } else {
    // wLength == 0: Status stage is always IN per USB 2.0 §9.3.1
    TU_ASSERT(status_stage_xact(rhport, TU_EP0_IN));
  }

  return true;
}

// Callback when a transaction completes on the DATA stage or Status stage of EP0
static bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
  (void) result;
  usbd_control_xfer_t* const ctrl_xfer = &_usbd_dev.ctrl_xfer;

  // Status Stage complete: ep_addr matches the resolved Status stage endpoint
  uint8_t const ep_status = status_stage_ep(&ctrl_xfer->request);
  if (ep_addr == ep_status) {
    TU_ASSERT(0 == xferred_bytes);

    // invoke optional dcd hook if available
    dcd_edpt0_status_complete(rhport, &ctrl_xfer->request);

    if (NULL != ctrl_xfer->complete_cb) {
      ctrl_xfer->complete_cb(rhport, CONTROL_STAGE_ACK, &ctrl_xfer->request);
    }

    return true;
  }

  // Data stage progress
  if (ctrl_xfer->request.bmRequestType_bit.direction == TUSB_DIR_OUT) {
    TU_VERIFY(ctrl_xfer->buffer);
    // Clamp host overrun to remaining capacity (data_len) so memcpy can't overflow the caller buffer
    xferred_bytes = tu_min32(xferred_bytes, ctrl_xfer->data_len - ctrl_xfer->total_xferred);
    if (ctrl_xfer->buffer != _ctrl_epbuf.buf) {
      memcpy(ctrl_xfer->buffer, _ctrl_epbuf.buf, xferred_bytes);
    }
    TU_LOG_MEM(CFG_TUD_LOG_LEVEL, ctrl_xfer->buffer, xferred_bytes, 2);
  }

  ctrl_xfer->total_xferred += (uint16_t) xferred_bytes;
  ctrl_xfer->buffer += xferred_bytes;

  // Data Stage complete when wLength reached or short packet (incl. ZLP) seen
  if ((ctrl_xfer->request.wLength == ctrl_xfer->total_xferred) ||
      (xferred_bytes < CFG_TUD_ENDPOINT0_BUFSIZE)) {
    bool is_ok = true;

    if (NULL != ctrl_xfer->complete_cb) {
      // Callback can still stall control in status phase, e.g. OUT data doesn't make sense
      is_ok = ctrl_xfer->complete_cb(rhport, CONTROL_STAGE_DATA, &ctrl_xfer->request);
    }

    if (is_ok) {
      TU_ASSERT(status_stage_xact(rhport, ep_status));
    } else {
      // Stall both IN and OUT control endpoint
      dcd_edpt_stall(rhport, TU_EP0_OUT);
      dcd_edpt_stall(rhport, TU_EP0_IN);
    }
  } else {
    // More data to transfer
    TU_ASSERT(data_stage_xact(rhport));
  }

  return true;
}

//--------------------------------------------------------------------+
// Control Request Parser & Handling
//--------------------------------------------------------------------+

// Helper to invoke class driver control request handler
static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request) {
  _usbd_dev.ctrl_xfer.complete_cb = driver->control_xfer_cb;
  TU_LOG_USBD("  %s control request\r\n", driver->name);
  return driver->control_xfer_cb(rhport, CONTROL_STAGE_SETUP, request);
}

// Process a standard request to the device recipient.
static bool process_std_device_request(uint8_t rhport, tusb_control_request_t const * p_request) {
  switch (p_request->bRequest) { //-V2520
    case TUSB_REQ_SET_ADDRESS:
      // Depending on mcu, status phase could be sent either before or after changing device address,
      // or even require stack to not response with status at all
      // Therefore DCD must take full responsibility to response and include zlp status packet if needed.
      dcd_set_address(rhport, (uint8_t) p_request->wValue);
      _usbd_dev.addressed = 1;
      return true;

    case TUSB_REQ_GET_CONFIGURATION: {
      uint8_t cfg_num = _usbd_dev.cfg_num;
      tud_control_xfer(rhport, p_request, &cfg_num, 1);
      return true;
    }

    case TUSB_REQ_SET_CONFIGURATION: {
      uint8_t const cfg_num = (uint8_t) p_request->wValue;

      // Only process if new configure is different
      if (_usbd_dev.cfg_num != cfg_num) {
        if (_usbd_dev.cfg_num != 0) {
          // already configured: need to clear all endpoints and driver first
          TU_LOG_USBD("  Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num);

          dcd_sof_enable(rhport, false);
          dcd_edpt_close_all(rhport);

          // close all drivers and current configured state except bus speed
          const uint8_t speed = _usbd_dev.speed;
          configuration_reset(rhport);

          _usbd_dev.speed = speed; // restore speed
        }

        _usbd_dev.cfg_num = cfg_num;

        // Handle the new configuration
        if (cfg_num == 0) {
          tud_umount_cb();
        } else {
          if (!process_set_config(rhport, cfg_num)) {
            _usbd_dev.cfg_num = 0;
            TU_ASSERT(false);
          }
          tud_mount_cb();
        }
      }

      tud_control_status(rhport, p_request);
      return true;
    }

    case TUSB_REQ_GET_DESCRIPTOR:
      return process_get_descriptor(rhport, p_request);

    case TUSB_REQ_SET_FEATURE:
      switch (p_request->wValue) { //-V2520
        case TUSB_REQ_FEATURE_REMOTE_WAKEUP:
          TU_LOG_USBD("    Enable Remote Wakeup\r\n");
          // Host may enable remote wake up before suspending especially HID device
          _usbd_dev.remote_wakeup_en = 1;
          tud_control_status(rhport, p_request);
          return true;

        #if CFG_TUD_TEST_MODE
        case TUSB_REQ_FEATURE_TEST_MODE: {
          // Only handle the test mode if supported and valid
          TU_VERIFY(0 == tu_u16_low(p_request->wIndex));

          uint8_t const selector = tu_u16_high(p_request->wIndex);
          TU_VERIFY(TUSB_FEATURE_TEST_J <= selector && selector <= TUSB_FEATURE_TEST_FORCE_ENABLE);

          _usbd_dev.ctrl_xfer.complete_cb = process_test_mode_cb;
          tud_control_status(rhport, p_request);
          return true;
        }
        #endif

        // Stall unsupported feature selector
        default: return false;
      }

    case TUSB_REQ_CLEAR_FEATURE:
      // Only support remote wakeup for device feature
      TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
      TU_LOG_USBD("    Disable Remote Wakeup\r\n");

      // Host may disable remote wake up after resuming
      _usbd_dev.remote_wakeup_en = 0;
      tud_control_status(rhport, p_request);
      return true;

    case TUSB_REQ_GET_STATUS: {
      // Device status bit mask
      // - Bit 0: Self Powered TODO must invoke callback to get actual status
      // - Bit 1: Remote Wakeup enabled
      return process_get_status(rhport, p_request, (uint16_t) _usbd_dev.dev_state_bm);
    }

    default:
      TU_BREAKPOINT();
      return false;
  }
}


// Reply to a standard GET_STATUS (device/interface/endpoint) with its 2-byte status word.
// GET_STATUS is Device-to-host only; reject a mis-directed (OUT) request rather than handing
// usbd the address of a stack local to write host data into after this frame has returned.
static bool process_get_status(uint8_t rhport, tusb_control_request_t const * request, uint16_t status) {
  TU_VERIFY(request->bmRequestType_bit.direction == TUSB_DIR_IN);
  return tud_control_xfer(rhport, request, &status, 2);
}

// This handles the actual request and its response.
// Returns false if unable to complete the request, causing caller to stall control endpoints.
static bool process_setup_received(uint8_t rhport, tusb_control_request_t const * p_request) {
  // Initialize control transfer state for this request. The request copy must be
  // visible to usbd_control_xfer_cb when the (asynchronous) status ZLP completes,
  // since the SETUP packet event has already gone out of scope by then.
  usbd_control_xfer_t* const ctrl_xfer = &_usbd_dev.ctrl_xfer;
  ctrl_xfer->request = *p_request;
  ctrl_xfer->buffer = NULL;
  ctrl_xfer->total_xferred = 0;
  ctrl_xfer->data_len = 0;
  ctrl_xfer->complete_cb = NULL;

  p_request = &ctrl_xfer->request; // re-direct request pointer to internal copy (modifiable for hacking)
  TU_ASSERT(p_request->bmRequestType_bit.type < TUSB_REQ_TYPE_INVALID);

  // Vendor request
  if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) {
    ctrl_xfer->complete_cb = tud_vendor_control_xfer_cb;
    return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request);
  }

#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
  if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME) {
    TU_LOG_USBD("  %s", tu_str_std_request[p_request->bRequest]);
    if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) {
      TU_LOG_USBD("\r\n");
    }
  }
#endif

  switch (p_request->bmRequestType_bit.recipient) { //-V2520
    //------------- Device Requests e.g in enumeration -------------//
    case TUSB_REQ_RCPT_DEVICE:
      if ( TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type ) {
        uint8_t const itf = tu_u16_low(p_request->wIndex);
        TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv));

        usbd_class_driver_t const * driver = get_driver(_usbd_dev.itf2drv[itf]);
        TU_VERIFY(driver);

        // forward to class driver: "non-STD request to Interface"
        return invoke_class_control(rhport, driver, p_request);
      }

      if (TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type) {
        // Non-standard request is not supported
        TU_BREAKPOINT();
        return false;
      }

      return process_std_device_request(rhport, p_request);

    //------------- Class/Interface Specific Request -------------//
    case TUSB_REQ_RCPT_INTERFACE: {
      uint8_t itf;
      #if CFG_TUD_PRINTER
      // Printer GET_DEVICE_ID has a weird wIndex = interface (high) | alt (low)
      // attempt to interpret this as a printer request if matched
      if (TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type &&
          TUSB_DIR_IN == p_request->bmRequestType_bit.direction &&
          TUSB_PRINTER_REQUEST_GET_DEVICE_ID == p_request->bRequest) {
        itf = tu_u16_high(p_request->wIndex);
        if (itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)) {
          const usbd_class_driver_t * driver = get_driver(_usbd_dev.itf2drv[itf]);
          if (driver != NULL && driver->control_xfer_cb == printerd_control_xfer_cb) {
            if (invoke_class_control(rhport, driver, p_request)) {
              return true;
            }
          }
        }
      }
      #endif
      itf = tu_u16_low(p_request->wIndex);
      TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv));

      usbd_class_driver_t const * driver = get_driver(_usbd_dev.itf2drv[itf]);
      TU_VERIFY(driver);

      // all requests to Interface (STD or Class) is forwarded to class driver.
      // notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE
      if (!invoke_class_control(rhport, driver, p_request)) {
        // For GET_INTERFACE and SET_INTERFACE, it is mandatory to respond even if the class
        // driver doesn't use alternate settings or implement this
        TU_VERIFY(TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type);

        // Clear complete callback if driver set since it can also stall the request.
        ctrl_xfer->complete_cb = NULL;

        switch (p_request->bRequest) { //-V2520
          case TUSB_REQ_GET_INTERFACE: {
            uint8_t alternate = 0;
            tud_control_xfer(rhport, p_request, &alternate, 1);
            break;
          }

          case TUSB_REQ_SET_INTERFACE:
            // A class that implements altsettings handles SET_INTERFACE itself and returns true,
            // so reaching here means the class does not — where only alt 0 is valid. Any non-zero
            // alt (unimplemented, or rejected as invalid by the class) is a Request Error (stall).
            TU_VERIFY(tu_u16_low(p_request->wValue) == 0);
            tud_control_status(rhport, p_request);
            break;

          case TUSB_REQ_GET_STATUS:
            // USB 2.0 9.4.5: interface GET_STATUS returns 2 reserved (zero) bytes
            TU_VERIFY(process_get_status(rhport, p_request, 0x0000));
            break;

          default: return false;
        }
      }
      break;
    }

    //------------- Endpoint Request -------------//
    case TUSB_REQ_RCPT_ENDPOINT: {
      uint8_t const ep_addr = tu_u16_low(p_request->wIndex);
      uint8_t const ep_num  = tu_edpt_number(ep_addr);
      uint8_t const ep_dir  = tu_edpt_dir(ep_addr);

      TU_ASSERT(ep_num < TU_ARRAY_SIZE(_usbd_dev.ep2drv) );
      usbd_class_driver_t const * driver = get_driver(_usbd_dev.ep2drv[ep_num][ep_dir]);

      if (TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type) {
        // Forward class request to its driver
        TU_VERIFY(driver);
        return invoke_class_control(rhport, driver, p_request);
      } else {
        // Handle STD request to endpoint
        switch (p_request->bRequest) { //-V2520
          case TUSB_REQ_GET_STATUS:
            // USB 2.0 9.4.5: endpoint GET_STATUS bit 0 = Halt
            TU_VERIFY(process_get_status(rhport, p_request, usbd_edpt_stalled(rhport, ep_addr) ? 0x0001u : 0x0000u));
            break;

          case TUSB_REQ_CLEAR_FEATURE:
          case TUSB_REQ_SET_FEATURE: {
            // ENDPOINT_HALT is the only endpoint feature; it exists only on a non-control endpoint
            // that an interface actually owns. Any other selector, the control endpoint (EP0 has no
            // Halt feature, USB 2.0 9.4.9), or an endpoint no driver owns is a Request Error (stall).
            TU_VERIFY(TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue);
            TU_VERIFY(ep_num != 0);
            TU_VERIFY(driver != NULL);

            if ( TUSB_REQ_CLEAR_FEATURE == p_request->bRequest ) {
              usbd_edpt_clear_stall(rhport, ep_addr);
            } else {
              usbd_edpt_stall(rhport, ep_addr);
            }

            // Some classes such as USBTMC need to clear/re-init their buffer on CLEAR_FEATURE.
            // Clear complete callback if driver set since it can also stall the request.
            (void) invoke_class_control(rhport, driver, p_request);
            ctrl_xfer->complete_cb = NULL;

            // STD request must always be ACKed; skip ZLP status if driver already did that.
            if (!(_usbd_dev.ep_status[0][TUSB_DIR_IN] & TU_EDPT_STATE_BUSY)) {
              tud_control_status(rhport, p_request);
            }
          }
          break;

          // Unknown/Unsupported request
          default:
            TU_BREAKPOINT();
            return false;
        }
      }
      break;
    }

    // Unknown recipient
    default:
      TU_BREAKPOINT();
      return false;
  }

  return true;
}

// Process Set Configure Request
// This function parse configuration descriptor & open drivers accordingly
static bool process_set_config(uint8_t rhport, uint8_t cfg_num) {
  // index is cfg_num-1
  const tusb_desc_configuration_t *desc_cfg =
    (const tusb_desc_configuration_t *)tud_descriptor_configuration_cb(cfg_num - 1);
  TU_ASSERT(desc_cfg != NULL && desc_cfg->bDescriptorType == TUSB_DESC_CONFIGURATION);

  // Parse configuration descriptor
  _usbd_dev.self_powered = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_SELF_POWERED) ? 1u : 0u;

  // Parse interface descriptor
  const uint8_t *p_desc   = ((const uint8_t *)desc_cfg) + sizeof(tusb_desc_configuration_t);
  const uint8_t *desc_end = ((const uint8_t *)desc_cfg) + tu_le16toh(desc_cfg->wTotalLength);

  while (tu_desc_in_bounds(p_desc, desc_end)) {
    // Class will always start with Interface Association (if any) and then Interface descriptor
    if (TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc)) {
      p_desc = tu_desc_next(p_desc); // next to Interface
      continue;
    }

    TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc));
    const tusb_desc_interface_t *desc_itf = (const tusb_desc_interface_t *)p_desc;

    // Find driver for this interface
    const uint16_t remaining_len = (uint16_t)(desc_end - p_desc);
    uint8_t        drv_id;
    for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
      const usbd_class_driver_t *driver = get_driver(drv_id);
      TU_ASSERT(driver);
      const uint16_t drv_len = driver->open(rhport, desc_itf, remaining_len);

      if ((sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len)) {
        // Open successfully
        TU_LOG_USBD("  %s opened\r\n", driver->name);

        // bind found driver to all interfaces and endpoint within drv_len
        TU_ASSERT(tu_bind_driver_to_ep_itf(drv_id, _usbd_dev.ep2drv, _usbd_dev.itf2drv, CFG_TUD_INTERFACE_MAX, p_desc,
                                           drv_len));

        p_desc += drv_len; // next Interface
        break; // exit driver find loop
      }
    }

    // Failed if there is no supported drivers
    TU_ASSERT(drv_id < TOTAL_DRIVER_COUNT);
  }

  return true;
}

// return descriptor's buffer and update desc_len
static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request) {
  tusb_desc_type_t const desc_type = (tusb_desc_type_t) tu_u16_high(p_request->wValue);
  uint8_t const desc_index = tu_u16_low( p_request->wValue );

  switch(desc_type) { //-V2520
    case TUSB_DESC_DEVICE: {
      TU_LOG_USBD(" Device\r\n");

      void *desc_device = (void *)(uintptr_t)tud_descriptor_device_cb();
      TU_ASSERT(desc_device);

      // Only response with exactly 1 Packet if: not addressed and host requested more data than device descriptor has.
      // This only happens with the very first get device descriptor and EP0 size = 8 or 16.
      if ((CFG_TUD_ENDPOINT0_SIZE < sizeof(tusb_desc_device_t)) && !_usbd_dev.addressed &&
          p_request->wLength > sizeof(tusb_desc_device_t)) {
        // Hack here: we modify the request length to prevent usbd_control response with zlp
        // since we are responding with 1 packet & less data than wLength.
        ((tusb_control_request_t *)(uintptr_t)p_request)->wLength = CFG_TUD_ENDPOINT0_SIZE;
        return tud_control_xfer(rhport, p_request, desc_device, CFG_TUD_ENDPOINT0_SIZE);
      } else {
        return tud_control_xfer(rhport, p_request, desc_device, sizeof(tusb_desc_device_t));
      }
    }
    // break; // unreachable

    case TUSB_DESC_BOS: {
      TU_LOG_USBD(" BOS\r\n");

      // requested by host if USB > 2.0 ( i.e 2.1 or 3.x )
      uintptr_t desc_bos = (uintptr_t) tud_descriptor_bos_cb();
      TU_VERIFY(desc_bos != 0);

      // Use offsetof to avoid pointer to the odd/misaligned address
      uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_bos + offsetof(tusb_desc_bos_t, wTotalLength))) );

      return tud_control_xfer(rhport, p_request, (void*) desc_bos, total_len);
    }
    // break; // unreachable

    case TUSB_DESC_CONFIGURATION:
    case TUSB_DESC_OTHER_SPEED_CONFIG: {
      uintptr_t desc_config;

      if ( desc_type == TUSB_DESC_CONFIGURATION ) {
        TU_LOG_USBD(" Configuration[%u]\r\n", desc_index);
        desc_config = (uintptr_t) tud_descriptor_configuration_cb(desc_index);
        TU_ASSERT(desc_config != 0);
      }else {
        // Host only request this after getting Device Qualifier descriptor
        TU_LOG_USBD(" Other Speed Configuration\r\n");
        desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index);
        TU_VERIFY(desc_config != 0);
      }

      // Use offsetof to avoid pointer to the odd/misaligned address
      uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_config + offsetof(tusb_desc_configuration_t, wTotalLength))) );

      return tud_control_xfer(rhport, p_request, (void*) desc_config, total_len);
    }
    // break; // unreachable

    case TUSB_DESC_STRING: {
      TU_LOG_USBD(" String[%u]\r\n", desc_index);

      // String Descriptor always uses the desc set from user
      uint8_t const* desc_str = (uint8_t const*) tud_descriptor_string_cb(desc_index, p_request->wIndex);
      TU_VERIFY(desc_str);

      // first byte of descriptor is its size
      return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_str, tu_desc_len(desc_str));
    }
    // break; // unreachable

    case TUSB_DESC_DEVICE_QUALIFIER: {
      TU_LOG_USBD(" Device Qualifier\r\n");
      uint8_t const* desc_qualifier = tud_descriptor_device_qualifier_cb();
      TU_VERIFY(desc_qualifier);
      return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_qualifier, tu_desc_len(desc_qualifier));
    }
    // break; // unreachable

    default: return false;
  }
}

//--------------------------------------------------------------------+
// DCD Event Handler
//--------------------------------------------------------------------+
TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) {
  bool send = false;
  switch (event->event_id) {
    case DCD_EVENT_UNPLUGGED:
      _usbd_dev.connected = 0;
      _usbd_dev.addressed = 0;
      _usbd_dev.cfg_num = 0;
      _usbd_dev.suspended = 0;
      send = true;
      break;

    case DCD_EVENT_SUSPEND:
      // NOTE: When plugging/unplugging device, the D+/D- state are unstable and
      // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ).
      // In addition, some MCUs such as SAMD or boards that haven no VBUS detection cannot distinguish
      // suspended vs disconnected. We will skip handling SUSPEND/RESUME event if not currently connected
      if (_usbd_dev.connected) {
        _usbd_dev.suspended = 1;
        send = true;
      }
      break;

    case DCD_EVENT_RESUME:
      // skip event if not connected (especially required for SAMD)
      if (_usbd_dev.connected) {
        _usbd_dev.suspended = 0;
        send = true;
      }
      break;

    case DCD_EVENT_SOF:
      // SOF driver handler in ISR context
      for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
        usbd_class_driver_t const* driver = get_driver(i);
        if (driver && driver->sof) {
          driver->sof(event->rhport, event->sof.frame_count);
        }
      }

      // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup
      // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational
      if (_usbd_dev.suspended) {
        _usbd_dev.suspended = 0;

        dcd_event_t const event_resume = {.rhport = event->rhport, .event_id = DCD_EVENT_RESUME};
        queue_event(&event_resume, in_isr);
      }

      if (tu_bit_test(_usbd_dev.sof_consumer, SOF_CONSUMER_USER)) {
        dcd_event_t const event_sof = {.rhport = event->rhport, .event_id = DCD_EVENT_SOF, .sof.frame_count = event->sof.frame_count};
        queue_event(&event_sof, in_isr);
      }
      break;

    case DCD_EVENT_SETUP_RECEIVED:
      _usbd_queued_setup++;
      send = true;
      break;

    case DCD_EVENT_XFER_COMPLETE: {
      // Invoke the class callback associated with the endpoint address
      uint8_t const ep_addr = event->xfer_complete.ep_addr;
      uint8_t const epnum = tu_edpt_number(ep_addr);
      uint8_t const ep_dir = tu_edpt_dir(ep_addr);

      send = true;
      if(epnum > 0) {
        usbd_class_driver_t const* driver = get_driver(_usbd_dev.ep2drv[epnum][ep_dir]);

        if (driver && driver->xfer_isr) {
          // Clear busy + claimed
          _usbd_dev.ep_status[epnum][ep_dir] &= (uint8_t) ~(TU_EDPT_STATE_BUSY | TU_EDPT_STATE_CLAIMED);

          send = !driver->xfer_isr(event->rhport, ep_addr, (xfer_result_t) event->xfer_complete.result, event->xfer_complete.len);

          // xfer_isr() is deferred to xfer_cb(), revert busy/claimed status
          if (send) {
            // set busy + claimed
            _usbd_dev.ep_status[epnum][ep_dir] |= (TU_EDPT_STATE_BUSY | TU_EDPT_STATE_CLAIMED);
          }
        }
      }
      break;
    }

    default:
      send = true;
      break;
  }

  if (send && !queue_event(event, in_isr)) {
    // event dropped by a full queue: undo state that would otherwise wedge permanently
    if (event->event_id == DCD_EVENT_SETUP_RECEIVED) {
      // undo the increment, else every later SETUP is skipped as "other SETUP in queue"
      // and EP0 is deaf until re-init
      _usbd_queued_setup--;
    } else if (event->event_id == DCD_EVENT_XFER_COMPLETE) {
      // clear busy + claimed, else the endpoint can never be claimed or re-armed again
      uint8_t const epnum = tu_edpt_number(event->xfer_complete.ep_addr);
      uint8_t const ep_dir = tu_edpt_dir(event->xfer_complete.ep_addr);
      _usbd_dev.ep_status[epnum][ep_dir] &= (uint8_t) ~(TU_EDPT_STATE_BUSY | TU_EDPT_STATE_CLAIMED);
    }
  }
}

//--------------------------------------------------------------------+
// USBD API For Class Driver
//--------------------------------------------------------------------+

void usbd_int_set(bool enabled) {
  if (enabled) {
    dcd_int_enable(_usbd_rhport);
  } else {
    dcd_int_disable(_usbd_rhport);
  }
}

void usbd_spin_lock(bool in_isr) {
  osal_spin_lock(&_usbd_spin, in_isr);
}
void usbd_spin_unlock(bool in_isr) {
  osal_spin_unlock(&_usbd_spin, in_isr);
}

// Parse consecutive endpoint descriptors (IN & OUT)
bool usbd_open_edpt_pair(uint8_t rhport, const uint8_t *p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t *ep_out,
                         uint8_t *ep_in) {
  for (int i = 0; i < ep_count; i++) {
    const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc;

    TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && xfer_type == desc_ep->bmAttributes.xfer);
    TU_ASSERT(usbd_edpt_open(rhport, desc_ep));

    if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
      (*ep_in) = desc_ep->bEndpointAddress;
    } else {
      (*ep_out) = desc_ep->bEndpointAddress;
    }

    p_desc = tu_desc_next(p_desc);
  }

  return true;
}

// Helper to defer an isr function
void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) {
  dcd_event_t event = {
      .rhport   = 0,
      .event_id = USBD_EVENT_FUNC_CALL,
  };
  event.func_call.func  = func;
  event.func_call.param = param;

  queue_event(&event, in_isr);
}

//--------------------------------------------------------------------+
// USBD Endpoint API
//--------------------------------------------------------------------+

bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) {
  rhport = _usbd_rhport;

  TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < CFG_TUD_ENDPPOINT_MAX);
  TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t)_usbd_dev.speed));

  return dcd_edpt_open(rhport, desc_ep);
}

bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr) {
  (void) rhport;

  // TODO add this check later, also make sure we don't starve an out endpoint while suspending
  // TU_VERIFY(tud_ready());

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);
  return tu_edpt_claim(&_usbd_dev.ep_status[epnum][dir], _usbd_mutex);
}

bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) {
  (void) rhport;

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);
  return tu_edpt_release(&_usbd_dev.ep_status[epnum][dir], _usbd_mutex);
}

bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes, bool is_isr) {
  rhport = _usbd_rhport;

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);

  // TODO skip ready() check for now since enumeration also use this API
  // TU_VERIFY(tud_ready());

  TU_LOG_USBD("  Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes);
#if CFG_TUD_LOG_LEVEL >= 3
  if(dir == TUSB_DIR_IN) {
    TU_LOG_MEM(CFG_TUD_LOG_LEVEL, buffer, total_bytes, 2);
  }
#endif

  // Attempt to transfer on a busy endpoint, sound like an race condition !
  TU_ASSERT((_usbd_dev.ep_status[epnum][dir] & TU_EDPT_STATE_BUSY) == 0);

  // Set busy first since the actual transfer can be complete before dcd_edpt_xfer()
  // could return and USBD task can preempt and clear the busy
  _usbd_dev.ep_status[epnum][dir] |= TU_EDPT_STATE_BUSY;

  if (dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes, is_isr)) {
    return true;
  } else {
    // DCD error, mark endpoint as ready to allow next transfer
    _usbd_dev.ep_status[epnum][dir] &= (uint8_t) ~(TU_EDPT_STATE_BUSY | TU_EDPT_STATE_CLAIMED);
    TU_LOG_USBD("FAILED\r\n");
    TU_BREAKPOINT();
    return false;
  }
}

// The number of bytes has to be given explicitly to allow more flexible control of how many
// bytes should be written and second to keep the return value free to give back a boolean
// success message. If total_bytes is too big, the FIFO will copy only what is available
// into the USB buffer!
bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes, bool is_isr) {
  #if CFG_TUD_EDPT_DEDICATED_HWFIFO
  rhport = _usbd_rhport;

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);

  TU_LOG_USBD("  Queue FIFO EP %02X with %u bytes ... ", ep_addr, total_bytes);

  // Attempt to transfer on a busy endpoint, sound like a race condition !
  TU_ASSERT((_usbd_dev.ep_status[epnum][dir] & TU_EDPT_STATE_BUSY) == 0);

  // Set busy first since the actual transfer can be complete before dcd_edpt_xfer() could return
  // and usbd task can preempt and clear the busy
  _usbd_dev.ep_status[epnum][dir] |= TU_EDPT_STATE_BUSY;

  if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes, is_isr)) {
    TU_LOG_USBD("OK\r\n");
    return true;
  } else {
    // DCD error, mark endpoint as ready to allow next transfer
    _usbd_dev.ep_status[epnum][dir] &= (uint8_t) ~(TU_EDPT_STATE_BUSY | TU_EDPT_STATE_CLAIMED);
    TU_LOG_USBD("failed\r\n");
    TU_BREAKPOINT();
    return false;
  }
  #else
  (void)rhport;
  (void)ep_addr;
  (void)ff;
  (void)total_bytes;
  (void)is_isr;
  return false;
  #endif
}

bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) {
  (void) rhport;

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);

  return (_usbd_dev.ep_status[epnum][dir] & TU_EDPT_STATE_BUSY) != 0;
}

void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
  rhport = _usbd_rhport;

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);

  // only stalled if currently cleared
  TU_LOG_USBD("    Stall EP %02X\r\n", ep_addr);
  dcd_edpt_stall(rhport, ep_addr);
  _usbd_dev.ep_status[epnum][dir] |= (TU_EDPT_STATE_STALLED | TU_EDPT_STATE_BUSY);
}

void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
  rhport = _usbd_rhport;

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);

  TU_LOG_USBD("    Clear Stall EP %02X\r\n", ep_addr);
  const bool was_stalled = (_usbd_dev.ep_status[epnum][dir] & TU_EDPT_STATE_STALLED) != 0;
  dcd_edpt_clear_stall(rhport, ep_addr);
  // Clear STALLED|BUSY unconditionally (long-standing behavior; some classes, e.g. audio's
  // set-interface, call this on a non-stalled endpoint solely to drop a leftover BUSY bit).
  // Only release the CLAIMED ownership bit when the endpoint was actually stalled: the stall
  // aborts the in-flight transfer in the dcd with no completion event to release the claim, so
  // clearing it here prevents starvation. On a non-stalled clear (e.g. a data-toggle reset) a
  // transfer may still be legitimately claimed by another task, so keep CLAIMED to preserve the
  // claim->xfer mutual exclusion.
  uint8_t clear_mask = TU_EDPT_STATE_STALLED | TU_EDPT_STATE_BUSY;
  if (was_stalled) {
    clear_mask |= TU_EDPT_STATE_CLAIMED;
  }
  _usbd_dev.ep_status[epnum][dir] &= (uint8_t) ~clear_mask;
}

bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) {
  (void) rhport;

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);

  return (_usbd_dev.ep_status[epnum][dir] & TU_EDPT_STATE_STALLED) != 0;
}

/**
 * usbd_edpt_close will disable an endpoint.
 * In progress transfers on this EP may be delivered after this call.
 */
void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
#ifdef TUP_DCD_EDPT_ISO_ALLOC
  (void) rhport; (void) ep_addr;
  // ISO alloc/activate Should be used instead
#else
  rhport = _usbd_rhport;

  TU_LOG_USBD("  CLOSING Endpoint: 0x%02X\r\n", ep_addr);

  uint8_t const epnum = tu_edpt_number(ep_addr);
  uint8_t const dir = tu_edpt_dir(ep_addr);

  dcd_edpt_close(rhport, ep_addr);
  _usbd_dev.ep_status[epnum][dir] = 0;
#endif

  return;
}

void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en) {
  rhport = _usbd_rhport;

  uint8_t consumer_old = _usbd_dev.sof_consumer;
  // Keep track how many class instances need the SOF interrupt
  if (en) {
    _usbd_dev.sof_consumer |= (uint8_t)(1 << consumer);
  } else {
    _usbd_dev.sof_consumer &= (uint8_t)(~(1 << consumer));
  }

  // Test logically unequal
  if(!_usbd_dev.sof_consumer != !consumer_old) {
    dcd_sof_enable(rhport, _usbd_dev.sof_consumer);
  }
}

bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) {
#ifdef TUP_DCD_EDPT_ISO_ALLOC
  rhport = _usbd_rhport;

  TU_ASSERT(tu_edpt_number(ep_addr) < CFG_TUD_ENDPPOINT_MAX);
  return dcd_edpt_iso_alloc(rhport, ep_addr, largest_packet_size);
#else
  (void) rhport; (void) ep_addr; (void) largest_packet_size;
  return false;
#endif
}

bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) {
#ifdef TUP_DCD_EDPT_ISO_ALLOC
  rhport = _usbd_rhport;

  uint8_t const epnum = tu_edpt_number(desc_ep->bEndpointAddress);
  uint8_t const dir = tu_edpt_dir(desc_ep->bEndpointAddress);

  TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX);
  TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t)_usbd_dev.speed));

  _usbd_dev.ep_status[epnum][dir] = 0;
  return dcd_edpt_iso_activate(rhport, desc_ep);
#else
  (void) rhport; (void) desc_ep;
  return false;
#endif
}

#endif
