serialport
Advanced tools
Comparing version 1.1.3 to 1.2.0
{ | ||
"name": "serialport", | ||
"version": "1.1.3", | ||
"version": "1.2.0", | ||
"description": "Welcome your robotic javascript overlords. Better yet, program them!", | ||
@@ -30,3 +30,3 @@ "author": { | ||
"dependencies": { | ||
"bindings": "1.1.0", | ||
"bindings": "1.1.1", | ||
"async": "0.1.18", | ||
@@ -41,3 +41,3 @@ "sf": "0.1.6", | ||
"engines": { | ||
"node": ">= 0.7.0" | ||
"node": ">= 0.10.0" | ||
}, | ||
@@ -44,0 +44,0 @@ "bin": { |
@@ -8,2 +8,3 @@ "use strict"; | ||
var SerialPortBinding = require("bindings")("serialport.node"); | ||
var EventEmitter = require('events').EventEmitter; | ||
var util = require('util'); | ||
@@ -16,8 +17,25 @@ var fs = require('fs'); | ||
var BAUDRATES = [500000, 230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1800, 1200, 600, 300, 200, 150, 134, 110, 75, 50]; | ||
var DATABITS = [8, 7, 6, 5]; | ||
var STOPBITS = [1, 2, 1.5]; | ||
// Removing check for valid BaudRates due to ticket: #140 | ||
// var BAUDRATES = [500000, 230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1800, 1200, 600, 300, 200, 150, 134, 110, 75, 50]; | ||
// VALIDATION ARRAYS | ||
var DATABITS = [5, 6, 7, 8]; | ||
var STOPBITS = [1, 1.5, 2]; | ||
var PARITY = ['none', 'even', 'mark', 'odd', 'space']; | ||
var FLOWCONTROL = [false, true]; | ||
var FLOWCONTROLS = ["XON", "XOFF", "XANY", "RTSCTS"]; | ||
// Stuff from ReadStream, refactored for our usage: | ||
var kPoolSize = 40 * 1024; | ||
var kMinPoolSpace = 128; | ||
var pool; | ||
function allocNewPool() { | ||
pool = new Buffer(kPoolSize); | ||
pool.used = 0; | ||
} | ||
var parsers = { | ||
@@ -50,7 +68,10 @@ raw: function (emitter, buffer) { | ||
baudrate: 9600, | ||
parity: 'none', | ||
rtscts: false, | ||
xon: false, | ||
xoff: false, | ||
xany: false, | ||
databits: 8, | ||
stopbits: 1, | ||
parity: 'none', | ||
flowcontrol: false, | ||
buffersize: 255, | ||
stopbits: 1, | ||
buffersize: 256, | ||
parser: parsers.raw | ||
@@ -60,3 +81,2 @@ }; | ||
options = options || {}; | ||
options.__proto__ = _options; | ||
openImmediately = (openImmediately === undefined || openImmediately === null) ? true : openImmediately; | ||
@@ -66,17 +86,24 @@ | ||
if (BAUDRATES.indexOf(options.baudrate) == -1) { | ||
throw new Error('Invalid "baudrate": ' + options.baudrate); | ||
stream.Stream.call(this); | ||
options.baudRate = options.baudRate || options.baudrate || _options.baudrate; | ||
// Removing check for valid BaudRates due to ticket: #140 | ||
// if (BAUDRATES.indexOf(options.baudrate) == -1) { | ||
// throw new Error('Invalid "baudrate": ' + options.baudrate); | ||
// } | ||
options.dataBits = options.dataBits || options.databits || _options.databits; | ||
if (DATABITS.indexOf(options.dataBits) == -1) { | ||
throw new Error('Invalid "databits": ' + options.dataBits); | ||
} | ||
if (DATABITS.indexOf(options.databits) == -1) { | ||
throw new Error('Invalid "databits": ' + options.databits); | ||
} | ||
if (STOPBITS.indexOf(options.stopbits) == -1) { | ||
options.stopBits = options.stopBits || options.stopbits || _options.stopbits; | ||
if (STOPBITS.indexOf(options.stopBits) == -1) { | ||
throw new Error('Invalid "stopbits": ' + options.stopbits); | ||
} | ||
options.parity = options.parity || _options.parity; | ||
if (PARITY.indexOf(options.parity) == -1) { | ||
throw new Error('Invalid "parity": ' + options.parity); | ||
} | ||
if (FLOWCONTROL.indexOf(options.flowcontrol) == -1) { | ||
throw new Error('Invalid "flowcontrol": ' + options.flowcontrol); | ||
} | ||
if (!path) { | ||
@@ -86,17 +113,47 @@ throw new Error('Invalid port specified: ' + path); | ||
stream.Stream.call(this); | ||
// flush defaults, then update with provided details | ||
options.rtscts = _options.rtscts; | ||
options.xon = _options.xon; | ||
options.xoff = _options.xoff; | ||
options.xany = _options.xany; | ||
if (options.flowControl || options.flowcontrol) { | ||
var fc = options.flowControl || options.flowcontrol; | ||
options = options || {}; | ||
options.baudRate = options.baudRate || options.baudrate || 9600; | ||
options.dataBits = options.dataBits || options.databits || 8; | ||
options.parity = options.parity || 'none'; | ||
options.stopBits = options.stopBits || options.stopbits || 1; | ||
options.bufferSize = options.bufferSize || options.buffersize || 100; | ||
options.flowControl = options.flowControl || options.flowcontrol || false; | ||
if (typeof fc == 'boolean') { | ||
options.rtscts = true; | ||
} else { | ||
fc.forEach(function (flowControl) { | ||
var fcup = flowControl.toUpperCase(); | ||
var idx = FLOWCONTROLS.indexOf(fcup); | ||
if (idx < 0) { | ||
throw new Error('Invalid "flowControl": ' + fcup + ". Valid options: "+FLOWCONTROLS.join(", ")); | ||
} else { | ||
// "XON", "XOFF", "XANY", "DTRDTS", "RTSCTS" | ||
switch (idx) { | ||
case 0: options.xon = true; break; | ||
case 1: options.xoff = true; break; | ||
case 2: options.xany = true; break; | ||
case 3: options.rtscts = true; break; | ||
} | ||
} | ||
}) | ||
} | ||
} | ||
options.bufferSize = options.bufferSize || options.buffersize || _options.buffersize; | ||
options.parser = options.parser || _options.parser; | ||
options.dataCallback = function (data) { | ||
options.parser(self, data); | ||
}; | ||
// options.dataReadyCallback = function () { | ||
// self.readStream._read(4024); | ||
// }; | ||
options.errorCallback = function (err) { | ||
self.emit('error', err); | ||
// console.log("sp err:", JSON.stringify(err)); | ||
self.emit('error', {spErr: err}); | ||
}; | ||
@@ -108,3 +165,3 @@ options.disconnectedCallback = function () { | ||
self.emit('error', new Error("Disconnected")); | ||
self.close(); | ||
// self.close(); | ||
}; | ||
@@ -114,2 +171,12 @@ | ||
path = '\\\\.\\' + path; | ||
} else { | ||
// All other platforms: | ||
this.fd = null; | ||
this.paused = true; | ||
this.bufferSize = options.bufferSize || 64 * 1024; | ||
this.readable = true; | ||
this.reading = false; | ||
if (options.encoding) | ||
this.setEncoding(this.encoding); | ||
} | ||
@@ -134,3 +201,3 @@ | ||
if (err) { | ||
self.emit('error', err); | ||
self.emit('error', {openErr: err}); | ||
if (callback) { callback(err); } | ||
@@ -140,11 +207,16 @@ return; | ||
if (process.platform !== 'win32') { | ||
self.readStream = fs.createReadStream(self.path, { bufferSize: self.options.bufferSize, fd: fd }); | ||
self.readStream.on("data", self.options.dataCallback); | ||
self.readStream.on("error", self.options.errorCallback); | ||
self.readStream.on("close", function () { | ||
self.close(); | ||
}); | ||
self.readStream.on("end", function () { | ||
self.emit('end'); | ||
}); | ||
// self.readStream = new SerialStream(self.fd, { bufferSize: self.options.bufferSize }); | ||
// self.readStream.on("data", self.options.dataCallback); | ||
// self.readStream.on("error", self.options.errorCallback); | ||
// self.readStream.on("close", function () { | ||
// self.close(); | ||
// }); | ||
// self.readStream.on("end", function () { | ||
// console.log(">>END"); | ||
// self.emit('end'); | ||
// }); | ||
// self.readStream.resume(); | ||
self.paused = false; | ||
self.serialPoller = new SerialPortBinding.SerialportPoller(self.fd, function() {self._read();}); | ||
self.serialPoller.start(); | ||
} | ||
@@ -172,3 +244,3 @@ | ||
if (err) { | ||
self.emit('error', err); | ||
self.emit('error', {spWriteErr: err}); | ||
} | ||
@@ -181,7 +253,116 @@ if (callback) { | ||
if (process.platform !== 'win32') { | ||
SerialPort.prototype._read = function() { | ||
var self = this; | ||
// console.log(">>READ"); | ||
if (!self.readable || self.paused || self.reading) return; | ||
self.reading = true; | ||
if (!pool || pool.length - pool.used < kMinPoolSpace) { | ||
// discard the old pool. Can't add to the free list because | ||
// users might have refernces to slices on it. | ||
pool = null; | ||
allocNewPool(); | ||
} | ||
// Grab another reference to the pool in the case that while we're in the | ||
// thread pool another read() finishes up the pool, and allocates a new | ||
// one. | ||
var thisPool = pool; | ||
var toRead = Math.min(pool.length - pool.used, ~~self.bufferSize); | ||
var start = pool.used; | ||
function afterRead(err, bytesRead, readPool, bytesRequested) { | ||
self.reading = false; | ||
if (err) { | ||
if (err.code && err.code == 'EAGAIN') { | ||
if (self.fd >= 0) | ||
self.serialPoller.start(); | ||
} else { | ||
self.fd = null; | ||
self.options.errorCallback(err); | ||
self.readable = false; | ||
return; | ||
} | ||
} | ||
// Since we will often not read the number of bytes requested, | ||
// let's mark the ones we didn't need as available again. | ||
pool.used -= bytesRequested - bytesRead; | ||
// console.log(">>ACTUALLY READ: ", bytesRead); | ||
if (bytesRead === 0) { | ||
if (self.fd >= 0) | ||
self.serialPoller.start(); | ||
} else { | ||
var b = thisPool.slice(start, start + bytesRead); | ||
// do not emit events if the stream is paused | ||
if (self.paused) { | ||
self.buffer = Buffer.concat([self.buffer, b]); | ||
return; | ||
} else { | ||
self._emitData(b); | ||
} | ||
// do not emit events anymore after we declared the stream unreadable | ||
if (!self.readable) return; | ||
self._read(); | ||
} | ||
} | ||
// console.log(">>REQUEST READ: ", toRead); | ||
fs.read(self.fd, pool, pool.used, toRead, self.pos, function(err, bytesRead){ | ||
var readPool = pool; | ||
var bytesRequested = toRead; | ||
afterRead(err, bytesRead, readPool, bytesRequested);} | ||
); | ||
pool.used += toRead; | ||
}; | ||
SerialPort.prototype._emitData = function(d) { | ||
var self = this; | ||
// if (self._decoder) { | ||
// var string = self._decoder.write(d); | ||
// if (string.length) self.options.dataCallback(string); | ||
// } else { | ||
self.options.dataCallback(d); | ||
// } | ||
}; | ||
SerialPort.prototype.pause = function() { | ||
var self = this; | ||
self.paused = true; | ||
}; | ||
SerialPort.prototype.resume = function() { | ||
var self = this; | ||
self.paused = false; | ||
if (self.buffer) { | ||
var buffer = self.buffer; | ||
self.buffer = null; | ||
self._emitData(buffer); | ||
} | ||
// No longer open? | ||
if (null == self.fd) | ||
return; | ||
self._read(); | ||
}; | ||
} // if !'win32' | ||
SerialPort.prototype.close = function (callback) { | ||
var self = this; | ||
var fd = this.fd; | ||
this.fd = 0; | ||
var fd = self.fd; | ||
@@ -202,2 +383,5 @@ if (self.closing) { | ||
if (self.readStream) { | ||
// Make sure we clear the readStream's fd, or it'll try to close() it. | ||
// We already close()d it. | ||
self.readStream.fd = null; | ||
self.readStream.destroy(); | ||
@@ -216,2 +400,8 @@ } | ||
self.closing = false; | ||
self.fd = 0; | ||
if (process.platform !== 'win32') { | ||
self.readable = false; | ||
self.serialPoller.close(); | ||
} | ||
}); | ||
@@ -293,3 +483,3 @@ } catch (ex) { | ||
var self = this; | ||
var fd = this.fd; | ||
var fd = self.fd; | ||
@@ -296,0 +486,0 @@ if (!fd) { |
@@ -16,7 +16,2 @@ // To test with a z-wave device, I recommend: http://www.aeon-labs.com/site/products/view/2/ | ||
}); | ||
*/ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
628179
46
679
+ Addedbindings@1.1.1(transitive)
- Removedbindings@1.1.0(transitive)
Updatedbindings@1.1.1