Socket
Socket
Sign inDemoInstall

noble

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

noble - npm Package Compare versions

Comparing version 0.1.1 to 0.1.2

bin/bluez-scanner.py

9

install.js

@@ -11,3 +11,3 @@ var os = require('os');

exec('npm install xpc-connection@0.0.1', function(error, stdout, stderr) {
exec('npm install xpc-connection@~0.0.2', function(error, stdout, stderr) {
console.log('noble install: done');

@@ -17,8 +17,3 @@ process.exit(error ? -1 : 0);

} else if (platform === 'linux') {
console.log('noble install: installing dbus ...');
exec('npm install dbus', function(error, stdout, stderr) {
console.log('noble install: done');
process.exit(error ? -1 : 0);
});
process.exit(0);
} else {

@@ -25,0 +20,0 @@ console.error('noble install: Your platform is not supported!');

@@ -25,4 +25,2 @@ var debug = require('debug')('bindings');

this._bluez.on('discover', this.onDiscover.bind(this));
this._bluez.init();
};

@@ -114,4 +112,2 @@

this._gatttool[address].disconnect();
// TODO: kill gatttool, unbind events
};

@@ -122,2 +118,8 @@

this._gatttool[address].kill();
this._gatttool[address].removeAllListeners();
delete this._gatttool[address];
this.emit('disconnect', uuid);

@@ -286,2 +288,2 @@ };

module.exports = nobleBindings;
module.exports = nobleBindings;
var debug = require('debug')('bluez');
var events = require('events');
var spawn = require('child_process').spawn;
var util = require('util');
var dbus = require('dbus');
var BlueZ4 = require('./bluez4');
var BlueZ5 = require('./bluez5');
var BlueZ = function() {
var bluezScanner = __dirname + '/../../bin/bluez-scanner.py';
debug('bluezScanner = ' + bluezScanner);
var BlueZ = function() {
this._bluezScanner = spawn('stdbuf', ['-o', '0', '-e', '0', '-i', '0', bluezScanner]);
this._bluezScanner.on('close', this.onClose.bind(this));
this._bluezScanner.stdout.on('data', this.onStdoutData.bind(this));
this._bluezScanner.stderr.on('data', this.onStderrData.bind(this));
this._bluezScanner.on('error', function() { });
this._buffer = "";
};

@@ -16,41 +26,74 @@

BlueZ.prototype.init = function() {
this._bluez = null;
BlueZ.prototype.onClose = function(code) {
debug('close = ' + code);
};
dbus.start(function() {
if (this._bluez === null) {
try {
this._bluez = new BlueZ5(dbus);
} catch(e) {
// console.error(e);
BlueZ.prototype.onStdoutData = function(data) {
this._buffer += data.toString();
debug('buffer = ' + JSON.stringify(this._buffer));
var newLineIndex;
while ((newLineIndex = this._buffer.indexOf('\n')) !== -1) {
var line = this._buffer.substring(0, newLineIndex);
this._buffer = this._buffer.substring(newLineIndex + 1);
var splitLine = line.split(': ');
var key = splitLine[0];
var value = splitLine[1];
if (key === 'Adapter') {
var state = 'unknown';
if (value === 'None') {
state = 'unsupported';
} else if (value === 'PoweredOff') {
state = 'poweredOff';
} else if (value === 'PoweredOn') {
state = 'poweredOn';
}
}
if (this._bluez === null) {
try {
this._bluez = new BlueZ4(dbus);
} catch(e) {
// console.error(e);
this.emit('stateChange', state);
} else if (key === 'DeviceFound') {
var splitValue = value.split(',');
var properties = {};
for (var i in splitValue) {
var splitValueValue = splitValue[i].split(' = ');
properties[splitValueValue[0].trim()] = splitValueValue[1].trim();
}
}
if (this._bluez === null) {
throw new Error('Could not init BlueZ');
} else {
this._bluez.on('stateChange', this.onStateChange.bind(this));
this._bluez.on('discover', this.onDiscover.bind(this));
var address = properties.Address;
var advertisement = {
localName: properties.Name,
serviceUuids: []
};
var rssi = properties.RSSI;
process.nextTick(function() {
this.emit('stateChange', this._bluez._powered ? 'poweredOn' : 'poweredOff');
}.bind(this));
var uuids = properties.UUIDs.split(' ');
for (var j in uuids) {
var uuid = uuids[j].split('-').join('');
if (uuid.match(/^0000.{4}00001000800000805f9b/)) {
uuid = uuid.substring(4, 8);
}
advertisement.serviceUuids.push(uuid);
}
this.emit('discover', address, advertisement, rssi);
} else if (key === 'Error') {
console.error('bluez-scanner error: ' + value);
}
}.bind(this));
}
};
BlueZ.prototype.onStateChange = function(state) {
this.emit('stateChange', state);
BlueZ.prototype.onStderrData = function(data) {
console.error('stderr: ' + data);
};
BlueZ.prototype.startScanning = function() {
this._bluez.startScanning();
this._bluezScanner.stdin.write('start\n');

@@ -61,3 +104,3 @@ this.emit('scanStart');

BlueZ.prototype.stopScanning = function() {
this._bluez.startScanning();
this._bluezScanner.stdin.write('stop\n');

@@ -67,7 +110,3 @@ this.emit('scanStop');

BlueZ.prototype.onDiscover = function(address, advertisement, rssi) {
this.emit('discover', address, advertisement, rssi);
};
module.exports = BlueZ;
module.exports = BlueZ;

@@ -33,27 +33,34 @@ /*jshint loopfunc: true */

Gatttool.prototype.kill = function() {
this._gatttool.kill();
};
Gatttool.prototype.onClose = function(code) {
console.log('close = ' + code);
debug('close = ' + code);
};
Gatttool.prototype.onStdoutData = function(data) {
var string = data.toString().replace(/(\u001b\[C)|(\u001b\[16@)/g, '').replace(/\r/g, '\n');
var string = data.toString().replace(/(\u001b\[C)|(\u001b\[16@)|(\u001b\[4h)|(\u001b\[4l)/g, '').replace(/\r/g, '\n');
this._buffer += string;
if (this._buffer === ' Characteristic value was written successfully\n' ||
this._buffer === ' Read characteristics by UUID failed: No attribute found within the given range\n') {
if (this._buffer === '\n ' ||
this._buffer === ' \n ' ||
this._buffer === ' Characteristic value was written successfully\n' ||
this._buffer === ' Read characteristics by UUID failed: No attribute found within the given range\n' ||
this._buffer === ' Characteristic value/descriptor read failed: Attribute can\'t be read\n') {
this._gatttool.stdin.write('\n');
}
// console.log('***');
// console.log(JSON.stringify(this._buffer));
// console.log('***');
debug('***');
debug(JSON.stringify(this._buffer));
debug('***');
var found;
while ((found = this._buffer.match(/([\s\S]*)\[(.{3})\]\[(.{17})\]\[(.*)\]>(.*)/)) !== null) {
// console.log(found);
debug(found);
var output = found[1];
var connected = (found[2] === 'CON');
var address = found[3];
//var address = found[3];
var type = found[4];

@@ -105,3 +112,3 @@

this.emit(connected ? 'connect' : 'disconnect', address);
this.emit(connected ? 'connect' : 'disconnect', this._address);
}

@@ -112,3 +119,3 @@ }

Gatttool.prototype.onStderrData = function(data) {
console.log('stderr: ' + data);
console.error('stderr: ' + data);
};

@@ -129,3 +136,3 @@

Gatttool.prototype._executeNextCommand = function() {
this._currentCommand = this._commandQueue.pop();
this._currentCommand = this._commandQueue.shift();

@@ -137,4 +144,4 @@ this._gatttool.stdin.write(this._currentCommand.command + '\n');

// TODO: handle 'public' and 'random'
this.executeCommand('connect' /*+ ' ' + this._address + ' random'*/, false, function(output) {
// console.log('connect output: ' + JSON.stringify(output));
this.executeCommand('connect'/*+ ' ' + this._address + ' random'*/, false, function(output) {
debug('connect output: ' + JSON.stringify(output));
}.bind(this));

@@ -145,3 +152,3 @@ };

this.executeCommand('disconnect', false, function(output) {
// console.log('disconnect output: ' + JSON.stringify(output));
debug('disconnect output: ' + JSON.stringify(output));
}.bind(this));

@@ -152,3 +159,3 @@ };

this.executeCommand('primary', true, function(output) {
// console.log('primary output: ' + JSON.stringify(output));
debug('primary output: ' + JSON.stringify(output));

@@ -170,6 +177,6 @@ var serviceUuids = [];

// console.log(attrHandle);
// console.log(endGrpHandle);
// console.log(uuid);
// console.log();
debug(attrHandle);
debug(endGrpHandle);
debug(uuid);
debug();

@@ -198,3 +205,3 @@ this._services[uuid] = {

// console.log(serviceUuids);
debug(serviceUuids);
this.emit('servicesDiscover', this._address, serviceUuids);

@@ -208,3 +215,3 @@ }.bind(this));

this.executeCommand('char-read-uuid 0x2802 ' + service.attrHandle + ' ' + service.endGrpHandle, true, function(output) {
console.log('discover included services output: ' + JSON.stringify(output));
debug('discover included services output: ' + JSON.stringify(output));

@@ -234,3 +241,3 @@ var includedServices = [];

this.executeCommand('characteristics ' + service.attrHandle + ' ' + service.endGrpHandle, true, function(output) {
// console.log('characteristics output: ' + JSON.stringify(output));
debug('characteristics output: ' + JSON.stringify(output));

@@ -255,7 +262,7 @@ var characteristics = [];

// console.log(handle);
// console.log(properties);
// console.log(valueHandle);
// console.log(uuid);
// console.log();
debug(handle);
debug(properties);
debug(valueHandle);
debug(uuid);
debug();

@@ -330,5 +337,6 @@ this._characteristics[serviceUuid][uuid] = {

this.executeCommand('char-read-hnd ' + characteristic.valueHandle, true, function(output) {
// console.log('read output: ' + JSON.stringify(output));
debug('read output: ' + JSON.stringify(output));
var bytes = null;
for (var i in output) {
for (var i in output) {
var line = output[i].trim();

@@ -338,3 +346,3 @@

if (found) {
var bytes = found[1].trim().split(' ');
bytes = found[1].trim().split(' ');

@@ -344,6 +352,6 @@ for (var j in bytes) {

}
this.emit('read', this._address, serviceUuid, characteristicUuid, new Buffer(bytes));
}
}
this.emit('read', this._address, serviceUuid, characteristicUuid, bytes ? new Buffer(bytes) : null);
}.bind(this));

@@ -362,3 +370,3 @@ };

this.executeCommand(command, !withoutResponse, function(output) {
// console.log('write output: ' + JSON.stringify(output));
debug('write output: ' + JSON.stringify(output));

@@ -396,2 +404,4 @@ this.emit('write', this._address, serviceUuid, characteristicUuid);

this.executeCommand(command, true, function(output) {
debug('broadcast output: ' + JSON.stringify(output));
for (var i in output) {

@@ -429,2 +439,4 @@ var line = output[i].trim();

this.executeCommand(command, true, function(output) {
debug('notify output: ' + JSON.stringify(output));
for (var i in output) {

@@ -466,2 +478,4 @@ var line = output[i].trim();

this.executeCommand(command, true, function(output) {
debug('descriptors discover output: ' + JSON.stringify(output));
var descriptorUuids = [];

@@ -494,3 +508,3 @@ for (var j in output) {

this.executeCommand('char-read-hnd ' + descriptor.handle, true, function(output) {
// console.log('value read output: ' + JSON.stringify(output));
debug('value read output: ' + JSON.stringify(output));

@@ -524,3 +538,3 @@ for (var i in output) {

this.executeCommand(command, false, function(output) {
// console.log('value write output: ' + JSON.stringify(output));
debug('value write output: ' + JSON.stringify(output));

@@ -533,5 +547,6 @@ this.emit('valueWrite', this._address, serviceUuid, characteristicUuid, descriptorUuid);

this.executeCommand('char-read-hnd 0x' + handle.toString(16), true, function(output) {
// console.log('handle read output: ' + JSON.stringify(output));
debug('handle read output: ' + JSON.stringify(output));
var bytes = null;
for (var i in output) {
for (var i in output) {
var line = output[i].trim();

@@ -541,3 +556,3 @@

if(found) {
var bytes = found[1].trim().split(' ');
bytes = found[1].trim().split(' ');

@@ -547,6 +562,6 @@ for (var j in bytes) {

}
this.emit('handleRead', this._address, handle, new Buffer(bytes));
}
}
this.emit('handleRead', this._address, handle, bytes ? new Buffer(bytes) : null);
}.bind(this));

@@ -563,3 +578,3 @@ };

this.executeCommand(command, !withoutResponse, function(output) {
// console.log('write handle output: ' + JSON.stringify(output));
debug('write handle output: ' + JSON.stringify(output));

@@ -566,0 +581,0 @@ this.emit('handleWrite', this._address, handle);

@@ -65,2 +65,35 @@ var debug = require('debug')('peripheral');

Peripheral.prototype.discoverSomeServicesAndCharacteristics = function(serviceUuids, characteristicsUuids, callback) {
this.discoverServices(serviceUuids, function(err, services) {
var numDiscovered = 0;
var allCharacteristics = [];
for (var i in services) {
var service = services[i];
service.discoverCharacteristics(characteristicsUuids, function(error, characteristics) {
numDiscovered++;
if (error === null) {
for (var j in characteristics) {
var characteristic = characteristics[j];
allCharacteristics.push(characteristic);
}
}
if (numDiscovered === services.length) {
if (callback) {
callback(null, services, allCharacteristics);
}
}
}.bind(this));
}
}.bind(this));
};
Peripheral.prototype.discoverAllServicesAndCharacteristics = function(callback) {
this.discoverSomeServicesAndCharacteristics([], [], callback);
};
Peripheral.prototype.readHandle = function(handle, callback) {

@@ -67,0 +100,0 @@ if (callback) {

@@ -5,3 +5,3 @@ {

"description": "A node.js BLE (Bluetooth low energy) library.",
"version": "0.1.1",
"version": "0.1.2",
"repository": {

@@ -8,0 +8,0 @@ "type": "git",

@@ -13,8 +13,12 @@ noble

* node 0.8.x is required, until an [issue with signals with the npm dbus module](https://github.com/Shouqun/node-dbus/issues/45) is fixed.
* [BlueZ](http://www.bluez.org) 4 or 5 (with ```gatttool``` on path)
* Install BlueZ 5.x (optional, needed if there are issues with the stock BlueZ 4.x)
* ```sudo apt-get install libglib2.0-dev libdbus-1-dev libusb-dev libudev-dev libical-dev libreadline-dev``` (build dependencies)
* extract archive, ```./configure --disable-systemd```, ```make```, ```sudo make install```
* ```sudo apt-get install g++ libdbus-glib-1-dev libexpat1-dev``` (required for the dbus npm module)
* [BlueZ](http://www.bluez.org) __4.100 or 4.101__ is needed !
* 4.99 does not support connecting to LE devices
* Install BlueZ 4.101 (if you are running an older unsupported version)
* install build dependencies: ```sudo apt-get install libglib2.0-dev libdbus-1-dev libusb-dev libudev-dev libical-dev libreadline-dev```
* fetch archive: ```wget https://www.kernel.org/pub/linux/bluetooth/bluez-4.101.tar.bz2```
* extract archive: ```tar xvjf bluez-4.101.tar.bz2```
* change directory: ```cd bluez-4.101```
* configure: ```./configure --disable-systemd```
* build: ```make```
* install: ```sudo make install```

@@ -69,2 +73,12 @@ Install

Peripheral discover all services and characteristics
peripheral.discoverAllServicesAndCharacteristics([callback(error, services, characteristics));
Peripheral discover some services and characteristics
var serviceUUIDs = ["<service UUID 1>", ...];
var characteristicUUIDs = ["<characteristic UUID 1>", ...];
peripheral.discoverSomeServicesAndCharacteristics(serviceUUIDs, characteristicUUIDs, [callback(error, services, characteristics));
Service discover included services

@@ -285,2 +299,9 @@

* TDB (most likely Windows 8 only)
Useful Links
------------
* [Bluetooth Development Portal](http://developer.bluetooth.org)
* [GATT Specifications](http://developer.bluetooth.org/gatt/Pages/default.aspx)
* [Bluetooth: ATT and GATT](http://epx.com.br/artigos/bluetooth_gatt.php)

@@ -287,0 +308,0 @@ License

@@ -158,2 +158,94 @@ var should = require('should');

describe('discoverSomeServicesAndCharacteristics', function() {
var mockServiceUuids = [];
var mockCharacteristicUuids = [];
var mockServices = null;
beforeEach(function() {
peripheral.discoverServices = sinon.spy();
mockServices = [
{
uuid: '1',
discoverCharacteristics: sinon.spy()
},
{
uuid: '2',
discoverCharacteristics: sinon.spy()
}
];
});
it('should call discoverServices', function() {
peripheral.discoverSomeServicesAndCharacteristics(mockServiceUuids);
peripheral.discoverServices.calledWith(mockServiceUuids).should.equal(true);
});
it('should call discoverCharacteristics on each service discovered', function() {
peripheral.discoverSomeServicesAndCharacteristics(mockServiceUuids, mockCharacteristicUuids);
var discoverServicesCallback = peripheral.discoverServices.getCall(0).args[1];
discoverServicesCallback(null, mockServices);
mockServices[0].discoverCharacteristics.calledWith(mockCharacteristicUuids).should.equal(true);
mockServices[1].discoverCharacteristics.calledWith(mockCharacteristicUuids).should.equal(true);
});
it('should callback', function() {
var calledback = false;
peripheral.discoverSomeServicesAndCharacteristics(mockServiceUuids, mockCharacteristicUuids, function() {
calledback = true;
});
var discoverServicesCallback = peripheral.discoverServices.getCall(0).args[1];
discoverServicesCallback(null, mockServices);
mockServices[0].discoverCharacteristics.getCall(0).args[1](null, []);
mockServices[1].discoverCharacteristics.getCall(0).args[1](null, []);
calledback.should.equal(true);
});
it('should callback with the services and characteristics discovered', function() {
var calledbackServices = null;
var calledbackCharacteristics = null;
peripheral.discoverSomeServicesAndCharacteristics(mockServiceUuids, mockCharacteristicUuids, function(err, services, characteristics) {
calledbackServices = services;
calledbackCharacteristics = characteristics;
});
var discoverServicesCallback = peripheral.discoverServices.getCall(0).args[1];
discoverServicesCallback(null, mockServices);
var mockCharacteristic1 = { uuid: '1' };
var mockCharacteristic2 = { uuid: '2' };
var mockCharacteristic3 = { uuid: '3' };
mockServices[0].discoverCharacteristics.getCall(0).args[1](null, [mockCharacteristic1]);
mockServices[1].discoverCharacteristics.getCall(0).args[1](null, [mockCharacteristic2, mockCharacteristic3]);
calledbackServices.should.equal(mockServices);
calledbackCharacteristics.should.eql([mockCharacteristic1, mockCharacteristic2, mockCharacteristic3]);
});
});
describe('discoverAllServicesAndCharacteristics', function() {
it('should call discoverSomeServicesAndCharacteristics', function() {
var mockCallback = sinon.spy();
peripheral.discoverSomeServicesAndCharacteristics = sinon.spy();
peripheral.discoverAllServicesAndCharacteristics(mockCallback);
peripheral.discoverSomeServicesAndCharacteristics.calledWithExactly([], [], mockCallback).should.equal(true);
});
});
describe('readHandle', function() {

@@ -160,0 +252,0 @@ it('should delegate to noble', function() {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc