1# USB DDK Development
2
3## When to Use
4
5The USB Driver Development Kit (USB DDK) is a toolset that helps you develop USB device drivers at the application layer based on the user mode. It provides a series of device access APIs, for example, opening and closing USB interfaces, and performing non-isochronous transfer, isochronous transfer, control transfer, and interrupt transfer over USB pipes.
6
7## Constraints
8
9* The open APIs of the USB DDK can be used to develop drivers of non-standard USB peripherals.
10
11* The open APIs of the USB DDK can be used only within the DriverExtensionAbility lifecycle.
12
13* To use the open APIs of the USB DDK, you need to declare the matching ACL permissions in **module.json5**, for example, **ohos.permission.ACCESS_DDK_USB**.
14
15## Available APIs
16
17| Name| Description|
18| -------- | -------- |
19| OH_Usb_Init(void) | Initializes the USB DDK.|
20| OH_Usb_Release(void) | Releases the USB DDK.|
21| OH_Usb_GetDeviceDescriptor(uint64_t deviceId, struct UsbDeviceDescriptor *desc) | Obtains a device descriptor.|
22| OH_Usb_GetConfigDescriptor(uint64_t deviceId, uint8_t configIndex, struct UsbDdkConfigDescriptor **const config) | Obtains a configuration descriptor. To avoid memory leakage, use **OH_Usb_FreeConfigDescriptor()** to release a descriptor after use.|
23| OH_Usb_FreeConfigDescriptor(const struct UsbDdkConfigDescriptor *const config) | Releases a configuration descriptor. To avoid memory leakage, release a descriptor in time after use.|
24| OH_Usb_ClaimInterface(uint64_t deviceId, uint8_t interfaceIndex, uint64_t *interfaceHandle) | Declares a USB interface.|
25| OH_Usb_SelectInterfaceSetting(uint64_t interfaceHandle, uint8_t settingIndex) | Activates the alternate setting of a USB interface.|
26| OH_Usb_GetCurrentInterfaceSetting(uint64_t interfaceHandle, uint8_t \*settingIndex) | Obtains the alternate setting of a USB interface.|
27| OH_Usb_SendControlReadRequest(uint64_t interfaceHandle, const struct UsbControlRequestSetup \*setup, uint32_t timeout, uint8_t \*data, uint32_t \*dataLen) | Sends a control read transfer request. This API returns the result synchronously.|
28| OH_Usb_SendControlWriteRequest(uint64_t interfaceHandle, const struct UsbControlRequestSetup \*setup, uint32_t, const uint8_t \*data, uint32_t dataLen) | Sends a control write transfer request. This API returns the result synchronously.|
29| OH_Usb_ReleaseInterface(uint64_t interfaceHandle) | Releases a USB interface.|
30| OH_Usb_SendPipeRequest(const struct UsbRequestPipe *pipe, UsbDeviceMemMap *devMmap) | Sends a pipe request. This API returns the result synchronously. It applies to interrupt transfer and bulk transfer.|
31| OH_Usb_CreateDeviceMemMap(uint64_t deviceId, size_t size, UsbDeviceMemMap **devMmap) | Creates a buffer. To avoid resource leakage, use **OH_Usb_DestroyDeviceMemMap()** to destroy a buffer after use.|
32| OH_Usb_DestroyDeviceMemMap(UsbDeviceMemMap *devMmap) | Destroys a buffer. To avoid resource leakage, destroy a buffer in time after use.|
33
34For details about the APIs, see [USB DDK](../reference/apis-driverdevelopment-kit/_usb_ddk.md).
35
36## How to Develop
37
38To develop a USB driver using the USB DDK, perform the following steps:
39
40**Adding Dynamic Link Libraries**
41
42Add the following library to **CMakeLists.txt**:
43```txt
44libusb_ndk.z.so
45```
46
47**Including Header Files**
48```c++
49#include <usb/usb_ddk_api.h>
50#include <usb/usb_ddk_types.h>
51```
52
531. Obtains a device descriptor.
54
55    Call **OH_Usb_Init** of **usb_ddk_api.h** to initialize the USB DDK, and call **OH_Usb_GetDeviceDescriptor** to obtain the device descriptor.
56
57    ```c++
58    // Initialize the USB DDK.
59    OH_Usb_Init();
60    struct UsbDeviceDescriptor devDesc;
61    uint64_t deviceId = 0;
62    // Obtain the device descriptor.
63    OH_Usb_GetDeviceDescriptor(deviceId, &devDesc);
64    ```
65
662. Obtain a configuration descriptor, and declare the USB interface.
67
68    Call **OH_Usb_GetConfigDescriptor** of **usb_ddk_api.h** to obtain the configuration descriptor **config**, and call **OH_Usb_ClaimInterface** to declare claiming of the USB interface.
69
70    ```c++
71    struct UsbDdkConfigDescriptor *config = nullptr;
72    // Obtain the configuration descriptor.
73    OH_Usb_GetConfigDescriptor(deviceId, 1, &config);
74    // Obtain the index of the target USB interface based on the configuration descriptor.
75    uint8_t interfaceIndex = 0;
76    // Declare the USB interface.
77    uint64_t interfaceHandle = 0;
78    OH_Usb_ClaimInterface(deviceId, interfaceIndex, &interfaceHandle);
79    // Release the configuration descriptor.
80    OH_Usb_FreeConfigDescriptor(config);
81    ```
823. Obtain the activated alternate setting of a USB interface.
83
84    Call **OH_Usb_GetCurrentInterfaceSetting** of **usb_ddk_api.h** to obtain the alternate setting, and call **OH_Usb_SelectInterfaceSetting** to activate it.
85
86    ```c++
87    uint8_t settingIndex = 0;
88    // Obtain the alternate setting.
89    OH_Usb_GetCurrentInterfaceSetting(interfaceHandle, &settingIndex);
90
91    // Activate the alternate setting.
92    OH_Usb_SelectInterfaceSetting(interfaceHandle, &settingIndex);
93    ```
944. Send control read requests and control write requests.
95
96    Call **OH_Usb_SendControlReadRequest** of **usb_ddk_api.h** to send a control read request, or call **OH_Usb_SendControlWriteRequest** to send a control write request.
97
98    ```c++
99        // Timeout interval. Set it to 1s.
100    uint32_t timeout = 1000;
101
102    struct UsbControlRequestSetup setupRead;
103    setupRead.bmRequestType	= 0x80;
104    setupRead.bRequest = 0x08;
105    setupRead.wValue = 0;
106    setupRead.wIndex = 0;
107    setupRead.wLength = 0x01;
108    uint8_t dataRead[256] = {0};
109    uint32_t dataReadLen = 256;
110    // Send a control read request.
111    OH_Usb_SendControlReadRequest(interfaceHandle, &setupRead, timeout, dataRead, &dataReadLen);
112
113    struct UsbControlRequestSetup setupWrite;
114    setupWrite.bmRequestType = 0;
115    setupWrite.bRequest = 0x09;
116    setupWrite.wValue = 1;
117    setupWrite.wIndex = 0;
118    setupWrite.wLength = 0;
119    uint8_t dataWrite[256] = {0};
120    uint32_t dataWriteLen = 256;
121    // Send a control write request.
122    OH_Usb_SendControlWriteRequest(interfaceHandle, &setupWrite, timeout, dataWrite, &dataWriteLen);
123    ```
124
1255. Create a buffer, and send a request.
126
127    Call **OH_Usb_CreateDeviceMemMap** of **usb_ddk_api.h** to create the buffer **devMmap**, and call **OH_Usb_SendPipeRequest** to send a request.
128
129    ```c++
130    struct UsbDeviceMemMap *devMmap = nullptr;
131    // Create a buffer for storing data.
132    size_t bufferLen = 10;
133    OH_Usb_CreateDeviceMemMap(deviceId, bufferLen, &devMmap);
134    struct UsbRequestPipe pipe;
135    pipe.interfaceHandle = interfaceHandle;
136    // Obtain the target endpoint based on the configuration descriptor.
137    pipe.endpoint = 128;
138    pipe.timeout = UINT32_MAX;
139    // Send a request.
140    OH_Usb_SendPipeRequest(&pipe, devMmap);
141    ```
142
1436. Release resources.
144
145    After all requests are processed and before the application exits, call **OH_Usb_DestroyDeviceMemMap** of **usb_ddk_api.h** to destroy the buffer, call **OH_Usb_ReleaseInterface** to release the USB interface, , and call **OH_Usb_Release** to release the USB DDK.
146
147    ```c++
148    // Destroy the buffer.
149    OH_Usb_DestroyDeviceMemMap(devMmap);
150    // Release the USB interface.
151    OH_Usb_ReleaseInterface(interfaceHandle);
152    // Release the USB DDK.
153    OH_Usb_Release();
154    ```
155