Skip to content

Commit 031861d

Browse files
author
AJ Keller
committed
Fix leaked event emitter with time sync, remove extra log statement
1 parent 6fd9ddf commit 031861d

File tree

6 files changed

+197
-36
lines changed

6 files changed

+197
-36
lines changed

changelog.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
# 1.3.3
2+
3+
### New Features
4+
5+
* Add `timeOffsetMaster` to object emitted when bad time sync.
6+
7+
### Bug Fixes
8+
9+
* Fixed log statement on impedance setting function
10+
* Remove event emitter with time sync on reject of sync clock full
11+
112
# 1.3.2
213

314
### Enhancements

examples/timeSync/timeSync.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,16 @@ var sampleFunc = sample => {
6363
// Resynchronize every every second
6464
if (sample._count % (sampleRate * 1) === 0) {
6565
ourBoard.syncClocksFull()
66-
.then(syncObj => {
67-
// Sync was successful
68-
if (syncObj.valid) {
69-
// Log the object to check it out!
70-
console.log(`timeOffset`,syncObj.timeOffsetMaster);
71-
} else {
72-
// Retry it
73-
console.log(`Was not able to sync... retry!`);
74-
}
75-
});
66+
.then(syncObj => {
67+
// Sync was successful
68+
if (syncObj.valid) {
69+
// Log the object to check it out!
70+
console.log(`timeOffset`,syncObj.timeOffsetMaster);
71+
} else {
72+
// Retry it
73+
console.log(`Was not able to sync... retry!`);
74+
}
75+
});
7676
}
7777

7878
if (sample.timeStamp) { // true after the first successful sync

openBCIBoard.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ function OpenBCIFactory() {
176176
this._lowerChannelsSampleObject = null;
177177
this.sync = {
178178
curSyncObj: null,
179+
eventEmitter: null,
179180
objArray: [],
180181
sntpActive: false,
181182
timeOffsetMaster: 0,
@@ -1327,7 +1328,6 @@ function OpenBCIFactory() {
13271328
if (this.options.verbose) console.log('pInput: ' + pInput + ' nInput: ' + nInput);
13281329
// Get impedance settings to send the board
13291330
k.getImpedanceSetter(channelNumber,pInput,nInput).then((commandsArray) => {
1330-
console.log(commandsArray);
13311331
this.write(commandsArray);
13321332
//delayInMS += commandsArray.length * k.OBCIWriteIntervalDelayMSLong;
13331333
delayInMS += this.commandsToWrite * k.OBCIWriteIntervalDelayMSShort; // Account for commands waiting to be sent in the write buffer
@@ -1564,10 +1564,11 @@ function OpenBCIFactory() {
15641564
if (!this.usingVersionTwoFirmware()) reject('Time sync not implemented on v1 firmware, please update to v2');
15651565
setTimeout(() => {
15661566
return reject('syncClocksFull timeout after 500ms with no sync');
1567-
}, 1000); // Should not take more than 1s to sync up
1568-
this.once('synced',syncObj => {
1567+
}, 500); // Should not take more than 1s to sync up
1568+
this.sync.eventEmitter = syncObj => {
15691569
return resolve(syncObj);
1570-
});
1570+
};
1571+
this.once('synced', this.sync.eventEmitter);
15711572
this.sync.curSyncObj = openBCISample.newSyncObject();
15721573
this.sync.curSyncObj.timeSyncSent = this.time();
15731574
this.curParsingMode = k.OBCIParsingTimeSyncSent;
@@ -1853,7 +1854,9 @@ function OpenBCIFactory() {
18531854
// Fix the curParsingMode back to normal
18541855
this.curParsingMode = k.OBCIParsingNormal;
18551856
// Emit the bad sync object for fun
1856-
this.emit('synced',openBCISample.newSyncObject());
1857+
var badObject = openBCISample.newSyncObject();
1858+
badObject.timeOffsetMaster = this.sync.timeOffsetMaster;
1859+
this.emit('synced', badObject);
18571860
// Set back to null
18581861
this.sync.curSyncObj = null;
18591862
// Return will exit this method with the err
@@ -1951,6 +1954,12 @@ function OpenBCIFactory() {
19511954
return resolve(rawPacket);
19521955
})
19531956
.catch(err => {
1957+
// Emit the bad sync object for fun
1958+
var badObject = openBCISample.newSyncObject();
1959+
badObject.timeOffsetMaster = this.sync.timeOffsetMaster;
1960+
this.emit('synced', badObject);
1961+
// Set back to null
1962+
this.sync.curSyncObj = null;
19541963
console.log('Error in _processPacketTimeSyncSet', err)
19551964
return reject(err);
19561965
});

openBCISample.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,6 @@ function parsePacketTimeSyncedAccel(dataBuf,channelSettingsArray,boardOffsetTime
707707
return new Promise((resolve, reject) => {
708708
// The sample object we are going to build
709709
var sampleObject = {};
710-
711710
if (dataBuf.byteLength != k.OBCIPacketSize) reject("Error [parsePacketTimeSyncedAccel]: input buffer must be " + k.OBCIPacketSize + " bytes!");
712711

713712
// Get the sample number
@@ -803,10 +802,12 @@ function getFromTimePacketTime(dataBuf) {
803802
// Ths packet has 'A0','00'....,'00','00','FF','FF','FF','FF','C3' where the 'FF's are times
804803
const lastBytePosition = k.OBCIPacketSize - 1; // This is 33, but 0 indexed would be 32 minus 1 for the stop byte and another two for the aux channel or the
805804
return new Promise((resolve, reject) => {
806-
if (dataBuf.byteLength != k.OBCIPacketSize) reject("Error [getFromTimePacketTime]: input buffer must be " + k.OBCIPacketSize + " bytes!");
807-
808-
// Grab the time from the packet
809-
resolve(dataBuf.readUInt32BE(lastBytePosition - k.OBCIStreamPacketTimeByteSize));
805+
if (dataBuf.byteLength != k.OBCIPacketSize) {
806+
reject("Error [getFromTimePacketTime]: input buffer must be " + k.OBCIPacketSize + " bytes!");
807+
} else {
808+
// Grab the time from the packet
809+
resolve(dataBuf.readUInt32BE(lastBytePosition - k.OBCIStreamPacketTimeByteSize));
810+
}
810811
});
811812
}
812813

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "openbci",
3-
"version": "1.3.2",
3+
"version": "1.3.3",
44
"description": "The official Node.js SDK for the OpenBCI Biosensor Board.",
55
"main": "openBCIBoard",
66
"scripts": {

test/openBCIBoard-test.js

Lines changed: 155 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,16 @@ describe('openbci-sdk',function() {
296296
(ourBoard.impedanceTest.onChannel).should.equal(0);
297297
(ourBoard.impedanceTest.sampleNumber).should.equal(0);
298298
});
299+
it('configures sync object correctly', function() {
300+
ourBoard = new openBCIBoard.OpenBCIBoard();
301+
expect(ourBoard.sync.curSyncObj).to.be.null;
302+
expect(ourBoard.sync.eventEmitter).to.be.null;
303+
expect(ourBoard.sync.objArray.length).to.equal(0);
304+
(ourBoard.sync.sntpActive).should.equal(false);
305+
(ourBoard.sync.timeOffsetMaster).should.equal(0);
306+
(ourBoard.sync.timeOffsetAvg).should.equal(0);
307+
expect(ourBoard.sync.timeOffsetArray.length).to.equal(0);
308+
});
299309
it('configures impedance array with the correct amount of channels for default', function() {
300310
ourBoard = new openBCIBoard.OpenBCIBoard();
301311
(ourBoard.impedanceArray.length).should.equal(8);
@@ -1085,19 +1095,64 @@ describe('openbci-sdk',function() {
10851095
.catch(function(err) {
10861096
expect(ourBoard.curParsingMode).to.equal(k.OBCIParsingNormal);
10871097
expect(ourBoard.sync.curSyncObj).to.be.null;
1098+
expect(ourBoard.sync.eventEmitter).to.be.null;
10881099
done();
10891100
});
10901101
});
10911102
it("should emit sycned event with valid false", function(done) {
10921103
var timeSetPacketArrived = ourBoard.time();
1104+
var expectedTimeSyncOffsetMaster = 72;
10931105
ourBoard.curParsingMode = k.OBCIParsingTimeSyncSent;
10941106
ourBoard.sync.curSyncObj = openBCISample.newSyncObject();
1107+
ourBoard.sync.timeOffsetMaster = expectedTimeSyncOffsetMaster;
10951108
ourBoard.once('synced',obj => {
10961109
expect(obj.valid).to.be.false;
1110+
expect(obj.timeOffsetMaster).to.equal(expectedTimeSyncOffsetMaster);
10971111
done();
1098-
})
1112+
});
10991113
ourBoard._processPacketTimeSyncSet(timeSyncSetPacket,timeSetPacketArrived);
11001114
});
1115+
it("should reset when bad raw packet", function(done) {
1116+
var timeSetPacketArrived = ourBoard.time();
1117+
var badPacket;
1118+
if (k.getVersionNumber(process.version) >= 6) {
1119+
// from introduced in node version 6.x.x
1120+
badPacket = Buffer.from(timeSyncSetPacket.slice(0,30));
1121+
} else {
1122+
badPacket = new Buffer(timeSyncSetPacket.slice(0,30));
1123+
}
1124+
ourBoard.sync.curSyncObj = openBCISample.newSyncObject();
1125+
ourBoard._processPacketTimeSyncSet(badPacket,timeSetPacketArrived)
1126+
.then(() => {
1127+
done("failed to get rejected");
1128+
})
1129+
.catch(function(err) {
1130+
expect(ourBoard.curParsingMode).to.equal(k.OBCIParsingNormal);
1131+
expect(ourBoard.sync.curSyncObj).to.be.null;
1132+
expect(ourBoard.sync.eventEmitter).to.be.null;
1133+
done();
1134+
});
1135+
});
1136+
it("should emit bad synced object bad raw packet", function(done) {
1137+
var timeSetPacketArrived = ourBoard.time();
1138+
var expectedTimeSyncOffsetMaster = 72;
1139+
var badPacket;
1140+
if (k.getVersionNumber(process.version) >= 6) {
1141+
// from introduced in node version 6.x.x
1142+
badPacket = Buffer.from(timeSyncSetPacket.slice(0,30));
1143+
} else {
1144+
badPacket = new Buffer(timeSyncSetPacket.slice(0,30));
1145+
}
1146+
ourBoard.curParsingMode = k.OBCIParsingTimeSyncSent;
1147+
ourBoard.sync.curSyncObj = openBCISample.newSyncObject();
1148+
ourBoard.sync.timeOffsetMaster = expectedTimeSyncOffsetMaster;
1149+
ourBoard.once('synced',obj => {
1150+
expect(obj.valid).to.be.false;
1151+
expect(obj.timeOffsetMaster).to.equal(expectedTimeSyncOffsetMaster);
1152+
done();
1153+
});
1154+
ourBoard._processPacketTimeSyncSet(badPacket,timeSetPacketArrived);
1155+
});
11011156
it("should calculate round trip time as the difference between time sent and time set packet arrived",function(done) {
11021157
var timeSetPacketArrived = ourBoard.time();
11031158
var expectedRoundTripTime = 20; //ms
@@ -1554,7 +1609,7 @@ describe('openbci-sdk',function() {
15541609
// Pretend that half of buf1 got sent in the first serial flush
15551610
// and that the last half of it will arrive a lil later
15561611
var splitPoint = 15;
1557-
if (process.version > 6) {
1612+
if (k.getVersionNumber(process.version) >= 6) {
15581613
// from introduced in node version 6.x.x
15591614
ourBoard.buffer = Buffer.from(buf1.slice(0,splitPoint));
15601615
} else {
@@ -1593,7 +1648,7 @@ describe('openbci-sdk',function() {
15931648

15941649
ourBoard["buffer"] = null;
15951650
var bufFirstHalf, bufLastHalf;
1596-
if (process.version > 6) {
1651+
if (k.getVersionNumber(process.version) >= 6) {
15971652
// from introduced in node version 6.x.x
15981653
bufFirstHalf = Buffer.from(buf3.slice(0,splitPoint));
15991654
bufLastHalf = Buffer.from(buf3.slice(splitPoint));
@@ -2881,7 +2936,7 @@ describe('#daisy', function () {
28812936
});
28822937
});
28832938

2884-
describe('#sync', function() {
2939+
describe('#syncWhileStreaming', function() {
28852940
var ourBoard;
28862941
this.timeout(4000);
28872942
before(function (done) {
@@ -2943,43 +2998,128 @@ describe('#sync', function() {
29432998
it('can sync while streaming', done => {
29442999
var syncAfterSamples = 50;
29453000
var notSynced = true;
3001+
var syncFunc = obj => {
3002+
ourBoard.removeListener('sample',samp);
3003+
done();
3004+
};
29463005
var samp = sample => {
29473006
if (sample.sampleNumber >= syncAfterSamples && notSynced) {
29483007
notSynced = false;
29493008
// Call the first one
2950-
ourBoard.syncClocks().catch(err => done);
3009+
ourBoard.syncClocks()
3010+
.catch((err) => {
3011+
ourBoard.removeListener('sample',samp);
3012+
ourBoard.removeListener('synced',syncFunc);
3013+
done();
3014+
});
29513015
}
29523016
};
29533017
ourBoard.on('sample',samp);
2954-
// Attached the emitted
2955-
ourBoard.once('synced',obj => {
2956-
console.log('syhnc obj', obj);
2957-
ourBoard.removeListener('sample',samp);
2958-
done();
2959-
});
3018+
ourBoard.once('synced', syncFunc);
29603019
});
29613020
});
29623021
describe('#syncClocksFull', function() {
29633022
it('can run a full clock sync', done => {
29643023
var notSynced = true;
29653024
var sampleFun = sample => {
2966-
console.log('sample',sample);
2967-
29683025
if (notSynced) {
29693026
notSynced = false;
29703027
// Call the first one
29713028
ourBoard.syncClocksFull()
29723029
.then(syncObj => {
2973-
console.log(syncObj);
29743030
if (syncObj.valid) {
3031+
ourBoard.removeListener('sample',sampleFun);
29753032
done();
29763033
} else {
3034+
ourBoard.removeListener('sample',sampleFun);
29773035
done("Not able to sync");
29783036
}
2979-
}).catch(err => done);
3037+
}).catch((err) => {
3038+
ourBoard.removeListener('sample',sampleFun);
3039+
done();
3040+
});
29803041
}
29813042
};
29823043
ourBoard.on('sample',sampleFun);
29833044
});
29843045
});
29853046
});
3047+
3048+
describe('#syncErrors', function() {
3049+
var ourBoard;
3050+
this.timeout(4000);
3051+
before(function (done) {
3052+
ourBoard = new openBCIBoard.OpenBCIBoard({
3053+
verbose:true,
3054+
simulatorFirmwareVersion: 'v2'
3055+
});
3056+
var useSim = () => {
3057+
ourBoard.simulatorEnable()
3058+
.then(() => {
3059+
return ourBoard.connect(k.OBCISimulatorPortName);
3060+
})
3061+
.then(() => {
3062+
return ourBoard.softReset();
3063+
})
3064+
.catch(err => console.log(err));
3065+
};
3066+
ourBoard.autoFindOpenBCIBoard()
3067+
.then(portName => {
3068+
return setTimeout(() => {
3069+
console.log('Issuing connect');
3070+
ourBoard.connect(portName);
3071+
},500);
3072+
})
3073+
.catch((err) => {
3074+
useSim();
3075+
})
3076+
.then(() => {
3077+
//console.log('connected');
3078+
})
3079+
.catch(err => {
3080+
console.log('Error: ' + err);
3081+
});
3082+
3083+
3084+
ourBoard.once('ready', () => {
3085+
done();
3086+
});
3087+
});
3088+
after(function(done) {
3089+
if (ourBoard.connected) {
3090+
ourBoard.disconnect().then(() => {
3091+
done();
3092+
}).catch(() => done);
3093+
} else {
3094+
done();
3095+
}
3096+
});
3097+
afterEach(() => {
3098+
this.buffer = null;
3099+
});
3100+
describe('#syncClocksFull', function() {
3101+
it('should reject syncClocksFull request because of timeout', done => {
3102+
var notSynced = true;
3103+
var sampleFun = sample => {
3104+
if (notSynced) {
3105+
notSynced = false;
3106+
// Call the first one
3107+
ourBoard.syncClocksFull()
3108+
.then(syncObj => {
3109+
done("Should not be able to sync");
3110+
}).catch((err) => {
3111+
ourBoard.removeListener('sample',sampleFun);
3112+
done();
3113+
});
3114+
ourBoard.streamStop();
3115+
}
3116+
};
3117+
ourBoard.streamStart()
3118+
.catch(err => {
3119+
ourBoard.removeListener('sample',sampleFun);
3120+
done('coulnd not start stime sync')
3121+
});
3122+
ourBoard.on('sample',sampleFun);
3123+
});
3124+
});
3125+
});

0 commit comments

Comments
 (0)