@stoprocent/noble 1.9.2-16

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 (112) hide show
  1. package/.editorconfig +11 -0
  2. package/.eslintrc.js +25 -0
  3. package/.github/FUNDING.yml +2 -0
  4. package/.github/workflows/fediverse-action.yml +16 -0
  5. package/.github/workflows/nodepackage.yml +77 -0
  6. package/.github/workflows/npm-publish.yml +26 -0
  7. package/.github/workflows/prebuild.yml +65 -0
  8. package/.nycrc.json +4 -0
  9. package/CHANGELOG.md +119 -0
  10. package/LICENSE +20 -0
  11. package/MAINTAINERS.md +1 -0
  12. package/README.md +833 -0
  13. package/assets/noble-logo.png +0 -0
  14. package/assets/noble-logo.svg +13 -0
  15. package/binding.gyp +19 -0
  16. package/codecov.yml +5 -0
  17. package/examples/advertisement-discovery.js +65 -0
  18. package/examples/cache-gatt-discovery.js +198 -0
  19. package/examples/cache-gatt-reconnect.js +164 -0
  20. package/examples/echo.js +104 -0
  21. package/examples/enter-exit.js +78 -0
  22. package/examples/peripheral-explorer-async.js +133 -0
  23. package/examples/peripheral-explorer.js +225 -0
  24. package/examples/pizza/README.md +15 -0
  25. package/examples/pizza/central.js +194 -0
  26. package/examples/pizza/pizza.js +60 -0
  27. package/index.d.ts +203 -0
  28. package/index.js +6 -0
  29. package/lib/characteristic.js +161 -0
  30. package/lib/characteristics.json +449 -0
  31. package/lib/descriptor.js +72 -0
  32. package/lib/descriptors.json +47 -0
  33. package/lib/distributed/bindings.js +326 -0
  34. package/lib/hci-socket/acl-stream.js +60 -0
  35. package/lib/hci-socket/bindings.js +788 -0
  36. package/lib/hci-socket/crypto.js +74 -0
  37. package/lib/hci-socket/gap.js +432 -0
  38. package/lib/hci-socket/gatt.js +809 -0
  39. package/lib/hci-socket/hci-status.json +71 -0
  40. package/lib/hci-socket/hci.js +1264 -0
  41. package/lib/hci-socket/signaling.js +76 -0
  42. package/lib/hci-socket/smp.js +140 -0
  43. package/lib/hci-uart/bindings.js +569 -0
  44. package/lib/hci-uart/hci-serial-parser.js +70 -0
  45. package/lib/hci-uart/hci.js +1336 -0
  46. package/lib/mac/binding.gyp +26 -0
  47. package/lib/mac/bindings.js +11 -0
  48. package/lib/mac/src/ble_manager.h +41 -0
  49. package/lib/mac/src/ble_manager.mm +435 -0
  50. package/lib/mac/src/callbacks.cc +222 -0
  51. package/lib/mac/src/callbacks.h +84 -0
  52. package/lib/mac/src/napi_objc.h +12 -0
  53. package/lib/mac/src/napi_objc.mm +50 -0
  54. package/lib/mac/src/noble_mac.h +34 -0
  55. package/lib/mac/src/noble_mac.mm +264 -0
  56. package/lib/mac/src/objc_cpp.h +26 -0
  57. package/lib/mac/src/objc_cpp.mm +126 -0
  58. package/lib/mac/src/peripheral.h +23 -0
  59. package/lib/manufacture.js +48 -0
  60. package/lib/noble.js +593 -0
  61. package/lib/peripheral.js +219 -0
  62. package/lib/resolve-bindings-web.js +9 -0
  63. package/lib/resolve-bindings.js +44 -0
  64. package/lib/service.js +72 -0
  65. package/lib/services.json +92 -0
  66. package/lib/webbluetooth/bindings.js +368 -0
  67. package/lib/websocket/bindings.js +321 -0
  68. package/lib/win/binding.gyp +23 -0
  69. package/lib/win/bindings.js +11 -0
  70. package/lib/win/src/ble_manager.cc +802 -0
  71. package/lib/win/src/ble_manager.h +77 -0
  72. package/lib/win/src/callbacks.cc +274 -0
  73. package/lib/win/src/callbacks.h +33 -0
  74. package/lib/win/src/napi_winrt.cc +76 -0
  75. package/lib/win/src/napi_winrt.h +12 -0
  76. package/lib/win/src/noble_winrt.cc +308 -0
  77. package/lib/win/src/noble_winrt.h +34 -0
  78. package/lib/win/src/notify_map.cc +62 -0
  79. package/lib/win/src/notify_map.h +50 -0
  80. package/lib/win/src/peripheral.h +23 -0
  81. package/lib/win/src/peripheral_winrt.cc +296 -0
  82. package/lib/win/src/peripheral_winrt.h +82 -0
  83. package/lib/win/src/radio_watcher.cc +125 -0
  84. package/lib/win/src/radio_watcher.h +61 -0
  85. package/lib/win/src/winrt_cpp.cc +82 -0
  86. package/lib/win/src/winrt_cpp.h +11 -0
  87. package/lib/win/src/winrt_guid.cc +12 -0
  88. package/lib/win/src/winrt_guid.h +13 -0
  89. package/misc/nrf52840dk.hex +6921 -0
  90. package/misc/prj.conf +43 -0
  91. package/package.json +96 -0
  92. package/test/lib/characteristic.test.js +791 -0
  93. package/test/lib/descriptor.test.js +249 -0
  94. package/test/lib/distributed/bindings.test.js +918 -0
  95. package/test/lib/hci-socket/acl-stream.test.js +188 -0
  96. package/test/lib/hci-socket/bindings.test.js +1756 -0
  97. package/test/lib/hci-socket/crypto.test.js +55 -0
  98. package/test/lib/hci-socket/gap.test.js +1089 -0
  99. package/test/lib/hci-socket/gatt.test.js +2392 -0
  100. package/test/lib/hci-socket/hci.test.js +1891 -0
  101. package/test/lib/hci-socket/signaling.test.js +94 -0
  102. package/test/lib/hci-socket/smp.test.js +268 -0
  103. package/test/lib/manufacture.test.js +77 -0
  104. package/test/lib/peripheral.test.js +623 -0
  105. package/test/lib/resolve-bindings.test.js +102 -0
  106. package/test/lib/service.test.js +195 -0
  107. package/test/lib/webbluetooth/bindings.test.js +190 -0
  108. package/test/lib/websocket/bindings.test.js +456 -0
  109. package/test/noble.test.js +1565 -0
  110. package/test.js +131 -0
  111. package/with-bindings.js +5 -0
  112. package/ws-slave.js +404 -0
@@ -0,0 +1,788 @@
1
+ const events = require('events');
2
+ const util = require('util');
3
+
4
+ const AclStream = require('./acl-stream');
5
+ const Gatt = require('./gatt');
6
+ const Gap = require('./gap');
7
+ const Hci = require('./hci');
8
+ const Signaling = require('./signaling');
9
+
10
+ const NobleBindings = function (options) {
11
+ this._state = null;
12
+
13
+ this._addresses = {};
14
+ this._addresseTypes = {};
15
+ this._connectable = {};
16
+ this._isExtended = 'extended' in options && options.extended;
17
+ this.scannable = {};
18
+
19
+ this._pendingConnectionUuid = null;
20
+ this._connectionQueue = [];
21
+
22
+ this._handles = {};
23
+ this._gatts = {};
24
+ this._aclStreams = {};
25
+ this._signalings = {};
26
+
27
+ this._hci = new Hci(options);
28
+ this._gap = new Gap(this._hci);
29
+ };
30
+
31
+ util.inherits(NobleBindings, events.EventEmitter);
32
+
33
+ NobleBindings.prototype.setScanParameters = function (interval, window) {
34
+ this._gap.setScanParameters(interval, window);
35
+ };
36
+
37
+ NobleBindings.prototype.startScanning = function (
38
+ serviceUuids,
39
+ allowDuplicates
40
+ ) {
41
+ this._scanServiceUuids = serviceUuids || [];
42
+
43
+ this._gap.startScanning(allowDuplicates);
44
+ };
45
+
46
+ NobleBindings.prototype.stopScanning = function () {
47
+ this._gap.stopScanning();
48
+ };
49
+
50
+ NobleBindings.prototype.connect = function (peripheralUuid, parameters) {
51
+ const address = this._addresses[peripheralUuid];
52
+ const addressType = this._addresseTypes[peripheralUuid];
53
+
54
+ if (!this._pendingConnectionUuid) {
55
+ this._pendingConnectionUuid = peripheralUuid;
56
+
57
+ this._hci.createLeConn(address, addressType, parameters);
58
+ } else {
59
+ this._connectionQueue.push({ id: peripheralUuid, params: parameters });
60
+ }
61
+ };
62
+
63
+ NobleBindings.prototype.disconnect = function (peripheralUuid) {
64
+ this._hci.disconnect(this._handles[peripheralUuid]);
65
+ };
66
+
67
+ NobleBindings.prototype.cancelConnect = function (peripheralUuid) {
68
+ // TODO: check if it was not in the queue and only then issue cancel on hci
69
+ this._connectionQueue = this._connectionQueue.filter(
70
+ (c) => c.id !== peripheralUuid
71
+ );
72
+ this._hci.cancelConnect(this._handles[peripheralUuid]);
73
+ };
74
+
75
+ NobleBindings.prototype.reset = function () {
76
+ this._hci.reset();
77
+ };
78
+
79
+ NobleBindings.prototype.updateRssi = function (peripheralUuid) {
80
+ this._hci.readRssi(this._handles[peripheralUuid]);
81
+ };
82
+
83
+ NobleBindings.prototype.init = function () {
84
+ this.onSigIntBinded = this.onSigInt.bind(this);
85
+
86
+ this._gap.on('scanParametersSet', this.onScanParametersSet.bind(this));
87
+ this._gap.on('scanStart', this.onScanStart.bind(this));
88
+ this._gap.on('scanStop', this.onScanStop.bind(this));
89
+ this._gap.on('discover', this.onDiscover.bind(this));
90
+
91
+ this._hci.on('stateChange', this.onStateChange.bind(this));
92
+ this._hci.on('addressChange', this.onAddressChange.bind(this));
93
+ this._hci.on('leConnComplete', this.onLeConnComplete.bind(this));
94
+ this._hci.on('leConnUpdateComplete', this.onLeConnUpdateComplete.bind(this));
95
+ this._hci.on('rssiRead', this.onRssiRead.bind(this));
96
+ this._hci.on('disconnComplete', this.onDisconnComplete.bind(this));
97
+ this._hci.on('encryptChange', this.onEncryptChange.bind(this));
98
+ this._hci.on('aclDataPkt', this.onAclDataPkt.bind(this));
99
+
100
+ this._hci.init();
101
+
102
+ /* Add exit handlers after `init()` has completed. If no adaptor
103
+ is present it can throw an exception - in which case we don't
104
+ want to try and clear up afterwards (issue #502) */
105
+ process.on('SIGINT', this.onSigIntBinded);
106
+ process.on('exit', this.onExit.bind(this));
107
+ };
108
+
109
+ NobleBindings.prototype.onSigInt = function () {
110
+ const sigIntListeners = process.listeners('SIGINT');
111
+
112
+ if (sigIntListeners[sigIntListeners.length - 1] === this.onSigIntBinded) {
113
+ // we are the last listener, so exit
114
+ // this will trigger onExit, and clean up
115
+ process.exit(1);
116
+ }
117
+ };
118
+
119
+ NobleBindings.prototype.onExit = function () {
120
+ this.stopScanning();
121
+
122
+ for (const handle in this._aclStreams) {
123
+ this._hci.disconnect(handle);
124
+ }
125
+ };
126
+
127
+ NobleBindings.prototype.onStateChange = function (state) {
128
+ if (this._state === state) {
129
+ return;
130
+ }
131
+ this._state = state;
132
+
133
+ if (state === 'unauthorized') {
134
+ console.log(
135
+ 'noble warning: adapter state unauthorized, please run as root or with sudo'
136
+ );
137
+ console.log(
138
+ ' or see README for information on running without root/sudo:'
139
+ );
140
+ console.log(
141
+ ' https://github.com/sandeepmistry/noble#running-on-linux'
142
+ );
143
+ } else if (state === 'unsupported') {
144
+ console.log(
145
+ 'noble warning: adapter does not support Bluetooth Low Energy (BLE, Bluetooth Smart).'
146
+ );
147
+ console.log(' Try to run with environment variable:');
148
+ console.log(' [sudo] NOBLE_HCI_DEVICE_ID=x node ...');
149
+ }
150
+
151
+ this.emit('stateChange', state);
152
+ };
153
+
154
+ NobleBindings.prototype.onAddressChange = function (address) {
155
+ this.emit('addressChange', address);
156
+ };
157
+
158
+ NobleBindings.prototype.onScanParametersSet = function () {
159
+ this.emit('scanParametersSet');
160
+ };
161
+
162
+ NobleBindings.prototype.onScanStart = function (filterDuplicates) {
163
+ this.emit('scanStart', filterDuplicates);
164
+ };
165
+
166
+ NobleBindings.prototype.onScanStop = function () {
167
+ this.emit('scanStop');
168
+ };
169
+
170
+ NobleBindings.prototype.onDiscover = function (
171
+ status,
172
+ address,
173
+ addressType,
174
+ connectable,
175
+ advertisement,
176
+ rssi,
177
+ scannable
178
+ ) {
179
+ if (this._scanServiceUuids === undefined) {
180
+ return;
181
+ }
182
+
183
+ let serviceUuids = advertisement.serviceUuids || [];
184
+ const serviceData = advertisement.serviceData || [];
185
+ let hasScanServiceUuids = this._scanServiceUuids.length === 0;
186
+
187
+ if (!hasScanServiceUuids) {
188
+ let i;
189
+
190
+ serviceUuids = serviceUuids.slice();
191
+
192
+ for (i in serviceData) {
193
+ serviceUuids.push(serviceData[i].uuid);
194
+ }
195
+
196
+ for (i in serviceUuids) {
197
+ hasScanServiceUuids =
198
+ this._scanServiceUuids.indexOf(serviceUuids[i]) !== -1;
199
+
200
+ if (hasScanServiceUuids) {
201
+ break;
202
+ }
203
+ }
204
+ }
205
+
206
+ if (hasScanServiceUuids) {
207
+ const uuid = address.split(':').join('');
208
+ this._addresses[uuid] = address;
209
+ this._addresseTypes[uuid] = addressType;
210
+ this._connectable[uuid] = connectable;
211
+ this.scannable[uuid] = scannable;
212
+
213
+ this.emit(
214
+ 'discover',
215
+ uuid,
216
+ address,
217
+ addressType,
218
+ connectable,
219
+ advertisement,
220
+ rssi,
221
+ scannable
222
+ );
223
+ }
224
+ };
225
+
226
+ NobleBindings.prototype.onLeConnComplete = function (
227
+ status,
228
+ handle,
229
+ role,
230
+ addressType,
231
+ address,
232
+ interval,
233
+ latency,
234
+ supervisionTimeout,
235
+ masterClockAccuracy
236
+ ) {
237
+ if (role !== 0 && role !== undefined) {
238
+ // not master, ignore
239
+ return;
240
+ }
241
+ let uuid = null;
242
+
243
+ let error = null;
244
+
245
+ if (status === 0) {
246
+ uuid = address.split(':').join('').toLowerCase();
247
+
248
+ const aclStream = new AclStream(
249
+ this._hci,
250
+ handle,
251
+ this._hci.addressType,
252
+ this._hci.address,
253
+ addressType,
254
+ address
255
+ );
256
+ const gatt = new Gatt(address, aclStream);
257
+ const signaling = new Signaling(handle, aclStream);
258
+
259
+ this._gatts[uuid] = this._gatts[handle] = gatt;
260
+ this._signalings[uuid] = this._signalings[handle] = signaling;
261
+ this._aclStreams[handle] = aclStream;
262
+ this._handles[uuid] = handle;
263
+ this._handles[handle] = uuid;
264
+
265
+ this._gatts[handle].on('mtu', this.onMtu.bind(this));
266
+ this._gatts[handle].on(
267
+ 'servicesDiscover',
268
+ this.onServicesDiscovered.bind(this)
269
+ );
270
+ this._gatts[handle].on(
271
+ 'servicesDiscovered',
272
+ this.onServicesDiscoveredEX.bind(this)
273
+ );
274
+ this._gatts[handle].on(
275
+ 'includedServicesDiscover',
276
+ this.onIncludedServicesDiscovered.bind(this)
277
+ );
278
+ this._gatts[handle].on(
279
+ 'characteristicsDiscover',
280
+ this.onCharacteristicsDiscovered.bind(this)
281
+ );
282
+ this._gatts[handle].on(
283
+ 'characteristicsDiscovered',
284
+ this.onCharacteristicsDiscoveredEX.bind(this)
285
+ );
286
+ this._gatts[handle].on('read', this.onRead.bind(this));
287
+ this._gatts[handle].on('write', this.onWrite.bind(this));
288
+ this._gatts[handle].on('broadcast', this.onBroadcast.bind(this));
289
+ this._gatts[handle].on('notify', this.onNotify.bind(this));
290
+ this._gatts[handle].on('notification', this.onNotification.bind(this));
291
+ this._gatts[handle].on(
292
+ 'descriptorsDiscover',
293
+ this.onDescriptorsDiscovered.bind(this)
294
+ );
295
+ this._gatts[handle].on('valueRead', this.onValueRead.bind(this));
296
+ this._gatts[handle].on('valueWrite', this.onValueWrite.bind(this));
297
+ this._gatts[handle].on('handleRead', this.onHandleRead.bind(this));
298
+ this._gatts[handle].on('handleWrite', this.onHandleWrite.bind(this));
299
+ this._gatts[handle].on('handleNotify', this.onHandleNotify.bind(this));
300
+
301
+ this._signalings[handle].on(
302
+ 'connectionParameterUpdateRequest',
303
+ this.onConnectionParameterUpdateRequest.bind(this)
304
+ );
305
+
306
+ setTimeout(() => {
307
+ this._gatts[handle].exchangeMtu();
308
+ }, 0);
309
+ } else {
310
+ uuid = this._pendingConnectionUuid;
311
+ let statusMessage = Hci.STATUS_MAPPER[status] || 'HCI Error: Unknown';
312
+ const errorCode = ` (0x${status.toString(16)})`;
313
+ statusMessage = statusMessage + errorCode;
314
+ error = new Error(statusMessage);
315
+ }
316
+
317
+ this.emit('connect', uuid, error);
318
+
319
+ if (this._connectionQueue.length > 0) {
320
+ const queueItem = this._connectionQueue.shift();
321
+ const peripheralUuid = queueItem.id;
322
+
323
+ address = this._addresses[peripheralUuid];
324
+ addressType = this._addresseTypes[peripheralUuid];
325
+
326
+ this._pendingConnectionUuid = peripheralUuid;
327
+
328
+ this._hci.createLeConn(address, addressType, queueItem.params);
329
+ } else {
330
+ this._pendingConnectionUuid = null;
331
+ }
332
+ };
333
+
334
+ NobleBindings.prototype.onLeConnUpdateComplete = function (
335
+ handle,
336
+ interval,
337
+ latency,
338
+ supervisionTimeout
339
+ ) {
340
+ // no-op
341
+ };
342
+
343
+ NobleBindings.prototype.onDisconnComplete = function (handle, reason) {
344
+ const uuid = this._handles[handle];
345
+
346
+ if (uuid) {
347
+ this._aclStreams[handle].push(null, null);
348
+ this._gatts[handle].removeAllListeners();
349
+ this._signalings[handle].removeAllListeners();
350
+
351
+ delete this._gatts[uuid];
352
+ delete this._gatts[handle];
353
+ delete this._signalings[uuid];
354
+ delete this._signalings[handle];
355
+ delete this._aclStreams[handle];
356
+ delete this._handles[uuid];
357
+ delete this._handles[handle];
358
+
359
+ this.emit('disconnect', uuid, reason);
360
+ } else {
361
+ console.warn(`noble warning: unknown handle ${handle} disconnected!`);
362
+ }
363
+ };
364
+
365
+ NobleBindings.prototype.onEncryptChange = function (handle, encrypt) {
366
+ const aclStream = this._aclStreams[handle];
367
+
368
+ if (aclStream) {
369
+ aclStream.pushEncrypt(encrypt);
370
+ }
371
+ };
372
+
373
+ NobleBindings.prototype.onMtu = function (address, mtu) {
374
+ const uuid = address.split(':').join('').toLowerCase();
375
+
376
+ this.emit('onMtu', uuid, mtu);
377
+ };
378
+
379
+ NobleBindings.prototype.onRssiRead = function (handle, rssi) {
380
+ this.emit('rssiUpdate', this._handles[handle], rssi);
381
+ };
382
+
383
+ NobleBindings.prototype.onAclDataPkt = function (handle, cid, data) {
384
+ const aclStream = this._aclStreams[handle];
385
+
386
+ if (aclStream) {
387
+ aclStream.push(cid, data);
388
+ }
389
+ };
390
+
391
+ NobleBindings.prototype.addService = function (peripheralUuid, service) {
392
+ const handle = this._handles[peripheralUuid];
393
+ const gatt = this._gatts[handle];
394
+
395
+ if (gatt) {
396
+ gatt.addService(service);
397
+ } else {
398
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
399
+ }
400
+ };
401
+
402
+ NobleBindings.prototype.discoverServices = function (peripheralUuid, uuids) {
403
+ const handle = this._handles[peripheralUuid];
404
+ const gatt = this._gatts[handle];
405
+
406
+ if (gatt) {
407
+ gatt.discoverServices(uuids || []);
408
+ } else {
409
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
410
+ }
411
+ };
412
+
413
+ NobleBindings.prototype.onServicesDiscovered = function (
414
+ address,
415
+ serviceUuids
416
+ ) {
417
+ const uuid = address.split(':').join('').toLowerCase();
418
+
419
+ this.emit('servicesDiscover', uuid, serviceUuids);
420
+ };
421
+
422
+ NobleBindings.prototype.onServicesDiscoveredEX = function (address, services) {
423
+ const uuid = address.split(':').join('').toLowerCase();
424
+
425
+ this.emit('servicesDiscovered', uuid, services);
426
+ };
427
+
428
+ NobleBindings.prototype.discoverIncludedServices = function (
429
+ peripheralUuid,
430
+ serviceUuid,
431
+ serviceUuids
432
+ ) {
433
+ const handle = this._handles[peripheralUuid];
434
+ const gatt = this._gatts[handle];
435
+
436
+ if (gatt) {
437
+ gatt.discoverIncludedServices(serviceUuid, serviceUuids || []);
438
+ } else {
439
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
440
+ }
441
+ };
442
+
443
+ NobleBindings.prototype.onIncludedServicesDiscovered = function (
444
+ address,
445
+ serviceUuid,
446
+ includedServiceUuids
447
+ ) {
448
+ const uuid = address.split(':').join('').toLowerCase();
449
+
450
+ this.emit(
451
+ 'includedServicesDiscover',
452
+ uuid,
453
+ serviceUuid,
454
+ includedServiceUuids
455
+ );
456
+ };
457
+
458
+ NobleBindings.prototype.addCharacteristics = function (
459
+ peripheralUuid,
460
+ serviceUuid,
461
+ characteristics
462
+ ) {
463
+ const handle = this._handles[peripheralUuid];
464
+ const gatt = this._gatts[handle];
465
+
466
+ if (gatt) {
467
+ gatt.addCharacteristics(serviceUuid, characteristics);
468
+ } else {
469
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
470
+ }
471
+ };
472
+
473
+ NobleBindings.prototype.discoverCharacteristics = function (
474
+ peripheralUuid,
475
+ serviceUuid,
476
+ characteristicUuids
477
+ ) {
478
+ const handle = this._handles[peripheralUuid];
479
+ const gatt = this._gatts[handle];
480
+
481
+ if (gatt) {
482
+ gatt.discoverCharacteristics(serviceUuid, characteristicUuids || []);
483
+ } else {
484
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
485
+ }
486
+ };
487
+
488
+ NobleBindings.prototype.onCharacteristicsDiscovered = function (
489
+ address,
490
+ serviceUuid,
491
+ characteristics
492
+ ) {
493
+ const uuid = address.split(':').join('').toLowerCase();
494
+
495
+ this.emit('characteristicsDiscover', uuid, serviceUuid, characteristics);
496
+ };
497
+
498
+ NobleBindings.prototype.onCharacteristicsDiscoveredEX = function (
499
+ address,
500
+ serviceUuid,
501
+ characteristics
502
+ ) {
503
+ const uuid = address.split(':').join('').toLowerCase();
504
+
505
+ this.emit('characteristicsDiscovered', uuid, serviceUuid, characteristics);
506
+ };
507
+
508
+ NobleBindings.prototype.read = function (
509
+ peripheralUuid,
510
+ serviceUuid,
511
+ characteristicUuid
512
+ ) {
513
+ const handle = this._handles[peripheralUuid];
514
+ const gatt = this._gatts[handle];
515
+
516
+ if (gatt) {
517
+ gatt.read(serviceUuid, characteristicUuid);
518
+ } else {
519
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
520
+ }
521
+ };
522
+
523
+ NobleBindings.prototype.onRead = function (
524
+ address,
525
+ serviceUuid,
526
+ characteristicUuid,
527
+ data
528
+ ) {
529
+ const uuid = address.split(':').join('').toLowerCase();
530
+
531
+ this.emit('read', uuid, serviceUuid, characteristicUuid, data, false);
532
+ };
533
+
534
+ NobleBindings.prototype.write = function (
535
+ peripheralUuid,
536
+ serviceUuid,
537
+ characteristicUuid,
538
+ data,
539
+ withoutResponse
540
+ ) {
541
+ const handle = this._handles[peripheralUuid];
542
+ const gatt = this._gatts[handle];
543
+
544
+ if (gatt) {
545
+ gatt.write(serviceUuid, characteristicUuid, data, withoutResponse);
546
+ } else {
547
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
548
+ }
549
+ };
550
+
551
+ NobleBindings.prototype.onWrite = function (
552
+ address,
553
+ serviceUuid,
554
+ characteristicUuid
555
+ ) {
556
+ const uuid = address.split(':').join('').toLowerCase();
557
+
558
+ this.emit('write', uuid, serviceUuid, characteristicUuid);
559
+ };
560
+
561
+ NobleBindings.prototype.broadcast = function (
562
+ peripheralUuid,
563
+ serviceUuid,
564
+ characteristicUuid,
565
+ broadcast
566
+ ) {
567
+ const handle = this._handles[peripheralUuid];
568
+ const gatt = this._gatts[handle];
569
+
570
+ if (gatt) {
571
+ gatt.broadcast(serviceUuid, characteristicUuid, broadcast);
572
+ } else {
573
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
574
+ }
575
+ };
576
+
577
+ NobleBindings.prototype.onBroadcast = function (
578
+ address,
579
+ serviceUuid,
580
+ characteristicUuid,
581
+ state
582
+ ) {
583
+ const uuid = address.split(':').join('').toLowerCase();
584
+
585
+ this.emit('broadcast', uuid, serviceUuid, characteristicUuid, state);
586
+ };
587
+
588
+ NobleBindings.prototype.notify = function (
589
+ peripheralUuid,
590
+ serviceUuid,
591
+ characteristicUuid,
592
+ notify
593
+ ) {
594
+ const handle = this._handles[peripheralUuid];
595
+ const gatt = this._gatts[handle];
596
+
597
+ if (gatt) {
598
+ gatt.notify(serviceUuid, characteristicUuid, notify);
599
+ } else {
600
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
601
+ }
602
+ };
603
+
604
+ NobleBindings.prototype.onNotify = function (
605
+ address,
606
+ serviceUuid,
607
+ characteristicUuid,
608
+ state
609
+ ) {
610
+ const uuid = address.split(':').join('').toLowerCase();
611
+
612
+ this.emit('notify', uuid, serviceUuid, characteristicUuid, state);
613
+ };
614
+
615
+ NobleBindings.prototype.onNotification = function (
616
+ address,
617
+ serviceUuid,
618
+ characteristicUuid,
619
+ data
620
+ ) {
621
+ const uuid = address.split(':').join('').toLowerCase();
622
+
623
+ this.emit('read', uuid, serviceUuid, characteristicUuid, data, true);
624
+ };
625
+
626
+ NobleBindings.prototype.discoverDescriptors = function (
627
+ peripheralUuid,
628
+ serviceUuid,
629
+ characteristicUuid
630
+ ) {
631
+ const handle = this._handles[peripheralUuid];
632
+ const gatt = this._gatts[handle];
633
+
634
+ if (gatt) {
635
+ gatt.discoverDescriptors(serviceUuid, characteristicUuid);
636
+ } else {
637
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
638
+ }
639
+ };
640
+
641
+ NobleBindings.prototype.onDescriptorsDiscovered = function (
642
+ address,
643
+ serviceUuid,
644
+ characteristicUuid,
645
+ descriptorUuids
646
+ ) {
647
+ const uuid = address.split(':').join('').toLowerCase();
648
+
649
+ this.emit(
650
+ 'descriptorsDiscover',
651
+ uuid,
652
+ serviceUuid,
653
+ characteristicUuid,
654
+ descriptorUuids
655
+ );
656
+ };
657
+
658
+ NobleBindings.prototype.readValue = function (
659
+ peripheralUuid,
660
+ serviceUuid,
661
+ characteristicUuid,
662
+ descriptorUuid
663
+ ) {
664
+ const handle = this._handles[peripheralUuid];
665
+ const gatt = this._gatts[handle];
666
+
667
+ if (gatt) {
668
+ gatt.readValue(serviceUuid, characteristicUuid, descriptorUuid);
669
+ } else {
670
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
671
+ }
672
+ };
673
+
674
+ NobleBindings.prototype.onValueRead = function (
675
+ address,
676
+ serviceUuid,
677
+ characteristicUuid,
678
+ descriptorUuid,
679
+ data
680
+ ) {
681
+ const uuid = address.split(':').join('').toLowerCase();
682
+
683
+ this.emit(
684
+ 'valueRead',
685
+ uuid,
686
+ serviceUuid,
687
+ characteristicUuid,
688
+ descriptorUuid,
689
+ data
690
+ );
691
+ };
692
+
693
+ NobleBindings.prototype.writeValue = function (
694
+ peripheralUuid,
695
+ serviceUuid,
696
+ characteristicUuid,
697
+ descriptorUuid,
698
+ data
699
+ ) {
700
+ const handle = this._handles[peripheralUuid];
701
+ const gatt = this._gatts[handle];
702
+
703
+ if (gatt) {
704
+ gatt.writeValue(serviceUuid, characteristicUuid, descriptorUuid, data);
705
+ } else {
706
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
707
+ }
708
+ };
709
+
710
+ NobleBindings.prototype.onValueWrite = function (
711
+ address,
712
+ serviceUuid,
713
+ characteristicUuid,
714
+ descriptorUuid
715
+ ) {
716
+ const uuid = address.split(':').join('').toLowerCase();
717
+
718
+ this.emit(
719
+ 'valueWrite',
720
+ uuid,
721
+ serviceUuid,
722
+ characteristicUuid,
723
+ descriptorUuid
724
+ );
725
+ };
726
+
727
+ NobleBindings.prototype.readHandle = function (peripheralUuid, attHandle) {
728
+ const handle = this._handles[peripheralUuid];
729
+ const gatt = this._gatts[handle];
730
+
731
+ if (gatt) {
732
+ gatt.readHandle(attHandle);
733
+ } else {
734
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
735
+ }
736
+ };
737
+
738
+ NobleBindings.prototype.onHandleRead = function (address, handle, data) {
739
+ const uuid = address.split(':').join('').toLowerCase();
740
+
741
+ this.emit('handleRead', uuid, handle, data);
742
+ };
743
+
744
+ NobleBindings.prototype.writeHandle = function (
745
+ peripheralUuid,
746
+ attHandle,
747
+ data,
748
+ withoutResponse
749
+ ) {
750
+ const handle = this._handles[peripheralUuid];
751
+ const gatt = this._gatts[handle];
752
+
753
+ if (gatt) {
754
+ gatt.writeHandle(attHandle, data, withoutResponse);
755
+ } else {
756
+ console.warn(`noble warning: unknown peripheral ${peripheralUuid}`);
757
+ }
758
+ };
759
+
760
+ NobleBindings.prototype.onHandleWrite = function (address, handle) {
761
+ const uuid = address.split(':').join('').toLowerCase();
762
+
763
+ this.emit('handleWrite', uuid, handle);
764
+ };
765
+
766
+ NobleBindings.prototype.onHandleNotify = function (address, handle, data) {
767
+ const uuid = address.split(':').join('').toLowerCase();
768
+
769
+ this.emit('handleNotify', uuid, handle, data);
770
+ };
771
+
772
+ NobleBindings.prototype.onConnectionParameterUpdateRequest = function (
773
+ handle,
774
+ minInterval,
775
+ maxInterval,
776
+ latency,
777
+ supervisionTimeout
778
+ ) {
779
+ this._hci.connUpdateLe(
780
+ handle,
781
+ minInterval,
782
+ maxInterval,
783
+ latency,
784
+ supervisionTimeout
785
+ );
786
+ };
787
+
788
+ module.exports = NobleBindings;