Skip to content

Commit

Permalink
feat(hci): enhance connection queue to support multiple devices
Browse files Browse the repository at this point in the history
  • Loading branch information
stoprocent committed Dec 30, 2024
1 parent fde991e commit 1fdf3ed
Showing 1 changed file with 40 additions and 23 deletions.
63 changes: 40 additions & 23 deletions lib/hci-socket/bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,26 @@ NobleBindings.prototype.connect = function (peripheralUuid, parameters = {}) {
addressType = parameters && parameters.addressType ? parameters.addressType : 'random';
}

const createConnection = () => {
if (!this._pendingConnectionUuid) {
this._pendingConnectionUuid = peripheralUuid;
this._hci.createLeConn(address, addressType, parameters);
} else {
this._connectionQueue.push({ id: peripheralUuid, params: parameters });
}
// Add connection request to queue
this._connectionQueue.push({
id: peripheralUuid,
address,
addressType,
params: parameters
});

const processNextConnection = () => {
if (this._connectionQueue.length === 0) return;

const nextConn = this._connectionQueue[0]; // Look at next connection but don't remove yet
this._hci.createLeConn(nextConn.address, nextConn.addressType, nextConn.params);
};

if (this._isScanning) {
this.once('scanStop', createConnection);
this.once('scanStop', processNextConnection);
this.stopScanning();
} else {
createConnection();
processNextConnection();
}
};

Expand Down Expand Up @@ -128,6 +134,21 @@ NobleBindings.prototype.onSigInt = function () {
const sigIntListeners = process.listeners('SIGINT');

if (sigIntListeners[sigIntListeners.length - 1] === this.onSigIntBinded) {
// Stop scanning if active
if (this._isScanning) {
this.stopScanning();
}

// Disconnect all active connections
for (const handle in this._handles) {
if (this._handles.hasOwnProperty(handle)) {

Check failure on line 144 in lib/hci-socket/bindings.js

View workflow job for this annotation

GitHub Actions / lint

Do not access Object.prototype method 'hasOwnProperty' from target object
this.disconnect(this._handles[handle]);
}
}

// Clear connection queue
this._connectionQueue = [];

// we are the last listener, so exit
// this will trigger onExit, and clean up
process.exit(1);
Expand Down Expand Up @@ -259,8 +280,8 @@ NobleBindings.prototype.onLeConnComplete = function (
// not master, ignore
return;
}
let uuid = null;

let uuid = null;
let error = null;

if (status === 0) {
Expand Down Expand Up @@ -351,27 +372,23 @@ NobleBindings.prototype.onLeConnComplete = function (

this._gatts[handle].exchangeMtu();
} else {
uuid = this._pendingConnectionUuid;
const currentConn = this._connectionQueue[0];
uuid = currentConn ? currentConn.id : null;
let statusMessage = Hci.STATUS_MAPPER[status] || 'HCI Error: Unknown';
const errorCode = ` (0x${status.toString(16)})`;
statusMessage = statusMessage + errorCode;
error = new Error(statusMessage);
}

this.emit('connect', uuid, error);

if (this._connectionQueue.length > 0) {
const queueItem = this._connectionQueue.shift();
const peripheralUuid = queueItem.id;
// Remove the completed/failed connection attempt from queue
this._connectionQueue.shift();

address = this._addresses[peripheralUuid];
addressType = this._addresseTypes[peripheralUuid];

this._pendingConnectionUuid = peripheralUuid;
this.emit('connect', uuid, error);

this._hci.createLeConn(address, addressType, queueItem.params);
} else {
this._pendingConnectionUuid = null;
// Process next connection in queue if any
if (this._connectionQueue.length > 0 && !this._isScanning) {
const nextConn = this._connectionQueue[0];
this._hci.createLeConn(nextConn.address, nextConn.addressType, nextConn.params);
}
};

Expand Down

0 comments on commit 1fdf3ed

Please sign in to comment.