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<Readonly<Device>> | Queries the peripheral list. | 42e41f4b71Sopenharmony_ci| bindDevice(deviceId: number, onDisconnect: AsyncCallback<number>, callback: AsyncCallback<{deviceId: number; remote: rpc.IRemoteObject;}>): 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<number>): Promise<{deviceId: number; remote: rpc.IRemoteObject;}> | Binds a peripheral. This API uses a promise to return the result. | 44e41f4b71Sopenharmony_ci| bindDeviceDriver(deviceId: number, onDisconnect: AsyncCallback<number>, callback: AsyncCallback>RemoteDeviceDriver>): 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<number>): Promise<RemoteDeviceDriver>; | 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<number>): void | Unbinds a peripheral device. This API uses an asynchronous callback to return the result. | 47e41f4b71Sopenharmony_ci| unbindDevice(deviceId: number): Promise<number> | 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<Readonly<DeviceInfo>> | Obtains the list of detailed information about peripherals. | 57e41f4b71Sopenharmony_ci| queryDriverInfo(driverUid?: string): Array<Readonly<DriverInfo>> | 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