Skip to content

Commit

Permalink
Merge pull request #84 from aj-ptw/dropped-packet-alert
Browse files Browse the repository at this point in the history
Add dropped packet detection
  • Loading branch information
AJ Keller authored Sep 29, 2016
2 parents 094e328 + 2c0b2e3 commit 3c46100
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 7 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1040,13 +1040,17 @@ ourBoard.write('o');
Emitted when the serial connection to the board is closed.
### <a name="event-close"></a> .on('droppedPacket', callback)
Emitted when a packet (or packets) are dropped. Returns an array.
### <a name="event-error"></a> .on('error', callback)
Emitted when there is an on the serial port.
### <a name="event-impedance-array"></a> .on('impedanceArray', callback)
Emitted when there is a new impedanceArray available.
Emitted when there is a new impedanceArray available. Returns an array.
### <a name="event-query"></a> .on('query', callback)
Expand Down
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 1.3.0

### New Features

* Add dropped packet detection, new event `droppedPacket` can be added to get an array of dropped packet numbers in the case of the dropped packet event.

# 1.2.3

### Enhancements
Expand Down
8 changes: 7 additions & 1 deletion openBCIBoard.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,10 @@ function OpenBCIFactory() {
this.curParsingMode = k.OBCIParsingReset;
this.commandsToWrite = 0;
this.impedanceArray = openBCISample.impedanceArray(k.numberOfChannelsForBoardType(this.options.boardType));
this.writeOutDelay = k.OBCIWriteIntervalDelayMSShort;
this.previousSampleNumber = -1;
this.sampleCount = 0;
this.timeOfPacketArrival = 0;
this.writeOutDelay = k.OBCIWriteIntervalDelayMSShort;
// Strings

// NTP
Expand Down Expand Up @@ -1735,6 +1736,11 @@ function OpenBCIFactory() {
OpenBCIBoard.prototype._processQualifiedPacket = function(rawDataPacketBuffer) {
if (!rawDataPacketBuffer) return;
if (rawDataPacketBuffer.byteLength !== k.OBCIPacketSize) return;
var missedPacketArray = openBCISample.droppedPacketCheck(this.previousSampleNumber, rawDataPacketBuffer[k.OBCIPacketPositionSampleNumber]);
if (missedPacketArray) {
this.emit('droppedPacket', missedPacketArray);
}
this.previousSampleNumber = rawDataPacketBuffer[k.OBCIPacketPositionSampleNumber];
var packetType = openBCISample.getRawPacketType(rawDataPacketBuffer[k.OBCIPacketPositionStopByte]);
switch (packetType) {
case k.OBCIStreamPacketStandardAccel:
Expand Down
5 changes: 5 additions & 0 deletions openBCIConstants.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ const OBCISimulatorLineNoiseNone = 'None';
const OBCISampleRate125 = 125;
const OBCISampleRate250 = 250;

/** Max sample number */
const OBCISampleNumberMax = 255;

/** Packet Size */
const OBCIPacketSize = 33;

Expand Down Expand Up @@ -729,6 +732,8 @@ module.exports = {
/** Possible Sample Rates */
OBCISampleRate125,
OBCISampleRate250,
/** Max sample number */
OBCISampleNumberMax,
/** Packet Size */
OBCIPacketSize,
/** Notable Bytes */
Expand Down
37 changes: 36 additions & 1 deletion openBCISample.js
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,42 @@ var sampleModule = {
isTimeSyncSetConfirmationInBuffer,
makeTailByteFromPacketType,
isStopByte,
newSyncObject
newSyncObject,
/**
* @description Checks to make sure the previous sample number is one less
* then the new sample number. Takes into account sample numbers wrapping
* around at 255.
* @param `previousSampleNumber` {Number} - An integer number of the previous
* sample number.
* @param `newSampleNumber` {Number} - An integer number of the new sample
* number.
* @returns {Array} - Returns null if there is no dropped packets, otherwise,
* or on a missed packet, an array of their packet numbers is returned.
*/
droppedPacketCheck: (previousSampleNumber, newSampleNumber) => {
if (previousSampleNumber === k.OBCISampleNumberMax && newSampleNumber === 0) {
return null;
}

if (newSampleNumber - previousSampleNumber === 1) {
return null;
}

var missedPacketArray = [];

if (previousSampleNumber > newSampleNumber) {
var numMised = k.OBCISampleNumberMax - previousSampleNumber;
for (var i = 0; i < numMised; i++) {
missedPacketArray.push(previousSampleNumber + i + 1);
}
previousSampleNumber = -1;
}

for (var i = 1; i < (newSampleNumber - previousSampleNumber); i++) {
missedPacketArray.push(previousSampleNumber + i);
}
return missedPacketArray;
}
};

module.exports = sampleModule;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openbci",
"version": "1.2.3",
"version": "1.3.0",
"description": "The official Node.js SDK for the OpenBCI Biosensor Board.",
"main": "openBCIBoard",
"scripts": {
Expand Down
5 changes: 5 additions & 0 deletions test/OpenBCIConstants-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,11 @@ describe('OpenBCIConstants', function() {
assert.equal(250, k.OBCISampleRate250);
});
});
describe('Max sample number',function() {
it('should be 255',function () {
assert.equal(255, k.OBCISampleNumberMax);
});
});
describe("Radio Channel Limits", function() {
it("should get the right channel number max",function () {
expect(k.OBCIRadioChannelMax).to.be.equal(25);
Expand Down
40 changes: 37 additions & 3 deletions test/OpenBCISample-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ var assert = require('assert');
var openBCISample = require('../openBCISample');
var sinon = require('sinon');
var chai = require('chai'),
expect = chai.expect,
should = chai.should(),
expect = chai.expect;
expect = chai.expect,
assert = chai.assert;

var chaiAsPromised = require("chai-as-promised");
var sinonChai = require("sinon-chai");
Expand Down Expand Up @@ -1373,7 +1373,41 @@ describe('openBCISample',function() {
it("should have property boardTime",function() {
expect(syncObj).to.have.property("boardTime",0);
});
})
});
describe('#droppedPacketCheck',function() {
it("should return an array of missed packet numbers",function() {
previous = 0;
current = previous + 2;
assert.sameMembers(openBCISample.droppedPacketCheck(previous, current), [1], "dropped one packet");

previous = 0;
current = previous + 4;
assert.sameMembers(openBCISample.droppedPacketCheck(previous, current), [1,2,3], "dropped three packets");

previous = 255;
current = 2;
assert.sameMembers(openBCISample.droppedPacketCheck(previous, current), [0,1], "dropped two packets on wrap edge!");

previous = 254;
current = 2;
assert.sameMembers(openBCISample.droppedPacketCheck(previous, current), [255,0,1], "dropped three packets on wrap!");

previous = 250;
current = 1;
assert.sameMembers(openBCISample.droppedPacketCheck(previous, current), [251,252,253,254,255,0], "dropped a bunch of packets on wrap!");

});
it("should roll over when 255 was previous and current is 0", function() {
previous = 255;
current = 0;
expect(openBCISample.droppedPacketCheck(previous, current)).to.be.null;
});
it("should return null when previous is one less then new sample number", function() {
previous = 0;
current = previous + 1;
expect(openBCISample.droppedPacketCheck(previous, current)).to.be.null;
});
});
});


Expand Down
33 changes: 33 additions & 0 deletions test/openBCIBoard-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,39 @@ describe('openbci-sdk',function() {
funcSpyTimeSyncedAccel.should.not.have.been.called;
funcSpyTimeSyncedRawAux.should.not.have.been.called;
});
it("should emit a dropped packet on dropped packet",function(done) {
// Set to default state
ourBoard.previousSampleNumber = -1;
var sampleNumber0 = openBCISample.samplePacket(0);
ourBoard.once('droppedPacket',() => {
done();
});
var sampleNumber2 = openBCISample.samplePacket(2);
// Call the function under test
ourBoard._processDataBuffer(sampleNumber0);
ourBoard._processDataBuffer(sampleNumber2);
});
it("should emit a dropped packet on dropped packet with edge",function(done) {
// Set to default state
var count = 0;
ourBoard.previousSampleNumber = 253;
var buf1 = openBCISample.samplePacket(254);
var countFunc = arr => {
count++;
};
ourBoard.on('droppedPacket', countFunc);
var buf2 = openBCISample.samplePacket(0);
var buf3 = openBCISample.samplePacket(1);
// Call the function under test
ourBoard._processDataBuffer(buf1);
ourBoard._processDataBuffer(buf2);
ourBoard._processDataBuffer(buf3);
setTimeout(() => {
ourBoard.removeListener('droppedPacket', countFunc);
expect(count).to.equal(1);
done();
}, 10)
});
});

describe("#_processPacketTimeSyncSet", function() {
Expand Down

0 comments on commit 3c46100

Please sign in to comment.