@stoprocent/noble 1.17.0 → 1.17.2

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 CHANGED
@@ -16,9 +16,12 @@ This fork of `noble` was created to introduce several key improvements and new f
16
16
 
17
17
  2. **macOS Native Bindings Fix**: I have fixed the native bindings for macOS, ensuring better compatibility and performance on Apple devices.
18
18
 
19
- 3. **New Features**:
20
- - A `setAddress` function has been added, allowing users to set the MAC address of the central device.
19
+ 3. **Windows Native Bindings Fix**: I have fixed the native bindings for Windows, adding support for `Service Data` from advertisements.
20
+
21
+ 4. **New Features**:
22
+ - A `setAddress(...)` function has been added, allowing users to set the MAC address of the central device.
21
23
  - A `connect(...)/connectAsync(...)` function has been added, allowing users to connect directly to specific device by address/identifier without a need to prior scan.
24
+ - A `waitForPoweredOn(...)` function to wait for the adapter to be powered on in await/async functions.
22
25
  - Additionally, I plan to add raw L2CAP channel support, enhancing low-level Bluetooth communication capabilities.
23
26
 
24
27
  If you appreciate these enhancements and the continued development of this project, please consider supporting my work.
@@ -49,14 +52,16 @@ const noble = require('@stoprocent/noble');
49
52
 
50
53
  ```javascript
51
54
  // Read the battery level of the first found peripheral exposing the Battery Level characteristic
55
+ const noble = require('../');
52
56
 
53
- const noble = require('@stoprocent/noble');
54
-
55
- noble.on('stateChange', async (state) => {
56
- if (state === 'poweredOn') {
57
+ async function run() {
58
+ try {
59
+ await noble.waitForPoweredOn();
57
60
  await noble.startScanningAsync(['180f'], false);
61
+ } catch (error) {
62
+ console.error(error);
58
63
  }
59
- });
64
+ }
60
65
 
61
66
  noble.on('discover', async (peripheral) => {
62
67
  await noble.stopScanningAsync();
@@ -69,6 +74,9 @@ noble.on('discover', async (peripheral) => {
69
74
  await peripheral.disconnectAsync();
70
75
  process.exit(0);
71
76
  });
77
+
78
+ run();
79
+
72
80
  ```
73
81
  ## Use Noble With BLE5 Extended Features With HCI
74
82
 
@@ -2,19 +2,23 @@ const noble = require('../');
2
2
 
3
3
  const directConnect = process.argv[2].toLowerCase();
4
4
  const peripheralIdOrAddress = process.argv[3].toLowerCase();
5
+ const addressType = process.argv[4].toLowerCase() || 'random';
5
6
 
6
7
  const starTime = Date.now();
7
8
 
8
- noble.on('stateChange', async (state) => {
9
- if (state === 'poweredOn') {
9
+ async function main () {
10
+ try {
11
+ await noble.waitForPoweredOn();
10
12
  if (directConnect === '1') {
11
- await noble.stopScanningAsync();
12
- await noble.connectAsync(peripheralIdOrAddress.replace(/:/g, ''));
13
+ const peripheral = await noble.connectAsync(peripheralIdOrAddress.replace(/:/g, ''), { addressType });
14
+ await explore(peripheral);
13
15
  } else {
14
16
  await noble.startScanningAsync();
15
17
  }
18
+ } catch (error) {
19
+ console.error('Error:', error);
16
20
  }
17
- });
21
+ }
18
22
 
19
23
  noble.on('discover', async (peripheral) => {
20
24
  if ([peripheral.id, peripheral.address].includes(peripheralIdOrAddress)) {
@@ -143,3 +147,5 @@ process.on('SIGTERM', function () {
143
147
  console.log('Caught interrupt signal');
144
148
  noble.stopScanning(() => process.exit());
145
149
  });
150
+
151
+ main();
package/index.d.ts CHANGED
@@ -13,6 +13,14 @@
13
13
 
14
14
  import events = require("events");
15
15
 
16
+ export interface ConnectOptions {
17
+ addressType?: 'public' | 'random';
18
+ minInterval?: number;
19
+ maxInterval?: number;
20
+ latency?: number;
21
+ timeout?: number;
22
+ }
23
+
16
24
  export declare function waitForPoweredOn(timeout?: number): Promise<void>;
17
25
  /**
18
26
  * @deprecated
@@ -26,8 +34,8 @@ export declare function startScanning(serviceUUIDs?: string[], allowDuplicates?:
26
34
  export declare function startScanningAsync(serviceUUIDs?: string[], allowDuplicates?: boolean): Promise<void>;
27
35
  export declare function stopScanning(callback?: () => void): void;
28
36
  export declare function stopScanningAsync(): Promise<void>;
29
- export declare function connect(peripheralUuid: string, options?: object, callback?: (error: Error | undefined, peripheral: Peripheral) => void): void;
30
- export declare function connectAsync(peripheralUuid: string, options?: object): Promise<Peripheral>;
37
+ export declare function connect(peripheralUuid: string, options?: ConnectOptions, callback?: (error: Error | undefined, peripheral: Peripheral) => void): void;
38
+ export declare function connectAsync(peripheralUuid: string, options?: ConnectOptions): Promise<Peripheral>;
31
39
  export declare function cancelConnect(peripheralUuid: string, options?: object): void;
32
40
  export declare function reset(): void;
33
41
  export declare function stop(): void;
@@ -54,6 +62,10 @@ export declare function removeListener(event: string, listener: Function): event
54
62
 
55
63
  export declare function removeAllListeners(event?: string): events.EventEmitter;
56
64
 
65
+ export var state: "unknown" | "resetting" | "unsupported" | "unauthorized" | "poweredOff" | "poweredOn";
66
+ /**
67
+ * @deprecated Use `state` instead.
68
+ */
57
69
  export var _state: "unknown" | "resetting" | "unsupported" | "unauthorized" | "poweredOff" | "poweredOn";
58
70
 
59
71
  export var _bindings: any;
@@ -51,14 +51,14 @@ NobleBindings.prototype.stopScanning = function () {
51
51
  this._gap.stopScanning();
52
52
  };
53
53
 
54
- NobleBindings.prototype.connect = function (peripheralUuid, parameters) {
54
+ NobleBindings.prototype.connect = function (peripheralUuid, parameters = {}) {
55
55
  let address = this._addresses[peripheralUuid];
56
56
  let addressType = this._addresseTypes[peripheralUuid] || 'random'; // Default to 'random' if type is not defined
57
57
 
58
58
  // If address is not available, generate it from the UUID using the transformation logic inline
59
59
  if (!address) {
60
60
  address = peripheralUuid.match(/.{1,2}/g).join(':'); // Converts UUID back to MAC address format
61
- addressType = (parseInt(address.slice(0, 2).slice(0,2), 16) & 0x02) === 0 ? 'public' : 'random';
61
+ addressType = typeof(parameters) === 'object' && parameters.addressType ? parameters.addressType : 'random';
62
62
  }
63
63
 
64
64
  // Manage connection attempts
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "license": "MIT",
7
7
  "name": "@stoprocent/noble",
8
8
  "description": "A Node.js BLE (Bluetooth Low Energy) central library.",
9
- "version": "1.17.0",
9
+ "version": "1.17.2",
10
10
  "repository": {
11
11
  "type": "git",
12
12
  "url": "https://github.com/stoprocent/noble.git"
@@ -34,7 +34,7 @@
34
34
  "node-gyp-build": "^4.8.1"
35
35
  },
36
36
  "optionalDependencies": {
37
- "@stoprocent/bluetooth-hci-socket": "^1.4.2"
37
+ "@stoprocent/bluetooth-hci-socket": "^1.4.3"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@commitlint/cli": "^19.3.0",
@@ -135,23 +135,23 @@ describe('hci-socket bindings', () => {
135
135
  it('missing peripheral, no queue, public address', () => {
136
136
  bindings._hci.createLeConn = fake.resolves(null);
137
137
 
138
- bindings.connect('112233445566', 'parameters');
138
+ bindings.connect('112233445566', { addressType: 'public' });
139
139
 
140
140
  should(bindings._pendingConnectionUuid).eql('112233445566');
141
141
 
142
142
  assert.calledOnce(bindings._hci.createLeConn);
143
- assert.calledWith(bindings._hci.createLeConn, '11:22:33:44:55:66', 'public', 'parameters');
143
+ assert.calledWith(bindings._hci.createLeConn, '11:22:33:44:55:66', 'public', { addressType: 'public' });
144
144
  });
145
145
 
146
146
  it('missing peripheral, no queue, random address', () => {
147
147
  bindings._hci.createLeConn = fake.resolves(null);
148
148
 
149
- bindings.connect('f32233445566', 'parameters');
149
+ bindings.connect('f32233445566', { addressType: 'random' });
150
150
 
151
151
  should(bindings._pendingConnectionUuid).eql('f32233445566');
152
152
 
153
153
  assert.calledOnce(bindings._hci.createLeConn);
154
- assert.calledWith(bindings._hci.createLeConn, 'f3:22:33:44:55:66', 'random', 'parameters');
154
+ assert.calledWith(bindings._hci.createLeConn, 'f3:22:33:44:55:66', 'random', { addressType: 'random' });
155
155
  });
156
156
 
157
157
  it('existing peripheral, no queue', () => {