@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,219 @@
1
+ const events = require('events');
2
+ const util = require('util');
3
+
4
+ const Manufacturer = require('./manufacture');
5
+
6
+ function Peripheral (noble, id, address, addressType, connectable, advertisement, rssi, scannable) {
7
+ this._noble = noble;
8
+
9
+ this.id = id;
10
+ this.uuid = id; // for legacy
11
+ this.address = address;
12
+ this.addressType = addressType;
13
+ this.connectable = connectable;
14
+ this.scannable = scannable;
15
+ this.advertisement = advertisement;
16
+ this.rssi = rssi;
17
+ this.services = null;
18
+ this.mtu = null;
19
+ this.state = 'disconnected';
20
+ this.manufacturer = null;
21
+
22
+ if (typeof this.advertisement !== 'undefined' && typeof this.advertisement.manufacturerData !== 'undefined') {
23
+ this.manufacturer = new Manufacturer(noble, this.advertisement.manufacturerData);
24
+ }
25
+ }
26
+
27
+ util.inherits(Peripheral, events.EventEmitter);
28
+
29
+ Peripheral.prototype.toString = function () {
30
+ return JSON.stringify({
31
+ id: this.id,
32
+ address: this.address,
33
+ addressType: this.addressType,
34
+ connectable: this.connectable,
35
+ advertisement: this.advertisement,
36
+ rssi: this.rssi,
37
+ mtu: this.mtu,
38
+ state: this.state
39
+ });
40
+ };
41
+
42
+ const connect = function (options, callback) {
43
+ if (typeof options === 'function') {
44
+ callback = options;
45
+ options = undefined;
46
+ }
47
+
48
+ if (callback) {
49
+ this.once('connect', error => {
50
+ callback(error);
51
+ });
52
+ }
53
+
54
+ if (this.state === 'connected') {
55
+ this.emit('connect', new Error('Peripheral already connected'));
56
+ } else {
57
+ this.state = 'connecting';
58
+ this._noble.connect(this.id, options);
59
+ }
60
+ };
61
+
62
+ Peripheral.prototype.connect = connect;
63
+ Peripheral.prototype.connectAsync = function (options) {
64
+ return util.promisify(callback => this.connect(options, callback))();
65
+ };
66
+
67
+ Peripheral.prototype.cancelConnect = function (options) {
68
+ if (this.state === 'connecting') {
69
+ this.emit('connect', new Error('connection canceled!'));
70
+ this._noble.cancelConnect(this.id, options);
71
+ }
72
+ };
73
+
74
+ const disconnect = function (callback) {
75
+ if (callback) {
76
+ this.once('disconnect', () => {
77
+ callback(null);
78
+ });
79
+ }
80
+ this.state = 'disconnecting';
81
+ this._noble.disconnect(this.id);
82
+ };
83
+
84
+ Peripheral.prototype.disconnect = disconnect;
85
+ Peripheral.prototype.disconnectAsync = util.promisify(disconnect);
86
+
87
+ const updateRssi = function (callback) {
88
+ if (callback) {
89
+ this.once('rssiUpdate', rssi => {
90
+ callback(null, rssi);
91
+ });
92
+ }
93
+
94
+ this._noble.updateRssi(this.id);
95
+ };
96
+
97
+ Peripheral.prototype.updateRssi = updateRssi;
98
+ Peripheral.prototype.updateRssiAsync = util.promisify(updateRssi);
99
+
100
+ const discoverServices = function (uuids, callback) {
101
+ if (callback) {
102
+ this.once('servicesDiscover', services => {
103
+ callback(null, services);
104
+ });
105
+ }
106
+
107
+ this._noble.discoverServices(this.id, uuids);
108
+ };
109
+
110
+ Peripheral.prototype.discoverServices = discoverServices;
111
+ Peripheral.prototype.discoverServicesAsync = function (uuids) {
112
+ return util.promisify((callback) => this.discoverServices(uuids, callback))();
113
+ };
114
+
115
+ const discoverSomeServicesAndCharacteristics = function (serviceUuids, characteristicsUuids, callback) {
116
+ this.discoverServices(serviceUuids, (err, services) => {
117
+ if (!err && services.length < serviceUuids.length) {
118
+ err = 'Could not find all requested services';
119
+ }
120
+
121
+ if (err) {
122
+ callback(err, null, null);
123
+ return;
124
+ }
125
+ let numDiscovered = 0;
126
+ const allCharacteristics = [];
127
+
128
+ for (const i in services) {
129
+ const service = services[i];
130
+
131
+ service.discoverCharacteristics(characteristicsUuids, (error, characteristics) => {
132
+ numDiscovered++;
133
+
134
+ // TODO: handle `error`?
135
+ if (error === null) {
136
+ for (const j in characteristics) {
137
+ const characteristic = characteristics[j];
138
+
139
+ allCharacteristics.push(characteristic);
140
+ }
141
+ }
142
+
143
+ if (numDiscovered === services.length) {
144
+ if (callback) {
145
+ callback(null, services, allCharacteristics);
146
+ }
147
+ }
148
+ });
149
+ }
150
+ });
151
+ };
152
+
153
+ Peripheral.prototype.discoverSomeServicesAndCharacteristics = discoverSomeServicesAndCharacteristics;
154
+ Peripheral.prototype.discoverSomeServicesAndCharacteristicsAsync = function (serviceUuids, characteristicsUuids) {
155
+ return new Promise((resolve, reject) =>
156
+ this.discoverSomeServicesAndCharacteristics(
157
+ serviceUuids,
158
+ characteristicsUuids,
159
+ (error, services, characteristics) =>
160
+ error
161
+ ? reject(error)
162
+ : resolve({
163
+ services,
164
+ characteristics
165
+ })
166
+ )
167
+ );
168
+ };
169
+
170
+ const discoverAllServicesAndCharacteristics = function (callback) {
171
+ this.discoverSomeServicesAndCharacteristics([], [], callback);
172
+ };
173
+
174
+ Peripheral.prototype.discoverAllServicesAndCharacteristics = discoverAllServicesAndCharacteristics;
175
+ Peripheral.prototype.discoverAllServicesAndCharacteristicsAsync = function () {
176
+ return new Promise((resolve, reject) =>
177
+ this.discoverAllServicesAndCharacteristics(
178
+ (error, services, characteristics) =>
179
+ error
180
+ ? reject(error)
181
+ : resolve({
182
+ services,
183
+ characteristics
184
+ })
185
+ )
186
+ );
187
+ };
188
+
189
+ const readHandle = function (handle, callback) {
190
+ if (callback) {
191
+ this.once(`handleRead${handle}`, data => {
192
+ callback(null, data);
193
+ });
194
+ }
195
+
196
+ this._noble.readHandle(this.id, handle);
197
+ };
198
+
199
+ Peripheral.prototype.readHandle = readHandle;
200
+ Peripheral.prototype.readHandleAsync = util.promisify(readHandle);
201
+
202
+ const writeHandle = function (handle, data, withoutResponse, callback) {
203
+ if (!(data instanceof Buffer)) {
204
+ throw new Error('data must be a Buffer');
205
+ }
206
+
207
+ if (callback) {
208
+ this.once(`handleWrite${handle}`, () => {
209
+ callback(null);
210
+ });
211
+ }
212
+
213
+ this._noble.writeHandle(this.id, handle, data, withoutResponse);
214
+ };
215
+
216
+ Peripheral.prototype.writeHandle = writeHandle;
217
+ Peripheral.prototype.writeHandleAsync = util.promisify(writeHandle);
218
+
219
+ module.exports = Peripheral;
@@ -0,0 +1,9 @@
1
+ function resolveBindings (options) {
2
+ if (navigator.bluetooth && !process.env.NOBLE_WEBSOCKET) {
3
+ return new (require('./webbluetooth/bindings'))(options);
4
+ }
5
+
6
+ return new (require('./websocket/bindings'))(options);
7
+ }
8
+
9
+ module.exports = resolveBindings;
@@ -0,0 +1,44 @@
1
+ const os = require('os');
2
+
3
+ function getWindowsBindings () {
4
+ const ver = os
5
+ .release()
6
+ .split('.')
7
+ .map((str) => parseInt(str, 10));
8
+ if (
9
+ !(
10
+ ver[0] > 10 ||
11
+ (ver[0] === 10 && ver[1] > 0) ||
12
+ (ver[0] === 10 && ver[1] === 0 && ver[2] >= 15063)
13
+ )
14
+ ) {
15
+ return require('./hci-socket/bindings');
16
+ } else {
17
+ return require('./win/bindings');
18
+ }
19
+ }
20
+
21
+ module.exports = function (options) {
22
+ const platform = os.platform();
23
+
24
+ if (process.env.NOBLE_WEBSOCKET) {
25
+ return new (require('./websocket/bindings'))(options);
26
+ } else if (process.env.NOBLE_HCI_UART_PORT) {
27
+ return new (require('./hci-uart/bindings'))(options);
28
+ } else if (process.env.NOBLE_DISTRIBUTED) {
29
+ return new (require('./distributed/bindings'))(options);
30
+ } else if (
31
+ platform === 'linux' ||
32
+ platform === 'freebsd' ||
33
+ (process.env.BLUETOOTH_HCI_SOCKET_USB_VID &&
34
+ process.env.BLUETOOTH_HCI_SOCKET_USB_PID)
35
+ ) {
36
+ return new (require('./hci-socket/bindings'))(options);
37
+ } else if (platform === 'darwin') {
38
+ return new (require('./mac/bindings'))(options);
39
+ } else if (platform === 'win32') {
40
+ return new (getWindowsBindings())(options);
41
+ } else {
42
+ throw new Error('Unsupported platform');
43
+ }
44
+ };
package/lib/service.js ADDED
@@ -0,0 +1,72 @@
1
+ const events = require('events');
2
+ const util = require('util');
3
+
4
+ const services = require('./services.json');
5
+
6
+ function Service (noble, peripheralId, uuid) {
7
+ this._noble = noble;
8
+ this._peripheralId = peripheralId;
9
+
10
+ this.uuid = uuid;
11
+ this.name = null;
12
+ this.type = null;
13
+ this.includedServiceUuids = null;
14
+ this.characteristics = null;
15
+
16
+ const service = services[uuid];
17
+ if (service) {
18
+ this.name = service.name;
19
+ this.type = service.type;
20
+ }
21
+ }
22
+
23
+ util.inherits(Service, events.EventEmitter);
24
+
25
+ Service.prototype.toString = function () {
26
+ return JSON.stringify({
27
+ uuid: this.uuid,
28
+ name: this.name,
29
+ type: this.type,
30
+ includedServiceUuids: this.includedServiceUuids
31
+ });
32
+ };
33
+
34
+ const discoverIncludedServices = function (serviceUuids, callback) {
35
+ if (callback) {
36
+ this.once('includedServicesDiscover', includedServiceUuids => {
37
+ callback(null, includedServiceUuids);
38
+ });
39
+ }
40
+
41
+ this._noble.discoverIncludedServices(
42
+ this._peripheralId,
43
+ this.uuid,
44
+ serviceUuids
45
+ );
46
+ };
47
+
48
+ Service.prototype.discoverIncludedServices = discoverIncludedServices;
49
+ Service.prototype.discoverIncludedServicesAsync = function (serviceUuids) {
50
+ return util.promisify((callback) => this.discoverIncludedServices(serviceUuids, callback))();
51
+ };
52
+
53
+ const discoverCharacteristics = function (characteristicUuids, callback) {
54
+ if (callback) {
55
+ this.once('characteristicsDiscover', characteristics => {
56
+ callback(null, characteristics);
57
+ });
58
+ }
59
+
60
+ this._noble.discoverCharacteristics(
61
+ this._peripheralId,
62
+ this.uuid,
63
+ characteristicUuids
64
+ );
65
+ };
66
+
67
+ Service.prototype.discoverCharacteristics = discoverCharacteristics;
68
+ Service.prototype.discoverCharacteristicsAsync = function (characteristicUuids) {
69
+ return util.promisify((callback) => this.discoverCharacteristics(characteristicUuids, callback))();
70
+ };
71
+
72
+ module.exports = Service;
@@ -0,0 +1,92 @@
1
+ {
2
+ "1800" : { "name" : "Generic Access"
3
+ , "type" : "org.bluetooth.service.generic_access"
4
+ }
5
+ , "1801" : { "name" : "Generic Attribute"
6
+ , "type" : "org.bluetooth.service.generic_attribute"
7
+ }
8
+ , "1802" : { "name" : "Immediate Alert"
9
+ , "type" : "org.bluetooth.service.immediate_alert"
10
+ }
11
+ , "1803" : { "name" : "Link Loss"
12
+ , "type" : "org.bluetooth.service.link_loss"
13
+ }
14
+ , "1804" : { "name" : "Tx Power"
15
+ , "type" : "org.bluetooth.service.tx_power"
16
+ }
17
+ , "1805" : { "name" : "Current Time Service"
18
+ , "type" : "org.bluetooth.service.current_time"
19
+ }
20
+ , "1806" : { "name" : "Reference Time Update Service"
21
+ , "type" : "org.bluetooth.service.reference_time_update"
22
+ }
23
+ , "1807" : { "name" : "Next DST Change Service"
24
+ , "type" : "org.bluetooth.service.next_dst_change"
25
+ }
26
+ , "1808" : { "name" : "Glucose"
27
+ , "type" : "org.bluetooth.service.glucose"
28
+ }
29
+ , "1809" : { "name" : "Health Thermometer"
30
+ , "type" : "org.bluetooth.service.health_thermometer"
31
+ }
32
+ , "180a" : { "name" : "Device Information"
33
+ , "type" : "org.bluetooth.service.device_information"
34
+ }
35
+ , "180d" : { "name" : "Heart Rate"
36
+ , "type" : "org.bluetooth.service.heart_rate"
37
+ }
38
+ , "180e" : { "name" : "Phone Alert Status Service"
39
+ , "type" : "org.bluetooth.service.phone_alert_service"
40
+ }
41
+ , "180f" : { "name" : "Battery Service"
42
+ , "type" : "org.bluetooth.service.battery_service"
43
+ }
44
+ , "1810" : { "name" : "Blood Pressure"
45
+ , "type" : "org.bluetooth.service.blood_pressuer"
46
+ }
47
+ , "1811" : { "name" : "Alert Notification Service"
48
+ , "type" : "org.bluetooth.service.alert_notification"
49
+ }
50
+ , "1812" : { "name" : "Human Interface Device"
51
+ , "type" : "org.bluetooth.service.human_interface_device"
52
+ }
53
+ , "1813" : { "name" : "Scan Parameters"
54
+ , "type" : "org.bluetooth.service.scan_parameters"
55
+ }
56
+ , "1814" : { "name" : "Running Speed and Cadence"
57
+ , "type" : "org.bluetooth.service.running_speed_and_cadence"
58
+ }
59
+ , "1815" : { "name" : "Automation IO"
60
+ , "type" : "org.bluetooth.service.automation_io"
61
+ }
62
+ , "1816" : { "name" : "Cycling Speed and Cadence"
63
+ , "type" : "org.bluetooth.service.cycling_speed_and_cadence"
64
+ }
65
+ , "1818" : { "name" : "Cycling Power"
66
+ , "type" : "org.bluetooth.service.cycling_power"
67
+ }
68
+ , "1819" : { "name" : "Location and Navigation"
69
+ , "type" : "org.bluetooth.service.location_and_navigation"
70
+ }
71
+ , "181a" : { "name" : "Environmental Sensing"
72
+ , "type" : "org.bluetooth.service.environmental_sensing"
73
+ }
74
+ , "181b" : { "name" : "Body Composition"
75
+ , "type" : "org.bluetooth.service.body_composition"
76
+ }
77
+ , "181c" : { "name" : "User Data"
78
+ , "type" : "org.bluetooth.service.user_data"
79
+ }
80
+ , "181d" : { "name" : "Weight Scale"
81
+ , "type" : "org.bluetooth.service.weight_scale"
82
+ }
83
+ , "181e" : { "name" : "Bond Management"
84
+ , "type" : "org.bluetooth.service.bond_management"
85
+ }
86
+ , "181f" : { "name" : "Continuous Glucose Monitoring"
87
+ , "type" : "org.bluetooth.service.continuous_glucose_monitoring"
88
+ }
89
+ , "1820" : { "name" : "Internet Protocol Support"
90
+ , "type" : "org.bluetooth.service.internet_protocol_support"
91
+ }
92
+ }