@react-native-ohos/react-native-ble-plx 3.5.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/LICENSE +202 -0
  2. package/README.OpenSource +11 -0
  3. package/README.md +9 -0
  4. package/app.plugin.js +1 -0
  5. package/harmony/rn_bleplx/BuildProfile.ets +9 -0
  6. package/harmony/rn_bleplx/build-profile.json5 +8 -0
  7. package/harmony/rn_bleplx/hvigorfile.ts +6 -0
  8. package/harmony/rn_bleplx/index.ets +5 -0
  9. package/harmony/rn_bleplx/obfuscation-rules.txt +18 -0
  10. package/harmony/rn_bleplx/oh-package.json5 +13 -0
  11. package/harmony/rn_bleplx/src/main/cpp/CMakeLists.txt +9 -0
  12. package/harmony/rn_bleplx/src/main/cpp/generated/BlePlx.cpp +64 -0
  13. package/harmony/rn_bleplx/src/main/cpp/generated/BlePlx.h +21 -0
  14. package/harmony/rn_bleplx/src/main/cpp/generated/BlePlxRNOHGeneratedPackage.h +76 -0
  15. package/harmony/rn_bleplx/src/main/ets/BleDevice.ts +79 -0
  16. package/harmony/rn_bleplx/src/main/ets/BleModule.ts +1208 -0
  17. package/harmony/rn_bleplx/src/main/ets/BlePlxInterface.ts +7 -0
  18. package/harmony/rn_bleplx/src/main/ets/BlePlxModule.ts +226 -0
  19. package/harmony/rn_bleplx/src/main/ets/BlePlxPackage.ts +26 -0
  20. package/harmony/rn_bleplx/src/main/ets/Characteristic.ts +159 -0
  21. package/harmony/rn_bleplx/src/main/ets/CommonConstants.ts +10 -0
  22. package/harmony/rn_bleplx/src/main/ets/Descriptor.ts +123 -0
  23. package/harmony/rn_bleplx/src/main/ets/Service.ts +65 -0
  24. package/harmony/rn_bleplx/src/main/ets/common/BleError.ts +70 -0
  25. package/harmony/rn_bleplx/src/main/ets/common/BleErrorToJsObjectConverter.ts +43 -0
  26. package/harmony/rn_bleplx/src/main/ets/common/BleEvent.ts +13 -0
  27. package/harmony/rn_bleplx/src/main/ets/common/BleUtils.ts +66 -0
  28. package/harmony/rn_bleplx/src/main/ets/common/IdGenerator.ts +29 -0
  29. package/harmony/rn_bleplx/src/main/ets/common/IdGeneratorKey.ts +50 -0
  30. package/harmony/rn_bleplx/src/main/ets/common/InstanceIdGenerator.ts +17 -0
  31. package/harmony/rn_bleplx/src/main/ets/common/Logger.ts +64 -0
  32. package/harmony/rn_bleplx/src/main/ets/common/PermissionHandler.ts +78 -0
  33. package/harmony/rn_bleplx/src/main/ets/common/ServiceFactory.ts +17 -0
  34. package/harmony/rn_bleplx/src/main/ets/generated/components/ts.ts +8 -0
  35. package/harmony/rn_bleplx/src/main/ets/generated/index.ets +8 -0
  36. package/harmony/rn_bleplx/src/main/ets/generated/ts.ts +9 -0
  37. package/harmony/rn_bleplx/src/main/ets/generated/turboModules/BlePlx.ts +105 -0
  38. package/harmony/rn_bleplx/src/main/ets/generated/turboModules/ts.ts +8 -0
  39. package/harmony/rn_bleplx/src/main/module.json5 +7 -0
  40. package/harmony/rn_bleplx/ts.ts +6 -0
  41. package/harmony/rn_bleplx.har +0 -0
  42. package/package.json +181 -0
  43. package/src/BleError.js +555 -0
  44. package/src/BleManager.js +1324 -0
  45. package/src/BleModule.js +857 -0
  46. package/src/Characteristic.js +180 -0
  47. package/src/Descriptor.js +83 -0
  48. package/src/Device.js +378 -0
  49. package/src/NativeBlePlx.ts +101 -0
  50. package/src/Service.js +204 -0
  51. package/src/TypeDefinition.js +365 -0
  52. package/src/Utils.js +29 -0
  53. package/src/index.d.ts +2126 -0
  54. package/src/index.js +20 -0
@@ -0,0 +1,1208 @@
1
+ // Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
2
+ // Use of this source code is governed by a Apache-2.0 license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import ble from '@ohos.bluetooth.ble';
6
+ import access from '@ohos.bluetooth.access';
7
+ import { BusinessError } from '@ohos.base';
8
+ import Logger from './common/Logger'
9
+ import { ValuesBucket, ValueType } from '@kit.ArkData';
10
+ import { base64ToArrayBuffer, scanResultToJsObjectConverter } from './common/BleUtils'
11
+ import { constant } from '@kit.ConnectivityKit';
12
+ import { JSON } from '@kit.ArkTS';
13
+ import { BleErrorToJsObjectConverter } from './common/BleErrorToJsObjectConverter';
14
+ import { Service } from './Service';
15
+ import { Characteristic } from './Characteristic';
16
+ import { Descriptor } from './Descriptor';
17
+ import { ServiceFactory } from './common/ServiceFactory';
18
+ import { BleDevice } from './BleDevice';
19
+ import { BleError, BleErrorCode } from './common/BleError';
20
+ import { BleEvent } from './common/BleEvent';
21
+ import { BlePlxInterface } from './BlePlxInterface'
22
+
23
+ export class BleClientManager {
24
+ // restoreIdentifierKey
25
+ private restoreIdentifierKey: string;
26
+
27
+ // 代理
28
+ public delegate: BlePlxInterface | undefined;
29
+
30
+ // 连接的设备
31
+ private connectedDevices: Map<string, BleDevice> = new Map();
32
+
33
+ // Services
34
+ private discoveredServices: Map<number, Service> = new Map();
35
+
36
+ // Characteristics
37
+ private discoveredCharacteristics: Map<number, Characteristic> = new Map();
38
+
39
+ // Descriptors
40
+ private discoveredDescriptors: Map<number, Descriptor> = new Map();
41
+
42
+ // Devices
43
+ private discoveredDevices: Map<string, ValuesBucket> = new Map();
44
+
45
+ private errorConverter: BleErrorToJsObjectConverter = new BleErrorToJsObjectConverter();
46
+
47
+ private logLevel: string;
48
+
49
+ constructor(restoreIdentifierKey: string) {
50
+ this.restoreIdentifierKey = restoreIdentifierKey;
51
+
52
+ access.on("stateChange", (state => {
53
+ this.onStateChange(state);
54
+ }))
55
+ }
56
+
57
+ public invalidate() {
58
+ this.connectedDevices.clear();
59
+ this.discoveredServices.clear();
60
+ this.discoveredCharacteristics.clear();
61
+ this.discoveredDescriptors.clear();
62
+ this.discoveredDevices.clear();
63
+ }
64
+
65
+ private dispatchEvent(name: string, value: any) {
66
+ this.delegate?.dispatchEvent(name, value);
67
+ }
68
+
69
+ public enable(transactionId: string): Promise<void> {
70
+ try {
71
+ access.enableBluetooth();
72
+ return Promise.resolve();
73
+ } catch (e) {
74
+ let bleError = new BleError(BleErrorCode.BluetoothStateChangeFailed, e.message);
75
+ return Promise.reject(this.errorConverter.toJs(bleError));
76
+ }
77
+ }
78
+
79
+ public disable(transactionId: string): Promise<void> {
80
+ try {
81
+ access.disableBluetooth();
82
+ return Promise.resolve();
83
+ } catch (e) {
84
+ let bleError = new BleError(BleErrorCode.BluetoothStateChangeFailed, e.message);
85
+ return Promise.reject(this.errorConverter.toJs(bleError));
86
+ }
87
+ }
88
+
89
+ public state(): Promise<Object> {
90
+ var result: string = 'Unknown';
91
+ let state = access.getState();
92
+ switch (state) {
93
+ case access.BluetoothState.STATE_OFF:
94
+ result = 'PoweredOff';
95
+ break;
96
+ case access.BluetoothState.STATE_ON:
97
+ case access.BluetoothState.STATE_BLE_ON:
98
+ result = 'PoweredOn';
99
+ break;
100
+ case access.BluetoothState.STATE_TURNING_ON:
101
+ case access.BluetoothState.STATE_TURNING_OFF:
102
+ case access.BluetoothState.STATE_BLE_TURNING_ON:
103
+ case access.BluetoothState.STATE_BLE_TURNING_OFF:
104
+ result = 'Resetting';
105
+ break;
106
+ }
107
+ Logger.debug('State: ' + result);
108
+ return Promise.resolve(result);
109
+ }
110
+
111
+ // Mark: Scanning ---------------------------------------------------------------------------------------------------
112
+
113
+ /**
114
+ * @description 开始蓝牙扫描
115
+ * @param filteredUUIDs: Array<string>
116
+ * @param options: Map<string, number>
117
+ */
118
+ public startDeviceScan(filteredUUIDs?: Array<string>, options?: Object): Promise<void> {
119
+ try {
120
+ // 监听发现的设备
121
+ ble.on("BLEDeviceFind", (data: Array<ble.ScanResult>) => {
122
+ let device = data[0];
123
+ let result = scanResultToJsObjectConverter(device);
124
+ this.discoveredDevices.set(device.deviceId, result);
125
+ this.dispatchEvent(BleEvent.scanEvent, [null, result]);
126
+ });
127
+
128
+ // 扫描结果过滤策略集合
129
+ let filters: Array<ble.ScanFilter> = null;
130
+ if (filteredUUIDs && filteredUUIDs.length > 0) {
131
+ filters = [];
132
+ filteredUUIDs.forEach(item => {
133
+ let scanFilter: ble.ScanFilter = {
134
+ serviceUuid: item
135
+ };
136
+ filters.push(scanFilter);
137
+ })
138
+ }
139
+
140
+ // 扫描的参数配置
141
+ let scanOptions: ble.ScanOptions = {};
142
+ if (options?.hasOwnProperty('scanMode')) {
143
+ let scanMode = options?.['scanMode']
144
+ if (scanMode == 0) {
145
+ scanOptions.dutyMode = ble.ScanDuty.SCAN_MODE_LOW_POWER;
146
+ } else if (scanMode == 1) {
147
+ scanOptions.dutyMode = ble.ScanDuty.SCAN_MODE_BALANCED;
148
+ } else if (scanMode == 2) {
149
+ scanOptions.dutyMode = ble.ScanDuty.SCAN_MODE_LOW_LATENCY;
150
+ }
151
+ }
152
+ if (options?.hasOwnProperty('interval')) {
153
+ scanOptions.interval = options?.['interval'];
154
+ }
155
+ if (options?.hasOwnProperty('matchMode')) {
156
+ let matchMode = options?.['matchMode']
157
+ if (matchMode == 1) {
158
+ scanOptions.matchMode = ble.MatchMode.MATCH_MODE_AGGRESSIVE;
159
+ } else if (matchMode == 2) {
160
+ scanOptions.matchMode = ble.MatchMode.MATCH_MODE_STICKY;
161
+ }
162
+ }
163
+ if (options?.hasOwnProperty('phyType')) {
164
+ let phyType = options?.['phyType']
165
+ if (phyType == 1) {
166
+ scanOptions.phyType = ble.PhyType.PHY_LE_1M;
167
+ } else if (phyType == 255) {
168
+ scanOptions.phyType = ble.PhyType.PHY_LE_ALL_SUPPORTED;
169
+ }
170
+ }
171
+
172
+ if (JSON.stringify(scanOptions) != '{}') {
173
+ ble.startBLEScan(filters, scanOptions);
174
+ } else {
175
+ ble.startBLEScan(filters);
176
+ }
177
+ return Promise.resolve();
178
+ } catch (err) {
179
+ let bleError = new BleError(BleErrorCode.ScanStartFailed, 'Scan start failed.', null);
180
+ this.dispatchEvent(BleEvent.scanEvent, this.errorConverter.toJs(bleError));
181
+ return Promise.reject(this.errorConverter.toJs(bleError));
182
+ }
183
+ }
184
+
185
+ /**
186
+ * @description 停止蓝牙扫描
187
+ */
188
+ public stopDeviceScan(): Promise<void> {
189
+ try {
190
+ ble.off("BLEDeviceFind");
191
+ ble.stopBLEScan();
192
+ return Promise.resolve();
193
+ } catch (err) {
194
+ Logger.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
195
+ }
196
+ }
197
+
198
+ /**
199
+ * @description Request a connection parameter update.
200
+ */
201
+ public requestConnectionPriorityForDevice(deviceIdentifier: string, connectionPriority: number,
202
+ transactionId: string): Promise<Object> {
203
+ let device = this.connectedDevices.get(deviceIdentifier);
204
+ if (!device) {
205
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
206
+ bleError.deviceID = deviceIdentifier;
207
+ return Promise.reject(this.errorConverter.toJs(bleError));
208
+ }
209
+
210
+ return Promise.resolve(device.asJSObject());
211
+ }
212
+
213
+ /**
214
+ * @description 读取RSSI
215
+ */
216
+ public readRSSIForDevice(deviceIdentifier: string, transactionId: string): Promise<Object> {
217
+ return new Promise((resolve, reject) => {
218
+ let device = this.connectedDevices.get(deviceIdentifier);
219
+ if (!device) {
220
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
221
+ bleError.deviceID = deviceIdentifier
222
+ reject(this.errorConverter.toJs(bleError));
223
+ }
224
+
225
+ device.clientDevice.getRssiValue((err: BusinessError, data: number) => {
226
+ if (err == null) {
227
+ resolve(device.asJSObject(data));
228
+ } else {
229
+ let bleError = new BleError(BleErrorCode.DeviceRSSIReadFailed, err.message, null);
230
+ bleError.deviceID = deviceIdentifier
231
+ reject(this.errorConverter.toJs(bleError));
232
+ }
233
+ })
234
+ });
235
+ }
236
+
237
+ /**
238
+ * @description 请求MTU
239
+ */
240
+ public requestMTUForDevice(deviceIdentifier: string, mtu: number, transactionId: string): Promise<Object> {
241
+ return new Promise((resolve, reject) => {
242
+ let device = this.connectedDevices.get(deviceIdentifier);
243
+ if (!device) {
244
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
245
+ bleError.deviceID = deviceIdentifier
246
+ reject(this.errorConverter.toJs(bleError));
247
+ }
248
+
249
+ try {
250
+ device.clientDevice.on('BLEMtuChange', (result) => {
251
+ device.mtu = result;
252
+ resolve(device.asJSObject());
253
+ });
254
+ device.clientDevice.setBLEMtuSize(mtu);
255
+ } catch (error) {
256
+ let bleError = new BleError(BleErrorCode.DeviceMTUChangeFailed, 'MTU change failed.', null);
257
+ bleError.deviceID = deviceIdentifier
258
+ reject(this.errorConverter.toJs(bleError));
259
+ }
260
+ });
261
+ }
262
+
263
+ // Mark: Connection Management --------------------------------------------------------------------------------------
264
+
265
+ public devices(deviceIdentifiers: Array<string>): Promise<Object[]> {
266
+ var list = Array<ValuesBucket>();
267
+ deviceIdentifiers.forEach(deviceId => {
268
+ this.discoveredDevices.forEach((value, key) => {
269
+ if (key == deviceId) {
270
+ list.push(value);
271
+ }
272
+ })
273
+ })
274
+ return Promise.resolve(list);
275
+ }
276
+
277
+ public getConnectedDevices(serviceUUIDs: Array<string>): Promise<Object[]> {
278
+ var list = Array<ValuesBucket>();
279
+ serviceUUIDs.forEach(serviceUUID => {
280
+ this.connectedDevices.forEach(device => {
281
+ let service = device.getServiceByUUID(serviceUUID);
282
+ if (service) {
283
+ list.push(device.asJSObject());
284
+ }
285
+ })
286
+ })
287
+ return Promise.resolve(list);
288
+ }
289
+
290
+ /**
291
+ * @description client端发起连接远端蓝牙低功耗设备
292
+ */
293
+ public connectToDevice(deviceIdentifier: string, options?: Map<string, ValueType>): Promise<Object> {
294
+ return new Promise((resolve, reject) => {
295
+ let device: ble.GattClientDevice = ble.createGattClientDevice(deviceIdentifier);
296
+ try {
297
+ var deviceName: string = 'Unknown';
298
+ let cacheDevice = this.discoveredDevices.get(deviceIdentifier);
299
+ if (cacheDevice) {
300
+ deviceName = cacheDevice['name'] as string;
301
+ }
302
+
303
+ let client = new BleDevice(deviceIdentifier, deviceName);
304
+ client.clientDevice = device;
305
+
306
+ device.on('BLEConnectionStateChange', (state: ble.BLEConnectionChangeState) => {
307
+ Logger.debug('state changed:' + state.state.toString());
308
+ if (state.state == constant.ProfileConnectionState.STATE_CONNECTED) {
309
+ this.connectedDevices.set(deviceIdentifier, client);
310
+ this.dispatchEvent(BleEvent.connectedEvent, deviceIdentifier);
311
+ resolve(client.asJSObject());
312
+ } else if (state.state == constant.ProfileConnectionState.STATE_CONNECTING) {
313
+ this.dispatchEvent(BleEvent.connectingEvent, deviceIdentifier);
314
+ } else if (state.state == constant.ProfileConnectionState.STATE_DISCONNECTED) {
315
+ this.dispatchEvent(BleEvent.disconnectionEvent, [null, client.asJSObject()]);
316
+ this.connectedDevices.delete(deviceIdentifier);
317
+ }
318
+ });
319
+ device.on('BLEMtuChange', (mtu: number) => {
320
+ client.mtu = mtu;
321
+ this.connectedDevices.set(deviceIdentifier, client);
322
+ })
323
+ device.connect();
324
+ this.dispatchEvent(BleEvent.connectingEvent, deviceIdentifier);
325
+ } catch (err) {
326
+ let bleError = new BleError(BleErrorCode.DeviceConnectionFailed, err.message, null);
327
+ bleError.deviceID = deviceIdentifier
328
+ reject(this.errorConverter.toJs(bleError));
329
+ }
330
+ });
331
+ }
332
+
333
+ /**
334
+ * @description client端断开与远端蓝牙低功耗设备的连接
335
+ */
336
+ public cancelDeviceConnection(deviceIdentifier: string): Promise<Object> {
337
+ return new Promise((resolve, reject) => {
338
+ let device = this.connectedDevices.get(deviceIdentifier);
339
+ if (!device) {
340
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
341
+ bleError.deviceID = deviceIdentifier
342
+ reject(this.errorConverter.toJs(bleError));
343
+ return;
344
+ }
345
+
346
+ try {
347
+ device.clientDevice.on('BLEConnectionStateChange', (state: ble.BLEConnectionChangeState) => {
348
+ if (state.state == constant.ProfileConnectionState.STATE_DISCONNECTED) {
349
+ resolve(device.asJSObject());
350
+ return;
351
+ }
352
+ });
353
+ device.clientDevice.disconnect();
354
+ } catch (err) {
355
+ let bleError = new BleError(BleErrorCode.DeviceNotConnected, err.message, null);
356
+ bleError.deviceID = deviceIdentifier
357
+ reject(this.errorConverter.toJs(bleError));
358
+ return;
359
+ }
360
+ })
361
+ }
362
+
363
+ /**
364
+ * @description 设备是否已连接
365
+ */
366
+ public isDeviceConnected(deviceIdentifier: string): Promise<boolean> {
367
+ let regex = /[A-F\d]{2}:[A-F\d]{2}:[A-F\d]{2}:[A-F\d]{2}:[A-F\d]{2}:[A-F\d]{2}/;
368
+ if (deviceIdentifier.match(regex)) {
369
+ let device = this.connectedDevices.get(deviceIdentifier);
370
+ return Promise.resolve(device == null ? false : true);
371
+ }
372
+
373
+ let bleError = new BleError(BleErrorCode.InvalidIdentifiers, null, null);
374
+ bleError.deviceID = deviceIdentifier;
375
+ bleError.internalMessage = deviceIdentifier;
376
+ return Promise.reject(this.errorConverter.toJs(bleError));
377
+ }
378
+
379
+ // Mark: Discovery --------------------------------------------------------------------------------------------------
380
+
381
+ /**
382
+ * @description 获取设备的服务和特征
383
+ */
384
+ public discoverAllServicesAndCharacteristicsForDevice(deviceIdentifier: string,
385
+ transactionId: string): Promise<Object> {
386
+ return new Promise((resolve, reject) => {
387
+ let device = this.connectedDevices.get(deviceIdentifier);
388
+ if (!device) {
389
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
390
+ bleError.deviceID = deviceIdentifier
391
+ reject(this.errorConverter.toJs(bleError));
392
+ return;
393
+ }
394
+
395
+ device.clientDevice.getServices().then(services => {
396
+ let factory = new ServiceFactory();
397
+ var newServiceList: Service[] = [];
398
+ // services
399
+ services.forEach(service => {
400
+ let newService = factory.create(deviceIdentifier, service);
401
+ this.discoveredServices.set(newService.getId(), newService);
402
+ newServiceList.push(newService);
403
+
404
+ // characteristics
405
+ newService.getCharacteristics().forEach(characteristic => {
406
+ this.discoveredCharacteristics.set(characteristic.getId(), characteristic);
407
+
408
+ // descriptors
409
+ characteristic.getDescriptors().forEach(descriptor => {
410
+ Logger.debug('serviceUuid: ' + service.serviceUuid);
411
+ Logger.debug('characteristicUuid: ' + characteristic.getUuid());
412
+ Logger.debug('descriptorUuid: ' + descriptor.getUuid());
413
+ this.discoveredDescriptors.set(descriptor.getId(), descriptor);
414
+ })
415
+ })
416
+ })
417
+ device.setServices(newServiceList);
418
+ resolve(device.asJSObject());
419
+ }).catch(err => {
420
+ let bleError = new BleError(BleErrorCode.ServicesDiscoveryFailed, err.message, null);
421
+ bleError.deviceID = deviceIdentifier;
422
+ reject(this.errorConverter.toJs(bleError));
423
+ });
424
+ });
425
+ }
426
+
427
+ // Mark: Service and characteristic getters -------------------------------------------------------------------------
428
+
429
+ /**
430
+ * @description List of discovered services for specified device.
431
+ */
432
+ public servicesForDevice(deviceIdentifier: string): Promise<Object[]> {
433
+ return new Promise((resolve, reject) => {
434
+ let device = this.connectedDevices.get(deviceIdentifier);
435
+ if (!device) {
436
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
437
+ bleError.deviceID = deviceIdentifier;
438
+ reject(this.errorConverter.toJs(bleError));
439
+ return;
440
+ }
441
+
442
+ let services = device.getServices();
443
+ var results = new Array<ValuesBucket>();
444
+ services.forEach(obj => {
445
+ results.push(obj.asJSObject());
446
+ });
447
+ resolve(results);
448
+ });
449
+ }
450
+
451
+ /**
452
+ * @description List of discovered {@link Characteristic}s for given {@link Device} and {@link Service}.
453
+ */
454
+ public characteristicsForDevice(deviceIdentifier: string,
455
+ serviceUUID: string): Promise<Object[]> {
456
+ return new Promise((resolve, reject) => {
457
+ let device = this.connectedDevices.get(deviceIdentifier);
458
+ if (!device) {
459
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
460
+ bleError.deviceID = deviceIdentifier
461
+ bleError.serviceUUID = serviceUUID
462
+ reject(this.errorConverter.toJs(bleError));
463
+ return;
464
+ }
465
+
466
+ var service = device.getServiceByUUID(serviceUUID);
467
+ if (service == null) {
468
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The service does not exist.', null);
469
+ bleError.serviceUUID = serviceUUID
470
+ reject(this.errorConverter.toJs(bleError));
471
+ return;
472
+ }
473
+
474
+ let characteristics = service.getCharacteristics();
475
+ if (characteristics == null || characteristics.length == 0) {
476
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
477
+ bleError.serviceUUID = serviceUUID
478
+ reject(this.errorConverter.toJs(bleError));
479
+ return;
480
+ }
481
+
482
+ var results = new Array<ValuesBucket>();
483
+ characteristics.forEach(obj => {
484
+ results.push(obj.asJSObject());
485
+ });
486
+ resolve(results);
487
+ });
488
+ }
489
+
490
+ public characteristicsForService(serviceIdentifier: number): Promise<Object[]> {
491
+ return new Promise((resolve, reject) => {
492
+ let service = this.discoveredServices.get(serviceIdentifier);
493
+ if (service == null) {
494
+ let bleError = new BleError(BleErrorCode.ServiceNotFound, 'The service does not exist.', null);
495
+ bleError.serviceUUID = serviceIdentifier.toString()
496
+ reject(this.errorConverter.toJs(bleError));
497
+ return;
498
+ }
499
+
500
+ let characteristics = service.getCharacteristics()
501
+ if (characteristics == null || characteristics.length == 0) {
502
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
503
+ bleError.serviceUUID = serviceIdentifier.toString()
504
+ reject(this.errorConverter.toJs(bleError));
505
+ return;
506
+ }
507
+
508
+ var results = new Array<ValuesBucket>();
509
+ characteristics.forEach(obj => {
510
+ results.push(obj.asJSObject());
511
+ });
512
+ resolve(results);
513
+ });
514
+ }
515
+
516
+ /**
517
+ * @description List of discovered {@link Descriptor}s for given {@link Device}, {@link Service} and {@link Characteristic}.
518
+ */
519
+ public descriptorsForDevice(deviceIdentifier: string,
520
+ serviceUUID: string,
521
+ characteristicUUID: string): Promise<Object[]> {
522
+ return new Promise((resolve, reject) => {
523
+ let device = this.connectedDevices.get(deviceIdentifier);
524
+ if (!device) {
525
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
526
+ bleError.deviceID = deviceIdentifier
527
+ bleError.serviceUUID = serviceUUID
528
+ bleError.characteristicUUID = characteristicUUID
529
+ reject(this.errorConverter.toJs(bleError));
530
+ return;
531
+ }
532
+
533
+ let service = device.getServiceByUUID(serviceUUID);
534
+ if (service == null) {
535
+ let bleError = new BleError(BleErrorCode.ServiceNotFound, 'The service does not exist..', null);
536
+ bleError.deviceID = deviceIdentifier
537
+ bleError.serviceUUID = serviceUUID
538
+ bleError.characteristicUUID = characteristicUUID
539
+ reject(this.errorConverter.toJs(bleError));
540
+ return;
541
+ }
542
+
543
+ let characteristic = service.getCharacteristicByUUID(characteristicUUID)
544
+ if (characteristic == null) {
545
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
546
+ bleError.deviceID = deviceIdentifier
547
+ bleError.serviceUUID = serviceUUID
548
+ bleError.characteristicUUID = characteristicUUID
549
+ reject(this.errorConverter.toJs(bleError));
550
+ return;
551
+ }
552
+
553
+ let descriptors = characteristic.getDescriptors();
554
+ var results = new Array<ValuesBucket>();
555
+ descriptors.forEach(obj => {
556
+ results.push(obj.asJSObject());
557
+ });
558
+ resolve(results);
559
+ });
560
+ }
561
+
562
+ /**
563
+ * @description List of discovered descriptors for specified service.
564
+ */
565
+ public descriptorsForService(serviceIdentifier: number, characteristicUUID: string): Promise<Object[]> {
566
+ return new Promise((resolve, reject) => {
567
+ let service = this.discoveredServices.get(serviceIdentifier);
568
+ if (service == null) {
569
+ let bleError = new BleError(BleErrorCode.ServiceNotFound, 'The service does not exist.', null);
570
+ bleError.serviceUUID = serviceIdentifier.toString()
571
+ bleError.characteristicUUID = characteristicUUID
572
+ reject(this.errorConverter.toJs(bleError));
573
+ return;
574
+ }
575
+
576
+ let characteristic = service.getCharacteristicByUUID(characteristicUUID);
577
+ if (characteristic == null) {
578
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
579
+ bleError.serviceUUID = serviceIdentifier.toString()
580
+ bleError.characteristicUUID = characteristicUUID
581
+ reject(this.errorConverter.toJs(bleError));
582
+ return;
583
+ }
584
+
585
+ let descriptors = characteristic.getDescriptors();
586
+ var results = new Array<ValuesBucket>();
587
+ descriptors.forEach(obj => {
588
+ results.push(obj.asJSObject());
589
+ });
590
+ resolve(results);
591
+ });
592
+ }
593
+
594
+ /**
595
+ * @description List of discovered descriptors for specified characteristic.
596
+ */
597
+ public descriptorsForCharacteristic(characteristicIdentifier: number): Promise<Object[]> {
598
+ return new Promise((resolve, reject) => {
599
+ let characteristic = this.discoveredCharacteristics.get(characteristicIdentifier);
600
+ if (characteristic == null) {
601
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
602
+ bleError.characteristicUUID = characteristicIdentifier.toString()
603
+ reject(this.errorConverter.toJs(bleError));
604
+ return;
605
+ }
606
+
607
+ let descriptors = characteristic.getDescriptors();
608
+ var results = new Array<ValuesBucket>();
609
+ descriptors.forEach(obj => {
610
+ results.push(obj.asJSObject());
611
+ });
612
+ resolve(results);
613
+ });
614
+ }
615
+
616
+ /**
617
+ * @description Read characteristic's value.
618
+ */
619
+ public readCharacteristicForDevice(deviceIdentifier: string,
620
+ serviceUUID: string,
621
+ characteristicUUID: string,
622
+ transactionId: string): Promise<Object> {
623
+ return new Promise((resolve, reject) => {
624
+ let device = this.connectedDevices.get(deviceIdentifier);
625
+ if (!device) {
626
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
627
+ bleError.deviceID = deviceIdentifier
628
+ bleError.serviceUUID = serviceUUID
629
+ bleError.characteristicUUID = characteristicUUID
630
+ reject(this.errorConverter.toJs(bleError));
631
+ return;
632
+ }
633
+
634
+ let characteristic =
635
+ this.getCharacteristicOrEmitErrorWithDeviceId(deviceIdentifier, serviceUUID, characteristicUUID);
636
+ if (characteristic == null) {
637
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
638
+ bleError.deviceID = deviceIdentifier
639
+ bleError.serviceUUID = serviceUUID
640
+ bleError.characteristicUUID = characteristicUUID
641
+ reject(this.errorConverter.toJs(bleError));
642
+ return;
643
+ }
644
+
645
+ device.clientDevice.readCharacteristicValue(characteristic.gattCharacteristic).then(value => {
646
+ characteristic.setValue(value.characteristicValue);
647
+ let newChar = Characteristic.constructorWithOther(characteristic);
648
+ resolve(newChar.asJSObject());
649
+ }).catch(err => {
650
+ let bleError = new BleError(BleErrorCode.CharacteristicReadFailed, err.message, null);
651
+ bleError.deviceID = deviceIdentifier
652
+ bleError.serviceUUID = serviceUUID
653
+ bleError.characteristicUUID = characteristicUUID
654
+ reject(this.errorConverter.toJs(bleError));
655
+ });
656
+ });
657
+ }
658
+
659
+ /**
660
+ * @description Read characteristic's value.
661
+ */
662
+ public readCharacteristicForService(serviceIdentifier: number,
663
+ characteristicUUID: string,
664
+ transactionId: string): Promise<Object> {
665
+ let characteristic = this.getCharacteristicOrEmitErrorWithServiceId(serviceIdentifier, characteristicUUID);
666
+ if (characteristic == null) {
667
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
668
+ bleError.serviceUUID = serviceIdentifier.toString()
669
+ bleError.characteristicUUID = characteristicUUID
670
+ return Promise.reject(this.errorConverter.toJs(bleError));
671
+ }
672
+
673
+ return this.readCharacteristicForDevice(characteristic.getDeviceId(), characteristic.getServiceUUID(),
674
+ characteristicUUID, transactionId);
675
+ }
676
+
677
+ /**
678
+ * @description Read characteristic's value.
679
+ */
680
+ public readCharacteristic(characteristicIdentifier: number,
681
+ transactionId: string): Promise<Object> {
682
+ let characteristic = this.getCharacteristicOrEmitErrorWithCharId(characteristicIdentifier)
683
+ if (characteristic == null) {
684
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
685
+ bleError.characteristicUUID = characteristicIdentifier.toString()
686
+ return Promise.reject(this.errorConverter.toJs(bleError));
687
+ }
688
+
689
+ return this.readCharacteristicForDevice(characteristic.getDeviceId(), characteristic.getServiceUUID(),
690
+ characteristic.getUuid(), transactionId);
691
+ }
692
+
693
+ // MARK: Writing ---------------------------------------------------------------------------------------------------
694
+
695
+ /**
696
+ * @description Write value to characteristic.
697
+ */
698
+ public writeCharacteristicForDevice(deviceIdentifier: string,
699
+ serviceUUID: string,
700
+ characteristicUUID: string,
701
+ valueBase64: string,
702
+ response: boolean,
703
+ transactionId: string): Promise<Object> {
704
+ return new Promise((resolve, reject) => {
705
+ let device = this.connectedDevices.get(deviceIdentifier);
706
+ if (!device) {
707
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
708
+ bleError.deviceID = deviceIdentifier
709
+ bleError.serviceUUID = serviceUUID
710
+ bleError.characteristicUUID = characteristicUUID
711
+ reject(this.errorConverter.toJs(bleError));
712
+ return;
713
+ }
714
+
715
+ let characteristic =
716
+ this.getCharacteristicOrEmitErrorWithDeviceId(deviceIdentifier, serviceUUID, characteristicUUID);
717
+ if (!characteristic) {
718
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
719
+ bleError.deviceID = deviceIdentifier
720
+ bleError.serviceUUID = serviceUUID
721
+ bleError.characteristicUUID = characteristicUUID
722
+ reject(this.errorConverter.toJs(bleError));
723
+ return;
724
+ }
725
+
726
+ let newDescriptors: Array<ble.BLEDescriptor> = [];
727
+ characteristic.gattCharacteristic.descriptors.forEach(value => {
728
+ let newDescriptor: ble.BLEDescriptor = {
729
+ serviceUuid: value.serviceUuid,
730
+ characteristicUuid: value.characteristicUuid,
731
+ descriptorUuid: value.descriptorUuid,
732
+ descriptorValue: value.descriptorValue
733
+ }
734
+ newDescriptors.push(newDescriptor);
735
+ });
736
+
737
+ let newCharacteristic: ble.BLECharacteristic = {
738
+ serviceUuid: serviceUUID,
739
+ characteristicUuid: characteristicUUID,
740
+ characteristicValue: base64ToArrayBuffer(valueBase64),
741
+ descriptors: newDescriptors
742
+ };
743
+
744
+ device.clientDevice.writeCharacteristicValue(newCharacteristic,
745
+ response ? ble.GattWriteType.WRITE : ble.GattWriteType.WRITE_NO_RESPONSE).then(value => {
746
+ Logger.debug('Write characteristic: ' + JSON.stringify(characteristic), +' value: ' + valueBase64);
747
+ characteristic.setValue(base64ToArrayBuffer(valueBase64));
748
+ let newChar = Characteristic.constructorWithOther(characteristic);
749
+ resolve(newChar.asJSObject());
750
+ }).catch(err => {
751
+ let bleError = new BleError(BleErrorCode.CharacteristicWriteFailed, err.message, null);
752
+ bleError.deviceID = deviceIdentifier
753
+ bleError.serviceUUID = serviceUUID
754
+ bleError.characteristicUUID = characteristicUUID
755
+ reject(this.errorConverter.toJs(bleError));
756
+ });
757
+ });
758
+ }
759
+
760
+ /**
761
+ * @description Write value to characteristic.
762
+ */
763
+ public writeCharacteristicForService(serviceIdentifier: number,
764
+ characteristicUUID: string,
765
+ valueBase64: string,
766
+ response: boolean,
767
+ transactionId: string): Promise<Object> {
768
+ let characteristic = this.getCharacteristicOrEmitErrorWithServiceId(serviceIdentifier, characteristicUUID);
769
+ if (characteristic == null) {
770
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
771
+ bleError.serviceUUID = serviceIdentifier.toString()
772
+ bleError.characteristicUUID = characteristicUUID
773
+ return Promise.reject(this.errorConverter.toJs(bleError));
774
+ }
775
+
776
+ return this.writeCharacteristicForDevice(characteristic.getDeviceId(), characteristic.getServiceUUID(),
777
+ characteristicUUID, valueBase64, response, transactionId);
778
+ }
779
+
780
+ /**
781
+ * @description Write value to characteristic.
782
+ */
783
+ public writeCharacteristic(characteristicIdentifier: number,
784
+ valueBase64: string,
785
+ response: boolean,
786
+ transactionId: string): Promise<Object> {
787
+ let characteristic = this.getCharacteristicOrEmitErrorWithCharId(characteristicIdentifier)
788
+ if (characteristic == null) {
789
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
790
+ bleError.characteristicUUID = characteristicIdentifier.toString()
791
+ return Promise.reject(this.errorConverter.toJs(bleError));
792
+ }
793
+
794
+ return this.writeCharacteristicForDevice(characteristic.getDeviceId(), characteristic.getServiceUUID(),
795
+ characteristic.getUuid(), valueBase64, response, transactionId);
796
+ }
797
+
798
+ /**
799
+ * @description Setup monitoring of characteristic value.
800
+ */
801
+ public monitorCharacteristicForDevice(deviceIdentifier: string,
802
+ serviceUUID: string,
803
+ characteristicUUID: string,
804
+ transactionId: string,
805
+ subscriptionType?: string): Promise<void> {
806
+ return new Promise((resolve, reject) => {
807
+ if(subscriptionType === null){subscriptionType = 'notification'};
808
+ let device = this.connectedDevices.get(deviceIdentifier);
809
+ if (!device) {
810
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
811
+ bleError.deviceID = deviceIdentifier
812
+ bleError.serviceUUID = serviceUUID
813
+ bleError.characteristicUUID = characteristicUUID
814
+ reject(this.errorConverter.toJs(bleError));
815
+ return;
816
+ }
817
+
818
+ let characteristic =
819
+ this.getCharacteristicOrEmitErrorWithDeviceId(deviceIdentifier, serviceUUID, characteristicUUID);
820
+ if (!characteristic) {
821
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
822
+ bleError.deviceID = deviceIdentifier
823
+ bleError.serviceUUID = serviceUUID
824
+ bleError.characteristicUUID = characteristicUUID
825
+ reject(this.errorConverter.toJs(bleError));
826
+ return;
827
+ }
828
+ //根据subscriptionType选择不同的操作方法
829
+ let operationPromise;
830
+ switch (subscriptionType){
831
+ case 'indication':
832
+ operationPromise = device.clientDevice.setCharacteristicChangeIndication(characteristic.gattCharacteristic, true);
833
+ break;
834
+ case 'notification':
835
+ default:
836
+ operationPromise = device.clientDevice.setCharacteristicChangeNotification(characteristic.gattCharacteristic, true);
837
+ break;
838
+ }
839
+ operationPromise.then(value => {
840
+ this.dispatchEvent(BleEvent.readEvent, [null, characteristic.asJSObject(), transactionId]);
841
+ resolve();
842
+ }).catch(err => {
843
+ let bleError = new BleError(BleErrorCode.CharacteristicNotifyChangeFailed, err.message, null);
844
+ bleError.deviceID = deviceIdentifier
845
+ bleError.serviceUUID = serviceUUID
846
+ bleError.characteristicUUID = characteristicUUID
847
+ this.dispatchEvent(BleEvent.readEvent, [this.errorConverter.toJs(bleError), null, transactionId]);
848
+ reject(this.errorConverter.toJs(bleError));
849
+ });
850
+ });
851
+ }
852
+
853
+ /**
854
+ * @description Setup monitoring of characteristic value.
855
+ */
856
+ public monitorCharacteristicForService(serviceIdentifier: number,
857
+ characteristicUUID: string,
858
+ transactionId: string,
859
+ subscriptionType?: string): Promise<void> {
860
+ let characteristic = this.getCharacteristicOrEmitErrorWithServiceId(serviceIdentifier, characteristicUUID);
861
+ if (characteristic == null) {
862
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
863
+ bleError.serviceUUID = serviceIdentifier.toString()
864
+ bleError.characteristicUUID = characteristicUUID
865
+ return Promise.reject(this.errorConverter.toJs(bleError));
866
+ }
867
+ return this.monitorCharacteristicForDevice(characteristic.getDeviceId(), characteristic.getServiceUUID(),
868
+ characteristicUUID, transactionId, subscriptionType);
869
+ }
870
+
871
+ /**
872
+ * @description Setup monitoring of characteristic value.
873
+ */
874
+ public monitorCharacteristic(characteristicIdentifier: number,
875
+ transactionId: string,
876
+ subscriptionType?: string): Promise<void> {
877
+ let characteristic = this.getCharacteristicOrEmitErrorWithCharId(characteristicIdentifier)
878
+ if (characteristic == null) {
879
+ let bleError = new BleError(BleErrorCode.CharacteristicNotFound, 'The characteristic does not exist.', null);
880
+ bleError.characteristicUUID = characteristicIdentifier.toString()
881
+ return Promise.reject(this.errorConverter.toJs(bleError));
882
+ }
883
+ return this.monitorCharacteristicForDevice(characteristic.getDeviceId(), characteristic.getServiceUUID(),
884
+ characteristic.getUuid(), transactionId, subscriptionType);
885
+ }
886
+
887
+ // Mark: Characteristics operations ---------------------------------------------------------------------------------
888
+
889
+ /**
890
+ * @description Read value to descriptor.
891
+ */
892
+ public readDescriptorForDevice(deviceId: string,
893
+ serviceUUID: string,
894
+ characteristicUUID: string,
895
+ descriptorUUID: string,
896
+ transactionId: string): Promise<Object> {
897
+ return new Promise((resolve, reject) => {
898
+ let device = this.connectedDevices.get(deviceId);
899
+ if (!device) {
900
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
901
+ bleError.deviceID = deviceId
902
+ bleError.serviceUUID = serviceUUID
903
+ bleError.characteristicUUID = characteristicUUID
904
+ bleError.descriptorUUID = descriptorUUID
905
+ reject(this.errorConverter.toJs(bleError));
906
+ return;
907
+ }
908
+
909
+ let descriptor = this.getDescriptorWithDeviceId(deviceId, serviceUUID, characteristicUUID, descriptorUUID);
910
+ if (descriptor == null) {
911
+ let bleError = new BleError(BleErrorCode.DescriptorNotFound, 'The descriptor does not exist.', null);
912
+ bleError.deviceID = deviceId
913
+ bleError.serviceUUID = serviceUUID
914
+ bleError.characteristicUUID = characteristicUUID
915
+ bleError.descriptorUUID = descriptorUUID
916
+ reject(this.errorConverter.toJs(bleError));
917
+ return;
918
+ }
919
+
920
+ device.clientDevice.readDescriptorValue(descriptor.getNativeDescriptor()).then(value => {
921
+ descriptor.setValue(value.descriptorValue);
922
+ let newDes = Descriptor.constructorWithOther(descriptor);
923
+ resolve(newDes.asJSObject());
924
+ }).catch(err => {
925
+ let bleError = new BleError(BleErrorCode.DescriptorReadFailed, err.message, null);
926
+ bleError.deviceID = deviceId
927
+ bleError.serviceUUID = serviceUUID
928
+ bleError.characteristicUUID = characteristicUUID
929
+ bleError.descriptorUUID = descriptorUUID
930
+ reject(this.errorConverter.toJs(bleError));
931
+ });
932
+ });
933
+ }
934
+
935
+ /**
936
+ * @description Read value to descriptor.
937
+ */
938
+ public readDescriptorForService(serviceIdentifier: number,
939
+ characteristicUUID: string,
940
+ descriptorUUID: string,
941
+ transactionId: string): Promise<Object> {
942
+ let descriptor = this.getDescriptorWithServiceId(serviceIdentifier, characteristicUUID, descriptorUUID);
943
+ if (descriptor == null) {
944
+ let bleError = new BleError(BleErrorCode.DescriptorNotFound, 'The descriptor does not exist.', null);
945
+ bleError.serviceUUID = serviceIdentifier.toString()
946
+ bleError.characteristicUUID = characteristicUUID
947
+ bleError.descriptorUUID = descriptorUUID
948
+ return Promise.reject(this.errorConverter.toJs(bleError));
949
+ }
950
+
951
+ return this.readDescriptorForDevice(descriptor.getDeviceId(), descriptor.getServiceUuid(), characteristicUUID,
952
+ descriptorUUID, transactionId);
953
+ }
954
+
955
+
956
+ /**
957
+ * @description Read value to descriptor.
958
+ */
959
+ public readDescriptorForCharacteristic(characteristicIdentifier: number,
960
+ descriptorUUID: string,
961
+ transactionId: string): Promise<Object> {
962
+ let descriptor = this.getDescriptorWithCharId(characteristicIdentifier, descriptorUUID);
963
+ if (descriptor == null) {
964
+ let bleError = new BleError(BleErrorCode.DescriptorNotFound, 'The descriptor does not exist.', null);
965
+ bleError.characteristicUUID = characteristicIdentifier.toString()
966
+ bleError.descriptorUUID = descriptorUUID
967
+ return Promise.reject(this.errorConverter.toJs(bleError));
968
+ }
969
+
970
+ return this.readDescriptorForDevice(descriptor.getDeviceId(), descriptor.getServiceUuid(),
971
+ descriptor.getCharacteristicUuid(), descriptorUUID, transactionId);
972
+ }
973
+
974
+ /**
975
+ * @description Read value to descriptor.
976
+ */
977
+ public readDescriptor(descriptorIdentifier: number,
978
+ transactionId: string): Promise<Object> {
979
+ let descriptor = this.discoveredDescriptors.get(descriptorIdentifier);
980
+ if (descriptor == null) {
981
+ let bleError = new BleError(BleErrorCode.DescriptorNotFound, 'The descriptor does not exist.', null);
982
+ bleError.descriptorUUID = descriptor.getUuid();
983
+ return Promise.reject(this.errorConverter.toJs(bleError));
984
+ }
985
+
986
+ return this.readDescriptorForDevice(descriptor.getDeviceId(), descriptor.getServiceUuid(),
987
+ descriptor.getCharacteristicUuid(),
988
+ descriptor.getUuid(), transactionId);
989
+ }
990
+
991
+ /**
992
+ * @description Read value to descriptor.
993
+ */
994
+ public writeDescriptorForDevice(deviceId: string,
995
+ serviceUUID: string,
996
+ characteristicUUID: string,
997
+ descriptorUUID: string,
998
+ valueBase64: string,
999
+ transactionId: string): Promise<Object> {
1000
+ return new Promise((resolve, reject) => {
1001
+ let device = this.connectedDevices.get(deviceId);
1002
+ if (!device) {
1003
+ let bleError = new BleError(BleErrorCode.DeviceNotFound, 'The device is not connected.', null);
1004
+ bleError.deviceID = deviceId
1005
+ bleError.serviceUUID = serviceUUID
1006
+ bleError.characteristicUUID = characteristicUUID
1007
+ bleError.descriptorUUID = descriptorUUID
1008
+ reject(this.errorConverter.toJs(bleError));
1009
+ return;
1010
+ }
1011
+
1012
+ let descriptor: ble.BLEDescriptor = {
1013
+ serviceUuid: serviceUUID,
1014
+ characteristicUuid: characteristicUUID,
1015
+ descriptorUuid: descriptorUUID,
1016
+ descriptorValue: base64ToArrayBuffer(valueBase64)
1017
+ }
1018
+ try {
1019
+ device.clientDevice.writeDescriptorValue(descriptor)
1020
+ let service = device?.getServiceByUUID(serviceUUID)
1021
+ let characteristic = service?.getCharacteristicByUUID(characteristicUUID)
1022
+ let newDesc = Descriptor.constructorWithNative(characteristic, descriptor)
1023
+ resolve(newDesc.asJSObject());
1024
+ } catch (err) {
1025
+ let bleError = new BleError(BleErrorCode.DescriptorWriteFailed, err.message, null);
1026
+ bleError.deviceID = deviceId
1027
+ bleError.serviceUUID = serviceUUID
1028
+ bleError.characteristicUUID = characteristicUUID
1029
+ bleError.descriptorUUID = descriptorUUID
1030
+ reject(this.errorConverter.toJs(bleError));
1031
+ };
1032
+ });
1033
+ }
1034
+
1035
+ /**
1036
+ * @description Read value to descriptor.
1037
+ */
1038
+ public writeDescriptorForService(serviceIdentifier: number,
1039
+ characteristicUUID: string,
1040
+ descriptorUUID: string,
1041
+ valueBase64: string,
1042
+ transactionId: string): Promise<Object> {
1043
+ let descriptor = this.getDescriptorWithServiceId(serviceIdentifier, characteristicUUID, descriptorUUID);
1044
+ if (descriptor == null) {
1045
+ let bleError = new BleError(BleErrorCode.DescriptorNotFound, 'The descriptor does not exist.', null);
1046
+ bleError.serviceUUID = serviceIdentifier.toString()
1047
+ bleError.characteristicUUID = characteristicUUID
1048
+ bleError.descriptorUUID = descriptorUUID
1049
+ return Promise.reject(this.errorConverter.toJs(bleError));
1050
+ }
1051
+
1052
+ return this.writeDescriptorForDevice(descriptor.getDeviceId(), descriptor.getServiceUuid(), characteristicUUID,
1053
+ descriptorUUID, valueBase64, transactionId);
1054
+ }
1055
+
1056
+ /**
1057
+ * @description Read value to descriptor.
1058
+ */
1059
+ public writeDescriptorForCharacteristic(characteristicIdentifier: number,
1060
+ descriptorUUID: string,
1061
+ valueBase64: string,
1062
+ transactionId: string): Promise<Object> {
1063
+ let descriptor = this.getDescriptorWithCharId(characteristicIdentifier, descriptorUUID);
1064
+ if (descriptor == null) {
1065
+ let bleError = new BleError(BleErrorCode.DescriptorNotFound, 'The descriptor does not exist.', null);
1066
+ bleError.characteristicUUID = characteristicIdentifier.toString()
1067
+ bleError.descriptorUUID = descriptorUUID
1068
+ return Promise.reject(this.errorConverter.toJs(bleError));
1069
+ }
1070
+
1071
+ return this.writeDescriptorForDevice(descriptor.getDeviceId(), descriptor.getServiceUuid(),
1072
+ descriptor.getCharacteristicUuid(), descriptorUUID, valueBase64, transactionId);
1073
+ }
1074
+
1075
+ /**
1076
+ * @description Read value to descriptor.
1077
+ */
1078
+ public writeDescriptor(descriptorIdentifier: number,
1079
+ valueBase64: string,
1080
+ transactionId: string): Promise<Object> {
1081
+ let descriptor = this.discoveredDescriptors.get(descriptorIdentifier);
1082
+ if (descriptor == null) {
1083
+ let bleError = new BleError(BleErrorCode.DescriptorNotFound, 'The descriptor does not exist.', null);
1084
+ bleError.descriptorUUID = descriptorIdentifier.toString()
1085
+ return Promise.reject(this.errorConverter.toJs(bleError));
1086
+ }
1087
+
1088
+ return this.writeDescriptorForDevice(descriptor.getDeviceId(), descriptor.getServiceUuid(),
1089
+ descriptor.getCharacteristicUuid(), descriptor.getUuid(), valueBase64, transactionId);
1090
+ }
1091
+
1092
+ public cancelTransaction(transactionId: string): Promise<void> {
1093
+ let bleError = new BleError(BleErrorCode.UnknownError, null, null);
1094
+ return Promise.reject(this.errorConverter.toJs(bleError));
1095
+ }
1096
+
1097
+ public setLogLevel(logLevel: string): Promise<string> {
1098
+ this.logLevel = logLevel;
1099
+ return this.getLogLevel();
1100
+ }
1101
+
1102
+ public getLogLevel(): Promise<string> {
1103
+ return Promise.resolve(this.logLevel);
1104
+ }
1105
+
1106
+ // Mark: Tools (Private) ------------------------------------------------------------------------------------
1107
+
1108
+ private onStateChange(state: access.BluetoothState) {
1109
+ this.state().then(value => {
1110
+ this.dispatchEvent(BleEvent.stateChangeEvent, value);
1111
+ });
1112
+ }
1113
+
1114
+ private getCharacteristicOrEmitErrorWithCharId(characteristicIdentifier: number): Characteristic | null {
1115
+ let characteristic = this.discoveredCharacteristics.get(characteristicIdentifier);
1116
+ return characteristic;
1117
+ }
1118
+
1119
+ private getCharacteristicOrEmitErrorWithServiceId(serviceIdentifier: number,
1120
+ characteristicUUID: string): Characteristic | null {
1121
+ let service = this.discoveredServices.get(serviceIdentifier);
1122
+ if (service == null) {
1123
+ return null;
1124
+ }
1125
+
1126
+ let characteristic = service.getCharacteristicByUUID(characteristicUUID);
1127
+ return characteristic;
1128
+ }
1129
+
1130
+ private getCharacteristicOrEmitErrorWithDeviceId(deviceId: string, serviceUUID: string,
1131
+ characteristicUUID: string): Characteristic | null {
1132
+ let device = this.connectedDevices.get(deviceId);
1133
+ if (device == null) {
1134
+ return null;
1135
+ }
1136
+
1137
+ let service = device.getServiceByUUID(serviceUUID);
1138
+ if (service == null) {
1139
+ return null;
1140
+ }
1141
+
1142
+ let characteristic = service.getCharacteristicByUUID(characteristicUUID);
1143
+ if (characteristic == null) {
1144
+ return null;
1145
+ }
1146
+
1147
+ return characteristic;
1148
+ }
1149
+
1150
+ private getDescriptorWithCharId(characteristicIdentifier: number, descriptorUUID: string): Descriptor | null {
1151
+ let characteristic = this.discoveredCharacteristics.get(characteristicIdentifier);
1152
+ if (characteristic == null) {
1153
+ return null;
1154
+ }
1155
+
1156
+ let descriptor = characteristic.getDescriptorByUUID(descriptorUUID);
1157
+ if (descriptor == null) {
1158
+ return null;
1159
+ }
1160
+
1161
+ return descriptor;
1162
+ }
1163
+
1164
+ private getDescriptorWithServiceId(serviceIdentifier: number, characteristicUUID: string,
1165
+ descriptorUUID: string): Descriptor | null {
1166
+ let service = this.discoveredServices.get(serviceIdentifier);
1167
+ if (service == null) {
1168
+ return null;
1169
+ }
1170
+
1171
+ let characteristic = service.getCharacteristicByUUID(characteristicUUID);
1172
+ if (characteristic == null) {
1173
+ return null;
1174
+ }
1175
+
1176
+ let descriptor = characteristic.getDescriptorByUUID(descriptorUUID);
1177
+ if (descriptor == null) {
1178
+ return null;
1179
+ }
1180
+
1181
+ return descriptor;
1182
+ }
1183
+
1184
+ private getDescriptorWithDeviceId(deviceId: string, serviceUUID: string, characteristicUUID: string,
1185
+ descriptorUUID: string): Descriptor | null {
1186
+ let device = this.connectedDevices.get(deviceId);
1187
+ if (device == null) {
1188
+ return null;
1189
+ }
1190
+
1191
+ let service = device.getServiceByUUID(serviceUUID);
1192
+ if (service == null) {
1193
+ return null;
1194
+ }
1195
+
1196
+ let characteristic = service.getCharacteristicByUUID(characteristicUUID);
1197
+ if (characteristic == null) {
1198
+ return null;
1199
+ }
1200
+
1201
+ let descriptor = characteristic.getDescriptorByUUID(descriptorUUID);
1202
+ if (descriptor == null) {
1203
+ return null;
1204
+ }
1205
+
1206
+ return descriptor;
1207
+ }
1208
+ }