Skip to content

Commit

Permalink
Fix hard crash on frames with no parser
Browse files Browse the repository at this point in the history
  • Loading branch information
joshperry committed Dec 4, 2014
1 parent 07dedf0 commit 3301253
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .jshintrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"curly": true,
"proto": true,
"eqeqeq": true,
"immed": true,
"latedef": true,
Expand Down
56 changes: 33 additions & 23 deletions lib/xbee-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ var util = require('util');
var events = require('events');

exports = module.exports;
exports.XBeeAPI = XBeeAPI;

var C = exports.constants = require('./constants.js');
var frame_parser = exports._frame_parser = require('./frame-parser');
Expand All @@ -32,7 +31,7 @@ function XBeeAPI(options) {
this.buildState = {
buffer: new Buffer(512, 'ascii'),
frameId: 0
}
};

this.parseState = {
buffer: new Buffer(512, 'ascii'),
Expand All @@ -46,11 +45,13 @@ function XBeeAPI(options) {
};

return this;
};
}
util.inherits(XBeeAPI, events.EventEmitter);

exports.XBeeAPI = XBeeAPI;

XBeeAPI.prototype.escape = function(buffer) {
if (this.escapeBuffer == undefined)
if (this.escapeBuffer === undefined)
this.escapeBuffer = new Buffer(512, 'ascii');

var offset = 0;
Expand All @@ -65,7 +66,7 @@ XBeeAPI.prototype.escape = function(buffer) {
}

return new Buffer(this.escapeBuffer.slice(0, offset));
}
};

XBeeAPI.prototype.buildFrame = function(frame) {
var S = this.buildState;
Expand All @@ -88,43 +89,50 @@ XBeeAPI.prototype.buildFrame = function(frame) {
for (var i = 0; i < length; i++) checksum += S.buffer[i+3];
S.buffer.writeUInt8(255 - (checksum % 256), length+3);

if (this.options.api_mode == 2)
if (this.options.api_mode === 2)
return this.escape(S.buffer.slice(0, length+4));
else
return new Buffer(S.buffer.slice(0, length+4));
}
};

// Note that this expects the whole frame to be escaped!
XBeeAPI.prototype.parseFrame = function(buffer) {
var frame = {
type: buffer.readUInt8(3) // Read Frame Type
};

// Frame Type Specific Parsing, drop start, legth, type and checksum
frame_parser[frame.type](frame, buffer.slice(4, buffer.length-1));

return frame;
}
};

XBeeAPI.prototype.canParse = function(buffer) {
var type = buffer.readUInt8(3);
return type in frame_parser;
};

XBeeAPI.prototype.nextFrameId = function() {
this.buildState.frameId++;
if (this.buildState.frameId > 255) {
this.buildState.frameId = 1;
}
return this.buildState.frameId;
}
};


XBeeAPI.prototype.rawParser = function() {
var self = this;
return function(emitter, buffer) {
self.parseRaw(buffer);
}
}
};
};

XBeeAPI.prototype.parseRaw = function(buffer) {
var S = this.parseState;
for(var i = 0; i < buffer.length; i++) {
S.b = buffer[i];
if (S.b == C.START_BYTE && S.waiting) {
if (S.b === C.START_BYTE && S.waiting) {
S.length = 0;
S.total = 0;
S.checksum = 0x00;
Expand All @@ -133,7 +141,7 @@ XBeeAPI.prototype.parseRaw = function(buffer) {
S.waiting = false;
}

if (this.options.api_mode == 2 && S.b == C.ESCAPE) {
if (this.options.api_mode === 2 && S.b === C.ESCAPE) {
S.escape_next = true;
continue;
}
Expand All @@ -145,15 +153,15 @@ XBeeAPI.prototype.parseRaw = function(buffer) {

S.buffer.writeUInt8(S.b, S.offset++);

if (S.offset == 1) {
if (S.offset === 1) {
continue;
}

if (S.offset == 2) {
if (S.offset === 2) {
S.length = S.b << 8; // most sign. bit of the length
continue;
}
if (S.offset == 3) {
if (S.offset === 3) {
S.length += S.b; // least sign. bit of the length
continue;
}
Expand All @@ -167,16 +175,18 @@ XBeeAPI.prototype.parseRaw = function(buffer) {
}
}

if (S.length > 0 && S.offset == S.length + 4) {
if (S.length > 0 && S.offset === S.length + 4) {
S.waiting = true;
if (S.checksum != (255 - (S.total % 256))) {
if (S.checksum !== (255 - (S.total % 256))) {
throw new Error("Checksum Mismatch", S);
} else if (this.options.raw_frames) {
this.emit("frame_raw", S.buffer.slice(0, S.offset));
}

var rawFrame = S.buffer.slice(0, S.offset);
if (this.options.raw_frames || !this.canParse(rawFrame)) {
this.emit("frame_raw", rawFrame);
} else {
this.emit("frame_object",
this.parseFrame(S.buffer.slice(0, S.offset)));
this.emit("frame_object", this.parseFrame(rawFrame));
}
}
}
}
};

0 comments on commit 3301253

Please sign in to comment.