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