@stoprocent/noble 1.17.4 → 1.18.1

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.
@@ -61,20 +61,26 @@ NobleBindings.prototype.connect = function (peripheralUuid, parameters = {}) {
61
61
  addressType = parameters && parameters.addressType ? parameters.addressType : 'random';
62
62
  }
63
63
 
64
- const createConnection = () => {
65
- if (!this._pendingConnectionUuid) {
66
- this._pendingConnectionUuid = peripheralUuid;
67
- this._hci.createLeConn(address, addressType, parameters);
68
- } else {
69
- this._connectionQueue.push({ id: peripheralUuid, params: parameters });
70
- }
64
+ // Add connection request to queue
65
+ this._connectionQueue.push({
66
+ id: peripheralUuid,
67
+ address,
68
+ addressType,
69
+ params: parameters
70
+ });
71
+
72
+ const processNextConnection = () => {
73
+ if (this._connectionQueue.length === 0) return;
74
+
75
+ const nextConn = this._connectionQueue[0]; // Look at next connection but don't remove yet
76
+ this._hci.createLeConn(nextConn.address, nextConn.addressType, nextConn.params);
71
77
  };
72
78
 
73
79
  if (this._isScanning) {
74
- this.once('scanStop', createConnection);
80
+ this.once('scanStop', processNextConnection);
75
81
  this.stopScanning();
76
82
  } else {
77
- createConnection();
83
+ processNextConnection();
78
84
  }
79
85
  };
80
86
 
@@ -128,6 +134,21 @@ NobleBindings.prototype.onSigInt = function () {
128
134
  const sigIntListeners = process.listeners('SIGINT');
129
135
 
130
136
  if (sigIntListeners[sigIntListeners.length - 1] === this.onSigIntBinded) {
137
+ // Stop scanning if active
138
+ if (this._isScanning) {
139
+ this.stopScanning();
140
+ }
141
+
142
+ // Disconnect all active connections
143
+ for (const handle in this._handles) {
144
+ if (Object.hasOwn(this._handles, handle)) {
145
+ this.disconnect(this._handles[handle]);
146
+ }
147
+ }
148
+
149
+ // Clear connection queue
150
+ this._connectionQueue = [];
151
+
131
152
  // we are the last listener, so exit
132
153
  // this will trigger onExit, and clean up
133
154
  process.exit(1);
@@ -259,8 +280,8 @@ NobleBindings.prototype.onLeConnComplete = function (
259
280
  // not master, ignore
260
281
  return;
261
282
  }
262
- let uuid = null;
263
283
 
284
+ let uuid = null;
264
285
  let error = null;
265
286
 
266
287
  if (status === 0) {
@@ -351,27 +372,23 @@ NobleBindings.prototype.onLeConnComplete = function (
351
372
 
352
373
  this._gatts[handle].exchangeMtu();
353
374
  } else {
354
- uuid = this._pendingConnectionUuid;
375
+ const currentConn = this._connectionQueue[0];
376
+ uuid = currentConn ? currentConn.id : null;
355
377
  let statusMessage = Hci.STATUS_MAPPER[status] || 'HCI Error: Unknown';
356
378
  const errorCode = ` (0x${status.toString(16)})`;
357
379
  statusMessage = statusMessage + errorCode;
358
380
  error = new Error(statusMessage);
359
381
  }
360
382
 
361
- this.emit('connect', uuid, error);
362
-
363
- if (this._connectionQueue.length > 0) {
364
- const queueItem = this._connectionQueue.shift();
365
- const peripheralUuid = queueItem.id;
383
+ // Remove the completed/failed connection attempt from queue
384
+ this._connectionQueue.shift();
366
385
 
367
- address = this._addresses[peripheralUuid];
368
- addressType = this._addresseTypes[peripheralUuid];
369
-
370
- this._pendingConnectionUuid = peripheralUuid;
386
+ this.emit('connect', uuid, error);
371
387
 
372
- this._hci.createLeConn(address, addressType, queueItem.params);
373
- } else {
374
- this._pendingConnectionUuid = null;
388
+ // Process next connection in queue if any
389
+ if (this._connectionQueue.length > 0 && !this._isScanning) {
390
+ const nextConn = this._connectionQueue[0];
391
+ this._hci.createLeConn(nextConn.address, nextConn.addressType, nextConn.params);
375
392
  }
376
393
  };
377
394
 
@@ -274,9 +274,9 @@ Gap.prototype.parseServices = function (
274
274
  manufacturerData: undefined,
275
275
  serviceData: [],
276
276
  serviceUuids: [],
277
- solicitationServiceUuids: []
277
+ serviceSolicitationUuids: []
278
278
  };
279
-
279
+
280
280
  while (i + 1 < eir.length) {
281
281
  const length = eir.readUInt8(i);
282
282
 
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.4",
9
+ "version": "1.18.1",
10
10
  "repository": {
11
11
  "type": "git",
12
12
  "url": "https://github.com/stoprocent/noble.git"
@@ -137,7 +137,9 @@ describe('hci-socket bindings', () => {
137
137
 
138
138
  bindings.connect('112233445566', { addressType: 'public' });
139
139
 
140
- should(bindings._pendingConnectionUuid).eql('112233445566');
140
+ should(bindings._connectionQueue).length(1);
141
+ should(bindings._connectionQueue[0].id).eql('112233445566');
142
+ should(bindings._connectionQueue[0].params).eql({ addressType: 'public' });
141
143
 
142
144
  assert.calledOnce(bindings._hci.createLeConn);
143
145
  assert.calledWith(bindings._hci.createLeConn, '11:22:33:44:55:66', 'public', { addressType: 'public' });
@@ -148,7 +150,9 @@ describe('hci-socket bindings', () => {
148
150
 
149
151
  bindings.connect('f32233445566', { addressType: 'random' });
150
152
 
151
- should(bindings._pendingConnectionUuid).eql('f32233445566');
153
+ should(bindings._connectionQueue).length(1);
154
+ should(bindings._connectionQueue[0].id).eql('f32233445566');
155
+ should(bindings._connectionQueue[0].params).eql({ addressType: 'random' });
152
156
 
153
157
  assert.calledOnce(bindings._hci.createLeConn);
154
158
  assert.calledWith(bindings._hci.createLeConn, 'f3:22:33:44:55:66', 'random', { addressType: 'random' });
@@ -165,7 +169,9 @@ describe('hci-socket bindings', () => {
165
169
 
166
170
  bindings.connect('peripheralUuid', 'parameters');
167
171
 
168
- should(bindings._pendingConnectionUuid).eql('peripheralUuid');
172
+ should(bindings._connectionQueue).length(1);
173
+ should(bindings._connectionQueue[0].id).eql('peripheralUuid');
174
+ should(bindings._connectionQueue[0].params).eql('parameters');
169
175
 
170
176
  assert.calledOnce(bindings._hci.createLeConn);
171
177
  assert.calledWith(bindings._hci.createLeConn, 'address', 'addressType', 'parameters');
@@ -175,8 +181,10 @@ describe('hci-socket bindings', () => {
175
181
  bindings._pendingConnectionUuid = 'pending-uuid';
176
182
 
177
183
  bindings.connect('peripheralUuid', 'parameters');
178
-
179
- should(bindings._connectionQueue).deepEqual([{ id: 'peripheralUuid', params: 'parameters' }]);
184
+
185
+ should(bindings._connectionQueue).length(1);
186
+ should(bindings._connectionQueue[0].id).eql('peripheralUuid');
187
+ should(bindings._connectionQueue[0].params).eql('parameters');
180
188
  });
181
189
  });
182
190
 
@@ -641,7 +649,7 @@ describe('hci-socket bindings', () => {
641
649
 
642
650
  const connectCallback = sinon.spy();
643
651
 
644
- bindings._pendingConnectionUuid = 'pending_uuid';
652
+ bindings._connectionQueue.push({ id: 'pending_uuid' });
645
653
  bindings.on('connect', connectCallback);
646
654
  bindings.onLeConnComplete(status, handle, role, addressType, address);
647
655
 
@@ -651,7 +659,7 @@ describe('hci-socket bindings', () => {
651
659
 
652
660
  assert.calledOnceWithMatch(connectCallback, 'pending_uuid', sinon.match({ message: 'custom mapper (0x1)' }));
653
661
 
654
- should(bindings._pendingConnectionUuid).equal(null);
662
+ should(bindings._connectionQueue).length(0);
655
663
  });
656
664
 
657
665
  it('with unmapped status on master node', () => {
@@ -663,7 +671,7 @@ describe('hci-socket bindings', () => {
663
671
 
664
672
  const connectCallback = sinon.spy();
665
673
 
666
- bindings._pendingConnectionUuid = 'pending_uuid';
674
+ bindings._connectionQueue.push({ id: 'pending_uuid' });
667
675
  bindings.on('connect', connectCallback);
668
676
  bindings.onLeConnComplete(status, handle, role, addressType, address);
669
677
 
@@ -673,29 +681,31 @@ describe('hci-socket bindings', () => {
673
681
 
674
682
  assert.calledOnceWithExactly(connectCallback, 'pending_uuid', sinon.match({ message: 'HCI Error: Unknown (0x2)' }));
675
683
 
676
- should(bindings._pendingConnectionUuid).equal(null);
684
+ should(bindings._connectionQueue).length(0);
677
685
  });
678
686
 
679
687
  it('with connection queue', () => {
680
688
  const status = 0;
681
689
  const handle = 'handle';
682
690
  const role = 0;
683
- const addressType = 'addressType';
684
- const address = 'address:split:by:separator';
691
+ const addressType = 'random';
692
+ const address = '11:22:33:44:55:66';
685
693
 
686
694
  const connectCallback = sinon.spy();
687
695
 
688
- bindings._connectionQueue = [{ id: 'queuedId', params: { p1: 'p1' } }];
689
- bindings._addresses = { queuedId: 'queuedAddress' };
690
- bindings._addresseTypes = { queuedId: 'queuedAddressType' };
696
+ bindings._addresses = { 'queuedId_1': '112233445566', 'queuedId_2': '998877665544' };
697
+ bindings._addresseTypes = { 'queuedId_1': 'random', 'queuedId_2': 'public' };
698
+ bindings.connect('queuedId_1', { addressType: 'random' });
699
+ bindings.connect('queuedId_2', { addressType: 'public' });
700
+
691
701
  bindings.on('connect', connectCallback);
692
702
  bindings.onLeConnComplete(status, handle, role, addressType, address);
693
703
 
694
- assert.calledOnceWithExactly(connectCallback, 'addresssplitbyseparator', null);
695
-
696
- assert.calledOnceWithExactly(createLeConnSpy, 'queuedAddress', 'queuedAddressType', { p1: 'p1' });
704
+ assert.calledOnceWithExactly(connectCallback, '112233445566', null);
705
+ assert.calledWithExactly(createLeConnSpy, '112233445566', 'random', { addressType: 'random' });
706
+ assert.calledWithExactly(createLeConnSpy, '998877665544', 'public', { addressType: 'public' });
697
707
 
698
- should(bindings._pendingConnectionUuid).equal('queuedId');
708
+ should(bindings._connectionQueue).length(1);
699
709
  });
700
710
  });
701
711
 
@@ -344,7 +344,7 @@ describe('hci-socket gap', () => {
344
344
  manufacturerData: undefined,
345
345
  serviceData: [],
346
346
  serviceUuids: [],
347
- solicitationServiceUuids: []
347
+ serviceSolicitationUuids: []
348
348
  },
349
349
  rssi,
350
350
  count: 1,
@@ -375,7 +375,7 @@ describe('hci-socket gap', () => {
375
375
  manufacturerData: 'manufacturerData',
376
376
  serviceData: ['data'],
377
377
  serviceUuids: ['uuids'],
378
- solicitationServiceUuids: ['solicitation']
378
+ serviceSolicitationUuids: []
379
379
  };
380
380
  const count = 8;
381
381
  const hasScanResponse = true;
@@ -473,7 +473,6 @@ describe('hci-socket gap', () => {
473
473
  manufacturerData: undefined,
474
474
  serviceData: [],
475
475
  serviceUuids: [],
476
- solicitationServiceUuids: [],
477
476
  serviceSolicitationUuids: []
478
477
  },
479
478
  rssi,
@@ -513,7 +512,6 @@ describe('hci-socket gap', () => {
513
512
  manufacturerData: undefined,
514
513
  serviceData: [],
515
514
  serviceUuids: [],
516
- solicitationServiceUuids: [],
517
515
  serviceSolicitationUuids: []
518
516
  },
519
517
  rssi,
@@ -553,7 +551,6 @@ describe('hci-socket gap', () => {
553
551
  manufacturerData: undefined,
554
552
  serviceData: [],
555
553
  serviceUuids: [],
556
- solicitationServiceUuids: [],
557
554
  serviceSolicitationUuids: []
558
555
  },
559
556
  rssi,
@@ -599,7 +596,6 @@ describe('hci-socket gap', () => {
599
596
  manufacturerData: undefined,
600
597
  serviceData: [],
601
598
  serviceUuids: ['201'],
602
- solicitationServiceUuids: [],
603
599
  serviceSolicitationUuids: []
604
600
  },
605
601
  rssi,
@@ -646,7 +642,6 @@ describe('hci-socket gap', () => {
646
642
  manufacturerData: undefined,
647
643
  serviceData: [],
648
644
  serviceUuids: ['0f0e0d0c0b0a09080706050403020100'],
649
- solicitationServiceUuids: [],
650
645
  serviceSolicitationUuids: []
651
646
  },
652
647
  rssi,
@@ -692,7 +687,6 @@ describe('hci-socket gap', () => {
692
687
  manufacturerData: undefined,
693
688
  serviceData: [],
694
689
  serviceUuids: [],
695
- solicitationServiceUuids: [],
696
690
  serviceSolicitationUuids: []
697
691
  },
698
692
  rssi,
@@ -738,7 +732,6 @@ describe('hci-socket gap', () => {
738
732
  manufacturerData: undefined,
739
733
  serviceData: [],
740
734
  serviceUuids: [],
741
- solicitationServiceUuids: [],
742
735
  serviceSolicitationUuids: []
743
736
  },
744
737
  rssi,
@@ -784,7 +777,6 @@ describe('hci-socket gap', () => {
784
777
  manufacturerData: undefined,
785
778
  serviceData: [],
786
779
  serviceUuids: [],
787
- solicitationServiceUuids: [],
788
780
  serviceSolicitationUuids: ['201']
789
781
  },
790
782
  rssi,
@@ -830,7 +822,6 @@ describe('hci-socket gap', () => {
830
822
  manufacturerData: undefined,
831
823
  serviceData: [],
832
824
  serviceUuids: [],
833
- solicitationServiceUuids: [],
834
825
  serviceSolicitationUuids: ['0f0e0d0c0b0a09080706050403020100']
835
826
  },
836
827
  rssi,
@@ -881,7 +872,6 @@ describe('hci-socket gap', () => {
881
872
  }
882
873
  ],
883
874
  serviceUuids: [],
884
- solicitationServiceUuids: [],
885
875
  serviceSolicitationUuids: []
886
876
  },
887
877
  rssi,
@@ -932,7 +922,6 @@ describe('hci-socket gap', () => {
932
922
  }
933
923
  ],
934
924
  serviceUuids: [],
935
- solicitationServiceUuids: [],
936
925
  serviceSolicitationUuids: []
937
926
  },
938
927
  rssi,
@@ -983,7 +972,6 @@ describe('hci-socket gap', () => {
983
972
  }
984
973
  ],
985
974
  serviceUuids: [],
986
- solicitationServiceUuids: [],
987
975
  serviceSolicitationUuids: []
988
976
  },
989
977
  rssi,
@@ -1029,7 +1017,6 @@ describe('hci-socket gap', () => {
1029
1017
  manufacturerData: undefined,
1030
1018
  serviceData: [],
1031
1019
  serviceUuids: [],
1032
- solicitationServiceUuids: [],
1033
1020
  serviceSolicitationUuids: ['4030201']
1034
1021
  },
1035
1022
  rssi,
@@ -1074,7 +1061,6 @@ describe('hci-socket gap', () => {
1074
1061
  manufacturerData,
1075
1062
  serviceData: [],
1076
1063
  serviceUuids: [],
1077
- solicitationServiceUuids: [],
1078
1064
  serviceSolicitationUuids: []
1079
1065
  },
1080
1066
  rssi,
@@ -1137,7 +1123,6 @@ describe('hci-socket gap', () => {
1137
1123
  }
1138
1124
  ],
1139
1125
  serviceUuids: [],
1140
- solicitationServiceUuids: [],
1141
1126
  serviceSolicitationUuids: []
1142
1127
  },
1143
1128
  rssi,
@@ -1186,7 +1171,6 @@ describe('hci-socket gap', () => {
1186
1171
  }
1187
1172
  ],
1188
1173
  serviceUuids: [],
1189
- solicitationServiceUuids: [],
1190
1174
  serviceSolicitationUuids: []
1191
1175
  },
1192
1176
  rssi,
@@ -1220,7 +1204,6 @@ describe('hci-socket gap', () => {
1220
1204
  }
1221
1205
  ],
1222
1206
  serviceUuids: [],
1223
- solicitationServiceUuids: [],
1224
1207
  serviceSolicitationUuids: []
1225
1208
  },
1226
1209
  rssi,