// Module ID: 2011 // Function ID: 2012 // Name: RTCControlSocket // Dependencies: [1370, 2012, 5117, 1102, 5140, 569, 3, 5121, 14388, 1382, 38, 2] // Module 2011 (RTCControlSocket) import LoggerDefault from "Logger" /* 3 */; import _modDef38 from "module_38" /* 38 */; import BackoffDefault from "Backoff" /* 569 */; import DurationsDefault from "Durations" /* 1102 */; import PlatformUtils from "PlatformUtils" /* 1382 */; import TimeUtils from "TimeUtils" /* 5121 */; import DeveloperOptionsStore from "DeveloperOptionsStore" /* 1370 */; import MediaEngineStore from "MediaEngineStore" /* 2012 */; import Constants from "Constants" /* 5117 */; import TypedEventEmitter from "TypedEventEmitter" /* 5140 */; import size_mod from "module_2" /* 2 */; let hasOwnProperty; let metroImportAll; let metroImportDefault; let metroRequire; const f87117 = (name) => ({ name: name.name, type: name.type, priority: 1000 * name.priority, payload_type: name.payloadType, rtx_payload_type: name.rtxPayloadType, encode: name.encode, decode: name.decode }); const f87118 = (type) => { let tmp; const obj = { type: type.type, rid: type.rid, ssrc: type.ssrc, active: type.active, quality: type.quality, rtx_ssrc: type.rtxSsrc, max_bitrate: type.maxBitrate, max_framerate: type.maxFrameRate, max_resolution: tmp }; tmp = undefined; if (null != type.maxResolution) { size = { type: type.maxResolution.type, width: type.maxResolution.width, height: type.maxResolution.height }; tmp = size; } return obj; }; const f87119 = (rid) => { let VIDEO; let tmp5; const type = rid.type; if ("audio" === type) { VIDEO = constants.AUDIO; } else if ("test" === type) { VIDEO = constants.TEST; } else if ("screen" === type) { VIDEO = constants.SCREEN; } else { VIDEO = constants.VIDEO; } const obj = { type: VIDEO, rid: rid.rid, ssrc: rid.ssrc, rtxSsrc: rid.rtx_ssrc, active: rid.active, quality: rid.quality, maxBitrate: rid.max_bitrate, maxFrameRate: rid.max_framerate, maxResolution: tmp5 }; tmp5 = undefined; if (null != rid.max_resolution) { size = { type: rid.max_resolution.type, width: rid.max_resolution.width, height: rid.max_resolution.height }; tmp5 = size; } return obj; }; function noop() { } ({ Features: hasOwnProperty, MediaEngineContextTypes: metroRequire, MediaTypes: metroImportDefault, SpeakingFlags: metroImportAll } = Constants); const RTCSocketOpcode = { IDENTIFY: 0, [0]: "IDENTIFY", SELECT_PROTOCOL: 1, [1]: "SELECT_PROTOCOL", READY: 2, [2]: "READY", HEARTBEAT: 3, [3]: "HEARTBEAT", SELECT_PROTOCOL_ACK: 4, [4]: "SELECT_PROTOCOL_ACK", SPEAKING: 5, [5]: "SPEAKING", HEARTBEAT_ACK: 6, [6]: "HEARTBEAT_ACK", RESUME: 7, [7]: "RESUME", HELLO: 8, [8]: "HELLO", RESUMED: 9, [9]: "RESUMED", CLIENT_CONNECT: 11, [11]: "CLIENT_CONNECT", VIDEO: 12, [12]: "VIDEO", CLIENT_DISCONNECT: 13, [13]: "CLIENT_DISCONNECT", SESSION_UPDATE: 14, [14]: "SESSION_UPDATE", MEDIA_SINK_WANTS: 15, [15]: "MEDIA_SINK_WANTS", VOICE_BACKEND_VERSION: 16, [16]: "VOICE_BACKEND_VERSION", CHANNEL_OPTIONS_UPDATE: 17, [17]: "CHANNEL_OPTIONS_UPDATE", FLAGS: 18, [18]: "FLAGS", PLATFORM: 20, [20]: "PLATFORM", DAVE_PROTOCOL_PREPARE_TRANSITION: 21, [21]: "DAVE_PROTOCOL_PREPARE_TRANSITION", DAVE_PROTOCOL_EXECUTE_TRANSITION: 22, [22]: "DAVE_PROTOCOL_EXECUTE_TRANSITION", DAVE_PROTOCOL_READY_FOR_TRANSITION: 23, [23]: "DAVE_PROTOCOL_READY_FOR_TRANSITION", DAVE_PROTOCOL_PREPARE_EPOCH: 24, [24]: "DAVE_PROTOCOL_PREPARE_EPOCH", MLS_EXTERNAL_SENDER_PACKAGE: 25, [25]: "MLS_EXTERNAL_SENDER_PACKAGE", MLS_KEY_PACKAGE: 26, [26]: "MLS_KEY_PACKAGE", MLS_PROPOSALS: 27, [27]: "MLS_PROPOSALS", MLS_COMMIT_WELCOME: 28, [28]: "MLS_COMMIT_WELCOME", MLS_PREPARE_COMMIT_TRANSITION: 29, [29]: "MLS_PREPARE_COMMIT_TRANSITION", MLS_WELCOME: 30, [30]: "MLS_WELCOME", MLS_INVALID_COMMIT_WELCOME: 31, [31]: "MLS_INVALID_COMMIT_WELCOME", CLIENT_CANNOT_REACH_RTC_SERVER: 32, [32]: "CLIENT_CANNOT_REACH_RTC_SERVER", SFU_UPDATE: 33, [33]: "SFU_UPDATE" }; let obj2 = { AUTHENTICATION_FAILED: 4004, [4004]: "AUTHENTICATION_FAILED", INVALID_SESSION: 4006, [4006]: "INVALID_SESSION", SERVER_NOT_FOUND: 4011, [4011]: "SERVER_NOT_FOUND", SERVER_CRASH: 4015, [4015]: "SERVER_CRASH", CANCELED: 4016, [4016]: "CANCELED", HEARTBEAT_TIMEOUT: 4800, [4800]: "HEARTBEAT_TIMEOUT", UNRESUMABLE: 4801, [4801]: "UNRESUMABLE", RESET_BACKOFF: 4802, [4802]: "RESET_BACKOFF", REPEATED_MLS_INVALID_MESSAGES: 4803, [4803]: "REPEATED_MLS_INVALID_MESSAGES", DAVE_DOWNGRADE_REFUSED: 4804, [4804]: "DAVE_DOWNGRADE_REFUSED" }; const authStore2 = { DISCONNECTED: 0, [0]: "DISCONNECTED", CONNECTING: 1, [1]: "CONNECTING", IDENTIFYING: 2, [2]: "IDENTIFYING", RESUMING: 3, [3]: "RESUMING", CONNECTED: 4, [4]: "CONNECTED", RECONNECTING: 5, [5]: "RECONNECTING" }; let closure_13 = 20 * DurationsDefault.Millis.SECOND; const MINUTE = DurationsDefault.Millis.MINUTE; let closure_15 = 5 * DurationsDefault.Millis.SECOND; let obj3 = { Connecting: "connecting", Connect: "connect", Disconnect: "disconnect", Resuming: "resuming", Ready: "ready", SelectProtocolAck: "select-protocol-ack", SfuUpdate: "sfu-update", Speaking: "speaking", Video: "video", Ping: "ping", ClientConnect: "client-connect", ClientDisconnect: "client-disconnect", Codecs: "codecs", MediaSessionId: "media-session-id", MediaSinkWants: "media-sink-wants", VoiceBackendVersion: "voice-backend-version", KeyframeInterval: "keyframe-interval", ChannelOptionsUpdateSecureFramesProtocol: "update-secure-frames-protocol", Flags: "flags", Platform: "platform", SDP: "sdp", Encryption: "encryption", BandwidthEstimationExperiment: "bandwidth-estimation-experiment", SecureFramesInit: "secure-frames-init", SecureFramesPrepareTransition: "secure-frames-prepare-transition", SecureFramesExecuteTransition: "secure-frames-execute-transition", SecureFramesPrepareEpoch: "secure-frames-prepare-epoch", MLSExternalSenderPackage: "mls-external-sender-package", MLSProposals: "mls-proposals", MLSPrepareCommitTransition: "mls-prepare-commit-transition", MLSWelcome: "mls-welcome", ReceiveMessage: "receive-message", SendMessage: "send-message" }; class RTCControlSocket extends TypedEventEmitter { constructor(url, DEFAULT) { if (DEFAULT === undefined) { DEFAULT = metroRequire.DEFAULT; } const tmp6 = new RTCControlSocket(tmp4, tmp3, tmp2, DEFAULT, tmp, url); tmp6.backoff = new BackoffDefault(1000, 5000); tmp6.serverVersion = 0; tmp6.url = url; new BackoffDefault(1000, 5000); const tmp8 = LoggerDefault; tmp6.logger = new tmp8("RTCControlSocket(" + DEFAULT + ")"); const logger = tmp6.logger; new tmp8("RTCControlSocket(" + DEFAULT + ")"); logger.enableNativeLogger(true); tmp6.webSocket = null; tmp6.connectionState = constants3.DISCONNECTED; tmp6.helloTimeout = null; tmp6.lastHeartbeatAckTime = null; tmp6.heartbeatInterval = null; tmp6.heartbeater = null; tmp6.heartbeatAck = true; tmp6.expeditedHeartbeatTimeout = null; tmp6.heartbeatIntervalModifier = 1; tmp6.connectionStartTime = 0; tmp6.lastRecvSeqNum = null; tmp6.sessionId = null; tmp6.serverId = null; tmp6.channelId = null; tmp6.token = null; tmp6.resumable = false; return tmp6; } createWebSocket() { let self = this; let logger = this.logger; logger.info("[CONNECT] " + this.url); if (null !== this.webSocket) { let logger2 = self.logger; let str = "Connect called with already existing websocket"; logger2.error("Connect called with already existing websocket"); self.cleanupWebSocket((close) => close.close(4000)); } let obj = self(5121); self.connectionStartTime = obj.now(); self.helloTimeout = setTimeout(() => { const obj = TimeUtils; self.handleClose(false, 0, "The connection timed out after " + obj.now() - self.connectionStartTime + " ms - did not receive OP_HELLO in time."); }, closure_13); obj2 = self(14388); obj3 = { location: "RTCControlSocket", supportsSfuUpdate: MediaEngineStore.supports(constants.UDP_ENDPOINT_UPDATE) }; const webSocket = new WebSocket("" + self.url + "?v=" + obj2.getVoiceGatewayProtocolVersion(obj3)); self.webSocket = webSocket; webSocket.binaryType = "arraybuffer"; webSocket.onopen = () => { if (self.connectionState === constants.CONNECTING) { self.emit(obj3.Connect); } else if (self.connectionState === constants.RECONNECTING) { self.doResumeOrClose(); } self.connectionState = constants.CONNECTED; obj2 = TimeUtils; const diff = obj2.now() - obj.connectionStartTime; const logger = obj.logger; logger.info("[CONNECTED] " + self.url + " in " + diff + " ms"); self.emit(obj3.Ping, Math.round(diff / 2)); }; webSocket.onmessage = function(data) { let audio_ssrc; let d; let op; let seq; let streams; let user_id; let video_ssrc; let obj = self; const result = self.parseWebSocketMessage(data); ({ op, seq, d } = result); self.emit(obj3.ReceiveMessage, op, d); if (seq) { obj.lastRecvSeqNum = seq; } if (DeveloperOptionsStore.isLoggingGatewayEvents) { let tmp5 = globalThis; const _Uint8Array = Uint8Array; if (d instanceof Uint8Array) { const items = []; HermesBuiltin.arraySpread(items, d, 0); const mapped = items.map((item) => { const str = item.toString(16); return str.padStart(2, "0"); }); const logger2 = obj.logger; const _HermesInternal2 = HermesInternal; logger2.info("~> " + op + ": 0x" + mapped.join("")); } else { const logger = obj.logger; const _JSON = JSON; const _HermesInternal = HermesInternal; let str = ": "; logger.info("~> " + op + ": " + JSON.stringify(d)); } } if (obj.HELLO === op) { obj.clearHelloTimeout(); obj.handleHello(d); } else if (obj.READY === op) { obj.handleReady(d); } else if (obj.SFU_UPDATE === op) { obj.emit(obj3.SfuUpdate, d); } else if (obj.RESUMED === op) { obj.handleResumed(d); } else if (obj.SELECT_PROTOCOL_ACK === op) { obj.emit(obj3.SelectProtocolAck); if (d.bandwidth_estimation_experiment) { obj.emit(obj3.BandwidthEstimationExperiment, d.bandwidth_estimation_experiment); } obj.emit(obj3.Codecs, d.audio_codec, d.video_codec); if (d.media_session_id) { obj.emit(obj3.MediaSessionId, d.media_session_id); } if (d.sdp) { obj.emit(obj3.SDP, d.sdp); } else if (d.mode) { obj.emit(obj3.Encryption, d.mode, d.secret_key); } if (d.keyframe_interval) { obj.emit(obj3.KeyframeInterval, d.keyframe_interval); } let num8 = d.dave_protocol_version; const emit2 = obj.emit; const SecureFramesInit = tmp3.SecureFramesInit; if (!num8) { num8 = 0; } emit2(SecureFramesInit, num8); obj.resumable = true; } else if (obj.SPEAKING === op) { const speaking = d.speaking; let tmp58 = speaking; if (typeof speaking === "boolean") { tmp58 = speaking ? tmp76.VOICE : tmp76.NONE; } obj.emit(obj3.Speaking, d.user_id, d.ssrc, tmp58); } else if (obj.HEARTBEAT === op) { obj.sendHeartbeat(); } else if (obj.HEARTBEAT_ACK === op) { obj.handleHeartbeatAck(d); } else if (obj.VIDEO === op) { const Video = tmp3.Video; ({ user_id, audio_ssrc, video_ssrc, streams } = d); let mapped1; const emit = obj.emit; if (streams != null) { mapped1 = streams.map(f87119); } if (mapped1 == null) { mapped1 = []; } emit(Video, user_id, audio_ssrc, video_ssrc, mapped1); } else if (obj.CLIENT_CONNECT === op) { obj.emit(obj3.ClientConnect, d.user_ids); } else if (obj.CLIENT_DISCONNECT === op) { obj.emit(obj3.ClientDisconnect, d.user_id); } else if (obj.SESSION_UPDATE === op) { const tmp42 = null == d.audio_codec && null == d.video_codec; if (!tmp42) { obj.emit(obj3.Codecs, d.audio_codec, d.video_codec); } if (null != d.media_session_id) { obj.emit(obj3.MediaSessionId, d.media_session_id); } if (d.keyframe_interval) { obj.emit(obj3.KeyframeInterval, d.keyframe_interval); } } else if (obj.MEDIA_SINK_WANTS === op) { obj.emit(obj3.MediaSinkWants, d); } else if (obj.VOICE_BACKEND_VERSION === op) { const tmp38 = null != d.voice && null != d.rtc_worker; if (tmp38) { obj.emit(obj3.VoiceBackendVersion, d.voice, d.rtc_worker); } } else if (obj.FLAGS === op) { const tmp35 = null != d.flags && null != d.user_id; if (tmp35) { obj.emit(obj3.Flags, d.user_id, d.flags); } } else if (obj.PLATFORM === op) { const tmp32 = null != d.platform && null != d.user_id; if (tmp32) { obj.emit(obj3.Platform, d.user_id, d.platform); } } else if (obj.DAVE_PROTOCOL_PREPARE_TRANSITION === op) { const tmp29 = null != d.transition_id && null != d.protocol_version; if (tmp29) { obj.emit(obj3.SecureFramesPrepareTransition, d.transition_id, d.protocol_version); } } else if (obj.DAVE_PROTOCOL_EXECUTE_TRANSITION === op) { if (null != d.transition_id) { obj.emit(obj3.SecureFramesExecuteTransition, d.transition_id); } } else if (obj.DAVE_PROTOCOL_PREPARE_EPOCH === op) { const tmp25 = null != d.epoch && null != d.protocol_version; if (tmp25) { obj.emit(obj3.SecureFramesPrepareEpoch, d.epoch, d.protocol_version); } } else if (obj.MLS_EXTERNAL_SENDER_PACKAGE === op) { obj.emit(obj3.MLSExternalSenderPackage, d); } else if (obj.MLS_PROPOSALS === op) { obj.emit(obj3.MLSProposals, d); } else if (obj.MLS_PREPARE_COMMIT_TRANSITION === op) { const _DataView2 = DataView; const self3 = this; const self4 = this; const dataView = new DataView(d.buffer, d.byteOffset, 2); const uint16 = dataView.getUint16(0, false); obj.emit(obj3.MLSPrepareCommitTransition, uint16, d.slice(2)); } else if (obj.MLS_WELCOME === op) { const _DataView = DataView; self = this; const self2 = this; const dataView1 = new DataView(d.buffer, d.byteOffset, 2); const uint161 = dataView1.getUint16(0, false); obj.emit(obj3.MLSWelcome, uint161, d.slice(2)); } else { const logger3 = obj.logger; const _HermesInternal3 = HermesInternal; logger3.info("Unhandled op " + op); } }; webSocket.onerror = () => self.handleClose(false, 0, "An error with the websocket occurred"); webSocket.onclose = (wasClean) => self.handleClose(wasClean.wasClean, wasClean.code, wasClean.reason); } send(op) { let tmp = arg1; if (arg1 === undefined) { tmp = null; } const self = this; const webSocket = this.webSocket; if (null != webSocket) { const _WebSocket = WebSocket; if (webSocket.readyState === WebSocket.OPEN) { const _JSON = JSON; const obj = { op, d: tmp }; const json = JSON.stringify(obj); if (DeveloperOptionsStore.isLoggingGatewayEvents) { const logger = self.logger; const _HermesInternal = HermesInternal; logger.info("<~ " + json); } self.emit(obj3.SendMessage, op, tmp); try { webSocket.send(json); } catch (err) { } } } } sendBinary(MLS_COMMIT_WELCOME, uint8Array) { const webSocket = this.webSocket; if (null != webSocket) { const _WebSocket = WebSocket; if (webSocket.readyState === WebSocket.OPEN) { const _Uint8Array = Uint8Array; const self = this; const self2 = this; uint8Array = new Uint8Array(uint8Array.byteLength + 1); uint8Array[0] = MLS_COMMIT_WELCOME; const result = uint8Array.set(uint8Array, 1); try { webSocket.send(uint8Array.buffer); } catch (err) { } } } } doResumeOrClose() { const self = this; const obj = TimeUtils; const nowResult = obj.now(); if (null !== this.serverId) { if (null !== self.channelId) { if (null !== self.token) { if (null !== self.sessionId) { if (self.resumable) { self.doResume(); self.lastHeartbeatAckTime = nowResult; } } } } } self.disconnect(false, obj2.UNRESUMABLE, "Cannot resume connection."); } doResume() { let logger; let serverId; const self = this; let num = this.lastRecvSeqNum; if (num == null) { num = -1; } ({ logger, serverId } = self); const info = logger.info; if (serverId == null) { serverId = ""; } let str = self.channelId; if (str == null) { str = ""; } let str2 = self.sessionId; if (str2 == null) { str2 = ""; } info("[RESUME] resuming session. serverId=" + serverId + " channelId=" + str + " sessionId=" + str2 + " seqAck=" + num); self.emit(obj3.Resuming); self.connectionState = constants3.RESUMING; const obj = { token: self.token, session_id: self.sessionId, server_id: self.serverId, channel_id: self.channelId, seq_ack: num }; self.send(obj.RESUME, obj); } handleHello(d) { let heartbeatInterval; let logger; let tmp4; let num = d.v; if (num == null) { num = 3; } const self = this; this.serverVersion = num; if (this.serverVersion <= 3) { let num3 = 0.1; const tmp7 = require; if (PlatformUtils.isPlatformEmbedded) { num3 = 0.25; } self.heartbeatInterval = d.heartbeat_interval * num3; tmp4 = tmp7; } else { self.heartbeatInterval = d.heartbeat_interval * self.heartbeatIntervalModifier; tmp4 = require; const tmp = require; if (!PlatformUtils.isPlatformEmbedded) { let num2 = self.heartbeatInterval; const _Math = Math; const tmp6 = closure_15; if (num2 == null) { num2 = NaN; } self.heartbeatInterval = min(tmp6, num2); tmp4 = tmp; } } const tmp4Result = tmp4(5121); const diff = tmp4Result.now() - self.connectionStartTime; ({ logger, heartbeatInterval } = self); const info = logger.info; if (heartbeatInterval == null) { heartbeatInterval = "??"; } info("[HELLO] heartbeat interval: " + heartbeatInterval + ", version: " + self.serverVersion + ", took " + diff + " ms"); self.startHeartbeater(); } handleReady(experiments) { let ip; let modes; let port; let ssrc; let streams; const self = this; const backoff = this.backoff; backoff.succeed(); const obj = TimeUtils; const logger = this.logger; logger.info("[READY] took " + obj.now() - this.connectionStartTime + " ms"); if (this.serverVersion >= 6) { self.send(obj.VOICE_BACKEND_VERSION, {}); } const Ready = obj3.Ready; ({ ip, port, modes, ssrc, streams } = experiments); let mapped; const emit = self.emit; if (streams != null) { mapped = streams.map(f87119); } if (mapped == null) { mapped = []; } emit(Ready, ip, port, modes, ssrc, mapped, experiments.experiments); } supportsSfuUpdate() { return this.serverVersion >= 10; } handleResumed() { const backoff = this.backoff; backoff.succeed(); } handleClose(arg0, arg1, arg2) { let backoff; let logger2; const self = this; let flag = arg0; let closure_2 = arg1; let closure_0 = arg2; this.connectionState = constants3.DISCONNECTED; if (!arg0) { flag = false; } self.cleanupWebSocket(); if (arg1 !== obj2.AUTHENTICATION_FAILED) { if (arg1 !== obj2.SERVER_CRASH) { if (arg1 !== obj2.SERVER_NOT_FOUND) { if (arg1 !== obj2.INVALID_SESSION) { if (self.backoff.fails > 3) { const logger = self.logger; logger.warn("[WS CLOSED] Backoff exceed. Resetting."); self.disconnect(flag, arg1, arg2); } else { ({ backoff, logger: logger2 } = self); const warn = logger2.warn; const failResult = backoff.fail(() => self.reconnect(flag, closure_2, closure_0)); const result = failResult / 1000; const _HermesInternal = HermesInternal; const str1 = flag.toString(); warn("[WS CLOSED] (clean: " + str1 + ", code: " + arg1 + ", reason: " + arg2 + ") retrying in " + result.toFixed(2) + " seconds."); } } } } } return self.disconnect(flag, arg1, arg2); } disconnect(arg0, arg1, arg2) { const logger = this.logger; logger.warn("[DISCONNECT] (" + arg0.toString() + ", " + arg1 + ", " + arg2 + ")"); this.cleanupWebSocket(); this.cleanupState(); this.connectionState = constants3.DISCONNECTED; this.emit(obj3.Disconnect, arg0, arg1, arg2); } reconnect(arg0, arg1, arg2) { const logger = this.logger; logger.info("[RECONNECT] wasClean=" + arg0.toString() + " code=" + arg1 + " reason=" + arg2); this.cleanupWebSocket((close) => close.close(4000)); this.connectionState = constants3.RECONNECTING; const webSocket = this.createWebSocket(); } cleanupWebSocket(fn) { this.stopHeartbeater(); this.clearHelloTimeout(); const webSocket = this.webSocket; this.webSocket = null; if (null != webSocket) { webSocket.onopen = noop; webSocket.onmessage = noop; webSocket.onerror = noop; webSocket.onclose = noop; if (fn != null) { fn(webSocket); } } const backoff = this.backoff; backoff.cancel(); } cleanupState() { this.serverId = null; this.channelId = null; this.sessionId = null; this.token = null; this.resumable = false; this.lastRecvSeqNum = null; } parseWebSocketMessage(data) { if (data.data instanceof ArrayBuffer) { const _Uint8Array = Uint8Array; const self2 = this; const self3 = this; const self = this; const uint8Array = new Uint8Array(data.data); let uint16 = null; if (this.serverVersion >= 8) { const _DataView = DataView; const self4 = this; const self5 = this; const dataView = new DataView(uint8Array.buffer); uint16 = dataView.getUint16(0, false); } let num3 = 0; if (self.serverVersion >= 8) { num3 = 2; } const obj = { op: uint8Array[num3], seq: uint16, d: uint8Array.subarray(num3 + 1) }; return obj; } else { const _JSON = JSON; return JSON.parse(data.data); } } clearHelloTimeout() { const self = this; if (null != this.helloTimeout) { const _clearTimeout = clearTimeout; clearTimeout(self.helloTimeout); self.helloTimeout = null; } } handleHeartbeatAck(d) { const self = this; const logger = this.logger; logger.info("Heartbeat ACK received"); let t = d; if (this.serverVersion >= 8) { t = d.t; } const emit = self.emit; const Ping = obj3.Ping; const obj = TimeUtils; emit(Ping, obj.now() - t); obj2 = TimeUtils; self.lastHeartbeatAckTime = obj2.now(); self.heartbeatAck = true; if (null !== self.expeditedHeartbeatTimeout) { const _clearTimeout = clearTimeout; clearTimeout(self.expeditedHeartbeatTimeout); self.expeditedHeartbeatTimeout = null; const logger2 = self.logger; logger2.info("Expedited heartbeat succeeded"); } } handleHeartbeatTimeout() { let backoff; let logger; const self = this; this.cleanupWebSocket((close) => close.close(4000)); ({ backoff, logger } = this); const result = backoff.fail(() => self.reconnect(false, obj2.HEARTBEAT_TIMEOUT, "Heartbeat timeout.")) / 1000; logger.warn("[HEARTBEAT ACK TIMEOUT] reconnecting in " + result.toFixed(2) + " seconds."); } startHeartbeater() { const self = this; _modDef38(null != this.heartbeatInterval, "RTCControlSocket: Heartbeat interval should never null here."); const logger = this.logger; logger.info("Starting heartbeat with interval: " + this.heartbeatInterval); if (null !== this.heartbeater) { const _clearInterval = clearInterval; clearInterval(self.heartbeater); } self.heartbeatAck = true; self.heartbeater = setInterval(() => { if (self.heartbeatAck) { self.heartbeatAck = false; self.sendHeartbeat(); } else if (null === self.expeditedHeartbeatTimeout) { const result = obj.handleHeartbeatTimeout(); } }, self.heartbeatInterval); } sendHeartbeat() { let obj; const self = this; if (this.serverVersion >= 8) { let num = self.lastRecvSeqNum; if (num == null) { num = -1; } const logger2 = self.logger; const _HermesInternal = HermesInternal; logger2.info("Sending heartbeat with last received sequence number: " + num); const send2 = self.send; const HEARTBEAT2 = obj.HEARTBEAT; obj2 = { t: obj3.now(), seq_ack: num }; obj3 = TimeUtils; send2(HEARTBEAT2, obj2); } else { const logger = self.logger; logger.info("Sending heartbeat"); const send = self.send; const HEARTBEAT = obj.HEARTBEAT; obj = TimeUtils; send(HEARTBEAT, obj.now()); } } stopHeartbeater() { const self = this; if (null !== this.heartbeater) { const _clearInterval = clearInterval; clearInterval(self.heartbeater); self.heartbeater = null; } if (null !== self.expeditedHeartbeatTimeout) { const _clearTimeout = clearTimeout; clearTimeout(self.expeditedHeartbeatTimeout); self.expeditedHeartbeatTimeout = null; } } connect() { let flag; const self = this; if (this.connectionState !== constants3.DISCONNECTED) { const logger = self.logger; logger.error("Cannot start a new connection, connection state is not disconnected"); flag = false; } else { self.connectionState = tmp.CONNECTING; const webSocket = self.createWebSocket(); self.emit(obj3.Connecting); flag = true; } return flag; } identify(streamParameters) { let channelId; let mapped; let maxDaveProtocolVersion; let serverId; let sessionId; let token; let userId; let video; ({ serverId, channelId, sessionId, token, video } = streamParameters); ({ userId, maxDaveProtocolVersion } = streamParameters); if (video === undefined) { video = false; } streamParameters = streamParameters.streamParameters; this.serverId = serverId; this.channelId = channelId; this.sessionId = sessionId; this.token = token; this.connectionState = constants3.IDENTIFYING; const obj = { server_id: serverId, channel_id: channelId, user_id: userId, session_id: sessionId, token, max_dave_protocol_version: maxDaveProtocolVersion, video, streams: mapped }; mapped = undefined; const send = this.send; const IDENTIFY = obj.IDENTIFY; if (streamParameters != null) { mapped = streamParameters.map(f87118); } send(IDENTIFY, obj); } expeditedHeartbeat(arg0) { const self = this; let str = arg1; if (arg1 === undefined) { str = ""; } let flag = arg2; if (arg2 === undefined) { flag = true; } if (null != self.webSocket) { const logger2 = self.logger; let str5 = ""; const info2 = logger2.info; if ("" !== str) { str5 = `reason: ${str}`; } info2(`Performing an expedited heartbeat ${str5}`); self.heartbeatAck = false; self.sendHeartbeat(); if (null !== self.expeditedHeartbeatTimeout) { const _clearTimeout = clearTimeout; clearTimeout(self.expeditedHeartbeatTimeout); } const _setTimeout = setTimeout; self.expeditedHeartbeatTimeout = setTimeout(() => { self.expeditedHeartbeatTimeout = null; const obj = self; if (false === self.heartbeatAck) { const result = obj.handleHeartbeatTimeout(); } }, arg0); } else if (flag) { return self.resetBackoff(str); } else { const logger = self.logger; let str2 = ""; const info = logger.info; if ("" !== str) { str2 = `reason: ${str}`; } info(`Expedited heartbeat requested, but is disconnected and a reset was not requested ${str2}`); } return false; } resetBackoff() { let str = arg0; if (arg0 === undefined) { str = ""; } const self = this; let flag = this.backoff.fails > 0 && null == self.webSocket; if (flag) { const logger = self.logger; let str2 = ""; const info = logger.info; if ("" !== str) { str2 = `for reason: ${str}`; } info(`Connection backoff reset ${str2}`); const backoff = self.backoff; backoff.succeed(); self.reconnect(false, obj2.RESET_BACKOFF, "Reset backoff."); flag = true; } return flag; } close() { const logger = this.logger; logger.info("CLOSE"); this.cleanupWebSocket((close) => close.close(4000)); this.cleanupState(); this.connectionState = constants3.DISCONNECTED; this.emit(obj3.Disconnect, true, 1000, "Force Close"); } destroy() { this.close(); } selectProtocol(protocol, rTCConnectionId, sdp, _selectedExperiments) { let codecs; let codecs1; const obj = {}; let tmp = obj; sdp = null; if (null != sdp) { if ("sdp" in sdp) { if (null != sdp.sdp) { if ("" !== sdp.sdp) { sdp = sdp.sdp; obj3 = { codecs: codecs.map(f87117), rtc_connection_id: rTCConnectionId }; const merged = Object.assign(sdp); codecs = sdp.codecs; tmp = obj3; } } } let BooleanResult = "address" in sdp && null != sdp.address && "" !== sdp.address; if (BooleanResult) { const _Boolean = Boolean; BooleanResult = Boolean(sdp.port); } if (BooleanResult) { BooleanResult = null != sdp.mode; } if (BooleanResult) { BooleanResult = "" !== sdp.mode; } tmp = obj; if (BooleanResult) { const obj4 = { address: null, port: null, mode: null }; ({ address: obj2.address, port: obj2.port, mode: obj2.mode } = sdp); const obj5 = { codecs: codecs1.map(f87117), rtc_connection_id: rTCConnectionId, experiments: _selectedExperiments }; const merged1 = Object.assign(sdp); codecs1 = sdp.codecs; tmp = obj5; sdp = obj4; } } const send = this.send; const SELECT_PROTOCOL = obj.SELECT_PROTOCOL; const obj9 = { protocol, data: sdp }; const merged2 = Object.assign(tmp); send(SELECT_PROTOCOL, obj9); } updateSession(codecs) { const obj = { codecs: codecs.map(f87117) }; codecs = codecs.codecs; const send = this.send; const SESSION_UPDATE = obj.SESSION_UPDATE; send(SESSION_UPDATE, obj); } speaking(_lastSentSpeakingStatus, packetDelay, _lastSentSSRC) { let num = packetDelay; if (packetDelay === undefined) { num = 0; } let num2 = _lastSentSSRC; if (_lastSentSSRC === undefined) { num2 = 0; } let BooleanResult = _lastSentSpeakingStatus; const send = this.send; const SPEAKING = obj.SPEAKING; if (this.serverVersion <= 3) { const _Boolean = Boolean; BooleanResult = Boolean(_lastSentSpeakingStatus); } send(SPEAKING, { speaking: BooleanResult, delay: num, ssrc: num2 }); } video(audio_ssrc, video_ssrc, rtx_ssrc, arr) { let mapped; let obj = { audio_ssrc, video_ssrc, rtx_ssrc, streams: mapped }; mapped = undefined; const send = this.send; const VIDEO = obj.VIDEO; if (arr != null) { mapped = arr.map(f87118); } send(VIDEO, obj); } mediaSinkWants(localVideoSinkWants) { const self = this; if (this.serverVersion >= 5) { self.send(obj.MEDIA_SINK_WANTS, localVideoSinkWants); } } secureFramesReadyForTransition(transition_id) { const obj = { transition_id }; this.send(obj.DAVE_PROTOCOL_READY_FOR_TRANSITION, obj); } sendMLSKeyPackage(arg0) { const logger = this.logger; logger.info("Sending MLS key package"); const sendBinary = this.sendBinary; const MLS_KEY_PACKAGE = obj.MLS_KEY_PACKAGE; const uint8Array = new Uint8Array(arg0); sendBinary(MLS_KEY_PACKAGE, uint8Array); } sendMLSCommitWelcome(byteLength) { const logger = this.logger; logger.info("Sending MLS commit + welcome message"); const sendBinary = this.sendBinary; const MLS_COMMIT_WELCOME = obj.MLS_COMMIT_WELCOME; const uint8Array = new Uint8Array(byteLength); sendBinary(MLS_COMMIT_WELCOME, uint8Array); } flagMLSInvalidCommitWelcome(transition_id) { const obj = { transition_id }; this.send(obj.MLS_INVALID_COMMIT_WELCOME, obj); } disconnectForRepeatedMLSInvalidMessages(arg0) { const logger = this.logger; logger.warn("[MLS] " + arg0 + " consecutive invalid commit/welcome messages."); this.cleanupWebSocket((close) => close.close(constants.REPEATED_MLS_INVALID_MESSAGES)); this.disconnect(false, obj2.REPEATED_MLS_INVALID_MESSAGES, "Repeated invalid MLS commit/welcome messages."); } disconnectForRefusedDaveDowngrade(EPOCH) { const logger = this.logger; logger.warn("[DAVE] Refused protocol downgrade to version 0 at " + EPOCH + "."); this.cleanupWebSocket((close) => close.close(constants.DAVE_DOWNGRADE_REFUSED)); this.disconnect(false, obj2.DAVE_DOWNGRADE_REFUSED, "Refused DAVE protocol downgrade."); } noRoute() { this.send(obj.CLIENT_CANNOT_REACH_RTC_SERVER, {}); } setHeartbeatIntervalModifier(heartbeatIntervalModifier) { this.heartbeatIntervalModifier = heartbeatIntervalModifier; } } const prototype = RTCControlSocket.prototype; let size = size_mod; let result = size.fileFinishedImporting("lib/RTCControlSocket.tsx"); export default RTCControlSocket; export { RTCSocketOpcode }; export const RTCSocketCloseCode = obj2; export const SocketEvent = obj3;