Comparing version 1.6.0 to 1.7.0
@@ -0,1 +1,9 @@ | ||
## Version 1.7.0 | ||
* hci-socket binding: now supports "long writes" ([@projectgus](https://github.com/projectgus)) | ||
* hci-socket binding: use latest bluetooth-hci-socket dependency (~0.5.1) | ||
* hci-socket binding: add support to extract service solicitation UUID's from advertisement ([@smartyw](https://github.com/smartyw)) | ||
* web-socket binding: fixed write handle not working ([@christopherhex](https://github.com/christopherhex)) | ||
* hci-socket binding: initial bindUser support via HCI_CHANNEL_USER environment variable | ||
## Version 1.6.0 | ||
@@ -2,0 +10,0 @@ |
@@ -92,3 +92,4 @@ var debug = require('debug')('gap'); | ||
serviceData: [], | ||
serviceUuids: [] | ||
serviceUuids: [], | ||
solicitationServiceUuids: [] | ||
}; | ||
@@ -105,2 +106,3 @@ | ||
advertisement.serviceUuids = []; | ||
advertisement.serviceSolicitationUuids = []; | ||
} | ||
@@ -113,2 +115,3 @@ | ||
var serviceUuid = null; | ||
var serviceSolicitationUuid = null; | ||
@@ -162,2 +165,20 @@ while ((i + 1) < eir.length) { | ||
case 0x14: // List of 16 bit solicitation UUIDs | ||
for (j = 0; j < bytes.length; j += 2) { | ||
serviceSolicitationUuid = bytes.readUInt16LE(j).toString(16); | ||
if (advertisement.serviceSolicitationUuids.indexOf(serviceSolicitationUuid) === -1) { | ||
advertisement.serviceSolicitationUuids.push(serviceSolicitationUuid); | ||
} | ||
} | ||
break; | ||
case 0x15: // List of 128 bit solicitation UUIDs | ||
for (j = 0; j < bytes.length; j += 16) { | ||
serviceSolicitationUuid = bytes.slice(j, j + 16).toString('hex').match(/.{1,2}/g).reverse().join(''); | ||
if (advertisement.serviceSolicitationUuids.indexOf(serviceSolicitationUuid) === -1) { | ||
advertisement.serviceSolicitationUuids.push(serviceSolicitationUuid); | ||
} | ||
} | ||
break; | ||
case 0x16: // Service Data, there can be multiple occurences | ||
@@ -173,2 +194,11 @@ var serviceDataUuid = bytes.slice(0, 2).toString('hex').match(/.{1,2}/g).reverse().join(''); | ||
case 0x1f: // List of 32 bit solicitation UUIDs | ||
for (j = 0; j < bytes.length; j += 4) { | ||
serviceSolicitationUuid = bytes.readUInt32LE(j).toString(16); | ||
if (advertisement.serviceSolicitationUuids.indexOf(serviceSolicitationUuid) === -1) { | ||
advertisement.serviceSolicitationUuids.push(serviceSolicitationUuid); | ||
} | ||
} | ||
break; | ||
case 0xff: // Manufacturer Specific Data | ||
@@ -175,0 +205,0 @@ advertisement.manufacturerData = bytes; |
@@ -21,2 +21,6 @@ var debug = require('debug')('att'); | ||
var ATT_OP_WRITE_RESP = 0x13; | ||
var ATT_OP_PREPARE_WRITE_REQ = 0x16; | ||
var ATT_OP_PREPARE_WRITE_RESP = 0x17; | ||
var ATT_OP_EXECUTE_WRITE_REQ = 0x18; | ||
var ATT_OP_EXECUTE_WRITE_RESP = 0x19; | ||
var ATT_OP_HANDLE_NOTIFY = 0x1b; | ||
@@ -127,2 +131,4 @@ var ATT_OP_HANDLE_IND = 0x1d; | ||
debug(this._address + ': read: ' + data.toString('hex')); | ||
this._currentCommand.callback(data); | ||
@@ -281,2 +287,25 @@ | ||
Gatt.prototype.prepareWriteRequest = function(handle, offset, data) { | ||
var buf = new Buffer(5 + data.length); | ||
buf.writeUInt8(ATT_OP_PREPARE_WRITE_REQ); | ||
buf.writeUInt16LE(handle, 1); | ||
buf.writeUInt16LE(offset, 3); | ||
for (var i = 0; i < data.length; i++) { | ||
buf.writeUInt8(data.readUInt8(i), i + 5); | ||
} | ||
return buf; | ||
}; | ||
Gatt.prototype.executeWriteRequest = function(handle, cancelPreparedWrites) { | ||
var buf = new Buffer(2); | ||
buf.writeUInt8(ATT_OP_EXECUTE_WRITE_REQ); | ||
buf.writeUInt8(cancelPreparedWrites ? 0 : 1, 1); | ||
return buf; | ||
}; | ||
Gatt.prototype.handleConfirmation = function() { | ||
@@ -300,7 +329,5 @@ var buf = new Buffer(1); | ||
this._mtu = newMtu; | ||
} | ||
this.emit('mtu', this._address, mtu); | ||
} else { | ||
this.emit('mtu', this._address, 23); | ||
} | ||
this.emit('mtu', this._address, this._mtu); | ||
}.bind(this)); | ||
@@ -509,2 +536,4 @@ }; | ||
}.bind(this)); | ||
} else if (data.length + 3 > this._mtu) { | ||
return this.longWrite(serviceUuid, characteristicUuid, data, withoutResponse); | ||
} else { | ||
@@ -521,2 +550,44 @@ this._queueCommand(this.writeRequest(characteristic.valueHandle, data, false), function(data) { | ||
/* Perform a "long write" as described Bluetooth Spec section 4.9.4 "Write Long Characteristic Values" */ | ||
Gatt.prototype.longWrite = function(serviceUuid, characteristicUuid, data, withoutResponse) { | ||
var characteristic = this._characteristics[serviceUuid][characteristicUuid]; | ||
var limit = this._mtu - 5; | ||
var prepareWriteCallback = function(data_chunk) { | ||
return function(resp) { | ||
var opcode = resp[0]; | ||
if (opcode != ATT_OP_PREPARE_WRITE_RESP) { | ||
debug(this._address + ': unexpected reply opcode %d (expecting ATT_OP_PREPARE_WRITE_RESP)', opcode); | ||
} else { | ||
var expected_length = data_chunk.length + 5; | ||
if (resp.length !== expected_length) { | ||
/* the response should contain the data packet echoed back to the caller */ | ||
debug(this._address + ': unexpected prepareWriteResponse length %d (expecting %d)', resp.length, expected_length); | ||
} | ||
} | ||
}.bind(this); | ||
}.bind(this); | ||
/* split into prepare-write chunks and queue them */ | ||
var offset = 0; | ||
while (offset < data.length) { | ||
var end = offset+limit; | ||
var chunk = data.slice(offset, end); | ||
this._queueCommand(this.prepareWriteRequest(characteristic.valueHandle, offset, chunk), prepareWriteCallback(chunk)); | ||
offset = end; | ||
} | ||
/* queue the execute command with a callback to emit the write signal when done */ | ||
this._queueCommand(this.executeWriteRequest(characteristic.valueHandle), function(resp) { | ||
var opcode = resp[0]; | ||
if (opcode === ATT_OP_EXECUTE_WRITE_RESP && !withoutResponse) { | ||
this.emit('write', this._address, serviceUuid, characteristicUuid); | ||
} | ||
}.bind(this)); | ||
}; | ||
Gatt.prototype.broadcast = function(serviceUuid, characteristicUuid, broadcast) { | ||
@@ -523,0 +594,0 @@ var characteristic = this._characteristics[serviceUuid][characteristicUuid]; |
@@ -31,5 +31,7 @@ var debug = require('debug')('hci'); | ||
var OCF_SET_EVENT_MASK = 0x0001; | ||
var OCF_RESET = 0x0003; | ||
var OCF_READ_LE_HOST_SUPPORTED = 0x006C; | ||
var OCF_WRITE_LE_HOST_SUPPORTED = 0x006D; | ||
var OGF_INFO_PARAM = 0x04; | ||
@@ -52,2 +54,3 @@ var OCF_READ_LOCAL_VERSION = 0x0001; | ||
var SET_EVENT_MASK_CMD = OCF_SET_EVENT_MASK | OGF_HOST_CTL << 10; | ||
var RESET_CMD = OCF_RESET | OGF_HOST_CTL << 10; | ||
var READ_LE_HOST_SUPPORTED_CMD = OCF_READ_LE_HOST_SUPPORTED | OGF_HOST_CTL << 10; | ||
@@ -75,2 +78,3 @@ var WRITE_LE_HOST_SUPPORTED_CMD = OCF_WRITE_LE_HOST_SUPPORTED | OGF_HOST_CTL << 10; | ||
this._state = null; | ||
this._deviceId = null; | ||
@@ -92,6 +96,13 @@ this._handleBuffers = {}; | ||
this._socket.bindRaw(deviceId); | ||
this._socket.start(); | ||
if (process.env.HCI_CHANNEL_USER) { | ||
this._deviceId = this._socket.bindUser(deviceId); | ||
this._socket.start(); | ||
this.pollIsDevUp(); | ||
this.reset(); | ||
} else { | ||
this._deviceId = this._socket.bindRaw(deviceId); | ||
this._socket.start(); | ||
this.pollIsDevUp(); | ||
} | ||
}; | ||
@@ -154,2 +165,17 @@ | ||
Hci.prototype.reset = function() { | ||
var cmd = new Buffer(4); | ||
// header | ||
cmd.writeUInt8(HCI_COMMAND_PKT, 0); | ||
cmd.writeUInt16LE(OCF_RESET | OGF_HOST_CTL << 10, 1); | ||
// length | ||
cmd.writeUInt8(0x00, 3); | ||
debug('reset - writing: ' + cmd.toString('hex')); | ||
this._socket.write(cmd); | ||
}; | ||
Hci.prototype.readLocalVersion = function() { | ||
@@ -507,3 +533,8 @@ var cmd = new Buffer(4); | ||
Hci.prototype.processCmdCompleteEvent = function(cmd, status, result) { | ||
if (cmd === READ_LE_HOST_SUPPORTED_CMD) { | ||
if (cmd === RESET_CMD) { | ||
this.setEventMask(); | ||
this.setLeEventMask(); | ||
this.readLocalVersion(); | ||
this.readBdAddr(); | ||
} else if (cmd === READ_LE_HOST_SUPPORTED_CMD) { | ||
if (status === 0) { | ||
@@ -510,0 +541,0 @@ var le = result.readUInt8(0); |
@@ -306,3 +306,3 @@ var events = require('events'); | ||
this._sendCommand({ | ||
action: 'readHandle', | ||
action: 'writeHandle', | ||
peripheralUuid: peripheral.uuid, | ||
@@ -309,0 +309,0 @@ handle: handle, |
@@ -6,3 +6,3 @@ { | ||
"description": "A Node.js BLE (Bluetooth Low Energy) central library.", | ||
"version": "1.6.0", | ||
"version": "1.7.0", | ||
"repository": { | ||
@@ -35,3 +35,3 @@ "type": "git", | ||
"optionalDependencies": { | ||
"bluetooth-hci-socket": "~0.4.4", | ||
"bluetooth-hci-socket": "^0.5.1", | ||
"bplist-parser": "0.0.6", | ||
@@ -38,0 +38,0 @@ "xpc-connection": "~0.1.4" |
@@ -1,6 +0,8 @@ | ||
# noble | ||
# ![noble](assets/noble-logo.png) | ||
[![Build Status](https://travis-ci.org/sandeepmistry/noble.svg?branch=master)](https://travis-ci.org/sandeepmistry/noble) | ||
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sandeepmistry/noble?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | ||
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sandeepmistry/noble?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![OpenCollective](https://opencollective.com/noble/backers/badge.svg)](#backers) | ||
[![OpenCollective](https://opencollective.com/noble/sponsors/badge.svg)](#sponsors) | ||
A Node.js BLE (Bluetooth Low Energy) central module. | ||
@@ -63,4 +65,3 @@ | ||
| OS X 10.11 (El Capitan) | 6 | | ||
| Linux/Windows - Adapter dependent | | | ||
| | 5 (CSR based adapter) | | ||
| Linux/Windows - Adapter dependent | 5 (CSR based adapter) | | ||
@@ -280,2 +281,3 @@ ## Install | ||
serviceUuids: ["<service UUID>", ...], | ||
serviceSolicitationUuid: ["<service solicitation UUID>", ...], | ||
manufacturerData: <Buffer>, | ||
@@ -296,2 +298,4 @@ serviceData: [ | ||
__Note:__ on OS X the address will be set to 'unknown' if the device has not been connected previously. | ||
#### Warnings | ||
@@ -464,2 +468,72 @@ | ||
## Backers | ||
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/noble#backer)] | ||
<a href="https://opencollective.com/noble/backer/0/website" target="_blank"><img src="https://opencollective.com/noble/backer/0/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/1/website" target="_blank"><img src="https://opencollective.com/noble/backer/1/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/2/website" target="_blank"><img src="https://opencollective.com/noble/backer/2/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/3/website" target="_blank"><img src="https://opencollective.com/noble/backer/3/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/4/website" target="_blank"><img src="https://opencollective.com/noble/backer/4/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/5/website" target="_blank"><img src="https://opencollective.com/noble/backer/5/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/6/website" target="_blank"><img src="https://opencollective.com/noble/backer/6/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/7/website" target="_blank"><img src="https://opencollective.com/noble/backer/7/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/8/website" target="_blank"><img src="https://opencollective.com/noble/backer/8/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/9/website" target="_blank"><img src="https://opencollective.com/noble/backer/9/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/10/website" target="_blank"><img src="https://opencollective.com/noble/backer/10/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/11/website" target="_blank"><img src="https://opencollective.com/noble/backer/11/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/12/website" target="_blank"><img src="https://opencollective.com/noble/backer/12/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/13/website" target="_blank"><img src="https://opencollective.com/noble/backer/13/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/14/website" target="_blank"><img src="https://opencollective.com/noble/backer/14/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/15/website" target="_blank"><img src="https://opencollective.com/noble/backer/15/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/16/website" target="_blank"><img src="https://opencollective.com/noble/backer/16/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/17/website" target="_blank"><img src="https://opencollective.com/noble/backer/17/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/18/website" target="_blank"><img src="https://opencollective.com/noble/backer/18/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/19/website" target="_blank"><img src="https://opencollective.com/noble/backer/19/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/20/website" target="_blank"><img src="https://opencollective.com/noble/backer/20/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/21/website" target="_blank"><img src="https://opencollective.com/noble/backer/21/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/22/website" target="_blank"><img src="https://opencollective.com/noble/backer/22/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/23/website" target="_blank"><img src="https://opencollective.com/noble/backer/23/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/24/website" target="_blank"><img src="https://opencollective.com/noble/backer/24/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/25/website" target="_blank"><img src="https://opencollective.com/noble/backer/25/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/26/website" target="_blank"><img src="https://opencollective.com/noble/backer/26/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/27/website" target="_blank"><img src="https://opencollective.com/noble/backer/27/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/28/website" target="_blank"><img src="https://opencollective.com/noble/backer/28/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/backer/29/website" target="_blank"><img src="https://opencollective.com/noble/backer/29/avatar.svg"></a> | ||
## Sponsors | ||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/noble#sponsor)] | ||
<a href="https://opencollective.com/noble/sponsor/0/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/0/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/1/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/1/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/2/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/2/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/3/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/3/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/4/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/4/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/5/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/5/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/6/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/6/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/7/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/7/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/8/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/8/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/9/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/9/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/10/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/10/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/11/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/11/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/12/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/12/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/13/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/13/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/14/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/14/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/15/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/15/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/16/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/16/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/17/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/17/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/18/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/18/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/19/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/19/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/20/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/20/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/21/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/21/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/22/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/22/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/23/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/23/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/24/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/24/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/25/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/25/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/26/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/26/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/27/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/27/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/28/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/28/avatar.svg"></a> | ||
<a href="https://opencollective.com/noble/sponsor/29/website" target="_blank"><img src="https://opencollective.com/noble/sponsor/29/avatar.svg"></a> | ||
## Useful Links | ||
@@ -466,0 +540,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
318361
48
6837
552
7