Skip to content

Instantly share code, notes, and snippets.

@johnnyman727
Created November 19, 2014 22:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnnyman727/63419a0906fc3304273e to your computer and use it in GitHub Desktop.
Save johnnyman727/63419a0906fc3304273e to your computer and use it in GitHub Desktop.
Using two BLE modules, have a master BLE repeatedly scan, connect, and disconnect from a BLE acting as an iBeacon
var tessel = require('tessel'),
bleLib = require('ble-ble113a');
function iBeaconStart(tesselPort){
var uuid = 'D1CF12135FA04B2E9AC32109440633DB', // Apple's example UUID
major = 111,
minor = 111,
blePort = tessel.port[tesselPort];
var iBeacon = bleLib.use(blePort, function(err) {
if (err) return console.log("Error connecting to slave", err);
iBeacon.setAdvertisingData(createIBeaconAdvertisementPacket(major, minor), function (e2){
if (e2) console.log("Error setting advertisement packet", e2);
// start adveristing to any listening masters
iBeacon.startAdvertising(function(e3) {
if (e3) return console.log("Err starting to advertise", e3);
tessel.led[1].output(1);
console.log('waiting to be discovered...');
});
});
});
iBeacon.on('disconnect', function() {
iBeacon.startAdvertising(function(e4) {
console.log('started advertising after disconnect');
})
})
// Major is usually meant to differentiate discrete locations (store A, store B)
// Minor is meant to differentiate microlocations within a discrete location (corners of a store)
function createIBeaconAdvertisementPacket(major, minor, peripheral) {
// LE General Discovery, Single Mode Device
var flags = new Buffer([0x02, 0x01, 0x06]);
// Manufacturer data
var manufacturerData = new Buffer([0x1a, 0xff]);
// Preamble
var preamble = new Buffer([0x4c, 0x00, 0x02, 0x15]);
// // Apple AirLocate Service UUID
// var airLocate = new Buffer([0xe2, 0xc5, 0x6d, 0xb5, 0xdf, 0xfb, 0x48, 0xd2, 0xb0, 0x60, 0xd0, 0xf5, 0xa7, 0x10, 0x96, 0xe0]);
// Altitude UUID
var altitude = new Buffer(uuid, 'hex')
var majorBuf = new Buffer(2);
majorBuf.writeUInt16BE(major, 0);
var minorBuf = new Buffer(2);
minorBuf.writeUInt16BE(minor, 0);
// Measured signal strength
var signalStrength = 0xc6
if (peripheral) {
signalStrength = peripheral.rssi;
}
return Buffer.concat([flags, manufacturerData, preamble, altitude, majorBuf, minorBuf, new Buffer([signalStrength])]);
}
}
function deviceScanStart(tesselPort) {
var blePort = tessel.port[tesselPort];
var scanner = bleLib.use(blePort),
ledTimeout,
discoverPool = [],
poolRunning = false;
scanner.on('ready', function(err) {
console.log('Scanning...');
scanner.startScanning({
allowDuplicates: true
});
});
scanner.on('discover', function(peripheral) {
if (ledTimeout) clearTimeout(ledTimeout);
tessel.led[0].output(1);
ledTimeout = setTimeout(function(){ tessel.led[0].output(0); }, 50);
console.log("Discovered peripheral!", peripheral.toString());
peripheral.connect(function (err) {
if (err) console.log("ERROR connect:", err);
});
});
scanner.on('connect', function(peripheral){
console.log('managed to connect!');
// timeout to disconnect
setTimeout(function(){
scanner.disconnect(peripheral, function (err) {
if (err) console.log("ERROR disconnect:", err);
else console.log('managed to disconnect!');
scanner.startScanning(function(err) {
if (err) throw err;
console.log("Started scanning again ")
});
});
}, 1000);
scanner.discoverAllServices(peripheral, function (error, services) {
if (error){
console.log('Service discovery error',error);
}
console.log(services.toString());
});
});
scanner.on('servicesDiscover', function(services){
console.log('got services!', services.toString());
});
}
iBeaconStart('A');
deviceScanStart('B');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment