@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.
- package/lib/hci-socket/bindings.js +40 -23
- package/lib/hci-socket/gap.js +2 -2
- package/package.json +1 -1
- package/prebuilds/darwin-x64+arm64/@stoprocent+noble.node +0 -0
- package/prebuilds/win32-ia32/@stoprocent+noble.node +0 -0
- package/prebuilds/win32-x64/@stoprocent+noble.node +0 -0
- package/test/lib/hci-socket/bindings.test.js +28 -18
- package/test/lib/hci-socket/gap.test.js +2 -19
|
@@ -61,20 +61,26 @@ NobleBindings.prototype.connect = function (peripheralUuid, parameters = {}) {
|
|
|
61
61
|
addressType = parameters && parameters.addressType ? parameters.addressType : 'random';
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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',
|
|
80
|
+
this.once('scanStop', processNextConnection);
|
|
75
81
|
this.stopScanning();
|
|
76
82
|
} else {
|
|
77
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
368
|
-
addressType = this._addresseTypes[peripheralUuid];
|
|
369
|
-
|
|
370
|
-
this._pendingConnectionUuid = peripheralUuid;
|
|
386
|
+
this.emit('connect', uuid, error);
|
|
371
387
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
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
|
|
package/lib/hci-socket/gap.js
CHANGED
|
@@ -274,9 +274,9 @@ Gap.prototype.parseServices = function (
|
|
|
274
274
|
manufacturerData: undefined,
|
|
275
275
|
serviceData: [],
|
|
276
276
|
serviceUuids: [],
|
|
277
|
-
|
|
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
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -137,7 +137,9 @@ describe('hci-socket bindings', () => {
|
|
|
137
137
|
|
|
138
138
|
bindings.connect('112233445566', { addressType: 'public' });
|
|
139
139
|
|
|
140
|
-
should(bindings.
|
|
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.
|
|
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.
|
|
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).
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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 = '
|
|
684
|
-
const address = '
|
|
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.
|
|
689
|
-
bindings.
|
|
690
|
-
bindings.
|
|
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, '
|
|
695
|
-
|
|
696
|
-
assert.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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,
|