Skip to content

Commit

Permalink
providing callbacks API
Browse files Browse the repository at this point in the history
  • Loading branch information
loicguillois committed Nov 8, 2016
1 parent 9402f35 commit 02e6a0c
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 117 deletions.
4 changes: 4 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
"use strict";

module.exports = {
GARMIN_ID: 0x0fcf,
GARMIN_STICK_2: 0x1008,
GARMIN_STICK_3: 0x1009,

MESSAGE_TX_SYNC: 0xA4,
DEFAULT_NETWORK_NUMBER: 0x00,

Expand Down
252 changes: 148 additions & 104 deletions src/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,129 +4,173 @@ var usb = require('usb');
var messages = require('./messages');
var constants = require('./constants');

const GARMIN_ID = 0x0fcf;
const GARMIN_STICK_2 = 0x1008;
const GARMIN_STICK_3 = 0x1009;

//usb.setDebugLevel(4);

var device = null;
var outEndpoint = null;

// TODO : affect real channel
var channel = 0;
var currentChannel = 0;

var write = function(buffer) {
outEndpoint.transfer(buffer, function(err) {
if(err) {
var callbacks = {};
var channelCounts = 0;
var channelTypes = [];

var write = function (buffer) {
outEndpoint.transfer(buffer, function (err) {
if (err) {
console.log(err);
}
})
}

module.exports = {
findAdapter: function () {
device = usb.findByIds(GARMIN_ID, GARMIN_STICK_3);
if (device === undefined) {
device = usb.findByIds(GARMIN_ID, GARMIN_STICK_2);
}
return device;
},

open: function () {
device.open();
let iface = device.interfaces[0];

if(iface.isKernelDriverActive()) {
iface.detachKernelDriver();
}
const types = {
FEC: 17,
HEART_RATE: 120,
CADENCE: 122,
};

var connect = function (deviceType, callback) {
let channel = channelCounts;
let deviceID = 0;
let period = null;
let deviceTypeId = null;
switch (deviceType) {
case 17:
period = 8182;
deviceTypeId = "FEC";
break;
case 120:
period = 8070;
deviceTypeId = "HEART_RATE";
break;
case 122:
period = 8086;
deviceTypeId = "CADENCE";
break;
default:
throw 'device type not supported';
}

iface.claim();
let InEndpoint = iface.endpoints[0];
outEndpoint = iface.endpoints[1];
// TODO: powermeter (need to test)
//var deviceType = 11;
//driver.attach(channel, 'receive', deviceID, deviceType, 5, 255, 8182, 57);

let oldCadenceCount = null;
let oldCadenceTime = null;
attach(channel, 'receive', deviceID, deviceType, 0, 255, period, 57);
callbacks[deviceTypeId] = callback;
channelTypes[channelCounts] = deviceType;
channelCounts++;
}

InEndpoint.on('data', (data) => {
if(data.readUInt8(constants.BUFFER_INDEX_CHANNEL_NUM) != channel) {
return;
}
var findAdapter = function () {
device = usb.findByIds(constants.GARMIN_ID, constants.GARMIN_STICK_3);
if (device === undefined) {
device = usb.findByIds(constants.GARMIN_ID, constants.GARMIN_STICK_2);
}
return device;
}

switch (data.readUInt8(constants.BUFFER_INDEX_MSG_TYPE)) {
case constants.MESSAGE_CHANNEL_BROADCAST_DATA:
case constants.MESSAGE_CHANNEL_ACKNOWLEDGED_DATA:
case constants.MESSAGE_CHANNEL_BURST_DATA:
// send ACK
//write(messages.requestMessage(channel, constants.MESSAGE_CHANNEL_ID));
var open = function () {
device.open();
let iface = device.interfaces[0];

// Get HeartRate
/*var hrmPayload = data.slice(constants.BUFFER_INDEX_MSG_DATA + 4);
var beatTime = hrmPayload.readUInt16LE(0);
var beatCount = hrmPayload.readUInt8(2);
var ComputedHeartRate = hrmPayload.readUInt8(3);
if (iface.isKernelDriverActive()) {
iface.detachKernelDriver();
}

console.log(beatTime, beatCount, ComputedHeartRate);*/
iface.claim();
let InEndpoint = iface.endpoints[0];
outEndpoint = iface.endpoints[1];

// Get cadence
/*let cadenceTime = data.readUInt8(constants.BUFFER_INDEX_MSG_DATA + 4);
cadenceTime |= data.readUInt8(constants.BUFFER_INDEX_MSG_DATA + 5) << 8;
let oldCadenceCount = null;
let oldCadenceTime = null;

let cadenceCount = data.readUInt8(constants.BUFFER_INDEX_MSG_DATA + 6);
cadenceCount |= data.readUInt8(constants.BUFFER_INDEX_MSG_DATA + 7) << 8;
InEndpoint.on('data', function (data) {
if (data.readUInt8(constants.BUFFER_INDEX_CHANNEL_NUM) != currentChannel) {
return;
}

if(oldCadenceCount != null) {
if(oldCadenceTime > cadenceTime) {
cadenceTime += (1024 * 64);
switch (data.readUInt8(constants.BUFFER_INDEX_MSG_TYPE)) {
case constants.MESSAGE_CHANNEL_BROADCAST_DATA:
case constants.MESSAGE_CHANNEL_ACKNOWLEDGED_DATA:
case constants.MESSAGE_CHANNEL_BURST_DATA:
// send ACK
write(messages.requestMessage(currentChannel, constants.MESSAGE_CHANNEL_ID));

switch (channelTypes[currentChannel]) {
case types.HEART_RATE:
let hrmPayload = data.slice(constants.BUFFER_INDEX_MSG_DATA + 4);
//var beatTime = hrmPayload.readUInt16LE(0);
//var beatCount = hrmPayload.readUInt8(2);
let computedHeartRate = hrmPayload.readUInt8(3);
callbacks['HEART_RATE'](computedHeartRate);
break;
case types.CADENCE:
let cadenceTime = data.readUInt8(constants.BUFFER_INDEX_MSG_DATA + 4);
cadenceTime |= data.readUInt8(constants.BUFFER_INDEX_MSG_DATA + 5) << 8;

let cadenceCount = data.readUInt8(constants.BUFFER_INDEX_MSG_DATA + 6);
cadenceCount |= data.readUInt8(constants.BUFFER_INDEX_MSG_DATA + 7) << 8;

if (oldCadenceCount != null) {
if (oldCadenceTime > cadenceTime) {
cadenceTime += (1024 * 64);
}
let diffCount = cadenceCount - oldCadenceCount;
let diffTime = cadenceTime - oldCadenceTime;
let rpm = 60 * diffCount / (diffTime / 1024);

if (rpm) {
callbacks['CADENCE'](rpm);
}
}
let diffCount = cadenceCount - oldCadenceCount;
let diffTime = cadenceTime - oldCadenceTime;
let rpm = 60 * diffCount / (diffTime / 1024);

if(rpm) {
console.log(rpm);
oldCadenceCount = cadenceCount;
oldCadenceTime = cadenceTime;
break;
case types.FEC:
var fecPayload = data.slice(constants.BUFFER_INDEX_MSG_DATA);
// Specific Trainer Data
if (fecPayload.readUInt8(0) === 0x19) {
let cadence = fecPayload.readUInt8(2);
let power = fecPayload.readUInt16LE(5);
callbacks['FEC'](cadence, power);
}
}
oldCadenceCount = cadenceCount;
oldCadenceTime = cadenceTime;*/


var fecPayload = data.slice(constants.BUFFER_INDEX_MSG_DATA);
// Specific Trainer Data
if(fecPayload.readUInt8(0) === 0x19) {
let cadence = fecPayload.readUInt8(2);
let power = fecPayload.readUInt16LE(5);
console.log(cadence + "rpm at " + power + "watts")
}
break;
case constants.MESSAGE_CHANNEL_ID:
break;
default:
break;
}
})

InEndpoint.on('error', (e) => {
console.log("error=" + e);
})

InEndpoint.on('end', () => {
console.log("STOP RECIEVING");
})

InEndpoint.startPoll();
},

attach: function (channel, type, deviceID, deviceType, transmissionType, timeout, period, frequency) {
write(messages.resetSystem());
write(messages.requestMessage(channel));
write(messages.setNetworkKey());
write(messages.assignChannel(channel, type));
write(messages.setDevice(channel, deviceID, deviceType, transmissionType));
write(messages.searchChannel(channel, timeout));
write(messages.setPeriod(channel, period));
write(messages.setFrequency(channel, frequency));
write(messages.openChannel(channel));
}
break;
}
break;
case constants.MESSAGE_CHANNEL_ID:
break;
default:
break;
}
})

InEndpoint.on('error', (e) => {
console.log("error=" + e);
})

InEndpoint.on('end', () => {
console.log("STOP RECIEVING");
})

InEndpoint.startPoll();
}

var attach = function (channel, type, deviceID, deviceType, transmissionType, timeout, period, frequency) {
currentChannel = channel;
write(messages.resetSystem());
write(messages.requestMessage(channel));
write(messages.setNetworkKey());
write(messages.assignChannel(channel, type));
write(messages.setDevice(channel, deviceID, deviceType, transmissionType));
write(messages.searchChannel(channel, timeout));
write(messages.setPeriod(channel, period));
write(messages.setFrequency(channel, frequency));
write(messages.openChannel(channel));
}

module.exports = {
types: types,
connect: connect,
findAdapter: findAdapter,
open: open,
attach: attach
}
22 changes: 9 additions & 13 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,17 @@ if(device != undefined) {
var channel = 0;
var deviceID = 0;

// powermeter
//var deviceType = 11;
//driver.attach(channel, 'receive', deviceID, deviceType, 5, 255, 8182, 57);
/*driver.connect(driver.types.HEART_RATE, function(heartRate) {
console.log(heartRate + "bpm")
});*/

// heart : OK
//let deviceType = 120;
//driver.attach(channel, 'receive', deviceID, deviceType, 0, 255, 8070, 57);
driver.connect(driver.types.CADENCE, function(cadence) {
console.log(cadence + "rpm")
});

// cadence : OK TODO test with 8102 as frequency
//let deviceType = 122;
//driver.attach(channel, 'receive', deviceID, deviceType, 0, 255, 8086, 57);

// FE-C
var deviceType = 17;
driver.attach(channel, 'receive', deviceID, deviceType, 0, 255, 8182, 57);
/*driver.connect(driver.types.FEC, function(cadence, power) {
console.log(cadence + "rpm at " + power + "watts");
});*/
} else {
console.log("USB ANT+ ADAPTER NOT FOUND !");
}

0 comments on commit 02e6a0c

Please sign in to comment.