node-aurora
Version:
Provides an interface to the Aurora Dreamband.
317 lines (216 loc) • 10.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _events = require('events');
var _events2 = _interopRequireDefault(_events);
var _AuroraConstants = require('./AuroraConstants');
var _AuroraCmdResponseParser = require('./AuroraCmdResponseParser');
var _AuroraCmdResponseParser2 = _interopRequireDefault(_AuroraCmdResponseParser);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var AuroraBluetoothParser = function (_EventEmitter) {
(0, _inherits3.default)(AuroraBluetoothParser, _EventEmitter);
function AuroraBluetoothParser() {
(0, _classCallCheck3.default)(this, AuroraBluetoothParser);
var _this = (0, _possibleConstructorReturn3.default)(this, (AuroraBluetoothParser.__proto__ || (0, _getPrototypeOf2.default)(AuroraBluetoothParser)).call(this));
_this._cmdDataReceiveResponseObject = function (buffer) {
if (_this._cmdState != _AuroraConstants.BleCmdStates.CMD_RESP_OBJECT_READY) throw new Error('Invalid state to receive object response.');
try {
_this._cmdResponseParser.parseObject(buffer.toString('ascii'));
} catch (error) {
_this.emit('parseError', 'Failed parsing object: ' + error);
}
};
_this._cmdDataReceiveResponseTable = function (buffer) {
if (_this._cmdState != _AuroraConstants.BleCmdStates.CMD_RESP_TABLE_READY) throw new Error('Invalid state to receive table response.');
try {
_this._cmdResponseParser.parseTable(buffer.toString('ascii'));
} catch (error) {
_this.emit('parseError', 'Failed parsing table: ' + error);
}
};
_this._triggerCmdError = function (message) {
_this._cmd.error = true;
_this._cmd.response = {
error: -64,
message: message
};
_this.emit('cmdResponse', _this._cmd);
_this.reset();
};
_this._onCmdTimeout = function () {
_this._triggerCmdError('Command timed out.');
};
_this._cmdResponseParser = new _AuroraCmdResponseParser2.default();
_this.reset();
return _this;
}
(0, _createClass3.default)(AuroraBluetoothParser, [{
key: 'reset',
value: function reset() {
clearTimeout(this._cmdWatchdogTimer);
this._cmd = null;
this._cmdResponseParser.reset();
this._cmdState = _AuroraConstants.BleCmdStates.IDLE;
}
}, {
key: 'setCmd',
value: function setCmd(cmd) {
if (this._cmdState != _AuroraConstants.BleCmdStates.IDLE) throw new Error('Parser command state not idle.');
this.reset();
this._cmd = {
command: cmd
};
this._cmdWatchdogTimer = setTimeout(this._onCmdTimeout, 2000);
}
}, {
key: 'onStreamDataCharNotification',
value: function onStreamDataCharNotification(dataBuffer) {
var stream = null;
var streamDataType = _AuroraConstants.DataTypes.UNKNOWN;
var streamDataLength = 0;
for (var i = 0; i < dataBuffer.length; i++) {
if (!stream) {
var streamId = dataBuffer[i];
if (streamId > _AuroraConstants.STREAM_ID_MAX) {
this.emit('parseError', 'Invalid stream id: ' + streamId);
continue;
}
i++;
if (i < dataBuffer.length) {
streamDataType = dataBuffer[i] >> 4;
streamDataLength = dataBuffer[i] & 0x0F;
if (i + streamDataLength <= dataBuffer.length) {
stream = {
streamId: streamId,
stream: _AuroraConstants.StreamIdsToNames[streamId],
data: [],
time: Date.now()
};
continue;
}
}
this.emit('parseError', 'Incomplete stream packet.');
} else {
switch (streamDataType) {
case _AuroraConstants.DataTypes.BOOL:
case _AuroraConstants.DataTypes.UINT8:
stream.data.push(dataBuffer.readUInt8(i));
break;
case _AuroraConstants.DataTypes.INT8:
stream.data.push(dataBuffer.readInt8(i));
break;
case _AuroraConstants.DataTypes.UINT16:
stream.data.push(dataBuffer.readUInt16LE(i));
i += 1;
break;
case _AuroraConstants.DataTypes.INT16:
stream.data.push(dataBuffer.readInt16LE(i));
i += 1;
break;
case _AuroraConstants.DataTypes.UINT32:
case _AuroraConstants.DataTypes.PTR:
stream.data.push(dataBuffer.readUInt32LE(i));
i += 3;
break;
case _AuroraConstants.DataTypes.INT32:
stream.data.push(dataBuffer.readInt32LE(i));
i += 3;
break;
case _AuroraConstants.DataTypes.FLOAT:
stream.data.push(dataBuffer.readFloatLE(i));
i += 3;
break;
case _AuroraConstants.DataTypes.UNKNOWN:
case _AuroraConstants.DataTypes.STR:
case _AuroraConstants.DataTypes.CHAR:
default:
this.emit('parseError', 'Invalid or unsupported stream data type: ' + streamDataType);
}
streamDataLength--;
if (!streamDataLength) {
this.emit('streamData', stream);
stream = null;
}
}
}
}
}, {
key: 'onAuroraEventCharNotification',
value: function onAuroraEventCharNotification(eventBuffer) {
if (eventBuffer.length != 5) {
this.emit('parseError', 'Incomplete event packet.');
return;
}
var eventId = eventBuffer[0];
if (eventId > _AuroraConstants.EVENT_ID_MAX) {
this.emit('parseError', 'Invalid event id.');
return;
}
this.emit('auroraEvent', {
eventId: eventId,
event: _AuroraConstants.EventIdsToNames[eventId],
flags: eventBuffer.readUInt32LE(1),
time: Date.now()
});
}
}, {
key: 'onCmdStatusCharNotification',
value: function onCmdStatusCharNotification(statusBuffer) {
this._cmdState = statusBuffer[0];
clearTimeout(this._cmdWatchdogTimer);
this._cmdWatchdogTimer = setTimeout(this._onCmdTimeout, 10000);
if (this._cmdState != _AuroraConstants.BleCmdStates.IDLE && !this._cmd) {
this.emit('parseError', 'Invalid status change. No command set.');
return;
}
switch (this._cmdState) {
//is this the end of a command? i.e now idle
case _AuroraConstants.BleCmdStates.IDLE:
if (this._cmd) {
this._cmd.response = this._cmdResponseParser.getResponse();
this._cmd.error = statusBuffer[1] !== 0;
this.emit('cmdResponse', this._cmd);
}
this.reset();
break;
//do we have a response to receive
case _AuroraConstants.BleCmdStates.CMD_RESP_OBJECT_READY:
//second statusBuffer byte is number of bytes available to read
this.emit('cmdResponseRead', statusBuffer[1], this._cmdDataReceiveResponseObject);
break;
case _AuroraConstants.BleCmdStates.CMD_RESP_TABLE_READY:
//second statusBuffer byte is number of bytes available to read
this.emit('cmdResponseRead', statusBuffer[1], this._cmdDataReceiveResponseTable);
break;
//command waiting for input
case _AuroraConstants.BleCmdStates.CMD_INPUT_REQUESTED:
this.emit('cmdInputRequested');
clearTimeout(this._cmdWatchdogTimer);
break;
default:
this.emit('parseError', 'Unknown command state: ' + statusBuffer[0]);
break;
}
}
}, {
key: 'onCmdOutputCharNotification',
value: function onCmdOutputCharNotification(output) {
this.emit('cmdOutputReady', output);
clearTimeout(this._cmdWatchdogTimer);
this._cmdWatchdogTimer = setTimeout(this._onCmdTimeout, 10000);
}
}]);
return AuroraBluetoothParser;
}(_events2.default);
exports.default = AuroraBluetoothParser;