1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /**
17  * @addtogroup USB
18  * @{
19  *
20  * @brief Declares USB-related APIs, including the custom data types and functions used to obtain descriptors,
21  *  interface objects, and request objects, and to submit requests.
22  *
23  * @since 1.0
24  * @version 1.0
25  */
26 
27 /**
28  * @file usb_ddk_interface.h
29  *
30  * @brief Declares the data types and interface functions provided by the host of the USB driver development kit (DDK).
31  *
32  * @since 1.0
33  * @version 1.0
34  */
35 #ifndef USB_INTERFACE_H
36 #define USB_INTERFACE_H
37 
38 #include "usb_session.h"
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /**
45  * @brief Defines the default ID of the USB control interface.
46  */
47 #define USB_CTRL_INTERFACE_ID   0xFF
48 
49 /**
50  * @brief Defines the request object type.
51  *
52  * It will be filled in the corresponding field in {@link UsbControlRequest}.
53  */
54 typedef enum {
55     /** USB device object */
56     USB_REQUEST_TARGET_DEVICE,
57     /** Interface object */
58     USB_REQUEST_TARGET_INTERFACE,
59     /** Endpoint object */
60     USB_REQUEST_TARGET_ENDPOINT,
61     /** Other objects */
62     USB_REQUEST_TARGET_OTHER,
63 } UsbRequestTargetType;
64 
65 /**
66  * @brief Defines the control request type.
67  *
68  * It will be filled in the corresponding field in {@link UsbControlRequest}.
69  */
70 typedef enum {
71     /** Standard request */
72     USB_REQUEST_TYPE_STANDARD,
73     /** Class request */
74     USB_REQUEST_TYPE_CLASS,
75     /** Vendor request */
76     USB_REQUEST_TYPE_VENDOR,
77 } UsbControlRequestType;
78 
79 /**
80  * @brief Defines the request data direction.
81  *
82  * It will be filled in the corresponding field in {@link UsbControlRequest} or {@link UsbRequestParamsData}.
83  */
84 typedef enum {
85     /** Data transfer from the host to the device */
86     USB_REQUEST_DIR_TO_DEVICE,
87     /** Data transfer from the device to the host */
88     USB_REQUEST_DIR_FROM_DEVICE,
89 } UsbRequestDirection;
90 
91 /**
92  * @brief Defines the request parameter type.
93  *
94  * It will be filled in the corresponding field in {@link UsbRequestParams} to indicate whether the request parameter
95  * is of the control type or data type.
96  */
97 typedef enum {
98     /** Control type */
99     USB_REQUEST_PARAMS_CTRL_TYPE,
100     /** Data type */
101     USB_REQUEST_PARAMS_DATA_TYPE,
102 } UsbRequestParamsType;
103 
104 /**
105  * @brief Defines the USB request type.
106  */
107 typedef enum {
108     /** Invalid request */
109     USB_REQUEST_TYPE_INVALID,
110     /** Control request */
111     USB_REQUEST_TYPE_DEVICE_CONTROL,
112     /** Write request */
113     USB_REQUEST_TYPE_PIPE_WRITE,
114     /** Read request */
115     USB_REQUEST_TYPE_PIPE_READ,
116 } UsbRequestPipeType;
117 
118 /**
119  * @brief Defines a USB interface operation handle.
120  */
121 typedef void *UsbInterfaceHandle;
122 
123 /**
124  * @brief Defines a USB pipe information object.
125  */
126 struct UsbPipeInfo {
127     /** Interface ID of the current pipe */
128     uint8_t interfaceId;
129     /** Pipe ID, which is used to search the specified pipe */
130     uint8_t pipeId;
131     /** Pipe address, which is used to fill the I/O request through {@link UsbRequestFill} */
132     uint8_t pipeAddress;
133     /** Pipe type */
134     UsbPipeType pipeType;
135     /** Pipe direction */
136     UsbPipeDirection pipeDirection;
137     /** Maximum size of packets received and sent over the pipe */
138     uint16_t maxPacketSize;
139     /** Interval for the host to query the pipe */
140     uint8_t interval;
141 };
142 
143 /**
144  * @brief Defines a USB pipe object.
145  */
146 struct UsbPipe {
147     /** USB basic object */
148     struct UsbObject object;
149     /** USB pipe information. For details, see {@link UsbPipeInfo}. */
150     struct UsbPipeInfo info;
151 };
152 
153 /**
154  * @brief Defines a USB interface information object.
155  */
156 struct UsbInterfaceInfo {
157     /** Interface index */
158     uint8_t interfaceIndex;
159     /** Index of the enabled interface */
160     uint8_t altSettings;
161     /** Index of the current enabled interface */
162     uint8_t curAltSetting;
163     /** Pipe quantity */
164     uint8_t pipeNum;
165     /** Interface class */
166     uint8_t interfaceClass;
167     /** Interface subclass */
168     uint8_t interfaceSubClass;
169     /** Interface protocol */
170     uint8_t interfaceProtocol;
171 };
172 
173 /**
174  * @brief Defines a USB interface object.
175  */
176 struct UsbInterface {
177     /** USB basic object */
178     struct UsbObject object;
179     /** USB interface information. For details, see {@link UsbInterfaceInfo}. */
180     struct UsbInterfaceInfo info;
181 };
182 
183 /**
184  * @brief Defines USB request completion information.
185  */
186 struct UsbRequestCompInfo {
187     /** Request pipe type. For details, see {@link UsbRequestPipeType}. */
188     UsbRequestPipeType type;
189     /** Pointer to the user data buffer */
190     unsigned char *buffer;
191     /** The address of data buffer */
192     uint32_t length;
193     /** Actual length of the data sent at request completion */
194     uint32_t actualLength;
195     /** Request status. For details, see {@link UsbRequestStatus}. */
196     UsbRequestStatus status;
197     /** Pointer to the user data */
198     void *userData;
199 };
200 
201 /**
202  * @brief Defines a USB request.
203  *
204  * There are two types of request objects: <b>UsbObject</b> (USB basic object) and <b>UsbRequestCompInfo</b>
205  * (USB request completion information ). You can query the current request execution status through the USB request
206  * completion information.
207  * The isochronous (block) request and non-isochronous (non-block) request share this data structure but use different
208  * application interfaces. The isochronous (block) request uses the <b>UsbSubmitRequestSync</b> interface,
209  * whereas the non-isochronous (non-block) request uses the <b>UsbSubmitRequestAsync</b> interface.
210  */
211 struct UsbRequest {
212     /** USB basic object */
213     struct UsbObject object;
214     /** USB request completion information. For details, see {@link UsbRequestCompInfo}. */
215     struct UsbRequestCompInfo compInfo;
216 }__attribute__((aligned(4)));
217 
218 /**
219  * @brief Defines the callback function for completion of a user request. It will be used to fill the
220  * {@link UsbRequestParams} object.
221  */
222 typedef void (*UsbRequestCallback)(struct UsbRequest *request);
223 
224 /**
225  * @brief Defines a control request object, which will be used to fill in the {@link UsbRequestParams} object.
226  */
227 struct UsbControlRequest {
228     /** Type of the received control request packet. For details, see {@link UsbRequestTargetType}. */
229     UsbRequestTargetType target;
230     /** Control request type. For details, see {@link UsbControlRequestType}. */
231     uint8_t reqType;
232     /** Request data direction. For details, see {@link UsbRequestDirection}. */
233     UsbRequestDirection directon;
234     /** Request command */
235     uint8_t request;
236     /** Value set based on the request */
237     uint16_t value;
238     /** Index set based on the request to identify an endpoint or interface */
239     uint16_t index;
240     /** Pointer to the transmitted data */
241     void *buffer;
242     /** Length of the transmitted data */
243     uint32_t length;
244 };
245 
246 /**
247  * @brief Defines data request parameters, which will be used to fill the {@link UsbRequestParams} object.
248  */
249 struct UsbRequestParamsData {
250     /** Number of transmitted data packets in isochronous transfer */
251     int32_t numIsoPackets;
252     /** Request data direction. For details, see {@link UsbRequestDirection}. */
253     UsbRequestDirection directon;
254     /** Pointer to the request data */
255     unsigned char *buffer;
256     /** Length of the request data */
257     uint32_t length;
258 };
259 
260 /**
261  * @brief Defines a USB request parameter object, which can be {@link UsbControlRequest} (control request parameter)
262  * or {@link UsbRequestParamsData} (data request parameter).
263  */
264 struct UsbRequestParams {
265     /** Interface ID */
266     uint8_t interfaceId;
267     /** Pipe ID. For details, see {@link UsbPipeInfo}. */
268     uint8_t pipeId;
269     /** Pipe address. For details, see {@link UsbPipeInfo}. */
270     uint8_t pipeAddress;
271     /** Callback function for request completion on the user side. For details, see {@link UsbRequestCallback}. */
272     UsbRequestCallback callback;
273     /** Pointer to the user data */
274     void *userData;
275     /** Request timeout interval */
276     uint32_t timeout;
277     /** Request parameter type */
278     UsbRequestParamsType requestType;
279     /** Request parameter */
280     union {
281         /** Control request parameter. For details, see {@link UsbControlRequest}. */
282         struct UsbControlRequest ctrlReq;
283         /** Data request parameter. For details, see {@link UsbRequestParamsData}. */
284         struct UsbRequestParamsData dataReq;
285     };
286 };
287 
288 /**
289  * @brief Initializes the USB DDK on the host side.
290  *
291  * You can use this function to allocate and initialize resources.
292  *
293  * @param session Indicates the double pointer to the session context. It can be set to <b>NULL</b> or a value defined
294  * in {@link UsbSession}.
295  *
296  * @return Returns <b>0</b> if the operation is successful; returns a negative value defined in {@link HDF_STATUS}
297  * otherwise.
298  */
299 int32_t UsbInitHostSdk(struct UsbSession **session);
300 
301 /**
302  * @brief Exits the USB DDK on the host side.
303  *
304  * You can use this function to release occupied resources.
305  *
306  * @param session Indicates the pointer to the session context. It can be set to <b>NULL</b> or a value defined in
307  * {@link UsbSession}.
308  *
309  * @return Returns <b>0</b> if the operation is successful; returns a negative value defined in {@link HDF_STATUS}
310  * otherwise.
311  */
312 int32_t UsbExitHostSdk(const struct UsbSession *session);
313 
314 /**
315  * @brief Obtains a USB interface object based on a specified interface index in unforce state.
316  *
317  * @param session Indicates the pointer to the session context. It can be set to <b>NULL</b> or a value defined in
318  * {@link UsbSession}.
319  * @param busNum Indicates the USB device bus number.
320  * @param usbAddr Indicates the USB device address.
321  * @param interfaceIndex Indicates the index of the interface object to be obtained. This parameter is defined in the
322  * <b>UsbInterfaceInfo</b> structure.
323  * The default index of the control interface is <b>0xFF</b>.
324  *
325  * @return Returns the pointer to the <b>UsbInterface</b> structure if the operation is successful; returns <b>NULL</b>
326  * otherwise.
327  */
328 struct UsbInterface *UsbClaimInterfaceUnforce(const struct UsbSession *session, uint8_t busNum,
329     uint8_t usbAddr, uint8_t interfaceIndex);
330 
331 /**
332  * @brief Obtains a USB interface object based on a specified interface index in force state.
333  *
334  * @param session Indicates the pointer to the session context. It can be set to <b>NULL</b> or a value defined in
335  * {@link UsbSession}.
336  * @param busNum Indicates the USB device bus number.
337  * @param usbAddr Indicates the USB device address.
338  * @param interfaceIndex Indicates the index of the interface object to be obtained. This parameter is defined in the
339  * <b>UsbInterfaceInfo</b> structure.
340  * The default index of the control interface is <b>0xFF</b>.
341  *
342  * @return Returns the pointer to the <b>UsbInterface</b> structure if the operation is successful; returns <b>NULL</b>
343  * otherwise.
344  */
345 struct UsbInterface *UsbClaimInterface(const struct UsbSession *session, uint8_t busNum,
346     uint8_t usbAddr, uint8_t interfaceIndex);
347 
348 /**
349  * @brief Obtains a USB interface object based on a specified interface index in force state.
350  *
351  * @param session Indicates the pointer to the session context. It can be set to <b>NULL</b> or a value defined in
352  * {@link UsbSession}.
353  * @param busNum Indicates the USB device bus number.
354  * @param usbAddr Indicates the USB device address.
355  * @param interfaceIndex Indicates the index of the interface object to be obtained. This parameter is defined in the
356  * <b>UsbInterfaceInfo</b> structure.
357  * The default index of the control interface is <b>0xFF</b>.
358  * @param diable Indicates the USB device manage policy.
359  * @return Returns the pointer to the <b>UsbInterface</b> structure if the operation is successful; returns <b>NULL</b>
360  * otherwise.
361  */
362 struct UsbInterface *UsbManageInterface(const struct UsbSession *session, uint8_t busNum,
363     uint8_t usbAddr, uint8_t interfaceIndex, bool disable);
364 
365 /**
366  * @brief Releases a USB interface object.
367  *
368  * @param interfaceObj Indicates the pointer to the USB interface object to release.
369  *
370  * @return Returns <b>0</b> if the operation is successful; returns a negative value defined in {@link HDF_STATUS}
371  * otherwise.
372  */
373 int32_t UsbReleaseInterface(const struct UsbInterface *interfaceObj);
374 
375 /**
376  * @brief Adds or removes an interface.
377  *
378  * @param status Indicates the interface operation status.
379  * @param interfaceObj Indicates the pointer to the USB interface object to add or remove.
380  *
381  * @return Returns <b>0</b> if the operation is successful; returns a negative value defined in {@link HDF_STATUS}
382  * otherwise.
383  */
384 int32_t UsbAddOrRemoveInterface(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr,
385     uint8_t interfaceIndex, UsbInterfaceStatus status);
386 
387 /**
388  * @brief Opens a USB interface object.
389  *
390  * @param interfaceObj Indicates the pointer to the USB interface object to open.
391  *
392  * @return Returns the pointer to the <b>UsbInterfaceHandle</b> if the operation is successful; returns <b>NULL</b>
393  * otherwise.
394  */
395 UsbInterfaceHandle *UsbOpenInterface(const struct UsbInterface *interfaceObj);
396 
397 /**
398  * @brief Closes a USB interface object.
399  *
400  * @param interfaceHandle Indicates the pointer to the handle of the USB interface object to close.
401  *
402  * @return Returns <b>0</b> if the operation is successful; returns a negative value defined in {@link HDF_STATUS}
403  * otherwise.
404  */
405 int32_t UsbCloseInterface(const UsbInterfaceHandle *interfaceHandle, bool isCtrInterface);
406 
407 /**
408  * @brief Sets the optional configuration.
409  *
410  * @param interfaceHandle Indicates the pointer to the USB interface handle.
411  * @param settingIndex Indicates the index of the optional configuration.
412  *
413  * @return Returns <b>0</b> if the operation is successful; returns a negative value defined in {@link HDF_STATUS}
414  * otherwise.
415  */
416 int32_t UsbSelectInterfaceSetting(const UsbInterfaceHandle *interfaceHandle, uint8_t settingIndex,
417     struct UsbInterface **interfaceObj);
418 
419 /**
420  * @brief Obtains pipe information from the specified optional configuration.
421  *
422  * @param interfaceHandle Indicates the pointer to the USB interface handle.
423  * @param settingIndex Indicates the index of the optional configuration.
424  * @param pipeIndex Indicates the pipe index.
425  * @param pipeInfo Indicates the pointer to the obtained pipe information.
426  *
427  */
428 int32_t UsbGetPipeInfo(const UsbInterfaceHandle *interfaceHandle, uint8_t altSettingIndex,
429     uint8_t pipeId, struct UsbPipeInfo *pipeInfo);
430 
431 /**
432  * @brief Clears the status of a specified pipe.
433  *
434  * @param interfaceHandle Indicates the pointer to the USB interface handle.
435  * @param pipeAddress Indicates the pipe address.
436  *
437  */
438 int32_t UsbClearInterfaceHalt(const UsbInterfaceHandle *interfaceHandle, uint8_t pipeAddress);
439 
440 /**
441  * @brief Allocates a USB request.
442  *
443  * I/O requests are allocated based on the size of the user space. If they are used to send isochronous transfer
444  * packets, extra space will be allocated.
445  *
446  * @param interfaceHandle Indicates the pointer to the USB interface handle.
447  * @param isoPackets Indicates the number of isochronous transfer packets. For details, see {@link UsbPipeType}.
448  * @param length Indicates the size of the user space to allocate.
449  *
450  * @return Returns the pointer to the <b>UsbRequest</b> structure if the operation is successful; returns <b>NULL</b>
451  * otherwise.
452  */
453 struct UsbRequest *UsbAllocRequest(const UsbInterfaceHandle *interfaceHandle, int32_t isoPackets, int32_t length);
454 struct UsbRequest *UsbAllocRequestByMmap(const UsbInterfaceHandle *interfaceHandle, int32_t isoPackets, int32_t length);
455 struct UsbRequest *UsbAllocRequestByAshmem(
456     const UsbInterfaceHandle *interfaceHandle, int32_t isoPackets, int32_t length, int32_t fd);
457 /**
458  * @brief Releases a request object.
459  *
460  * @param request Indicates the pointer to the USB request.
461  *
462  * @return Returns <b>0</b> if the operation is successful; returns a negative value defined in {@link HDF_STATUS}
463  * otherwise.
464  */
465 int32_t UsbFreeRequest(const struct UsbRequest *request);
466 int32_t UsbFreeRequestByMmap(const struct UsbRequest *request);
467 
468 /**
469  * @brief Sends an asynchronous request.
470  *
471  * @param request Indicates the pointer to the USB request.
472  *
473  * @return Returns <b>0</b> if the operation is successful; returns a negative value defined in {@link HDF_STATUS}
474  * otherwise.
475  */
476 int32_t UsbSubmitRequestAsync(const struct UsbRequest *const request);
477 
478 /**
479  * @brief Fills an I/O request based on specified parameters.
480  *
481  * @param request Indicates the pointer to the USB request.
482  * @param interfaceHandle Indicates the pointer to the USB interface handle.
483  * @param params Indicates the pointer to a list of parameters to fill. For details, see {@link UsbRequestParams}.
484  *
485  * @return Returns <b>0</b> if the operation is successful; returns a negative value defined in {@link HDF_STATUS}
486  * otherwise.
487  */
488 int32_t UsbFillRequest(const struct UsbRequest *request, const UsbInterfaceHandle *interfaceHandle,
489     const struct UsbRequestParams *params);
490 int32_t UsbFillRequestByMmap(
491     const struct UsbRequest *request, const UsbInterfaceHandle *interfaceHandle, const struct UsbRequestParams *params);
492 /**
493  * @brief Cancels an asynchronous USB request.
494 
495  * @param request Indicates the pointer to the USB request.
496  *
497  * @return Returns <b>UsbInterfaceHandle</b> if the operation is successful; returns <b>NULL</b> otherwise.
498  */
499 int32_t UsbCancelRequest(const struct UsbRequest *request);
500 
501 /**
502  * @brief Sends a synchronous USB request.
503  *
504  * @param request Indicates the pointer to the USB request.
505  *
506  * @return Returns <b>0</b> if the operation is successful; returns a negative value defined in {@link HDF_STATUS}
507  * otherwise.
508  */
509 int32_t UsbSubmitRequestSync(const struct UsbRequest *request);
510 int32_t UsbMemTestTrigger(bool enable);
511 int32_t GetInterfaceByHandle(const UsbInterfaceHandle *interfaceHandle, struct UsbInterface **interface);
512 int32_t UsbGetInterfaceSetting(const UsbInterfaceHandle *interfaceHandle, uint8_t *settingIndex);
513 int32_t UsbGetDeviceMemMapFd(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr);
514 bool UsbGetInterfaceActiveStatus(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr,
515     uint8_t interfaceIndex);
516 #ifdef __cplusplus
517 }
518 #endif
519 
520 #endif /* USB_INTERFACE_H */
521 /** @} */