@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.
- package/.editorconfig +11 -0
- package/.eslintrc.js +25 -0
- package/.github/FUNDING.yml +2 -0
- package/.github/workflows/fediverse-action.yml +16 -0
- package/.github/workflows/nodepackage.yml +77 -0
- package/.github/workflows/npm-publish.yml +26 -0
- package/.github/workflows/prebuild.yml +65 -0
- package/.nycrc.json +4 -0
- package/CHANGELOG.md +119 -0
- package/LICENSE +20 -0
- package/MAINTAINERS.md +1 -0
- package/README.md +833 -0
- package/assets/noble-logo.png +0 -0
- package/assets/noble-logo.svg +13 -0
- package/binding.gyp +19 -0
- package/codecov.yml +5 -0
- package/examples/advertisement-discovery.js +65 -0
- package/examples/cache-gatt-discovery.js +198 -0
- package/examples/cache-gatt-reconnect.js +164 -0
- package/examples/echo.js +104 -0
- package/examples/enter-exit.js +78 -0
- package/examples/peripheral-explorer-async.js +133 -0
- package/examples/peripheral-explorer.js +225 -0
- package/examples/pizza/README.md +15 -0
- package/examples/pizza/central.js +194 -0
- package/examples/pizza/pizza.js +60 -0
- package/index.d.ts +203 -0
- package/index.js +6 -0
- package/lib/characteristic.js +161 -0
- package/lib/characteristics.json +449 -0
- package/lib/descriptor.js +72 -0
- package/lib/descriptors.json +47 -0
- package/lib/distributed/bindings.js +326 -0
- package/lib/hci-socket/acl-stream.js +60 -0
- package/lib/hci-socket/bindings.js +788 -0
- package/lib/hci-socket/crypto.js +74 -0
- package/lib/hci-socket/gap.js +432 -0
- package/lib/hci-socket/gatt.js +809 -0
- package/lib/hci-socket/hci-status.json +71 -0
- package/lib/hci-socket/hci.js +1264 -0
- package/lib/hci-socket/signaling.js +76 -0
- package/lib/hci-socket/smp.js +140 -0
- package/lib/hci-uart/bindings.js +569 -0
- package/lib/hci-uart/hci-serial-parser.js +70 -0
- package/lib/hci-uart/hci.js +1336 -0
- package/lib/mac/binding.gyp +26 -0
- package/lib/mac/bindings.js +11 -0
- package/lib/mac/src/ble_manager.h +41 -0
- package/lib/mac/src/ble_manager.mm +435 -0
- package/lib/mac/src/callbacks.cc +222 -0
- package/lib/mac/src/callbacks.h +84 -0
- package/lib/mac/src/napi_objc.h +12 -0
- package/lib/mac/src/napi_objc.mm +50 -0
- package/lib/mac/src/noble_mac.h +34 -0
- package/lib/mac/src/noble_mac.mm +264 -0
- package/lib/mac/src/objc_cpp.h +26 -0
- package/lib/mac/src/objc_cpp.mm +126 -0
- package/lib/mac/src/peripheral.h +23 -0
- package/lib/manufacture.js +48 -0
- package/lib/noble.js +593 -0
- package/lib/peripheral.js +219 -0
- package/lib/resolve-bindings-web.js +9 -0
- package/lib/resolve-bindings.js +44 -0
- package/lib/service.js +72 -0
- package/lib/services.json +92 -0
- package/lib/webbluetooth/bindings.js +368 -0
- package/lib/websocket/bindings.js +321 -0
- package/lib/win/binding.gyp +23 -0
- package/lib/win/bindings.js +11 -0
- package/lib/win/src/ble_manager.cc +802 -0
- package/lib/win/src/ble_manager.h +77 -0
- package/lib/win/src/callbacks.cc +274 -0
- package/lib/win/src/callbacks.h +33 -0
- package/lib/win/src/napi_winrt.cc +76 -0
- package/lib/win/src/napi_winrt.h +12 -0
- package/lib/win/src/noble_winrt.cc +308 -0
- package/lib/win/src/noble_winrt.h +34 -0
- package/lib/win/src/notify_map.cc +62 -0
- package/lib/win/src/notify_map.h +50 -0
- package/lib/win/src/peripheral.h +23 -0
- package/lib/win/src/peripheral_winrt.cc +296 -0
- package/lib/win/src/peripheral_winrt.h +82 -0
- package/lib/win/src/radio_watcher.cc +125 -0
- package/lib/win/src/radio_watcher.h +61 -0
- package/lib/win/src/winrt_cpp.cc +82 -0
- package/lib/win/src/winrt_cpp.h +11 -0
- package/lib/win/src/winrt_guid.cc +12 -0
- package/lib/win/src/winrt_guid.h +13 -0
- package/misc/nrf52840dk.hex +6921 -0
- package/misc/prj.conf +43 -0
- package/package.json +96 -0
- package/test/lib/characteristic.test.js +791 -0
- package/test/lib/descriptor.test.js +249 -0
- package/test/lib/distributed/bindings.test.js +918 -0
- package/test/lib/hci-socket/acl-stream.test.js +188 -0
- package/test/lib/hci-socket/bindings.test.js +1756 -0
- package/test/lib/hci-socket/crypto.test.js +55 -0
- package/test/lib/hci-socket/gap.test.js +1089 -0
- package/test/lib/hci-socket/gatt.test.js +2392 -0
- package/test/lib/hci-socket/hci.test.js +1891 -0
- package/test/lib/hci-socket/signaling.test.js +94 -0
- package/test/lib/hci-socket/smp.test.js +268 -0
- package/test/lib/manufacture.test.js +77 -0
- package/test/lib/peripheral.test.js +623 -0
- package/test/lib/resolve-bindings.test.js +102 -0
- package/test/lib/service.test.js +195 -0
- package/test/lib/webbluetooth/bindings.test.js +190 -0
- package/test/lib/websocket/bindings.test.js +456 -0
- package/test/noble.test.js +1565 -0
- package/test.js +131 -0
- package/with-bindings.js +5 -0
- 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
|
+
});
|