@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,918 @@
1
+ const proxyquire = require('proxyquire').noCallThru();
2
+ const should = require('should');
3
+ const sinon = require('sinon');
4
+ const { assert, fake } = sinon;
5
+
6
+ describe('distributed bindings', () => {
7
+ const wssOn = sinon.stub().resolves(null);
8
+
9
+ const WebSocketServerStub = sinon.stub();
10
+ WebSocketServerStub.prototype.on = wssOn;
11
+
12
+ const Bindings = proxyquire('../../../lib/distributed/bindings', {
13
+ ws: { Server: WebSocketServerStub }
14
+ });
15
+
16
+ const baseMessage = {
17
+ peripheralUuid: 'peripheralUuid',
18
+ address: 'address',
19
+ addressType: 'addressType',
20
+ connectable: 'connectable',
21
+ advertisement: {
22
+ localName: 'advertisement.localName',
23
+ txPowerLevel: 'advertisement.txPowerLevel',
24
+ serviceUuids: 'advertisement.serviceUuids',
25
+ manufacturerData: '000102',
26
+ serviceData: '030405'
27
+ },
28
+ rssi: 'rssi',
29
+ serviceUuids: 'serviceUuids',
30
+ serviceUuid: 'serviceUuid',
31
+ includedServiceUuids: 'includedServiceUuids',
32
+ characteristics: 'characteristics',
33
+ characteristicUuid: 'characteristicUuid',
34
+ isNotification: 'isNotification',
35
+ state: 'state',
36
+ descriptors: 'descriptors',
37
+ descriptorUuid: 'descriptorUuid',
38
+ handle: 'handle'
39
+ };
40
+
41
+ let clock;
42
+
43
+ beforeEach(() => {
44
+ clock = sinon.useFakeTimers({ toFake: ['nextTick'] });
45
+ });
46
+
47
+ afterEach(() => {
48
+ clock.restore();
49
+ sinon.reset();
50
+ });
51
+
52
+ it('Constructor initialization', () => {
53
+ const bindings = new Bindings();
54
+
55
+ assert.calledOnce(WebSocketServerStub);
56
+ assert.calledWith(WebSocketServerStub, {
57
+ port: 0xB1e
58
+ });
59
+
60
+ assert.calledOnce(wssOn);
61
+ assert.calledWith(wssOn, 'connection', sinon.match.typeOf('function'));
62
+
63
+ should(bindings.eventNames()).eql(['close', 'message']);
64
+ });
65
+
66
+ it('Constructor stateChange event', () => {
67
+ const stateChange = fake.resolves(null);
68
+
69
+ const bindings = new Bindings();
70
+ bindings.on('stateChange', stateChange);
71
+
72
+ clock.tick(1);
73
+
74
+ assert.calledOnce(stateChange);
75
+ assert.calledWith(stateChange, 'poweredOff');
76
+ });
77
+
78
+ it('_onConnection single client', () => {
79
+ const stateChange = fake.resolves(null);
80
+ const fakeWs = {
81
+ on: fake.resolves(null)
82
+ };
83
+
84
+ const bindings = new Bindings();
85
+ bindings._wss = {
86
+ clients: [0]
87
+ };
88
+ bindings.on('stateChange', stateChange);
89
+
90
+ bindings._onConnection(fakeWs);
91
+
92
+ assert.calledOnce(stateChange);
93
+ assert.calledWith(stateChange, 'poweredOn');
94
+
95
+ assert.calledTwice(fakeWs.on);
96
+ assert.calledWith(fakeWs.on, 'close', sinon.match.func);
97
+ assert.calledWith(fakeWs.on, 'message', sinon.match.func);
98
+ });
99
+
100
+ it('_onConnection start scan', () => {
101
+ const stateChange = fake.resolves(null);
102
+ const fakeWs = {
103
+ on: fake.resolves(null),
104
+ send: fake.resolves(null)
105
+ };
106
+
107
+ const bindings = new Bindings();
108
+ bindings._startScanCommand = {};
109
+ bindings._wss = {
110
+ clients: []
111
+ };
112
+ bindings.on('stateChange', stateChange);
113
+
114
+ bindings._onConnection(fakeWs);
115
+
116
+ assert.notCalled(stateChange);
117
+
118
+ assert.calledOnce(fakeWs.send);
119
+ assert.calledWith(fakeWs.send, '{}');
120
+
121
+ assert.calledTwice(fakeWs.on);
122
+ assert.calledWith(fakeWs.on, 'close', sinon.match.func);
123
+ assert.calledWith(fakeWs.on, 'message', sinon.match.func);
124
+ });
125
+
126
+ it('_onClose no clients', () => {
127
+ const stateChange = fake.resolves(null);
128
+
129
+ const bindings = new Bindings();
130
+ bindings._wss = {
131
+ clients: []
132
+ };
133
+ bindings.on('stateChange', stateChange);
134
+
135
+ bindings._onClose(null);
136
+
137
+ assert.calledOnce(stateChange);
138
+ assert.calledWith(stateChange, 'poweredOff');
139
+ });
140
+
141
+ it('_onClose with clients', () => {
142
+ const stateChange = fake.resolves(null);
143
+
144
+ const bindings = new Bindings();
145
+ bindings._wss = {
146
+ clients: [0]
147
+ };
148
+ bindings.on('stateChange', stateChange);
149
+
150
+ bindings._onClose(null);
151
+
152
+ assert.notCalled(stateChange);
153
+ });
154
+
155
+ it('_onMessage -> discover', () => {
156
+ const eventFunc = fake.resolves(null);
157
+
158
+ const bindings = new Bindings();
159
+ bindings.on('discover', eventFunc);
160
+
161
+ const message = Object.assign({}, baseMessage, { type: 'discover' });
162
+ bindings._onMessage('ws', message);
163
+
164
+ assert.calledOnce(eventFunc);
165
+
166
+ const expectedAdvertisement = {
167
+ localName: message.advertisement.localName,
168
+ txPowerLevel: message.advertisement.txPowerLevel,
169
+ serviceUuids: message.advertisement.serviceUuids,
170
+ manufacturerData: Buffer.from([0, 1, 2]),
171
+ serviceData: Buffer.from([3, 4, 5])
172
+ };
173
+ assert.calledWith(eventFunc, message.peripheralUuid, message.address, message.addressType, message.connectable, expectedAdvertisement, message.rssi);
174
+
175
+ should(bindings._peripherals).keys([message.peripheralUuid]);
176
+ });
177
+
178
+ it('_onMessage -> connect', () => {
179
+ const eventFunc = fake.resolves(null);
180
+
181
+ const bindings = new Bindings();
182
+ bindings.on('connect', eventFunc);
183
+
184
+ const message = Object.assign({}, baseMessage, { type: 'connect' });
185
+ bindings._onMessage('ws', message);
186
+
187
+ assert.calledOnce(eventFunc);
188
+ assert.calledWith(eventFunc, message.peripheralUuid);
189
+ });
190
+
191
+ it('_onMessage -> disconnect', () => {
192
+ const eventFunc = fake.resolves(null);
193
+
194
+ const bindings = new Bindings();
195
+ bindings.on('disconnect', eventFunc);
196
+
197
+ const message = Object.assign({}, baseMessage, { type: 'disconnect' });
198
+ bindings._onMessage('ws', message);
199
+
200
+ assert.calledOnce(eventFunc);
201
+ assert.calledWith(eventFunc, message.peripheralUuid);
202
+ });
203
+
204
+ it('_onMessage -> rssiUpdate', () => {
205
+ const eventFunc = fake.resolves(null);
206
+
207
+ const bindings = new Bindings();
208
+ bindings.on('rssiUpdate', eventFunc);
209
+
210
+ const message = Object.assign({}, baseMessage, { type: 'rssiUpdate' });
211
+ bindings._onMessage('ws', message);
212
+
213
+ assert.calledOnce(eventFunc);
214
+ assert.calledWith(eventFunc, message.peripheralUuid, message.rssi);
215
+ });
216
+
217
+ it('_onMessage -> servicesDiscover', () => {
218
+ const eventFunc = fake.resolves(null);
219
+
220
+ const bindings = new Bindings();
221
+ bindings.on('servicesDiscover', eventFunc);
222
+
223
+ const message = Object.assign({}, baseMessage, { type: 'servicesDiscover' });
224
+ bindings._onMessage('ws', message);
225
+
226
+ assert.calledOnce(eventFunc);
227
+ assert.calledWith(eventFunc, message.peripheralUuid, message.serviceUuids);
228
+ });
229
+
230
+ it('_onMessage -> includedServicesDiscover', () => {
231
+ const eventFunc = fake.resolves(null);
232
+
233
+ const bindings = new Bindings();
234
+ bindings.on('includedServicesDiscover', eventFunc);
235
+
236
+ const message = Object.assign({}, baseMessage, { type: 'includedServicesDiscover' });
237
+ bindings._onMessage('ws', message);
238
+
239
+ assert.calledOnce(eventFunc);
240
+ assert.calledWith(eventFunc, message.peripheralUuid, message.serviceUuid, message.includedServiceUuids);
241
+ });
242
+
243
+ it('_onMessage -> characteristicsDiscover', () => {
244
+ const eventFunc = fake.resolves(null);
245
+
246
+ const bindings = new Bindings();
247
+ bindings.on('characteristicsDiscover', eventFunc);
248
+
249
+ const message = Object.assign({}, baseMessage, { type: 'characteristicsDiscover' });
250
+ bindings._onMessage('ws', message);
251
+
252
+ assert.calledOnce(eventFunc);
253
+ assert.calledWith(eventFunc, message.peripheralUuid, message.serviceUuid, message.characteristics);
254
+ });
255
+
256
+ it('_onMessage -> read', () => {
257
+ const eventFunc = fake.resolves(null);
258
+
259
+ const bindings = new Bindings();
260
+ bindings.on('read', eventFunc);
261
+
262
+ const message = Object.assign({}, baseMessage, { type: 'read', data: '070809' });
263
+ bindings._onMessage('ws', message);
264
+
265
+ assert.calledOnce(eventFunc);
266
+ assert.calledWith(eventFunc, message.peripheralUuid, message.serviceUuid, message.characteristicUuid, Buffer.from([7, 8, 9]), message.isNotification);
267
+ });
268
+
269
+ it('_onMessage -> write', () => {
270
+ const eventFunc = fake.resolves(null);
271
+
272
+ const bindings = new Bindings();
273
+ bindings.on('write', eventFunc);
274
+
275
+ const message = Object.assign({}, baseMessage, { type: 'write' });
276
+ bindings._onMessage('ws', message);
277
+
278
+ assert.calledOnce(eventFunc);
279
+ assert.calledWith(eventFunc, message.peripheralUuid, message.serviceUuid, message.characteristicUuid);
280
+ });
281
+
282
+ it('_onMessage -> broadcast', () => {
283
+ const eventFunc = fake.resolves(null);
284
+
285
+ const bindings = new Bindings();
286
+ bindings.on('broadcast', eventFunc);
287
+
288
+ const message = Object.assign({}, baseMessage, { type: 'broadcast' });
289
+ bindings._onMessage('ws', message);
290
+
291
+ assert.calledOnce(eventFunc);
292
+ assert.calledWith(eventFunc, message.peripheralUuid, message.serviceUuid, message.characteristicUuid, message.state);
293
+ });
294
+
295
+ it('_onMessage -> notify', () => {
296
+ const eventFunc = fake.resolves(null);
297
+
298
+ const bindings = new Bindings();
299
+ bindings.on('notify', eventFunc);
300
+
301
+ const message = Object.assign({}, baseMessage, { type: 'notify' });
302
+ bindings._onMessage('ws', message);
303
+
304
+ assert.calledOnce(eventFunc);
305
+ assert.calledWith(eventFunc, message.peripheralUuid, message.serviceUuid, message.characteristicUuid, message.state);
306
+ });
307
+
308
+ it('_onMessage -> descriptorsDiscover', () => {
309
+ const eventFunc = fake.resolves(null);
310
+
311
+ const bindings = new Bindings();
312
+ bindings.on('descriptorsDiscover', eventFunc);
313
+
314
+ const message = Object.assign({}, baseMessage, { type: 'descriptorsDiscover' });
315
+ bindings._onMessage('ws', message);
316
+
317
+ assert.calledOnce(eventFunc);
318
+ assert.calledWith(eventFunc, message.peripheralUuid, message.serviceUuid, message.characteristicUuid, message.descriptors);
319
+ });
320
+
321
+ it('_onMessage -> valueRead', () => {
322
+ const eventFunc = fake.resolves(null);
323
+
324
+ const bindings = new Bindings();
325
+ bindings.on('valueRead', eventFunc);
326
+
327
+ const message = Object.assign({}, baseMessage, { type: 'valueRead', data: '070809' });
328
+ bindings._onMessage('ws', message);
329
+
330
+ assert.calledOnce(eventFunc);
331
+ assert.calledWith(eventFunc, message.peripheralUuid, message.serviceUuid, message.characteristicUuid, message.descriptorUuid, Buffer.from([7, 8, 9]));
332
+ });
333
+
334
+ it('_onMessage -> valueWrite', () => {
335
+ const eventFunc = fake.resolves(null);
336
+
337
+ const bindings = new Bindings();
338
+ bindings.on('valueWrite', eventFunc);
339
+
340
+ const message = Object.assign({}, baseMessage, { type: 'valueWrite' });
341
+ bindings._onMessage('ws', message);
342
+
343
+ assert.calledOnce(eventFunc);
344
+ assert.calledWith(eventFunc, message.peripheralUuid, message.serviceUuid, message.characteristicUuid, message.descriptorUuid);
345
+ });
346
+
347
+ it('_onMessage -> handleRead', () => {
348
+ const eventFunc = fake.resolves(null);
349
+
350
+ const bindings = new Bindings();
351
+ bindings.on('handleRead', eventFunc);
352
+
353
+ const message = Object.assign({}, baseMessage, { type: 'handleRead', data: '070809' });
354
+ bindings._onMessage('ws', message);
355
+
356
+ assert.calledOnce(eventFunc);
357
+ assert.calledWith(eventFunc, message.peripheralUuid, message.handle, Buffer.from([7, 8, 9]));
358
+ });
359
+
360
+ it('_onMessage -> handleWrite', () => {
361
+ const eventFunc = fake.resolves(null);
362
+
363
+ const bindings = new Bindings();
364
+ bindings.on('handleWrite', eventFunc);
365
+
366
+ const message = Object.assign({}, baseMessage, { type: 'handleWrite' });
367
+ bindings._onMessage('ws', message);
368
+
369
+ assert.calledOnce(eventFunc);
370
+ assert.calledWith(eventFunc, message.peripheralUuid, message.handle);
371
+ });
372
+
373
+ it('_onMessage -> handleNotify', () => {
374
+ const eventFunc = fake.resolves(null);
375
+
376
+ const bindings = new Bindings();
377
+ bindings.on('handleNotify', eventFunc);
378
+
379
+ const message = Object.assign({}, baseMessage, { type: 'handleNotify', data: '070809' });
380
+ bindings._onMessage('ws', message);
381
+
382
+ assert.calledOnce(eventFunc);
383
+ assert.calledWith(eventFunc, message.peripheralUuid, message.handle, Buffer.from([7, 8, 9]));
384
+ });
385
+
386
+ it('startScanning', () => {
387
+ const fakeSend = fake.returns(null);
388
+ const scanStart = fake.returns(null);
389
+
390
+ const bindings = new Bindings();
391
+ bindings._wss = { clients: [{ send: fakeSend }] };
392
+ bindings.on('scanStart', scanStart);
393
+
394
+ bindings.startScanning('service-uuids', 'allowDuplicates');
395
+
396
+ assert.calledOnce(fakeSend);
397
+ assert.calledWith(fakeSend, JSON.stringify({
398
+ action: 'startScanning',
399
+ serviceUuids: 'service-uuids',
400
+ allowDuplicates: 'allowDuplicates'
401
+ }));
402
+
403
+ assert.calledOnce(scanStart);
404
+ });
405
+
406
+ it('stopScanning', () => {
407
+ const fakeSend = fake.returns(null);
408
+ const scanStop = fake.returns(null);
409
+
410
+ const bindings = new Bindings();
411
+ bindings._wss = { clients: [{ send: fakeSend }] };
412
+ bindings.on('scanStop', scanStop);
413
+
414
+ bindings.stopScanning('device-uuid');
415
+
416
+ assert.calledOnce(fakeSend);
417
+ assert.calledWith(fakeSend, JSON.stringify({
418
+ action: 'stopScanning'
419
+ }));
420
+
421
+ assert.calledOnce(scanStop);
422
+ });
423
+
424
+ it('connect missing peripheral', () => {
425
+ try {
426
+ const bindings = new Bindings();
427
+ bindings.connect('device-uuid');
428
+ assert.fail('Should throw an error');
429
+ } catch (e) {
430
+ should(e).instanceOf(Error);
431
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
432
+ }
433
+ });
434
+
435
+ it('connect on existing peripheral', () => {
436
+ const fakeSend = fake.returns(null);
437
+
438
+ const bindings = new Bindings();
439
+ bindings._peripherals['device-uuid'] = {
440
+ ws: {
441
+ send: fakeSend
442
+ },
443
+ uuid: 'peripheral-uuid'
444
+ };
445
+
446
+ bindings.connect('device-uuid');
447
+
448
+ assert.calledOnce(fakeSend);
449
+ assert.calledWith(fakeSend, JSON.stringify({
450
+ action: 'connect',
451
+ peripheralUuid: 'peripheral-uuid'
452
+ }));
453
+ });
454
+
455
+ it('disconnect missing peripheral', () => {
456
+ try {
457
+ const bindings = new Bindings();
458
+ bindings.disconnect('device-uuid');
459
+ assert.fail('Should throw an error');
460
+ } catch (e) {
461
+ should(e).instanceOf(Error);
462
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
463
+ }
464
+ });
465
+
466
+ it('disconnect on existing peripheral', () => {
467
+ const fakeSend = fake.returns(null);
468
+
469
+ const bindings = new Bindings();
470
+ bindings._peripherals['device-uuid'] = {
471
+ ws: {
472
+ send: fakeSend
473
+ },
474
+ uuid: 'peripheral-uuid'
475
+ };
476
+
477
+ bindings.disconnect('device-uuid');
478
+
479
+ assert.calledOnce(fakeSend);
480
+ assert.calledWith(fakeSend, JSON.stringify({
481
+ action: 'disconnect',
482
+ peripheralUuid: 'peripheral-uuid'
483
+ }));
484
+ });
485
+
486
+ it('updateRssi missing peripheral', () => {
487
+ try {
488
+ const bindings = new Bindings();
489
+ bindings.updateRssi('device-uuid');
490
+ assert.fail('Should throw an error');
491
+ } catch (e) {
492
+ should(e).instanceOf(Error);
493
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
494
+ }
495
+ });
496
+
497
+ it('updateRssi on existing peripheral', () => {
498
+ const fakeSend = fake.returns(null);
499
+
500
+ const bindings = new Bindings();
501
+ bindings._peripherals['device-uuid'] = {
502
+ ws: {
503
+ send: fakeSend
504
+ },
505
+ uuid: 'peripheral-uuid'
506
+ };
507
+
508
+ bindings.updateRssi('device-uuid');
509
+
510
+ assert.calledOnce(fakeSend);
511
+ assert.calledWith(fakeSend, JSON.stringify({
512
+ action: 'updateRssi',
513
+ peripheralUuid: 'peripheral-uuid'
514
+ }));
515
+ });
516
+
517
+ it('discoverServices missing peripheral', () => {
518
+ try {
519
+ const bindings = new Bindings();
520
+ bindings.discoverServices('device-uuid', 'service-uuids');
521
+ assert.fail('Should throw an error');
522
+ } catch (e) {
523
+ should(e).instanceOf(Error);
524
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
525
+ }
526
+ });
527
+
528
+ it('discoverServices on existing peripheral', () => {
529
+ const fakeSend = fake.returns(null);
530
+
531
+ const bindings = new Bindings();
532
+ bindings._peripherals['device-uuid'] = {
533
+ ws: {
534
+ send: fakeSend
535
+ },
536
+ uuid: 'peripheral-uuid'
537
+ };
538
+
539
+ bindings.discoverServices('device-uuid', 'service-uuids');
540
+
541
+ assert.calledOnce(fakeSend);
542
+ assert.calledWith(fakeSend, JSON.stringify({
543
+ action: 'discoverServices',
544
+ peripheralUuid: 'peripheral-uuid',
545
+ uuids: 'service-uuids'
546
+ }));
547
+ });
548
+
549
+ it('discoverIncludedServices missing peripheral', () => {
550
+ try {
551
+ const bindings = new Bindings();
552
+ bindings.discoverIncludedServices('device-uuid', 'service-uuid', 'service-uuids');
553
+ assert.fail('Should throw an error');
554
+ } catch (e) {
555
+ should(e).instanceOf(Error);
556
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
557
+ }
558
+ });
559
+
560
+ it('discoverIncludedServices on existing peripheral', () => {
561
+ const fakeSend = fake.returns(null);
562
+
563
+ const bindings = new Bindings();
564
+ bindings._peripherals['device-uuid'] = {
565
+ ws: {
566
+ send: fakeSend
567
+ },
568
+ uuid: 'peripheral-uuid'
569
+ };
570
+
571
+ bindings.discoverIncludedServices('device-uuid', 'service-uuid', 'service-uuids');
572
+
573
+ assert.calledOnce(fakeSend);
574
+ assert.calledWith(fakeSend, JSON.stringify({
575
+ action: 'discoverIncludedServices',
576
+ peripheralUuid: 'peripheral-uuid',
577
+ serviceUuid: 'service-uuid',
578
+ serviceUuids: 'service-uuids'
579
+ }));
580
+ });
581
+
582
+ it('discoverCharacteristics missing peripheral', () => {
583
+ try {
584
+ const bindings = new Bindings();
585
+ bindings.discoverCharacteristics('device-uuid', 'service-uuid', 'char-uuid');
586
+ assert.fail('Should throw an error');
587
+ } catch (e) {
588
+ should(e).instanceOf(Error);
589
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
590
+ }
591
+ });
592
+
593
+ it('discoverCharacteristics on existing peripheral', () => {
594
+ const fakeSend = fake.returns(null);
595
+
596
+ const bindings = new Bindings();
597
+ bindings._peripherals['device-uuid'] = {
598
+ ws: {
599
+ send: fakeSend
600
+ },
601
+ uuid: 'peripheral-uuid'
602
+ };
603
+
604
+ bindings.discoverCharacteristics('device-uuid', 'service-uuid', 'char-uuid');
605
+
606
+ assert.calledOnce(fakeSend);
607
+ assert.calledWith(fakeSend, JSON.stringify({
608
+ action: 'discoverCharacteristics',
609
+ peripheralUuid: 'peripheral-uuid',
610
+ serviceUuid: 'service-uuid',
611
+ characteristicUuids: 'char-uuid'
612
+ }));
613
+ });
614
+
615
+ it('read missing peripheral', () => {
616
+ try {
617
+ const bindings = new Bindings();
618
+ bindings.read('device-uuid', 'service-uuid', 'char-uuid');
619
+ assert.fail('Should throw an error');
620
+ } catch (e) {
621
+ should(e).instanceOf(Error);
622
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
623
+ }
624
+ });
625
+
626
+ it('read on existing peripheral', () => {
627
+ const fakeSend = fake.returns(null);
628
+
629
+ const bindings = new Bindings();
630
+ bindings._peripherals['device-uuid'] = {
631
+ ws: {
632
+ send: fakeSend
633
+ },
634
+ uuid: 'peripheral-uuid'
635
+ };
636
+
637
+ bindings.read('device-uuid', 'service-uuid', 'char-uuid');
638
+
639
+ assert.calledOnce(fakeSend);
640
+ assert.calledWith(fakeSend, JSON.stringify({
641
+ action: 'read',
642
+ peripheralUuid: 'peripheral-uuid',
643
+ serviceUuid: 'service-uuid',
644
+ characteristicUuid: 'char-uuid'
645
+ }));
646
+ });
647
+
648
+ it('write missing peripheral', () => {
649
+ try {
650
+ const bindings = new Bindings();
651
+ bindings.write('device-uuid', 'service-uuid', 'char-uuid', 'data', 'withoutReponse');
652
+ assert.fail('Should throw an error');
653
+ } catch (e) {
654
+ should(e).instanceOf(Error);
655
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
656
+ }
657
+ });
658
+
659
+ it('write on existing peripheral', () => {
660
+ const fakeSend = fake.returns(null);
661
+
662
+ const bindings = new Bindings();
663
+ bindings._peripherals['device-uuid'] = {
664
+ ws: {
665
+ send: fakeSend
666
+ },
667
+ uuid: 'peripheral-uuid'
668
+ };
669
+
670
+ bindings.write('device-uuid', 'service-uuid', 'char-uuid', '01', 'withoutResponse');
671
+
672
+ assert.calledOnce(fakeSend);
673
+ assert.calledWith(fakeSend, JSON.stringify({
674
+ action: 'write',
675
+ peripheralUuid: 'peripheral-uuid',
676
+ serviceUuid: 'service-uuid',
677
+ characteristicUuid: 'char-uuid',
678
+ data: '01',
679
+ withoutResponse: 'withoutResponse'
680
+ }));
681
+ });
682
+
683
+ it('broadcast missing peripheral', () => {
684
+ try {
685
+ const bindings = new Bindings();
686
+ bindings.broadcast('device-uuid', 'service-uuid', 'char-uuid', 'broadcast');
687
+ assert.fail('Should throw an error');
688
+ } catch (e) {
689
+ should(e).instanceOf(Error);
690
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
691
+ }
692
+ });
693
+
694
+ it('broadcast on existing peripheral', () => {
695
+ const fakeSend = fake.returns(null);
696
+
697
+ const bindings = new Bindings();
698
+ bindings._peripherals['device-uuid'] = {
699
+ ws: {
700
+ send: fakeSend
701
+ },
702
+ uuid: 'peripheral-uuid'
703
+ };
704
+
705
+ bindings.broadcast('device-uuid', 'service-uuid', 'char-uuid', '01');
706
+
707
+ assert.calledOnce(fakeSend);
708
+ assert.calledWith(fakeSend, JSON.stringify({
709
+ action: 'broadcast',
710
+ peripheralUuid: 'peripheral-uuid',
711
+ serviceUuid: 'service-uuid',
712
+ characteristicUuid: 'char-uuid',
713
+ broadcast: '01'
714
+ }));
715
+ });
716
+
717
+ it('notify missing peripheral', () => {
718
+ try {
719
+ const bindings = new Bindings();
720
+ bindings.notify('device-uuid', 'service-uuid', 'char-uuid', 'notify');
721
+ assert.fail('Should throw an error');
722
+ } catch (e) {
723
+ should(e).instanceOf(Error);
724
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
725
+ }
726
+ });
727
+
728
+ it('notify on existing peripheral', () => {
729
+ const fakeSend = fake.returns(null);
730
+
731
+ const bindings = new Bindings();
732
+ bindings._peripherals['device-uuid'] = {
733
+ ws: {
734
+ send: fakeSend
735
+ },
736
+ uuid: 'peripheral-uuid'
737
+ };
738
+
739
+ bindings.notify('device-uuid', 'service-uuid', 'char-uuid', '01');
740
+
741
+ assert.calledOnce(fakeSend);
742
+ assert.calledWith(fakeSend, JSON.stringify({
743
+ action: 'notify',
744
+ peripheralUuid: 'peripheral-uuid',
745
+ serviceUuid: 'service-uuid',
746
+ characteristicUuid: 'char-uuid',
747
+ notify: '01'
748
+ }));
749
+ });
750
+
751
+ it('discoverDescriptors missing peripheral', () => {
752
+ try {
753
+ const bindings = new Bindings();
754
+ bindings.discoverDescriptors('device-uuid', 'service-uuid', 'char-uuid');
755
+ assert.fail('Should throw an error');
756
+ } catch (e) {
757
+ should(e).instanceOf(Error);
758
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
759
+ }
760
+ });
761
+
762
+ it('discoverDescriptors on existing peripheral', () => {
763
+ const fakeSend = fake.returns(null);
764
+
765
+ const bindings = new Bindings();
766
+ bindings._peripherals['device-uuid'] = {
767
+ ws: {
768
+ send: fakeSend
769
+ },
770
+ uuid: 'peripheral-uuid'
771
+ };
772
+
773
+ bindings.discoverDescriptors('device-uuid', 'service-uuid', 'char-uuid');
774
+
775
+ assert.calledOnce(fakeSend);
776
+ assert.calledWith(fakeSend, JSON.stringify({
777
+ action: 'discoverDescriptors',
778
+ peripheralUuid: 'peripheral-uuid',
779
+ serviceUuid: 'service-uuid',
780
+ characteristicUuid: 'char-uuid'
781
+ }));
782
+ });
783
+
784
+ it('readValue missing peripheral', () => {
785
+ try {
786
+ const bindings = new Bindings();
787
+ bindings.readValue('device-uuid', 'service-uuid', 'char-uuid', 'descr-uuid');
788
+ assert.fail('Should throw an error');
789
+ } catch (e) {
790
+ should(e).instanceOf(Error);
791
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
792
+ }
793
+ });
794
+
795
+ it('readValue on existing peripheral', () => {
796
+ const fakeSend = fake.returns(null);
797
+
798
+ const bindings = new Bindings();
799
+ bindings._peripherals['device-uuid'] = {
800
+ ws: {
801
+ send: fakeSend
802
+ },
803
+ uuid: 'peripheral-uuid'
804
+ };
805
+
806
+ bindings.readValue('device-uuid', 'service-uuid', 'char-uuid', 'descr-uuid');
807
+
808
+ assert.calledOnce(fakeSend);
809
+ assert.calledWith(fakeSend, JSON.stringify({
810
+ action: 'readValue',
811
+ peripheralUuid: 'peripheral-uuid',
812
+ serviceUuid: 'service-uuid',
813
+ characteristicUuid: 'char-uuid',
814
+ descriptorUuid: 'descr-uuid'
815
+ }));
816
+ });
817
+
818
+ it('writeValue missing peripheral', () => {
819
+ try {
820
+ const bindings = new Bindings();
821
+ bindings.writeValue('device-uuid', 'service-uuid', 'char-uuid', 'descr-uuid', '01');
822
+ assert.fail('Should throw an error');
823
+ } catch (e) {
824
+ should(e).instanceOf(Error);
825
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
826
+ }
827
+ });
828
+
829
+ it('writeValue on existing peripheral', () => {
830
+ const fakeSend = fake.returns(null);
831
+
832
+ const bindings = new Bindings();
833
+ bindings._peripherals['device-uuid'] = {
834
+ ws: {
835
+ send: fakeSend
836
+ },
837
+ uuid: 'peripheral-uuid'
838
+ };
839
+
840
+ bindings.writeValue('device-uuid', 'service-uuid', 'char-uuid', 'descr-uuid', '01');
841
+
842
+ assert.calledOnce(fakeSend);
843
+ assert.calledWith(fakeSend, JSON.stringify({
844
+ action: 'writeValue',
845
+ peripheralUuid: 'peripheral-uuid',
846
+ serviceUuid: 'service-uuid',
847
+ characteristicUuid: 'char-uuid',
848
+ descriptorUuid: 'descr-uuid',
849
+ data: '01'
850
+ }));
851
+ });
852
+
853
+ it('readHandle missing peripheral', () => {
854
+ try {
855
+ const bindings = new Bindings();
856
+ bindings.readHandle('device-uuid', 'handle');
857
+ assert.fail('Should throw an error');
858
+ } catch (e) {
859
+ should(e).instanceOf(Error);
860
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
861
+ }
862
+ });
863
+
864
+ it('readHandle on existing peripheral', () => {
865
+ const fakeSend = fake.returns(null);
866
+
867
+ const bindings = new Bindings();
868
+ bindings._peripherals['device-uuid'] = {
869
+ ws: {
870
+ send: fakeSend
871
+ },
872
+ uuid: 'peripheral-uuid'
873
+ };
874
+
875
+ bindings.readHandle('device-uuid', 'handle');
876
+
877
+ assert.calledOnce(fakeSend);
878
+ assert.calledWith(fakeSend, JSON.stringify({
879
+ action: 'readHandle',
880
+ peripheralUuid: 'peripheral-uuid',
881
+ handle: 'handle'
882
+ }));
883
+ });
884
+
885
+ it('writeHandle missing peripheral', () => {
886
+ try {
887
+ const bindings = new Bindings();
888
+ bindings.writeHandle('device-uuid', 'handle', 'data', 'withoutResponse');
889
+ assert.fail('Should throw an error');
890
+ } catch (e) {
891
+ should(e).instanceOf(Error);
892
+ should(e.message).eql('Cannot read property \'ws\' of undefined');
893
+ }
894
+ });
895
+
896
+ it('writeHandle on existing peripheral', () => {
897
+ const fakeSend = fake.returns(null);
898
+
899
+ const bindings = new Bindings();
900
+ bindings._peripherals['device-uuid'] = {
901
+ ws: {
902
+ send: fakeSend
903
+ },
904
+ uuid: 'peripheral-uuid'
905
+ };
906
+
907
+ bindings.writeHandle('device-uuid', 'handle', 'data', 'withoutResponse');
908
+
909
+ assert.calledOnce(fakeSend);
910
+ assert.calledWith(fakeSend, JSON.stringify({
911
+ action: 'readHandle',
912
+ peripheralUuid: 'peripheral-uuid',
913
+ handle: 'handle',
914
+ data: 'data',
915
+ withoutResponse: 'withoutResponse'
916
+ }));
917
+ });
918
+ });