1# GATT Development 2 3## Introduction 4Generic Attribute Profile (GATT) provides profile discovery and description services for BLE protocol. It defines how ATT attributes are organized and exchanged over a BLE connection.<br>A GATT server (referred to as server in this topic) is a device that stores attribute data locally and provides data access to a remote GATT client paired via BLE. A GATT client (referred to as client in this topic) is a device that accesses data on the remote GATT server via read, write, notify, or indicate operations. 5 6## When to Use 7 8You can use the APIs provided by the **gatt** module to: 9- Connect to the server and read and write data in the server. 10- Manage services on the server and respond to the requests from the client. 11 12## Available APIs 13 14For details about the APIs and sample code, see [@ohos.bluetooth.ble](../../reference/apis/js-apis-bluetooth-ble.md). 15 16The following table describes the related APIs. 17 18| API | Description | 19| ------------------------------------------ | ------------------------------------------------------------------------------------------------------ | 20| connect() | Connects the client to the remote BLE device. | 21| disconnect() | Disconnects the client from the remote BLE device. | 22| close() | Closes this client to unregister it from the protocol stack. After this API is called, this **GattClientDevice** instance cannot be used any longer.| 23| getDeviceName() | Obtains the name of the remote BLE device for the client. | 24| getServices() | Obtains all services of the remote BLE device for the client. | 25| readCharacteristicValue() | Reads a characteristic value of a service of the remote BLE device. | 26| readDescriptorValue() | Reads the descriptor contained in a characteristic of the remote BLE device. | 27| writeCharacteristicValue() | Writes a characteristic value to the remote BLE device. | 28| writeDescriptorValue() | Writes binary data to a descriptor of the remote BLE device. | 29| getRssiValue() | Obtains the received signal strength indication (RSSI) of the peer BLE device. This API can be used only after a connection is set up by **connect()**.| 30| setBLEMtuSize() | Sets the maximum transmission unit (MTU) that can be transmitted between the client and its peer BLE device. This API can be used only after a connection is set up by **connect()**.| 31| setCharacteristicChangeNotification() | Sets the characteristic change notification. The client will be notified when the characteristic value of the remote BLE device changes. | 32| setCharacteristicChangeIndication() | Sets the characteristic change indication. The client will be indicated when the characteristic value of the remote BLE device changes. | 33| on(type: 'BLECharacteristicChange') | Subscribes to the BLE characteristic changes. The client can receive a notification from the server only after the **setNotifyCharacteristicChanged** method is called. | 34| off(type: 'BLECharacteristicChange') | Unsubscribes from the BLE characteristic changes. | 35| on(type: 'BLEConnectionStateChange') | Subscribes to the BLE connection state changes for the client. | 36| off(type: 'BLEConnectionStateChange') | Unsubscribes from the BLE connection state changes for the client. | 37| on(type: 'BLEMtuChange') | Subscribes to MTU status changes for the client. | 38| off(type: 'BLEMtuChange') | Unsubscribes from MTU status changes for the client. | 39| addService() | Adds a service to this server. | 40| removeService() | Removes a service from this server. | 41| close() | Closes this server to unregister it from the protocol stack. After this API is called, the **GattServer** instance cannot be used any longer. | 42| notifyCharacteristicChanged() | Notifies a connected client device when a characteristic value changes. | 43| sendResponse() | Sends a response to a read or write request from the client. | 44| on(type: 'characteristicRead') | Subscribes to the characteristic read request event for the server. | 45| off(type: 'characteristicRead') | Unsubscribes from the characteristic read request event for the server. | 46| on(type: 'characteristicWrite') | Subscribes to the characteristic write request event for the server. | 47| off(type: 'characteristicWrite') | Unsubscribes from the characteristic write request event for the server. | 48| on(type: 'descriptorRead') | Subscribes to the descriptor read request event for the server. | 49| off(type: 'descriptorRead') | Unsubscribes from the descriptor read request event for the server. | 50| on(type: 'descriptorWrite') | Subscribes to the descriptor write request event for the server. | 51| off(type: 'descriptorWrite') | Unsubscribes from the descriptor write request event for the server. | 52| on(type: 'connectionStateChange') | Subscribes to the BLE connection state changes for the server. | 53| off(type: 'connectionStateChange') | Unsubscribes from the BLE connection state changes for the server. | 54| on(type: 'BLEMtuChange') | Subscribes to MTU status changes for the server. | 55| off(type: 'BLEMtuChange') | Unsubscribes from MTU status changes for the server. | 56 57## How to Develop 58 59### Reading and Writing Data in the Server 601. Import the **ble** module. 612. Create a **gattClient** instance. 623. Connect to the server. 634. Obtain the device name, services information, and RSSI of the server. 645. Read characteristics and descriptors from the server. 656. Write characteristics and descriptors to the server. 667. Disconnect from the server and close the **gattClient** instance. 67Example: 68```ts 69import ble from '@ohos.bluetooth.ble'; 70import { BusinessError } from '@ohos.base'; 71 72// serverDeviceId is the device ID of the GATT server obtained after Bluetooth scanning is started. 73let serverDeviceId = 'xx:xx:xx:xx:xx:xx'; 74 75// Create a GattClientDevice instance. 76let clientDevice = ble.createGattClientDevice(serverDeviceId); 77 78// Connect to the server. 79clientDevice.connect(); 80 81// Subscribe to connection status changes. 82clientDevice.on('BLEConnectionStateChange', (bleConnectionState) => { 83 let bleConnectionStateInfo = ''; 84 switch (bleConnectionState.state) { 85 case 0: 86 bleConnectionStateInfo = 'DISCONNECTED'; 87 break; 88 case 1: 89 bleConnectionStateInfo = 'CONNECTING'; 90 break; 91 case 2: 92 bleConnectionStateInfo = 'STATE_CONNECTED'; 93 break; 94 case 3: 95 bleConnectionStateInfo = 'STATE_DISCONNECTING'; 96 break; 97 default: 98 bleConnectionStateInfo = 'undefined'; 99 break; 100 } 101 console.info('status: ' + bleConnectionStateInfo); 102}) 103 104// Obtain the server device name. 105clientDevice.getDeviceName((err: BusinessError, data: string) => { 106 console.info('getDeviceName success, deviceName = ' + JSON.stringify(data)); 107}) 108 109// Obtain the service information of the server. 110clientDevice.getServices((code, gattServices) => { 111 let message = ''; 112 if (code != null) { 113 console.error('getServices error, errCode: ' + (code as BusinessError).code + ', errMessage: ' + (code as BusinessError).message); 114 } else { 115 for (let i = 0; i < gattServices.length; i++) { 116 message += 'serviceUuid is ' + gattServices[i].serviceUuid + '\n'; 117 } 118 console.info('getServices success, ' + message); 119 } 120}) 121 122// Obtain the RSSI. 123clientDevice.getRssiValue((err, cbRssi) => { 124 console.info('return code = ' + JSON.stringify(err) + ', RSSI = ' + JSON.stringify(cbRssi)) 125}); 126 127// Set the MTU to 256. 128clientDevice.setBLEMtuSize(256); 129 130// Read a characteristic from the server. 131// The values of the following fields are obtained from the result returned by getServices(). 132let serviceUuid = 'xxx'; 133let characteristicUuid = 'xxx'; 134let descriptorUuid = 'xxx'; 135let descriptorValue = new Uint8Array('xxx'.length).buffer; 136let characteristicValue = new Uint8Array('xxx'.length).buffer; 137let descriptors: Array<ble.BLEDescriptor> = new Array<ble.BLEDescriptor>(); 138let descriptor: ble.BLEDescriptor = { 139 serviceUuid: serviceUuid, 140 characteristicUuid: characteristicUuid, 141 descriptorUuid: descriptorUuid, 142 descriptorValue: descriptorValue 143} 144descriptors.push(descriptor); 145let bleCharacteristicDataIn: ble.BLECharacteristic = { 146 serviceUuid: serviceUuid, 147 characteristicUuid: characteristicUuid, 148 characteristicValue: characteristicValue, 149 descriptors: descriptors 150}; 151clientDevice.readCharacteristicValue(bleCharacteristicDataIn, (err, bleCharacteristicDataOut) => { 152 if (err != null) { 153 console.error('readCharacteristicValue error, code = ' + (err as BusinessError).code) 154 return; 155 } 156 let message = 'characteristic value = '; 157 let value = new Uint8Array(bleCharacteristicDataOut.characteristicValue); 158 for (let i = 0; i < bleCharacteristicDataOut.characteristicValue.byteLength; i++) { 159 message += value[i]; 160 } 161 console.info(message); 162}); 163 164// Read a descriptor. 165let descriptorIn: ble.BLEDescriptor = { 166 serviceUuid: serviceUuid, 167 characteristicUuid: characteristicUuid, 168 descriptorUuid: descriptorUuid, 169 descriptorValue: descriptorValue 170}; 171clientDevice.readDescriptorValue(descriptorIn, (err, descriptorOut) => { 172 if (err != null) { 173 console.error('readDescriptorValue error, code: ' + (err as BusinessError).code) 174 return; 175 } 176 let message = 'descriptor value: '; 177 let value = new Uint8Array(descriptorOut.descriptorValue); 178 for (let i = 0; i < descriptorOut.descriptorValue.byteLength; i++) { 179 message += value[i]; 180 } 181 console.info(message); 182}); 183 184// Write a characteristic. 185let string2ArrayBuffer: (str: string) => ArrayBuffer = (str: string): ArrayBuffer => { 186 let array = new Uint8Array(str.length); 187 for (let i = 0; i < str.length; i++) { 188 array[i] = str.charCodeAt(i); 189 } 190 return array.buffer; 191} 192 193let bufferCCC = string2ArrayBuffer('V'); 194let characteristic: ble.BLECharacteristic = { 195 serviceUuid: serviceUuid, 196 characteristicUuid: characteristicUuid, 197 characteristicValue: bufferCCC, 198 descriptors: descriptors 199}; 200clientDevice.writeCharacteristicValue(characteristic, ble.GattWriteType.WRITE); 201 202// Write a descriptor. 203let message = ''; 204if (clientDevice.writeDescriptorValue(descriptor)) { 205 message = 'writeDescriptorValue success'; 206} else { 207 message = 'writeDescriptorValue failed'; 208} 209console.info(message); 210 211// Disconnect from the server. 212clientDevice.disconnect(); 213console.info('disconnect success') 214 215// Close the GattClient instance. 216clientDevice.close(); 217console.info('close gattClientDevice success'); 218``` 219For details about the error codes, see [Bluetooth Error Codes](../../reference/errorcodes/errorcode-bluetoothManager.md). 220 221 222### Managing Services on the Server and Notifying the Client 2231. Import the **ble** module. 2242. Create a **gattServer** object. 2253. Add services. 2264. Notify the client after a characteristic is written to the server. 2275. Remove services. 2286. Close the gattServer instance. 229Example: 230```ts 231import ble from '@ohos.bluetooth.ble'; 232import { BusinessError } from '@ohos.base'; 233 234// Create a gattServer instance. 235let gattServerInstance = ble.createGattServer(); 236 237// Add services. 238let string2ArrayBuffer: (str: string) => ArrayBuffer = (str: string): ArrayBuffer => { 239 let array = new Uint8Array(str.length); 240 for (let i = 0; i < str.length; i++) { 241 array[i] = str.charCodeAt(i); 242 } 243 return array.buffer; 244} 245 246let characteristicsArray: Array<ble.BLECharacteristic> = new Array(8); 247let descriptorsArray: Array<ble.BLEDescriptor> = new Array<ble.BLEDescriptor>(); 248let characteristics1: ble.BLECharacteristic = { 249 serviceUuid: '0000aaaa-0000-1000-8000-00805f9b34fb', 250 characteristicUuid: '00002a10-0000-1000-8000-00805f9b34fb', 251 characteristicValue: string2ArrayBuffer('I am charac1'), 252 descriptors: descriptorsArray 253}; 254characteristicsArray.push(characteristics1); 255 256let descriptors1: ble.BLEDescriptor = { 257 serviceUuid: '0000aaaa-0000-1000-8000-00805f9b34fb', 258 characteristicUuid: '00002a10-0000-1000-8000-00805f9b34fb', 259 descriptorUuid: '00002904-0000-1000-8000-00805f9b34fb', 260 descriptorValue: string2ArrayBuffer('I am Server Descriptor1') 261} 262let descriptors2: ble.BLEDescriptor = { 263 serviceUuid: '0000aaaa-0000-1000-8000-00805f9b34fb', 264 characteristicUuid: '00002a10-0000-1000-8000-00805f9b34fb', 265 descriptorUuid: '00002905-0000-1000-8000-00805f9b34fb', 266 descriptorValue: string2ArrayBuffer('I am Server Descriptor2') 267} 268descriptorsArray.push(descriptors1); 269descriptorsArray.push(descriptors2); 270 271let service: ble.GattService = { 272 serviceUuid: '0000aaaa-0000-1000-8000-00805f9b34fb', 273 isPrimary: true, 274 characteristics: characteristicsArray 275}; 276gattServerInstance.addService(service); 277console.info('addService success'); 278 279// Subscribe to the characteristic write event and send a response to gattClient. 280gattServerInstance.on('characteristicWrite', (characteristicWriteReq) => { 281 let deviceId = characteristicWriteReq.deviceId; 282 let transId = characteristicWriteReq.transId; 283 let offset = characteristicWriteReq.offset; 284 let needRsp = characteristicWriteReq.needRsp; 285 let arrayBufferCCC: ArrayBuffer = string2ArrayBuffer('characteristicWriteForResponse'); 286 let serverResponse: ble.ServerResponse = { 287 deviceId: deviceId, 288 transId: transId, 289 status: 0, 290 offset: offset, 291 value: arrayBufferCCC 292 }; 293 // Send a response. 294 if (needRsp) { 295 gattServerInstance.sendResponse(serverResponse); 296 console.info('sendResponse success, response data: ' + JSON.stringify(serverResponse)); 297 } 298 // Unsubscribe from the characteristic write event. 299 gattServerInstance.off('characteristicWrite'); 300}) 301 302// Subscribe to the characteristic write event and notify the gattClient of the characteristic change. 303gattServerInstance.on('characteristicWrite', (characteristicWriteReq) => { 304 let characteristicUuid = characteristicWriteReq.characteristicUuid; 305 let serviceUuid = characteristicWriteReq.serviceUuid; 306 let deviceId = characteristicWriteReq.deviceId; 307 let notifyCharacteristic: ble.NotifyCharacteristic = { 308 serviceUuid: serviceUuid, 309 characteristicUuid: characteristicUuid, 310 characteristicValue: string2ArrayBuffer('Value4notifyCharacteristic'), 311 confirm: false 312 } 313 // Notify the connected client devices when the characteristic changes. 314 gattServerInstance.notifyCharacteristicChanged(deviceId, notifyCharacteristic); 315 console.info('notifyCharacteristicChanged success, deviceId = ' + deviceId); 316 // Unsubscribe from the characteristic write event. 317 gattServerInstance.off('characteristicWrite'); 318}) 319 320// Remove a service. 321gattServerInstance.removeService('0000aaaa-0000-1000-8000-00805f9b34fb'); 322console.info('removeService success') 323 324// Close the gattServer instance. 325gattServerInstance.close(); 326console.info('close gattServerInstance success'); 327``` 328For details about the error codes, see [Bluetooth Error Codes](../../reference/errorcodes/errorcode-bluetoothManager.md).