raw-modem
Version:
A library to send raw command to a modem and received the response
127 lines (126 loc) • 4.22 kB
JavaScript
;
let SerialPort = require('serialport');
const Rx = require('rxjs/Rx');
class DefaultSerialPort {
constructor() {
this._portOptions = null;
this._devicePort = null;
}
get devicePort() {
return this._devicePort;
}
_checkDevicePort() {
if (this.devicePort == null) {
throw new Error('Port not created');
}
}
open() {
return Rx.Observable.create(s => {
this._checkDevicePort();
this.devicePort.open(err => {
if (err) {
s.error(err);
}
else {
s.next();
s.complete();
}
});
});
}
close() {
return Rx.Observable.create(s => {
this._checkDevicePort();
if (this.devicePort.isOpen()) {
this.devicePort.close(err => {
if (err) {
s.error(err);
}
else {
s.next();
s.complete();
}
});
}
else {
s.next();
s.complete();
}
});
}
write(command, callback) {
return Rx.Observable.create(s => {
this._checkDevicePort();
let timeoutId = setTimeout(() => {
clearAllListeners();
this.close().subscribe(() => {
s.error(new Error('Command timedout'));
});
}, this._portOptions.commandTimeout);
let state = 'waiting-response';
let completeResponse = '';
let dataState = 'waiting-OK';
let defaultDataParser = data => {
let responseString = data.toString();
completeResponse += responseString;
let commandTrimmed = command.trim();
if (dataState === 'waiting-OK') {
let completeResponseTrimmed = completeResponse.trim();
if (completeResponseTrimmed.endsWith("OK")) {
let dataWithoutOK = completeResponseTrimmed.slice(0, completeResponseTrimmed.length - 2);
s.next(dataWithoutOK);
clearTimeout(timeoutId);
clearAllListeners();
s.complete();
}
}
};
let onDataCallback = data => {
if (callback != null) {
callback(data, s);
}
else {
defaultDataParser(data);
}
};
let onErrorCallback = err => {
if (state !== 'terminated') {
clearTimeout(timeoutId);
clearAllListeners();
s.error(err);
}
};
let clearAllListeners = () => {
this.devicePort.removeListener("data", onDataCallback);
this.devicePort.removeListener("error", onErrorCallback);
};
this.devicePort.on("data", onDataCallback);
this.devicePort.on("error", onErrorCallback);
let completeCommand = command;
this.devicePort.write(completeCommand, err => {
if (err) {
clearTimeout(timeoutId);
clearAllListeners();
state = 'terminated';
s.error(err);
}
});
});
}
setPortOptions(options) {
return Rx.Observable.create(s => {
if (this.devicePort != null) {
this.devicePort.close();
}
this._portOptions = options;
this._devicePort = new SerialPort(options.deviceName, {
baudRate: options.baudRate,
autoOpen: options.autoOpen,
parser: SerialPort.parsers.raw
});
s.next();
s.complete();
});
}
}
exports.DefaultSerialPort = DefaultSerialPort;