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