From cd53c0f5a1c15ebb3150a309348b53561cd4ea5a Mon Sep 17 00:00:00 2001 From: Alexandre Trovato Date: Sun, 14 Feb 2021 21:19:01 +0100 Subject: [PATCH] Scan parameters --- lib/hci-socket/bindings.js | 9 +++++++++ lib/hci-socket/gap.js | 6 +++++- lib/hci-socket/hci.js | 6 +++--- lib/noble.js | 13 +++++++++++++ test/test-noble.js | 20 ++++++++++++++++++++ 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/lib/hci-socket/bindings.js b/lib/hci-socket/bindings.js index 463c5baf5..10b9dc074 100644 --- a/lib/hci-socket/bindings.js +++ b/lib/hci-socket/bindings.js @@ -28,6 +28,10 @@ const NobleBindings = function () { util.inherits(NobleBindings, events.EventEmitter); +NobleBindings.prototype.setScanParameters = function (interval, window) { + this._gap.setScanParameters(interval, window); +}; + NobleBindings.prototype.startScanning = function (serviceUuids, allowDuplicates) { this._scanServiceUuids = serviceUuids || []; @@ -66,6 +70,7 @@ NobleBindings.prototype.updateRssi = function (peripheralUuid) { NobleBindings.prototype.init = function () { this.onSigIntBinded = this.onSigInt.bind(this); + this._gap.on('scanParametersSet', this.onScanParametersSet.bind(this)); this._gap.on('scanStart', this.onScanStart.bind(this)); this._gap.on('scanStop', this.onScanStop.bind(this)); this._gap.on('discover', this.onDiscover.bind(this)); @@ -129,6 +134,10 @@ NobleBindings.prototype.onAddressChange = function (address) { this.emit('addressChange', address); }; +NobleBindings.prototype.onScanParametersSet = function () { + this.emit('scanParametersSet'); +}; + NobleBindings.prototype.onScanStart = function (filterDuplicates) { this.emit('scanStart', filterDuplicates); }; diff --git a/lib/hci-socket/gap.js b/lib/hci-socket/gap.js index 6bcf11b95..efe41861b 100644 --- a/lib/hci-socket/gap.js +++ b/lib/hci-socket/gap.js @@ -23,6 +23,10 @@ const Gap = function (hci) { util.inherits(Gap, events.EventEmitter); +Gap.prototype.setScanParameters = function (interval, window) { + this._hci.setScanParameters(interval, window); +}; + Gap.prototype.startScanning = function (allowDuplicates) { this._scanState = 'starting'; this._scanFilterDuplicates = !allowDuplicates; @@ -52,7 +56,7 @@ Gap.prototype.onHciError = function (error) { }; Gap.prototype.onHciLeScanParametersSet = function () { - + this.emit('scanParametersSet'); }; // Called when receive an event "Command Complete" for "LE Set Scan Enable" diff --git a/lib/hci-socket/hci.js b/lib/hci-socket/hci.js index ccffaace2..dff1548cd 100644 --- a/lib/hci-socket/hci.js +++ b/lib/hci-socket/hci.js @@ -299,7 +299,7 @@ Hci.prototype.writeLeHostSupported = function () { this._socket.write(cmd); }; -Hci.prototype.setScanParameters = function () { +Hci.prototype.setScanParameters = function (interval = 0x0010, window = 0x0010) { const cmd = Buffer.alloc(11); // header @@ -311,8 +311,8 @@ Hci.prototype.setScanParameters = function () { // data cmd.writeUInt8(0x01, 4); // type: 0 -> passive, 1 -> active - cmd.writeUInt16LE(0x0010, 5); // internal, ms * 1.6 - cmd.writeUInt16LE(0x0010, 7); // window, ms * 1.6 + cmd.writeUInt16LE(interval, 5); // interval, ms * 1.6 + cmd.writeUInt16LE(window, 7); // window, ms * 1.6 cmd.writeUInt8(0x00, 9); // own address type: 0 -> public, 1 -> random cmd.writeUInt8(0x00, 10); // filter: 0 -> all event types diff --git a/lib/noble.js b/lib/noble.js index 072ec9a85..27c10aced 100644 --- a/lib/noble.js +++ b/lib/noble.js @@ -22,6 +22,7 @@ function Noble (bindings) { this._bindings.on('stateChange', this.onStateChange.bind(this)); this._bindings.on('addressChange', this.onAddressChange.bind(this)); + this._bindings.on('scanParametersSet', this.onScanParametersSet.bind(this)); this._bindings.on('scanStart', this.onScanStart.bind(this)); this._bindings.on('scanStop', this.onScanStop.bind(this)); this._bindings.on('discover', this.onDiscover.bind(this)); @@ -93,6 +94,18 @@ Noble.prototype.onAddressChange = function (address) { this.address = address; }; +Noble.prototype.setScanParameters = function (interval, window, callback) { + if (callback) { + this.once('scanParametersSet', callback); + } + this._bindings.setScanParameters(interval, window); +}; + +Noble.prototype.onScanParametersSet = function () { + debug('scanParametersSet'); + this.emit('scanParametersSet'); +}; + const startScanning = function (serviceUuids, allowDuplicates, callback) { if (typeof serviceUuids === 'function') { this.emit('warning', 'calling startScanning(callback) is deprecated'); diff --git a/test/test-noble.js b/test/test-noble.js index 2024c4bc3..cfc808a2a 100644 --- a/test/test-noble.js +++ b/test/test-noble.js @@ -1,5 +1,6 @@ require('should'); const sinon = require('sinon'); +const { fake, assert } = sinon; const Noble = require('../lib/noble'); @@ -14,6 +15,7 @@ describe('Noble', () => { mockBindings = { init: () => {}, on: () => {}, + setScanParameters: fake.returns(null), startScanning: sinon.spy(), stopScanning: sinon.spy() }; @@ -21,6 +23,10 @@ describe('Noble', () => { noble = new Noble(mockBindings); }); + afterEach(() => { + sinon.reset(); + }); + describe('startScanningAsync', () => { it('should delegate to binding', async () => { const expectedServiceUuids = [1, 2, 3]; @@ -66,4 +72,18 @@ describe('Noble', () => { await promise.should.be.resolved(); }); }); + + describe('setScanParameters', () => { + it('should delegate to binding', async () => { + const interval = 'interval'; + const window = 'window'; + + const promise = noble.setScanParameters(interval, window); + noble.emit('scanParametersSet'); + await promise; + + assert.calledOnce(mockBindings.setScanParameters); + assert.calledWith(mockBindings.setScanParameters, interval, window); + }); + }); });