Updated to use singleton for PTHI

Bryan Roe committed Jul 14, 2021 at 09:41 UTC 521603053bbea9d993976a5e9a4d02971ddb2c88
2 files changed +286 -297
agents/modules_meshcmd/amt-mei.js
+143 -148
@@ -1,5 +1,5 @@
1 /*
2 -Copyright 2018-2021 Intel Corporation
2 +Copyright 2018-2020 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
@@ -15,7 +15,10 @@ limitations under the License.
15 */
16
17 var Q = require('queue');
18 -function amt_heci() {
18 +var g_internal = null;
19 +
20 +function amt_heci()
21 +{
22 var emitterUtils = require('events').inherits(this);
23 emitterUtils.createEvent('error');
24
@@ -23,60 +26,86 @@ function amt_heci() {
26 var sendConsole = function (msg) { try { require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": msg }); } catch (ex) { } }
27
28 this._ObjectID = "pthi";
26 - this._rq = new Q();
27 - this._setupPTHI = function _setupPTHI() {
28 - this._amt = heci.create();
29 - this._amt.descriptorMetadata = "amt-pthi";
30 - this._amt.BiosVersionLen = 65;
31 - this._amt.UnicodeStringLen = 20;
32 -
33 - this._amt.Parent = this;
34 - this._amt.on('error', function _amtOnError(e) {
35 - if (this.Parent._rq.isEmpty()) {
36 - this.Parent.emit('error', e); // No pending requests, so propagate the error up
37 - }
38 - else {
39 - // There is a pending request, so fail the pending request
40 - var user = this.Parent._rq.deQueue();
41 - var params = user.optional;
42 - var callback = user.func;
43 - params.unshift({ Status: -1 }); // Relay an error
44 - callback.apply(this.Parent, params);
45 -
46 - if (!this.Parent._rq.isEmpty()) {
47 - // There are still more pending requests, so try to re-helpconnect MEI
48 - this.connect(heci.GUIDS.AMT, { noPipeline: 1 });
29 + var that = this;
30 + if (g_internal == null)
31 + {
32 + g_internal = { _rq: new Q(), _amt: null };
33 + g_internal._setupPTHI = function _g_setupPTHI()
34 + {
35 + console.info1('setupPTHI()');
36 + this._amt = heci.create();
37 + this._amt.descriptorMetadata = "amt-pthi";
38 + this._amt.BiosVersionLen = 65;
39 + this._amt.UnicodeStringLen = 20;
40 + this._amt.Parent = that;
41 +
42 + this._amt.on('error', function _amtOnError(e)
43 + {
44 + console.info1('PTHIError: ' + e);
45 + if (this.Parent._rq.isEmpty())
46 + {
47 + console.info1(' Queue is empty');
48 + this.Parent.emit('error', e); // No pending requests, so propagate the error up
49 }
50 - }
51 - });
52 - this._amt.on('connect', function _amtOnConnect() {
53 - this.on('data', function _amtOnData(chunk) {
54 - //console.log("Received: " + chunk.length + " bytes");
55 - var header = this.Parent.getCommand(chunk);
56 - //console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
57 -
58 - var user = this.Parent._rq.deQueue();
59 - var params = user.optional;
60 - var callback = user.func;
61 -
62 - params.unshift(header);
63 - callback.apply(this.Parent, params);
64 -
65 - if (this.Parent._rq.isEmpty()) {
66 - // No More Requests, we can close PTHI
67 - this.Parent._amt.disconnect();
68 - this.Parent._amt = null;
69 - }
70 - else {
71 - // Send the next request
72 - this.write(this.Parent._rq.peekQueue().send);
50 + else
51 + {
52 + console.info1(' Queue is NOT empty');
53 +
54 + // There is a pending request, so fail the pending request
55 + var user = this.Parent._rq.deQueue();
56 + var params = user.optional;
57 + var callback = user.func;
58 + params.unshift({ Status: -1 }); // Relay an error
59 + callback.apply(this.Parent, params);
60 +
61 + if (!this.Parent._rq.isEmpty())
62 + {
63 + // There are still more pending requests, so try to re-helpconnect MEI
64 + this.connect(heci.GUIDS.AMT, { noPipeline: 1 });
65 + }
66 }
67 });
68 + this._amt.on('connect', function _amtOnConnect()
69 + {
70 + this.on('data', function _amtOnData(chunk)
71 + {
72 + //console.log("Received: " + chunk.length + " bytes");
73 + var header = this.Parent.getCommand(chunk);
74 + console.info1("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
75 +
76 + var user = g_internal._rq.deQueue();
77 + var params = user.optional;
78 + var callback = user.func;
79 +
80 + params.unshift(header);
81 + callback.apply(this.Parent, params);
82 +
83 + if (g_internal._rq.isEmpty())
84 + {
85 + console.info1('No more requests, disconnecting');
86 +
87 + // No More Requests, we can close PTHI
88 + g_internal._amt.disconnect();
89 + g_internal._amt = null;
90 + }
91 + else
92 + {
93 + // Send the next request
94 + console.info1('Sending Next Request');
95 + this.write(g_internal._rq.peekQueue().send);
96 + }
97 + });
98 +
99 + // Start sending requests
100 + this.write(g_internal._rq.peekQueue().send);
101 + });
102
76 - // Start sending requests
77 - this.write(this.Parent._rq.peekQueue().send);
78 - });
79 - };
103 +
104 +
105 + };
106 + }
107 +
108 +
109 function trim(x) { var y = x.indexOf('\0'); if (y >= 0) { return x.substring(0, y); } else { return x; } }
110 this.getCommand = function getCommand(chunk) {
111 var command = chunk.length == 0 ? (this._rq.peekQueue().cmd | 0x800000) : chunk.readUInt32LE(4);
@@ -84,19 +113,30 @@ function amt_heci() {
113 return (ret);
114 };
115
87 - this.sendCommand = function sendCommand() {
116 + this.sendCommand = function sendCommand()
117 + {
118 if (arguments.length < 3 || typeof (arguments[0]) != 'number' || typeof (arguments[1]) != 'object' || typeof (arguments[2]) != 'function') { throw ('invalid parameters'); }
119 var args = [];
120 for (var i = 3; i < arguments.length; ++i) { args.push(arguments[i]); }
121
122 + console.info1('sendCommand(' + arguments[0] + ')', this._hashCode());
123 +
124 var header = Buffer.from('010100000000000000000000', 'hex');
125 header.writeUInt32LE(arguments[0] | 0x04000000, 4);
126 header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8);
95 - this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args, send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]])) });
127
97 - if (!this._amt) {
98 - this._setupPTHI();
99 - this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
128 + //this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args, send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]])) });
129 + //if(!this._amt)
130 + //{
131 + // this._setupPTHI();
132 + // this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
133 + //}
134 +
135 + g_internal._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args, send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]])) });
136 + if (!g_internal._amt)
137 + {
138 + g_internal._setupPTHI();
139 + g_internal._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
140 }
141 }
142
@@ -105,10 +145,11 @@ function amt_heci() {
145 for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
146 this.sendCommand(26, null, function (header, fn, opt) {
147 if (header.Status == 0) {
108 - var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, this._amt.BiosVersionLen).toString(), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4);
109 - for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen); ++i) {
110 - val.Versions[i] = { Description: v.slice(2, v.readUInt16LE(0) + 2).toString(), Version: v.slice(4 + this._amt.UnicodeStringLen, 4 + this._amt.UnicodeStringLen + v.readUInt16LE(2 + this._amt.UnicodeStringLen)).toString() };
111 - v = v.slice(4 + (2 * this._amt.UnicodeStringLen));
148 + var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, g_internal._amt.BiosVersionLen).toString(), Versions: [] }, v = CodeVersion.slice(g_internal._amt.BiosVersionLen + 4);
149 + for (i = 0; i < CodeVersion.readUInt32LE(g_internal._amt.BiosVersionLen) ; ++i)
150 + {
151 + val.Versions[i] = { Description: v.slice(2, v.readUInt16LE(0) + 2).toString(), Version: v.slice(4 + g_internal._amt.UnicodeStringLen, 4 + g_internal._amt.UnicodeStringLen + v.readUInt16LE(2 + g_internal._amt.UnicodeStringLen)).toString() };
152 + v = v.slice(4 + (2 * g_internal._amt.UnicodeStringLen));
153 }
154 if (val.BiosVersion.indexOf('\0') > 0) { val.BiosVersion = val.BiosVersion.substring(0, val.BiosVersion.indexOf('\0')); }
155 opt.unshift(val);
@@ -291,27 +332,34 @@ function amt_heci() {
332 this.getLocalSystemAccount = function getLocalSystemAccount(callback) {
333 var optional = [];
334 for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
294 - this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt) {
295 - if (header.Status == 0 && header.Data.length == 68) {
335 + this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt)
336 + {
337 + if (header.Status == 0 && header.Data.length == 68)
338 + {
339 opt.unshift({ user: trim(header.Data.slice(0, 33).toString()), pass: trim(header.Data.slice(33, 67).toString()), raw: header.Data });
340 }
298 - else {
341 + else
342 + {
343 opt.unshift(null);
344 }
345 fn.apply(this, opt);
346 }, callback, optional);
347 }
304 - this.getLanInterfaceSettings = function getLanInterfaceSettings(index, callback) {
348 + this.getLanInterfaceSettings = function getLanInterfaceSettings(index, callback)
349 + {
350 var optional = [];
351 for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
352 var ifx = Buffer.alloc(4);
353 ifx.writeUInt32LE(index);
309 - this.sendCommand(0x48, ifx, function onGetLanInterfaceSettings(header, fn, opt) {
310 - if (header.Status == 0) {
354 + this.sendCommand(0x48, ifx, function onGetLanInterfaceSettings(header, fn, opt)
355 + {
356 + if(header.Status == 0)
357 + {
358 var info = {};
359 info.enabled = header.Data.readUInt32LE(0);
360 info.dhcpEnabled = header.Data.readUInt32LE(8);
314 - switch (header.Data[12]) {
361 + switch(header.Data[12])
362 + {
363 case 1:
364 info.dhcpMode = 'ACTIVE'
365 break;
@@ -323,13 +371,14 @@ function amt_heci() {
371 break;
372 }
373 info.mac = header.Data.slice(14).toString('hex:');
326 -
374 +
375 var addr = header.Data.readUInt32LE(4);
376 info.address = ((addr >> 24) & 255) + '.' + ((addr >> 16) & 255) + '.' + ((addr >> 8) & 255) + '.' + (addr & 255);
377 opt.unshift(info);
378 fn.apply(this, opt);
379 }
332 - else {
380 + else
381 + {
382 opt.unshift(null);
383 fn.apply(this, opt);
384 }
@@ -346,32 +395,32 @@ function amt_heci() {
395 fn.apply(this, opt);
396 }, callback, optional);
397 }
349 - this.startConfiguration = function startConfiguration(callback) {
398 + this.startConfiguration = function startConfiguration() {
399 var optional = [];
351 - for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
352 - this.sendCommand(0x29, null, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
400 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
401 + this.sendCommand(0x29, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
402 }
354 - this.stopConfiguration = function stopConfiguration(callback) {
403 + this.stopConfiguration = function stopConfiguration() {
404 var optional = [];
356 - for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
357 - this.sendCommand(0x5E, null, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
405 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
406 + this.sendCommand(0x5E, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
407 }
359 - this.openUserInitiatedConnection = function openUserInitiatedConnection(callback) {
408 + this.openUserInitiatedConnection = function openUserInitiatedConnection() {
409 var optional = [];
361 - for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
362 - this.sendCommand(0x44, null, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
410 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
411 + this.sendCommand(0x44, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
412 }
364 - this.closeUserInitiatedConnection = function closeUnserInitiatedConnected(callback) {
413 + this.closeUserInitiatedConnection = function closeUnserInitiatedConnected() {
414 var optional = [];
366 - for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
367 - this.sendCommand(0x45, null, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
415 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
416 + this.sendCommand(0x45, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
417 }
369 - this.getRemoteAccessConnectionStatus = function getRemoteAccessConnectionStatus(callback) {
418 + this.getRemoteAccessConnectionStatus = function getRemoteAccessConnectionStatus() {
419 var optional = [];
371 - for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
372 - this.sendCommand(0x46, null, function (header, fn, opt) {
420 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
421 + this.sendCommand(0x46, data, function (header, fn, opt) {
422 if (header.Status == 0) {
374 - var hostname = header.Data.slice(14, header.Data.readUInt16LE(12) + 14).toString()
423 + var hostname = v.slice(14, header.Data.readUInt16LE(12) + 14).toString()
424 opt.unshift({ status: header.Status, networkStatus: header.Data.readUInt32LE(0), remoteAccessStatus: header.Data.readUInt32LE(4), remoteAccessTrigger: header.Data.readUInt32LE(8), mpsHostname: hostname, raw: header.Data });
425 } else {
426 opt.unshift({ status: header.Status });
@@ -379,81 +428,27 @@ function amt_heci() {
428 fn.apply(this, opt);
429 }, callback, optional);
430 }
382 - this.getProtocolVersion = function getProtocolVersion(callback) {
431 + this.getProtocolVersion = function getProtocolVersion(callback)
432 + {
433 var optional = [];
434 for (var i = 1; i < arguments.length; ++i) { opt.push(arguments[i]); }
435
386 - if (!this._tmpSession) { this._tmpSession = heci.create(); this._tmpSession.parent = this; }
387 - this._tmpSession.doIoctl(heci.IOCTL.HECI_VERSION, Buffer.alloc(5), Buffer.alloc(5), function (status, buffer, self, fn, opt) {
436 + if (!this._tmpSession) { this._tmpSession = heci.create(); this._tmpSession.parent = this;}
437 + this._tmpSession.doIoctl(heci.IOCTL.HECI_VERSION, Buffer.alloc(5), Buffer.alloc(5), function (status, buffer, self, fn, opt)
438 + {
439 if (status == 0) {
440 var result = buffer.readUInt8(0).toString() + '.' + buffer.readUInt8(1).toString() + '.' + buffer.readUInt8(2).toString() + '.' + buffer.readUInt16BE(3).toString();
441 opt.unshift(result);
442 fn.apply(self, opt);
443 }
393 - else {
444 + else
445 + {
446 opt.unshift(null);
447 fn.apply(self, opt);
448 }
449
450 }, this, callback, optional);
451 }
400 - this.startConfigurationHBased = function startConfigurationHBased(certHash, hostVpn, dnsSuffixList, func) {
401 - if ((certHash == null) || ((certHash.length != 32) && (certHash.length != 48))) { func({ status: -101 }); }
402 - this.stopConfiguration(function (status) {
403 - if (status == 0) {
404 - // We stopped the configuration, wait 20 seconds before starting up again.
405 - var f = function tf() { delete tf.parent.xtimeout; tf.parent.startConfigurationHBasedEx(certHash, hostVpn, dnsSuffixList, func); }
406 - f.parent = this;
407 - this.xtimeout = setTimeout(f, 20000);
408 - } else {
409 - // We are not in the connect mode, this is good, start configuration right away.
410 - this.startConfigurationHBasedEx(certHash, hostVpn, dnsSuffixList, func);
411 - }
412 - })
413 - }
414 - this.startConfigurationHBasedEx = function startConfigurationHBased(certHash, hostVpn, dnsSuffixList, func) {
415 - var optional = [];
416 - for (var i = 4; i < arguments.length; ++i) { optional.push(arguments[i]); }
417 -
418 - // Format the command
419 - var data = Buffer.alloc(4 + 64 + 4 + 4 + 320);
420 - data.writeUInt32LE((certHash.length == 48) ? 3 : 2, 0); // Write certificate hash type: SHA256 = 2, SHA384 = 3
421 - certHash.copy(data, 4); // Write the hash
422 - data.writeUInt32LE(hostVpn ? 1 : 0, 68); // Write is HostVPN is enabled
423 - if (dnsSuffixList != null) {
424 - data.writeUInt32LE(dnsSuffixList.length, 72); // Write the number of DNS Suffix, from 0 to 4
425 - var ptr = 76;
426 - for (var i = 0; i < dnsSuffixList.length; i++) { ptr += data.write(dnsSuffixList[i], ptr) + 1; } // Write up to 4 DNS Suffix with null seperation.
427 - }
428 -
429 - // Send the command
430 - this.sendCommand(139, data, function (header, fn, opt) {
431 - if (header.Status == 0) {
432 - var amtHash = null;
433 - if (header.Data[0] == 2) { amtHash = header.Data.slice(1, 33); } // SHA256
434 - if (header.Data[0] == 3) { amtHash = header.Data.slice(1, 49); } // SHA384
435 - opt.unshift({ status: header.Status, hash: amtHash.toString('hex') });
436 - } else {
437 - opt.unshift({ status: header.Status });
438 - }
439 - fn.apply(this, opt);
440 - }, func, optional);
441 - }
452 }
453
444 -module.exports = amt_heci;
445 -
446 -
447 -/*
448 -AMT_STATUS_SUCCESS = 0,
449 -AMT_STATUS_INTERNAL_ERROR = 1,
450 -AMT_STATUS_INVALID_AMT_MODE = 3,
451 -AMT_STATUS_INVALID_MESSAGE_LENGTH = 4,
452 -AMT_STATUS_MAX_LIMIT_REACHED = 23,
453 -AMT_STATUS_INVALID_PARAMETER = 36,
454 -AMT_STATUS_RNG_GENERATION_IN_PROGRESS = 47,
455 -AMT_STATUS_RNG_NOT_READY = 48,
456 -AMT_STATUS_CERTIFICATE_NOT_READY = 49,
457 -AMT_STATUS_INVALID_HANDLE = 2053
458 -AMT_STATUS_NOT_FOUND = 2068,
459 -*/
\ No newline at end of file
454 +module.exports = amt_heci;
\ No newline at end of file
agents/modules_meshcore/amt-mei.js
+143 -149
@@ -1,5 +1,5 @@
1 /*
2 -Copyright 2018-2021 Intel Corporation
2 +Copyright 2018-2020 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
@@ -15,7 +15,10 @@ limitations under the License.
15 */
16
17 var Q = require('queue');
18 -function amt_heci() {
18 +var g_internal = null;
19 +
20 +function amt_heci()
21 +{
22 var emitterUtils = require('events').inherits(this);
23 emitterUtils.createEvent('error');
24
@@ -23,60 +26,86 @@ function amt_heci() {
26 var sendConsole = function (msg) { try { require('MeshAgent').SendCommand({ "action": "msg", "type": "console", "value": msg }); } catch (ex) { } }
27
28 this._ObjectID = "pthi";
26 - this._rq = new Q();
27 - this._setupPTHI = function _setupPTHI() {
28 - this._amt = heci.create();
29 - this._amt.descriptorMetadata = "amt-pthi";
30 - this._amt.BiosVersionLen = 65;
31 - this._amt.UnicodeStringLen = 20;
32 -
33 - this._amt.Parent = this;
34 - this._amt.on('error', function _amtOnError(e) {
35 - if (this.Parent._rq.isEmpty()) {
36 - this.Parent.emit('error', e); // No pending requests, so propagate the error up
37 - }
38 - else {
39 - // There is a pending request, so fail the pending request
40 - var user = this.Parent._rq.deQueue();
41 - var params = user.optional;
42 - var callback = user.func;
43 - params.unshift({ Status: -1 }); // Relay an error
44 - callback.apply(this.Parent, params);
45 -
46 - if (!this.Parent._rq.isEmpty()) {
47 - // There are still more pending requests, so try to re-helpconnect MEI
48 - this.connect(heci.GUIDS.AMT, { noPipeline: 1 });
49 - }
50 - }
51 - });
52 - this._amt.on('connect', function _amtOnConnect() {
53 - this.on('data', function _amtOnData(chunk) {
54 - //console.log("Received: " + chunk.length + " bytes");
55 - var header = this.Parent.getCommand(chunk);
56 - //console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
57 -
58 - var user = this.Parent._rq.deQueue();
59 - var params = user.optional;
60 - var callback = user.func;
61 -
62 - params.unshift(header);
63 - callback.apply(this.Parent, params);
64 -
65 - if (this.Parent._rq.isEmpty()) {
66 - // No More Requests, we can close PTHI
67 - this.Parent._amt.disconnect();
68 - this.Parent._amt = null;
29 + var that = this;
30 + if (g_internal == null)
31 + {
32 + g_internal = { _rq: new Q(), _amt: null };
33 + g_internal._setupPTHI = function _g_setupPTHI()
34 + {
35 + console.info1('setupPTHI()');
36 + this._amt = heci.create();
37 + this._amt.descriptorMetadata = "amt-pthi";
38 + this._amt.BiosVersionLen = 65;
39 + this._amt.UnicodeStringLen = 20;
40 + this._amt.Parent = that;
41 +
42 + this._amt.on('error', function _amtOnError(e)
43 + {
44 + console.info1('PTHIError: ' + e);
45 + if (this.Parent._rq.isEmpty())
46 + {
47 + console.info1(' Queue is empty');
48 + this.Parent.emit('error', e); // No pending requests, so propagate the error up
49 }
70 - else {
71 - // Send the next request
72 - this.write(this.Parent._rq.peekQueue().send);
50 + else
51 + {
52 + console.info1(' Queue is NOT empty');
53 +
54 + // There is a pending request, so fail the pending request
55 + var user = this.Parent._rq.deQueue();
56 + var params = user.optional;
57 + var callback = user.func;
58 + params.unshift({ Status: -1 }); // Relay an error
59 + callback.apply(this.Parent, params);
60 +
61 + if (!this.Parent._rq.isEmpty())
62 + {
63 + // There are still more pending requests, so try to re-helpconnect MEI
64 + this.connect(heci.GUIDS.AMT, { noPipeline: 1 });
65 + }
66 }
67 });
68 + this._amt.on('connect', function _amtOnConnect()
69 + {
70 + this.on('data', function _amtOnData(chunk)
71 + {
72 + //console.log("Received: " + chunk.length + " bytes");
73 + var header = this.Parent.getCommand(chunk);
74 + console.info1("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
75
76 - // Start sending requests
77 - this.write(this.Parent._rq.peekQueue().send);
78 - });
79 - };
76 + var user = g_internal._rq.deQueue();
77 + var params = user.optional;
78 + var callback = user.func;
79 +
80 + params.unshift(header);
81 + callback.apply(this.Parent, params);
82 +
83 + if (g_internal._rq.isEmpty())
84 + {
85 + console.info1('No more requests, disconnecting');
86 +
87 + // No More Requests, we can close PTHI
88 + g_internal._amt.disconnect();
89 + g_internal._amt = null;
90 + }
91 + else
92 + {
93 + // Send the next request
94 + console.info1('Sending Next Request');
95 + this.write(g_internal._rq.peekQueue().send);
96 + }
97 + });
98 +
99 + // Start sending requests
100 + this.write(g_internal._rq.peekQueue().send);
101 + });
102 +
103 +
104 +
105 + };
106 + }
107 +
108 +
109 function trim(x) { var y = x.indexOf('\0'); if (y >= 0) { return x.substring(0, y); } else { return x; } }
110 this.getCommand = function getCommand(chunk) {
111 var command = chunk.length == 0 ? (this._rq.peekQueue().cmd | 0x800000) : chunk.readUInt32LE(4);
@@ -84,19 +113,30 @@ function amt_heci() {
113 return (ret);
114 };
115
87 - this.sendCommand = function sendCommand() {
116 + this.sendCommand = function sendCommand()
117 + {
118 if (arguments.length < 3 || typeof (arguments[0]) != 'number' || typeof (arguments[1]) != 'object' || typeof (arguments[2]) != 'function') { throw ('invalid parameters'); }
119 var args = [];
120 for (var i = 3; i < arguments.length; ++i) { args.push(arguments[i]); }
121
122 + console.info1('sendCommand(' + arguments[0] + ')', this._hashCode());
123 +
124 var header = Buffer.from('010100000000000000000000', 'hex');
125 header.writeUInt32LE(arguments[0] | 0x04000000, 4);
126 header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8);
95 - this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args, send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]])) });
127
97 - if (!this._amt) {
98 - this._setupPTHI();
99 - this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
128 + //this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args, send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]])) });
129 + //if(!this._amt)
130 + //{
131 + // this._setupPTHI();
132 + // this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
133 + //}
134 +
135 + g_internal._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args, send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]])) });
136 + if (!g_internal._amt)
137 + {
138 + g_internal._setupPTHI();
139 + g_internal._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
140 }
141 }
142
@@ -105,10 +145,11 @@ function amt_heci() {
145 for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
146 this.sendCommand(26, null, function (header, fn, opt) {
147 if (header.Status == 0) {
108 - var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, this._amt.BiosVersionLen).toString(), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4);
109 - for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen); ++i) {
110 - val.Versions[i] = { Description: v.slice(2, v.readUInt16LE(0) + 2).toString(), Version: v.slice(4 + this._amt.UnicodeStringLen, 4 + this._amt.UnicodeStringLen + v.readUInt16LE(2 + this._amt.UnicodeStringLen)).toString() };
111 - v = v.slice(4 + (2 * this._amt.UnicodeStringLen));
148 + var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, g_internal._amt.BiosVersionLen).toString(), Versions: [] }, v = CodeVersion.slice(g_internal._amt.BiosVersionLen + 4);
149 + for (i = 0; i < CodeVersion.readUInt32LE(g_internal._amt.BiosVersionLen) ; ++i)
150 + {
151 + val.Versions[i] = { Description: v.slice(2, v.readUInt16LE(0) + 2).toString(), Version: v.slice(4 + g_internal._amt.UnicodeStringLen, 4 + g_internal._amt.UnicodeStringLen + v.readUInt16LE(2 + g_internal._amt.UnicodeStringLen)).toString() };
152 + v = v.slice(4 + (2 * g_internal._amt.UnicodeStringLen));
153 }
154 if (val.BiosVersion.indexOf('\0') > 0) { val.BiosVersion = val.BiosVersion.substring(0, val.BiosVersion.indexOf('\0')); }
155 opt.unshift(val);
@@ -291,27 +332,34 @@ function amt_heci() {
332 this.getLocalSystemAccount = function getLocalSystemAccount(callback) {
333 var optional = [];
334 for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
294 - this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt) {
295 - if (header.Status == 0 && header.Data.length == 68) {
335 + this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt)
336 + {
337 + if (header.Status == 0 && header.Data.length == 68)
338 + {
339 opt.unshift({ user: trim(header.Data.slice(0, 33).toString()), pass: trim(header.Data.slice(33, 67).toString()), raw: header.Data });
340 }
298 - else {
341 + else
342 + {
343 opt.unshift(null);
344 }
345 fn.apply(this, opt);
346 }, callback, optional);
347 }
304 - this.getLanInterfaceSettings = function getLanInterfaceSettings(index, callback) {
348 + this.getLanInterfaceSettings = function getLanInterfaceSettings(index, callback)
349 + {
350 var optional = [];
351 for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
352 var ifx = Buffer.alloc(4);
353 ifx.writeUInt32LE(index);
309 - this.sendCommand(0x48, ifx, function onGetLanInterfaceSettings(header, fn, opt) {
310 - if (header.Status == 0) {
354 + this.sendCommand(0x48, ifx, function onGetLanInterfaceSettings(header, fn, opt)
355 + {
356 + if(header.Status == 0)
357 + {
358 var info = {};
359 info.enabled = header.Data.readUInt32LE(0);
360 info.dhcpEnabled = header.Data.readUInt32LE(8);
314 - switch (header.Data[12]) {
361 + switch(header.Data[12])
362 + {
363 case 1:
364 info.dhcpMode = 'ACTIVE'
365 break;
@@ -323,13 +371,14 @@ function amt_heci() {
371 break;
372 }
373 info.mac = header.Data.slice(14).toString('hex:');
326 -
374 +
375 var addr = header.Data.readUInt32LE(4);
376 info.address = ((addr >> 24) & 255) + '.' + ((addr >> 16) & 255) + '.' + ((addr >> 8) & 255) + '.' + (addr & 255);
377 opt.unshift(info);
378 fn.apply(this, opt);
379 }
332 - else {
380 + else
381 + {
382 opt.unshift(null);
383 fn.apply(this, opt);
384 }
@@ -346,32 +395,32 @@ function amt_heci() {
395 fn.apply(this, opt);
396 }, callback, optional);
397 }
349 - this.startConfiguration = function startConfiguration(callback) {
398 + this.startConfiguration = function startConfiguration() {
399 var optional = [];
351 - for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
352 - this.sendCommand(0x29, null, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
400 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
401 + this.sendCommand(0x29, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
402 }
354 - this.stopConfiguration = function stopConfiguration(callback) {
403 + this.stopConfiguration = function stopConfiguration() {
404 var optional = [];
356 - for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
357 - this.sendCommand(0x5E, null, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
405 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
406 + this.sendCommand(0x5E, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
407 }
359 - this.openUserInitiatedConnection = function openUserInitiatedConnection(callback) {
408 + this.openUserInitiatedConnection = function openUserInitiatedConnection() {
409 var optional = [];
361 - for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
362 - this.sendCommand(0x44, null, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
410 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
411 + this.sendCommand(0x44, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
412 }
364 - this.closeUserInitiatedConnection = function closeUnserInitiatedConnected(callback) {
413 + this.closeUserInitiatedConnection = function closeUnserInitiatedConnected() {
414 var optional = [];
366 - for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
367 - this.sendCommand(0x45, null, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
415 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
416 + this.sendCommand(0x45, data, function (header, fn, opt) { opt.unshift(header.Status); fn.apply(this, opt); }, callback, optional);
417 }
369 - this.getRemoteAccessConnectionStatus = function getRemoteAccessConnectionStatus(callback) {
418 + this.getRemoteAccessConnectionStatus = function getRemoteAccessConnectionStatus() {
419 var optional = [];
371 - for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
372 - this.sendCommand(0x46, null, function (header, fn, opt) {
420 + for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
421 + this.sendCommand(0x46, data, function (header, fn, opt) {
422 if (header.Status == 0) {
374 - var hostname = header.Data.slice(14, header.Data.readUInt16LE(12) + 14).toString()
423 + var hostname = v.slice(14, header.Data.readUInt16LE(12) + 14).toString()
424 opt.unshift({ status: header.Status, networkStatus: header.Data.readUInt32LE(0), remoteAccessStatus: header.Data.readUInt32LE(4), remoteAccessTrigger: header.Data.readUInt32LE(8), mpsHostname: hostname, raw: header.Data });
425 } else {
426 opt.unshift({ status: header.Status });
@@ -379,82 +428,27 @@ function amt_heci() {
428 fn.apply(this, opt);
429 }, callback, optional);
430 }
382 - this.getProtocolVersion = function getProtocolVersion(callback) {
431 + this.getProtocolVersion = function getProtocolVersion(callback)
432 + {
433 var optional = [];
434 for (var i = 1; i < arguments.length; ++i) { opt.push(arguments[i]); }
435
386 - if (!this._tmpSession) { this._tmpSession = heci.create(); this._tmpSession.parent = this; }
387 - this._tmpSession.doIoctl(heci.IOCTL.HECI_VERSION, Buffer.alloc(5), Buffer.alloc(5), function (status, buffer, self, fn, opt) {
436 + if (!this._tmpSession) { this._tmpSession = heci.create(); this._tmpSession.parent = this;}
437 + this._tmpSession.doIoctl(heci.IOCTL.HECI_VERSION, Buffer.alloc(5), Buffer.alloc(5), function (status, buffer, self, fn, opt)
438 + {
439 if (status == 0) {
440 var result = buffer.readUInt8(0).toString() + '.' + buffer.readUInt8(1).toString() + '.' + buffer.readUInt8(2).toString() + '.' + buffer.readUInt16BE(3).toString();
441 opt.unshift(result);
442 fn.apply(self, opt);
443 }
393 - else {
444 + else
445 + {
446 opt.unshift(null);
447 fn.apply(self, opt);
448 }
449
450 }, this, callback, optional);
451 }
400 - this.startConfigurationHBased = function startConfigurationHBased(certHash, hostVpn, dnsSuffixList, func) {
401 - if ((certHash == null) || ((certHash.length != 32) && (certHash.length != 48))) { func({ status: -101 }); }
402 - this.stopConfiguration(function (status) {
403 - if (status == 0) {
404 - // We stopped the configuration, wait 20 seconds before starting up again.
405 - var f = function tf() { delete tf.parent.xtimeout; tf.parent.startConfigurationHBasedEx(certHash, hostVpn, dnsSuffixList, func); }
406 - f.parent = this;
407 - this.xtimeout = setTimeout(f, 20000);
408 - } else {
409 - // We are not in the connect mode, this is good, start configuration right away.
410 - this.startConfigurationHBasedEx(certHash, hostVpn, dnsSuffixList, func);
411 - }
412 - })
413 - }
414 - this.startConfigurationHBasedEx = function startConfigurationHBased(certHash, hostVpn, dnsSuffixList, func) {
415 - var optional = [];
416 - for (var i = 4; i < arguments.length; ++i) { optional.push(arguments[i]); }
417 -
418 - // Format the command
419 - var len = 1 + 64 + 4 + 4;
420 - if (dnsSuffixList != null) { len += 320; }
421 - var data = Buffer.alloc(len);
422 - data[0] = (certHash.length == 48) ? 3 : 2; // Write certificate hash type: SHA256 = 2, SHA384 = 3
423 - certHash.copy(data, 1); // Write the hash
424 - data.writeUInt32LE(hostVpn ? 1 : 0, 65); // Write is HostVPN is enabled
425 - if (dnsSuffixList != null) {
426 - data.writeUInt32LE(dnsSuffixList.length, 69); // Write the number of DNS Suffix, from 0 to 4
427 - var ptr = 73;
428 - for (var i = 0; i < dnsSuffixList.length; i++) { ptr += data.write(dnsSuffixList[i], ptr) + 1; } // Write up to 4 DNS Suffix with null seperation.
429 - }
430 -
431 - // Send the command
432 - this.sendCommand(139, data, function (header, fn, opt) {
433 - if ((header.Status == 0) && (header.Data != null)) {
434 - var amtHash = null;
435 - if (header.Data[0] == 2) { amtHash = header.Data.slice(1, 33); } // SHA256
436 - if (header.Data[0] == 3) { amtHash = header.Data.slice(1, 49); } // SHA384
437 - opt.unshift({ status: header.Status, hash: amtHash.toString('hex') });
438 - } else {
439 - opt.unshift({ status: header.Status });
440 - }
441 - fn.apply(this, opt);
442 - }, func, optional);
443 - }
452 }
453
446 -module.exports = amt_heci;
447 -
448 -/*
449 -AMT_STATUS_SUCCESS = 0,
450 -AMT_STATUS_INTERNAL_ERROR = 1,
451 -AMT_STATUS_INVALID_AMT_MODE = 3,
452 -AMT_STATUS_INVALID_MESSAGE_LENGTH = 4,
453 -AMT_STATUS_MAX_LIMIT_REACHED = 23,
454 -AMT_STATUS_INVALID_PARAMETER = 36,
455 -AMT_STATUS_RNG_GENERATION_IN_PROGRESS = 47,
456 -AMT_STATUS_RNG_NOT_READY = 48,
457 -AMT_STATUS_CERTIFICATE_NOT_READY = 49,
458 -AMT_STATUS_INVALID_HANDLE = 2053
459 -AMT_STATUS_NOT_FOUND = 2068,
460 -*/
\ No newline at end of file
454 +module.exports = amt_heci;
\ No newline at end of file