libnx  v4.2.0
usbhs.h
Go to the documentation of this file.
1 /**
2  * @file usbhs.h
3  * @brief USB (usb:hs) devices service IPC wrapper.
4  * @author yellows8
5  * @copyright libnx Authors
6  */
7 #pragma once
8 #include "../types.h"
9 #include "../sf/service.h"
10 #include "../services/usb.h"
11 #include "../kernel/event.h"
12 
13 typedef enum {
14  ///< These use \ref usb_device_descriptor. Bit2..6 require [6.0.0+], these are ignored on eariler versions.
16  UsbHsInterfaceFilterFlags_idProduct = BIT(1),
17  UsbHsInterfaceFilterFlags_bcdDevice_Min = BIT(2),
18  UsbHsInterfaceFilterFlags_bcdDevice_Max = BIT(3),
19  UsbHsInterfaceFilterFlags_bDeviceClass = BIT(4),
20  UsbHsInterfaceFilterFlags_bDeviceSubClass = BIT(5),
22 
23  ///< These use \ref usb_interface_descriptor.
24  UsbHsInterfaceFilterFlags_bInterfaceClass = BIT(7),
25  UsbHsInterfaceFilterFlags_bInterfaceSubClass = BIT(8),
26  UsbHsInterfaceFilterFlags_bInterfaceProtocol = BIT(9),
28 
29 /// Interface filtering struct. When the associated flag bit is set, the associated descriptor field and struct field are compared, on mismatch the interface is filtered out.
30 /// [7.0.0+]: The filter struct has to be unique, it can't be used by anything else (including other processes). Hence, Flags has to be non-zero. When initialized with usb:hs:a and VID and/or PID filtering is enabled, the VID/PID will be checked against a blacklist.
31 typedef struct {
32  u16 Flags; ///< See \ref UsbHsInterfaceFilterFlags. Setting this to 0 is equivalent to disabling filtering.
33  u16 idVendor;
34  u16 idProduct;
35  u16 bcdDevice_Min; ///< Descriptor value must be >= bcdDevice_Min.
36  u16 bcdDevice_Max; ///< Descriptor value must be <= bcdDevice_Max.
37  u8 bDeviceClass;
38  u8 bDeviceSubClass;
39  u8 bDeviceProtocol;
40  u8 bInterfaceClass;
41  u8 bInterfaceSubClass;
42  u8 bInterfaceProtocol;
44 
45 /// Descriptors which are not available are set to all-zero.
46 /// The INPUT/OUTPUT endpoint descriptors were swapped with [8.0.0+], libnx converts this struct to the newer layout when running on pre-8.0.0.
47 typedef struct {
48  s32 ID;
49  u32 deviceID_2;
50  u32 unk_x8;
51 
52  struct usb_interface_descriptor interface_desc;
53  u8 pad_x15[0x7];
54  struct usb_endpoint_descriptor input_endpoint_descs[15];
55  u8 pad_x85[0x7];
56  struct usb_endpoint_descriptor output_endpoint_descs[15];
57  u8 pad_xf5[0x6];
58  struct usb_ss_endpoint_companion_descriptor input_ss_endpoint_companion_descs[15]; ///< ?
59  u8 pad_x155[0x6];
60  struct usb_ss_endpoint_companion_descriptor output_ss_endpoint_companion_descs[15]; ///< ?
61  u8 pad_x1b5[0x3];
63 
64 /// Interface struct. Note that devices have a seperate \ref UsbHsInterface for each interface.
65 typedef struct {
67 
68  char pathstr[0x40];
69  u32 busID;
70  u32 deviceID;
71 
72  struct usb_device_descriptor device_desc;
73  struct usb_config_descriptor config_desc;
74  u8 pad_x21b[0x5];
75 
76  u64 timestamp; ///< Unknown u64 timestamp for when the device was inserted?
78 
79 typedef struct {
80  u32 xferId;
81  Result res;
82  u32 requestedSize;
83  u32 transferredSize;
84  u64 unk_x10;
86 
87 /// The interface service object. These Events have autoclear=false.
88 typedef struct {
89  Service s;
90  Event event0; ///< Unknown.
91  Event eventCtrlXfer; ///< [2.0.0+] Signaled when CtrlXferAsync finishes.
92  s32 ID;
93 
94  UsbHsInterface inf; ///< Initialized with the input interface from \ref usbHsAcquireUsbIf, then overwritten with the cmd output. Pre-3.0.0 this only overwrites the first 0x1B8-bytes (data before pathstr).
96 
97 typedef struct {
98  Service s;
99  Event eventXfer; ///< [2.0.0+] Signaled when PostBufferAsync finishes.
100 
101  struct usb_endpoint_descriptor desc;
103 
104 /// Initialize usb:hs.
105 Result usbHsInitialize(void);
106 
107 /// Exit usb:hs.
108 void usbHsExit(void);
109 
110 /// Gets the Service object for the actual usb:hs service session.
112 
113 /// Returns the Event loaded during init with autoclear=false.
114 /// Signaled when a device was removed.
115 /// When signaled, the user should use \ref usbHsQueryAcquiredInterfaces and cleanup state for all interfaces which are not listed in the output interfaces (none of the IDs match \ref usbHsIfGetID output).
117 
118 /**
119  * @brief Returns an array of all \ref UsbHsInterface. Internally this loads the same interfaces as \ref usbHsQueryAvailableInterfaces, followed by \ref usbHsQueryAcquiredInterfaces. However, ID in \ref UsbHsInterface is set to -1, hence the output from this should not be used with \ref usbHsAcquireUsbIf.
120  * @param[in] filter \ref UsbHsInterfaceFilter.
121  * @param[out] interfaces Array of output interfaces.
122  * @param[in] interfaces_maxsize Max byte-size of the interfaces buffer.
123  * @param[out] total_entries Total number of output interfaces.
124  */
125 Result usbHsQueryAllInterfaces(const UsbHsInterfaceFilter* filter, UsbHsInterface* interfaces, size_t interfaces_maxsize, s32* total_entries);
126 
127 /**
128  * @brief Returns an array of \ref UsbHsInterface which are available.
129  * @param[in] filter \ref UsbHsInterfaceFilter.
130  * @param[out] interfaces Array of output interfaces.
131  * @param[in] interfaces_maxsize Max byte-size of the interfaces buffer.
132  * @param[out] total_entries Total number of output interfaces.
133  */
134 Result usbHsQueryAvailableInterfaces(const UsbHsInterfaceFilter* filter, UsbHsInterface* interfaces, size_t interfaces_maxsize, s32* total_entries);
135 
136 /**
137  * @brief Returns an array of \ref UsbHsInterface which were previously acquired.
138  * @param[out] interfaces Array of output interfaces.
139  * @param[in] interfaces_maxsize Max byte-size of the interfaces buffer.
140  * @param[out] total_entries Total number of output interfaces.
141  */
142 Result usbHsQueryAcquiredInterfaces(UsbHsInterface* interfaces, size_t interfaces_maxsize, s32* total_entries);
143 
144 /**
145  * @brief Creates an event which is signaled when an interface is available which passes the filtering checks.
146  * @param[out] out_event Event object.
147  * @param[in] autoclear Event autoclear.
148  * @param[in] index Event index, must be 0..2.
149  * @param[in] filter \ref UsbHsInterfaceFilter.
150  */
151 Result usbHsCreateInterfaceAvailableEvent(Event* out_event, bool autoclear, u8 index, const UsbHsInterfaceFilter* filter);
152 
153 /**
154  * @brief Destroys an event setup by \ref usbHsCreateInterfaceAvailableEvent. This *must* be used at some point during cleanup.
155  * @param[in] event Event object to close.
156  * @param[in] index Event index, must be 0..2.
157  */
159 
160 /**
161  * @brief Acquires/opens the specified interface. This returns an error if the interface was already acquired by another process.
162  * @param[in] s The service object.
163  * @param[in] interface Interface to use.
164  */
166 
167 /// UsbHsClientIfSession
168 
169 /// Closes the specified interface session.
171 
172 /// Returns whether the specified interface session was initialized.
173 static inline bool usbHsIfIsActive(UsbHsClientIfSession* s) {
174  return serviceIsActive(&s->s);
175 }
176 
177 /// Returns the ID which can be used for comparing with the ID in the output interfaces from \ref usbHsQueryAcquiredInterfaces.
179  return s->ID;
180 }
181 
182 /**
183  * @brief Selects an interface.
184  * @param[in] s The service object.
185  * @param[out] inf The output interface info. If NULL, the output is stored within s instead.
186  * @param[in] id ID
187  */
189 
190 /**
191  * @brief Gets an interface.
192  * @param[in] s The service object.
193  * @param[out] inf The output interface info. If NULL, the output is stored within s instead.
194  */
196 
197 /**
198  * @brief Gets an alternate interface.
199  * @param[in] s The service object.
200  * @param[out] inf The output interface info. If NULL, the output is stored within s instead.
201  * @param[in] id ID
202  */
204 
205 /// On [1.0.0] this is stubbed, just returns 0 with out=0.
207 
208 /// Uses a control transfer, this will block until the transfer finishes. The buffer address and size should be aligned to 0x1000-bytes, where wLength is the original size.
209 Result usbHsIfCtrlXfer(UsbHsClientIfSession* s, u8 bmRequestType, u8 bRequest, u16 wValue, u16 wIndex, u16 wLength, void* buffer, u32* transferredSize);
210 
211 /**
212  * @brief Opens an endpoint. maxUrbCount*maxXferSize must be non-zero.
213  * @param[in] s The interface object.
214  * @param[out] ep The endpoint object.
215  * @param[in] maxUrbCount maxUrbCount, must be <0x11.
216  * @param[in] maxXferSize Max transfer size for a packet. This can be desc->wMaxPacketSize. Must be <=0xFF0000.
217  * @param[in] desc Endpoint descriptor.
218  */
219 Result usbHsIfOpenUsbEp(UsbHsClientIfSession* s, UsbHsClientEpSession* ep, u16 maxUrbCount, u32 maxXferSize, struct usb_endpoint_descriptor *desc);
220 
221 /// Resets the device: has the same affect as unplugging the device and plugging it back in.
223 
224 /// UsbHsClientEpSession
225 
226 /// Closes the specified endpoint session.
228 
229 /// Uses a data transfer with the specified endpoint, this will block until the transfer finishes. The buffer address and size should be aligned to 0x1000-bytes, where the input size is the original size.
230 Result usbHsEpPostBuffer(UsbHsClientEpSession* s, void* buffer, u32 size, u32* transferredSize);
231 
usbHsIfIsActive
static bool usbHsIfIsActive(UsbHsClientIfSession *s)
Returns whether the specified interface session was initialized.
Definition: usbhs.h:173
UsbHsInterface::timestamp
u64 timestamp
Unknown u64 timestamp for when the device was inserted?
Definition: usbhs.h:76
u8
uint8_t u8
8-bit unsigned integer.
Definition: types.h:19
UsbHsInterfaceFilter::Flags
u16 Flags
See UsbHsInterfaceFilterFlags. Setting this to 0 is equivalent to disabling filtering.
Definition: usbhs.h:32
UsbHsInterfaceFilter
Interface filtering struct.
Definition: usbhs.h:31
Event
Kernel-mode event structure.
Definition: event.h:13
UsbHsInterfaceFilter::bcdDevice_Min
u16 bcdDevice_Min
Descriptor value must be >= bcdDevice_Min.
Definition: usbhs.h:35
usbHsEpClose
void usbHsEpClose(UsbHsClientEpSession *s)
UsbHsClientEpSession.
usbHsGetServiceSession
Service * usbHsGetServiceSession(void)
Gets the Service object for the actual usb:hs service session.
UsbHsInterfaceFilterFlags_bDeviceProtocol
@ UsbHsInterfaceFilterFlags_bDeviceProtocol
These use usb_interface_descriptor.
Definition: usbhs.h:21
usbHsQueryAcquiredInterfaces
Result usbHsQueryAcquiredInterfaces(UsbHsInterface *interfaces, size_t interfaces_maxsize, s32 *total_entries)
Returns an array of UsbHsInterface which were previously acquired.
usbHsIfResetDevice
Result usbHsIfResetDevice(UsbHsClientIfSession *s)
Resets the device: has the same affect as unplugging the device and plugging it back in.
UsbHsInterfaceFilterFlags
UsbHsInterfaceFilterFlags
Definition: usbhs.h:13
usbHsIfGetAlternateInterface
Result usbHsIfGetAlternateInterface(UsbHsClientIfSession *s, UsbHsInterfaceInfo *inf, u8 id)
Gets an alternate interface.
UsbHsInterfaceFilterFlags_idVendor
@ UsbHsInterfaceFilterFlags_idVendor
These use usb_device_descriptor. Bit2..6 require [6.0.0+], these are ignored on eariler versions.
Definition: usbhs.h:15
usb_endpoint_descriptor
Imported from libusb, with some adjustments.
Definition: usb.h:25
s32
int32_t s32
32-bit signed integer.
Definition: types.h:27
UsbHsXferReport
Definition: usbhs.h:79
UsbHsClientEpSession
Definition: usbhs.h:97
usbHsIfGetInterface
Result usbHsIfGetInterface(UsbHsClientIfSession *s, UsbHsInterfaceInfo *inf)
Gets an interface.
usbHsEpPostBuffer
Result usbHsEpPostBuffer(UsbHsClientEpSession *s, void *buffer, u32 size, u32 *transferredSize)
Uses a data transfer with the specified endpoint, this will block until the transfer finishes....
usb_interface_descriptor
Imported from libusb, with some adjustments.
Definition: usb.h:35
usbHsIfOpenUsbEp
Result usbHsIfOpenUsbEp(UsbHsClientIfSession *s, UsbHsClientEpSession *ep, u16 maxUrbCount, u32 maxXferSize, struct usb_endpoint_descriptor *desc)
Opens an endpoint.
UsbHsClientIfSession::inf
UsbHsInterface inf
Initialized with the input interface from usbHsAcquireUsbIf, then overwritten with the cmd output....
Definition: usbhs.h:94
u32
uint32_t u32
32-bit unsigned integer.
Definition: types.h:21
usbHsQueryAvailableInterfaces
Result usbHsQueryAvailableInterfaces(const UsbHsInterfaceFilter *filter, UsbHsInterface *interfaces, size_t interfaces_maxsize, s32 *total_entries)
Returns an array of UsbHsInterface which are available.
usb_device_descriptor
Imported from libusb, with some adjustments.
Definition: usb.h:48
UsbHsClientIfSession::eventCtrlXfer
Event eventCtrlXfer
[2.0.0+] Signaled when CtrlXferAsync finishes.
Definition: usbhs.h:91
usbHsDestroyInterfaceAvailableEvent
Result usbHsDestroyInterfaceAvailableEvent(Event *event, u8 index)
Destroys an event setup by usbHsCreateInterfaceAvailableEvent.
usbHsExit
void usbHsExit(void)
Exit usb:hs.
u64
uint64_t u64
64-bit unsigned integer.
Definition: types.h:22
usbHsAcquireUsbIf
Result usbHsAcquireUsbIf(UsbHsClientIfSession *s, UsbHsInterface *interface)
Acquires/opens the specified interface.
UsbHsClientIfSession::event0
Event event0
Unknown.
Definition: usbhs.h:90
UsbHsClientIfSession
The interface service object. These Events have autoclear=false.
Definition: usbhs.h:88
Result
u32 Result
Function error code result type.
Definition: types.h:44
usbHsInitialize
Result usbHsInitialize(void)
Initialize usb:hs.
UsbHsClientEpSession::eventXfer
Event eventXfer
[2.0.0+] Signaled when PostBufferAsync finishes.
Definition: usbhs.h:99
usbHsQueryAllInterfaces
Result usbHsQueryAllInterfaces(const UsbHsInterfaceFilter *filter, UsbHsInterface *interfaces, size_t interfaces_maxsize, s32 *total_entries)
Returns an array of all UsbHsInterface.
UsbHsInterface
Interface struct. Note that devices have a seperate UsbHsInterface for each interface.
Definition: usbhs.h:65
UsbHsInterfaceFilter::bcdDevice_Max
u16 bcdDevice_Max
Descriptor value must be <= bcdDevice_Max.
Definition: usbhs.h:36
PACKED
#define PACKED
Packs a struct so that it won't include padding bytes.
Definition: types.h:59
usbHsIfGetID
static s32 usbHsIfGetID(UsbHsClientIfSession *s)
Returns the ID which can be used for comparing with the ID in the output interfaces from usbHsQueryAc...
Definition: usbhs.h:178
usbHsIfClose
void usbHsIfClose(UsbHsClientIfSession *s)
UsbHsClientIfSession.
BIT
#define BIT(n)
Creates a bitmask from a bit number.
Definition: types.h:54
Service
Service object structure.
Definition: service.h:13
usbHsIfGetCurrentFrame
Result usbHsIfGetCurrentFrame(UsbHsClientIfSession *s, u32 *out)
On [1.0.0] this is stubbed, just returns 0 with out=0.
usbHsCreateInterfaceAvailableEvent
Result usbHsCreateInterfaceAvailableEvent(Event *out_event, bool autoclear, u8 index, const UsbHsInterfaceFilter *filter)
Creates an event which is signaled when an interface is available which passes the filtering checks.
serviceIsActive
static bool serviceIsActive(Service *s)
Returns whether a service has been initialized.
Definition: service.h:91
usbHsGetInterfaceStateChangeEvent
Event * usbHsGetInterfaceStateChangeEvent(void)
Returns the Event loaded during init with autoclear=false.
usb_ss_endpoint_companion_descriptor
Imported from libusb, with some adjustments.
Definition: usb.h:78
UsbHsInterfaceInfo
Descriptors which are not available are set to all-zero.
Definition: usbhs.h:47
u16
uint16_t u16
16-bit unsigned integer.
Definition: types.h:20
usbHsIfCtrlXfer
Result usbHsIfCtrlXfer(UsbHsClientIfSession *s, u8 bmRequestType, u8 bRequest, u16 wValue, u16 wIndex, u16 wLength, void *buffer, u32 *transferredSize)
Uses a control transfer, this will block until the transfer finishes. The buffer address and size sho...
usb_config_descriptor
Imported from libusb, with some adjustments.
Definition: usb.h:66
usbHsIfSetInterface
Result usbHsIfSetInterface(UsbHsClientIfSession *s, UsbHsInterfaceInfo *inf, u8 id)
Selects an interface.