/** * @file usbds.h * @brief USB (usb:ds) service IPC wrapper. * @brief Switch-as-device<>host USB comms, see also here: https://switchbrew.org/wiki/USB_services * @author SciresM, yellows8 * @copyright libnx Authors */ #pragma once #include "../types.h" #include "../sf/service.h" #include "../services/usb.h" #include "../kernel/event.h" #define USBDS_DEFAULT_InterfaceNumber 0x4 ///Value for usb_interface_descriptor bInterfaceNumber for automatically allocating the actual bInterfaceNumber. typedef struct { bool initialized; u8 interface_index; Service s; Event SetupEvent; Event CtrlInCompletionEvent; Event CtrlOutCompletionEvent; } UsbDsInterface; typedef struct { bool initialized; Service s; Event CompletionEvent; } UsbDsEndpoint; typedef struct { u16 idVendor; ///< VID u16 idProduct; ///< PID u16 bcdDevice; char Manufacturer[0x20]; char Product[0x20]; char SerialNumber[0x20]; } UsbDsDeviceInfo; typedef struct { u32 id; ///< urbId from post-buffer cmds u32 requestedSize; u32 transferredSize; u32 urb_status; } UsbDsReportEntry; typedef struct { UsbDsReportEntry report[8]; u32 report_count; } UsbDsReportData; typedef enum { UsbComplexId_Default = 0x2 } UsbComplexId; typedef enum { UsbDeviceSpeed_Full = 0x2, ///< USB 1.1 Full Speed UsbDeviceSpeed_High = 0x3, ///< USB 2.0 High Speed UsbDeviceSpeed_Super = 0x4, ///< USB 3.0 Super Speed } UsbDeviceSpeed; /// Opens a session with usb:ds. Result usbDsInitialize(void); /// Closes the usb:ds session. Any interfaces/endpoints which are left open are automatically closed, since otherwise usb-sysmodule won't fully reset usb:ds to defaults. void usbDsExit(void); /// Gets the Service object for the actual usb:ds service session. Service* usbDsGetServiceSession(void); /// Helper func. Result usbDsWaitReady(u64 timeout); /// Helper func. Result usbDsParseReportData(UsbDsReportData *reportdata, u32 urbId, u32 *requestedSize, u32 *transferredSize); ///@name IDsService ///@{ Event* usbDsGetStateChangeEvent(void); /// Gets the device state. See \ref UsbState. Result usbDsGetState(UsbState* out); /// Removed in [5.0.0+]. Result usbDsGetDsInterface(UsbDsInterface** out, struct usb_interface_descriptor* descriptor, const char* interface_name); /// Removed in [5.0.0+]. Result usbDsSetVidPidBcd(const UsbDsDeviceInfo* deviceinfo); /// Only available on [5.0.0+]. Result usbDsRegisterInterface(UsbDsInterface** out); /// Only available on [5.0.0+]. Result usbDsRegisterInterfaceEx(UsbDsInterface** out, u8 intf_num); /// Only available on [5.0.0+]. Result usbDsClearDeviceData(void); /// Only available on [5.0.0+]. Result usbDsAddUsbStringDescriptor(u8* out_index, const char* string); /// Only available on [5.0.0+]. Result usbDsAddUsbLanguageStringDescriptor(u8* out_index, const u16* lang_ids, u16 num_langs); /// Only available on [5.0.0+]. Result usbDsDeleteUsbStringDescriptor(u8 index); /// Only available on [5.0.0+]. Result usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed speed, struct usb_device_descriptor* descriptor); /// Only available on [5.0.0+]. Result usbDsSetBinaryObjectStore(const void* bos, size_t bos_size); /// Only available on [5.0.0+]. Result usbDsEnable(void); /// Only available on [5.0.0+]. Result usbDsDisable(void); ///@} ///@name IDsInterface ///@{ void usbDsInterface_Close(UsbDsInterface* interface); Result usbDsInterface_GetSetupPacket(UsbDsInterface* interface, void* buffer, size_t size); Result usbDsInterface_EnableInterface(UsbDsInterface* interface); Result usbDsInterface_DisableInterface(UsbDsInterface* interface); Result usbDsInterface_CtrlInPostBufferAsync(UsbDsInterface* interface, void* buffer, size_t size, u32* urbId); Result usbDsInterface_CtrlOutPostBufferAsync(UsbDsInterface* interface, void* buffer, size_t size, u32* urbId); Result usbDsInterface_GetCtrlInReportData(UsbDsInterface* interface, UsbDsReportData* out); Result usbDsInterface_GetCtrlOutReportData(UsbDsInterface* interface, UsbDsReportData* out); Result usbDsInterface_StallCtrl(UsbDsInterface* interface); /// Removed in [5.0.0+]. Result usbDsInterface_GetDsEndpoint(UsbDsInterface* interface, UsbDsEndpoint** endpoint, struct usb_endpoint_descriptor* descriptor); /// Only available on [5.0.0+]. Result usbDsInterface_RegisterEndpoint(UsbDsInterface* interface, UsbDsEndpoint** endpoint, u8 endpoint_address); /// Only available on [5.0.0+]. Result usbDsInterface_AppendConfigurationData(UsbDsInterface* interface, UsbDeviceSpeed speed, const void* buffer, size_t size); ///@} ///@name IDsEndpoint ///@{ void usbDsEndpoint_Close(UsbDsEndpoint* endpoint); Result usbDsEndpoint_Cancel(UsbDsEndpoint* endpoint); Result usbDsEndpoint_PostBufferAsync(UsbDsEndpoint* endpoint, void* buffer, size_t size, u32* urbId); Result usbDsEndpoint_GetReportData(UsbDsEndpoint* endpoint, UsbDsReportData* out); Result usbDsEndpoint_Stall(UsbDsEndpoint* endpoint); Result usbDsEndpoint_SetZlt(UsbDsEndpoint* endpoint, bool zlt); // Sets Zero Length Termination for endpoint ///@}