@stoprocent/noble 1.19.0 → 2.0.0
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/README.md +393 -650
- package/examples/advertisement-discovery.js +57 -48
- package/examples/connect-address.js +59 -34
- package/examples/echo.js +59 -69
- package/examples/enter-exit.js +55 -49
- package/examples/multiple-bindings.js +53 -0
- package/examples/peripheral-explorer-async.js +39 -21
- package/examples/peripheral-explorer.ts +52 -0
- package/index.d.ts +249 -209
- package/index.js +4 -1
- package/jest.config.js +4 -0
- package/lib/characteristic.js +153 -127
- package/lib/{win/src/callbacks.h → common/include/Emit.h} +17 -14
- package/lib/common/include/Peripheral.h +31 -0
- package/lib/common/include/ThreadSafeCallback.h +95 -0
- package/lib/{win/src/callbacks.cc → common/src/Emit.cc} +111 -68
- package/lib/descriptor.js +57 -54
- package/lib/hci-socket/acl-stream.js +2 -4
- package/lib/hci-socket/bindings.js +96 -73
- package/lib/hci-socket/gap.js +2 -3
- package/lib/hci-socket/gatt.js +2 -5
- package/lib/hci-socket/hci.js +19 -7
- package/lib/hci-socket/signaling.js +2 -3
- package/lib/hci-socket/smp.js +2 -3
- package/lib/hci-socket/vs.js +1 -0
- package/lib/mac/binding.gyp +5 -7
- package/lib/mac/bindings.js +1 -3
- package/lib/mac/src/ble_manager.h +1 -8
- package/lib/mac/src/ble_manager.mm +87 -44
- package/lib/mac/src/napi_objc.h +1 -0
- package/lib/mac/src/napi_objc.mm +0 -6
- package/lib/mac/src/noble_mac.h +5 -3
- package/lib/mac/src/noble_mac.mm +99 -57
- package/lib/mac/src/objc_cpp.h +3 -2
- package/lib/mac/src/objc_cpp.mm +0 -6
- package/lib/noble.js +579 -488
- package/lib/peripheral.js +171 -174
- package/lib/resolve-bindings.js +37 -30
- package/lib/service.js +58 -55
- package/lib/win/binding.gyp +4 -11
- package/lib/win/bindings.js +1 -3
- package/lib/win/src/ble_manager.cc +291 -166
- package/lib/win/src/ble_manager.h +11 -13
- package/lib/win/src/napi_winrt.cc +1 -7
- package/lib/win/src/napi_winrt.h +1 -1
- package/lib/win/src/noble_winrt.cc +88 -61
- package/lib/win/src/noble_winrt.h +5 -3
- package/lib/win/src/notify_map.cc +0 -7
- package/lib/win/src/notify_map.h +1 -8
- package/lib/win/src/peripheral_winrt.cc +29 -11
- package/lib/win/src/peripheral_winrt.h +1 -1
- package/lib/win/src/radio_watcher.cc +79 -69
- package/lib/win/src/radio_watcher.h +30 -11
- package/lib/win/src/winrt_cpp.cc +1 -1
- package/lib/win/src/winrt_cpp.h +3 -0
- package/package.json +14 -17
- package/prebuilds/darwin-x64+arm64/@stoprocent+noble.node +0 -0
- package/prebuilds/win32-ia32/@stoprocent+noble.node +0 -0
- package/prebuilds/win32-x64/@stoprocent+noble.node +0 -0
- package/test/lib/characteristic.test.js +202 -322
- package/test/lib/descriptor.test.js +62 -95
- package/test/lib/hci-socket/acl-stream.test.js +112 -108
- package/test/lib/hci-socket/bindings.test.js +576 -365
- package/test/lib/hci-socket/hci.test.js +442 -473
- package/test/lib/hci-socket/signaling.test.js +45 -48
- package/test/lib/hci-socket/smp.test.js +144 -142
- package/test/lib/hci-socket/vs.test.js +193 -18
- package/test/lib/peripheral.test.js +492 -322
- package/test/lib/resolve-bindings.test.js +207 -82
- package/test/lib/service.test.js +79 -88
- package/test/noble.test.js +381 -1085
- package/.editorconfig +0 -11
- package/.nycrc.json +0 -4
- package/codecov.yml +0 -5
- package/examples/cache-gatt-discovery.js +0 -198
- package/examples/cache-gatt-reconnect.js +0 -164
- package/examples/ext-advertisement-discovery.js +0 -65
- package/examples/peripheral-explorer.js +0 -225
- package/examples/pizza/central.js +0 -194
- package/examples/pizza/pizza.js +0 -60
- package/examples/test/test.custom.js +0 -131
- package/examples/uart-bind-params.js +0 -28
- package/lib/distributed/bindings.js +0 -326
- package/lib/mac/src/callbacks.cc +0 -222
- package/lib/mac/src/callbacks.h +0 -84
- package/lib/mac/src/peripheral.h +0 -23
- package/lib/resolve-bindings-web.js +0 -9
- package/lib/webbluetooth/bindings.js +0 -368
- package/lib/websocket/bindings.js +0 -321
- package/lib/win/src/peripheral.h +0 -23
- package/test/lib/distributed/bindings.test.js +0 -918
- package/test/lib/webbluetooth/bindings.test.js +0 -190
- package/test/lib/websocket/bindings.test.js +0 -456
- package/test/mocha.setup.js +0 -0
- package/with-bindings.js +0 -5
- package/with-custom-binding.js +0 -6
- package/ws-slave.js +0 -404
|
@@ -1,25 +1,200 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const proxyquire = require('proxyquire').noCallThru();
|
|
1
|
+
// Mock dependencies if needed
|
|
2
|
+
jest.mock('os', () => ({}));
|
|
4
3
|
|
|
5
|
-
const
|
|
6
|
-
const { assert } = sinon;
|
|
7
|
-
const vendorSpecific = proxyquire('../../../lib/hci-socket/vs', { os: fakeOs });
|
|
4
|
+
const vs = require('../../../lib/hci-socket/vs');
|
|
8
5
|
|
|
9
|
-
describe('
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
describe('Bluetooth Address Utility', () => {
|
|
7
|
+
const validAddress = '00:11:22:33:44:55';
|
|
8
|
+
|
|
9
|
+
describe('setAddressCmd', () => {
|
|
10
|
+
test('returns null for unsupported manufacturer', () => {
|
|
11
|
+
const result = vs.setAddressCmd(999, validAddress);
|
|
12
|
+
expect(result).toBeNull();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('returns null for invalid address', () => {
|
|
16
|
+
// Most vendor functions call parseAddress which validates the address
|
|
17
|
+
// Testing with a supported manufacturer (Broadcom - 15)
|
|
18
|
+
expect(() => vs.setAddressCmd(15, 'invalid-address')).toThrow();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('for each supported manufacturer', () => {
|
|
22
|
+
// Test Ericsson (0)
|
|
23
|
+
test('creates correct command for Ericsson (0)', () => {
|
|
24
|
+
const result = vs.setAddressCmd(0, validAddress);
|
|
25
|
+
|
|
26
|
+
expect(result).toBeInstanceOf(Buffer);
|
|
27
|
+
expect(result.length).toBe(9);
|
|
28
|
+
expect(result.readUInt16LE(0)).toBe(0x000d | (0x3f << 10)); // OCF | OGF
|
|
29
|
+
expect(result.readUInt8(2)).toBe(0x06); // Parameter length
|
|
30
|
+
|
|
31
|
+
// Check MAC address bytes are properly placed
|
|
32
|
+
expect(result.slice(3, 9)).toEqual(Buffer.from([0x55, 0x44, 0x33, 0x22, 0x11, 0x00]));
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Test CSR (10)
|
|
36
|
+
test('creates correct command for CSR (10)', () => {
|
|
37
|
+
const result = vs.setAddressCmd(10, validAddress);
|
|
38
|
+
|
|
39
|
+
expect(result).toBeInstanceOf(Buffer);
|
|
40
|
+
expect(result.length).toBe(27); // 3 header + 24 base
|
|
41
|
+
expect(result.readUInt16LE(0)).toBe(0x0000 | (0x3f << 10)); // OCF | OGF
|
|
42
|
+
expect(result.readUInt8(2)).toBe(0xC2);
|
|
43
|
+
|
|
44
|
+
// Check specific positions where MAC address bytes should be
|
|
45
|
+
expect(result.readUInt8(16 + 3)).toBe(0x33); // macAddress[2]
|
|
46
|
+
expect(result.readUInt8(18 + 3)).toBe(0x55); // macAddress[0]
|
|
47
|
+
expect(result.readUInt8(19 + 3)).toBe(0x44); // macAddress[1]
|
|
48
|
+
expect(result.readUInt8(20 + 3)).toBe(0x22); // macAddress[3]
|
|
49
|
+
expect(result.readUInt8(22 + 3)).toBe(0x11); // macAddress[4]
|
|
50
|
+
expect(result.readUInt8(23 + 3)).toBe(0x00); // macAddress[5]
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Test TI (13)
|
|
54
|
+
test('creates correct command for Texas Instruments (13)', () => {
|
|
55
|
+
const result = vs.setAddressCmd(13, validAddress);
|
|
56
|
+
|
|
57
|
+
expect(result).toBeInstanceOf(Buffer);
|
|
58
|
+
expect(result.length).toBe(9);
|
|
59
|
+
expect(result.readUInt16LE(0)).toBe(0x0006 | (0x3f << 10)); // OCF | OGF
|
|
60
|
+
expect(result.readUInt8(2)).toBe(0x06); // Parameter length
|
|
61
|
+
|
|
62
|
+
// Check MAC address bytes are properly placed
|
|
63
|
+
expect(result.slice(3, 9)).toEqual(Buffer.from([0x55, 0x44, 0x33, 0x22, 0x11, 0x00]));
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Test Broadcom (15)
|
|
67
|
+
test('creates correct command for Broadcom (15)', () => {
|
|
68
|
+
const result = vs.setAddressCmd(15, validAddress);
|
|
69
|
+
|
|
70
|
+
expect(result).toBeInstanceOf(Buffer);
|
|
71
|
+
expect(result.length).toBe(9);
|
|
72
|
+
expect(result.readUInt16LE(0)).toBe(0x0001 | (0x3f << 10)); // OCF | OGF
|
|
73
|
+
expect(result.readUInt8(2)).toBe(0x06); // Parameter length
|
|
74
|
+
|
|
75
|
+
// Check MAC address bytes are properly placed
|
|
76
|
+
expect(result.slice(3, 9)).toEqual(Buffer.from([0x55, 0x44, 0x33, 0x22, 0x11, 0x00]));
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Test Zeevo (18)
|
|
80
|
+
test('creates correct command for Zeevo (18)', () => {
|
|
81
|
+
const result = vs.setAddressCmd(18, validAddress);
|
|
82
|
+
|
|
83
|
+
expect(result).toBeInstanceOf(Buffer);
|
|
84
|
+
expect(result.length).toBe(9);
|
|
85
|
+
expect(result.readUInt16LE(0)).toBe(0x0001 | (0x3f << 10)); // OCF | OGF
|
|
86
|
+
expect(result.readUInt8(2)).toBe(0x06); // Parameter length
|
|
87
|
+
|
|
88
|
+
// Check MAC address bytes are properly placed
|
|
89
|
+
expect(result.slice(3, 9)).toEqual(Buffer.from([0x55, 0x44, 0x33, 0x22, 0x11, 0x00]));
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Test ST Microelectronics (48)
|
|
93
|
+
test('creates correct command for ST Microelectronics (48)', () => {
|
|
94
|
+
const result = vs.setAddressCmd(48, validAddress);
|
|
95
|
+
|
|
96
|
+
expect(result).toBeInstanceOf(Buffer);
|
|
97
|
+
expect(result.length).toBe(3 + 0xFF); // Header + ERICSSON_STORE_IN_FLASH_CP_SIZE
|
|
98
|
+
expect(result.readUInt16LE(0)).toBe(0x0022 | (0x3f << 10)); // OCF | OGF
|
|
99
|
+
expect(result.readUInt8(2)).toBe(0xFF); // Parameter length
|
|
100
|
+
expect(result.readUInt8(3)).toBe(0xFE); // user_id
|
|
101
|
+
expect(result.readUInt8(4)).toBe(0x06); // flash_length
|
|
102
|
+
|
|
103
|
+
// Check MAC address bytes are properly placed
|
|
104
|
+
expect(result.slice(5, 11)).toEqual(Buffer.from([0x55, 0x44, 0x33, 0x22, 0x11, 0x00]));
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Test Ericsson mobile (57)
|
|
108
|
+
test('creates correct command for Ericsson Mobile (57)', () => {
|
|
109
|
+
const result = vs.setAddressCmd(57, validAddress);
|
|
110
|
+
|
|
111
|
+
expect(result).toBeInstanceOf(Buffer);
|
|
112
|
+
expect(result.length).toBe(9);
|
|
113
|
+
expect(result.readUInt16LE(0)).toBe(0x000d | (0x3f << 10)); // OCF | OGF
|
|
114
|
+
expect(result.readUInt8(2)).toBe(0x06); // Parameter length
|
|
115
|
+
|
|
116
|
+
// Check MAC address bytes are properly placed
|
|
117
|
+
expect(result.slice(3, 9)).toEqual(Buffer.from([0x55, 0x44, 0x33, 0x22, 0x11, 0x00]));
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Test Marvell (72)
|
|
121
|
+
test('creates correct command for Marvell (72)', () => {
|
|
122
|
+
const result = vs.setAddressCmd(72, validAddress);
|
|
123
|
+
|
|
124
|
+
expect(result).toBeInstanceOf(Buffer);
|
|
125
|
+
expect(result.length).toBe(11);
|
|
126
|
+
expect(result.readUInt16LE(0)).toBe(0x0022 | (0x3f << 10)); // OCF | OGF
|
|
127
|
+
expect(result.readUInt8(2)).toBe(0x08); // Parameter length
|
|
128
|
+
expect(result.readUInt8(3)).toBe(0xFE); // parameter_id
|
|
129
|
+
expect(result.readUInt8(4)).toBe(0x06); // bdaddr_len
|
|
130
|
+
|
|
131
|
+
// Check MAC address bytes are properly placed
|
|
132
|
+
expect(result.slice(5, 11)).toEqual(Buffer.from([0x55, 0x44, 0x33, 0x22, 0x11, 0x00]));
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Test Atheros (305)
|
|
136
|
+
test('creates correct command for Atheros/Qualcomm (305)', () => {
|
|
137
|
+
const result = vs.setAddressCmd(305, validAddress);
|
|
138
|
+
|
|
139
|
+
expect(result).toBeInstanceOf(Buffer);
|
|
140
|
+
expect(result.length).toBe(9);
|
|
141
|
+
expect(result.readUInt16LE(0)).toBe(0x0001 | (0x3f << 10)); // OCF | OGF
|
|
142
|
+
expect(result.readUInt8(2)).toBe(0x06); // Parameter length
|
|
143
|
+
|
|
144
|
+
// Check MAC address bytes are properly placed
|
|
145
|
+
expect(result.slice(3, 9)).toEqual(Buffer.from([0x55, 0x44, 0x33, 0x22, 0x11, 0x00]));
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Test Linux Foundation (1521)
|
|
149
|
+
test('creates correct command for Linux Foundation (1521)', () => {
|
|
150
|
+
const result = vs.setAddressCmd(1521, validAddress);
|
|
151
|
+
|
|
152
|
+
expect(result).toBeInstanceOf(Buffer);
|
|
153
|
+
expect(result.length).toBe(9);
|
|
154
|
+
expect(result.readUInt16LE(0)).toBe(0x0006 | (0x3f << 10)); // OCF | OGF
|
|
155
|
+
expect(result.readUInt8(2)).toBe(0x06); // Parameter length
|
|
156
|
+
|
|
157
|
+
// Check MAC address bytes are properly placed
|
|
158
|
+
expect(result.slice(3, 9)).toEqual(Buffer.from([0x55, 0x44, 0x33, 0x22, 0x11, 0x00]));
|
|
159
|
+
});
|
|
160
|
+
});
|
|
12
161
|
});
|
|
13
|
-
|
|
162
|
+
|
|
14
163
|
describe('parseAddress', () => {
|
|
15
|
-
|
|
16
|
-
|
|
164
|
+
test('should throw an Error for invalid address', () => {
|
|
165
|
+
expect(() => {
|
|
166
|
+
vs.setAddressCmd(0, '00:11:22:33:44');
|
|
167
|
+
}).toThrow();
|
|
17
168
|
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
169
|
+
|
|
170
|
+
test('should convert to Buffer correctly', () => {
|
|
171
|
+
const result = vs.setAddressCmd(0, '00:11:22:33:44:55');
|
|
172
|
+
expect(result.slice(3)).toEqual(Buffer.from([0x55, 0x44, 0x33, 0x22, 0x11, 0x00]));
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
describe('edge cases', () => {
|
|
177
|
+
test('handle address with different case format', () => {
|
|
178
|
+
// Upper case should work the same
|
|
179
|
+
const result = vs.setAddressCmd(15, '00:11:22:33:44:55');
|
|
180
|
+
const resultUpperCase = vs.setAddressCmd(15, '00:11:22:33:44:55');
|
|
181
|
+
|
|
182
|
+
expect(result).toEqual(resultUpperCase);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test('handle invalid address format', () => {
|
|
186
|
+
// These should all return null
|
|
187
|
+
expect(() => vs.setAddressCmd(15, '00-11-22-33-44-55')).toThrow(); // Wrong separator
|
|
188
|
+
expect(() => vs.setAddressCmd(15, '00:11:22:33:44')).toThrow(); // Too short
|
|
189
|
+
expect(() => vs.setAddressCmd(15, '00:11:22:33:44:55:66')).toThrow(); // Too long
|
|
190
|
+
expect(() => vs.setAddressCmd(15, 'invalid')).toThrow(); // Not an address
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test('handle non-existent manufacturer', () => {
|
|
194
|
+
expect(vs.setAddressCmd(9999, validAddress)).toBeNull();
|
|
195
|
+
expect(vs.setAddressCmd(-1, validAddress)).toBeNull();
|
|
196
|
+
expect(vs.setAddressCmd(null, validAddress)).toBeNull();
|
|
197
|
+
expect(vs.setAddressCmd(undefined, validAddress)).toBeNull();
|
|
23
198
|
});
|
|
24
199
|
});
|
|
25
|
-
});
|
|
200
|
+
});
|