servermgrv2/public/hpilo/js/socket.js
2023-07-17 21:09:49 +09:00

508 lines
16 KiB
JavaScript

"use strict";
function Socket(options) {
function getStringFromData(buf, begin, len, defaultText) {
var szValue;
if ("function" == typeof TextDecoder) szValue = new TextDecoder("utf-8").decode(new Uint8Array(buf.buffer, buf.byteOffset + begin, len)); else try {
szValue = String.fromCharCode.apply(null, new Uint8Array(buf.buffer, buf.byteOffset + begin, len)),
szValue = decodeURIComponent(escape(szValue)).replace(/\0/g, "");
} catch (ex) {
szValue = "";
}
return szValue.length > 0 ? szValue : defaultText;
}
function getPostCodeFromData(buf) {
var index1, index2, szValue = "";
return buf.length >= 2 && (index1 = ("00" + buf[1].toString(16).toUpperCase()).substr(-2),
index2 = ("00" + buf[0].toString(16).toUpperCase()).substr(-2), szValue = index1 + index2),
szValue;
}
function IRC_CMD(dataView) {
this.cmd, this.size, this.seq, this.flags, this.buf;
try {
dataView && (this.cmd = dataView.getUint32(0, !0), this.size = dataView.getUint32(4, !0),
this.seq = dataView.getUint16(8, !0), this.flags = dataView.getUint16(10, !0), this.buf = new Uint8Array(dataView.buffer, dataView.byteOffset + 12));
} catch (e) {}
}
function IRC_SERVER_HELLO(dataView) {
this.iv, this.status, this.flags, this.session_key;
try {
dataView && (4 === me.version ? this.status = dataView.getUint8(0, !0) : (this.status = dataView.getUint8(16),
this.flags = dataView.getUint32(17, !0)));
} catch (e) {}
}
function Handshake(wsuri, sessionKey, channel, openCommand, success, failure) {
var socket, onfail = failure || function(sock, reason) {
console.log("Handshake failed: " + reason);
}, onsuccess = success || function(sock) {
sock.onmessage = function(evt) {};
}, sockopen_auth = function(evt) {
if (4 === me.version) return !0;
var client_hello = new Uint8Array(54);
client_hello[16] = openCommand, client_hello[17] = channel;
for (var i = 0; i < sessionKey.length; i++) client_hello[22 + i] = sessionKey.charCodeAt(i);
socket.send(client_hello);
}, sockrecv_auth = function(evt) {
var server_hello = new IRC_SERVER_HELLO(new DataView(evt.data));
if (4 === me.version) switch (server_hello.status) {
case DVCNET.CMD_AUTHENTICATE:
var name = channel === CMD_CHANNEL ? "CMD" : "KVM", client_hello = new Uint8Array(34);
client_hello[0] = "CMD" === name ? 2 : 1, client_hello[1] = 32;
for (var i = 0; i < sessionKey.length; i++) client_hello[2 + i] = sessionKey.charCodeAt(i);
socket.send(client_hello);
break;
case DVCNET.CMD_AUTHENTICATED:
socket.onmessage = null, socket.onopen = null, onsuccess(socket);
break;
case DVCNET.NEG_BUSY_NO_MURC:
video.set_licensed_murc(!1);
case DVCNET.NEG_BUSY:
me.cmdsocket = socket;
var msgKey = "IRC.message.ConsoleInUseNoShare", tmrMsgKey = "IRC.message.TimedAutoDisconnect", msgBox = {
callback: "neg_seize",
messageKey: msgKey,
stayTime: 10,
timerStringKey: tmrMsgKey,
title: null,
icon: null,
buttons: [ {
text: "Acquire",
textKey: "IRC.control.Acquire",
isDefault: !0,
value: !0
}, {
text: "Cancel",
textKey: "cancel",
isDefault: !1,
value: !1
} ]
};
video.confirm(msgBox);
break;
case DVCNET.NEG_SEIZE:
case DVCNET.NEG_SHARE:
onfail(socket, server_hello.status);
break;
case DVCNET.CMD_DENIED:
case DVCNET.NEG_DROP:
case DVCNET.CMD_NO_SESSIONS:
default:
socket.onmessage = null, socket.onopen = null, onfail(socket, server_hello.status);
} else switch (socket.onmessage = null, socket.onopen = null, server_hello.status) {
case 0:
onsuccess(socket);
break;
default:
onfail(socket, server_hello.status);
}
};
if ("function" == typeof MozWebSocket) socket = new MozWebSocket(wsuri); else {
if ("function" != typeof WebSocket) throw "No WebSockets!";
try {
socket = new WebSocket(wsuri);
} catch (e) {
"SyntaxError" === e.message && this.ie && wsuri.match(/[^[\]]+(?=])/g).length ? onfail(null, "IE+IPv6") : onfail(null, e.message);
}
}
socket && (socket.onerror = function(evt) {
1 === socket.readyState ? console.log("WebSocket connection failed: " + evt.type) : console.log("WebSocket error: " + evt.type);
}, socket.binaryType = "arraybuffer", socket.onmessage = sockrecv_auth, socket.onopen = sockopen_auth);
}
var me = this, KVM_CHANNEL = 0, CMD_CHANNEL = 1, DVCNET = {
CMD_AUTHENTICATE: 80,
CMD_DENIED: 81,
CMD_AUTHENTICATED: 82,
NEG_BUSY: 83,
NEG_DROP: 84,
NEG_SEIZE: 85,
NEG_SHARE: 86,
CMD_NO_SESSIONS: 88,
NEG_BUSY_NO_MURC: 89
}, SCSI_ERR = {
APPLET_CONNECT: -2,
NO_IMAGE: -3,
OPTION_ERROR: -4,
SCRIPT_CONNECT: -5,
NO_LICENSE: -6,
REJECTED: -7,
CONNECT_FAILED: -8,
OP_FAILED: -9,
EXPECTED_ISO: -10,
EXPECTED_IMG: -11,
VIDEO_STARTUP: -12,
FW_ACTIVE: -13,
FLASH_FAILED: -14
};
this.onstatuschange = function() {}, this.version = options.version || 4, this.openCommand = options.openCommand || 0,
this.sessionKey = options.sessionKey, this.sockaddr = "wss://" + options.host + "/wss/ircport",
this.sockrecv = options.sockrecv, this.ie = options.ie, this.video = options.video,
this.health_state = "", this.power_state = "", this.neg_seize = function(resp) {
if (me.openCommand = resp ? 1 : 0, resp === !0) {
var cmd = new Uint8Array(2);
cmd[0] = DVCNET.NEG_SEIZE, cmd[1] = 0, me.cmdsocket.send(cmd);
} else me.close(), me.onclose && me.onclose();
}, this.handleSeize = function(irc_cmd) {
var user = getStringFromData(irc_cmd.buf, 0, 64, "UNKNOWN"), addr = getStringFromData(irc_cmd.buf, 64, 64, "UNKNOWN"), dlgMsg = "IRC.message.RequestAcquire", tmrMsg = "IRC.message.AutoPermission", actMsg = "IRC.status.granted", messageInserts = [ {
placeHolder: "{0}",
value: user
}, {
placeHolder: "{1}",
value: addr
} ], msgBox = {
callback: "send_bool",
retvalOverride: !0,
messageKey: dlgMsg,
messageInserts: messageInserts,
title: null,
icon: null,
stayTime: 10,
timerStringKey: tmrMsg,
actionKey: actMsg,
buttons: [ {
textKey: "IRC.control.Yes",
isDefault: !0,
value: !0
}, {
textKey: "IRC.control.No",
value: !1
} ]
};
video.confirm(msgBox);
}, this.handleShare = function(irc_cmd) {
var user = getStringFromData(irc_cmd.buf, 0, 64, "UNKNOWN"), addr = getStringFromData(irc_cmd.buf, 64, 64, "UNKNOWN");
me.sendBool(!1), video.handle_share(user, addr);
}, this.handlePostCode = function(irc_cmd) {
if (2 === irc_cmd.size) {
var code = getPostCodeFromData(irc_cmd.buf);
video.post_code(code);
}
}, this.handleAckNotification = function(irc_cmd) {
var dlgMsg = "";
if (4 !== irc_cmd.size) return void $.log("IRC: rejecting Ack notification: size is not 4.");
var dataView = new DataView(irc_cmd.buf.buffer, irc_cmd.buf.byteOffset), result = dataView.getInt8(0, !0), device = dataView.getInt8(1, !0), type = dataView.getInt8(2, !0), connected = 0 !== dataView.getInt8(3, !0) ? !0 : !1;
if (0 === result) video.vm_change({
isFloppy: 1 == device,
isURL: 8 == type,
isConnected: !!connected
}); else if (0 > result && !connected) {
switch (result) {
case -1:
dlgMsg = "IRC.message.CannotParse";
break;
case SCSI_ERR.APPLET_CONNECT:
case SCSI_ERR.SCRIPT_CONNECT:
dlgMsg = "IRC.message.DriveAlreadyConnected";
break;
case SCSI_ERR.NO_IMAGE:
dlgMsg = "IRC.message.ImageNotFound";
break;
case SCSI_ERR.OPTION_ERROR:
dlgMsg = "IRC.message.InternalConfigError";
break;
case SCSI_ERR.NO_LICENSE:
dlgMsg = "IRC.message.VMNotLicensed";
break;
case SCSI_ERR.REJECTED:
dlgMsg = "IRC.message.CannotConnect";
break;
default:
dlgMsg = "IRC.message.UnknownError";
}
if (dlgMsg.length > 0) {
var msgBox = {
messageKey: dlgMsg,
stayTime: 10,
title: null,
icon: null
};
video.alert(msgBox);
}
}
}, this.handleFirmwareUpdate = function(irc_cmd) {
var dlgMsg = "IRC.message.ClosedFwUpgrade", msgBox = {
messageKey: dlgMsg,
stayTime: 20,
title: null,
icon: null
};
video.alert(msgBox), me.close();
}, this.handleUnauthorized = function(irc_cmd) {
var priv = "";
switch (irc_cmd.flags) {
case 2:
priv = "RemoteConsolePriv";
break;
case 3:
priv = "VirtualMediaPriv";
break;
case 4:
priv = "VirtualPowerAndResetPriv";
}
priv.length > 0 && video.unauthorized(priv);
}, this.handleLicenseViolation = function(irc_cmd) {
var dlgMsg = "IRC.message.IRCNotLicensed", msgBox = {
titleKey: "IRC.title.LicenseRequired",
type: "critical",
messageKey: dlgMsg
};
video.alert(msgBox), me.close();
}, this.handleReset = function(irc_cmd) {
var dlgMsg = "IRC.message.iLOReset", msgBox = {
messageKey: dlgMsg,
stayTime: 20,
title: null,
icon: null
};
video.alert(msgBox), me.close();
}, this.onhealthchange = function(health_state) {
this.health_state !== health_state && (this.health_state = health_state, video.health_change(health_state));
}, this.handleHealthState = function(health_state) {
if (me.onhealthchange) switch (health_state) {
case 0:
me.onhealthchange("OP_STATUS_OK");
break;
case 1:
me.onhealthchange("OP_STATUS_WARNING");
break;
case 2:
me.onhealthchange("OP_STATUS_CRITICAL");
break;
default:
me.onhealthchange("OP_STATUS_UNKNOWN");
}
}, this.handlePowerState = function(power_state) {
if (me.onpowerchange) switch (power_state) {
case 1:
me.onpowerchange("ON");
break;
case 0:
default:
me.onpowerchange("OFF");
}
}, this.onpowerchange = function(power_state) {
this.power_state !== power_state && (this.power_state = power_state, video.power_change(power_state));
}, this.cmdsockrecv = function(evt) {
var irc_cmd = new IRC_CMD(new DataView(evt.data));
switch (irc_cmd.cmd) {
case 2:
video.status_change("Post Complete");
break;
case 3:
me.handlePowerState(irc_cmd.buf[0]);
break;
case 4:
me.handleHealthState(irc_cmd.buf[0]);
break;
case 5:
me.handlePostCode(irc_cmd);
break;
case 6:
me.handleSeize(irc_cmd);
break;
case 7:
me.handleAckNotification(irc_cmd);
break;
case 9:
me.handleShare(irc_cmd);
break;
case 10:
console.log("IRC: received firmware update notification."), me.handleFirmwareUpdate(irc_cmd);
break;
case 11:
console.log("IRC: received unauthorized notification."), me.handleUnauthorized(irc_cmd);
break;
case 13:
break;
case 14:
me.handleLicenseViolation(irc_cmd);
break;
case 15:
console.log("IRC: iLO reset detected."), me.handleReset(irc_cmd);
break;
case 16:
case 17:
break;
default:
console.log("IRC: received unhandled command: ", irc_cmd);
}
}, this.open_cmdsocket = function() {
new Handshake(me.sockaddr, me.sessionKey, 1, 0, function(ws) {
ws.onmessage = me.cmdsockrecv, ws.onclose = function() {
me.onclose && me.onclose(), console.log("cmd socket closed");
}, ws.onerror = function(evt) {
console.log("cmd socket open error: " + evt);
}, me.cmdsocket = ws, me.send = me.send_kvm, setTimeout(function() {
me.all_keys_up();
}, 2e3);
}, null);
}, this.send_kvm = function(arr) {
this.socket && this.socket.readyState && this.socket.send(new Uint8Array(arr));
}, this.send_cmd = function(arr) {
this.cmdsocket && this.cmdsocket.readyState && this.cmdsocket.send(new Uint8Array(arr));
}, this.send_null = function(arr) {}, this.send = this.send_null, this.sendBool = function(rsp) {
var cmd = [ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ];
cmd[0] = rsp ? 4 : 3, this.send_cmd(cmd);
}, this.kbdsend = function(hidrpt) {
var cmd;
cmd = me.version > 2 ? [ 1, 0 ] : [ 255, 214 ], cmd = cmd.concat(hidrpt), me.send(cmd);
}, this.all_keys_up = function() {
me.kbdsend([ 0, 0, 0, 0, 0, 0, 0, 0 ]);
}, this.ctrl_alt_del = function() {
me.kbdsend([ 5, 0, 76, 0, 0, 0, 0, 0 ]), setTimeout(function() {
me.kbdsend([ 5, 0, 0, 0, 0, 0, 0, 0 ]), setTimeout(function() {
me.all_keys_up();
}, 5);
}, 250);
}, this.num_lock = function() {
me.kbdsend([ 0, 0, 83, 0, 0, 0, 0, 0 ]), setTimeout(function() {
me.all_keys_up();
}, 50);
}, this.caps_lock = function() {
me.kbdsend([ 0, 0, 57, 0, 0, 0, 0, 0 ]), setTimeout(function() {
me.all_keys_up();
}, 50);
}, this.refresh = function() {
me.version > 2 ? me.send([ 5, 0 ]) : me.send([ 27, 91, 126 ]);
}, this.send_ack = function() {
me.send([ 12, 0 ]);
}, this.keepalive = function() {
me.send([ 27, 91, 40 ]);
}, this.autoalive = function() {
me.send([ 27, 91, 38 ]);
}, this.mouse_send = function(rx, ry, ax, ay, button, wheel) {
if (2 === this.version) return !1;
var buf = [ 2, 0, 255 & ax, ax >> 8, 255 & ay, ay >> 8, 255 & rx, 255 & ry, button, wheel ];
return this.send(buf), !0;
}, this.no_op = function() {
return !1;
}, this.close = function() {
this.socket && this.socket.close(), this.cmdsocket && this.cmdsocket.close();
}, new Handshake(me.sockaddr, me.sessionKey, KVM_CHANNEL, me.openCommand, function(ws) {
me.connected = !0, me.socket = ws, me.socket.onmessage = me.sockrecv, me.socket.onclose = function(evt) {
console.log("WebSocket closed", evt), me.connected = !1, me.onclose && me.onclose();
}, me.socket.onerror = function(evt) {
console.log("WebSocket ERROR: ", evt);
}, me.open_cmdsocket();
}, function(ws, error) {
var alertToast = function(key) {
video.toast({
textKey: key,
type: "critical",
sticky: !0
});
};
switch (error) {
case DVCNET.CMD_DENIED:
switch (me.openCommand) {
case 1:
alertToast("IRC.message.AcquireDenied");
break;
case 2:
alertToast("IRC.message.ShareDenied");
break;
case 0:
default:
alertToast("IRC.message.SessionLimitReached");
}
break;
case 2:
var msgKey = "IRC.message.ConsoleInUseNoShare", tmrMsgKey = "IRC.message.TimedAutoDisconnect", msgBox = {
callback: "send_bool",
messageKey: msgKey,
stayTime: 10,
timerStringKey: tmrMsgKey,
title: null,
icon: null,
buttons: [ {
textKey: "IRC.control.Acquire",
isDefault: !0,
value: !0
}, {
textKey: "cancel",
isDefault: !1,
value: !1
} ]
};
return video.confirm(msgBox), void me.close();
case 3:
alertToast("status_labels.NOT_SUPPORTED");
break;
case 4:
video.toast({
text: "Bad Request",
type: "critical",
sticky: !0
});
break;
case 5:
video.toast({
text: "Internal Error",
type: "critical",
sticky: !0
});
break;
case 6:
case DVCNET.CMD_NO_SESSIONS:
alertToast("IRC.message.NoFreeSessions");
break;
case 7:
alertToast("IRC.message.FeatureNotLicensed");
break;
case "SyntaxError":
alertToast("IRC.message.WebSocketSyntaxError");
break;
case "IE+IPv6":
alertToast("IRC.message.WebSocketIEIPv6");
break;
default:
me.ie || isNaN(error) || video.toast({
text: "Unexpected error: " + error,
type: "critical",
sticky: !0
});
}
console.log("Handshake error: ", error), me.close(), me.onclose && me.onclose();
});
}