Skip to content

Commit

Permalink
Fixes openbci-archive#142 openbci-archive#144 graceful termination an…
Browse files Browse the repository at this point in the history
…d v2 firmware reject
  • Loading branch information
AJ Keller committed Mar 25, 2017
1 parent a552248 commit 5187f94
Show file tree
Hide file tree
Showing 11 changed files with 409 additions and 102 deletions.
19 changes: 7 additions & 12 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
language: node_js
node_js:
- "4.0"
- "4.1"
- "4.2"
- "4.3"
- "4.4"
- "4.5"
- "4.6"
- "5.11.0"
- "6.0"
- "6.1"
- "6.2"
- "6.3"
- "6.4"
- "6.5"
- "6.6"
- "6.7"
- "6.8"
- "4.7"
- "4.8"
- "5.12.0"
- "6.9"
- "6.10"
- "7.3"
- "7.7"
install:
- npm install --all
script:
Expand Down
28 changes: 27 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
# 1.6.0

### New Features
* Add note about serialport node error (thanks @octopicorn)
* Closes #142 - Graceful termination

### Breaking changes
* Connect rejects when radio system is down on firmware version 2 see #144
* Module drops all attached event emitters on disconnect see #144

### Bug Fixes
* Fixes #144 - v2 firmware succeeds when no board attached

### Dependency Package Updates
* `performance-now`: from `^0.2.0` to `2.1.0`
* `serialport` - from `4.0.1` to `4.0.7`

### Development Dependency Package Updates
* `bluebird`: from `3.4.6` to `3.5.0`
* `chai-as-promised`: from `^5.2.0` to `^6.0.0`
* `codecov`: from `^1.0.1` to `^2.1.0`
* `semistandard`: from `^9.0.0` to `^10.0.0`
* `sinon`: from `^1.17.2` to `^2.1.0`
* `snazzy`: from `^5.0.0` to `^6.0.0`


# 1.5.1

### New Features
Expand All @@ -7,7 +33,7 @@
* Removed `impedanceCalculationForChannel()` and `impedanceCalculationForAllChannels` from `OpenBCISample.js`

### Bug Fixes
* Fixes #28- Impedance not working properly.
* Fixes #28 - Impedance not working properly.

# 1.5.0

Expand Down
10 changes: 10 additions & 0 deletions openBCIBoard.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function OpenBCIFactory () {
var _options = {
boardType: [k.OBCIBoardDefault, k.OBCIBoardDaisy, k.OBCIBoardGanglion],
baudRate: 115200,
commsDownDetection: true,
hardSet: false,
simulate: false,
simulatorBoardFailure: false,
Expand Down Expand Up @@ -338,6 +339,8 @@ function OpenBCIFactory () {

this.emit('close');

this.removeAllListeners();

while (this.writeOutArray.length > 0) {
var command = this.writeOutArray.pop();
if (command.reject) command.reject(err);
Expand Down Expand Up @@ -1799,6 +1802,13 @@ function OpenBCIFactory () {
data = Buffer.concat([this.buffer, data], data.length + this.buffer.length);
}

if (this.options.commsDownDetection) {
if (openBCISample.isCommsSystemDown(data)) {
if (this.options.verbose) console.log(k.OBCIErrorRadioSystemDown);
this.emit(k.OBCIEmitterError, new Error(k.OBCIErrorRadioSystemDown));
}
}

switch (this.curParsingMode) {
case k.OBCIParsingEOT:
if (openBCISample.doesBufferHaveEOT(data)) {
Expand Down
4 changes: 4 additions & 0 deletions openBCIConstants.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ const obciByteStop = 0xC0;
const errorInvalidByteLength = 'Invalid Packet Byte Length';
const errorInvalidByteStart = 'Invalid Start Byte';
const errorInvalidByteStop = 'Invalid Stop Byte';
const errorRadioSystemDown = 'Failure: Communications timeout - Device failed to poll Host';
const errorTimeSyncIsNull = "'this.sync.curSyncObj' must not be null";
const errorTimeSyncNoComma = 'Missed the time sync sent confirmation. Try sync again';
const errorUndefinedOrNullInput = 'Undefined or Null Input';
Expand Down Expand Up @@ -339,6 +340,7 @@ const obciRadioBaudRateFastStr = 'fast';

/** Emitters */
const obciEmitterClose = 'close';
const obciEmitterCommsDown = 'commsDown';
const obciEmitterDroppedPacket = 'droppedPacket';
const obciEmitterEot = 'eot';
const obciEmitterError = 'error';
Expand Down Expand Up @@ -773,6 +775,7 @@ module.exports = {
OBCIErrorInvalidByteLength: errorInvalidByteLength,
OBCIErrorInvalidByteStart: errorInvalidByteStart,
OBCIErrorInvalidByteStop: errorInvalidByteStop,
OBCIErrorRadioSystemDown: errorRadioSystemDown,
OBCIErrorTimeSyncIsNull: errorTimeSyncIsNull,
OBCIErrorTimeSyncNoComma: errorTimeSyncNoComma,
OBCIErrorUndefinedOrNullInput: errorUndefinedOrNullInput,
Expand Down Expand Up @@ -905,6 +908,7 @@ module.exports = {
getVersionNumber,
/** Emitters */
OBCIEmitterClose: obciEmitterClose,
OBCIEmitterCommsDown: obciEmitterCommsDown,
OBCIEmitterDroppedPacket: obciEmitterDroppedPacket,
OBCIEmitterEot: obciEmitterEot,
OBCIEmitterError: obciEmitterError,
Expand Down
39 changes: 39 additions & 0 deletions openBCISample.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,13 @@ var sampleModule = {
doesBufferHaveEOT,
findV2Firmware,
isFailureInBuffer,
isCommsSystemDown,
isSuccessInBuffer,
isTimeSyncSetConfirmationInBuffer,
makeTailByteFromPacketType,
isStopByte,
newSyncObject,
stripAfterEOTBuffer,
stripToEOTBuffer,
/**
* @description Checks to make sure the previous sample number is one less
Expand Down Expand Up @@ -1031,6 +1033,43 @@ function isSuccessInBuffer (dataBuffer) {
return s.matches >= 1;
}

/**
* @description Used to slice a buffer for the EOT '$$$'.
* @param dataBuffer {Buffer} - The buffer of some length to parse
* @returns {Boolean} - If equal to radio system down message.
*/
function isCommsSystemDown(dataBuffer) {
if (k.isNull(dataBuffer)) return false;
dataBuffer = stripAfterEOTBuffer(dataBuffer);
return dataBuffer.toString() === `${k.OBCIErrorRadioSystemDown}${k.OBCIParseEOT}`;
}

/**
* @description Used to slice anything after EOT '$$$'.
* @param dataBuffer {Buffer} - The buffer of some length to parse
* @returns {Buffer} - The buffer to EOT.
*/
function stripAfterEOTBuffer (dataBuffer) {
if (k.isNull(dataBuffer)) return null;
let indexOfEOT = dataBuffer.indexOf(k.OBCIParseEOT);
if (indexOfEOT >= 0) {
indexOfEOT += k.OBCIParseEOT.length;
} else {
return dataBuffer;
}

if (indexOfEOT <= dataBuffer.byteLength) {
if (k.getVersionNumber(process.version) >= 6) {
// From introduced in node version 6.x.x
return Buffer.from(dataBuffer.slice(0, indexOfEOT));
} else {
return new Buffer(dataBuffer.slice(0, indexOfEOT));
}
} else {
return null;
}
}

/**
* @description Used to slice a buffer for the EOT '$$$'.
* @param dataBuffer {Buffer} - The buffer of some length to parse
Expand Down
164 changes: 87 additions & 77 deletions openBCISimulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,91 +194,101 @@ function OpenBCISimulatorFactory () {
return;
}

// TODO: this function assumes a type of Buffer for radio, and a type of String otherwise
// FIX THIS it makes it unusable outside the api code
switch (data[0]) {
case k.OBCIRadioKey:
this._processPrivateRadioMessage(data);
break;
case k.OBCIStreamStart:
if (!this.stream) this._startStream();
this.streaming = true;
break;
case k.OBCIStreamStop:
if (this.stream) clearInterval(this.stream); // Stops the stream
this.streaming = false;
break;
case k.OBCIMiscSoftReset:
if (this.stream) clearInterval(this.stream);
this.streaming = false;
this._output(new Buffer(`OpenBCI V3 Simulator On Board ADS1299 Device ID: 0x12345 ${this.options.daisy ? `On Daisy ADS1299 Device ID: 0xFFFFF\n` : ``} LIS3DH Device ID: 0x38422 ${this.options.firmwareVersion === k.OBCIFirmwareV2 ? `Firmware: v2.0.0\n` : ``}$$$`));
break;
case k.OBCISDLogForHour1:
case k.OBCISDLogForHour2:
case k.OBCISDLogForHour4:
case k.OBCISDLogForHour12:
case k.OBCISDLogForHour24:
case k.OBCISDLogForMin5:
case k.OBCISDLogForMin15:
case k.OBCISDLogForMin30:
case k.OBCISDLogForSec14:
// If we are not streaming, then do verbose output
if (!this.streaming) {
this._output(new Buffer('Wiring is correct and a card is present.\nCorresponding SD file OBCI_69.TXT\n$$$'));
if (this.options.boardFailure) {
if (this.options.firmwareVersion !== k.OBCIFirmwareV1) {
if (data[0] === k.OBCIRadioKey) {
this._processPrivateRadioMessage(data);
} else {
this._output(new Buffer(`${k.OBCIErrorRadioSystemDown}$$$`));
}
this.sd.active = true;
this.sd.startTime = now();
break;
case k.OBCISDLogStop:
if (!this.streaming) {
if (this.SDLogActive) {
this._output(new Buffer(`Total Elapsed Time: ${now() - this.sd.startTime} ms`));
this._output(new Buffer(`Max write time: ${Math.random() * 500} us`));
this._output(new Buffer(`Min write time: ${Math.random() * 200} us`));
this._output(new Buffer(`Overruns: 0`));
}
} else {
// TODO: this function assumes a type of Buffer for radio, and a type of String otherwise
// FIX THIS it makes it unusable outside the api code
switch (data[0]) {
case k.OBCIRadioKey:
this._processPrivateRadioMessage(data);
break;
case k.OBCIStreamStart:
if (!this.stream) this._startStream();
this.streaming = true;
break;
case k.OBCIStreamStop:
if (this.stream) clearInterval(this.stream); // Stops the stream
this.streaming = false;
break;
case k.OBCIMiscSoftReset:
if (this.stream) clearInterval(this.stream);
this.streaming = false;
this._output(new Buffer(`OpenBCI V3 Simulator On Board ADS1299 Device ID: 0x12345 ${this.options.daisy ? `On Daisy ADS1299 Device ID: 0xFFFFF\n` : ``} LIS3DH Device ID: 0x38422 ${this.options.firmwareVersion === k.OBCIFirmwareV2 ? `Firmware: v2.0.0\n` : ``}$$$`));
break;
case k.OBCISDLogForHour1:
case k.OBCISDLogForHour2:
case k.OBCISDLogForHour4:
case k.OBCISDLogForHour12:
case k.OBCISDLogForHour24:
case k.OBCISDLogForMin5:
case k.OBCISDLogForMin15:
case k.OBCISDLogForMin30:
case k.OBCISDLogForSec14:
// If we are not streaming, then do verbose output
if (!this.streaming) {
this._output(new Buffer('Wiring is correct and a card is present.\nCorresponding SD file OBCI_69.TXT\n$$$'));
}
this.sd.active = true;
this.sd.startTime = now();
break;
case k.OBCISDLogStop:
if (!this.streaming) {
if (this.SDLogActive) {
this._output(new Buffer(`Total Elapsed Time: ${now() - this.sd.startTime} ms`));
this._output(new Buffer(`Max write time: ${Math.random() * 500} us`));
this._output(new Buffer(`Min write time: ${Math.random() * 200} us`));
this._output(new Buffer(`Overruns: 0`));
this._printEOT();
} else {
this._output(new Buffer('No open file to close\n'));
this._printEOT();
}
}
this.SDLogActive = false;
break;
case k.OBCISyncTimeSet:
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
this.synced = true;
setTimeout(() => {
this._output(new Buffer(k.OBCISyncTimeSent));
this._syncUp();
}, 10);
}
break;
case k.OBCIChannelMaxNumber8:
if (this.options.daisy) {
this.options.daisy = false;
this._output(new Buffer(k.OBCIChannelMaxNumber8SuccessDaisyRemoved));
this._printEOT();
} else {
this._output(new Buffer('No open file to close\n'));
this._printEOT();
}
}
this.SDLogActive = false;
break;
case k.OBCISyncTimeSet:
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
this.synced = true;
setTimeout(() => {
this._output(new Buffer(k.OBCISyncTimeSent));
this._syncUp();
}, 10);
}
break;
case k.OBCIChannelMaxNumber8:
if (this.options.daisy) {
this.options.daisy = false;
this._output(new Buffer(k.OBCIChannelMaxNumber8SuccessDaisyRemoved));
this._printEOT();
} else {
this._printEOT();
}
break;
case k.OBCIChannelMaxNumber16:
if (this.options.daisy) {
this._output(new Buffer(k.OBCIChannelMaxNumber16DaisyAlreadyAttached));
this._printEOT();
} else {
if (this.options.daisyCanBeAttached) {
this.options.daisy = true;
this._output(new Buffer(k.OBCIChannelMaxNumber16DaisyAttached));
break;
case k.OBCIChannelMaxNumber16:
if (this.options.daisy) {
this._output(new Buffer(k.OBCIChannelMaxNumber16DaisyAlreadyAttached));
this._printEOT();
} else {
this._output(new Buffer(k.OBCIChannelMaxNumber16NoDaisyAttached));
this._printEOT();
if (this.options.daisyCanBeAttached) {
this.options.daisy = true;
this._output(new Buffer(k.OBCIChannelMaxNumber16DaisyAttached));
this._printEOT();
} else {
this._output(new Buffer(k.OBCIChannelMaxNumber16NoDaisyAttached));
this._printEOT();
}
}
}
break;
default:
break;
break;
default:
break;
}
}

/** Handle Callback */
Expand Down
Loading

0 comments on commit 5187f94

Please sign in to comment.