@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.
Files changed (97) hide show
  1. package/README.md +393 -650
  2. package/examples/advertisement-discovery.js +57 -48
  3. package/examples/connect-address.js +59 -34
  4. package/examples/echo.js +59 -69
  5. package/examples/enter-exit.js +55 -49
  6. package/examples/multiple-bindings.js +53 -0
  7. package/examples/peripheral-explorer-async.js +39 -21
  8. package/examples/peripheral-explorer.ts +52 -0
  9. package/index.d.ts +249 -209
  10. package/index.js +4 -1
  11. package/jest.config.js +4 -0
  12. package/lib/characteristic.js +153 -127
  13. package/lib/{win/src/callbacks.h → common/include/Emit.h} +17 -14
  14. package/lib/common/include/Peripheral.h +31 -0
  15. package/lib/common/include/ThreadSafeCallback.h +95 -0
  16. package/lib/{win/src/callbacks.cc → common/src/Emit.cc} +111 -68
  17. package/lib/descriptor.js +57 -54
  18. package/lib/hci-socket/acl-stream.js +2 -4
  19. package/lib/hci-socket/bindings.js +96 -73
  20. package/lib/hci-socket/gap.js +2 -3
  21. package/lib/hci-socket/gatt.js +2 -5
  22. package/lib/hci-socket/hci.js +19 -7
  23. package/lib/hci-socket/signaling.js +2 -3
  24. package/lib/hci-socket/smp.js +2 -3
  25. package/lib/hci-socket/vs.js +1 -0
  26. package/lib/mac/binding.gyp +5 -7
  27. package/lib/mac/bindings.js +1 -3
  28. package/lib/mac/src/ble_manager.h +1 -8
  29. package/lib/mac/src/ble_manager.mm +87 -44
  30. package/lib/mac/src/napi_objc.h +1 -0
  31. package/lib/mac/src/napi_objc.mm +0 -6
  32. package/lib/mac/src/noble_mac.h +5 -3
  33. package/lib/mac/src/noble_mac.mm +99 -57
  34. package/lib/mac/src/objc_cpp.h +3 -2
  35. package/lib/mac/src/objc_cpp.mm +0 -6
  36. package/lib/noble.js +579 -488
  37. package/lib/peripheral.js +171 -174
  38. package/lib/resolve-bindings.js +37 -30
  39. package/lib/service.js +58 -55
  40. package/lib/win/binding.gyp +4 -11
  41. package/lib/win/bindings.js +1 -3
  42. package/lib/win/src/ble_manager.cc +291 -166
  43. package/lib/win/src/ble_manager.h +11 -13
  44. package/lib/win/src/napi_winrt.cc +1 -7
  45. package/lib/win/src/napi_winrt.h +1 -1
  46. package/lib/win/src/noble_winrt.cc +88 -61
  47. package/lib/win/src/noble_winrt.h +5 -3
  48. package/lib/win/src/notify_map.cc +0 -7
  49. package/lib/win/src/notify_map.h +1 -8
  50. package/lib/win/src/peripheral_winrt.cc +29 -11
  51. package/lib/win/src/peripheral_winrt.h +1 -1
  52. package/lib/win/src/radio_watcher.cc +79 -69
  53. package/lib/win/src/radio_watcher.h +30 -11
  54. package/lib/win/src/winrt_cpp.cc +1 -1
  55. package/lib/win/src/winrt_cpp.h +3 -0
  56. package/package.json +14 -17
  57. package/prebuilds/darwin-x64+arm64/@stoprocent+noble.node +0 -0
  58. package/prebuilds/win32-ia32/@stoprocent+noble.node +0 -0
  59. package/prebuilds/win32-x64/@stoprocent+noble.node +0 -0
  60. package/test/lib/characteristic.test.js +202 -322
  61. package/test/lib/descriptor.test.js +62 -95
  62. package/test/lib/hci-socket/acl-stream.test.js +112 -108
  63. package/test/lib/hci-socket/bindings.test.js +576 -365
  64. package/test/lib/hci-socket/hci.test.js +442 -473
  65. package/test/lib/hci-socket/signaling.test.js +45 -48
  66. package/test/lib/hci-socket/smp.test.js +144 -142
  67. package/test/lib/hci-socket/vs.test.js +193 -18
  68. package/test/lib/peripheral.test.js +492 -322
  69. package/test/lib/resolve-bindings.test.js +207 -82
  70. package/test/lib/service.test.js +79 -88
  71. package/test/noble.test.js +381 -1085
  72. package/.editorconfig +0 -11
  73. package/.nycrc.json +0 -4
  74. package/codecov.yml +0 -5
  75. package/examples/cache-gatt-discovery.js +0 -198
  76. package/examples/cache-gatt-reconnect.js +0 -164
  77. package/examples/ext-advertisement-discovery.js +0 -65
  78. package/examples/peripheral-explorer.js +0 -225
  79. package/examples/pizza/central.js +0 -194
  80. package/examples/pizza/pizza.js +0 -60
  81. package/examples/test/test.custom.js +0 -131
  82. package/examples/uart-bind-params.js +0 -28
  83. package/lib/distributed/bindings.js +0 -326
  84. package/lib/mac/src/callbacks.cc +0 -222
  85. package/lib/mac/src/callbacks.h +0 -84
  86. package/lib/mac/src/peripheral.h +0 -23
  87. package/lib/resolve-bindings-web.js +0 -9
  88. package/lib/webbluetooth/bindings.js +0 -368
  89. package/lib/websocket/bindings.js +0 -321
  90. package/lib/win/src/peripheral.h +0 -23
  91. package/test/lib/distributed/bindings.test.js +0 -918
  92. package/test/lib/webbluetooth/bindings.test.js +0 -190
  93. package/test/lib/websocket/bindings.test.js +0 -456
  94. package/test/mocha.setup.js +0 -0
  95. package/with-bindings.js +0 -5
  96. package/with-custom-binding.js +0 -6
  97. package/ws-slave.js +0 -404
@@ -1,65 +1,74 @@
1
1
  const noble = require('../index');
2
2
 
3
- noble.on('stateChange', function (state) {
4
- if (state === 'poweredOn') {
5
- noble.startScanning([], false);
6
- } else {
7
- noble.stopScanning();
8
- }
9
- });
10
-
11
- noble.on('discover', function (peripheral) {
12
- console.log(`${new Date()}`);
13
- console.log(
14
- `Peripheral discovered (${peripheral.id} with address <${peripheral.address}, ${peripheral.addressType}>, connectable: ${peripheral.connectable}, scannable: ${peripheral.scannable}, RSSI ${peripheral.rssi}:`
15
- );
16
- console.log('\thello my local name is:');
17
- console.log(`\t\t${peripheral.advertisement.localName}`);
3
+ async function handleDiscovery (peripheral) {
4
+ console.log(`\n${new Date()}`);
18
5
  console.log(
19
- '\tcan I interest you in any of the following advertised services:'
6
+ `Peripheral discovered (${peripheral.id}):
7
+ - Address: ${peripheral.address} (${peripheral.addressType})
8
+ - Connectable: ${peripheral.connectable}
9
+ - Scannable: ${peripheral.scannable}
10
+ - RSSI: ${peripheral.rssi}`
20
11
  );
21
- console.log(`\t\t${JSON.stringify(peripheral.advertisement.serviceUuids)}`);
22
- const serviceData = peripheral.advertisement.serviceData;
23
12
 
13
+ // Local Name
14
+ if (peripheral.advertisement.localName) {
15
+ console.log(`Local Name: ${peripheral.advertisement.localName}`);
16
+ }
17
+
18
+ // Service UUIDs
19
+ if (peripheral.advertisement.serviceUuids.length) {
20
+ console.log('Advertised Services:');
21
+ console.log(` ${peripheral.advertisement.serviceUuids.join(', ')}`);
22
+ }
23
+
24
+ // Service Data
25
+ const serviceData = peripheral.advertisement.serviceData;
24
26
  if (serviceData && serviceData.length) {
25
- console.log('\there is my service data:');
26
- for (const i in serviceData) {
27
- console.log(
28
- `\t\t${JSON.stringify(serviceData[i].uuid)}: ${JSON.stringify(
29
- serviceData[i].data.toString('hex')
30
- )}`
31
- );
32
- }
27
+ console.log('Service Data:');
28
+ serviceData.forEach(data => {
29
+ console.log(` ${data.uuid}: ${data.data.toString('hex')}`);
30
+ });
33
31
  }
34
32
 
33
+ // Manufacturer Data
35
34
  if (peripheral.advertisement.manufacturerData) {
36
- console.log('\there is my manufacturer data:');
37
- console.log(
38
- `\t\t${JSON.stringify(
39
- peripheral.advertisement.manufacturerData.toString('hex')
40
- )}`
41
- );
35
+ console.log('Manufacturer Data:');
36
+ console.log(` ${peripheral.advertisement.manufacturerData.toString('hex')}`);
42
37
  }
43
38
 
39
+ // TX Power Level
44
40
  if (peripheral.advertisement.txPowerLevel !== undefined) {
45
- console.log('\tmy TX power level is:');
46
- console.log(`\t\t${peripheral.advertisement.txPowerLevel}`);
41
+ console.log(`TX Power Level: ${peripheral.advertisement.txPowerLevel}`);
47
42
  }
43
+ }
44
+
45
+ async function main () {
46
+ try {
47
+ console.log('Waiting for Bluetooth adapter...');
48
+ await noble.waitForPoweredOnAsync();
49
+ console.log('Bluetooth adapter ready');
48
50
 
49
- console.log();
50
- });
51
+ console.log('Starting scan for all devices...');
52
+ await noble.startScanningAsync([], false);
53
+
54
+ noble.on('discover', handleDiscovery);
55
+
56
+ } catch (error) {
57
+ throw new Error('Error:', error);
58
+ }
59
+ }
51
60
 
52
- process.on('SIGINT', function () {
53
- console.log('Caught interrupt signal');
54
- noble.stopScanning(() => process.exit());
55
- });
61
+ // Handle process termination
62
+ const cleanup = async () => {
63
+ console.log('\nCleaning up...');
64
+ await noble.stopScanningAsync();
65
+ noble.stop();
66
+ console.log('noble stopped');
67
+ };
56
68
 
57
- process.on('SIGQUIT', function () {
58
- console.log('Caught interrupt signal');
59
- noble.stopScanning(() => process.exit());
60
- });
69
+ process.on('SIGINT', cleanup);
70
+ process.on('SIGQUIT', cleanup);
71
+ process.on('SIGTERM', cleanup);
61
72
 
62
- process.on('SIGTERM', function () {
63
- console.log('Caught interrupt signal');
64
- noble.stopScanning(() => process.exit());
65
- });
73
+ // Start the application
74
+ main().catch(console.error);
@@ -1,40 +1,65 @@
1
1
  const noble = require('../index');
2
- const direct = require('debug')('connection/direct');
3
- const scan = require('debug')('connection/scan');
4
2
 
5
- function sleep (ms) {
6
- return new Promise(resolve => setTimeout(resolve, ms));
7
- }
3
+ async function main () {
4
+ try {
5
+ // Wait for the BLE adapter to be ready
6
+ console.log('Waiting for powered on state');
7
+ await noble.waitForPoweredOnAsync();
8
+ console.log('Powered on');
8
9
 
9
- async function run () {
10
- noble.on('stateChange', async function (state) {
11
- if (state === 'poweredOn') {
12
- try {
13
- direct('connecting');
14
- // const uuid = 'f1:36:1c:ab:94:cc'.split(':').join(''); // HCI Address UUID
15
- const uuid = '2561b846d6f83ee27580bca8ed6ec079'; // MacOS UUID
16
- const peripheral = await noble.connectAsync(uuid);
17
- direct(`connected ${peripheral.uuid}`);
18
- await peripheral.disconnectAsync();
19
- direct('disconnected');
20
- console.log('sleeping for 2000ms');
21
- await sleep(2000);
22
- scan('connecting by scan');
23
- await noble.startScanningAsync();
24
- noble.on('discover', async peripheral => {
25
- if (peripheral.uuid === uuid) {
26
- await noble.stopScanningAsync();
27
- await peripheral.connectAsync();
28
- scan(`connected ${peripheral.uuid}`);
29
- await peripheral.disconnectAsync();
30
- scan('disconnected');
31
- }
32
- });
33
- } catch (error) {
34
- console.log(error);
35
- }
10
+ // First attempt - direct connection
11
+ const uuid = '2561b846d6f83ee27580bca8ed6ec079'; // MacOS UUID
12
+ console.log('Attempting direct connection to:', uuid);
13
+
14
+ try {
15
+ const peripheral = await noble.connectAsync(uuid);
16
+ console.log('Direct connection successful to:', peripheral.id);
17
+ await peripheral.disconnectAsync();
18
+ console.log('Disconnected from direct connection');
19
+ } catch (error) {
20
+ console.log('Direct connection failed:', error.message);
36
21
  }
37
- });
22
+
23
+ // Wait before trying scan method
24
+ console.log('Waiting 2 seconds before scan attempt...');
25
+ await new Promise(resolve => setTimeout(resolve, 2000));
26
+
27
+ // Second attempt - scan and connect
28
+ console.log('Starting scan for device');
29
+ await noble.startScanningAsync();
30
+
31
+ noble.on('discover', async (peripheral) => {
32
+ if (peripheral.id === uuid) {
33
+ console.log('Found device in scan:', peripheral.id);
34
+ await noble.stopScanningAsync();
35
+
36
+ try {
37
+ await peripheral.connectAsync();
38
+ console.log('Scan connection successful to:', peripheral.id);
39
+ await peripheral.disconnectAsync();
40
+ console.log('Disconnected from scan connection');
41
+ } catch (error) {
42
+ console.log('Scan connection failed:', error.message);
43
+ }
44
+ }
45
+ });
46
+
47
+ } catch (error) {
48
+ console.error('Main error:', error);
49
+ }
38
50
  }
39
51
 
40
- run();
52
+ // Handle process termination
53
+ const cleanup = async () => {
54
+ console.log('Caught interrupt signal');
55
+ await noble.stopScanningAsync();
56
+ noble.stop();
57
+ console.log('noble stopped');
58
+ };
59
+
60
+ process.on('SIGINT', cleanup);
61
+ process.on('SIGQUIT', cleanup);
62
+ process.on('SIGTERM', cleanup);
63
+
64
+ // Start the application
65
+ main().catch(console.error);
package/examples/echo.js CHANGED
@@ -11,94 +11,84 @@ const noble = require('..');
11
11
  const ECHO_SERVICE_UUID = 'ec00';
12
12
  const ECHO_CHARACTERISTIC_UUID = 'ec0e';
13
13
 
14
- noble.on('stateChange', (state) => {
15
- if (state === 'poweredOn') {
14
+ async function main () {
15
+ try {
16
+ // Wait for the BLE adapter to be ready
17
+ console.log('Waiting for powered on');
18
+ await noble.waitForPoweredOnAsync();
19
+ console.log('Powered on');
20
+ await noble.setAddress('11:22:33:44:55:66');
21
+ console.log('Set address');
22
+ await noble.startScanningAsync([ECHO_SERVICE_UUID], false);
16
23
  console.log('Scanning');
17
- noble.startScanning([ECHO_SERVICE_UUID], false);
18
- } else {
19
- noble.stopScanning();
24
+ } catch (error) {
25
+ throw new Error('Error initializing BLE:', error);
20
26
  }
21
- });
27
+ }
22
28
 
23
- noble.on('discover', (peripheral) => {
29
+ noble.on('discover', async (peripheral) => {
24
30
  // connect to the first peripheral that is scanned
25
- noble.stopScanning();
31
+ await noble.stopScanningAsync();
26
32
  const name = peripheral.advertisement.localName;
27
33
  console.log(`Connecting to '${name}' ${peripheral.id}`);
28
34
  connectAndSetUp(peripheral);
29
35
  });
30
36
 
31
- function connectAndSetUp (peripheral) {
32
- peripheral.connect((error) => {
33
- if (error) {
34
- console.error(error);
35
- return;
36
- }
37
-
37
+ async function connectAndSetUp (peripheral) {
38
+ try {
39
+ await peripheral.connectAsync();
38
40
  console.log('Connected to', peripheral.id);
39
41
 
40
- // specify the services and characteristics to discover
41
- const serviceUUIDs = [ECHO_SERVICE_UUID];
42
- const characteristicUUIDs = [ECHO_CHARACTERISTIC_UUID];
43
-
44
- peripheral.discoverSomeServicesAndCharacteristics(
45
- serviceUUIDs,
46
- characteristicUUIDs,
47
- onServicesAndCharacteristicsDiscovered
42
+ // // specify the services and characteristics to discover
43
+ const { characteristics } = await peripheral.discoverSomeServicesAndCharacteristicsAsync(
44
+ [ECHO_SERVICE_UUID],
45
+ [ECHO_CHARACTERISTIC_UUID]
48
46
  );
49
- });
50
-
51
- peripheral.on('disconnect', () => console.log('disconnected'));
52
- }
53
-
54
- function onServicesAndCharacteristicsDiscovered (
55
- error,
56
- services,
57
- characteristics
58
- ) {
59
- if (error) {
60
- console.error(error);
61
- return;
62
- }
63
47
 
64
- console.log('Discovered services and characteristics');
65
- const echoCharacteristic = characteristics[0];
48
+ console.log('Discovered services and characteristics');
49
+ const echoCharacteristic = characteristics[0];
66
50
 
67
- // data callback receives notifications
68
- echoCharacteristic.on('data', (data, isNotification) => {
69
- console.log(`Received: "${data}"`);
70
- });
51
+ // data callback receives notifications
52
+ echoCharacteristic.on('read', (data, isNotification) => {
53
+ console.log(`Received: "${data}"`);
54
+ });
71
55
 
72
- // subscribe to be notified whenever the peripheral update the characteristic
73
- echoCharacteristic.subscribe((error) => {
74
- if (error) {
75
- console.error('Error subscribing to echoCharacteristic');
76
- } else {
56
+ // subscribe to be notified whenever the peripheral update the characteristic
57
+ try {
58
+ await echoCharacteristic.subscribeAsync();
77
59
  console.log('Subscribed for echoCharacteristic notifications');
60
+ } catch (error) {
61
+ console.error('Error subscribing to echoCharacteristic:', error);
62
+ return;
78
63
  }
79
- });
80
-
81
- // create an interval to send data to the service
82
- let count = 0;
83
- setInterval(() => {
84
- count++;
85
- const message = Buffer.from(`hello, ble ${count}`, 'utf-8');
86
- console.log(`Sending: '${message}'`);
87
- echoCharacteristic.write(message);
88
- }, 2500);
64
+
65
+ // create an interval to send data to the service
66
+ let count = 0;
67
+ setInterval(async () => {
68
+ count++;
69
+ const message = Buffer.from(`hello, ble ${count}`, 'utf-8');
70
+ console.log(`Sending: '${message}'`);
71
+ await echoCharacteristic.writeAsync(message, false);
72
+ }, 2500);
73
+
74
+ } catch (error) {
75
+ console.error('Error during connection setup:', error);
76
+ }
77
+
78
+ peripheral.on('disconnect', () => console.log('disconnected'));
89
79
  }
90
80
 
91
- process.on('SIGINT', function () {
81
+ // Handle process termination
82
+ const cleanup = async () => {
92
83
  console.log('Caught interrupt signal');
93
- noble.stopScanning(() => process.exit());
94
- });
84
+ await noble.stopScanningAsync();
85
+ noble.stop();
86
+ console.log('noble stopped');
87
+ };
95
88
 
96
- process.on('SIGQUIT', function () {
97
- console.log('Caught interrupt signal');
98
- noble.stopScanning(() => process.exit());
99
- });
89
+ process.on('SIGINT', cleanup);
90
+ process.on('SIGQUIT', cleanup);
91
+ process.on('SIGTERM', cleanup);
100
92
 
101
- process.on('SIGTERM', function () {
102
- console.log('Caught interrupt signal');
103
- noble.stopScanning(() => process.exit());
104
- });
93
+ // Start the application
94
+ main().catch(console.error);
@@ -1,4 +1,5 @@
1
- /* eslint-disable handle-callback-err */
1
+ const noble = require('../index');
2
+
2
3
  /*
3
4
  Continuously scans for peripherals and prints out message when they enter/exit
4
5
 
@@ -7,38 +8,54 @@
7
8
 
8
9
  based on code provided by: Mattias Ask (http://www.dittlof.com)
9
10
  */
10
- const noble = require('../index');
11
11
 
12
- const RSSI_THRESHOLD = -90;
12
+ const RSSI_THRESHOLD = -50;
13
13
  const EXIT_GRACE_PERIOD = 2000; // milliseconds
14
14
 
15
- const inRange = [];
16
-
17
- noble.on('discover', function (peripheral) {
18
- if (peripheral.rssi < RSSI_THRESHOLD) {
19
- // ignore
20
- return;
21
- }
22
-
23
- const id = peripheral.id;
24
- const entered = !inRange[id];
25
-
26
- if (entered) {
27
- inRange[id] = {
28
- peripheral
29
- };
30
-
31
- console.log(
32
- `"${peripheral.advertisement.localName}" entered (RSSI ${
33
- peripheral.rssi
34
- }) ${new Date()}`
35
- );
15
+ const inRange = {};
16
+
17
+ // Self-executing async function
18
+ (async function () {
19
+ try {
20
+ // Initialize noble
21
+ await noble.waitForPoweredOnAsync();
22
+ console.log('noble started');
23
+
24
+ // Start scanning
25
+ await noble.startScanningAsync([], true);
26
+ console.log('Scanning for peripherals...');
27
+
28
+ // Continuously discover peripherals
29
+ for await (const peripheral of noble.discoverAsync()) {
30
+ if (peripheral.rssi < RSSI_THRESHOLD) {
31
+ // ignore devices with weak signal
32
+ continue;
33
+ }
34
+
35
+ const id = peripheral.id;
36
+ const entered = !inRange[id];
37
+
38
+ if (entered) {
39
+ inRange[id] = {
40
+ peripheral
41
+ };
42
+
43
+ console.log(
44
+ `"${peripheral.advertisement.localName}" entered (RSSI ${
45
+ peripheral.rssi
46
+ }) ${new Date()}`
47
+ );
48
+ }
49
+
50
+ inRange[id].lastSeen = Date.now();
51
+ }
52
+ } catch (error) {
53
+ throw new Error('Error:', error);
36
54
  }
55
+ })();
37
56
 
38
- inRange[id].lastSeen = Date.now();
39
- });
40
-
41
- setInterval(function () {
57
+ // Check for peripherals that have left range
58
+ setInterval(() => {
42
59
  for (const id in inRange) {
43
60
  if (inRange[id].lastSeen < Date.now() - EXIT_GRACE_PERIOD) {
44
61
  const peripheral = inRange[id].peripheral;
@@ -54,25 +71,14 @@ setInterval(function () {
54
71
  }
55
72
  }, EXIT_GRACE_PERIOD / 2);
56
73
 
57
- noble.on('stateChange', function (state) {
58
- if (state === 'poweredOn') {
59
- noble.startScanning([], true);
60
- } else {
61
- noble.stopScanning();
62
- }
63
- });
64
-
65
- process.on('SIGINT', function () {
66
- console.log('Caught interrupt signal');
67
- noble.stopScanning(() => process.exit());
68
- });
69
-
70
- process.on('SIGQUIT', function () {
71
- console.log('Caught interrupt signal');
72
- noble.stopScanning(() => process.exit());
73
- });
74
-
75
- process.on('SIGTERM', function () {
74
+ // Handle process termination
75
+ const cleanup = async () => {
76
76
  console.log('Caught interrupt signal');
77
- noble.stopScanning(() => process.exit());
78
- });
77
+ await noble.stopScanningAsync();
78
+ noble.stop();
79
+ console.log('noble stopped');
80
+ };
81
+
82
+ process.on('SIGINT', cleanup);
83
+ process.on('SIGQUIT', cleanup);
84
+ process.on('SIGTERM', cleanup);
@@ -0,0 +1,53 @@
1
+ const { withBindings } = require('../index');
2
+
3
+ const nobleUartA = withBindings('hci', {
4
+ hciDriver: 'uart',
5
+ bindParams: {
6
+ uart: {
7
+ port: '/dev/tty.usbmodem1474201'
8
+ }
9
+ }
10
+ });
11
+
12
+ const nobleUartB = withBindings('hci', {
13
+ hciDriver: 'uart',
14
+ bindParams: {
15
+ uart: {
16
+ port: '/dev/tty.usbmodem1474401'
17
+ }
18
+ }
19
+ });
20
+
21
+ const nobleUartC = withBindings('default');
22
+
23
+ nobleUartA.on('discover', peripheral => {
24
+ console.log('UART A', peripheral.id);
25
+ });
26
+
27
+ nobleUartB.on('discover', peripheral => {
28
+ console.log('UART B', peripheral.id);
29
+ });
30
+
31
+ nobleUartC.on('discover', peripheral => {
32
+ console.log('UART C', peripheral.id);
33
+ });
34
+
35
+ nobleUartA.on('stateChange', state => {
36
+ if (state === 'poweredOn') {
37
+ nobleUartA.setAddress('00:11:22:33:44:01');
38
+ nobleUartA.startScanning([], true);
39
+ }
40
+ });
41
+
42
+ nobleUartB.on('stateChange', state => {
43
+ if (state === 'poweredOn') {
44
+ nobleUartB.setAddress('00:11:22:33:44:02');
45
+ nobleUartB.startScanning([], true);
46
+ }
47
+ });
48
+
49
+ nobleUartC.on('stateChange', state => {
50
+ if (state === 'poweredOn') {
51
+ nobleUartC.startScanning([], true);
52
+ }
53
+ });
@@ -1,22 +1,37 @@
1
1
  const noble = require('../');
2
2
 
3
- const directConnect = process.argv[2].toLowerCase();
4
- const peripheralIdOrAddress = process.argv[3].toLowerCase();
5
- const addressType = process.argv[4].toLowerCase() || 'random';
3
+ let directConnect = '0';
4
+ let peripheralIdOrAddress = 'cd:6b:86:03:39:40'.toLowerCase();
5
+ let addressType = 'random';
6
+
7
+ try {
8
+ directConnect = process.argv[2].toLowerCase() || '0';
9
+ peripheralIdOrAddress = process.argv[3].toLowerCase() || 'cd:6b:86:03:39:40';
10
+ addressType = process.argv[4].toLowerCase() || 'random';
11
+ } catch (error) {
12
+ console.error('Error:', error);
13
+ }
6
14
 
7
15
  const starTime = Date.now();
8
16
 
17
+ let peripheral;
9
18
  async function main () {
10
19
  try {
11
- await noble.waitForPoweredOn();
20
+ await noble.waitForPoweredOnAsync();
21
+
22
+ // Cancel the connection after 5 seconds if it is still connecting
23
+ setTimeout(() => {
24
+ noble.cancelConnect(peripheralIdOrAddress);
25
+ }, 5000);
26
+
12
27
  if (directConnect === '1') {
13
- const peripheral = await noble.connectAsync(peripheralIdOrAddress.replace(/:/g, ''), { addressType });
28
+ peripheral = await noble.connectAsync(peripheralIdOrAddress, { addressType });
14
29
  await explore(peripheral);
15
30
  } else {
16
- await noble.startScanningAsync();
31
+ await noble.startScanningAsync([], false);
17
32
  }
18
33
  } catch (error) {
19
- console.error('Error:', error);
34
+ throw new Error('Error:', error);
20
35
  }
21
36
  }
22
37
 
@@ -28,6 +43,7 @@ noble.on('discover', async (peripheral) => {
28
43
  await noble.stopScanningAsync();
29
44
 
30
45
  console.log(`Peripheral with ID ${peripheral.id} found`);
46
+
31
47
  const advertisement = peripheral.advertisement;
32
48
 
33
49
  const localName = advertisement.localName;
@@ -70,14 +86,19 @@ noble.on('discover', async (peripheral) => {
70
86
  const explore = async (peripheral) => {
71
87
  console.log('Services and characteristics:');
72
88
 
73
- peripheral.on('disconnect', () => {
74
- process.exit(0);
89
+ peripheral.on('disconnect', (reason) => {
90
+ console.log('Disconnected', reason);
91
+ noble.stop();
92
+ console.log('noble stopped');
75
93
  });
76
94
 
77
95
  if (peripheral.state !== 'connected') {
78
96
  await peripheral.connectAsync();
79
97
  }
80
98
 
99
+ const rssi = await peripheral.updateRssiAsync();
100
+ console.log('RSSI', rssi);
101
+
81
102
  const services = await peripheral.discoverServicesAsync([]);
82
103
 
83
104
  for (const service of services) {
@@ -136,19 +157,16 @@ const explore = async (peripheral) => {
136
157
 
137
158
  };
138
159
 
139
- process.on('SIGINT', function () {
140
- console.log('Caught interrupt signal');
141
- noble.stopScanning(() => process.exit());
142
- });
143
-
144
- process.on('SIGQUIT', function () {
160
+ // Handle process termination
161
+ const cleanup = async () => {
145
162
  console.log('Caught interrupt signal');
146
- noble.stopScanning(() => process.exit());
147
- });
163
+ await noble.stopScanningAsync();
164
+ noble.stop();
165
+ console.log('noble stopped');
166
+ };
148
167
 
149
- process.on('SIGTERM', function () {
150
- console.log('Caught interrupt signal');
151
- noble.stopScanning(() => process.exit());
152
- });
168
+ process.on('SIGINT', cleanup);
169
+ process.on('SIGQUIT', cleanup);
170
+ process.on('SIGTERM', cleanup);
153
171
 
154
172
  main();