1e41f4b71Sopenharmony_ci# Peripheral Driver Client Development
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## When to Use
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciPeripheral devices (or simply peripherals) are auxiliary devices connected to a device through physical ports, such as handwriting tablets, printers, and scanners. Applications can query and bind peripherals via peripheral management, so that the peripherals can use the customized capabilities provided by the peripheral drivers, such as the printer software.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciPeripheral management applies to all devices that can be ported to the OpenHarmony.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci## Environment Setup
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci### Development Tool and Configuration
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ciDevEco Studio, as the driver development tool, allows you to develop, debug, and package drivers.
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ciDownload and install DevEco Studio and verify basic operations to ensure that it can function properly. For details, see [Creating and Running a Project](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-create-new-project-0000001053342414-V5) in [DevEco Studio User Guide](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-tools-overview-0000001558763037-V5).
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci### SDK Version Configuration
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ciThe ArkTs APIs for peripheral management can be used only when the SDK is of API version 10 or later.
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci### HDC Configuration
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ciHarmonyOS Device Connector (HDC) is a command-line tool for debugging. It can be used to interact with real devices or emulators on Windows, Linux, and Mac. For details, see [HDC Configuration](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/hdc-V5).
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci**NOTE**<br>Configuration of the environment variable **hdc_server_port** and global environment variables is mandatory.
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci### Development Device
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ci* Currently, RK3568 is used as the device for development, debugging, and verification. For details about how to compile and burn the RK3568, see [Quick Start](https://gitee.com/openharmony/docs/blob/master/en/device-dev/quick-start/quickstart-pkg-3568-burn.md).
30e41f4b71Sopenharmony_ci* During client and driver development, you need to connect an external USB device for debugging. **Currently, only an external USB device is supported.**
31e41f4b71Sopenharmony_ci* The product ID and vendor ID of the USB device are required for defining drivers and implementing IPC.
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci## Available APIs
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ciThe following table describes the basic peripheral management capabilities. For details, see [API Reference](../../reference/apis-driverdevelopment-kit/js-apis-driver-deviceManager.md).
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci**Table 1** APIs for basic peripheral management
38e41f4b71Sopenharmony_ci
39e41f4b71Sopenharmony_ci| Name                                                                                                                                                      | Description                                                                                   |
40e41f4b71Sopenharmony_ci| -----------------------------------------------------------------------------------------------------------------------------------------------------------  | --------------------------------------------------------------------------------------- |
41e41f4b71Sopenharmony_ci| queryDevices(busType?: number): Array&lt;Readonly&lt;Device&gt;&gt;                                                                                          | Queries the peripheral list.                                                                      |
42e41f4b71Sopenharmony_ci| bindDevice(deviceId: number, onDisconnect: AsyncCallback&lt;number&gt;, callback: AsyncCallback&lt;{deviceId: number; remote: rpc.IRemoteObject;}&gt;): void | Binds a peripheral device. This API uses an asynchronous callback to return the result. If the peripheral device is bound, the **IRemoteObject** of the device driver is returned for subsequent interaction with the device driver.|
43e41f4b71Sopenharmony_ci| bindDevice(deviceId: number, onDisconnect: AsyncCallback&lt;number&gt;): Promise&lt;{deviceId: number; remote: rpc.IRemoteObject;}&gt;                       | Binds a peripheral. This API uses a promise to return the result.                                                                 |
44e41f4b71Sopenharmony_ci| bindDeviceDriver(deviceId: number, onDisconnect: AsyncCallback&lt;number&gt;, callback: AsyncCallback&gt;RemoteDeviceDriver&gt;): void;                                  | Binds a peripheral. This API uses an asynchronous callback to return the result. It is supported since API version 11.                                                                |
45e41f4b71Sopenharmony_ci| bindDeviceDriver(deviceId: number, onDisconnect: AsyncCallback&lt;number&gt;): Promise&lt;RemoteDeviceDriver&gt;;                                                        | Binds a peripheral. This API uses a promise to return the result. It is supported since API version 11.   
46e41f4b71Sopenharmony_ci| unbindDevice(deviceId: number, callback: AsyncCallback&lt;number&gt;): void                                                                                  | Unbinds a peripheral device. This API uses an asynchronous callback to return the result.                                                                             |
47e41f4b71Sopenharmony_ci| unbindDevice(deviceId: number): Promise&lt;number&gt;                                                                                                        | Unbinds a peripheral device. This API uses a promise to return the result.                                                                             |
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ci<!--Del-->
50e41f4b71Sopenharmony_ciThe following table lists the APIs for extended peripheral management. For details, see [deviceManager API Reference](../../reference/apis-driverdevelopment-kit/js-apis-driver-deviceManager-sys.md).
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ci**Table 2** APIs for extended peripheral management
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ci| Name                                                                         | Description             |
55e41f4b71Sopenharmony_ci|------------------------------------------------------------------------------|-----------------|
56e41f4b71Sopenharmony_ci| queryDeviceInfo(deviceId?: number): Array&lt;Readonly&lt;DeviceInfo&gt;&gt;  | Obtains the list of detailed information about peripherals.  |
57e41f4b71Sopenharmony_ci| queryDriverInfo(driverUid?: string): Array&lt;Readonly&lt;DriverInfo&gt;&gt; | Obtains the list of detailed information about peripheral drivers.|
58e41f4b71Sopenharmony_ci<!--DelEnd-->
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_ci## How to Develop
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ciYou can use the APIs to query and bind peripheral devices so as to use the customized driver capabilities of the peripherals.
63e41f4b71Sopenharmony_ci
64e41f4b71Sopenharmony_ciThe following sample code is a demo that illustrates how to develop both the client and server and implement IPC.
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci1. Create an OpenHarmony project. For details, see [Creating a Project] (https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-create-new-project-0000001053342414-V5).
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ci    **NOTE**
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci    > To develop a driver client, select the **Empty Ability** template.
71e41f4b71Sopenharmony_ci    >
72e41f4b71Sopenharmony_ci    > To develop the driver server, select the **Native C++** template.
73e41f4b71Sopenharmony_ci    >
74e41f4b71Sopenharmony_ci    >To develop both the driver client and server, select the **Native C++** template.
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci
77e41f4b71Sopenharmony_ci2. Import the related kit, and declare the product ID, vendor ID, and code of the USB device to be bound.
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci    **NOTE**
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci    > Write following sample code in the **entry/src/main/ets/pages/Index.ets** file.
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci    ```ts
84e41f4b71Sopenharmony_ci    import { hilog } from '@kit.PerformanceAnalysisKit';
85e41f4b71Sopenharmony_ci    import { deviceManager } from '@kit.DriverDevelopmentKit';
86e41f4b71Sopenharmony_ci    import { BusinessError } from '@kit.BasicServicesKit';
87e41f4b71Sopenharmony_ci    import { rpc } from '@kit.IPCKit';
88e41f4b71Sopenharmony_ci
89e41f4b71Sopenharmony_ci    const REQUEST_CODE: number = 99; // Custom communication code, which is for reference only.
90e41f4b71Sopenharmony_ci    const productId: number = 4258; // Declare the product ID of the connected USB device.
91e41f4b71Sopenharmony_ci    const vendorId: number = 4817; // Declare the vendor ID of the connected USB device.
92e41f4b71Sopenharmony_ci    ```
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci3. Define the **message** variable and remote object variable for communication with the driver.
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ci    **NOTE**
97e41f4b71Sopenharmony_ci
98e41f4b71Sopenharmony_ci    > The following APIs are defined in **struct Index{}**.
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci    ```ts
101e41f4b71Sopenharmony_ci    @State message: string = 'Hello';
102e41f4b71Sopenharmony_ci    private remote: rpc.IRemoteObject | null = null;
103e41f4b71Sopenharmony_ci    ```
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci4. Define the **queryDevices** API, and use it to obtain the device ID of the peripheral.
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ci    ```ts
108e41f4b71Sopenharmony_ci    private async queryTargetDeviceId(): Promise<number> {
109e41f4b71Sopenharmony_ci    try {
110e41f4b71Sopenharmony_ci      const devices: Array<deviceManager.Device> = deviceManager.queryDevices(deviceManager.BusType.USB);
111e41f4b71Sopenharmony_ci      const index = devices.findIndex((item: deviceManager.Device) => {
112e41f4b71Sopenharmony_ci        let usbDevice = item as deviceManager.USBDevice;
113e41f4b71Sopenharmony_ci        // If the product ID and vendor ID of the peripheral are unknown, you can view the information about the connected USB device in the log.
114e41f4b71Sopenharmony_ci        hilog.info(0, 'testTag', `usbDevice.productId = ${usbDevice.productId}, usbDevice.vendorId = ${usbDevice.vendorId}`);
115e41f4b71Sopenharmony_ci        return usbDevice.productId === productId && usbDevice.vendorId === vendorId;
116e41f4b71Sopenharmony_ci      });
117e41f4b71Sopenharmony_ci      if (index < 0) {
118e41f4b71Sopenharmony_ci        hilog.error(0, 'testTag', 'can not find device');
119e41f4b71Sopenharmony_ci        return -1;
120e41f4b71Sopenharmony_ci      }
121e41f4b71Sopenharmony_ci      return devices[index].deviceId;
122e41f4b71Sopenharmony_ci    } catch (error) {
123e41f4b71Sopenharmony_ci      hilog.error(0, 'testTag', `queryDevice failed, err: ${JSON.stringify(error)}`);
124e41f4b71Sopenharmony_ci    }
125e41f4b71Sopenharmony_ci    return -1;
126e41f4b71Sopenharmony_ci    }
127e41f4b71Sopenharmony_ci    ```
128e41f4b71Sopenharmony_ci
129e41f4b71Sopenharmony_ci5. Define the **bindDeviceDriver** API, and use it to obtain the remote driver object.
130e41f4b71Sopenharmony_ci
131e41f4b71Sopenharmony_ci    ```ts
132e41f4b71Sopenharmony_ci    private async getDriverRemote(deviceId: number): Promise<rpc.IRemoteObject | null> {
133e41f4b71Sopenharmony_ci    try {
134e41f4b71Sopenharmony_ci      let remoteDeviceDriver: deviceManager.RemoteDeviceDriver = await deviceManager.bindDeviceDriver(deviceId,
135e41f4b71Sopenharmony_ci        (err: BusinessError, id: number) => {
136e41f4b71Sopenharmony_ci        hilog.info(0, 'testTag', `device[${id}] id disconnect, err: ${JSON.stringify(err)}}`);
137e41f4b71Sopenharmony_ci      });
138e41f4b71Sopenharmony_ci      return remoteDeviceDriver.remote;
139e41f4b71Sopenharmony_ci    } catch (error) {
140e41f4b71Sopenharmony_ci      hilog.error(0, 'testTag', `bindDeviceDriver failed, err: ${JSON.stringify(error)}`);
141e41f4b71Sopenharmony_ci    }
142e41f4b71Sopenharmony_ci      return null;
143e41f4b71Sopenharmony_ci    }
144e41f4b71Sopenharmony_ci    ```
145e41f4b71Sopenharmony_ci
146e41f4b71Sopenharmony_ci6. Defines the **sendMessageRequest** API, and use it to perform IPC with the remote driver object.
147e41f4b71Sopenharmony_ci
148e41f4b71Sopenharmony_ci    ```ts
149e41f4b71Sopenharmony_ci    private async communicateWithRemote(): Promise<void> {
150e41f4b71Sopenharmony_ci      const deviceId: number = await this.queryTargetDeviceId();
151e41f4b71Sopenharmony_ci      if (deviceId < 0) {
152e41f4b71Sopenharmony_ci        hilog.error(0, 'testTag', 'can not find target device');
153e41f4b71Sopenharmony_ci        return;
154e41f4b71Sopenharmony_ci      }
155e41f4b71Sopenharmony_ci      this.remote = await this.getDriverRemote(deviceId);
156e41f4b71Sopenharmony_ci      if (this.remote === null) {
157e41f4b71Sopenharmony_ci        hilog.error(0, 'testTag', `getDriverRemote failed`);
158e41f4b71Sopenharmony_ci        return;
159e41f4b71Sopenharmony_ci      }
160e41f4b71Sopenharmony_ci
161e41f4b71Sopenharmony_ci      let option = new rpc.MessageOption();
162e41f4b71Sopenharmony_ci      let data = new rpc.MessageSequence();
163e41f4b71Sopenharmony_ci      let reply = new rpc.MessageSequence();
164e41f4b71Sopenharmony_ci
165e41f4b71Sopenharmony_ci      // Send "Hello" to the driver.
166e41f4b71Sopenharmony_ci      data.writeString(this.message); 
167e41f4b71Sopenharmony_ci
168e41f4b71Sopenharmony_ci      try {
169e41f4b71Sopenharmony_ci        await this.remote.sendMessageRequest(REQUEST_CODE, data, reply, option);
170e41f4b71Sopenharmony_ci        // Obtain the "Hello world" information returned by the driver.
171e41f4b71Sopenharmony_ci        this.message = reply.readString();
172e41f4b71Sopenharmony_ci        hilog.info(0, 'testTag', `sendMessageRequest, message: ${this.message}}`);
173e41f4b71Sopenharmony_ci      } catch (error) {
174e41f4b71Sopenharmony_ci        hilog.error(0, 'testTag', `sendMessageRequest failed, err: ${JSON.stringify(error)}`);
175e41f4b71Sopenharmony_ci      }
176e41f4b71Sopenharmony_ci    }
177e41f4b71Sopenharmony_ci    ```
178e41f4b71Sopenharmony_ci
179e41f4b71Sopenharmony_ci7. Render the UI. For details about UI development, see [UI Development](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/arkts-ui-development-V5).
180e41f4b71Sopenharmony_ci
181e41f4b71Sopenharmony_ci    ```ts
182e41f4b71Sopenharmony_ci    build() {
183e41f4b71Sopenharmony_ci      Row() {
184e41f4b71Sopenharmony_ci        Column() {
185e41f4b71Sopenharmony_ci          Text (this.message) // "Hello" is displayed.
186e41f4b71Sopenharmony_ci            .fontSize(60)
187e41f4b71Sopenharmony_ci            .fontWeight(FontWeight.Bold)
188e41f4b71Sopenharmony_ci            .onClick (() => { // Click Hello to communicate with the remote driver object. The message "Hello World" is displayed.
189e41f4b71Sopenharmony_ci              this.communicateWithRemote();
190e41f4b71Sopenharmony_ci            })
191e41f4b71Sopenharmony_ci        }
192e41f4b71Sopenharmony_ci        .width('100%')
193e41f4b71Sopenharmony_ci      }
194e41f4b71Sopenharmony_ci      .height('100%')
195e41f4b71Sopenharmony_ci    }
196e41f4b71Sopenharmony_ci    ```
197e41f4b71Sopenharmony_ci
198e41f4b71Sopenharmony_ci8. Develop the driver code. For details, see [Peripheral Driver Development](driverextensionability.md).
199e41f4b71Sopenharmony_ci
200e41f4b71Sopenharmony_ci<!--Del-->
201e41f4b71Sopenharmony_ciSystem applications can query detailed information about peripherals and drivers to implement management. The development procedure is as follows:
202e41f4b71Sopenharmony_ci
203e41f4b71Sopenharmony_ci1. Import the related kit.
204e41f4b71Sopenharmony_ci
205e41f4b71Sopenharmony_ci    ```ts
206e41f4b71Sopenharmony_ci     import { deviceManager } from '@kit.DriverDevelopmentKit';
207e41f4b71Sopenharmony_ci     import { BusinessError } from '@kit.BasicServicesKit';
208e41f4b71Sopenharmony_ci    ```
209e41f4b71Sopenharmony_ci
210e41f4b71Sopenharmony_ci2. Obtain the list of detailed information about peripherals.
211e41f4b71Sopenharmony_ci
212e41f4b71Sopenharmony_ci    ```ts 
213e41f4b71Sopenharmony_ci    try {
214e41f4b71Sopenharmony_ci       // For example, deviceId is 12345678. You can use queryDevices() to obtain the deviceId.
215e41f4b71Sopenharmony_ci       let deviceInfos : Array<deviceManager.DeviceInfo> = deviceManager.queryDeviceInfo(12345678);
216e41f4b71Sopenharmony_ci       for (let item of deviceInfos) {
217e41f4b71Sopenharmony_ci          console.info(`Device id is ${item.deviceId}`)
218e41f4b71Sopenharmony_ci       }
219e41f4b71Sopenharmony_ci     } catch (error) {
220e41f4b71Sopenharmony_ci       let err: BusinessError = error as BusinessError;
221e41f4b71Sopenharmony_ci       console.error(`Failed to query device info. Code is ${err.code}, message is ${err.message}`);
222e41f4b71Sopenharmony_ci     }
223e41f4b71Sopenharmony_ci    ```
224e41f4b71Sopenharmony_ci
225e41f4b71Sopenharmony_ci3. Obtains the list of detailed information about peripheral drivers.
226e41f4b71Sopenharmony_ci
227e41f4b71Sopenharmony_ci    ```ts
228e41f4b71Sopenharmony_ci    try {
229e41f4b71Sopenharmony_ci       // In this example, driver-12345 is the driver UID. During application development, you can use queryDeviceInfo to query the driver UID and use it as the input parameter.
230e41f4b71Sopenharmony_ci       let driverInfos : Array<deviceManager.DriverInfo> = deviceManager.queryDriverInfo("driver-12345");
231e41f4b71Sopenharmony_ci       for (let item of driverInfos) {
232e41f4b71Sopenharmony_ci          console.info(`driver name is ${item.driverName}`)
233e41f4b71Sopenharmony_ci       }
234e41f4b71Sopenharmony_ci    } catch (error) {
235e41f4b71Sopenharmony_ci       let err: BusinessError = error as BusinessError;
236e41f4b71Sopenharmony_ci       console.error(`Failed to query driver info. Code is ${err.code}, message is ${err.message}`);
237e41f4b71Sopenharmony_ci    }
238e41f4b71Sopenharmony_ci    ```
239e41f4b71Sopenharmony_ci<!--DelEnd-->
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ci## Application Signing
242e41f4b71Sopenharmony_ci
243e41f4b71Sopenharmony_ci**NOTE**<br>Configure the permission before enabling automatic signing.
244e41f4b71Sopenharmony_ci
245e41f4b71Sopenharmony_ciYou need to configure a signature file for your application to run on a device. Besides, to develop a peripheral driver client, you need to declare the **ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVER** permission for the peripheral.
246e41f4b71Sopenharmony_ci
247e41f4b71Sopenharmony_ciAutomatic signing: [Signing Your App/Service Automatically](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-signing-V5#section18815157237)
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ciPermission configuration: [Requesting ACL Permissions and Signing Your App/Service](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-signing-V5#section157591551175916).
250