Skip to content

Instantly share code, notes, and snippets.

@mrodem
Created November 22, 2017 10:12
Show Gist options
  • Save mrodem/2fa5fabf47f6e8ac20a98f80d6a8aa83 to your computer and use it in GitHub Desktop.
Save mrodem/2fa5fabf47f6e8ac20a98f80d6a8aa83 to your computer and use it in GitHub Desktop.
'use strict';
const { AdapterFactory, ServiceFactory } = require('pc-ble-driver-js');
const adapterFactory = AdapterFactory.getInstance();
const serviceFactory = new ServiceFactory();
let heartRateService;
let heartRateMeasurementCharacteristic;
const BLE_UUID_HEART_RATE_SERVICE = '180d';
const BLE_UUID_HEART_RATE_MEASUREMENT_CHAR = '2a37';
const BLE_UUID_CCCD = '2902';
function addAdapterListener(adapter, prefix) {
adapter.on('logMessage', (severity, message) => { console.log(`${prefix} logMessage: ${message}`); });
adapter.on('status', status => { console.log(`${prefix} status: ${JSON.stringify(status, null, 1)}`); });
adapter.on('error', error => { console.log(`${prefix} error: ${JSON.stringify(error, null, 1)}`); });
adapter.on('deviceConnected', device => { console.log(`${prefix} deviceConnected: ${device.address}`); });
adapter.on('deviceDisconnected', device => { console.log(`${prefix} deviceDisconnected: ${JSON.stringify(device, null, 1)}`); });
adapter.on('deviceDiscovered', device => { console.log(`${prefix} deviceDiscovered: ${JSON.stringify(device)}`); });
}
function characteristicsInit() {
const charValue = new Array(250);
heartRateMeasurementCharacteristic = serviceFactory.createCharacteristic(
heartRateService,
BLE_UUID_HEART_RATE_MEASUREMENT_CHAR,
charValue,
{
broadcast: false,
read: true,
write: true,
writeWoResp: false,
reliableWrite: false,
notify: true,
indicate: false,
},
{
maxLength: charValue.length,
readPerm: ['open'],
writePerm: ['open'],
});
serviceFactory.createDescriptor(
heartRateMeasurementCharacteristic,
BLE_UUID_CCCD,
[0, 0],
{
maxLength: 2,
readPerm: ['open'],
writePerm: ['open'],
variableLength: false,
});
}
function servicesInit(adapter) {
return new Promise((resolve, reject) => {
console.log('Initializing the heart rate service and its characteristics/descriptors...');
heartRateService = serviceFactory.createService(BLE_UUID_HEART_RATE_SERVICE);
characteristicsInit();
adapter.setServices([heartRateService], err => {
if (err) {
return reject(Error(`Error initializing services: ${JSON.stringify(err, null, 1)}'.`));
}
return resolve();
});
});
}
function setupAdapter(adapter) {
return new Promise((resolve, reject) => {
adapter.open(
{
baudRate: 1000000,
parity: 'none',
flowControl: 'none',
enableBLE: false,
eventInterval: 0,
logLevel: 'trace',
},
openErr => {
if (openErr) {
reject(openErr);
} else {
adapter.enableBLE(null, enableErr => {
if (enableErr) {
reject(openErr);
} else {
resolve();
}
});
}
});
});
}
function startAdvertising(adapter) {
return new Promise((resolve, reject) =>
adapter.setAdvertisingData(
{
txPowerLevel: 20,
},
{}, // scan response data
advDataErr => {
if (advDataErr) {
return reject(advDataErr);
}
return resolve();
}))
.then(() =>
new Promise((resolve, reject) => {
adapter.startAdvertising(
{
interval: 100,
timeout: 100,
},
startAdvErr => {
if (startAdvErr) {
return reject(startAdvErr);
}
return resolve();
});
}));
}
function onConnected(adapter, device) {
return new Promise((resolve, reject) => {
const mtu = 247;
adapter.requestAttMtu(device.instanceId, mtu, (err, newMtu) => {
if (err) {
return reject(err);
}
console.log(`ATT_MTU is ${newMtu}`);
return resolve();
});
});
}
adapterFactory.getAdapters((error, adapters) => {
const adapter = adapters[Object.keys(adapters)[0]];
addAdapterListener(adapter, '#PERIPH');
setupAdapter(adapter)
.then(() => servicesInit(adapter))
.then(() => startAdvertising(adapter))
.then(() => {
adapter.once('deviceConnected', device => {
onConnected(adapter, device);
});
adapter.once('attMtuChanged', (device, attMtu) => {
console.log(`ATT MTU changed to ${attMtu}`);
});
})
.catch(err => {
console.log(`Error: ${err}`);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment