sinch-rtc
Version:
RTC JavaScript/Web SDK
195 lines • 7.47 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CallReportUtils = void 0;
const api_1 = require("../../ocra/api");
const api_2 = require("../../ocra/api");
const Direction_1 = require("../../session/Direction");
const SinchError_1 = require("../../SinchError");
const CallEndCause_1 = require("../CallEndCause");
const OutboundCall_1 = require("../OutboundCall");
const CallDestination_1 = require("./CallDestination");
const CallOrigin_1 = require("./CallOrigin");
/**
* Class acting as a helper for converting properties of different components into format used in
* call reporting functionality.
*/
class CallReportUtils {
static getCallResult(call) {
switch (call.details.endCause) {
case CallEndCause_1.CallEndCause.Canceled:
return api_1.CallResult.Canceled;
case CallEndCause_1.CallEndCause.Denied:
return api_1.CallResult.Denied;
case CallEndCause_1.CallEndCause.Failure:
return api_1.CallResult.Failure;
case CallEndCause_1.CallEndCause.HungUp:
case CallEndCause_1.CallEndCause.Inactive:
return CallReportUtils.inferHungUpResult(call.details);
case CallEndCause_1.CallEndCause.Timeout:
return api_1.CallResult.NoAnswer;
case CallEndCause_1.CallEndCause.OtherDeviceAnswered:
return api_1.CallResult.OtherPeerAnswered;
default:
return api_1.CallResult.Failure;
}
}
static getCallReportDirection(call) {
return call.direction == Direction_1.Direction.Inbound
? api_2.Direction.Inbound
: api_2.Direction.Outbound;
}
static getDurationInSeconds(durationMs) {
return durationMs / 1000;
}
static getClientErrors(error) {
if (error == undefined) {
return undefined;
}
const clientError = {
message: error.message,
code: error.code,
domain: CallReportUtils.getClientErrorDomain(error.domain),
};
return [clientError];
}
static getClientErrorDomain(domain) {
switch (domain) {
case SinchError_1.ErrorType.Http:
return api_1.ClientErrorDomain.Http;
case SinchError_1.ErrorType.Network:
return api_1.ClientErrorDomain.Network;
default:
return undefined;
}
}
static getRemoteDomain(call) {
return call instanceof OutboundCall_1.OutboundCall
? call.destination.domain
: call.remoteDomain;
}
static getCallDestination(call, userId) {
return new CallDestination_1.CallDestination(call, userId).getDestination();
}
static getCallOrigin(call, userId) {
return new CallOrigin_1.CallOrigin(call, userId).getOrigin();
}
static getCallReportInstance(instance) {
return {
version: instance.version,
id: instance.id,
};
}
static getIceCandidate(candidate) {
return {
address: candidate.address,
port: candidate.port,
type: this.getIceCandidateType(candidate.candidateType),
ipProtocolVersion: this.getIpVersion(candidate.address),
transportProtocol: this.getIceTransportProtocol(candidate.protocol),
relayProtocol: this.getRelayProtocol(candidate.relayProtocol),
url: candidate.url,
};
}
static getPrimaryIceCandidate({ connectionInfos, isLocal, }) {
const mapFunc = (connectionInfo) => isLocal
? connectionInfo.localIceCandidate
: connectionInfo.remoteIceCandidate;
const candidates = connectionInfos.map(mapFunc);
const frequencyMap = new Map();
candidates.forEach((candidate) => {
var _a;
const key = this.getIceCandidateHash(candidate);
frequencyMap.set(key, [(((_a = frequencyMap.get(key)) === null || _a === void 0 ? void 0 : _a[0]) || 0) + 1, candidate]);
});
let mostUsedCanididate = undefined;
let maxCount = 0;
for (const [, pair] of frequencyMap) {
if (pair[0] > maxCount) {
maxCount = pair[0];
mostUsedCanididate = pair[1];
}
}
return mostUsedCanididate;
}
static filterSubsequentSameConnectionInfos(connectionInfos) {
const filteredInfo = [];
let current;
for (const info of connectionInfos) {
if (current && this.isConnectionInfoEqual(current, info)) {
continue;
}
current = info;
filteredInfo.push(info);
}
return filteredInfo;
}
static isConnectionInfoEqual(a, b) {
return (this.getIceCandidateHash(a.localIceCandidate) ==
this.getIceCandidateHash(b.localIceCandidate) &&
this.getIceCandidateHash(a.remoteIceCandidate) ===
this.getIceCandidateHash(b.remoteIceCandidate));
}
static getIceCandidateHash(candidate) {
return `${candidate.address}:${candidate.port}:${candidate.ipProtocolVersion}:${candidate.type}:${candidate.transportProtocol}`;
}
static getIceCandidateType(type) {
switch (type) {
case "host":
return api_1.IceCandidateType.Host;
case "prflx":
return api_1.IceCandidateType.Prflx;
case "relay":
return api_1.IceCandidateType.Relay;
case "srflx":
return api_1.IceCandidateType.Srflx;
}
}
static getIceTransportProtocol(transport) {
switch (transport) {
case "udp":
return api_1.TransportProtocol.Udp;
case "tcp":
return api_1.TransportProtocol.Tcp;
}
}
static getRelayProtocol(protocol) {
if (protocol === undefined || protocol === null) {
return undefined;
}
switch (protocol.toLowerCase()) {
case "udp":
return api_1.RelayProtocol.Udp;
case "tcp":
return api_1.RelayProtocol.Tcp;
case "tls":
return api_1.RelayProtocol.Tls;
default:
return undefined;
}
}
static getIpVersion(host) {
// The "address" field in WebRTC stats could contain:
// - ipv4 address
// - ipv6 address
// - fully qualified domain name
// https://www.w3.org/TR/webrtc-stats/#dom-rtcicecandidatestats-address
if (host === undefined) {
return api_1.IpProtocolVersion.Unknown;
}
const dotCount = host.split(".").length - 1;
if (dotCount == 3) {
return api_1.IpProtocolVersion.Ipv4;
}
// ipv6 supports "compressed" representation, that omits leading zeroes.
const colonsCount = host.split(":").length - 1;
if (colonsCount >= 1)
return api_1.IpProtocolVersion.Ipv6;
return api_1.IpProtocolVersion.Unknown;
}
static inferHungUpResult(details) {
const wasEstablished = details.establishedTime != undefined;
return wasEstablished ? api_1.CallResult.Established : api_1.CallResult.Answered;
}
}
exports.CallReportUtils = CallReportUtils;
//# sourceMappingURL=CallReportUtils.js.map