diff --git a/README.md b/README.md index 64249cc..ffb19a2 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ telnet features. | Echo | `'echo'` | [RFC857](http://tools.ietf.org/html/rfc857) | Suppress Go Ahead | `'suppress go ahead'` | [RFC858](http://tools.ietf.org/html/rfc858) | Window Size | `'window size'` | [RFC1073](http://tools.ietf.org/html/rfc1073) - +| Com Port Option | `'com port option'` | [RFC2217](http://tools.ietf.org/html/rfc2217) Installation ------------ @@ -49,6 +49,11 @@ telnet.createServer(function (client) { } }) + // listen for com port option events from the client + client.on('com port option', function (c) { + console.log('com port set %s to %d', c.name, c.value) + }) + // listen for the actual data from the client client.on('data', function (b) { client.write(b) diff --git a/lib/telnet.js b/lib/telnet.js index c2e53d5..b0be9c8 100644 --- a/lib/telnet.js +++ b/lib/telnet.js @@ -116,11 +116,7 @@ var OPTIONS = { EXOPL: 255 // http://tools.ietf.org/html/rfc861 }; -var OPTION_NAMES = Object.keys(OPTIONS).reduce(function(out, key) { - var value = OPTIONS[key]; - out[value] = key.toLowerCase(); - return out; -}, {}); +var OPTION_NAMES = generateReverseLookup(OPTIONS); var SUB = { IS: 0, @@ -132,6 +128,23 @@ var SUB = { USER_VARIABLE: 3 }; +var COM_PORT_OPTIONS = { + BAUDRATE: 1, + DATASIZE: 2, + PARITY: 3, + STOPSIZE: 4, + CONTROL: 5 +}; + +var COM_PORT_OPTION_NAMES = generateReverseLookup(COM_PORT_OPTIONS); + +function generateReverseLookup(table) { + return Object.keys(table).reduce(function(out, key) { + var value = table[key]; + out[value] = key.toLowerCase(); + return out; + }, {}); +} /** * Client */ @@ -676,6 +689,43 @@ Client.prototype.terminal_type = function(cmd) { return i; }; +Client.prototype.com_port_option = function(cmd) { + var data = cmd.data; + var i = 0; + if (data.length < 7) return -1; + var iac1 = data.readUInt8(i++); + var sb = data.readUInt8(i++); + var option = data.readUInt8(i++); + var command = data.readUInt8(i++); + var valueBytes = ""; + for (var s = i; i < data.length; i++) { + if (data[i] === COMMANDS.IAC) { + valueBytes = data.slice(s, i); + break; + } + } + if(valueBytes.length === 0 || valueBytes.length > 4) + return -1; + if(typeof COM_PORT_OPTION_NAMES[command] === "undefined") + return -1; + // pad to 4 bytes + valueBytes = Buffer.concat([Buffer([0,0,0]), valueBytes]).slice(-4); + var value = valueBytes.readUInt32BE(); + var iac2 = data.readUInt8(i++); + var se = data.readUInt8(i++); + assert(iac1 === COMMANDS.IAC); + assert(sb === COMMANDS.SB); + assert(option === OPTIONS.COM_PORT_OPTION); + assert(Number.isInteger(value) && value >= 0); + assert(iac2 === COMMANDS.IAC); + assert(se === COMMANDS.SE); + this.emit("com port option", { + name: COM_PORT_OPTION_NAMES[command], + value: value + }); + return i; +}; + Client.prototype._setRawMode = function(mode) { this.isRaw = mode; if (!this.writable) return; diff --git a/test/test.js b/test/test.js index 29b66cc..f17afb5 100644 --- a/test/test.js +++ b/test/test.js @@ -24,7 +24,7 @@ describe('telnet', function () { done(); }); }); - + /* after(function (done) { client.end(function () { client = null; @@ -34,7 +34,7 @@ describe('telnet', function () { }); }); }); - + */ it('should be listening on port ' + port, function (done) { client = net.connect({port: port}, function () { done();