1
0
Fork 0
mirror of https://github.com/Ylianst/MeshCentral.git synced 2025-03-09 15:40:18 +00:00

Improved MeshAgent and MeshCmd.

This commit is contained in:
Ylian Saint-Hilaire 2018-01-25 16:12:53 -08:00
parent c3144c097a
commit a5e5611cbe
17 changed files with 198 additions and 154 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -800,7 +800,7 @@ function createMeshCore(agent) {
}
case 'info': { // Return information about the agent and agent core module
response = 'Current Core: ' + obj.meshCoreInfo + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform Info: ' + process.platform + '.\r\nCapabilities: ' + obj.meshCoreCapabilities + '.\r\nServer URL: ' + mesh.ServerUrl + '.';
if (amtLmsState >= 0) { response += '\r\nBuilt -in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amtLmsState] + '.'; }
if (amtLmsState >= 0) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amtLmsState] + '.'; }
response += '\r\nModules: ' + JSON.stringify(addedModules) + '';
response += '\r\nServerConnected: ' + mesh.isControlChannelConnected + '';
var oldNodeId = db.Get('OldNodeId');

View file

@ -467,18 +467,18 @@ function AmtStackCreateService(wsmanStack) {
obj.AMT_MessageLog_PositionToFirstRecord(_GetMessageLog0, [func, tag, []]);
}
function _GetMessageLog0(stack, name, responses, status, tag) {
if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2]); return; }
if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; }
obj.AMT_MessageLog_GetRecords(responses.Body["IterationIdentifier"], 390, _GetMessageLog1, tag);
}
function _GetMessageLog1(stack, name, responses, status, tag) {
if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2]); return; }
if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2], status); return; }
var i, j, x, e, AmtMessages = tag[2], t = new Date(), TimeStamp, ra = responses.Body["RecordArray"];
if (typeof ra === 'string') { responses.Body["RecordArray"] = [responses.Body["RecordArray"]]; }
for (i in ra) {
e = Buffer.from(ra[i], 'base64');
if (e != null) {
TimeStamp = ReadIntXBuf(e, 0);
TimeStamp = ReadIntX(e, 0);
if ((TimeStamp > 0) && (TimeStamp < 0xFFFFFFFF)) {
x = { 'DeviceAddress': e[4], 'EventSensorType': e[5], 'EventType': e[6], 'EventOffset': e[7], 'EventSourceType': e[8], 'EventSeverity': e[9], 'SensorNumber': e[10], 'Entity': e[11], 'EntityInstance': e[12], 'EventData': [], 'Time': new Date((TimeStamp + (t.getTimezoneOffset() * 60)) * 1000) };
for (j = 13; j < 21; j++) { x['EventData'].push(e[j]); }
@ -678,17 +678,17 @@ function AmtStackCreateService(wsmanStack) {
// TODO: Just put some of them here, but many more still need to be added, helpful link here:
// https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Fsecurityadminevents.htm
obj.GetAuditLogExtendedDataStr = function (id, data) {
if ((id == 1602 || id == 1604) && data.charCodeAt(0) == 0) { return data.substring(2, 2 + data.charCodeAt(1)); } // ACL Entry Added/Removed (Digest)
if (id == 1603) { if (data.charCodeAt(1) == 0) { return data.substring(3); } return null; } // ACL Entry Modified
if (id == 1605) { return ["Invalid ME access", "Invalid MEBx access"][data.charCodeAt(0)]; } // ACL Access with Invalid Credentials
if (id == 1606) { var r = ["Disabled", "Enabled"][data.charCodeAt(0)]; if (data.charCodeAt(1) == 0) { r += ", " + data.substring(3); } return r;} // ACL Entry State
if (id == 1607) { return "Remote " + ["NoAuth", "ServerAuth", "MutualAuth"][data.charCodeAt(0)] + ", Local " + ["NoAuth", "ServerAuth", "MutualAuth"][data.charCodeAt(1)]; } // TLS State Changed
if (id == 1617) { return obj.RealmNames[ReadInt(data, 0)] + ", " + ["NoAuth", "Auth", "Disabled"][data.charCodeAt(4)]; } // Set Realm Authentication Mode
if (id == 1619) { return ["BIOS", "MEBx", "Local MEI", "Local WSMAN", "Remote WSAMN"][data.charCodeAt(0)]; } // Intel AMT Unprovisioning Started
if ((id == 1602 || id == 1604) && data[0] == 0) { return data.splice(2, 2 + data[1]).toString(); } // ACL Entry Added/Removed (Digest)
if (id == 1603) { if (data[1] == 0) { return data.splice(3).toString(); } return null; } // ACL Entry Modified
if (id == 1605) { return ["Invalid ME access", "Invalid MEBx access"][data[0]]; } // ACL Access with Invalid Credentials
if (id == 1606) { var r = ["Disabled", "Enabled"][data[0]]; if (data[1] == 0) { r += ", " + data[3]; } return r; } // ACL Entry State
if (id == 1607) { return "Remote " + ["NoAuth", "ServerAuth", "MutualAuth"][data[0]] + ", Local " + ["NoAuth", "ServerAuth", "MutualAuth"][data[1]]; } // TLS State Changed
if (id == 1617) { return obj.RealmNames[ReadInt(data, 0)] + ", " + ["NoAuth", "Auth", "Disabled"][data[4]]; } // Set Realm Authentication Mode
if (id == 1619) { return ["BIOS", "MEBx", "Local MEI", "Local WSMAN", "Remote WSAMN"][data[0]]; } // Intel AMT Unprovisioning Started
if (id == 1900) { return "From " + ReadShort(data, 0) + "." + ReadShort(data, 2) + "." + ReadShort(data, 4) + "." + ReadShort(data, 6) + " to " + ReadShort(data, 8) + "." + ReadShort(data, 10) + "." + ReadShort(data, 12) + "." + ReadShort(data, 14); } // Firmware Updated
if (id == 2100) { var t4 = new Date(); t4.setTime(ReadInt(data, 0) * 1000 + (new Date().getTimezoneOffset() * 60000)); return t4.toLocaleString(); } // Intel AMT Time Set
if (id == 3000) { return "From " + ["None", "KVM", "All"][data.charCodeAt(0)] + " to " + ["None", "KVM", "All"][data.charCodeAt(1)]; } // Opt-In Policy Change
if (id == 3001) { return ["Success", "Failed 3 times"][data.charCodeAt(0)]; } // Send Consent Code Event
if (id == 3000) { return "From " + ["None", "KVM", "All"][data[0]] + " to " + ["None", "KVM", "All"][data[1]]; } // Opt-In Policy Change
if (id == 3001) { return ["Success", "Failed 3 times"][data[0]]; } // Send Consent Code Event
return null;
}
@ -697,22 +697,15 @@ function AmtStackCreateService(wsmanStack) {
}
function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; }
function ReadShort(v, p) { return (v.charCodeAt(p) << 8) + v.charCodeAt(p + 1); }
function ReadInt(v, p) { return (v.charCodeAt(p) * 0x1000000) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
function ReadIntX(v, p) { return (v.charCodeAt(p + 3) * 0x1000000) + (v.charCodeAt(p + 2) << 16) + (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
function ReadIntXBuf(v, p) { return (v[p + 3] * 0x1000000) + (v[p + 2] << 16) + (v[p + 1] << 8) + v[p]; }
function ReadShort(v, p) { return (v[p] << 8) + v[p + 1]; }
function ReadInt(v, p) { return (v[p] * 0x1000000) + (v[p + 1] << 16) + (v[p + 2] << 8) + v[p + 3]; } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
function ReadIntX(v, p) { return (v[p + 3] * 0x1000000) + (v[p + 2] << 16) + (v[p + 1] << 8) + v[p]; }
function btoa(x) { return Buffer.from(x).toString('base64'); }
function atob(x) {
var z = null;
try {
z = Buffer.from(x, 'base64').toString();
} catch (e) { console.log(e); }
return z;
}
function atob(x) { var z = null; try { z = Buffer.from(x, 'base64').toString(); } catch (e) { console.log(e); } return z; }
function _GetAuditLog0(stack, name, responses, status, tag) {
if (status != 200) { tag[0](obj, [], status); return; }
var ptr, i, e, x, r = tag[1], t = new Date(), TimeStamp;
var ptr, i, e, es, x, r = tag[1], t = new Date(), TimeStamp;
if (responses.Body['RecordsReturned'] > 0) {
responses.Body['EventRecords'] = MakeToArray(responses.Body['EventRecords']);
@ -720,11 +713,13 @@ function AmtStackCreateService(wsmanStack) {
for (i in responses.Body['EventRecords']) {
e = null;
try {
e = atob(responses.Body['EventRecords'][i]);
} catch (e) {
console.log(e + " " + responses.Body['EventRecords'][i])
es = atob(responses.Body['EventRecords'][i]);
e = new Buffer(es);
} catch (ex) {
console.log(ex + " " + responses.Body['EventRecords'][i])
}
x = { 'AuditAppID': ReadShort(e, 0), 'EventID': ReadShort(e, 2), 'InitiatorType': e.charCodeAt(4) };
x = { 'AuditAppID': ReadShort(e, 0), 'EventID': ReadShort(e, 2), 'InitiatorType': e[4] };
x['AuditApp'] = _AmtAuditStringTable[x['AuditAppID']];
x['Event'] = _AmtAuditStringTable[(x['AuditAppID'] * 100) + x['EventID']];
if (!x['Event']) x['Event'] = '#' + x['EventID'];
@ -732,15 +727,15 @@ function AmtStackCreateService(wsmanStack) {
// Read and process the initiator
if (x['InitiatorType'] == 0) {
// HTTP digest
var userlen = e.charCodeAt(5);
x['Initiator'] = e.substring(6, 6 + userlen);
var userlen = e[5];
x['Initiator'] = e.slice(6, 6 + userlen).toString();
ptr = 6 + userlen;
}
if (x['InitiatorType'] == 1) {
// Kerberos
x['KerberosUserInDomain'] = ReadInt(e, 5);
var userlen = e.charCodeAt(9);
x['Initiator'] = GetSidString(e.substring(10, 10 + userlen));
var userlen = e[9];
x['Initiator'] = GetSidString(e.slice(10, 10 + userlen));
ptr = 10 + userlen;
}
if (x['InitiatorType'] == 2) {
@ -753,23 +748,23 @@ function AmtStackCreateService(wsmanStack) {
x['Initiator'] = '<i>KVM Default Port</i>';
ptr = 5;
}
// Read timestamp
TimeStamp = ReadInt(e, ptr);
x['Time'] = new Date((TimeStamp + (t.getTimezoneOffset() * 60)) * 1000);
ptr += 4;
// Read network access
x['MCLocationType'] = e.charCodeAt(ptr++);
var netlen = e.charCodeAt(ptr++);
x['NetAddress'] = e.substring(ptr, ptr + netlen);
x['MCLocationType'] = e[ptr++];
var netlen = e[ptr++];
x['NetAddress'] = e.slice(ptr, ptr + netlen).toString();
// Read extended data
ptr += netlen;
var exlen = e.charCodeAt(ptr++);
x['Ex'] = e.substring(ptr, ptr + exlen);
var exlen = e[ptr++];
x['Ex'] = e.slice(ptr, ptr + exlen);
x['ExStr'] = obj.GetAuditLogExtendedDataStr((x['AuditAppID'] * 100) + x['EventID'], x['Ex']);
r.push(x);
}
}

View file

@ -33,6 +33,7 @@ function CreateWsmanComm(host, port, user, pass, tls, extra) {
obj.pass = pass;
obj.tls = tls;
obj.digest = null;
obj.RequestCount = 0;
// Private method
// pri = priority, if set to 1, the call is high priority and put on top of the stack.
@ -58,13 +59,16 @@ function CreateWsmanComm(host, port, user, pass, tls, extra) {
obj.PerformAjaxEx = function (postdata, callback, tag, url, action) {
if (obj.FailAllError != 0) { if (obj.FailAllError != 999) { obj.gotNextMessagesError({ status: obj.FailAllError }, 'error', null, [postdata, callback, tag]); } return; }
if (!postdata) postdata = "";
// console.log("SEND: " + postdata); // DEBUG
//console.log("SEND: " + postdata); // DEBUG
// We are in a DukTape environement
if (obj.digest == null) { obj.digest = require('http-digest').create(obj.user, obj.pass); obj.digest.http = require('http'); }
var request = { protocol: (obj.tls == 1 ? 'https:' : 'http:'), method: 'POST', host: obj.host, path: '/wsman', port: obj.port };
var req = obj.digest.request(request,
function (response) {
var request = { protocol: (obj.tls == 1 ? 'https:' : 'http:'), method: 'POST', host: obj.host, path: '/wsman', port: obj.port, rejectUnauthorized: false, checkServerIdentity: function (cert) { console.log('checkServerIdentity', JSON.stringify(cert)); } };
var req = obj.digest.request(request);
//console.log('Request ' + (obj.RequestCount++));
req.on('error', function (e) { obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); });
req.on('response', function (response) {
//console.log('Response: ' + response.statusCode);
if (response.statusCode != 200) {
console.log('ERR:' + JSON.stringify(response));
obj.gotNextMessagesError({ status: response.statusCode }, 'error', null, [postdata, callback, tag]);
@ -74,11 +78,11 @@ function CreateWsmanComm(host, port, user, pass, tls, extra) {
response.on('end', function () { obj.gotNextMessages(response.acc, 'success', { status: response.statusCode }, [postdata, callback, tag]); });
}
});
req.on('error', function (e) { console.log(JSON.stringify(e)); obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); });
// Send POST body, this work with binary.
req.write(postdata);
req.end();
obj.ActiveAjaxCount++;
return req;
}
@ -101,7 +105,7 @@ function CreateWsmanComm(host, port, user, pass, tls, extra) {
obj.ActiveAjaxCount--;
if (obj.FailAllError == 999) return;
if (obj.FailAllError != 0) { callArgs[1](null, obj.FailAllError, callArgs[2]); return; }
// if (s != 200) { console.log("ERROR, status=" + status + "\r\n\r\nreq=" + callArgs[0]); } // Debug: Display the request & response if something did not work.
//if (status != 200) { console.log("ERROR, status=" + status + "\r\n\r\nreq=" + callArgs[0]); } // Debug: Display the request & response if something did not work.
if (obj.FailAllError != 999) { callArgs[1]({ Header: { HttpError: request.status } }, request.status, callArgs[2]); }
obj.PerformNextAjax();
}

View file

@ -16,6 +16,7 @@ limitations under the License.
var MemoryStream = require('MemoryStream');
var lme_id = 0;
var lme_port_offset = 0; // Debug: Set this to "-100" to bind to 16892 & 16893 and IN_ADDRANY. This is for LMS debugging.
var APF_DISCONNECT = 1;
@ -68,9 +69,7 @@ function stream_bufferedWrite() {
return (this._readCheckImmediate == undefined);
};
this.write = function (chunk) {
for (var args in arguments) {
if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; }
}
for (var args in arguments) { if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; } }
var tmp = Buffer.alloc(chunk.length);
chunk.copy(tmp);
this.buffer.push({ offset: 0, data: tmp });
@ -90,8 +89,7 @@ function stream_bufferedWrite() {
list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead));
this.buffer[0].offset += (size - bytesRead);
bytesRead += (size - bytesRead);
}
else {
} else {
// Reading the entire thing
list.push(this.buffer[0].data.slice(offset));
bytesRead += len;
@ -101,12 +99,9 @@ function stream_bufferedWrite() {
this._readCheckImmediate = setImmediate(function (buffered) {
buffered._readCheckImmediate = undefined;
if (buffered.buffer.length == 0) {
// drained
buffered.emit('drain');
}
else {
// not drained
buffered.emit('readable');
buffered.emit('drain'); // Drained
} else {
buffered.emit('readable'); // Not drained
}
}, this);
return (Buffer.concat(list));
@ -114,11 +109,13 @@ function stream_bufferedWrite() {
}
function lme_heci() {
function lme_heci(options) {
var emitterUtils = require('events').inherits(this);
emitterUtils.createEvent('error');
emitterUtils.createEvent('connect');
if (options.debug == true) { lme_port_offset = -100; } // LMS debug mode
var heci = require('heci');
this.INITIAL_RXWINDOW_SIZE = 4096;
@ -147,8 +144,7 @@ function lme_heci() {
outBuffer.write(name.toString(), 5);
this.write(outBuffer);
//console.log('Answering APF_SERVICE_REQUEST');
}
else {
} else {
//console.log('UNKNOWN APF_SERVICE_REQUEST');
}
break;
@ -166,10 +162,14 @@ function lme_heci() {
}
this[name][port] = require('net').createServer();
this[name][port].HECI = this;
this[name][port].listen({ port: port, host: '127.0.0.1' });
if (lme_port_offset == 0) {
this[name][port].listen({ port: port, host: '127.0.0.1' }); // Normal mode
} else {
this[name][port].listen({ port: (port + lme_port_offset) }); // Debug mode
}
this[name][port].on('connection', function (socket) {
//console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort);
this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort);
this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort - lme_port_offset);
});
var outBuffer = Buffer.alloc(5);
outBuffer.writeUInt8(81, 0);
@ -246,8 +246,7 @@ function lme_heci() {
if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) {
this.sockets[rChannelId].bufferedStream.emit('readable');
}
}
else {
} else {
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST');
}
break;
@ -265,8 +264,7 @@ function lme_heci() {
outBuffer.writeUInt32BE(written, 5);
this.HECI.write(outBuffer);
});
}
else {
} else {
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA');
}
break;
@ -281,8 +279,7 @@ function lme_heci() {
buffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
buffer.writeUInt32BE(amtId, 1);
this.write(buffer);
}
else {
} else {
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE');
}
break;
@ -309,12 +306,10 @@ function lme_heci() {
if (remoteFamily == 'IPv6') {
buffer.writeUInt32BE(3);
buffer.write('::1');
}
else {
} else {
buffer.writeUInt32BE(9);
buffer.write('127.0.0.1');
}
buffer.writeUInt32BE(localPort);
}
this._LME.write(buffer.buffer);

View file

@ -1,19 +1,3 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var MemoryStream = require('MemoryStream');
var WindowsWireless = new Buffer([
0x0A, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x5F, 0x53, 0x63, 0x61, 0x6E, 0x28, 0x29, 0x0A, 0x7B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x77, 0x6C, 0x61, 0x6E,
@ -187,7 +171,8 @@ function AccessPoint(_ssid, _bssid, _lq)
}
AccessPoint.prototype.toString = function ()
{
return (this.ssid + " [" + this.bssid + "]: " + this.lq);
return ("[" + this.bssid + "]: " + this.ssid + " (" + this.lq + ")");
//return (this.ssid + " [" + this.bssid + "]: " + this.lq);
}
function WiFiScanner()
@ -232,12 +217,12 @@ function WiFiScanner()
}
if (wlan != null)
{
this.child = require('ILibProcessPipe').CreateProcess("/sbin/iwlist", "iwlist", wlan, "scan");
this.child = require('child_process').execFile('/sbin/iwlist', ['iwlist', wlan, 'scan']);
this.child.parent = this;
this.child.ms = new MemoryStream();
this.child.ms.parent = this.child;
this.child.on('data', function (buffer) { this.ms.write(buffer); });
this.child.on('end', function () { this.ms.end(); });
this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); });
this.child.on('exit', function () { this.ms.end(); });
this.child.ms.on('end', function ()
{
var str = this.buffer.toString();
@ -263,6 +248,11 @@ function WiFiScanner()
{
_lq = lnblock.slice(13,lnblock.length-4);
}
else if (lnblock.startsWith('Quality='))
{
_lq = lnblock.slice(8, 10);
var scale = lnblock.slice(11, 13);
}
}
this.parent.parent.emit('accessPoint', new AccessPoint(_ssid, _bssid, _lq));
}

View file

@ -83,7 +83,7 @@ function AMTScanner() {
return ((num >> 24) & 0xFF) + '.' + ((num >> 16) & 0xFF) + '.' + ((num >> 8) & 0xFF) + '.' + (num & 0xFF);
}
this.scan = function (rangestr, timeout, func) {
this.scan = function (rangestr, timeout) {
var iprange = this.parseIPv4Range(rangestr);
var rmcp = this.buildRmcpPing(0);
var server = this.dgram.createSocket({ type: 'udp4' });
@ -97,7 +97,6 @@ function AMTScanner() {
//console.log("Server closed");
server.close();
server.parent.emit('found', server.scanResults);
if (func != null) { func(server.scanResults); }
delete server;
}, timeout);
};

View file

@ -16,6 +16,7 @@ limitations under the License.
var MemoryStream = require('MemoryStream');
var lme_id = 0;
var lme_port_offset = 0; // Debug: Set this to "-100" to bind to 16892 & 16893 and IN_ADDRANY. This is for LMS debugging.
var APF_DISCONNECT = 1;
@ -68,9 +69,7 @@ function stream_bufferedWrite() {
return (this._readCheckImmediate == undefined);
};
this.write = function (chunk) {
for (var args in arguments) {
if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; }
}
for (var args in arguments) { if (typeof (arguments[args]) == 'function') { this.once('drain', arguments[args]); break; } }
var tmp = Buffer.alloc(chunk.length);
chunk.copy(tmp);
this.buffer.push({ offset: 0, data: tmp });
@ -90,8 +89,7 @@ function stream_bufferedWrite() {
list.push(this.buffer[0].data.slice(offset, offset + size - bytesRead));
this.buffer[0].offset += (size - bytesRead);
bytesRead += (size - bytesRead);
}
else {
} else {
// Reading the entire thing
list.push(this.buffer[0].data.slice(offset));
bytesRead += len;
@ -101,12 +99,9 @@ function stream_bufferedWrite() {
this._readCheckImmediate = setImmediate(function (buffered) {
buffered._readCheckImmediate = undefined;
if (buffered.buffer.length == 0) {
// drained
buffered.emit('drain');
}
else {
// not drained
buffered.emit('readable');
buffered.emit('drain'); // Drained
} else {
buffered.emit('readable'); // Not drained
}
}, this);
return (Buffer.concat(list));
@ -114,11 +109,13 @@ function stream_bufferedWrite() {
}
function lme_heci() {
function lme_heci(options) {
var emitterUtils = require('events').inherits(this);
emitterUtils.createEvent('error');
emitterUtils.createEvent('connect');
if (options.debug == true) { lme_port_offset = -100; } // LMS debug mode
var heci = require('heci');
this.INITIAL_RXWINDOW_SIZE = 4096;
@ -147,8 +144,7 @@ function lme_heci() {
outBuffer.write(name.toString(), 5);
this.write(outBuffer);
//console.log('Answering APF_SERVICE_REQUEST');
}
else {
} else {
//console.log('UNKNOWN APF_SERVICE_REQUEST');
}
break;
@ -166,10 +162,14 @@ function lme_heci() {
}
this[name][port] = require('net').createServer();
this[name][port].HECI = this;
this[name][port].listen({ port: port, host: '127.0.0.1' });
if (lme_port_offset == 0) {
this[name][port].listen({ port: port, host: '127.0.0.1' }); // Normal mode
} else {
this[name][port].listen({ port: (port + lme_port_offset) }); // Debug mode
}
this[name][port].on('connection', function (socket) {
//console.log('New [' + socket.remoteFamily + '] TCP Connection on: ' + socket.remoteAddress + ' :' + socket.localPort);
this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort);
this.HECI.LMS.bindDuplexStream(socket, socket.remoteFamily, socket.localPort - lme_port_offset);
});
var outBuffer = Buffer.alloc(5);
outBuffer.writeUInt8(81, 0);
@ -246,8 +246,7 @@ function lme_heci() {
if (!this.sockets[rChannelId].bufferedStream.isEmpty() && this.sockets[rChannelId].bufferedStream.isWaiting()) {
this.sockets[rChannelId].bufferedStream.emit('readable');
}
}
else {
} else {
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_WINDOW_ADJUST');
}
break;
@ -265,8 +264,7 @@ function lme_heci() {
outBuffer.writeUInt32BE(written, 5);
this.HECI.write(outBuffer);
});
}
else {
} else {
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_DATA');
}
break;
@ -281,8 +279,7 @@ function lme_heci() {
buffer.writeUInt8(APF_CHANNEL_CLOSE, 0);
buffer.writeUInt32BE(amtId, 1);
this.write(buffer);
}
else {
} else {
//console.log('Unknown Recipient ID/' + rChannelId + ' for APF_CHANNEL_CLOSE');
}
break;
@ -309,12 +306,10 @@ function lme_heci() {
if (remoteFamily == 'IPv6') {
buffer.writeUInt32BE(3);
buffer.write('::1');
}
else {
} else {
buffer.writeUInt32BE(9);
buffer.write('127.0.0.1');
}
buffer.writeUInt32BE(localPort);
}
this._LME.write(buffer.buffer);