@stoprocent/noble 1.11.7 → 1.13.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/binding.gyp +3 -0
- package/examples/uart-bind-params.js +28 -0
- package/lib/hci-socket/bindings.js +4 -0
- package/lib/hci-socket/hci.js +20 -21
- package/lib/hci-socket/vs.js +156 -0
- package/lib/mac/binding.gyp +23 -11
- package/lib/noble.js +8 -0
- package/lib/win/binding.gyp +25 -5
- package/package.json +13 -22
- package/prebuilds/android-arm/node.napi.armv7.node +0 -0
- package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
- package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/node.napi.musl.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/test/lib/hci-socket/hci.test.js +47 -7
- package/test/lib/hci-socket/vs.test.js +25 -0
- package/.eslintrc.js +0 -25
- package/.github/FUNDING.yml +0 -2
- package/.github/workflows/fediverse-action.yml +0 -16
- package/.github/workflows/nodepackage.yml +0 -68
- package/.github/workflows/npm-publish.yml +0 -26
- package/.github/workflows/prebuild.yml +0 -66
- package/CHANGELOG.md +0 -119
- package/MAINTAINERS.md +0 -1
- package/test.js +0 -131
package/binding.gyp
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const noble = require('../with-custom-binding');
|
|
2
|
+
|
|
3
|
+
// Needs to export env: BLUETOOTH_HCI_SOCKET_FORCE_UART=1
|
|
4
|
+
|
|
5
|
+
const nobleUartA = noble({ bindParams: { uart: { port: '/dev/tty.usbmodem1...' } } });
|
|
6
|
+
const nobleUartB = noble({ bindParams: { uart: { port: '/dev/tty.usbmodem2...' } } });
|
|
7
|
+
|
|
8
|
+
nobleUartA.on('discover', peripheral => {
|
|
9
|
+
console.log('UART A', peripheral.address);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
nobleUartB.on('discover', peripheral => {
|
|
13
|
+
console.log('UART B', peripheral.address);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
nobleUartA.on('stateChange', state => {
|
|
17
|
+
if (state === 'poweredOn') {
|
|
18
|
+
nobleUartA.setAddress('00:11:22:33:44:01');
|
|
19
|
+
nobleUartA.startScanning();
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
nobleUartB.on('stateChange', state => {
|
|
24
|
+
if (state === 'poweredOn') {
|
|
25
|
+
nobleUartB.setAddress('00:11:22:33:44:02');
|
|
26
|
+
nobleUartB.startScanning();
|
|
27
|
+
}
|
|
28
|
+
});
|
|
@@ -34,6 +34,10 @@ NobleBindings.prototype.setScanParameters = function (interval, window) {
|
|
|
34
34
|
this._gap.setScanParameters(interval, window);
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
NobleBindings.prototype.setAddress = function (address) {
|
|
38
|
+
this._hci.setAddress(address);
|
|
39
|
+
};
|
|
40
|
+
|
|
37
41
|
NobleBindings.prototype.startScanning = function (
|
|
38
42
|
serviceUuids,
|
|
39
43
|
allowDuplicates
|
package/lib/hci-socket/hci.js
CHANGED
|
@@ -4,6 +4,7 @@ const events = require('events');
|
|
|
4
4
|
const util = require('util');
|
|
5
5
|
|
|
6
6
|
const BluetoothHciSocket = require('@stoprocent/bluetooth-hci-socket');
|
|
7
|
+
const vendorSpecific = require('./vs');
|
|
7
8
|
|
|
8
9
|
const HCI_COMMAND_PKT = 0x01;
|
|
9
10
|
const HCI_ACLDATA_PKT = 0x02;
|
|
@@ -32,7 +33,6 @@ const OCF_DISCONNECT = 0x0006;
|
|
|
32
33
|
const OGF_HOST_CTL = 0x03;
|
|
33
34
|
const OCF_SET_EVENT_MASK = 0x0001;
|
|
34
35
|
const OCF_RESET = 0x0003;
|
|
35
|
-
const OCF_SET_RANDOM_MAC = 0x0005;
|
|
36
36
|
const OCF_SET_PHY = 0x0031;
|
|
37
37
|
const OCF_READ_LE_HOST_SUPPORTED = 0x006c;
|
|
38
38
|
const OCF_WRITE_LE_HOST_SUPPORTED = 0x006d;
|
|
@@ -96,10 +96,12 @@ const STATUS_MAPPER = require('./hci-status');
|
|
|
96
96
|
|
|
97
97
|
const Hci = function (options) {
|
|
98
98
|
options = options || {};
|
|
99
|
+
this._manufacturer = null;
|
|
99
100
|
this._socket = new BluetoothHciSocket();
|
|
100
101
|
this._isDevUp = null;
|
|
101
102
|
this._isExtended = 'extended' in options && options.extended;
|
|
102
103
|
this._state = null;
|
|
104
|
+
this._bindParams = 'bindParams' in options ? options.bindParams : undefined;
|
|
103
105
|
|
|
104
106
|
this._handleBuffers = {};
|
|
105
107
|
|
|
@@ -151,13 +153,13 @@ Hci.prototype.init = function (options) {
|
|
|
151
153
|
this._socket.on('error', this.onSocketError.bind(this));
|
|
152
154
|
|
|
153
155
|
if (this._userChannel) {
|
|
154
|
-
this._socket.bindUser(this._deviceId);
|
|
156
|
+
this._socket.bindUser(this._deviceId, this._bindParams);
|
|
155
157
|
this._socket.start();
|
|
156
158
|
|
|
157
159
|
this.reset();
|
|
158
160
|
} else {
|
|
159
161
|
if (!this._bound) {
|
|
160
|
-
this._socket.bindRaw(this._deviceId);
|
|
162
|
+
this._socket.bindRaw(this._deviceId, this._bindParams);
|
|
161
163
|
this._bound = true;
|
|
162
164
|
}
|
|
163
165
|
this._socket.start();
|
|
@@ -218,26 +220,20 @@ Hci.prototype.setCodedPhySupport = function () {
|
|
|
218
220
|
this._socket.write(cmd);
|
|
219
221
|
};
|
|
220
222
|
|
|
221
|
-
Hci.prototype.
|
|
222
|
-
|
|
223
|
+
Hci.prototype.setAddress = function (address) {
|
|
224
|
+
// Command
|
|
225
|
+
const addrCmd = vendorSpecific.setAddressCmd(this._manufacturer, address);
|
|
223
226
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
+
if (addrCmd !== null && Buffer.isBuffer(addrCmd)) {
|
|
228
|
+
// Make Command Buffer
|
|
229
|
+
const cmd = Buffer.alloc(1 + addrCmd.byteLength);
|
|
230
|
+
cmd.writeUInt8(HCI_COMMAND_PKT, 0);
|
|
231
|
+
addrCmd.copy(cmd, 1);
|
|
227
232
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
cmd.writeUInt8(0x05, 4); // mac 6 byte
|
|
233
|
-
cmd.writeUInt8(0x04, 5); // mac 5 byte
|
|
234
|
-
cmd.writeUInt8(0x03, 6); // mac 4 byte
|
|
235
|
-
cmd.writeUInt8(0x02, 7); // mac 3 byte
|
|
236
|
-
cmd.writeUInt8(0x01, 8); // mac 2 byte
|
|
237
|
-
cmd.writeUInt8(0x00, 9); // mac 1 byte
|
|
238
|
-
|
|
239
|
-
debug(`set random mac address - writing: ${cmd.toString('hex')}`);
|
|
240
|
-
this._socket.write(cmd);
|
|
233
|
+
debug(`set address - writing: ${cmd.toString('hex')}`);
|
|
234
|
+
this._socket.write(cmd);
|
|
235
|
+
this.readBdAddr();
|
|
236
|
+
}
|
|
241
237
|
};
|
|
242
238
|
|
|
243
239
|
Hci.prototype.setSocketFilter = function () {
|
|
@@ -938,6 +934,9 @@ Hci.prototype.processCmdCompleteEvent = function (cmd, status, result) {
|
|
|
938
934
|
this.setScanParameters();
|
|
939
935
|
}
|
|
940
936
|
|
|
937
|
+
// Update manufacturer
|
|
938
|
+
this._manufacturer = manufacturer;
|
|
939
|
+
|
|
941
940
|
this.emit(
|
|
942
941
|
'readLocalVersion',
|
|
943
942
|
hciVer,
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// This file is based on the bluez implementation
|
|
2
|
+
// https://github.com/bluez/bluez/blob/master/tools/bdaddr.c
|
|
3
|
+
|
|
4
|
+
const OGF_VENDOR_CMD = 0x3f;
|
|
5
|
+
|
|
6
|
+
const OCF_ERICSSON_WRITE_BD_ADDR = 0x000d;
|
|
7
|
+
const OCF_TI_WRITE_BD_ADDR = 0x0006;
|
|
8
|
+
const OCF_LINUX_FOUNDATION_WRITE_BD_ADDR = 0x0006;
|
|
9
|
+
const OCF_BCM_WRITE_BD_ADDR = 0x0001;
|
|
10
|
+
const OCF_ZEEVO_WRITE_BD_ADDR = 0x0001;
|
|
11
|
+
const OCF_MRVL_WRITE_BD_ADDR = 0x0022;
|
|
12
|
+
const OCF_ERICSSON_STORE_IN_FLASH = 0x0022;
|
|
13
|
+
const ERICSSON_STORE_IN_FLASH_CP_SIZE = 0xFF;
|
|
14
|
+
|
|
15
|
+
function parseAddress (address) {
|
|
16
|
+
// Parse MAC Address as in 00:00:00:00:00:00 into Buffer (needs to reverse byte order)
|
|
17
|
+
const macAddress = Buffer.from(address.split(':').reverse().join(''), 'hex');
|
|
18
|
+
|
|
19
|
+
if (Buffer.isBuffer(macAddress) && macAddress.byteLength !== 6) {
|
|
20
|
+
throw new Error('Invalid MAC Address. Should be formated as 00:00:00:00:00:00 string.');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return macAddress;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// eslint-disable-next-line camelcase
|
|
27
|
+
function csr_write_bd_addr (address) {
|
|
28
|
+
// Parse MAC Address
|
|
29
|
+
const macAddress = parseAddress(address);
|
|
30
|
+
|
|
31
|
+
if (macAddress === null) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Base command
|
|
36
|
+
const base = Buffer.from([
|
|
37
|
+
0x02, 0x00, 0x0c, 0x00, 0x11, 0x47, 0x03, 0x70,
|
|
38
|
+
0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
|
|
39
|
+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
// Command
|
|
43
|
+
const cmd = Buffer.alloc(3 + base.byteLength);
|
|
44
|
+
|
|
45
|
+
cmd.writeUInt16LE(0x00 | OGF_VENDOR_CMD << 10, 0);
|
|
46
|
+
cmd.writeUInt8(0xC2, 2);
|
|
47
|
+
|
|
48
|
+
base.writeUint8(macAddress.readUInt8(2), 16);
|
|
49
|
+
base.writeUint8(0x00, 17);
|
|
50
|
+
base.writeUint8(macAddress.readUInt8(0), 18);
|
|
51
|
+
base.writeUint8(macAddress.readUInt8(1), 19);
|
|
52
|
+
base.writeUint8(macAddress.readUInt8(3), 20);
|
|
53
|
+
base.writeUint8(0x00, 21);
|
|
54
|
+
base.writeUint8(macAddress.readUInt8(4), 22);
|
|
55
|
+
base.writeUint8(macAddress.readUInt8(5), 23);
|
|
56
|
+
base.copy(cmd, 3);
|
|
57
|
+
|
|
58
|
+
return cmd;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// eslint-disable-next-line camelcase
|
|
62
|
+
function ericsson_store_in_flash (user_id, data) {
|
|
63
|
+
// Check Data
|
|
64
|
+
if (Buffer.isBuffer(data) === false || data.byteLength > OCF_ERICSSON_STORE_IN_FLASH - 2) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Command
|
|
69
|
+
const cmd = Buffer.alloc(3 + ERICSSON_STORE_IN_FLASH_CP_SIZE);
|
|
70
|
+
|
|
71
|
+
cmd.writeUInt16LE(OCF_ERICSSON_STORE_IN_FLASH | OGF_VENDOR_CMD << 10, 0);
|
|
72
|
+
cmd.writeUInt8(ERICSSON_STORE_IN_FLASH_CP_SIZE, 2);
|
|
73
|
+
cmd.writeUInt8(user_id, 3); // user_id
|
|
74
|
+
cmd.writeUInt8(data.byteLength, 4); // flash_length
|
|
75
|
+
data.copy(cmd, 5); // flash_data
|
|
76
|
+
|
|
77
|
+
return cmd;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// eslint-disable-next-line camelcase
|
|
81
|
+
function st_write_bd_addr (address) {
|
|
82
|
+
// Parse MAC Address
|
|
83
|
+
const macAddress = parseAddress(address);
|
|
84
|
+
|
|
85
|
+
if (macAddress === null) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return ericsson_store_in_flash(0xFE, macAddress);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// eslint-disable-next-line camelcase
|
|
93
|
+
function mrvl_write_bd_addr (address) {
|
|
94
|
+
// Parse MAC Address
|
|
95
|
+
const macAddress = parseAddress(address);
|
|
96
|
+
|
|
97
|
+
if (macAddress === null) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Command
|
|
102
|
+
const cmd = Buffer.alloc(11);
|
|
103
|
+
|
|
104
|
+
cmd.writeUInt16LE(OCF_MRVL_WRITE_BD_ADDR | OGF_VENDOR_CMD << 10, 0);
|
|
105
|
+
cmd.writeUInt8(0x08, 2);
|
|
106
|
+
cmd.writeUInt8(0xFE, 3); // parameter_id
|
|
107
|
+
cmd.writeUInt8(0x06, 4); // bdaddr_len
|
|
108
|
+
macAddress.copy(cmd, 5); // bdaddr
|
|
109
|
+
|
|
110
|
+
return cmd;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// eslint-disable-next-line camelcase
|
|
114
|
+
function write_common_bd_addr (OCF_VS_WRITE_BD_ADDR) {
|
|
115
|
+
// Return a function
|
|
116
|
+
return (address) => {
|
|
117
|
+
// Parse MAC Address
|
|
118
|
+
const macAddress = parseAddress(address);
|
|
119
|
+
|
|
120
|
+
if (macAddress === null) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Command
|
|
125
|
+
const cmd = Buffer.alloc(9);
|
|
126
|
+
|
|
127
|
+
cmd.writeUInt16LE(OCF_VS_WRITE_BD_ADDR | OGF_VENDOR_CMD << 10, 0);
|
|
128
|
+
cmd.writeUInt8(0x06, 2);
|
|
129
|
+
macAddress.copy(cmd, 3); // bdaddr
|
|
130
|
+
|
|
131
|
+
return cmd;
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const vendors = new Map();
|
|
136
|
+
|
|
137
|
+
vendors.set(0, write_common_bd_addr(OCF_ERICSSON_WRITE_BD_ADDR));
|
|
138
|
+
vendors.set(10, csr_write_bd_addr);
|
|
139
|
+
vendors.set(13, write_common_bd_addr(OCF_TI_WRITE_BD_ADDR));
|
|
140
|
+
vendors.set(15, write_common_bd_addr(OCF_BCM_WRITE_BD_ADDR));
|
|
141
|
+
vendors.set(18, write_common_bd_addr(OCF_ZEEVO_WRITE_BD_ADDR));
|
|
142
|
+
vendors.set(48, st_write_bd_addr);
|
|
143
|
+
vendors.set(57, write_common_bd_addr(OCF_ERICSSON_WRITE_BD_ADDR));
|
|
144
|
+
vendors.set(72, mrvl_write_bd_addr);
|
|
145
|
+
vendors.set(1521, write_common_bd_addr(OCF_LINUX_FOUNDATION_WRITE_BD_ADDR));
|
|
146
|
+
|
|
147
|
+
module.exports = {
|
|
148
|
+
// Vendor Specific Set Address
|
|
149
|
+
setAddressCmd: (manufacturer, address) => {
|
|
150
|
+
const generateCommand = vendors.get(manufacturer);
|
|
151
|
+
if (typeof generateCommand === 'function') {
|
|
152
|
+
return generateCommand(address) || null;
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
};
|
package/lib/mac/binding.gyp
CHANGED
|
@@ -1,26 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
+
'variables': {
|
|
3
|
+
'openssl_fips' : ''
|
|
4
|
+
},
|
|
2
5
|
'targets': [
|
|
3
6
|
{
|
|
4
7
|
'target_name': 'binding',
|
|
5
|
-
'sources': [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
'sources': [
|
|
9
|
+
'src/noble_mac.mm',
|
|
10
|
+
'src/napi_objc.mm',
|
|
11
|
+
'src/ble_manager.mm',
|
|
12
|
+
'src/objc_cpp.mm',
|
|
13
|
+
'src/callbacks.cc'
|
|
14
|
+
],
|
|
15
|
+
'include_dirs': [
|
|
16
|
+
"<!(node -p \"require('node-addon-api').include_dir\")"
|
|
17
|
+
],
|
|
8
18
|
'cflags!': [ '-fno-exceptions' ],
|
|
9
19
|
'cflags_cc!': [ '-fno-exceptions' ],
|
|
20
|
+
"defines": ["NAPI_CPP_EXCEPTIONS"],
|
|
10
21
|
'xcode_settings': {
|
|
11
22
|
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
|
|
23
|
+
'MACOSX_DEPLOYMENT_TARGET': '10.9',
|
|
12
24
|
'CLANG_CXX_LIBRARY': 'libc++',
|
|
13
|
-
'MACOSX_DEPLOYMENT_TARGET': '10.7',
|
|
14
25
|
'OTHER_CFLAGS': [
|
|
15
|
-
|
|
26
|
+
'-fobjc-arc',
|
|
27
|
+
'-arch x86_64',
|
|
28
|
+
'-arch arm64'
|
|
16
29
|
],
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
'
|
|
30
|
+
'OTHER_LDFLAGS': [
|
|
31
|
+
'-framework CoreBluetooth',
|
|
32
|
+
'-arch x86_64',
|
|
33
|
+
'-arch arm64'
|
|
21
34
|
]
|
|
22
|
-
}
|
|
23
|
-
'product_dir': '../lib/mac/native',
|
|
35
|
+
}
|
|
24
36
|
}
|
|
25
37
|
]
|
|
26
38
|
}
|
package/lib/noble.js
CHANGED
|
@@ -110,6 +110,14 @@ Noble.prototype.onScanParametersSet = function () {
|
|
|
110
110
|
this.emit('scanParametersSet');
|
|
111
111
|
};
|
|
112
112
|
|
|
113
|
+
Noble.prototype.setAddress = function (address) {
|
|
114
|
+
if (this._bindings.setAddress) {
|
|
115
|
+
this._bindings.setAddress(address);
|
|
116
|
+
} else {
|
|
117
|
+
this.emit('warning', 'current binding does not implement setAddress method.');
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
113
121
|
const startScanning = function (serviceUuids, allowDuplicates, callback) {
|
|
114
122
|
if (typeof serviceUuids === 'function') {
|
|
115
123
|
this.emit('warning', 'calling startScanning(callback) is deprecated');
|
package/lib/win/binding.gyp
CHANGED
|
@@ -1,22 +1,42 @@
|
|
|
1
1
|
{
|
|
2
|
+
'variables': {
|
|
3
|
+
'openssl_fips' : ''
|
|
4
|
+
},
|
|
2
5
|
'targets': [
|
|
3
6
|
{
|
|
4
7
|
'target_name': 'binding',
|
|
5
|
-
'sources': [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
'sources': [
|
|
9
|
+
'src/noble_winrt.cc',
|
|
10
|
+
'src/napi_winrt.cc',
|
|
11
|
+
'src/peripheral_winrt.cc',
|
|
12
|
+
'src/radio_watcher.cc',
|
|
13
|
+
'src/notify_map.cc',
|
|
14
|
+
'src/ble_manager.cc',
|
|
15
|
+
'src/winrt_cpp.cc',
|
|
16
|
+
'src/winrt_guid.cc',
|
|
17
|
+
'src/callbacks.cc'
|
|
18
|
+
],
|
|
19
|
+
'include_dirs': [
|
|
20
|
+
"<!(node -p \"require('node-addon-api').include_dir\")",
|
|
21
|
+
"<!@(node -p \"require('napi-thread-safe-callback').include\")"
|
|
22
|
+
],
|
|
8
23
|
'cflags!': [ '-fno-exceptions' ],
|
|
9
24
|
'cflags_cc!': [ '-fno-exceptions' ],
|
|
10
25
|
'msvs_settings': {
|
|
11
26
|
'VCCLCompilerTool': {
|
|
12
27
|
'ExceptionHandling': 1,
|
|
13
|
-
'AdditionalOptions': [
|
|
28
|
+
'AdditionalOptions': [
|
|
29
|
+
'/await',
|
|
30
|
+
'/std:c++latest'
|
|
31
|
+
],
|
|
14
32
|
},
|
|
15
33
|
},
|
|
16
34
|
'msvs_target_platform_version':'10.0.18362.0',
|
|
17
35
|
'msvs_target_platform_minversion':'10.0.18362.0',
|
|
18
36
|
'conditions': [
|
|
19
|
-
['OS=="win"', {
|
|
37
|
+
['OS=="win"', {
|
|
38
|
+
'defines': [ '_HAS_EXCEPTIONS=1' ]
|
|
39
|
+
}]
|
|
20
40
|
],
|
|
21
41
|
}
|
|
22
42
|
]
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"author": "Sandeep Mistry",
|
|
2
|
+
"author": "Sandeep Mistry <sandeep.mistry@gmail.com>",
|
|
3
3
|
"maintainers": [
|
|
4
|
-
"
|
|
5
|
-
"Luis Montes"
|
|
4
|
+
"Marek Serafin <marek@serafin.email>"
|
|
6
5
|
],
|
|
7
6
|
"license": "MIT",
|
|
8
7
|
"name": "@stoprocent/noble",
|
|
9
8
|
"description": "A Node.js BLE (Bluetooth Low Energy) central library.",
|
|
10
|
-
"version": "1.
|
|
9
|
+
"version": "1.13.0",
|
|
11
10
|
"repository": {
|
|
12
11
|
"type": "git",
|
|
13
12
|
"url": "https://github.com/stoprocent/noble.git"
|
|
@@ -28,12 +27,6 @@
|
|
|
28
27
|
"engines": {
|
|
29
28
|
"node": ">=6"
|
|
30
29
|
},
|
|
31
|
-
"os": [
|
|
32
|
-
"darwin",
|
|
33
|
-
"linux",
|
|
34
|
-
"freebsd",
|
|
35
|
-
"win32"
|
|
36
|
-
],
|
|
37
30
|
"dependencies": {
|
|
38
31
|
"debug": "^4.3.4",
|
|
39
32
|
"napi-thread-safe-callback": "^0.0.6",
|
|
@@ -41,9 +34,10 @@
|
|
|
41
34
|
"node-gyp-build": "^4.5.0"
|
|
42
35
|
},
|
|
43
36
|
"optionalDependencies": {
|
|
44
|
-
"@stoprocent/bluetooth-hci-socket": "^
|
|
37
|
+
"@stoprocent/bluetooth-hci-socket": "^1.1.2"
|
|
45
38
|
},
|
|
46
39
|
"devDependencies": {
|
|
40
|
+
"@semantic-release/exec": "^6.0.3",
|
|
47
41
|
"async": "^3.2.4",
|
|
48
42
|
"cross-env": "^7.0.3",
|
|
49
43
|
"eslint": "^8.31.0",
|
|
@@ -53,12 +47,13 @@
|
|
|
53
47
|
"eslint-plugin-n": "^15.6.0",
|
|
54
48
|
"eslint-plugin-promise": "^6.1.1",
|
|
55
49
|
"mocha": "^10.2.0",
|
|
56
|
-
"node-gyp": "^9.
|
|
50
|
+
"node-gyp": "^9.4.0",
|
|
57
51
|
"nyc": "^15.1.0",
|
|
58
52
|
"prebuildify": "^5.0.1",
|
|
59
|
-
"prebuildify-
|
|
53
|
+
"prebuildify-cross": "5.0.0",
|
|
60
54
|
"prettier": "^2.8.1",
|
|
61
55
|
"proxyquire": "^2.1.3",
|
|
56
|
+
"semantic-release": "21.1.0",
|
|
62
57
|
"should": "~13.2.3",
|
|
63
58
|
"sinon": "^15.0.1",
|
|
64
59
|
"ws": "^8.11.0"
|
|
@@ -67,11 +62,9 @@
|
|
|
67
62
|
"install": "node-gyp-build",
|
|
68
63
|
"lint": "eslint \"**/*.js\"",
|
|
69
64
|
"lint-fix": "eslint \"**/*.js\" --fix",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"prebuild-linux": "prebuildify --napi --strip",
|
|
74
|
-
"prebuild-download": "prebuildify-ci download",
|
|
65
|
+
"prebuildify": "prebuildify --napi --target 14.0.0 --force --strip --verbose",
|
|
66
|
+
"prebuildify-cross": "prebuildify-cross --napi --target 14.0.0 --force --strip --verbose",
|
|
67
|
+
"semantic-release": "semantic-release",
|
|
75
68
|
"pretest": "npm run rebuild",
|
|
76
69
|
"rebuild": "node-gyp rebuild",
|
|
77
70
|
"coverage": "nyc npm test && nyc report --reporter=text-lcov > .nyc_output/lcov.info",
|
|
@@ -80,9 +73,7 @@
|
|
|
80
73
|
"browser": {
|
|
81
74
|
"./lib/resolve-bindings.js": "./lib/resolve-bindings-web.js"
|
|
82
75
|
},
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
4
|
|
86
|
-
]
|
|
76
|
+
"publishConfig": {
|
|
77
|
+
"access": "public"
|
|
87
78
|
}
|
|
88
79
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -22,6 +22,7 @@ describe('hci-socket hci', () => {
|
|
|
22
22
|
Socket.prototype.isDevUp = sinon.stub();
|
|
23
23
|
Socket.prototype.removeAllListeners = sinon.stub();
|
|
24
24
|
Socket.prototype.setFilter = sinon.stub();
|
|
25
|
+
Socket.prototype.setAddress = sinon.stub();
|
|
25
26
|
Socket.prototype.write = sinon.stub();
|
|
26
27
|
|
|
27
28
|
hci = new Hci({});
|
|
@@ -43,7 +44,7 @@ describe('hci-socket hci', () => {
|
|
|
43
44
|
assert.calledWithMatch(hci._socket.on, 'data', sinon.match.func);
|
|
44
45
|
assert.calledWithMatch(hci._socket.on, 'error', sinon.match.func);
|
|
45
46
|
|
|
46
|
-
assert.calledOnceWithExactly(hci._socket.bindUser, deviceId);
|
|
47
|
+
assert.calledOnceWithExactly(hci._socket.bindUser, deviceId, undefined);
|
|
47
48
|
assert.calledOnceWithExactly(hci._socket.start);
|
|
48
49
|
|
|
49
50
|
assert.calledOnceWithExactly(hci.reset);
|
|
@@ -60,7 +61,7 @@ describe('hci-socket hci', () => {
|
|
|
60
61
|
assert.calledWithMatch(hci._socket.on, 'data', sinon.match.func);
|
|
61
62
|
assert.calledWithMatch(hci._socket.on, 'error', sinon.match.func);
|
|
62
63
|
|
|
63
|
-
assert.calledOnceWithExactly(hci._socket.bindRaw, deviceId);
|
|
64
|
+
assert.calledOnceWithExactly(hci._socket.bindRaw, deviceId, undefined);
|
|
64
65
|
assert.calledOnceWithExactly(hci._socket.start);
|
|
65
66
|
|
|
66
67
|
assert.calledOnceWithExactly(hci.pollIsDevUp);
|
|
@@ -230,11 +231,6 @@ describe('hci-socket hci', () => {
|
|
|
230
231
|
assert.calledOnceWithExactly(hci._socket.write, Buffer.from([0x01, 0x31, 0x20, 0x03, 0x00, 0x05, 0x05]));
|
|
231
232
|
});
|
|
232
233
|
|
|
233
|
-
it('should write randomMAC command', () => {
|
|
234
|
-
hci.setRandomMAC();
|
|
235
|
-
assert.calledOnceWithExactly(hci._socket.write, Buffer.from([0x01, 0x05, 0x20, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00]));
|
|
236
|
-
});
|
|
237
|
-
|
|
238
234
|
it('should setSocketFilter', () => {
|
|
239
235
|
hci.setSocketFilter();
|
|
240
236
|
assert.calledOnceWithExactly(hci._socket.setFilter, Buffer.from([0x16, 0, 0, 0, 0x20, 0xc1, 0x08, 0, 0, 0, 0, 0x40, 0, 0]));
|
|
@@ -270,6 +266,50 @@ describe('hci-socket hci', () => {
|
|
|
270
266
|
assert.calledOnceWithExactly(hci._socket.write, Buffer.from([1, 9, 0x10, 0]));
|
|
271
267
|
});
|
|
272
268
|
|
|
269
|
+
describe('setAddress', () => {
|
|
270
|
+
it('should write vendor specific (Linux Foundation) command based on read local version response', () => {
|
|
271
|
+
hci.readBdAddr = sinon.spy();
|
|
272
|
+
hci.setScanEnabled = sinon.spy();
|
|
273
|
+
hci.setScanParameters = sinon.spy();
|
|
274
|
+
|
|
275
|
+
const cmd = 4097;
|
|
276
|
+
const status = 0;
|
|
277
|
+
// hciVer=12, hciRev=0, lmpVer=12, manufacturer=1521, lmpSubVer=65535
|
|
278
|
+
const result = Buffer.from([0x0C, 0x00, 0x00, 0x0C, 0xF1, 0x05, 0xFF, 0xFF]);
|
|
279
|
+
|
|
280
|
+
hci.processCmdCompleteEvent(cmd, status, result);
|
|
281
|
+
|
|
282
|
+
hci.setAddress('11:22:33:44:55:66');
|
|
283
|
+
assert.calledOnceWithExactly(hci._socket.write, Buffer.from([0x01, 0x06, 0xfc, 0x06, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]));
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it('should write vendor specific (Ericsson) command based on manufacturer value (', () => {
|
|
287
|
+
hci._manufacturer = 0;
|
|
288
|
+
hci.readBdAddr = sinon.spy();
|
|
289
|
+
hci.setAddress('11:22:33:44:55:66');
|
|
290
|
+
assert.calledOnceWithExactly(hci._socket.write, Buffer.from([0x01, 0x0d, 0xfc, 0x06, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]));
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('should write vendor specific (Texas Instrument) command based on manufacturer value', () => {
|
|
294
|
+
hci._manufacturer = 13;
|
|
295
|
+
hci.readBdAddr = sinon.spy();
|
|
296
|
+
hci.setAddress('11:22:33:44:55:66');
|
|
297
|
+
assert.calledOnceWithExactly(hci._socket.write, Buffer.from([0x01, 0x06, 0xfc, 0x06, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]));
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('should write vendor specific (BCM) command based on manufacturer value', () => {
|
|
301
|
+
hci._manufacturer = 15;
|
|
302
|
+
hci.readBdAddr = sinon.spy();
|
|
303
|
+
hci.setAddress('11:22:33:44:55:66');
|
|
304
|
+
assert.calledOnceWithExactly(hci._socket.write, Buffer.from([0x01, 0x01, 0xfc, 0x06, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]));
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it('should not write vendor specific command', () => {
|
|
308
|
+
hci.setAddress('11:22:33:44:55:66');
|
|
309
|
+
assert.notCalled(hci._socket.write);
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
|
|
273
313
|
describe('setLeEventMask', () => {
|
|
274
314
|
it('should setLeEventMask', () => {
|
|
275
315
|
hci.setLeEventMask();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const should = require('should');
|
|
2
|
+
const sinon = require('sinon');
|
|
3
|
+
const proxyquire = require('proxyquire').noCallThru();
|
|
4
|
+
|
|
5
|
+
const fakeOs = {};
|
|
6
|
+
const { assert } = sinon;
|
|
7
|
+
const vendorSpecific = proxyquire('../../../lib/hci-socket/vs', { os: fakeOs });
|
|
8
|
+
|
|
9
|
+
describe('hci-socket vs', () => {
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
sinon.reset();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe('parseAddress', () => {
|
|
15
|
+
it('should convert to Buffer', () => {
|
|
16
|
+
assert.match(vendorSpecific.setAddressCmd(0, '00:11:22:33:44:55').slice(3), Buffer.from([0x55, 0x44, 0x33, 0x22, 0x11, 0x00]));
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should not convert to Buffer and throw an Error', () => {
|
|
20
|
+
should.throws(function () {
|
|
21
|
+
vendorSpecific.setAddressCmd(0, '00:11:22:33:44');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
package/.eslintrc.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
root: true,
|
|
3
|
-
extends: ['eslint:recommended', 'semistandard'],
|
|
4
|
-
parserOptions: {
|
|
5
|
-
ecmaVersion: 2017
|
|
6
|
-
},
|
|
7
|
-
env: {
|
|
8
|
-
browser: true,
|
|
9
|
-
mocha: true,
|
|
10
|
-
node: true
|
|
11
|
-
},
|
|
12
|
-
globals: {
|
|
13
|
-
Promise: true
|
|
14
|
-
},
|
|
15
|
-
rules: {
|
|
16
|
-
'space-before-function-paren': ['error', 'always'],
|
|
17
|
-
'no-unused-vars': [
|
|
18
|
-
'error',
|
|
19
|
-
{
|
|
20
|
-
args: 'none'
|
|
21
|
-
}
|
|
22
|
-
],
|
|
23
|
-
semi: 'error'
|
|
24
|
-
}
|
|
25
|
-
};
|
package/.github/FUNDING.yml
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# YAML
|
|
2
|
-
---
|
|
3
|
-
name: fediverse-action
|
|
4
|
-
on: [push]
|
|
5
|
-
jobs:
|
|
6
|
-
post:
|
|
7
|
-
runs-on: ubuntu-latest
|
|
8
|
-
steps:
|
|
9
|
-
- uses: actions/checkout@v3
|
|
10
|
-
- id: log
|
|
11
|
-
run: echo "::set-output name=message::$(git log --no-merges -1 --oneline)"
|
|
12
|
-
- if: "contains(steps.log.outputs.message, 'Release ')"
|
|
13
|
-
uses: rzr/fediverse-action@master
|
|
14
|
-
with:
|
|
15
|
-
access-token: ${{ secrets.MASTODON_ACCESS_TOKEN }}
|
|
16
|
-
message: "https://github.com/${{ github.repository }}/commit/${{ steps.log.outputs.message }} ~ #FediVerseAction"
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
name: Node.js package
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
branches:
|
|
6
|
-
- master
|
|
7
|
-
push:
|
|
8
|
-
branches:
|
|
9
|
-
- master
|
|
10
|
-
|
|
11
|
-
jobs:
|
|
12
|
-
build:
|
|
13
|
-
runs-on: ${{ matrix.os }}
|
|
14
|
-
strategy:
|
|
15
|
-
matrix:
|
|
16
|
-
os: [ubuntu-20.04, ubuntu-latest, macos-latest, windows-2019]
|
|
17
|
-
node: [12, 14, 16, 18]
|
|
18
|
-
steps:
|
|
19
|
-
- uses: actions/checkout@v3
|
|
20
|
-
- uses: actions/setup-node@v3
|
|
21
|
-
with:
|
|
22
|
-
node-version: ${{ matrix.node }}
|
|
23
|
-
- name: Install dependencies (ubuntu-latest)
|
|
24
|
-
if: ${{ matrix.os == 'ubuntu-latest' }}
|
|
25
|
-
run: |
|
|
26
|
-
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
|
27
|
-
sudo apt -qq update
|
|
28
|
-
sudo apt install -y g++-9
|
|
29
|
-
export CC="g++-9"
|
|
30
|
-
- name: Install NPM packages
|
|
31
|
-
run: |
|
|
32
|
-
npm install
|
|
33
|
-
- name: Run tests
|
|
34
|
-
run: |
|
|
35
|
-
npm test
|
|
36
|
-
- name: Lint
|
|
37
|
-
run: |
|
|
38
|
-
npm run lint
|
|
39
|
-
|
|
40
|
-
quality:
|
|
41
|
-
name: Quality phase
|
|
42
|
-
runs-on: ubuntu-latest
|
|
43
|
-
steps:
|
|
44
|
-
- name: ⬇️ Checkout code
|
|
45
|
-
uses: actions/checkout@v3
|
|
46
|
-
- name: 💽 Setup nodejs
|
|
47
|
-
uses: actions/setup-node@v3
|
|
48
|
-
with:
|
|
49
|
-
node-version: '14'
|
|
50
|
-
- name: 📇 Use npm cache
|
|
51
|
-
uses: c-hive/gha-npm-cache@v1
|
|
52
|
-
- name: Install dependencies (ubuntu-latest)
|
|
53
|
-
run: |
|
|
54
|
-
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
|
55
|
-
sudo apt -qq update
|
|
56
|
-
sudo apt install -y g++-9
|
|
57
|
-
export CC="g++-9"
|
|
58
|
-
- name: 📦 Install NPM packages
|
|
59
|
-
run: |
|
|
60
|
-
npm install
|
|
61
|
-
- name: ✅ Test with coverage
|
|
62
|
-
run: |
|
|
63
|
-
npm run coverage
|
|
64
|
-
- name: 📄 Codecov report upload
|
|
65
|
-
uses: codecov/codecov-action@v2
|
|
66
|
-
with:
|
|
67
|
-
fail_ci_if_error: true
|
|
68
|
-
file: .nyc_output/lcov.info
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
name: npm-publish
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- master # Change this to your default branch
|
|
6
|
-
jobs:
|
|
7
|
-
npm-publish:
|
|
8
|
-
name: npm-publish
|
|
9
|
-
runs-on: ubuntu-latest
|
|
10
|
-
steps:
|
|
11
|
-
- uses: actions/checkout@master
|
|
12
|
-
- id: log
|
|
13
|
-
run: echo "::set-output name=message::$(git log --no-merges -1 --oneline)"
|
|
14
|
-
- if: "contains(steps.log.outputs.message, 'Release ')"
|
|
15
|
-
uses: actions/setup-node@master
|
|
16
|
-
with:
|
|
17
|
-
node-version: 16.0.0
|
|
18
|
-
- if: "contains(steps.log.outputs.message, 'Release ')"
|
|
19
|
-
uses: pascalgn/npm-publish-action@1.3.9
|
|
20
|
-
with: # All of these inputs are optional
|
|
21
|
-
tag_name: "v%s"
|
|
22
|
-
tag_message: "v%s"
|
|
23
|
-
commit_pattern: "^Release (\\S+)"
|
|
24
|
-
env: # More info about the environment variables in the README
|
|
25
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Leave this as is, it's automatically generated
|
|
26
|
-
NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} # You need to set this in your repo settings
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
name: prebuild
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- master
|
|
7
|
-
tags:
|
|
8
|
-
- '*'
|
|
9
|
-
pull_request:
|
|
10
|
-
branches:
|
|
11
|
-
- master
|
|
12
|
-
workflow_dispatch:
|
|
13
|
-
|
|
14
|
-
jobs:
|
|
15
|
-
prebuild:
|
|
16
|
-
strategy:
|
|
17
|
-
matrix:
|
|
18
|
-
include:
|
|
19
|
-
- name: darwin
|
|
20
|
-
os: macos-11
|
|
21
|
-
node: x64
|
|
22
|
-
- name: linux
|
|
23
|
-
os: ubuntu-latest
|
|
24
|
-
- name: win32
|
|
25
|
-
os: windows-2019
|
|
26
|
-
name: Build ${{ matrix.name }}
|
|
27
|
-
runs-on: ${{ matrix.os }}
|
|
28
|
-
steps:
|
|
29
|
-
- if: matrix.node
|
|
30
|
-
uses: actions/setup-node@v3
|
|
31
|
-
with:
|
|
32
|
-
node-version: 14.x
|
|
33
|
-
architecture: ${{ matrix.node }}
|
|
34
|
-
- uses: actions/checkout@v3
|
|
35
|
-
- name: Install dependencies (ubuntu-latest)
|
|
36
|
-
# Use g++-9 only on versions after 'ubuntu-18.04'
|
|
37
|
-
if: ${{ matrix.os == 'ubuntu-latest' }}
|
|
38
|
-
run: |
|
|
39
|
-
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
|
40
|
-
sudo apt -qq update
|
|
41
|
-
sudo apt install -y g++-9
|
|
42
|
-
export CC="g++-9"
|
|
43
|
-
- run: npm install --ignore-scripts
|
|
44
|
-
- run: npm run prebuild-${{ matrix.name }}
|
|
45
|
-
- run: tar -zcvf ${{ matrix.name }}.tar.gz -C prebuilds .
|
|
46
|
-
- uses: actions/upload-artifact@v2
|
|
47
|
-
with:
|
|
48
|
-
name: ${{ matrix.name }}
|
|
49
|
-
path: ${{ matrix.name }}.tar.gz
|
|
50
|
-
retention-days: 1
|
|
51
|
-
release:
|
|
52
|
-
needs: prebuild
|
|
53
|
-
name: Release
|
|
54
|
-
runs-on: ubuntu-latest
|
|
55
|
-
if: startsWith(github.ref, 'refs/tags/')
|
|
56
|
-
steps:
|
|
57
|
-
- uses: actions/checkout@v3
|
|
58
|
-
- uses: actions/download-artifact@v2
|
|
59
|
-
with:
|
|
60
|
-
path: artifacts
|
|
61
|
-
- uses: docker://antonyurchenko/git-release:v4
|
|
62
|
-
env:
|
|
63
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
64
|
-
ALLOW_EMPTY_CHANGELOG: true
|
|
65
|
-
with:
|
|
66
|
-
args: artifacts/*/*.tar.gz
|
package/CHANGELOG.md
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
## Version 1.9.1
|
|
2
|
-
|
|
3
|
-
* Don't forget previously discovered services and characteristics ([@elafargue](https://github.com/elafargue))
|
|
4
|
-
* Fixed peripheral-explorer example with newer async versions
|
|
5
|
-
* web socket binding: various fixes ([@hadrienk](https://github.com/hadrienk))
|
|
6
|
-
* Fix multiple init of bindings with multiple stateChange listeners added or noble.state is accessed
|
|
7
|
-
|
|
8
|
-
## Version 1.9.0
|
|
9
|
-
|
|
10
|
-
* Don't initialize bindings until first state change listener added
|
|
11
|
-
* webble: hooked up disconnect event
|
|
12
|
-
* webble: clear cached services on reconnect
|
|
13
|
-
* hci-socket: Added upport 32-bit and 128-bit service data UUIDs ([@arekzelechowski](https://github.com/arekzelechowski))
|
|
14
|
-
* Update 'connectable' property upon discovery ([@dimitrisx](https://github.com/dimitrisx))
|
|
15
|
-
* macOS: Added support for High Sierra
|
|
16
|
-
* webble: remove subscribe listeners on disconnect
|
|
17
|
-
|
|
18
|
-
## Version 1.8.1
|
|
19
|
-
|
|
20
|
-
* easier install instructions for Windows ([@don](https://github.com/don))
|
|
21
|
-
* hci-socket binding: more descriptive error outputs ([@mbifulco](https://github.com/mbifulco))
|
|
22
|
-
* hci-socket binding: report non-connectable advertisements without scan response
|
|
23
|
-
* Corrected deprecated `read` event for characteristics no emitting for notifications
|
|
24
|
-
|
|
25
|
-
## Version 1.8.0
|
|
26
|
-
|
|
27
|
-
* hci-socket binding: always set scan parameters before scanning ([@Lahorde](https://github.com/Lahorde))
|
|
28
|
-
* hci-socket binding: add L2CAP signaling layer for non-Linux or Linux user channel mode
|
|
29
|
-
* hci-socket binding: Workarounds for scanning with N.T.C. C.H.I.P
|
|
30
|
-
* hci-socket binding: if `init()` fails we don't want to try and clear up ([@gfwilliams](https://github.com/gfwilliams))
|
|
31
|
-
* Fix read events firing for notifications ([@zkiiito](https://github.com/zkiiito))
|
|
32
|
-
* Add FreeBSD support ([@myfreeweb](https://github.com/myfreeweb))
|
|
33
|
-
* Fix startScanning callback calling setting error to try ([@MarSoft](https://github.com/MarSoft))
|
|
34
|
-
* New Web Bluetooth API shim ([@monteslu](https://github.com/monteslu))
|
|
35
|
-
|
|
36
|
-
## Version 1.7.0
|
|
37
|
-
|
|
38
|
-
* hci-socket binding: now supports "long writes" ([@projectgus](https://github.com/projectgus))
|
|
39
|
-
* hci-socket binding: use latest bluetooth-hci-socket dependency (~0.5.1)
|
|
40
|
-
* hci-socket binding: add support to extract service solicitation UUID's from advertisement ([@smartyw](https://github.com/smartyw))
|
|
41
|
-
* web-socket binding: fixed write handle not working ([@christopherhex](https://github.com/christopherhex))
|
|
42
|
-
* hci-socket binding: initial bindUser support via HCI_CHANNEL_USER environment variable
|
|
43
|
-
|
|
44
|
-
## Version 1.6.0
|
|
45
|
-
|
|
46
|
-
* hci-socket binding: use latest bluetooth-hci-socket dependency (~0.4.4)
|
|
47
|
-
* Added characteristic.subscribe and characteristic.unsubscribe API's (characteristic.notify is now deprecated)
|
|
48
|
-
* hci-socket binding: use OCF_LE_SET_EVENT_MASK for LE_SET_EVENT_MASK_CMD
|
|
49
|
-
* hci-socket binding: check READ_LE_HOST_SUPPORTED_CMD status before parsing result
|
|
50
|
-
|
|
51
|
-
## Version 1.5.0
|
|
52
|
-
|
|
53
|
-
* hci-socket binding: add NOBLE_MULTI_ROLE flag for ignoring peripheral role commands ([@popasquat89](https://github.com/bradjc))
|
|
54
|
-
* Fix variable typo in ```with-bindings.js`` ([@rclai](https://github.com/rclai))
|
|
55
|
-
|
|
56
|
-
## Version 1.4.0
|
|
57
|
-
|
|
58
|
-
* hci-socket binding: include service data UUID's when filtering discover
|
|
59
|
-
* hci-socket binding: emit scan start/stop when external app changes scanning start ([@bradjc](https://github.com/bradjc))
|
|
60
|
-
* Support for pluggable bindings ([@hgwood](https://github.com/hgwood))
|
|
61
|
-
* hci-socket binding: don't kill all descriptors when looking for new Characteristics ([@Neutrosider](https://github.com/Neutrosider))
|
|
62
|
-
|
|
63
|
-
## Version 1.3.0
|
|
64
|
-
|
|
65
|
-
* Check and report LE Create Conn command status
|
|
66
|
-
* Correct parsing master clock accuracy value from LE Conn Complete event
|
|
67
|
-
* Added logic to reject rather than ignore unknown requests/commands. ([@george-hawkins](https://github.com/george-hawkins))
|
|
68
|
-
* Don't reset scan state on read local version response if state is powered on
|
|
69
|
-
* Expose local adapter address via ```noble.address```, available after ```poweredOn``` state change event
|
|
70
|
-
* Fix ```serviceUuids``` var check in ```peripheral-explorer.js``` ([@jrobeson](https://github.com/jrobeson))
|
|
71
|
-
|
|
72
|
-
## Version 1.2.1
|
|
73
|
-
|
|
74
|
-
* Use latest v0.4.1 bluetooth-hci-socket dependency (for kernel 4.1.x disconnect workaround)
|
|
75
|
-
* Add read + write LE host supported commands (for kernel 4.1.x disconnect workaround)
|
|
76
|
-
* Fix a potential exception when accessing a non existent element ([@Loghorn](https://github.com/Loghorn))
|
|
77
|
-
|
|
78
|
-
## Version 1.2.0
|
|
79
|
-
|
|
80
|
-
* Use v0.4.0 of bluetooth-hci-socket
|
|
81
|
-
* Ignore peripherals with only connectable flag on OS X 10.10
|
|
82
|
-
* Bindings no longer init themselves
|
|
83
|
-
* Fix this._discoveredPeripheralUUids = []; variable not initalized in constructor ([@jacobrosenthal](https://github.com/jacobrosenthal))
|
|
84
|
-
* New ```peripheral.connectable``` property
|
|
85
|
-
* Updates to Linux prerequisites in read me
|
|
86
|
-
* Throw error if scanning is started when state is not powered on
|
|
87
|
-
|
|
88
|
-
## Version 1.1.0
|
|
89
|
-
|
|
90
|
-
* Introduce ```peripheral.id```, ```periheral.uuid``` is deprecated now
|
|
91
|
-
* Initial Windows support via WinUSB and bluetooth-hci-socket
|
|
92
|
-
* Rework Linux stack to use [bluetooth-hci-socket](https://github.com/sandeepmistry/node-bluetooth-hci-socket)
|
|
93
|
-
* Clarify notify related API's in read me ([@OJFord](https://github.com/OJFord))
|
|
94
|
-
|
|
95
|
-
## Version 1.0.2
|
|
96
|
-
|
|
97
|
-
* Add mac dummy in binding.pyq ([@DomiR](https://github.com/DomiR))
|
|
98
|
-
* Fixes for distributed and websocket bindings ([@Loghorn](https://github.com/Loghorn))
|
|
99
|
-
* OS X Mavericks and legacy: manually emit write event for write without response requests
|
|
100
|
-
* Update README for packages needed for rpm-based systems ([@ppannuto](https://github.com/ppannuto))
|
|
101
|
-
* Linux: refresh serviceUuids for incoming advertisement ([@BBarash](https://github.com/BBarash))
|
|
102
|
-
|
|
103
|
-
## Version 1.0.1
|
|
104
|
-
|
|
105
|
-
* correct peripherals not being created correctly
|
|
106
|
-
|
|
107
|
-
## Version 1.0
|
|
108
|
-
|
|
109
|
-
* remove unneeded setTimeout's in OS X bindings
|
|
110
|
-
* added persistent peripherals between calls to .startScanning() on mavericks ([@andySigler](https://github.com/andySigler))
|
|
111
|
-
* report error or print warning if startScanning is called with state is not poweredOn
|
|
112
|
-
* emit events for warnings ([@voodootikigod ](https://github.com/voodootikigod))
|
|
113
|
-
* disable scanning flag on start on Linux to prevent unsupport adapter state in some cases
|
|
114
|
-
* update debug dependency version
|
|
115
|
-
* add address type to peripheral if known
|
|
116
|
-
|
|
117
|
-
## Older
|
|
118
|
-
|
|
119
|
-
* Changes not recorded
|
package/MAINTAINERS.md
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
* Philippe Coval <mailto:p.coval@samsung.com> (https://www.npmjs.com/~rzr)
|
package/test.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
const noble = require('./index');
|
|
2
|
-
|
|
3
|
-
console.log('noble');
|
|
4
|
-
|
|
5
|
-
noble.on('stateChange', function (state) {
|
|
6
|
-
console.log('on -> stateChange: ' + state);
|
|
7
|
-
|
|
8
|
-
if (state === 'poweredOn') {
|
|
9
|
-
noble.startScanning([], true);
|
|
10
|
-
} else {
|
|
11
|
-
noble.stopScanning();
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
noble.on('scanStart', function () {
|
|
16
|
-
console.log('on -> scanStart');
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
noble.on('scanStop', function () {
|
|
20
|
-
console.log('on -> scanStop');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
noble.on('discover', function (peripheral) {
|
|
24
|
-
console.log('on -> discover: ' + peripheral);
|
|
25
|
-
|
|
26
|
-
noble.stopScanning();
|
|
27
|
-
|
|
28
|
-
peripheral.on('connect', function () {
|
|
29
|
-
console.log('on -> connect');
|
|
30
|
-
this.updateRssi();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
peripheral.on('disconnect', function () {
|
|
34
|
-
console.log('on -> disconnect');
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
peripheral.on('rssiUpdate', function (rssi) {
|
|
38
|
-
console.log('on -> RSSI update ' + rssi);
|
|
39
|
-
this.discoverServices();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
peripheral.on('servicesDiscover', function (services) {
|
|
43
|
-
console.log('on -> peripheral services discovered ' + services);
|
|
44
|
-
|
|
45
|
-
const serviceIndex = 0;
|
|
46
|
-
|
|
47
|
-
services[serviceIndex].on(
|
|
48
|
-
'includedServicesDiscover',
|
|
49
|
-
function (includedServiceUuids) {
|
|
50
|
-
console.log(
|
|
51
|
-
'on -> service included services discovered ' + includedServiceUuids
|
|
52
|
-
);
|
|
53
|
-
this.discoverCharacteristics();
|
|
54
|
-
}
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
services[serviceIndex].on(
|
|
58
|
-
'characteristicsDiscover',
|
|
59
|
-
function (characteristics) {
|
|
60
|
-
console.log(
|
|
61
|
-
'on -> service characteristics discovered ' + characteristics
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
const characteristicIndex = 0;
|
|
65
|
-
|
|
66
|
-
characteristics[characteristicIndex].on(
|
|
67
|
-
'read',
|
|
68
|
-
function (data, isNotification) {
|
|
69
|
-
console.log(
|
|
70
|
-
'on -> characteristic read ' + data + ' ' + isNotification
|
|
71
|
-
);
|
|
72
|
-
console.log(data);
|
|
73
|
-
|
|
74
|
-
peripheral.disconnect();
|
|
75
|
-
}
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
characteristics[characteristicIndex].on('write', function () {
|
|
79
|
-
console.log('on -> characteristic write ');
|
|
80
|
-
|
|
81
|
-
peripheral.disconnect();
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
characteristics[characteristicIndex].on('broadcast', function (state) {
|
|
85
|
-
console.log('on -> characteristic broadcast ' + state);
|
|
86
|
-
|
|
87
|
-
peripheral.disconnect();
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
characteristics[characteristicIndex].on('notify', function (state) {
|
|
91
|
-
console.log('on -> characteristic notify ' + state);
|
|
92
|
-
|
|
93
|
-
peripheral.disconnect();
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
characteristics[characteristicIndex].on(
|
|
97
|
-
'descriptorsDiscover',
|
|
98
|
-
function (descriptors) {
|
|
99
|
-
console.log('on -> descriptors discover ' + descriptors);
|
|
100
|
-
|
|
101
|
-
const descriptorIndex = 0;
|
|
102
|
-
|
|
103
|
-
descriptors[descriptorIndex].on('valueRead', function (data) {
|
|
104
|
-
console.log('on -> descriptor value read ' + data);
|
|
105
|
-
console.log(data);
|
|
106
|
-
peripheral.disconnect();
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
descriptors[descriptorIndex].on('valueWrite', function () {
|
|
110
|
-
console.log('on -> descriptor value write ');
|
|
111
|
-
peripheral.disconnect();
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
descriptors[descriptorIndex].readValue();
|
|
115
|
-
// descriptors[descriptorIndex].writeValue(new Buffer([0]));
|
|
116
|
-
}
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
characteristics[characteristicIndex].read();
|
|
120
|
-
// characteristics[characteristicIndex].write(new Buffer('hello'));
|
|
121
|
-
// characteristics[characteristicIndex].broadcast(true);
|
|
122
|
-
// characteristics[characteristicIndex].notify(true);
|
|
123
|
-
// characteristics[characteristicIndex].discoverDescriptors();
|
|
124
|
-
}
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
services[serviceIndex].discoverIncludedServices();
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
peripheral.connect();
|
|
131
|
-
});
|