@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,368 @@
1
+ const util = require('util');
2
+ const events = require('events');
3
+
4
+ const debug = require('debug')('webble-bindings');
5
+
6
+ function makeList (uuid) {
7
+ return { services: [uuid] };
8
+ }
9
+
10
+ function addDashes (uuid) {
11
+ if (!uuid || typeof uuid !== 'string') {
12
+ return uuid;
13
+ }
14
+ if (uuid && uuid.length === 32) {
15
+ uuid = `${uuid.substring(0, 8)}-${uuid.substring(8, 12)}-${uuid.substring(12, 16)}-${uuid.substring(16, 20)}-${uuid.substring(20)}`;
16
+ }
17
+ return uuid.toLowerCase();
18
+ }
19
+
20
+ function stripDashes (uuid) {
21
+ if (typeof uuid === 'string') {
22
+ uuid = uuid.split('-').join('');
23
+ }
24
+ return uuid;
25
+ }
26
+
27
+ const NobleBindings = function () {
28
+ this._ble = null;
29
+ this._startScanCommand = null;
30
+ this._peripherals = {};
31
+ };
32
+ util.inherits(NobleBindings, events.EventEmitter);
33
+
34
+ NobleBindings.prototype.init = function (ble) {
35
+ if (ble) {
36
+ this._ble = ble;
37
+ } else {
38
+ this._ble = navigator.bluetooth;
39
+ }
40
+
41
+ const self = this;
42
+ process.nextTick(() => {
43
+ debug('initing');
44
+ if (!self._ble) {
45
+ return self.emit('error', new Error('This browser does not support WebBluetooth.'));
46
+ }
47
+ debug('emit powered on');
48
+ self.emit('stateChange', 'poweredOn');
49
+ });
50
+ };
51
+
52
+ NobleBindings.prototype.onOpen = function () {
53
+ debug('on -> open');
54
+ };
55
+
56
+ NobleBindings.prototype.onClose = function () {
57
+ debug('on -> close');
58
+
59
+ this.emit('stateChange', 'poweredOff');
60
+ };
61
+
62
+ NobleBindings.prototype.startScanning = function (options, allowDuplicates) {
63
+ const self = this;
64
+
65
+ if (Array.isArray(options)) {
66
+ options = { services: options };
67
+ }
68
+
69
+ if (typeof options !== 'object') {
70
+ options = { services: options };
71
+ }
72
+
73
+ if (!Array.isArray(options.services)) {
74
+ options.services = [options.services];
75
+ }
76
+
77
+ options.services = options.services.map(service => {
78
+ // web bluetooth requires 4 char hex service names to be passed in as integers
79
+ if (typeof service === 'string' && service.length === 4) {
80
+ service = parseInt(`0x${service}`);
81
+ } else if (typeof service === 'string' && service.length === 6 && service.indexOf('0x') === 0) {
82
+ service = parseInt(service);
83
+ }
84
+ return service;
85
+ });
86
+
87
+ const dashedUuids = options.services.map(addDashes);
88
+
89
+ const filterList = dashedUuids.map(makeList);
90
+ if (options.name) {
91
+ filterList.push({ name: options.name });
92
+ }
93
+ if (options.namePrefix) {
94
+ filterList.push({ namePrefix: options.namePrefix });
95
+ }
96
+
97
+ const request = { filters: filterList };
98
+
99
+ debug('startScanning', request, allowDuplicates);
100
+
101
+ this._ble.requestDevice(request)
102
+ .then(device => {
103
+ debug('scan finished', device);
104
+ self.emit('scanStop', {});
105
+ if (device) {
106
+ const address = device.id;
107
+ // TODO use device.adData when api is ready
108
+ // rssi = device.adData.rssi;
109
+
110
+ self._peripherals[address] = {
111
+ uuid: address,
112
+ address: address,
113
+ advertisement: { localName: device.name }, // advertisement,
114
+ device: device,
115
+ cachedServices: {},
116
+ localName: device.name,
117
+ serviceUuids: options.services
118
+ };
119
+ if (device.adData) {
120
+ self._peripherals[address].rssi = device.adData.rssi;
121
+ }
122
+
123
+ self.emit('discover', device.id, device.id, device.addressType, !device.paired, self._peripherals[address].advertisement, self._peripherals[address].rssi);
124
+ }
125
+ })
126
+ .catch(err => {
127
+ debug('err scanning', err);
128
+ self.emit('scanStop', {});
129
+ self.emit('error', err);
130
+ });
131
+
132
+ this.emit('scanStart');
133
+ };
134
+
135
+ NobleBindings.prototype.stopScanning = function () {
136
+ this._startScanCommand = null;
137
+
138
+ // TODO: need web api completed for this to work'=
139
+ this.emit('scanStop');
140
+ };
141
+
142
+ NobleBindings.prototype.connect = function (deviceUuid) {
143
+ const self = this;
144
+ debug('connect', deviceUuid);
145
+ const peripheral = this._peripherals[deviceUuid];
146
+ // clear any cached services in case this is a reconnect
147
+ peripheral.cachedServices = {};
148
+
149
+ // Attempts to connect to remote GATT Server.
150
+ peripheral.device.gatt.connect()
151
+ .then(gattServer => {
152
+ debug('peripheral connected', gattServer);
153
+
154
+ const onDisconnected = function (event) {
155
+ debug('disconnected', peripheral.uuid);
156
+ self.emit('disconnect', peripheral.uuid);
157
+ };
158
+ peripheral.device.addEventListener('gattserverdisconnected', onDisconnected, { once: true });
159
+
160
+ self.emit('connect', deviceUuid);
161
+ }, err => {
162
+ debug('err connecting', err);
163
+ self.emit('connect', deviceUuid, err);
164
+ });
165
+ };
166
+
167
+ NobleBindings.prototype.disconnect = function (deviceUuid) {
168
+ const peripheral = this._peripherals[deviceUuid];
169
+ if (peripheral.device.gatt) {
170
+ peripheral.device.gatt.disconnect();
171
+ this.emit('disconnect', deviceUuid);
172
+ }
173
+ };
174
+
175
+ NobleBindings.prototype.updateRssi = function (deviceUuid) {
176
+ // TODO: need web api completed for this to work
177
+ // var peripheral = this._peripherals[deviceUuid];
178
+ // this.emit('rssiUpdate', deviceUuid, rssi);
179
+ };
180
+
181
+ NobleBindings.prototype.discoverServices = function (deviceUuid, uuids) {
182
+ const peripheral = this._peripherals[deviceUuid];
183
+
184
+ // TODO: need web api completed for this to work
185
+ if (peripheral) {
186
+ this.emit('servicesDiscover', deviceUuid, peripheral.serviceUuids);
187
+ }
188
+ };
189
+
190
+ NobleBindings.prototype.discoverIncludedServices = function (deviceUuid, serviceUuid, serviceUuids) {
191
+ // TODO impelment when web API has functionatility then emit response
192
+ // var peripheral = this._peripherals[deviceUuid];
193
+ // this.emit('includedServicesDiscover', deviceUuid, serviceUuid, includedServiceUuids);
194
+ };
195
+
196
+ NobleBindings.prototype.discoverCharacteristics = function (deviceUuid, serviceUuid, characteristicUuids) {
197
+ const self = this;
198
+ const peripheral = self._peripherals[deviceUuid];
199
+
200
+ if (peripheral) {
201
+ self.getPrimaryService(peripheral, serviceUuid)
202
+ .then(service => service.getCharacteristics())
203
+ .then(characteristics => {
204
+ const discoveredCharacteristics = characteristics.map(char => {
205
+ const charInfo = { uuid: stripDashes(char.uuid), properties: [] };
206
+
207
+ if (char.properties.writeWithoutResponse) {
208
+ charInfo.properties.push('writeWithoutResponse');
209
+ }
210
+
211
+ if (char.properties.write) {
212
+ charInfo.properties.push('write');
213
+ }
214
+
215
+ if (char.properties.read) {
216
+ charInfo.properties.push('read');
217
+ }
218
+
219
+ if (char.properties.notify) {
220
+ charInfo.properties.push('notify');
221
+ }
222
+
223
+ return charInfo;
224
+ });
225
+
226
+ debug('discoverCharacteristics', deviceUuid, serviceUuid, discoveredCharacteristics);
227
+ self.emit('characteristicsDiscover', deviceUuid, serviceUuid, discoveredCharacteristics);
228
+ });
229
+ }
230
+ };
231
+
232
+ NobleBindings.prototype.getPrimaryService = function (peripheral, serviceUuid) {
233
+ serviceUuid = addDashes(serviceUuid);
234
+
235
+ if (peripheral.cachedServices[serviceUuid]) {
236
+ return new Promise((resolve, reject) => {
237
+ resolve(peripheral.cachedServices[serviceUuid]);
238
+ });
239
+ }
240
+
241
+ return peripheral.device.gatt.getPrimaryService(serviceUuid)
242
+ .then(service => {
243
+ peripheral.cachedServices[serviceUuid] = service;
244
+ return service;
245
+ });
246
+ };
247
+
248
+ NobleBindings.prototype.read = function (deviceUuid, serviceUuid, characteristicUuid) {
249
+ const self = this;
250
+ const peripheral = this._peripherals[deviceUuid];
251
+ debug('read', deviceUuid, serviceUuid, characteristicUuid);
252
+
253
+ self.getPrimaryService(peripheral, serviceUuid)
254
+ .then(service => service.getCharacteristic(addDashes(characteristicUuid)))
255
+ .then(characteristic => characteristic.readValue())
256
+ .then(data => {
257
+ self.emit('read', peripheral.uuid, serviceUuid, characteristicUuid, Buffer.from(data.buffer), false);
258
+ })
259
+ .catch(err => {
260
+ debug('error reading characteristic', err);
261
+ self.emit('error', err);
262
+ });
263
+ };
264
+
265
+ NobleBindings.prototype.write = function (deviceUuid, serviceUuid, characteristicUuid, data, withoutResponse) {
266
+ const self = this;
267
+ const peripheral = this._peripherals[deviceUuid];
268
+ debug('write', deviceUuid, serviceUuid, characteristicUuid, data, withoutResponse);
269
+
270
+ self.getPrimaryService(peripheral, serviceUuid)
271
+ .then(service => service.getCharacteristic(addDashes(characteristicUuid)))
272
+ .then(characteristic => characteristic.writeValue(data))
273
+ .then(() => {
274
+ debug('value written');
275
+ self.emit('write', peripheral.uuid, serviceUuid, characteristicUuid);
276
+ })
277
+ .catch(err => {
278
+ debug('error writing to characteristic', serviceUuid, characteristicUuid, err);
279
+ });
280
+ };
281
+
282
+ NobleBindings.prototype.broadcast = function (deviceUuid, serviceUuid, characteristicUuid, broadcast) {
283
+ // TODO impelment when web API has functionatility then emit response
284
+ // var peripheral = this._peripherals[deviceUuid];
285
+ // this.emit('broadcast', deviceUuid, serviceUuid, characteristicUuid, state);
286
+ };
287
+
288
+ NobleBindings.prototype.notify = function (deviceUuid, serviceUuid, characteristicUuid, notify) {
289
+ const self = this;
290
+ const peripheral = this._peripherals[deviceUuid];
291
+
292
+ const charPromise = self.getPrimaryService(peripheral, serviceUuid)
293
+ .then(service => service.getCharacteristic(addDashes(characteristicUuid)));
294
+
295
+ peripheral.notifcationListeners = peripheral.notifcationListeners || {};
296
+
297
+ if (notify) {
298
+ charPromise.then(characteristic => characteristic.startNotifications())
299
+ .then(characteristic => {
300
+ debug('notifications started', characteristicUuid);
301
+ peripheral.notifcationListeners[`${serviceUuid}__${characteristicUuid}`] = function (evt) {
302
+ debug('oncharacteristicvaluechanged', evt, Buffer.from(evt.target.value.buffer));
303
+ self.emit('read', deviceUuid, serviceUuid, characteristicUuid, Buffer.from(evt.target.value.buffer), true);
304
+ };
305
+ characteristic.addEventListener('characteristicvaluechanged', peripheral.notifcationListeners[`${serviceUuid}__${characteristicUuid}`]);
306
+
307
+ const onDisconnected = function () {
308
+ characteristic.removeEventListener('characteristicvaluechanged', peripheral.notifcationListeners[`${serviceUuid}__${characteristicUuid}`]);
309
+ delete peripheral.notifcationListeners[`${serviceUuid}__${characteristicUuid}`];
310
+ };
311
+ peripheral.device.addEventListener('gattserverdisconnected', onDisconnected, { once: true });
312
+
313
+ self.emit('notify', deviceUuid, serviceUuid, characteristicUuid, true);
314
+ return characteristic;
315
+ })
316
+ .catch(err => {
317
+ debug('error enabling notifications on characteristic', err);
318
+ self.emit('error', err);
319
+ });
320
+ } else {
321
+ charPromise.then(characteristic => characteristic.stopNotifications())
322
+ .then(characteristic => {
323
+ debug('notifications stopped', characteristic);
324
+ if (peripheral.notifcationListeners[`${serviceUuid}__${characteristicUuid}`]) {
325
+ characteristic.removeEventListener('characteristicvaluechanged', peripheral.notifcationListeners[`${serviceUuid}__${characteristicUuid}`]);
326
+ delete peripheral.notifcationListeners[`${serviceUuid}__${characteristicUuid}`];
327
+ }
328
+ self.emit('notify', deviceUuid, serviceUuid, characteristicUuid, false);
329
+ return characteristic;
330
+ })
331
+ .catch(err => {
332
+ debug('error disabling notifications on characteristic', err);
333
+ self.emit('error', err);
334
+ });
335
+ }
336
+ };
337
+
338
+ NobleBindings.prototype.discoverDescriptors = function (deviceUuid, serviceUuid, characteristicUuid) {
339
+ // TODO impelment when web API has functionatility then emit response
340
+ // var peripheral = this._peripherals[deviceUuid];
341
+ // this.emit('descriptorsDiscover', deviceUuid, serviceUuid, characteristicUuid, descriptors);
342
+ };
343
+
344
+ NobleBindings.prototype.readValue = function (deviceUuid, serviceUuid, characteristicUuid, descriptorUuid) {
345
+ // TODO impelment when web API has functionatility then emit response
346
+ // var peripheral = this._peripherals[deviceUuid];
347
+ // this.emit('valueRead', deviceUuid, serviceUuid, characteristicUuid, descriptorUuid, data);
348
+ };
349
+
350
+ NobleBindings.prototype.writeValue = function (deviceUuid, serviceUuid, characteristicUuid, descriptorUuid, data) {
351
+ // TODO impelment when web API has functionatility then emit response
352
+ // var peripheral = this._peripherals[deviceUuid];
353
+ // this.emit('valueWrite', deviceUuid, serviceUuid, characteristicUuid, descriptorUuid);
354
+ };
355
+
356
+ NobleBindings.prototype.readHandle = function (deviceUuid, handle) {
357
+ // TODO impelment when web API has functionatility then emit response
358
+ // var peripheral = this._peripherals[deviceUuid];
359
+ // this.emit('handleRead', deviceUuid, handle, data);
360
+ };
361
+
362
+ NobleBindings.prototype.writeHandle = function (deviceUuid, handle, data, withoutResponse) {
363
+ // TODO impelment when web API has functionatility then emit response
364
+ // var peripheral = this._peripherals[deviceUuid];
365
+ // this.emit('handleWrite', deviceUuid, handle);
366
+ };
367
+
368
+ module.exports = NobleBindings;
@@ -0,0 +1,321 @@
1
+ const events = require('events');
2
+ const util = require('util');
3
+
4
+ const WebSocket = require('ws');
5
+
6
+ const NobleBindings = function () {
7
+ const port = 0xB1e;
8
+ this._ws = new WebSocket(`ws://localhost:${port}`);
9
+
10
+ this._startScanCommand = null;
11
+ this._peripherals = {};
12
+
13
+ this.on('message', this._onMessage.bind(this));
14
+
15
+ if (!this._ws.on) {
16
+ this._ws.on = this._ws.addEventListener;
17
+ }
18
+
19
+ this._ws.on('open', this._onOpen.bind(this));
20
+ this._ws.on('close', this._onClose.bind(this));
21
+ this._ws.on('error', this._onClose.bind(this));
22
+
23
+ const _this = this;
24
+ this._ws.on('message', event => {
25
+ const data = (process.title === 'browser') ? event.data : event;
26
+
27
+ _this.emit('message', JSON.parse(data));
28
+ });
29
+ };
30
+
31
+ util.inherits(NobleBindings, events.EventEmitter);
32
+
33
+ NobleBindings.prototype.init = function () {
34
+ // no-op
35
+ };
36
+
37
+ NobleBindings.prototype._onOpen = function () {
38
+ console.log('on -> open');
39
+ };
40
+
41
+ NobleBindings.prototype._onClose = function () {
42
+ console.log('on -> close');
43
+ this.emit('stateChange', 'poweredOff');
44
+ };
45
+
46
+ NobleBindings.prototype._onMessage = function (event) {
47
+ let {
48
+ type,
49
+ peripheralUuid,
50
+ address,
51
+ addressType,
52
+ connectable,
53
+ advertisement,
54
+ rssi,
55
+ serviceUuids,
56
+ serviceUuid,
57
+ includedServiceUuids,
58
+ characteristics,
59
+ characteristicUuid,
60
+ isNotification,
61
+ state,
62
+ descriptors,
63
+ descriptorUuid,
64
+ handle
65
+ } = event;
66
+ const data = event.data ? Buffer.from(event.data, 'hex') : null;
67
+
68
+ if (type === 'stateChange') {
69
+ console.log(state);
70
+ this.emit('stateChange', state);
71
+ } else if (type === 'discover') {
72
+ advertisement = {
73
+ localName: advertisement.localName,
74
+ txPowerLevel: advertisement.txPowerLevel,
75
+ serviceUuids: advertisement.serviceUuids,
76
+ manufacturerData: (advertisement.manufacturerData ? Buffer.from(advertisement.manufacturerData, 'hex') : null),
77
+ serviceData: (advertisement.serviceData ? Buffer.from(advertisement.serviceData, 'hex') : null)
78
+ };
79
+
80
+ this._peripherals[peripheralUuid] = {
81
+ uuid: peripheralUuid,
82
+ address: address,
83
+ advertisement: advertisement,
84
+ rssi: rssi
85
+ };
86
+
87
+ this.emit('discover', peripheralUuid, address, addressType, connectable, advertisement, rssi);
88
+ } else if (type === 'connect') {
89
+ this.emit('connect', peripheralUuid);
90
+ } else if (type === 'disconnect') {
91
+ this.emit('disconnect', peripheralUuid);
92
+ } else if (type === 'rssiUpdate') {
93
+ this.emit('rssiUpdate', peripheralUuid, rssi);
94
+ } else if (type === 'servicesDiscover') {
95
+ this.emit('servicesDiscover', peripheralUuid, serviceUuids);
96
+ } else if (type === 'includedServicesDiscover') {
97
+ this.emit('includedServicesDiscover', peripheralUuid, serviceUuid, includedServiceUuids);
98
+ } else if (type === 'characteristicsDiscover') {
99
+ this.emit('characteristicsDiscover', peripheralUuid, serviceUuid, characteristics);
100
+ } else if (type === 'read') {
101
+ this.emit('read', peripheralUuid, serviceUuid, characteristicUuid, data, isNotification);
102
+ } else if (type === 'write') {
103
+ this.emit('write', peripheralUuid, serviceUuid, characteristicUuid);
104
+ } else if (type === 'broadcast') {
105
+ this.emit('broadcast', peripheralUuid, serviceUuid, characteristicUuid, state);
106
+ } else if (type === 'notify') {
107
+ this.emit('notify', peripheralUuid, serviceUuid, characteristicUuid, state);
108
+ } else if (type === 'descriptorsDiscover') {
109
+ this.emit('descriptorsDiscover', peripheralUuid, serviceUuid, characteristicUuid, descriptors);
110
+ } else if (type === 'valueRead') {
111
+ this.emit('valueRead', peripheralUuid, serviceUuid, characteristicUuid, descriptorUuid, data);
112
+ } else if (type === 'valueWrite') {
113
+ this.emit('valueWrite', peripheralUuid, serviceUuid, characteristicUuid, descriptorUuid);
114
+ } else if (type === 'handleRead') {
115
+ this.emit('handleRead', peripheralUuid, handle, data);
116
+ } else if (type === 'handleWrite') {
117
+ this.emit('handleWrite', peripheralUuid, handle);
118
+ } else if (type === 'handleNotify') {
119
+ this.emit('handleNotify', peripheralUuid, handle, data);
120
+ }
121
+ };
122
+
123
+ NobleBindings.prototype._sendCommand = function (command, errorCallback) {
124
+ const message = JSON.stringify(command);
125
+ this._ws.send(message, error => {
126
+ if (error != null) {
127
+ console.warn('could not send command', command, error);
128
+ if (typeof errorCallback === 'function') {
129
+ errorCallback(error);
130
+ }
131
+ }
132
+ });
133
+ };
134
+
135
+ NobleBindings.prototype.startScanning = function (serviceUuids, allowDuplicates) {
136
+ this._startScanCommand = {
137
+ action: 'startScanning',
138
+ serviceUuids: serviceUuids,
139
+ allowDuplicates: allowDuplicates
140
+ };
141
+ this._sendCommand(this._startScanCommand);
142
+
143
+ this.emit('scanStart');
144
+ };
145
+
146
+ NobleBindings.prototype.stopScanning = function () {
147
+ this._startScanCommand = null;
148
+
149
+ this._sendCommand({
150
+ action: 'stopScanning'
151
+ });
152
+
153
+ this.emit('scanStop');
154
+ };
155
+
156
+ NobleBindings.prototype.connect = function (deviceUuid) {
157
+ const peripheral = this._peripherals[deviceUuid];
158
+
159
+ this._sendCommand({
160
+ action: 'connect',
161
+ peripheralUuid: peripheral.uuid
162
+ });
163
+ };
164
+
165
+ NobleBindings.prototype.disconnect = function (deviceUuid) {
166
+ const peripheral = this._peripherals[deviceUuid];
167
+
168
+ this._sendCommand({
169
+ action: 'disconnect',
170
+ peripheralUuid: peripheral.uuid
171
+ });
172
+ };
173
+
174
+ NobleBindings.prototype.updateRssi = function (deviceUuid) {
175
+ const peripheral = this._peripherals[deviceUuid];
176
+
177
+ this._sendCommand({
178
+ action: 'updateRssi',
179
+ peripheralUuid: peripheral.uuid
180
+ });
181
+ };
182
+
183
+ NobleBindings.prototype.discoverServices = function (deviceUuid, uuids) {
184
+ const peripheral = this._peripherals[deviceUuid];
185
+
186
+ this._sendCommand({
187
+ action: 'discoverServices',
188
+ peripheralUuid: peripheral.uuid,
189
+ uuids: uuids
190
+ });
191
+ };
192
+
193
+ NobleBindings.prototype.discoverIncludedServices = function (deviceUuid, serviceUuid, serviceUuids) {
194
+ const peripheral = this._peripherals[deviceUuid];
195
+
196
+ this._sendCommand({
197
+ action: 'discoverIncludedServices',
198
+ peripheralUuid: peripheral.uuid,
199
+ serviceUuid: serviceUuid,
200
+ serviceUuids: serviceUuids
201
+ });
202
+ };
203
+
204
+ NobleBindings.prototype.discoverCharacteristics = function (deviceUuid, serviceUuid, characteristicUuids) {
205
+ const peripheral = this._peripherals[deviceUuid];
206
+
207
+ this._sendCommand({
208
+ action: 'discoverCharacteristics',
209
+ peripheralUuid: peripheral.uuid,
210
+ serviceUuid: serviceUuid,
211
+ characteristicUuids: characteristicUuids
212
+ });
213
+ };
214
+
215
+ NobleBindings.prototype.read = function (deviceUuid, serviceUuid, characteristicUuid) {
216
+ const peripheral = this._peripherals[deviceUuid];
217
+
218
+ this._sendCommand({
219
+ action: 'read',
220
+ peripheralUuid: peripheral.uuid,
221
+ serviceUuid: serviceUuid,
222
+ characteristicUuid: characteristicUuid
223
+ });
224
+ };
225
+
226
+ NobleBindings.prototype.write = function (deviceUuid, serviceUuid, characteristicUuid, data, withoutResponse) {
227
+ const peripheral = this._peripherals[deviceUuid];
228
+
229
+ this._sendCommand({
230
+ action: 'write',
231
+ peripheralUuid: peripheral.uuid,
232
+ serviceUuid: serviceUuid,
233
+ characteristicUuid: characteristicUuid,
234
+ data: data.toString('hex'),
235
+ withoutResponse: withoutResponse
236
+ });
237
+ };
238
+
239
+ NobleBindings.prototype.broadcast = function (deviceUuid, serviceUuid, characteristicUuid, broadcast) {
240
+ const peripheral = this._peripherals[deviceUuid];
241
+
242
+ this._sendCommand({
243
+ action: 'broadcast',
244
+ peripheralUuid: peripheral.uuid,
245
+ serviceUuid: serviceUuid,
246
+ characteristicUuid: characteristicUuid,
247
+ broadcast: broadcast
248
+ });
249
+ };
250
+
251
+ NobleBindings.prototype.notify = function (deviceUuid, serviceUuid, characteristicUuid, notify) {
252
+ const peripheral = this._peripherals[deviceUuid];
253
+
254
+ this._sendCommand({
255
+ action: 'notify',
256
+ peripheralUuid: peripheral.uuid,
257
+ serviceUuid: serviceUuid,
258
+ characteristicUuid: characteristicUuid,
259
+ notify: notify
260
+ });
261
+ };
262
+
263
+ NobleBindings.prototype.discoverDescriptors = function (deviceUuid, serviceUuid, characteristicUuid) {
264
+ const peripheral = this._peripherals[deviceUuid];
265
+
266
+ this._sendCommand({
267
+ action: 'discoverDescriptors',
268
+ peripheralUuid: peripheral.uuid,
269
+ serviceUuid: serviceUuid,
270
+ characteristicUuid: characteristicUuid
271
+ });
272
+ };
273
+
274
+ NobleBindings.prototype.readValue = function (deviceUuid, serviceUuid, characteristicUuid, descriptorUuid) {
275
+ const peripheral = this._peripherals[deviceUuid];
276
+
277
+ this._sendCommand({
278
+ action: 'readValue',
279
+ peripheralUuid: peripheral.uuid,
280
+ serviceUuid: serviceUuid,
281
+ characteristicUuid: characteristicUuid,
282
+ descriptorUuid: descriptorUuid
283
+ });
284
+ };
285
+
286
+ NobleBindings.prototype.writeValue = function (deviceUuid, serviceUuid, characteristicUuid, descriptorUuid, data) {
287
+ const peripheral = this._peripherals[deviceUuid];
288
+
289
+ this._sendCommand({
290
+ action: 'writeValue',
291
+ peripheralUuid: peripheral.uuid,
292
+ serviceUuid: serviceUuid,
293
+ characteristicUuid: characteristicUuid,
294
+ descriptorUuid: descriptorUuid,
295
+ data: data.toString('hex')
296
+ });
297
+ };
298
+
299
+ NobleBindings.prototype.readHandle = function (deviceUuid, handle) {
300
+ const peripheral = this._peripherals[deviceUuid];
301
+
302
+ this._sendCommand({
303
+ action: 'readHandle',
304
+ peripheralUuid: peripheral.uuid,
305
+ handle: handle
306
+ });
307
+ };
308
+
309
+ NobleBindings.prototype.writeHandle = function (deviceUuid, handle, data, withoutResponse) {
310
+ const peripheral = this._peripherals[deviceUuid];
311
+
312
+ this._sendCommand({
313
+ action: 'writeHandle',
314
+ peripheralUuid: peripheral.uuid,
315
+ handle: handle,
316
+ data: data.toString('hex'),
317
+ withoutResponse: withoutResponse
318
+ });
319
+ };
320
+
321
+ module.exports = NobleBindings;