Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Rewrote encodeString based on ActionScript version in Mikrotik API wiki.

Fixed hexDump function.
Added getChannel function to Connection object to retrieve a previously
closed channel.
Removed "deferring closing connection" log message.
  • Loading branch information...
commit adc4232a7e928f2f2b5449aa1b600fd572d7f820 1 parent 4d1b9a3
@Trakkasure authored
Showing with 76 additions and 44 deletions.
  1. +74 −42 lib/index.js
  2. +2 −2 package.json
View
116 lib/index.js
@@ -7,54 +7,75 @@ var emptyString=String.fromCharCode(0);
var api;
(function(){
-/**
- * Parse !re return records into an array of objects
- */
/*
* Instance methods of the connection object (returned after calling new)
*/
+
+/* thanks to Håkon Nessjøen of Avelia AS for the Action Script version where this function is 100% derived. */
function encodeString(s) {
- var l=s.length;
- var r;
- if (l < 0x80) {
- r = String.fromCharCode(l);
- } else if (l < 0x4000) {
- r |= 0x8000;
- r = String.fromCharCode( (l >> 8) & 0xFF) + String.fromCharCode(l & 0xFF);
- } else if (l < 0x200000) {
- r |= 0xC00000;
- r = String.fromCharCode( (l >> 8) & 0xFF) + String.fromCharCode( (l >> 8) & 0xFF) + String.fromCharCode(l & 0xFF);
- } else if (l < 0x10000000) {
- r |= 0xE0000000;
- r = String.fromCharCode( (l >> 8) & 0xFF) + String.fromCharCode( (l >> 8) & 0xFF) + String.fromCharCode( (l >> 8) & 0xFF) + String.fromCharCode(l & 0xFF);
- } else if (l >= 0x10000000)
- l = String.fromCharCode(0xF0) + String.fromCharCode( (l >> 8) & 0xFF) + String.fromCharCode( (l >> 8) & 0xFF) + String.fromCharCode( (l >> 8) & 0xFF) + String.fromCharCode(l & 0xFF);
- return r+s;
+ var data = null;
+ var len = Buffer.byteLength(s);
+ var offset=0;
+
+ if (len < 0x80) {
+ data=new Buffer(len+1);
+ data[offset++]=len;
+ } else
+ if (len < 0x4000) {
+ data=new Buffer(len+2);
+ len |= 0x8000;
+ data[offset++]=(len >> 8) & 0xff;
+ data[offset++]=len & 0xff;
+ } else
+ if (len < 0x200000) {
+ data=new Buffer(len+3);
+ len |= 0xC00000;
+ data[offset++]=(len >> 16) & 0xff;
+ data[offset++]=(len >> 8) & 0xff;
+ data[offset++]=len & 0xff;
+ } else
+ if (len < 0x10000000) {
+ data=new Buffer(len+4);
+ len |= 0xE0000000;
+ data[offset++]=(len >> 24) & 0xff;
+ data[offset++]=(len >> 16) & 0xff;
+ data[offset++]=(len >> 8) & 0xff;
+ data[offset++]=len & 0xff;
+ } else {
+ data=new Buffer(len+5);
+ data[offset++]=0xF0;
+ data[offset++]=(len >> 24) & 0xff;
+ data[offset++]=(len >> 16) & 0xff;
+ data[offset++]=(len >> 8) & 0xff;
+ data[offset++]=len & 0xff;
+ }
+ data.utf8Write(s,offset);
+ return data;
}
function decodeLength(data){ // Ported from the PHP API on the Wiki. Thanks
- var idx=0;
- var b=data[idx++];
- if (b&128) {
- if ((b&192)==128) {
- len=((b&63)<<8)+data[idx++];
+var idx=0;
+var b=data[idx++];
+if (b&128) {
+ if ((b&192)==128) {
+ len=((b&63)<<8)+data[idx++];
+ } else {
+ if ((b & 224) == 192) {
+ len = ((b & 31) << 8 ) + data[idx++];
+ len = (len << 8 ) + data[idx++];
} else {
- if ((b & 224) == 192) {
- len = ((b & 31) << 8 ) + data[idx++];
+ if ((b & 240) == 224) {
+ len = ((b & 15) << 8 ) + data[idx++];
+ len = (len << 8 ) + data[idx++];
len = (len << 8 ) + data[idx++];
} else {
- if ((b & 240) == 224) {
- len = ((b & 15) << 8 ) + data[idx++];
- len = (len << 8 ) + data[idx++];
- len = (len << 8 ) + data[idx++];
- } else {
- len = data[idx++];
- len = (len << 8 ) + data[idx++];
- len = (len << 8 ) + data[idx++];
- len = (len << 8 ) + data[idx++];
- }
+ len = data[idx++];
+ len = (len << 8 ) + data[idx++];
+ len = (len << 8 ) + data[idx++];
+ len = (len << 8 ) + data[idx++];
}
}
+ }
} else {
len=b;
}
@@ -208,8 +229,8 @@ function hexDump(data) {
else cref[i]=String.fromCharCode(data[j])
hex[i]=Number(data[j]).toString(16);
while (hex[i].length < 2) hex[i] = "0" + hex[i];
- if (j==8) {
- console.log(hex.join(' ')+' '+ cref.join('') )
+ if (hex.length==8) {
+ console.log("%d: %s %s",j-7,hex.join(' '),cref.join('') );
hex=[];
cref=[];
}
@@ -221,7 +242,7 @@ function hexDump(data) {
}
}
api.prototype.read=function(data) { // This is the handler for when the socket receives data. Don't call instance function directly
- if (this.debug>2) {
+ if (this.debug>4) {
hexDump(data);
//util.debug('read: new packet:'+);
}
@@ -276,7 +297,7 @@ api.prototype.write=function(a) { // This shouldn't be called directly. Please u
else if (!Array.isArray(a)) return;
var self=this;
a.forEach(function(i){
- if (this.debug>2)
+ if (self.debug>2)
util.debug('write: sending '+i);
self.socket.write(encodeString(i));
});
@@ -289,7 +310,7 @@ api.prototype.connect=function(connectHandler) {
this.connecting=true;
var self=this;
this.socket.on('data',function(a){self.read(a)});
- this.socket.on('error',function(a){
+ this.socket.on('eerror',function(a){
if (self.debug>1)
util.log('Connection error: '+a);
self.socket.destroy();
@@ -442,6 +463,14 @@ function Connection(instance) {
o.addListener('close',function(){if ((instance.closing||instance.closeOnDone)&&Object.keys(instance.channel).length) self.close();});
return o;
},
+ getChannel:function(id) {
+ if (!id && id!==0)
+ throw('Missing channel ID parameter'+id);
+ if (!instance.channel[id]) throw('Channel does not exist '+id);
+ if (instance.debug>0)
+ util.debug('Getting channel: '+id);
+ return instance.channel[id];
+ },
write: function(a){return instance.write(a)},
closeChannel:function(id) {
if (!id) throw("Missing ID for stream channel to close.");
@@ -466,7 +495,7 @@ function Connection(instance) {
}
if (!force&&Object.keys(instance.channel).length>0) {
instance.closing=true;
- console.log('deferring closing connection');
+ if (instance.debug>1) console.log('deferring closing connection');
return;
}
if (instance.debug>0)
@@ -497,6 +526,9 @@ function Connection(instance) {
}
util.inherits(Connection,events.EventEmitter);
api._conn={};
+/**
+ * Parse !re return records into an array of objects
+ */
MikroNode.parseItems=function(data) {
var db=[];
var idx=0;
View
4 package.json
@@ -1,14 +1,14 @@
{
"name": "mikronode",
"description": "Mikrotik API implemented in Node",
- "version": "0.3.0",
+ "version": "0.3.1",
"author": "Brandon Myers <trakkasure@gmail.com>",
"contributors": [
{ "name": "Brandon Myers", "email": "trakkasure@gmail.com" }
],
"keywords": ["mikrotik", "socket", "api"],
"repository": "git://github.com/trakkasure/mikronode",
- "bugs" : "https://github.com/Trakkasure/mikronode/issues"
+ "bugs" : "https://github.com/Trakkasure/mikronode/issues",
"main": "lib/index",
"engines": { "node": ">= 0.3.8" }
}
Please sign in to comment.
Something went wrong with that request. Please try again.