Skip to content

Instantly share code, notes, and snippets.

@jhays
Created October 17, 2019 19:05
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save jhays/7f5a5dc37e683b8ddc8aa72614df5a05 to your computer and use it in GitHub Desktop.
A sample BLE peripheral service and characteristic for use with Node.js and bleno.
/* characteristic.js
* A simple custom BLE peripheral characteristic for use with Node.js and bleno.
* This characteristic supports read, write, and notify properties.
* Julian Hays - 10/14/19
*/
var util = require('util');
var bleno = require('bleno-mac'); //or 'bleno-mac' if you are using that
var BlenoCharacteristic = bleno.Characteristic;
var CustomCharacteristic = function() {
CustomCharacteristic.super_.call(this, {
uuid: 'fd758b93-0bfa-4c52-8af0-85845a74a606',
properties: ['read', 'write', 'notify']
});
this._value = new Buffer(0);
this._updateValueCallback = null;
};
util.inherits(CustomCharacteristic, BlenoCharacteristic);
module.exports = CustomCharacteristic;
CustomCharacteristic.prototype.onReadRequest = function (offset, callback) {
console.log('CustomCharacteristic onReadRequest');
var data = new Buffer(1);
data.writeUInt8(42, 0);
callback(this.RESULT_SUCCESS, data);
};
CustomCharacteristic.prototype.onWriteRequest = function(data, offset, withoutResponse, callback) {
this._value = data;
console.log('CustomCharacteristic - onWriteRequest: value = ' + this._value.toString('hex'));
callback(this.RESULT_SUCCESS);
};
var isSubscribed = false
var notifyInterval = 5 //seconds
function delayedNotification(callback) {
setTimeout(function() {
if (isSubscribed) {
var data = Buffer(3);
var now = new Date();
data.writeUInt8(now.getHours(), 0);
data.writeUInt8(now.getMinutes(), 1);
data.writeUInt8(now.getSeconds(), 2);
callback(data);
delayedNotification(callback);
}
}, notifyInterval * 1000);
}
CustomCharacteristic.prototype.onSubscribe = function(maxValueSize, updateValueCallback) {
console.log('CustomCharacteristic - onSubscribe');
isSubscribed = true;
delayedNotification(updateValueCallback);
this._updateValueCallback = updateValueCallback;
};
CustomCharacteristic.prototype.onUnsubscribe = function() {
console.log('CustomCharacteristic - onUnsubscribe');
isSubscribed = false;
this._updateValueCallback = null;
};
/* service.js
* A simple custom BLE peripheral service for use with Node.js and bleno.
* Julian Hays - 10/14/19
*/
var bleno = require('bleno-mac') ;
var BlenoPrimaryService = bleno.PrimaryService;
bleno.on('stateChange', function(state) {
console.log('on -> stateChange: ' + state);
if (state === 'poweredOn') {
console.log("request startAdvertising");
bleno.startAdvertising('CustomService', ['27cf08c1-076a-41af-becd-02ed6f6109b9']);
} else {
console.log("request stopAdvertising");
bleno.stopAdvertising();
}
});
var CustomCharacteristic = require('./characteristic');
bleno.on('advertisingStart', function(error) {
console.log('on -> advertisingStart: ' + (error ? 'error ' + error : 'success'));
if (!error) {
bleno.setServices([
new BlenoPrimaryService({
uuid: '27cf08c1-076a-41af-becd-02ed6f6109b9',
characteristics: [
new CustomCharacteristic()
]
})
]);
}
});
@jhays
Copy link
Author

jhays commented Dec 17, 2019

A step-by-step tutorial on this code is available on the Punch Through blog:
https://punchthrough.com/how-to-use-node-js-to-speed-up-ble-app-development/

@beegee-tokyo
Copy link

Is there any update required. I tried the codes and fail with the error Error: Cannot find module 'bluetooth-hci-socket'

B:\Projects\Bleno>node service.js
internal/modules/cjs/loader.js:960
  throw err;
  ^

Error: Cannot find module 'bluetooth-hci-socket'
Require stack:
- B:\Projects\Bleno\node_modules\bleno\lib\hci-socket\mgmt.js
- B:\Projects\Bleno\node_modules\bleno\lib\hci-socket\smp.js
- B:\Projects\Bleno\node_modules\bleno\lib\hci-socket\acl-stream.js
- B:\Projects\Bleno\node_modules\bleno\lib\hci-socket\bindings.js
- B:\Projects\Bleno\node_modules\bleno\lib\bleno.js
- B:\Projects\Bleno\node_modules\bleno\index.js
- B:\Projects\Bleno\service.js
←[90m    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:957
:15)←[39m
←[90m    at Function.Module._load (internal/modules/cjs/loader.js:840:27)←[39m
←[90m    at Module.require (internal/modules/cjs/loader.js:1019:19)←[39m
←[90m    at require (internal/modules/cjs/helpers.js:77:18)←[39m
    at Object.<anonymous> (B:\Projects\Bleno\node_modules\←[4mbleno←[24m\lib\hci
-socket\mgmt.js:6:26)
←[90m    at Module._compile (internal/modules/cjs/loader.js:1133:30)←[39m
←[90m    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:1
0)←[39m
←[90m    at Module.load (internal/modules/cjs/loader.js:977:32)←[39m
←[90m    at Function.Module._load (internal/modules/cjs/loader.js:877:14)←[39m
←[90m    at Module.require (internal/modules/cjs/loader.js:1019:19)←[39m {
  code: ←[32m'MODULE_NOT_FOUND'←[39m,
  requireStack: [
    ←[32m'B:\\Projects\\Bleno\\node_modules\\bleno\\lib\\hci-socket\\mgmt.js'←[3
9m,
    ←[32m'B:\\Projects\\Bleno\\node_modules\\bleno\\lib\\hci-socket\\smp.js'←[39
m,
    ←[32m'B:\\Projects\\Bleno\\node_modules\\bleno\\lib\\hci-socket\\acl-stream.
js'←[39m,
    ←[32m'B:\\Projects\\Bleno\\node_modules\\bleno\\lib\\hci-socket\\bindings.js
'←[39m,
    ←[32m'B:\\Projects\\Bleno\\node_modules\\bleno\\lib\\bleno.js'←[39m,
    ←[32m'B:\\Projects\\Bleno\\node_modules\\bleno\\index.js'←[39m,
    ←[32m'B:\\Projects\\Bleno\\service.js'←[39m
  ]
}```

@jhays
Copy link
Author

jhays commented May 12, 2020

Hello- what OS are you attempting this on?

Have you tried installing the bluetooth-hci-socket package?

npm install bluetooth-hci-socket

@beegee-tokyo
Copy link

I tried on Windows 7.
npm install bluetooth-hci-socket fails with some error messages. Have no access to the log right now. Maybe tomorrow.

But I am about to give up on mocking a BLE device on Windows now. Found a way with my own code to mock it on Android.

But thanks for the quick reply.

@jhays
Copy link
Author

jhays commented May 12, 2020

Glad you found another solution. If you give it another try on Windows, perhaps this thread will help:

noble/node-bluetooth-hci-socket#35

@mhkasif
Copy link

mhkasif commented Sep 20, 2020

hey
unable to run on catalina.
stateChange event doesn't call.
and it stuck at bleno-echo example .

@edwardbc
Copy link

edwardbc commented Oct 12, 2020

To run on a newer macOS you need bleno-mac and some specific package branches.

Try this on your package.json

  "dependencies": {
    "bleno": "github:notjosh/bleno#inject-bindings",
    "bleno-mac": "github:notjosh/bleno-mac",
    "xpc-connection": "sandeepmistry/node-xpc-connection#pull/26/head"
  },
  "resolutions": {
    "xpc-connection": "sandeepmistry/node-xpc-connection#pull/26/head"
  }

Then import bleno-mac as bleno

@waghekapil
Copy link

Thanks for sharing the code and guide link.
Your code and step-by-step guide is very well explained.

A step-by-step tutorial on this code is available on the Punch Through blog:
https://punchthrough.com/how-to-use-node-js-to-speed-up-ble-app-development/

How can we show multiple characteristics? Adding new is not working (see below code example)

characteristics: [ new CustomCharacteristic(), new NewCustomCharacteristic(), // Add new here ]

help me to add multiple services and/or characteristics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment