Git Product home page Git Product logo

bleno's Introduction

noble

Build Status Gitter OpenCollective OpenCollective

A Node.js BLE (Bluetooth Low Energy) central module.

Want to implement a peripheral? Checkout bleno

Note: macOS / Mac OS X, Linux, FreeBSD and Windows are currently the only supported OSes. Other platforms may be developed later on.

Prerequisites

OS X

Linux

  • Kernel version 3.6 or above
  • libbluetooth-dev

Ubuntu/Debian/Raspbian

sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev

Make sure node is on your path, if it's not, some options:

Fedora / Other-RPM based

sudo yum install bluez bluez-libs bluez-libs-devel

Intel Edison

See Configure Intel Edison for Bluetooth LE (Smart) Development

FreeBSD

Make sure you have GNU Make:

sudo pkg install gmake

Disable automatic loading of the default Bluetooth stack by putting no-ubt.conf into /usr/local/etc/devd/no-ubt.conf and restarting devd (sudo service devd restart).

Unload ng_ubt kernel module if already loaded:

sudo kldunload ng_ubt

Make sure you have read and write permissions on the /dev/usb/* device that corresponds to your Bluetooth adapter.

Windows

node-gyp requirements for Windows

Install the required tools and configurations using Microsoft's windows-build-tools from an elevated PowerShell or cmd.exe (run as Administrator).

npm install --global --production windows-build-tools

node-bluetooth-hci-socket prerequisites

  • Compatible Bluetooth 4.0 USB adapter
  • WinUSB driver setup for Bluetooth 4.0 USB adapter, using Zadig tool

See @don's set up guide on Bluetooth LE with Node.js and Noble on Windows

Notes

Maximum simultaneous connections

This limit is imposed upon by the Bluetooth adapter hardware as well as it's firmware.

Platform
OS X 10.11 (El Capitan) 6
Linux/Windows - Adapter dependent 5 (CSR based adapter)

Adapter specific known issues

Some BLE adapters cannot connect to a peripheral while they are scanning (examples below). You will get the following messages when trying to connect :

Sena UD-100 (Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)) : Error: Command disallowed

Intel Dual Band Wireless-AC 7260 (Intel Corporation Wireless 7260 (rev 73)) : Error: Connection Rejected due to Limited Resources (0xd)

You need to stop scanning before trying to connect in order to solve this issue.

Install

npm install noble

Usage

var noble = require('noble');

Actions

Start scanning

noble.startScanning(); // any service UUID, no duplicates


noble.startScanning([], true); // any service UUID, allow duplicates


var serviceUUIDs = ["<service UUID 1>", ...]; // default: [] => all
var allowDuplicates = <false|true>; // default: false

noble.startScanning(serviceUUIDs, allowDuplicates[, callback(error)]); // particular UUID's

NOTE: noble.state must be poweredOn before scanning is started. noble.on('stateChange', callback(state)); can be used register for state change events.

Stop scanning

noble.stopScanning();

Peripheral

Connect
peripheral.connect([callback(error)]);
Disconnect or cancel pending connection
peripheral.disconnect([callback(error)]);
Update RSSI
peripheral.updateRssi([callback(error, rssi)]);
Discover services
peripheral.discoverServices(); // any service UUID

var serviceUUIDs = ["<service UUID 1>", ...];
peripheral.discoverServices(serviceUUIDs[, callback(error, services)]); // particular UUID's
Discover all services and characteristics
peripheral.discoverAllServicesAndCharacteristics([callback(error, services, characteristics)]);
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
service.discoverIncludedServices(); // any service UUID

var serviceUUIDs = ["<service UUID 1>", ...];
service.discoverIncludedServices(serviceUUIDs[, callback(error, includedServiceUuids)]); // particular UUID's
Discover characteristics
service.discoverCharacteristics() // any characteristic UUID

var characteristicUUIDs = ["<characteristic UUID 1>", ...];
service.discoverCharacteristics(characteristicUUIDs[, callback(error, characteristics)]); // particular UUID's

Characteristic

Read
characteristic.read([callback(error, data)]);
Write
characteristic.write(data, withoutResponse[, callback(error)]); // data is a buffer, withoutResponse is true|false
  • withoutResponse:
    • false: send a write request, used with "write" characteristic property
    • true: send a write command, used with "write without response" characteristic property
Broadcast
characteristic.broadcast(broadcast[, callback(error)]); // broadcast is true|false
Subscribe
characteristic.subscribe([callback(error)]);
  • subscribe to a characteristic, triggers 'data' events when peripheral sends an notification or indication
  • use for characteristics with notify or indicate properties
Unsubscribe
characteristic.unsubscribe([callback(error)]);
  • unsubscribe to a characteristic
  • use for characteristics with notify or indicate properties
Discover descriptors
characteristic.discoverDescriptors([callback(error, descriptors)]);
Read value
descriptor.readValue([callback(error, data)]);
Write value
descriptor.writeValue(data[, callback(error)]); // data is a buffer

Handle

Read
peripheral.readHandle(handle, callback(error, data));
Write
peripheral.writeHandle(handle, data, withoutResponse, callback(error));

Events

See Node.js EventEmitter docs for more info. on API's.

Adapter state change

state = <"unknown" | "resetting" | "unsupported" | "unauthorized" | "poweredOff" | "poweredOn">

noble.on('stateChange', callback(state));

Scan started:

noble.on('scanStart', callback);

The event is emitted when scanning is started or if another application enables scanning or changes scanning settings.

Scan stopped

noble.on('scanStop', callback);

The event is emitted when scanning is stopped or if another application stops scanning.

Peripheral discovered

peripheral = {
  id: "<id>",
  address: "<BT address">, // Bluetooth Address of device, or 'unknown' if not known
  addressType: "<BT address type>", // Bluetooth Address type (public, random), or 'unknown' if not known
  connectable: <connectable>, // true or false, or undefined if not known
  advertisement: {
    localName: "<name>",
    txPowerLevel: <int>,
    serviceUuids: ["<service UUID>", ...],
    serviceSolicitationUuid: ["<service solicitation UUID>", ...],
    manufacturerData: <Buffer>,
    serviceData: [
        {
            uuid: "<service UUID>"
            data: <Buffer>
        },
        ...
    ]
  },
  rssi: <rssi>
};

noble.on('discover', callback(peripheral));

Note: on OS X the address will be set to 'unknown' if the device has not been connected previously.

Warnings

noble.on('warning', callback(message));

Peripheral

Connected
peripheral.once('connect', callback);
Disconnected:
peripheral.once('disconnect', callback);
RSSI update
peripheral.once('rssiUpdate', callback(rssi));
Services discovered
peripheral.once('servicesDiscover', callback(services));

Service

Included services discovered
service.once('includedServicesDiscover', callback(includedServiceUuids));
Characteristics discovered
characteristic = {
  uuid: "<uuid>",
   // properties: 'broadcast', 'read', 'writeWithoutResponse', 'write', 'notify', 'indicate', 'authenticatedSignedWrites', 'extendedProperties'
  properties: [...]
};

service.once('characteristicsDiscover', callback(characteristics));

Characteristic

Data

Emitted when characteristic read has completed, result of characteristic.read(...) or characteristic value has been updated by peripheral via notification or indication - after having been enabled with notify(true[, callback(error)]).

characteristic.on('data', callback(data, isNotification));

characteristic.once('read', callback(data, isNotification)); // legacy

Note: isNotification event parameter value MAY be undefined depending on platform support. The parameter is deprecated after version 1.8.1, and not supported when on macOS High Sierra and later.

Write

Emitted when characteristic write has completed, result of characteristic.write(...).

characteristic.once('write', withoutResponse, callback());
Broadcast

Emitted when characteristic broadcast state changes, result of characteristic.broadcast(...).

characteristic.once('broadcast', callback(state));
Notify

Emitted when characteristic notification state changes, result of characteristic.notify(...).

characteristic.once('notify', callback(state));
Descriptors discovered
descriptor = {
  uuid: '<uuid>'
};

characteristic.once('descriptorsDiscover', callback(descriptors));

Descriptor

Value read
descriptor.once('valueRead', data);
Value write
descriptor.once('valueWrite');

Running on Linux

Running without root/sudo

Run the following command:

sudo setcap cap_net_raw+eip $(eval readlink -f `which node`)

This grants the node binary cap_net_raw privileges, so it can start/stop BLE advertising.

Note: The above command requires setcap to be installed, it can be installed using the following:

  • apt: sudo apt-get install libcap2-bin
  • yum: su -c \'yum install libcap2-bin\'

Multiple Adapters

hci0 is used by default to override set the NOBLE_HCI_DEVICE_ID environment variable to the interface number.

Example, specify hci1:

sudo NOBLE_HCI_DEVICE_ID=1 node <your file>.js

Reporting all HCI events

By default noble waits for both the advertisement data and scan response data for each Bluetooth address. If your device does not use scan response the following environment variable can be used to bypass it.

sudo NOBLE_REPORT_ALL_HCI_EVENTS=1 node <your file>.js

bleno compatibility

By default noble will respond with an error whenever a GATT request message is received. If your intention is to use bleno in tandem with noble, the following environment variable can be used to bypass this functionality. Note: this requires a Bluetooth 4.1 adapter.

sudo NOBLE_MULTI_ROLE=1 node <your file>.js

Advanced usage

Override default bindings

By default, noble will select bindings to communicate with Bluetooth devices depending on your platform. If you prefer to specify what bindings noble should use:

var noble = require('noble/with-bindings')(require('./my-custom-bindings'));

Backers

Support us with a monthly donation and help us continue our activities. [Become a backer]

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]

Useful Links

License

Copyright (C) 2015 Sandeep Mistry [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Analytics

bleno's People

Contributors

beaufortfrancois avatar bhaveshgohel avatar bradfol avatar carlospuk avatar cheesebaron avatar don avatar dragom avatar gfwilliams avatar guimier avatar hashok avatar jacobrosenthal avatar jonathanwiesel avatar malikolivier avatar mnkhouri avatar mploch-sonavation avatar pfafman avatar programmarchy avatar robertchiras avatar sandeepmistry avatar suppsandrob avatar valpackett avatar vdharmon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bleno's Issues

Can't install bleno

Hi,
I've just tried to install bleno on osx (10.9.2) and can't get it to work.

Following the instructions I get:

abigail:bleno $ npm install bleno
npm WARN install Refusing to install bleno as a dependency of itself

Is there anything I'm missing?

Having bleno on more than one device

It be would nice if bleno can handle more than one device.
So when one is connected and not advertising, other one can act as beacon.
Some kind of bleno manager to have more responsive virtual peripheral.

Set Advertisement Frequency

Is it possible to add the ability to adjust the advertisement frequency. I think on Linux it defaults to 1Hz and in a BLE rich environment the advert package might not get detected for a few cycles.

When doing iBeacons this leads on iOS devices for them listing them as proximity unknown and not picking up the iBeacon in a timely fashion.

This is possible if using the hcitool, although not really intuitive. See this question

Thanks,
Tim

Allow multiple connections

I know its against the BLE specification. But is there a way, as a peripheral, to allow multiple centrals to connect? Like using startAdvertising() multiple times? Or manually managing sockets?
Thanks a lot!

Possibly the wrong advertisement data is being sent

The advertisement data I'm seeing with TI RF Packet Sniffer is not what I would expect. Here's a simple peripheral showcasing the issue: https://gist.github.com/zdennis/8447896

When running the advertisement data is: 02 01 0A 02 0A 08 0C 09 43 53 52 38 35 31 30 20 41 31 30

However I'd expect the advertisement data to be: 02 01 05 11 06 d7 4f 4a f1 9b 70 15 91 4f 4c 1a 99 93 38 61 dd

In fact, this is what hci-ble.js thinks it's advertising in HciBle.prototype.startAdvertising but it's not what's being advertised. This is with both bleno 0.1.1 and also bleno @ ee06f6c .

This is using bluez 5.12 (I am currently building bluez 5.13 to try there as well).

Any thoughts?

Can't use multiple services or characteristics

I can't seem to make the beacon to expose more than one service or more than one characteristic in the same service, tried both ways but no luck, this is my code for multiple services:

var bleno = require('bleno'),
    name =  'RPi',
    serviceUuids = ['fff0','eee0'],
    Characteristic = bleno.Characteristic,
    PrimaryService = bleno.PrimaryService;


bleno.on('stateChange', function(state) {
    winston.log.info('on -> stateChange: ' + state);
    if (state === 'poweredOn') {
        bleno.startAdvertising(name, serviceUuids);
    } else {
        bleno.stopAdvertising();
    }
});

bleno.on('advertisingStart', function(error) {
    winston.log.info('on -> advertisingStart: ' + (error ? 'error ' + error : 'success'));
    if(!error){
        var IPcharacteristic = new Characteristic({
            uuid: 'fff1',
            properties: [ 'read' ],
            value: new Buffer(THE IP ADDRESS','ascii')
        });

        var tokenCharacteristic = new Characteristic({
            uuid: 'fff2',
            properties: [ 'read' ],
            value: new Buffer('THE TOKEN','ascii')
        });

        var IPService = new PrimaryService({
            uuid: 'fff0',
            characteristics: [IPcharacteristic]
        });

        var tokenService = new PrimaryService({
            uuid: 'eee0',
            characteristics: [tokenCharacteristic]
        });

        bleno.setServices([IPService, tokenService], function(error){
            winston.log.error('Error setting services:' + error);
        });
    }
});

bleno.on('advertisingStop', function(error){
   winston.log.info('on -> advertisingStop: ' + (error ? 'error ' + error : 'success'));
});

Am I doing something wrong?

I'm using iOS apps like LightBlue and Hello BLE to test it; however I can't seem to make it show both things, either characteristics nor services, only one shows up.

Write data with Bleno

Hi there,
I am currently trying to use Bleno to connect to an iOS 7 device. The connection works and the iOS device subscribes to my characteristic, but I don't really understand how to send data to the iOS device. The onWriteRequest handler is never called and there seems to be no .write() method or something similar on the characteristic, and I couldn't find anything in the documentation.

How exactly is this done?

noble <-> bleno between two mavericks laptops

I've been playing with noble and bleno using slightly modified versions of test.js from both repos between two mavericks laptops

I got one laptop to connect to the other and write a buffer successfully!

Only glaring problem is that the discovery can be quite slow -- at times it only took a few seconds for the laptop running noble to discover to one running bleno, but most times it took between 30 seconds to minutes, or in some cases after a few minutes of not discovering anything I quit the program and tried again

setting Major and Minor when running test-ibeacon.js

There is a problem when setting Major and Minor number in test-ibeacon.js. The number read will be messed up because at Line 64 and Line 65 in bleno.js writeUInt16LE was used instead of writeUInt16BE.

Using writeUInt16BE corrected the issue.
My env is OS X 10.9 on 2011 Macbook Air.

Thank you very much for sharing this wonderful BLE sample code with us.
By the way, the naming of noble and bleno are very ingenious!!!

Device directly starts with 'poweredOff' state

At executing any .js, the first event received is 'stateChange' to 'poweredOff'. The change to 'poweredOn' is never received. Therefore, the peripheral never starts the advertisement.

I guess there is some problem with the platform. I am testing noble in a Raspberry Pi (xbian):
Kernel: 3.12.7+
bluez_4.99-2
node v0.10.26
I have tried with an app that is working properly in Ubuntu and with the tests in bleno (test.js and test-ibeacon.js). The three files work in Ubuntu, but doesn't work in my Rpi.
In all the cases, 'stateChange' to 'poweredOff' is the only event received.

Note: I have checked and the patch proposed in Issue #18 is already applied to my version of bleno.

Name property not taking into consideration

I'm starting the advertising service like this:

...
bleno.startAdvertising('Test peripheral', ['fff0']);
...

However when looking at the device from iOS apps the name is always raspberrypi.

Any clues about why the name is being overridden?

StateChanges

What exactly causes 'stateChange' events to be triggered? Specifically ones where the state becomes 'poweredOff'. I've found that I'd have bleno running and communicating with the iphone app I'm developing, and the state would become 'poweredOff' randomly, disconnecting itself from my app. I was wondering if there are some things I should look out for to avoid this from happening.

Write attribute that is more than 20 bytes?

Is there a way to write more than 20 bytes? I have my iOS LightBlue application tries to write to my BLE peripheral that run on my Linux box, it seems to only take 20 bytes. Is there a way to write more than 20 bytes?

Restarting app during a central connection fails to resume on Linux (RPi)

When running my app for the first time on Raspberry Pi, I can connect as normal and use the service and characteristics via an app such as LightBlue.

However, if I kill and restart the process on the Pi, LightBlue can never work with the peripheral again. I have to restart the Pi to be able to re-establish a connection again.

Looking at the log in LightBlue it appears to connect, then get disconnected again when in this state (I briefly see the RSSI value update as well which suggest an initial connection is made).

Any idea what could be causing this?

Pairing

Is it possible to force pairing with bleno (and to subsequently pair successfully)?

And... awesome project. Used it today to test out a firmware change for some hardware and it saved me a ton of time and frustration.

bleno cant send 256 bytes on dynamic read and notify

When i try to send 256 bytes using dynamic read or notification using bleno, the other end (Android or noble) receives only 22 bytes. See code below.

However, when 256 bytes are sent using a static readonly characteristic, all 256 bytes are received properly.

The BLE spec says characteristic values can be 512 bytes.

Is this a bug?

Environment:
bleno: Macbook pro with Mavericks. Node v0.10.24
noble: Ubuntu 13 desktop with Node v0.10.24
android: API 19, Nexus 4

var chars = [];
for(var i = 0; i < 256; i++) {
    chars.push('a');
}

var StaticReadOnlyCharacteristic = function() {
    StaticReadOnlyCharacteristic.super_.call(this, {
        uuid: 'fffffffffffffffffffffffffffffff1',
        properties: ['read'],
        value: new Buffer(chars.join('')),
        descriptors: [
            new Descriptor({
                uuid: '2901',
                value: 'user description'
            })
        ]
    });
};
util.inherits(StaticReadOnlyCharacteristic, Characteristic);

var DynamicReadOnlyCharacteristic = function() {
    DynamicReadOnlyCharacteristic.super_.call(this, {
        uuid: 'fffffffffffffffffffffffffffffff2',
        properties: ['read']
    });
};

util.inherits(DynamicReadOnlyCharacteristic, Characteristic);

DynamicReadOnlyCharacteristic.prototype.onReadRequest = function(offset, callback) {
    console.log("on -> readRequest");
    var result = this.RESULT_SUCCESS;
    var data = new Buffer(chars.join(''));

    if (offset > data.length) {
        result = this.RESULT_INVALID_OFFSET;
        data = null;
    }

    callback(result, data);
};

Several services/characteristics don't work

Hello!
In short, I have noble (thank you for your work, by the way) on linux with BlueZ 4.101.
My iPad app tries to find characteristics from linux peripheral. It works in case of only one service and one characteristic. When I add one more, it fails to find any services (though the app finds the peripheral).

I've also described my problem here (and pasted my code): http://stackoverflow.com/questions/24925795/bluetooth-le-on-ios-cannot-work-with-many-services-and-characteristics

I wish you can help me, because I have no idea what to do.

P.S. I've tested my .js code with LightBlue on my Mac - it works. And gatttool also finds all the needed characteristics. And nRF Master also. However, LightBlue on iPad finds nothing (the iPad has Bluetooth 4.0 support and runs the latest iOS 7 version).

Reading characteristics with LightBlue kills reconnecting to the peripheral

First of all: I've started using Bleno yesterday and it works great on my Macbook. The BT service is advertised - reading and writing of characteristics works as expected. Awesome.

I use the LightBlue app (https://itunes.apple.com/us/app/lightblue-bluetooth-low-energy/id557428110?mt=8) on my iPhone to read the service and change values from there. As long as I only stay on the top level service overview (after tapping the peripheral name) it works fine. In this case, I can connect to the peripheral, disconnect and reconnect many times.

However, once I dive into one of the characteristics to read or write the value, it will prevent any future reconnects. Reading/writing the characteristic and browsing the service still works fine while you're connected, but once you disconnect you won't be able to go back and will end up with a 'Timeout interrogating the peripheral' error message.

I tried bleno on a Macbook (10.9.3) and a Raspberry Pi (latest raspbian). Same behaviour on both machines. I also tried multiple iPhones running LightBlue.

bleno advertising not working after noble peripheral disconnect

Trying to use bleno for BLE broadcasting just after disconnecting from a peripheral won't work.

We want to scan and connect to a peripheral while broadcasting BLE packets using the same adapter.
Since it doesn't seems possible, we do :

  1. broadcast using bleno.startXXXAdvertising and listen using noble.startScanning
  2. once peripheral is discovered, stop advertising with bleno.stopAdvertising
  3. do something with the peripheral
  4. disconnect using noble peripheral.disconnect()
  5. restart broadcasting using bleno.startXXXAdvertising

Step 5 don't thow an error but doesn't actually resume broadcast.

I have a small test program here :
https://gist.github.com/remydavid/d3d2cec640d290e2ca44
Tested on 2 linux box with 2 different BLE adapters (bleno 0.1.5, node v0.10.30, BlueZ 5.21)

Get onReadRequest callback data with CoreBluetooth

I'm developing an iOS app that reads a Bluetooth service then when characteristic is read I return an array of values.

Let's say my characteristic is the following:

var bleno = require('bleno');
var Characteristic = bleno.Characteristic;

module.exports = new Characteristic({

    uuid: 'fff3',
    properties: [ 'read' ],
    value: new Buffer('List users'),
    onReadRequest: function(offset, callback){
         var list = {
             array: [{
                 test: 'test1'
             },{
                 test: 'test2'
             }]
          };
          callback(Characteristic.RESULT_SUCCESS, new Buffer(JSON.stringify(list)));
    }
});

My problem is how I read that list from the callback in my iOS app? It seems I can only read the characteristic's value, in this case the value is List users. How I can access the data a send in the callback of the onReadRequest method.

SMP support?

When I reboot linux (bluetoothd not running as a service) and run bleno then try to connect from device with SMP pairing request, tracking from hcidump, there is no answer to that request.
But when I run bluetoothd -n -d from console, and right after that, stop it with ctrl-C. then run bleno again. This time devices SMP pairing request is answered.
How to enable SMP support right after clean booting, without running then stopping bluetoothd?

Environment:
Raspberry Pi, raspbian, kernel 3.10.25. Bluez >5.15 (git fetch from master)
Nexus 4, Android 4.4.2 (Scan device in Android Bluetooth Setting, then click peripheal for pairing(SMP))

Thanks,

onSubscribe not been called when I click on "Listen for notifications" on LightBlue

I'm running Bleno on RaspberryPi (Model B) with Raspbian (Kernel version 3.12.20+). LightBlue is on iOS7 iPhone5.

What makes the subscribe handler begin called?

ivan.js:

var util = require('util');
var bleno = require('bleno');

console.log('Ivan');

bleno.on('stateChange', stateChangeCallback);
bleno.on('advertisingStartError', advertisingStartErrorCallback);
bleno.on('advertisingStart', advertisingStartCallback);
bleno.on('advertisingStop', advertisingStopCallback);
bleno.on('servicesSet', servicesSetCallback);
bleno.on('accept', acceptCallback);
bleno.on('disconnect', disconnectCallback);
bleno.on('rssiUpdate', rssiUpdateCallback);

function stateChangeCallback(state) {
console.log("stateChangeCallback: " + state);
if(state=='poweredOn') {
console.log("Start advertising");
bleno.startAdvertising('Ivan', [myService.uuid]);
} else {
console.log("Stop advertising");
bleno.stopAdvertising();
}
}

function advertisingStartCallback(error) {
if(!error) {
console.log("Setting services");
bleno.setServices([myService]);
} else {
console.log("Error starting advertising: " + error);
}
}

function advertisingStartErrorCallback(error) {console.log("advertisingStartErrorCallback: " + error);}
function advertisingStopCallback() {console.log("advertisingStopCallback");}
function servicesSetCallback() {console.log("servicesSetCallback" );}
function acceptCallback(clientAddress) {console.log("acceptCallback: " + clientAddress);}
function disconnectCallback(clientAddress) {console.log("disconnectCallback: " + clientAddress);}
function rssiUpdateCallback(rssi) {console.log("rssiUpdateCallback: " + rssi);}

var Descriptor = bleno.Descriptor;
var Characteristic = bleno.Characteristic;
var PrimaryService = bleno.PrimaryService;

var myCharacteristicDescriptor = new Descriptor({
uuid: '2902',
value: 'myCharacteristic' // static value, must be of type Buffer or string if set
});

var myCharacteristicOnWriteRequest = function(data, offset, withoutResponse, callback) {
console.log("myCharacteristicOnWriteRequest");
var result = Characteristic.RESULT_SUCCESS;
callback(result);
}

var myCharacteristicOnReadRequest = function(offset, callback) {
console.log("myCharacteristicOnReadRequest");
var result = Characteristic.RESULT_SUCCESS;
var data = new Buffer('A1','hex');
callback(result, data);
}

var myCharacteristicUpdateValueCallback = null;

var myCharacteristicOnSubscribe = function(maxValueSize, updateValueCallback) {
console.log("myCharacteristicOnSubscribe");
myCharacteristicUpdateValueCallback = updateValueCallback;
}

var myCharacteristicOnUnsubscribe = function() {console.log("myCharacteristicOnUnsubscribe");}
var myCharacteristicOnNotify = function() {console.log("myCharacteristicOnNotify");}

var myCharacteristic = new Characteristic({
uuid: 'C011', // or 'fff1' for 16-bit
properties: ['write', 'read', 'notify'], // can be a combination of 'read', 'write', 'writeWithoutResponse', 'notify'
secure: [ ], // enable security for properties, can be a combination of 'read', 'write', 'writeWithoutResponse', 'notify'
value: null, // optional static value, must be of type Buffer
descriptors: [
// see Descriptor for data type
myCharacteristicDescriptor
],
onReadRequest: myCharacteristicOnReadRequest, // optional read request handler, function(offset, callback) { ... }
onWriteRequest: myCharacteristicOnWriteRequest, // optional write request handler, function(data, offset, withoutResponse, callback) { ...}
onSubscribe:myCharacteristicOnSubscribe, // optional notify subscribe handler, function(maxValueSize, updateValueCallback) { ...}
onUnsubscribe: myCharacteristicOnUnsubscribe, // optional notify unsubscribe handler, function() { ...}
onNotify: myCharacteristicOnNotify // optional notify sent handler, function() { ...}
});

var myService = new PrimaryService({
uuid: 'C010', // or 'fff0' for 16-bit
name: 'myService',
characteristics: [
// see Characteristic for data type
myCharacteristic
]
});

Can't retrieve Services / Characteristics on Arduino Yun

Hi,
I'm using bleno on Arduino Yun, advertising works perfectly, I can also have a central connect to the peripheral, but when I try to retrieve the services and characteristics, it doesn't work. (I'm using the LightBlue app on iPhone to test)
The Arduino Yun bleno module is compiled/used with BlueZ 5.13. But I suspect that it is not compiled with the correct arguments. (--disable-systemd --disable-monitor --disable-cups --disable-client --disable-obex --enable-library)
I suspect that the problem comes from BlueZ (not sur though).
What BlueZ's components are essentials to bleno?
Thanks!

Android BluetoothGatt.setCharacteristicNotification(characteristic, true) doesnt call onSubscribe

NotifyOnlyCharacteristic.prototype.onSubscribe = function(maxValueSize, updateValueCallback) {
    console.log('NotifyOnlyCharacteristic subscribe');

    this.counter = 0;
    this.changeInterval = setInterval(function() {
        var data = new Buffer(4);
        data.writeUInt32LE(this.counter, 0);

        console.log('NotifyOnlyCharacteristic update value: ' + this.counter);
        updateValueCallback(data);
        this.counter++;
    }.bind(this), 5000);
};

I am using this code to setup a NotifyCharacteristic. This application running OS X Mavericks acts a peripheral for an Android app (BluetoothLeSample).

In the Android app, when

BluetoothGatt.setCharacteristicNotification(characteristic, true);

is called. It doesn't result in a call of the "onSubscribe" method in bleno. Any ideas?

events come in slow

Hi,

I'm using your library together with some RFDuino's and sometimes the events coming in, happen really slow. Takes like have a second before they come through :-(

But sometimes, after disconnecting and reconnecting again, they come in very fast.

I'm using discoverSomeServicesAndCharacteristics(), characteristic.on('read', function(){}) and characteristic.notify() to listen for incoming button presses on the RFDuino.

Is there something that may explain this 'slowness'?
Is notify() the right way to listen for incoming 'events'?

I only have it with your library. If I use the iOS BLE library, it's always fast.

I'm using Mac OS X Mavericks.

Thx,
Sam

npm install on rpi

Node version v0.10.29, installed via dpkg from http://node-arm.herokuapp.com/node_latest_armhf.deb

I'm getting:

735 verbose /usr/local/bin,[object Object] binRoot
736 info postuninstall [email protected]
737 error [email protected] install: `node install.js`
737 error Exit status 1
738 error Failed at the [email protected] install script.
738 error This is most likely a problem with the bleno package,
738 error not with npm itself.
738 error Tell the author that this fails on your system:
738 error     node install.js
738 error You can get their info via:
738 error     npm owner ls bleno
738 error There is likely additional logging output above.
739 error System Linux 3.10.25+
740 error command "/usr/local/bin/node" "/usr/local/bin/npm" "i" "-g" "ibeacon-cli"
741 error cwd /home/pi
742 error node -v v0.10.29
743 error npm -v 1.4.14
744 error code ELIFECYCLE
745 verbose exit [ 1, true ]

Device name doesn't work properly (at least in Ubuntu)

I'm using this great library in Ubuntu 12.04. I don't know if this is an issue in Ubuntu or Bleno, but here I go:

The name specified using Bleno seems to be used only in the advertisement, but it is not the name provided bythe 0x1800 primary service. The service replies 'ubuntu' as the name.

More specifically:
If I define the name 'myName' using:
bleno.startAdvertising('myName', ['fff0']);
I get the next result:

  • In LightBlue (iOS):
    • It detects a peripheral showing the name 'ubuntu', although in a small typography it also indicates 'myName'. I guess the small typography shows the contents of the advertisement, but LightBlue considers the name to be ubuntu.
  • In nRF Master (Android)
    • It shows 'myName' as the name before connecting.
    • However, if I request the value of the characteristic 0x2A00 (Device Name) in the primary service 0x1800, I get the value 'ubuntu'.

Considering these observations, it seems that ubuntu adds its own 0x1800 primary service to my peripheral.
I have tried to overwrite this service defining my own 0x1800 primary service, with my own 0x2A00 (Device Name) and 0x2A01 (Appearance) characteristics. However, it doesn't work. nRF Master detects two 0x1800 services, the 'ubuntu' service is still there.

Do you think this could be a bug in Bleno? or Ubuntu will always define its own name characteristic?

Error running on raspbian

I'm trying to get a sample bleno app running on my Raspberry PI which is running raspbian. The code I'm trying to run runs on OSX, but errors when I try to start it on linux. When using hcitool manually I'm able to configure the pi to broadcast.

I have installed node and npm by compiling them and they seem to be working. I have installed libbluetooth-dev as well.

When I try to run the bleno app with debug=* it seems to be looking for 2 files I don't have.

hci-ble hciBle = /home/pi/projects/peripheral/node_modules/bleno/lib/linux/../../build/Release/hci-ble +0ms
l2cap-ble l2capBle = /home/pi/projects/peripheral/node_modules/bleno/lib/linux/../../build/Release/l2cap-ble +0ms

Neither of these files exist, and the error I get is

stderr: execvp(): No such file or directory

stderr: execvp(): No such file or directory

events.js:66
throw arguments[1]; // Unhandled 'error' event
^
Error: write EPIPE
at errnoException (net.js:769:11)
at Object.afterWrite (net.js:593:19)

I feel like I missing something silly.

Thanks in advance for any help you might be able to provide!

"Error: spawn ENOENT" . I get this error while trying to run test.js

Here is the full error,

Error: spawn ENOENT at errnoException (child_process.js:998:11) at Process.ChildProcess._handle.onexit (child_process.js:789:34)

I googled this error, and some suggested that it could because of different npm version. I have npm -v 1.4.9 and node -v 0.10.28 . I tried executing "npm update -g " but gave me following error.

npm http GET https://registry.npmjs.org/npm
npm http 200 https://registry.npmjs.org/npm
npm http GET https://registry.npmjs.org/npm/-/npm-1.4.14.tgz
npm http 200 https://registry.npmjs.org/npm/-/npm-1.4.14.tgz
npm ERR! error rolling back Error: EACCES, unlink '/usr/local/bin/npm'
npm ERR! error rolling back [email protected] { [Error: EACCES, unlink '/usr/local/bin
/npm'] errno: 3, code: 'EACCES', path: '/usr/local/bin/npm' }
npm ERR! Error: EACCES, unlink '/usr/local/bin/npm'
npm ERR! { [Error: EACCES, unlink '/usr/local/bin/npm'] errno: 3, code: 'EACCES
', path: '/usr/local/bin/npm' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

npm ERR! System Linux 3.10.25+
npm ERR! command "/usr/local/bin/node" "/usr/local/bin/npm" "update" "-g"
npm ERR! cwd /home/pi/node_modules
npm ERR! node -v v0.10.28
npm ERR! npm -v 1.4.9
npm ERR! path /usr/local/bin/npm
npm ERR! code EACCES
npm ERR! errno 3
npm ERR! stack Error: EACCES, unlink '/usr/local/bin/npm'
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/pi/node_modules/npm-debug.log
npm ERR! not ok code 0

Thank you in advance.

Setup credentials?

Hi, I'm fairly new to bluetooth development. I'm trying to read the characteristics in a Raspberry Pi from my iphone with CoreBluetooth. The problem is, I want to protect some of those characteristics from being read without authentication. I noticed there is a "secure" parameter in the Characteristic constructor, but I don't know how to set the credentials to restrict the access to it.

Thanks in advance.

onStateChange -> unknown

Hi guys,

Any ideas what would be causing my Bluetooth Dongle to return an unknown state? I'm using it through Virtualbox, do you think that might cause an issue?

Thanks

Enhance: Allow adjusting connection latency

On iOS, there is the possibility for a peripheral to change the connection latency, i.e. the inter packet interval, which basically limits the possible datarate. This API exists on OS X too (however, it is broken as far as I can tell). The API allows three different latencies.

On Linux this can be done using hcitool lecup, which upgrades the connection to more specific values. For testing purposes (my project requires initial fast data rates) I added the following to l2cap-ble.c in src/: (the parameters match the parameters of hcitool lecup)

void hci_le_conn_update2(int dd, uint16_t handle, uint16_t min, uint16_t max,
                        uint16_t latency, uint16_t to_multiplier)
{
        le_connection_update_cp cp;
    struct hci_request rq;
    evt_le_connection_update_complete evt;

        memset(&cp, 0, sizeof(cp));

        cp.handle               = htobs(handle);
        cp.min_interval    = htobs(min);
        cp.max_interval    = htobs(max);
        cp.latency         = htobs(latency);
        cp.supervision_timeout  = htobs(to_multiplier);
        cp.min_ce_length           = htobs(0x0001);
        cp.max_ce_length           = htobs(0x0001);


    memset(&rq, 0, sizeof(rq));
    rq.ogf = OGF_LE_CTL;
    rq.ocf = OCF_LE_CONN_UPDATE;
    rq.cparam = &cp;
    rq.clen = LE_CONN_UPDATE_CP_SIZE;
    rq.event = EVT_LE_CONN_UPDATE_COMPLETE;
    rq.rparam = &evt;
    rq.rlen = sizeof(evt);

    if(hci_send_req(dd, &rq, 1000) < 0) {
        // printing to console seems a bad idea as it seems to be used for communication
        // if we land here, BAAAD
             //return -1;
    }

    if(evt.status) {
          // baaaad
         // return -1;
    }
    // return 0;  GOOD
}

For testing purposes and because I haven't got the time to understand how the js part communicates with the c part, I added the following in the main function after a successful connection accept: (Please note, I only added the one function call before the while loop)

...
  baswap(&clientBdAddr, &sockAddr.l2_bdaddr);
      printf("accept %s\n", batostr(&clientBdAddr));

      l2capConnInfoLen = sizeof(l2capConnInfo);
      getsockopt(clientL2capSock, SOL_L2CAP, L2CAP_CONNINFO, &l2capConnInfo, &l2capConnInfoLen);
      hciHandle = l2capConnInfo.hci_handle;

      // force faster connection
      // This should be compatible with iOS requirements for LowLatency
      hci_le_conn_update2(hciSocket, hciHandle, 20, 40, 0, 5000);
      while(1) {
        FD_ZERO(&rfds);
        FD_SET(0, &rfds);
...

I haven't really got the time to test it, I will do later today. It would be cool if bleno would export this functionality to the top level to allow switching the latency depending on the state the peripheral is in. As OS X Corebluetooth API allows similar latency adjustments I would allow to be as specific as the linux API is to the top level of bleno and match it to the closest setting Corebluetooth offers. I think this would allow the biggest flexibility while offering only a single interface and as the latency changes are not guaranteed it is fine to adjust them on OS X to the closest possible one.

Indicate Support for Linux

I'm curious when support for the indicate property is scheduled for Linux. I have an application that requires this functionality so I was reading through the source code to see how to make it work. indicate is implemented on Mac already, and as far I can tell the following code block is all that was needed to make indicate work on OS X:

if (characteristic.properties.indexOf('indicate') !== -1) {
    if (characteristic.secure.indexOf('indicate') !== -1) {
        properties |= 0x200;
    } else {
        properties |= 0x20;
    }
}

When browsing through the Linux code, I found this block that looks very similar to the one above:

 if (characteristic.properties.indexOf('notify') !== -1) {
    properties |= 0x10;

    if (characteristic.secure.indexOf('notify') !== -1) {
        secure |= 0x10;
    }
}

If I added the following to l2cap-ble.js, is this all that is necessary to support Linux?

 if (characteristic.properties.indexOf('indicate') !== -1) {
    properties |= 0x200;

    if (characteristic.secure.indexOf('indicate') !== -1) {
        secure |= 0x20;
    }
}

And of course, there is always the possibility indicate support is already on the way. Does anybody know anything about this? I really could use it for some projects I'm working on.

If there is more to do, what is it? I could find few mentions of the word indicate in the repository, so I would guess that this would provide support, but I am very new to both Node and BLE and am not versed enough to know for sure. Thanks for taking the time to read this.

UUID and Local Name are persistent after stopAdvertising()

I am looking for a way to insure that my advertised data is no longer discoverable after I stop advertising. What I am seeing is that even if I kill the hci and l2cap daemons, the top-level UUID and Local name can be found by a scan.

The example only shows the use of stopAdvertising() if the device state is not "poweredOn". What is the proper way to end an advertisement session?

Keep getting this error

Hi,

I keep getting this error when I'm running the example code.

throw new Error('No blink(1)'s could be found');

Could you expand upon what blink(1) is.

The system I'm running this on is a raspberry pi with an IOGear Bluetooth 4.0 Dongle with BLE support.

Thanks

'index out of range' when central tries to unsubscribe

Hi,

I wrote a notifier service based on the given examples, but when noble is trying to unsubscribe from bleno's with this command:
characteristic.notify(false, notify._notifyDisable);

bleno is crashing with an 'index out of range'

buffer.js:604
    throw new RangeError('index out of range');
          ^
RangeError: index out of range
    at checkInt (buffer.js:604:11)

Peripheral:
Machine: Raspberry PI, Kernel 3.6.11+, Bluez 5.8, GBU521 Dongle
code: http://pastebin.com/bpUBihb5
console output: http://pastebin.com/2qwBY91p

Central:
Machine: Thinkpad T400s, Kernel 3.5.0-45-generic, Bluez 5.8, GBU521 Dongle
code: http://pastebin.com/Esa5xhvz
console output: http://pastebin.com/jZ81CgMM

any idea?
Thanks.

Wrong security checks in L2capBle.prototype.handleReadByTypeRequest?

Hi! I'm porting bleno to Go, so this will likely be the first of a few questions I have as I work through the code.

In L2capBle.prototype.handleReadByTypeRequest, around line 661, we find:

    if (secure && (this._security !== 'medium' && this._security !== 'high')) {
      response = this.errorResponse(ATT_OP_READ_BY_TYPE_REQ, startHandle, ATT_ECODE_AUTHENTICATION);
    } else ...

This check doesn't look right -- it asks for authentication only when this._security is not medium and not high. Should it be instead

    if (secure && this._security !== 'low') {

Services are not discoverable

Hello,

Thank you for your awesome project.
I'm struggling with an issue.

My developing environment is:

  • Raspberry pi (Raspbian) with kernel 3.10.24+ ( as peripheral )
  • IOGear Bluetooth dongle GBU521
  • iPhone 5 ( as Central )
  • node 0.10.24

I wrote a node.js test code with 2 services but these services are not discoverable like this screen shot :

img_5026

(pi-parkboo is my rpi's name)

I think my dongle works correctly because when I wrote a very simple BLE advertising code with C it works perfectly and BLE scanner can catch there are services.

My code snippet is : https://gist.github.com/parkboo/7277ccda610323a95027

Issue with more than four characteristics

Hi Sandeep,

I have an issue trying to simulate a peripheral with your tool.
I coded a unique service with five characteristics with notify and write properties. From an Android app, I enable notifications for every characteristics and then I simulate modifications by sending 'write' commands and catching notifications.
The problem is that after a variable amount of commands sent, bleno does not send back the 'write response' as before (but still send the notification), so Android waits until a timeout disconnects the device. If I disable a characteristic, so I now have four of them instead of five, I get no issue and everything works fine...
Is there any limitations in the number of characterstics that a service can have ?

Wardleth

Maximum Read Throughput?

Has anyone done any profiling on the maximum throughput for read commands? I have a 110-byte read-only characteristic that is taking me ~700 ms to read fully (long read) with an Android client. Since each read response can only contain 22 bytes or less, the 6 22-byte reads are taking place in the ~700 ms mentioned earlier, meaning each short read is taking ~100 ms.

I've tried seeing if different Android phones (Moto G, Moto E), Bluetooth dongles (IOGEAR, Pluggable, Mac), or operating systems (Linux, Mac) would change my results, but all combinations seem to offer the same read speeds. In Android, a readCharacteristic() is a single command that performs a long read of the Bluetooth characteristic passed as a parameter. That is, the readCharacteristic() Android API method is responsible for performing all 6 22-byte reads.

I am hoping to significantly increase my read speeds by at least 350%. I'm wondering whether the bottleneck is in the Android 4.4.+ code, a limitation of the Bleno library, or something else. Has anybody seen higher read rates?

In onReadRequest - offset=0 (22 bytes)
In onReadRequest - offset=22 (22 bytes)
In onReadRequest - offset=44 (22 bytes)
In onReadRequest - offset=66 (22 bytes)
In onReadRequest - offset=88 (22 bytes)
In onReadRequest - offset=110 (0 bytes)

Extended advertisement data

Hi! I'm working on a project which requires service data, manufacture data, and a 128-bit service ID. Unfortunately, the current advertisement data limit of 31 bytes isn't enough to encapsulate all this info. I was looking at your noble package, which supports "extended" advertisement data by waiting for every even number of events before reporting discovery. Would something similar be possible with bleno? I've been looking into hci-ble.js and hci-ble.c, but wondered if you've started working on or considered adding this functionality.

Thanks!

EPIPE Error

Hello,

I'm having an issue with my implementation, I know it very raw and need some work, or probably I'm doing everything wrong, I'm not really sure; however this is my code:

var bleno = require('bleno');

var name = 'Test';
var serviceUuids = ['fff0']

bleno.startAdvertising(name, serviceUuids);

var Characteristic = bleno.Characteristic;
var BlenoDescriptor = bleno.Descriptor;
var PrimaryService = bleno.PrimaryService;

var characteristic = new Characteristic({
    uuid: 'fff1',
    properties: [ 'read' ],
    value: new Buffer('48454c4c4f574f524c44','hex'), // optional static value, must be of type Buffer
    descriptors: [
        new BlenoDescriptor({
        uuid: 'fffffffffffffffffffffffffffffff2',
        value: 'Testing HW'
      })
    ]
});


var primaryService = new PrimaryService({
    uuid: 'fff0', // or 'fff0' for 16-bit
    characteristics: [characteristic]
});


bleno.setServices(primaryService);

When running I get this error

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: write EPIPE
    at errnoException (net.js:901:11)
    at Object.afterWrite (net.js:718:19)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.