@telegenta/webclient 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,17 @@
1
1
  <!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Source: phone-client.js</title><!--[if lt IE 9]>
2
2
  <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
3
- <![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="dark"><div class="sidebar-container"><div class="sidebar" id="sidebar"><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="EventClient.html">EventClient</a></div><div class="sidebar-section-children"><a href="InvalidMediaDevice.html">InvalidMediaDevice</a></div><div class="sidebar-section-children"><a href="InvalidOptions.html">InvalidOptions</a></div><div class="sidebar-section-children"><a href="InvalidParameter.html">InvalidParameter</a></div><div class="sidebar-section-children"><a href="LogHandler.html">LogHandler</a></div><div class="sidebar-section-children"><a href="MediaNotPrepared.html">MediaNotPrepared</a></div><div class="sidebar-section-children"><a href="NoActiveSession.html">NoActiveSession</a></div><div class="sidebar-section-children"><a href="NotAllowed.html">NotAllowed</a></div><div class="sidebar-section-children"><a href="NotReady.html">NotReady</a></div><div class="sidebar-section-children"><a href="Phone.html">Phone</a></div><div class="sidebar-section-children"><a href="Request.html">Request</a></div><div class="sidebar-section-children"><a href="Requestor.html">Requestor</a></div><div class="sidebar-section-children"><a href="Session.html">Session</a></div><div class="sidebar-section-children"><a href="UnableToConnect.html">UnableToConnect</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-events"><div>Events</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#event:callDataInfo">callDataInfo</a></div><div class="sidebar-section-children"><a href="global.html#event:callDurationUpdate">callDurationUpdate</a></div><div class="sidebar-section-children"><a href="global.html#event:callEnded">callEnded</a></div><div class="sidebar-section-children"><a href="global.html#event:callQualityReportUpdate">callQualityReportUpdate</a></div><div class="sidebar-section-children"><a href="global.html#event:connectionStateChange">connectionStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:holdStateChange">holdStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:incomingCall">incomingCall</a></div><div class="sidebar-section-children"><a href="global.html#event:muteStateChange">muteStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:recordingStateChange">recordingStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionCreated">sessionCreated</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionRemoved">sessionRemoved</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionStateChange">sessionStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:whisperModeChange">whisperModeChange</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#CALL_DIRECTION">CALL_DIRECTION</a></div><div class="sidebar-section-children"><a href="global.html#CALL_DISPOSITION">CALL_DISPOSITION</a></div><div class="sidebar-section-children"><a href="global.html#CONNECTION_STATE">CONNECTION_STATE</a></div><div class="sidebar-section-children"><a href="global.html#LOGLVL">LOGLVL</a></div><div class="sidebar-section-children"><a href="global.html#SESSION_STATE">SESSION_STATE</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">phone-client.js</h1></header><article><pre class="prettyprint source lang-js"><code>// 'use strict';
4
- import EventEmitter from "events";
5
- import JsSIP from "jssip";
6
- import { LogHandler, LOGLVL } from "./logger";
7
- import * as Exceptions from "./exceptions";
8
- import * as Tools from "./tools";
9
- import { EventClient } from "./event-client";
10
- import camelcaseKeys from "camelcase-keys";
3
+ <![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="dark"><div class="sidebar-container"><div class="sidebar" id="sidebar"><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="EventClient.html">EventClient</a></div><div class="sidebar-section-children"><a href="EventServiceNotConnected.html">EventServiceNotConnected</a></div><div class="sidebar-section-children"><a href="InvalidMediaDevice.html">InvalidMediaDevice</a></div><div class="sidebar-section-children"><a href="InvalidOptions.html">InvalidOptions</a></div><div class="sidebar-section-children"><a href="InvalidParameter.html">InvalidParameter</a></div><div class="sidebar-section-children"><a href="LogHandler.html">LogHandler</a></div><div class="sidebar-section-children"><a href="MediaNotPrepared.html">MediaNotPrepared</a></div><div class="sidebar-section-children"><a href="NoActiveSession.html">NoActiveSession</a></div><div class="sidebar-section-children"><a href="NotAllowed.html">NotAllowed</a></div><div class="sidebar-section-children"><a href="NotReady.html">NotReady</a></div><div class="sidebar-section-children"><a href="Phone.html">Phone</a></div><div class="sidebar-section-children"><a href="Request.html">Request</a></div><div class="sidebar-section-children"><a href="Requestor.html">Requestor</a></div><div class="sidebar-section-children"><a href="Session.html">Session</a></div><div class="sidebar-section-children"><a href="UnableToConnect.html">UnableToConnect</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-events"><div>Events</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#event:callDataInfo">callDataInfo</a></div><div class="sidebar-section-children"><a href="global.html#event:callDurationUpdate">callDurationUpdate</a></div><div class="sidebar-section-children"><a href="global.html#event:callEnded">callEnded</a></div><div class="sidebar-section-children"><a href="global.html#event:callQualityReportUpdate">callQualityReportUpdate</a></div><div class="sidebar-section-children"><a href="global.html#event:connectionStateChange">connectionStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:holdStateChange">holdStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:incomingCall">incomingCall</a></div><div class="sidebar-section-children"><a href="global.html#event:muteStateChange">muteStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:recordingStateChange">recordingStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionCreated">sessionCreated</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionRemoved">sessionRemoved</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionStateChange">sessionStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:whisperModeChange">whisperModeChange</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#CALL_DIRECTION">CALL_DIRECTION</a></div><div class="sidebar-section-children"><a href="global.html#CALL_DISPOSITION">CALL_DISPOSITION</a></div><div class="sidebar-section-children"><a href="global.html#CONNECTION_STATE">CONNECTION_STATE</a></div><div class="sidebar-section-children"><a href="global.html#LOGLVL">LOGLVL</a></div><div class="sidebar-section-children"><a href="global.html#SESSION_STATE">SESSION_STATE</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">phone-client.js</h1></header><article><pre class="prettyprint source lang-js"><code>// 'use strict';
4
+ import EventEmitter from 'events';
5
+ import JsSIP from 'jssip';
6
+ import { LogHandler, LOGLVL } from './logger';
7
+ import * as Exceptions from './exceptions';
8
+ import * as Tools from './tools';
9
+ import { EventClient } from './event-client';
10
+ import camelcaseKeys from 'camelcase-keys';
11
11
 
12
12
  const options = {
13
- wssServer: "wss://api.telegenta.com/sip/",
14
- eventServer: "wss://api.telegenta.com/es/",
13
+ wssServer: 'wss://api.telegenta.com/sip/',
14
+ eventServer: 'wss://api.telegenta.com/es/',
15
15
  provisionToken: null,
16
16
  authorizationUsername: null,
17
17
  password: null,
@@ -44,9 +44,9 @@ const DTMF_FREQUENCY_TABLE = {
44
44
  8: [1336, 852],
45
45
  9: [1477, 852],
46
46
  c: [1633, 852],
47
- "*": [1209, 941],
47
+ '*': [1209, 941],
48
48
  0: [1336, 941],
49
- "#": [1477, 941],
49
+ '#': [1477, 941],
50
50
  d: [1633, 941],
51
51
  };
52
52
 
@@ -117,11 +117,11 @@ export class Phone extends EventEmitter {
117
117
  this._activeSessions = {};
118
118
 
119
119
  // Create remote audio element
120
- this._remoteAudioElement = document.createElement("AUDIO");
120
+ this._remoteAudioElement = document.createElement('AUDIO');
121
121
  this._remoteAudioElement.autoplay = true;
122
122
 
123
123
  // Tone generator
124
- this._toneAudioElement = document.createElement("AUDIO");
124
+ this._toneAudioElement = document.createElement('AUDIO');
125
125
  this._toneAudioElement.autoplay = true;
126
126
  this._toneTimer = null;
127
127
  this._repeatToneActive = false;
@@ -136,9 +136,9 @@ export class Phone extends EventEmitter {
136
136
 
137
137
  // Handle jssip debug logs
138
138
  if (this.log.level === LOGLVL.DEBUG) {
139
- JsSIP.debug.disable("JsSIP:*");
139
+ JsSIP.debug.disable('JsSIP:*');
140
140
  } else {
141
- JsSIP.debug.disable("JsSIP:*");
141
+ JsSIP.debug.disable('JsSIP:*');
142
142
  }
143
143
  }
144
144
 
@@ -150,7 +150,7 @@ export class Phone extends EventEmitter {
150
150
  *
151
151
  */
152
152
  prepareMedia() {
153
- this.log.info("Get media permission");
153
+ this.log.info('Get media permission');
154
154
  const self = this;
155
155
  const constraints = { audio: true, video: false };
156
156
  return new Promise(function (resolve, reject) {
@@ -158,13 +158,13 @@ export class Phone extends EventEmitter {
158
158
  () => {
159
159
  self._mediaPermission = true;
160
160
  self._mediaPermissionError = false;
161
- self.log.info("Media permission granted");
161
+ self.log.info('Media permission granted');
162
162
  resolve();
163
163
  },
164
164
  (err) => {
165
165
  self._mediaPermission = false;
166
166
  self._mediaPermissionError = true;
167
- self.log.error("Denied media permission: " + err);
167
+ self.log.error('Denied media permission: ' + err);
168
168
  reject(err);
169
169
  },
170
170
  );
@@ -199,7 +199,7 @@ export class Phone extends EventEmitter {
199
199
  this._checkMediaPermission();
200
200
  // Check phone is not running already, if so stop it first
201
201
  if (this._isStarted) {
202
- this.log.warning("Phone already started, stopping first");
202
+ this.log.warning('Phone already started, stopping first');
203
203
  this.stop();
204
204
  }
205
205
 
@@ -214,29 +214,29 @@ export class Phone extends EventEmitter {
214
214
  try {
215
215
  pt = JSON.parse(atob(this._options.provisionToken));
216
216
  } catch (err) {
217
- throw new Exceptions.InvalidOptions("provisionToken", "Invalid token");
217
+ throw new Exceptions.InvalidOptions('provisionToken', 'Invalid token');
218
218
  }
219
219
 
220
- this.log.info("Using provisioning token authorization");
220
+ this.log.info('Using provisioning token authorization');
221
221
  this._options.wssServer = pt.wss_server;
222
222
  this._options.eventServer = pt.event_server;
223
223
  this._options.authorizationUsername = pt.wss_username;
224
224
  this._options.password = pt.wss_password;
225
225
  this._options.callToken = pt.wss_token;
226
226
  } else {
227
- this.log.info("Using manual specified credentials");
227
+ this.log.info('Using manual specified credentials');
228
228
 
229
229
  // Check auth info is provided
230
230
  if (!this._options.authorizationUsername) {
231
- throw new Exceptions.InvalidOptions("authorizationUsername", "Missing username");
231
+ throw new Exceptions.InvalidOptions('authorizationUsername', 'Missing username');
232
232
  }
233
233
 
234
234
  if (!this._options.password) {
235
- throw new Exceptions.InvalidOptions("password", "Missing password");
235
+ throw new Exceptions.InvalidOptions('password', 'Missing password');
236
236
  }
237
237
 
238
238
  if (!this._options.callToken) {
239
- throw new Exceptions.InvalidOptions("callToken", "Missing call token");
239
+ throw new Exceptions.InvalidOptions('callToken', 'Missing call token');
240
240
  }
241
241
  }
242
242
 
@@ -259,18 +259,18 @@ export class Phone extends EventEmitter {
259
259
  if (this._options.useCallDataInfoEvent) {
260
260
  // Subscribe to calldata_available events
261
261
  let eventSpec = {
262
- event_name: "calldata_available",
262
+ event_name: 'calldata_available',
263
263
  call_token: this._options.callToken,
264
264
  };
265
265
 
266
266
  this._eventClient
267
267
  .subscribe(eventSpec, (data) => {
268
268
  try {
269
- this.log.debug("Received remote call data info");
269
+ this.log.debug('Received remote call data info');
270
270
  this.log.debug(data);
271
271
  this._fireCallDataInfoEvent(data);
272
272
  } catch (e) {
273
- this.log.error("Event callback failed: " + e);
273
+ this.log.error('Event callback failed: ' + e);
274
274
  }
275
275
  })
276
276
  .then(
@@ -293,10 +293,10 @@ export class Phone extends EventEmitter {
293
293
  try {
294
294
  wsSocket = new JsSIP.WebSocketInterface(this._options.wssServer);
295
295
  } catch (err) {
296
- throw new Exceptions.UnableToConnect("Unable to connect phone websocket: " + err);
296
+ throw new Exceptions.UnableToConnect('Unable to connect phone websocket: ' + err);
297
297
  }
298
298
 
299
- this.log.info("Starting phone");
299
+ this.log.info('Starting phone');
300
300
  this.log.debug(this._options);
301
301
 
302
302
  this._UA = new JsSIP.UA({
@@ -305,15 +305,15 @@ export class Phone extends EventEmitter {
305
305
  password: this._options.password,
306
306
  register: this._options.register,
307
307
  display_name: this._options.authorizationUsername,
308
- uri: this._options.authorizationUsername + "@telegenta.com",
308
+ uri: this._options.authorizationUsername + '@telegenta.com',
309
309
  session_timers: false,
310
310
  });
311
311
 
312
312
  // Setup remote media handler
313
313
  const self = this;
314
- this._UA.on("newRTCSession", function (data) {
315
- self.log.debug("New RTCSession");
316
- if (data.originator === "remote") {
314
+ this._UA.on('newRTCSession', function (data) {
315
+ self.log.debug('New RTCSession');
316
+ if (data.originator === 'remote') {
317
317
  // Create new session
318
318
  const session = new Session(self);
319
319
 
@@ -326,18 +326,20 @@ export class Phone extends EventEmitter {
326
326
  // Check if we have other sessions and reject call if autoBusyIncoming is true
327
327
  if (self._options.autoBusyIncoming) {
328
328
  if (Object.keys(self._activeSessions).length > 0) {
329
- self.log.info(`Autorejecting incoming call ${session.uuid} because there is already active calls`);
330
- session.reject(486, "Busy");
329
+ self.log.info(
330
+ `Autorejecting incoming call ${session.uuid} because there is already active calls`,
331
+ );
332
+ session.reject(486, 'Busy');
331
333
  return;
332
334
  } else {
333
- self.log.debug("There are no other sessions, adding incoming call");
335
+ self.log.debug('There are no other sessions, adding incoming call');
334
336
  }
335
337
  }
336
338
 
337
339
  self._addSession(session);
338
340
 
339
341
  // Set new session state
340
- session._setSessionState("INCOMING");
342
+ session._setSessionState('INCOMING');
341
343
 
342
344
  // Now fire incomingCall event
343
345
  self._fireIncomingCallEvent(session);
@@ -345,33 +347,33 @@ export class Phone extends EventEmitter {
345
347
  });
346
348
 
347
349
  // Setup connection state event subscriptions
348
- this._UA.on("connecting", function (/* data */) {
349
- self._setConnectionState("CONNECTING");
350
+ this._UA.on('connecting', function (/* data */) {
351
+ self._setConnectionState('CONNECTING');
350
352
  });
351
353
 
352
- this._UA.on("connected", function (/* data */) {
353
- self._setConnectionState("CONNECTED");
354
+ this._UA.on('connected', function (/* data */) {
355
+ self._setConnectionState('CONNECTED');
354
356
  });
355
357
 
356
- this._UA.on("disconnected", function (/* data */) {
357
- self._setConnectionState("DISCONNECTED");
358
+ this._UA.on('disconnected', function (/* data */) {
359
+ self._setConnectionState('DISCONNECTED');
358
360
  });
359
361
 
360
- this._UA.on("registered", function (/* data */) {
361
- self._setConnectionState("REGISTERED");
362
+ this._UA.on('registered', function (/* data */) {
363
+ self._setConnectionState('REGISTERED');
362
364
  });
363
365
 
364
- this._UA.on("unregistered", function (/* data */) {
365
- self._setConnectionState("UNREGISTERED");
366
+ this._UA.on('unregistered', function (/* data */) {
367
+ self._setConnectionState('UNREGISTERED');
366
368
  });
367
369
 
368
- this._UA.on("registrationFailed", function (/* data */) {
369
- self._setConnectionState("REGISTRATION_FAILED");
370
+ this._UA.on('registrationFailed', function (/* data */) {
371
+ self._setConnectionState('REGISTRATION_FAILED');
370
372
  });
371
373
 
372
374
  this._UA.start();
373
375
  this._isStarted = true;
374
- this.log.info("Successfully started phone");
376
+ this.log.info('Successfully started phone');
375
377
  }
376
378
 
377
379
  /**
@@ -381,7 +383,7 @@ export class Phone extends EventEmitter {
381
383
  stop() {
382
384
  // Check phone is started first
383
385
  if (!this._isStarted) {
384
- throw new Exceptions.NotReady("Phone is not started");
386
+ throw new Exceptions.NotReady('Phone is not started');
385
387
  }
386
388
 
387
389
  // Make sure events are not firing anymore, we can't rely on GC.
@@ -393,18 +395,18 @@ export class Phone extends EventEmitter {
393
395
 
394
396
  // Disconnect event client if needed
395
397
  if (!this._eventClient) {
396
- this.log.debug("Event client not running, not stopping");
398
+ this.log.debug('Event client not running, not stopping');
397
399
  return;
398
400
  }
399
401
  try {
400
402
  this._eventClient.disconnect();
401
403
  delete this._eventClient;
402
404
  } catch (e) {
403
- this.log.warning("Unable to disconnect event client");
405
+ this.log.warning('Unable to disconnect event client');
404
406
  }
405
407
 
406
408
  this._isStarted = false;
407
- this.log.info("Phone client successfully stopped");
409
+ this.log.info('Phone client successfully stopped');
408
410
  }
409
411
 
410
412
  /**
@@ -426,12 +428,12 @@ export class Phone extends EventEmitter {
426
428
  call(number, params = {}) {
427
429
  // Check phone is started first
428
430
  if (!this._isStarted) {
429
- throw new Exceptions.NotReady("Phone is not started");
431
+ throw new Exceptions.NotReady('Phone is not started');
430
432
  }
431
433
 
432
434
  // Check we dont have any other connecting calls
433
435
  if (this._checkForConnectingCalls()) {
434
- throw Exceptions.NotAllowed("Unable to make new calls while others are connecting");
436
+ throw new Exceptions.NotAllowed('Unable to make new calls while others are connecting');
435
437
  }
436
438
 
437
439
  // Hold other calls if needed
@@ -451,9 +453,9 @@ export class Phone extends EventEmitter {
451
453
  );
452
454
 
453
455
  // Trim phone number to remove spaces and '()'
454
- number = number.trim().replace(/ |\(|\)/g, "");
456
+ number = number.trim().replace(/ |\(|\)/g, '');
455
457
 
456
- this.log.info("Calling number: " + number);
458
+ this.log.info('Calling number: ' + number);
457
459
 
458
460
  let session = new Session(this);
459
461
  session.newOutboundSession(number, callParams);
@@ -469,12 +471,12 @@ export class Phone extends EventEmitter {
469
471
  * @throws NotAllowed - If there are calls currently connecting
470
472
  */
471
473
  listen(listenKey) {
472
- const s = listenKey.split("@");
474
+ const s = listenKey.split('@');
473
475
  let callUUID = s[0];
474
- let mediaSwitch = "sip:" + s[1];
476
+ let mediaSwitch = 'sip:' + s[1];
475
477
 
476
- this.log.debug("Initiating listen to call with uuid " + callUUID + " on media switch " + mediaSwitch);
477
- return this.call("listen-" + callUUID, {
478
+ this.log.debug('Initiating listen to call with uuid ' + callUUID + ' on media switch ' + mediaSwitch);
479
+ return this.call('listen-' + callUUID, {
478
480
  mediaSwitchURI: mediaSwitch,
479
481
  _isListenCall: true,
480
482
  });
@@ -600,7 +602,7 @@ export class Phone extends EventEmitter {
600
602
 
601
603
  // Begin repeating tones
602
604
  _startRepeatTone(sequences) {
603
- this.log.info("Repeating tone sequence started");
605
+ this.log.info('Repeating tone sequence started');
604
606
  this.log.debug(sequences);
605
607
  this._repeatToneSequence = sequences;
606
608
  this._repeatToneSequencePos = 0;
@@ -630,7 +632,7 @@ export class Phone extends EventEmitter {
630
632
  // End repeating tones
631
633
  _endRepeatTone() {
632
634
  if (this._repeatToneActive) {
633
- this.log.info("Repeating tone stopped");
635
+ this.log.info('Repeating tone stopped');
634
636
  this._repeatToneActive = false;
635
637
  this.stopTone();
636
638
  }
@@ -641,7 +643,7 @@ export class Phone extends EventEmitter {
641
643
  // Create audio context
642
644
  const AudioContext = window.AudioContext || window.webkitAudioContext || false;
643
645
  if (!AudioContext) {
644
- throw new Exceptions.NotAllowed("Audio API not supported by this browser");
646
+ throw new Exceptions.NotAllowed('Audio API not supported by this browser');
645
647
  }
646
648
 
647
649
  const ctx = new AudioContext();
@@ -669,17 +671,17 @@ export class Phone extends EventEmitter {
669
671
  * @throws NotAllowed If there are connection calls
670
672
  */
671
673
  holdAllCalls() {
672
- this.log.info("Holding all active sessions");
674
+ this.log.info('Holding all active sessions');
673
675
  // Check all session can be set on hold
674
676
  if (this._checkForConnectingCalls()) {
675
- throw Exceptions.NotAllowed("A session is currently connecting");
677
+ throw new Exceptions.NotAllowed('A session is currently connecting');
676
678
  }
677
679
 
678
680
  // Iterate through all active calls and hold them
679
681
  for (let key in this._activeSessions) {
680
682
  if (this._activeSessions.hasOwnProperty(key)) {
681
683
  let session = this._activeSessions[key];
682
- if (session.state === "ACTIVE") {
684
+ if (session.state === 'ACTIVE') {
683
685
  session.hold();
684
686
  }
685
687
  }
@@ -708,9 +710,9 @@ export class Phone extends EventEmitter {
708
710
 
709
711
  // Fire event
710
712
  try {
711
- this.emit("sessionCreated", { session: session });
713
+ this.emit('sessionCreated', { session: session });
712
714
  } catch (e) {
713
- this.log.error("Exception in sessionCreated event: " + e);
715
+ this.log.error('Exception in sessionCreated event: ' + e);
714
716
  }
715
717
  }
716
718
 
@@ -726,9 +728,9 @@ export class Phone extends EventEmitter {
726
728
 
727
729
  // Fire event
728
730
  try {
729
- this.emit("sessionRemoved", { session: session });
731
+ this.emit('sessionRemoved', { session: session });
730
732
  } catch (e) {
731
- this.log.error("Exception in sessionRemoved event: " + e);
733
+ this.log.error('Exception in sessionRemoved event: ' + e);
732
734
  }
733
735
 
734
736
  delete this._activeSessions[session.__containerId];
@@ -753,7 +755,12 @@ export class Phone extends EventEmitter {
753
755
  for (let key in this._activeSessions) {
754
756
  if (this._activeSessions.hasOwnProperty(key)) {
755
757
  let session = this._activeSessions[key];
756
- if (session.state === "INITIALIZING" || session.state === "CALLING" || session.state === "PROGRESS" || session.state === "INCOMING") {
758
+ if (
759
+ session.state === 'INITIALIZING' ||
760
+ session.state === 'CALLING' ||
761
+ session.state === 'PROGRESS' ||
762
+ session.state === 'INCOMING'
763
+ ) {
757
764
  return true;
758
765
  }
759
766
  }
@@ -778,12 +785,12 @@ export class Phone extends EventEmitter {
778
785
  * @param {CONNECTION_STATE} state - The current connection state
779
786
  */
780
787
 
781
- this.log.info("Connection state: " + state);
788
+ this.log.info('Connection state: ' + state);
782
789
  this._connectionState = state;
783
790
  try {
784
- this.emit("connectionStateChange", { state: state });
791
+ this.emit('connectionStateChange', { state: state });
785
792
  } catch (e) {
786
- this.log.error("Exception in connectionStateChange event: " + e);
793
+ this.log.error('Exception in connectionStateChange event: ' + e);
787
794
  }
788
795
  }
789
796
 
@@ -794,9 +801,9 @@ export class Phone extends EventEmitter {
794
801
  */
795
802
  _fireIncomingCallEvent(session) {
796
803
  try {
797
- this.emit("incomingCall", session);
804
+ this.emit('incomingCall', session);
798
805
  } catch (e) {
799
- this.log.error("Exception in incomingCall event: " + e);
806
+ this.log.error('Exception in incomingCall event: ' + e);
800
807
  }
801
808
  }
802
809
 
@@ -849,12 +856,12 @@ export class Phone extends EventEmitter {
849
856
 
850
857
  // Add some extra convenience fields
851
858
  e.durationStr = Tools.createDurationString(e.duration);
852
- e.answerDurationStr = e.answerDuration ? Tools.createDurationString(e.answerDuration) : "";
853
- e.activeDurationStr = e.activeDuration ? Tools.createDurationString(e.activeDuration) : "";
859
+ e.answerDurationStr = e.answerDuration ? Tools.createDurationString(e.answerDuration) : '';
860
+ e.activeDurationStr = e.activeDuration ? Tools.createDurationString(e.activeDuration) : '';
854
861
  try {
855
- this.emit("callDataInfo", e);
862
+ this.emit('callDataInfo', e);
856
863
  } catch (e) {
857
- this.log.error("Exception in callDataInfo event: " + e);
864
+ this.log.error('Exception in callDataInfo event: ' + e);
858
865
  }
859
866
  }
860
867
 
@@ -935,33 +942,37 @@ export class Session extends EventEmitter {
935
942
  let options = {
936
943
  mediaConstraints: { audio: true, video: false },
937
944
  pcConfig: {
938
- iceServers: [{ urls: ["stun:stun.l.google.com:19302"] }],
945
+ iceServers: [{ urls: ['stun:stun.l.google.com:19302'] }],
939
946
  },
940
- extraHeaders: ["X-Call-token: " + this._phone.options.callToken, "X-P-UUID: " + this._callUUID, "X-Max-cost: " + callParams.maximumCallCost],
947
+ extraHeaders: [
948
+ 'X-Call-token: ' + this._phone.options.callToken,
949
+ 'X-P-UUID: ' + this._callUUID,
950
+ 'X-Max-cost: ' + callParams.maximumCallCost,
951
+ ],
941
952
  };
942
953
 
943
954
  // Append explicit caller id if needed
944
955
  if (callParams.explicitCallerId) {
945
- options.extraHeaders.push("X-CID-Number-Id: " + callParams.explicitCallerId);
956
+ options.extraHeaders.push('X-CID-Number-Id: ' + callParams.explicitCallerId);
946
957
  }
947
958
 
948
959
  // Append explicit short cid if needed
949
960
  if (callParams.explicitShortCallerId) {
950
- options.extraHeaders.push("X-Short-CID-Id: " + callParams.explicitShortCallerId);
961
+ options.extraHeaders.push('X-Short-CID-Id: ' + callParams.explicitShortCallerId);
951
962
  }
952
963
 
953
964
  // Append meta info
954
965
  if (callParams.metaInfo) {
955
- options.extraHeaders.push("X-Meta-Info: " + encodeURI(callParams.metaInfo.toString().substr(0, 255)));
966
+ options.extraHeaders.push('X-Meta-Info: ' + encodeURI(callParams.metaInfo.toString().substr(0, 255)));
956
967
  }
957
968
 
958
969
  // Enable recording?
959
970
  if (callParams.record) {
960
971
  if (isNaN(callParams.record)) {
961
- throw new Exceptions.InvalidParameter("Record parameter must be a number");
972
+ throw new Exceptions.InvalidParameter('Record parameter must be a number');
962
973
  }
963
974
  this.log.debug(`Recording enabled and kept for ${callParams.record} days`);
964
- options.extraHeaders.push("X-Record: " + callParams.record);
975
+ options.extraHeaders.push('X-Record: ' + callParams.record);
965
976
  this._isRecording = true;
966
977
  } else {
967
978
  this._isRecording = false;
@@ -972,8 +983,8 @@ export class Session extends EventEmitter {
972
983
 
973
984
  // Manually specified media switch
974
985
  if (callParams.mediaSwitchURI) {
975
- this.log.debug("Requesting specific media switch " + callParams.mediaSwitchURI);
976
- options.extraHeaders.push("X-RMS: " + callParams.mediaSwitchURI);
986
+ this.log.debug('Requesting specific media switch ' + callParams.mediaSwitchURI);
987
+ options.extraHeaders.push('X-RMS: ' + callParams.mediaSwitchURI);
977
988
  } else {
978
989
  // Request specific media switch to group calls on same server
979
990
  const otherSessions = this.getOtherSessions();
@@ -981,24 +992,24 @@ export class Session extends EventEmitter {
981
992
  if (otherSessions.length > 0) {
982
993
  if (otherSessions[0]._mediaSwitch) {
983
994
  // There are existing active calls, append first media switch address found and request call grouping to this
984
- this.log.debug("Requesting call grouping on media switch " + otherSessions[0]._mediaSwitch);
985
- options.extraHeaders.push("X-RMS: sip:" + otherSessions[0]._mediaSwitch);
995
+ this.log.debug('Requesting call grouping on media switch ' + otherSessions[0]._mediaSwitch);
996
+ options.extraHeaders.push('X-RMS: sip:' + otherSessions[0]._mediaSwitch);
986
997
  } else {
987
- this.log.warning("Other sessions exist but media switch address is invalid");
998
+ this.log.warning('Other sessions exist but media switch address is invalid');
988
999
  }
989
1000
  } else {
990
- this.log.debug("No other active calls, no media switch grouping requested");
1001
+ this.log.debug('No other active calls, no media switch grouping requested');
991
1002
  }
992
1003
  }
993
1004
 
994
1005
  // Prepare invite uri
995
- const uri = "sip:" + number + "@telegenta.com";
1006
+ const uri = 'sip:' + number + '@telegenta.com';
996
1007
 
997
1008
  // Not start call and create sip session
998
1009
  try {
999
1010
  this._initWebRTCSession(this._phone._UA.call(uri, options));
1000
1011
  } catch (error) {
1001
- this.log.error("Error starting call:", error);
1012
+ this.log.error('Error starting call:', error);
1002
1013
  return null;
1003
1014
  }
1004
1015
 
@@ -1009,16 +1020,16 @@ export class Session extends EventEmitter {
1009
1020
 
1010
1021
  // Create new inbound session
1011
1022
  newInboundSession(newSessionRequest) {
1012
- this._callUUID = newSessionRequest.request.getHeader("X-P-UUID", 0);
1013
- this._destinationNumber = newSessionRequest.request.getHeader("X-DID", 0);
1014
- this._localNumberName = unescape(newSessionRequest.request.getHeader("X-DID-NAME", 0));
1023
+ this._callUUID = newSessionRequest.request.getHeader('X-P-UUID', 0);
1024
+ this._destinationNumber = newSessionRequest.request.getHeader('X-DID', 0);
1025
+ this._localNumberName = unescape(newSessionRequest.request.getHeader('X-DID-NAME', 0));
1015
1026
  this._originName = newSessionRequest.request.from.display_name;
1016
1027
  this._originatingNumber = newSessionRequest.request.from.uri.user;
1017
1028
  this.log.info(`Incoming call from ${this._originatingNumber} [${this._callUUID}]`);
1018
1029
  this.log.debug(newSessionRequest);
1019
1030
 
1020
1031
  // Get media switch info
1021
- this._mediaSwitch = newSessionRequest.request.getHeader("X-MS");
1032
+ this._mediaSwitch = newSessionRequest.request.getHeader('X-MS');
1022
1033
  this.log.debug(`Media switch handling call: ${this._mediaSwitch}`);
1023
1034
 
1024
1035
  this._initWebRTCSession(newSessionRequest.session);
@@ -1052,10 +1063,10 @@ export class Session extends EventEmitter {
1052
1063
  const self = this;
1053
1064
 
1054
1065
  // ICE CANDIDATES
1055
- this._webRTCSession.on("icecandidate", function (event) {
1066
+ this._webRTCSession.on('icecandidate', function (event) {
1056
1067
  const c = event.candidate;
1057
1068
  self.log.debug(`Got ICE candidate: ${c.candidate}`);
1058
- if (c.type === "srflx" &amp;&amp; c.relatedAddress !== null &amp;&amp; c.relatedPort !== null) {
1069
+ if (c.type === 'srflx' &amp;&amp; c.relatedAddress !== null &amp;&amp; c.relatedPort !== null) {
1059
1070
  self.log.info(`Accepting ICE candidate: ${c.candidate}`);
1060
1071
 
1061
1072
  // Clear timer first
@@ -1078,24 +1089,24 @@ export class Session extends EventEmitter {
1078
1089
  }
1079
1090
  });
1080
1091
 
1081
- this._webRTCSession.on("connecting", function (/* data */) {
1092
+ this._webRTCSession.on('connecting', function (/* data */) {
1082
1093
  self._startDurationUpdateTimer();
1083
1094
  self._startRTCPStatsUpdateTimer();
1084
- self._setSessionState("INITIALIZING");
1095
+ self._setSessionState('INITIALIZING');
1085
1096
  });
1086
1097
 
1087
- this._webRTCSession.on("sending", function (/* data */) {
1098
+ this._webRTCSession.on('sending', function (/* data */) {
1088
1099
  // Play call initialized tone if needed
1089
1100
  if (self._phone.options.playCallInitializedTone) {
1090
1101
  self._phone._startRepeatTone(ST_CALLINIT);
1091
1102
  }
1092
1103
 
1093
- self._setSessionState("CALLING");
1104
+ self._setSessionState('CALLING');
1094
1105
  });
1095
1106
 
1096
- this._webRTCSession.on("progress", function (data) {
1097
- if (data.originator === "remote") {
1098
- self._setSessionState("PROGRESS", { code: data.response.status_code });
1107
+ this._webRTCSession.on('progress', function (data) {
1108
+ if (data.originator === 'remote') {
1109
+ self._setSessionState('PROGRESS', { code: data.response.status_code });
1099
1110
  self._phone._endRepeatTone();
1100
1111
 
1101
1112
  // Ringback handling on 180 RINGING
@@ -1110,14 +1121,14 @@ export class Session extends EventEmitter {
1110
1121
  try {
1111
1122
  self.hangup();
1112
1123
  } catch (e) {
1113
- self.log.info("No active session, ignoring answer call timeout");
1124
+ self.log.info('No active session, ignoring answer call timeout');
1114
1125
  }
1115
1126
  }, self._answerCallTimeout * 1000);
1116
1127
  }
1117
1128
  }
1118
1129
  });
1119
1130
 
1120
- this._webRTCSession.on("accepted", function (data) {
1131
+ this._webRTCSession.on('accepted', function (data) {
1121
1132
  // Always end ringsback
1122
1133
  self._phone._endRepeatTone();
1123
1134
 
@@ -1130,27 +1141,27 @@ export class Session extends EventEmitter {
1130
1141
  }
1131
1142
 
1132
1143
  // Get initial recording state
1133
- if (data.originator === "remote") {
1134
- const recState = data.response.getHeader("X-Recording");
1135
- if (recState === "true") {
1136
- self.log.debug("Call is being prerecorded");
1144
+ if (data.originator === 'remote') {
1145
+ const recState = data.response.getHeader('X-Recording');
1146
+ if (recState === 'true') {
1147
+ self.log.debug('Call is being prerecorded');
1137
1148
  // self._isRecording = true;
1138
1149
  // self.emit('recordingStateChange', {state: true, error: null});
1139
1150
  } else {
1140
- self.log.debug("No call recording started yet");
1151
+ self.log.debug('No call recording started yet');
1141
1152
  }
1142
1153
 
1143
1154
  // Get media switch info
1144
- self._mediaSwitch = data.response.getHeader("X-MS");
1155
+ self._mediaSwitch = data.response.getHeader('X-MS');
1145
1156
  self.log.debug(`Media switch handling call: ${self._mediaSwitch}`);
1146
1157
  }
1147
1158
  });
1148
1159
 
1149
- this._webRTCSession.on("confirmed", function (/* data */) {
1150
- self._setSessionState("ACTIVE");
1160
+ this._webRTCSession.on('confirmed', function (/* data */) {
1161
+ self._setSessionState('ACTIVE');
1151
1162
  });
1152
1163
 
1153
- this._webRTCSession.on("ended", function (/* data */) {
1164
+ this._webRTCSession.on('ended', function (/* data */) {
1154
1165
  // End any ringsbacks if needed
1155
1166
  self._phone._endRepeatTone();
1156
1167
 
@@ -1161,10 +1172,10 @@ export class Session extends EventEmitter {
1161
1172
  clearTimeout(self._answerCallTimer);
1162
1173
  }
1163
1174
 
1164
- self._setSessionState("TERMINATED");
1175
+ self._setSessionState('TERMINATED');
1165
1176
  });
1166
1177
 
1167
- this._webRTCSession.on("failed", function (data) {
1178
+ this._webRTCSession.on('failed', function (data) {
1168
1179
  // End any ringsbacks if needed
1169
1180
  self._phone._endRepeatTone();
1170
1181
 
@@ -1182,54 +1193,54 @@ export class Session extends EventEmitter {
1182
1193
  if (data.message) {
1183
1194
  m = `${data.message.status_code} ${data.message.reason_phrase}`;
1184
1195
  } else {
1185
- m = "";
1196
+ m = '';
1186
1197
  }
1187
1198
 
1188
- self._setSessionState("FAILED", { cause: data.cause, message: m });
1199
+ self._setSessionState('FAILED', { cause: data.cause, message: m });
1189
1200
  });
1190
1201
 
1191
- this._webRTCSession.on("dtmf", function (data) {
1192
- self.log.debug("Session DTMF", data);
1202
+ this._webRTCSession.on('dtmf', function (data) {
1203
+ self.log.debug('Session DTMF', data);
1193
1204
  });
1194
1205
 
1195
- this._webRTCSession.on("newInfo", function (data) {
1196
- self.log.debug("New session info", data);
1206
+ this._webRTCSession.on('newInfo', function (data) {
1207
+ self.log.debug('New session info', data);
1197
1208
  });
1198
1209
 
1199
- this._webRTCSession.on("hold", function (/* data */) {
1210
+ this._webRTCSession.on('hold', function (/* data */) {
1200
1211
  self._isOnHold = true;
1201
1212
  self._fireHoldStateEvent();
1202
- self._setSessionState("ON_HOLD");
1213
+ self._setSessionState('ON_HOLD');
1203
1214
  });
1204
1215
 
1205
- this._webRTCSession.on("unhold", function (/* data */) {
1216
+ this._webRTCSession.on('unhold', function (/* data */) {
1206
1217
  self._isOnHold = false;
1207
1218
  self._fireHoldStateEvent();
1208
- self._setSessionState("ACTIVE");
1219
+ self._setSessionState('ACTIVE');
1209
1220
  });
1210
1221
 
1211
- this._webRTCSession.on("muted", function (data) {
1212
- self.log.debug("Microphone muted", data);
1222
+ this._webRTCSession.on('muted', function (data) {
1223
+ self.log.debug('Microphone muted', data);
1213
1224
  self._isMuted = true;
1214
1225
  self._fireMuteStateEvent();
1215
1226
  });
1216
1227
 
1217
- this._webRTCSession.on("unmuted", function (data) {
1218
- self.log.debug("Microphone unmuted", data);
1228
+ this._webRTCSession.on('unmuted', function (data) {
1229
+ self.log.debug('Microphone unmuted', data);
1219
1230
  self._isMuted = false;
1220
1231
  self._fireMuteStateEvent();
1221
1232
  });
1222
1233
 
1223
- this._webRTCSession.on("reinvite", function (data) {
1224
- self.log.debug("Session reinvite", data);
1234
+ this._webRTCSession.on('reinvite', function (data) {
1235
+ self.log.debug('Session reinvite', data);
1225
1236
  });
1226
1237
 
1227
- this._webRTCSession.on("update", function (data) {
1228
- self.log.debug("Session update", data);
1238
+ this._webRTCSession.on('update', function (data) {
1239
+ self.log.debug('Session update', data);
1229
1240
  });
1230
1241
 
1231
- this._webRTCSession.on("getusermediafailed", function (data) {
1232
- self.log.error("Getusermedia failed", data);
1242
+ this._webRTCSession.on('getusermediafailed', function (data) {
1243
+ self.log.error('Getusermedia failed', data);
1233
1244
  });
1234
1245
 
1235
1246
  // If connection connect audio stream
@@ -1238,7 +1249,7 @@ export class Session extends EventEmitter {
1238
1249
  }
1239
1250
 
1240
1251
  // DEBUG STUFF
1241
- this.log.debug("WebRTCSession object:");
1252
+ this.log.debug('WebRTCSession object:');
1242
1253
  this.log.debug(this);
1243
1254
  }
1244
1255
 
@@ -1249,13 +1260,13 @@ export class Session extends EventEmitter {
1249
1260
  */
1250
1261
  hangup(disposition = null) {
1251
1262
  if (!disposition) {
1252
- this.log.info("Hanging up call");
1263
+ this.log.info('Hanging up call');
1253
1264
  this._webRTCSession.terminate();
1254
1265
  } else {
1255
1266
  this.log.info(`Hanging up call with disposition ${disposition}`);
1256
1267
  this._manualDisposition = disposition;
1257
1268
  this._webRTCSession.terminate({
1258
- extraHeaders: ["X-HDISP: " + disposition],
1269
+ extraHeaders: ['X-HDISP: ' + disposition],
1259
1270
  });
1260
1271
  }
1261
1272
  }
@@ -1268,14 +1279,14 @@ export class Session extends EventEmitter {
1268
1279
  let options = {
1269
1280
  mediaConstraints: { audio: true, video: false },
1270
1281
  pcConfig: {
1271
- iceServers: [{ urls: ["stun:stun.l.google.com:19302"] }],
1282
+ iceServers: [{ urls: ['stun:stun.l.google.com:19302'] }],
1272
1283
  },
1273
- extraHeaders: ["X-Call-token: " + this._phone.options.callToken],
1284
+ extraHeaders: ['X-Call-token: ' + this._phone.options.callToken],
1274
1285
  };
1275
1286
 
1276
1287
  // Append meta info if needed
1277
1288
  if (metaInfo) {
1278
- options.extraHeaders.push("X-Meta-Info: " + encodeURI(metaInfo.toString().substr(0, 255)));
1289
+ options.extraHeaders.push('X-Meta-Info: ' + encodeURI(metaInfo.toString().substr(0, 255)));
1279
1290
  }
1280
1291
 
1281
1292
  this._webRTCSession.answer(options);
@@ -1289,8 +1300,8 @@ export class Session extends EventEmitter {
1289
1300
  * @param statusCode - SIP Status code
1290
1301
  * @param reasonPhrase - Reason phrase
1291
1302
  */
1292
- reject(statusCode = 603, reasonPhrase = "Rejected call") {
1293
- this.log.info("Rejecting call");
1303
+ reject(statusCode = 603, reasonPhrase = 'Rejected call') {
1304
+ this.log.info('Rejecting call');
1294
1305
  this._webRTCSession.terminate({
1295
1306
  status_code: statusCode,
1296
1307
  reason_phrase: reasonPhrase,
@@ -1331,7 +1342,7 @@ export class Session extends EventEmitter {
1331
1342
 
1332
1343
  // Set destination number
1333
1344
  set destinationNumber(number) {
1334
- this.log.debug("Setting destination number to: " + number);
1345
+ this.log.debug('Setting destination number to: ' + number);
1335
1346
  this._destinationNumber = number;
1336
1347
  }
1337
1348
 
@@ -1349,17 +1360,17 @@ export class Session extends EventEmitter {
1349
1360
  */
1350
1361
  get direction() {
1351
1362
  if (this._isListenCall) {
1352
- this.log.debug("Call direction is LISTEN");
1353
- return "LISTEN";
1354
- } else if (this._webRTCSession.direction === "incoming") {
1355
- this.log.debug("Call direction is INBOUND");
1356
- return "INBOUND";
1357
- } else if (this._webRTCSession.direction === "outgoing") {
1358
- this.log.debug("Call direction is OUTBOUND");
1359
- return "OUTBOUND";
1363
+ this.log.debug('Call direction is LISTEN');
1364
+ return 'LISTEN';
1365
+ } else if (this._webRTCSession.direction === 'incoming') {
1366
+ this.log.debug('Call direction is INBOUND');
1367
+ return 'INBOUND';
1368
+ } else if (this._webRTCSession.direction === 'outgoing') {
1369
+ this.log.debug('Call direction is OUTBOUND');
1370
+ return 'OUTBOUND';
1360
1371
  } else {
1361
- this.log.error("Unknown call direction: " + this._webRTCSession.direction);
1362
- return "UNKNOWN";
1372
+ this.log.error('Unknown call direction: ' + this._webRTCSession.direction);
1373
+ return 'UNKNOWN';
1363
1374
  }
1364
1375
  }
1365
1376
 
@@ -1369,33 +1380,33 @@ export class Session extends EventEmitter {
1369
1380
  */
1370
1381
  startRecording() {
1371
1382
  const opt = {
1372
- extraHeaders: ["Record: on"],
1383
+ extraHeaders: ['Record: on'],
1373
1384
  };
1374
1385
 
1375
- this.log.debug("Request start recording");
1386
+ this.log.debug('Request start recording');
1376
1387
 
1377
1388
  const self = this;
1378
- this._webRTCSession.once("newInfo", (data) => {
1379
- if (data.originator === "local") {
1380
- data.info.on("succeeded", function (/* data */) {
1381
- self.log.info("Recording started successfully");
1389
+ this._webRTCSession.once('newInfo', (data) => {
1390
+ if (data.originator === 'local') {
1391
+ data.info.on('succeeded', function (/* data */) {
1392
+ self.log.info('Recording started successfully');
1382
1393
  self._isRecording = true;
1383
1394
  try {
1384
- self.emit("recordingStateChange", { state: true, error: null });
1395
+ self.emit('recordingStateChange', { state: true, error: null });
1385
1396
  } catch (e) {
1386
- self.log.error("Exception in recordingStateChange event: " + e);
1397
+ self.log.error('Exception in recordingStateChange event: ' + e);
1387
1398
  }
1388
1399
  });
1389
1400
 
1390
- data.info.on("failed", function (data) {
1401
+ data.info.on('failed', function (data) {
1391
1402
  self._recordingError = data.response.reason_phrase;
1392
- self.log.error("Recording start failed: " + self._recordingError);
1403
+ self.log.error('Recording start failed: ' + self._recordingError);
1393
1404
  self._fireRecordingStateEvent();
1394
1405
  });
1395
1406
  }
1396
1407
  });
1397
1408
 
1398
- this._webRTCSession.sendInfo("application/info", null, opt);
1409
+ this._webRTCSession.sendInfo('application/info', null, opt);
1399
1410
  }
1400
1411
 
1401
1412
  /**
@@ -1403,35 +1414,35 @@ export class Session extends EventEmitter {
1403
1414
  */
1404
1415
  stopRecording() {
1405
1416
  const opt = {
1406
- extraHeaders: ["Record: off"],
1417
+ extraHeaders: ['Record: off'],
1407
1418
  };
1408
1419
 
1409
- this.log.debug("Request stop recording");
1420
+ this.log.debug('Request stop recording');
1410
1421
 
1411
1422
  const self = this;
1412
1423
 
1413
- this._webRTCSession.once("newInfo", (data) => {
1414
- data.info.on("succeeded", function (/* data */) {
1415
- self.log.info("Recording stopped successfully");
1424
+ this._webRTCSession.once('newInfo', (data) => {
1425
+ data.info.on('succeeded', function (/* data */) {
1426
+ self.log.info('Recording stopped successfully');
1416
1427
  self._isRecording = false;
1417
1428
  try {
1418
- self.emit("recordingStateChange", { state: false, error: null });
1429
+ self.emit('recordingStateChange', { state: false, error: null });
1419
1430
  } catch (e) {
1420
- self.log.error("Exception in recordingStateChange event: " + e);
1431
+ self.log.error('Exception in recordingStateChange event: ' + e);
1421
1432
  }
1422
1433
  });
1423
1434
 
1424
- data.info.on("failed", function (data) {
1425
- self.log.error("Recording stopped failed: " + data.response.reason_phrase);
1435
+ data.info.on('failed', function (data) {
1436
+ self.log.error('Recording stopped failed: ' + data.response.reason_phrase);
1426
1437
  try {
1427
- self.emit("recordingStateChange", { state: self._isRecording, error: data.response.reason_phrase });
1438
+ self.emit('recordingStateChange', { state: self._isRecording, error: data.response.reason_phrase });
1428
1439
  } catch (e) {
1429
- self.log.error("Exception in recordingStateChange event: " + e);
1440
+ self.log.error('Exception in recordingStateChange event: ' + e);
1430
1441
  }
1431
1442
  });
1432
1443
  });
1433
1444
 
1434
- this._webRTCSession.sendInfo("application/info", null, opt);
1445
+ this._webRTCSession.sendInfo('application/info', null, opt);
1435
1446
  }
1436
1447
 
1437
1448
  /**
@@ -1460,7 +1471,7 @@ export class Session extends EventEmitter {
1460
1471
  * Mute microphone
1461
1472
  */
1462
1473
  muteMic() {
1463
- this.log.info("Mute microphone");
1474
+ this.log.info('Mute microphone');
1464
1475
  this._webRTCSession.mute();
1465
1476
  }
1466
1477
 
@@ -1468,7 +1479,7 @@ export class Session extends EventEmitter {
1468
1479
  * Unmute microphone
1469
1480
  */
1470
1481
  unmuteMic() {
1471
- this.log.info("Unmute microphone");
1482
+ this.log.info('Unmute microphone');
1472
1483
  this._webRTCSession.unmute();
1473
1484
  }
1474
1485
 
@@ -1496,7 +1507,7 @@ export class Session extends EventEmitter {
1496
1507
  * Hold call
1497
1508
  */
1498
1509
  hold() {
1499
- this.log.info("Hold call");
1510
+ this.log.info('Hold call');
1500
1511
  this._webRTCSession.hold();
1501
1512
  }
1502
1513
 
@@ -1504,7 +1515,7 @@ export class Session extends EventEmitter {
1504
1515
  * Unhold call
1505
1516
  */
1506
1517
  unhold() {
1507
- this.log.info("Uncall call");
1518
+ this.log.info('Uncall call');
1508
1519
  this._phone.holdAllCalls();
1509
1520
  this._webRTCSession.unhold();
1510
1521
  }
@@ -1537,10 +1548,10 @@ export class Session extends EventEmitter {
1537
1548
  sendDTMF(code, playLocal = true) {
1538
1549
  // Check for correct DTMF and get frequencies
1539
1550
  if (!(code in DTMF_FREQUENCY_TABLE)) {
1540
- throw new Exceptions.InvalidParameter("Invalid DTMF code");
1551
+ throw new Exceptions.InvalidParameter('Invalid DTMF code');
1541
1552
  }
1542
1553
 
1543
- this.log.info("Sending DTMF: " + code);
1554
+ this.log.info('Sending DTMF: ' + code);
1544
1555
  this._webRTCSession.sendDTMF(code);
1545
1556
 
1546
1557
  if (playLocal) {
@@ -1548,15 +1559,15 @@ export class Session extends EventEmitter {
1548
1559
 
1549
1560
  // First mute microphone before playing DTMF
1550
1561
  if (this._isMuted) {
1551
- this.log.debug("Mic already muted, just sending DTMF");
1562
+ this.log.debug('Mic already muted, just sending DTMF');
1552
1563
  this._phone.playTone(500, f[0], f[1]);
1553
1564
  } else {
1554
- this.log.debug("Mute mic while sending DTMF");
1565
+ this.log.debug('Mute mic while sending DTMF');
1555
1566
  this._webRTCSession.mute();
1556
1567
 
1557
1568
  const self = this;
1558
1569
  this._phone.playTone(500, f[0], f[1], function () {
1559
- self.log.debug("Unmute mic after DTMF");
1570
+ self.log.debug('Unmute mic after DTMF');
1560
1571
  self._webRTCSession.unmute();
1561
1572
  });
1562
1573
  }
@@ -1572,20 +1583,22 @@ export class Session extends EventEmitter {
1572
1583
  this.log.info(`Transferring ${this.uuid} => ${dstSession.uuid}`);
1573
1584
 
1574
1585
  // Create ReferSubscriber event class
1575
- const referSubscriber = this._webRTCSession.refer(this._webRTCSession._request.ruri, { replaces: dstSession._webRTCSession });
1586
+ const referSubscriber = this._webRTCSession.refer(this._webRTCSession._request.ruri, {
1587
+ replaces: dstSession._webRTCSession,
1588
+ });
1576
1589
 
1577
1590
  const self = this;
1578
1591
 
1579
1592
  // Setup some logging
1580
- referSubscriber.on("requestSucceeded", function () {
1581
- self.log.info("Transfer completed successfully");
1593
+ referSubscriber.on('requestSucceeded', function () {
1594
+ self.log.info('Transfer completed successfully');
1582
1595
  });
1583
1596
 
1584
- referSubscriber.on("requestFailed", function (cause) {
1597
+ referSubscriber.on('requestFailed', function (cause) {
1585
1598
  self.log.error(`Transfer rejected: ${cause}`);
1586
1599
  });
1587
1600
 
1588
- referSubscriber.on("failed", function (cause) {
1601
+ referSubscriber.on('failed', function (cause) {
1589
1602
  self.log.error(`Transfer failed: ${cause}`);
1590
1603
  });
1591
1604
  }
@@ -1603,14 +1616,14 @@ export class Session extends EventEmitter {
1603
1616
  playback(media_file_id, hangup_after = false) {
1604
1617
  // Check event service is enabled first
1605
1618
  if (!this._phone._options.connectEventService) {
1606
- throw new Exceptions.NotAllowed("Event service not enabled");
1619
+ throw new Exceptions.NotAllowed('Event service not enabled');
1607
1620
  }
1608
1621
 
1609
1622
  this.log.info(`Playback media file ${media_file_id} hangup after ${hangup_after}`);
1610
1623
 
1611
- const p = this._phone._eventClient.fireEvent("call_command", {
1624
+ const p = this._phone._eventClient.fireEvent('call_command', {
1612
1625
  call_uuid: this.uuid,
1613
- call_command: "playback",
1626
+ call_command: 'playback',
1614
1627
  media_file_id: media_file_id,
1615
1628
  hangup_after: hangup_after,
1616
1629
  });
@@ -1626,7 +1639,7 @@ export class Session extends EventEmitter {
1626
1639
  // When playback starts set state to playback
1627
1640
  p.then(() => {
1628
1641
  // Set session state
1629
- this._setSessionState("PLAYBACK");
1642
+ this._setSessionState('PLAYBACK');
1630
1643
  });
1631
1644
  }
1632
1645
 
@@ -1642,12 +1655,12 @@ export class Session extends EventEmitter {
1642
1655
  * @throws InvalidOptions - If invalid mode given
1643
1656
  */
1644
1657
  setWhisperMode(mode = 0) {
1645
- if (!this.direction === "LISTEN") {
1646
- throw new Exceptions.NotAllowed("Call is not correct type (listen)");
1658
+ if (!this.direction === 'LISTEN') {
1659
+ throw new Exceptions.NotAllowed('Call is not correct type (listen)');
1647
1660
  }
1648
1661
 
1649
1662
  if (mode &lt; 0 || mode > 2) {
1650
- throw new Exceptions.InvalidOptions("Invalid mode");
1663
+ throw new Exceptions.InvalidOptions('Invalid mode');
1651
1664
  }
1652
1665
 
1653
1666
  let t_dtmf_mode;
@@ -1705,13 +1718,13 @@ export class Session extends EventEmitter {
1705
1718
  duration: Date.now() - self._callBeginTime,
1706
1719
  durationStr: Tools.createDurationString(Date.now() - self._callBeginTime),
1707
1720
  activeDuration: activeDuration,
1708
- activeDurationStr: activeDuration ? Tools.createDurationString(activeDuration) : "",
1721
+ activeDurationStr: activeDuration ? Tools.createDurationString(activeDuration) : '',
1709
1722
  };
1710
1723
 
1711
1724
  try {
1712
- self.emit("callDurationUpdate", e);
1725
+ self.emit('callDurationUpdate', e);
1713
1726
  } catch (e) {
1714
- self.log.error("Exception in call duration update event: " + e);
1727
+ self.log.error('Exception in call duration update event: ' + e);
1715
1728
  }
1716
1729
  }, 1000);
1717
1730
  }
@@ -1775,40 +1788,46 @@ export class Session extends EventEmitter {
1775
1788
  for (let report of data.values()) {
1776
1789
  // this.log.debug(report);
1777
1790
  switch (report.type) {
1778
- case "outbound-rtp":
1791
+ case 'outbound-rtp':
1779
1792
  // this.log.debug('Got: outbound-rtp');
1780
1793
  // this.log.debug(report);
1781
1794
  // Packets
1782
1795
  totalReport.outboundPacketsSent = report.packetsSent;
1783
- deltaReport.outboundPacketsSent = report.packetsSent - this._currentReport.outboundPacketsSent;
1796
+ deltaReport.outboundPacketsSent =
1797
+ report.packetsSent - this._currentReport.outboundPacketsSent;
1784
1798
  // Bytes
1785
1799
  totalReport.outboundBytesSent = report.bytesSent;
1786
- deltaReport.outboundBytesSent = report.bytesSent - this._currentReport.outboundBytesSent;
1800
+ deltaReport.outboundBytesSent =
1801
+ report.bytesSent - this._currentReport.outboundBytesSent;
1787
1802
  break;
1788
1803
 
1789
- case "inbound-rtp":
1804
+ case 'inbound-rtp':
1790
1805
  // this.log.debug('Got: inbound-rtp');
1791
1806
  // this.log.debug(report);
1792
1807
  // Packets
1793
1808
  totalReport.inboundPacketsReceived = report.packetsReceived;
1794
- deltaReport.inboundPacketsReceived = report.packetsReceived - this._currentReport.inboundPacketsReceived;
1809
+ deltaReport.inboundPacketsReceived =
1810
+ report.packetsReceived - this._currentReport.inboundPacketsReceived;
1795
1811
  // Bytes
1796
1812
  totalReport.inboundBytesReceived = report.bytesReceived;
1797
- deltaReport.inboundBytesReceived = report.bytesReceived - this._currentReport.inboundBytesReceived;
1813
+ deltaReport.inboundBytesReceived =
1814
+ report.bytesReceived - this._currentReport.inboundBytesReceived;
1798
1815
  // Loss
1799
1816
  totalReport.inboundPacketsLost = report.packetsLost;
1800
- deltaReport.inboundPacketsLost = report.packetsLost - this._currentReport.inboundPacketsLost;
1817
+ deltaReport.inboundPacketsLost =
1818
+ report.packetsLost - this._currentReport.inboundPacketsLost;
1801
1819
  // Jitter
1802
1820
  totalReport.inboundJitter = report.jitter * 1000;
1803
1821
  deltaReport.inboundJitter = report.jitter * 1000;
1804
1822
  break;
1805
1823
 
1806
- case "remote-inbound-rtp":
1824
+ case 'remote-inbound-rtp':
1807
1825
  // this.log.debug('Got: remote-inbound-rtp');
1808
1826
  // this.log.debug(report);
1809
1827
  // Loss
1810
1828
  totalReport.outboundPacketsLost = report.packetsLost;
1811
- deltaReport.outboundPacketsLost = report.packetsLost - this._currentReport.outboundPacketsLost;
1829
+ deltaReport.outboundPacketsLost =
1830
+ report.packetsLost - this._currentReport.outboundPacketsLost;
1812
1831
  // Jitter
1813
1832
  totalReport.outboundJitter = report.jitter * 1000;
1814
1833
  deltaReport.outboundJitter = report.jitter * 1000;
@@ -1834,9 +1853,9 @@ export class Session extends EventEmitter {
1834
1853
  };
1835
1854
 
1836
1855
  try {
1837
- this.emit("callQualityReportUpdate", finalReport);
1856
+ this.emit('callQualityReportUpdate', finalReport);
1838
1857
  } catch (e) {
1839
- this.log.error("Exception in call quality report update event: " + e);
1858
+ this.log.error('Exception in call quality report update event: ' + e);
1840
1859
  }
1841
1860
  }
1842
1861
  });
@@ -1860,27 +1879,28 @@ export class Session extends EventEmitter {
1860
1879
  // this.log.debug(`R factor loss effect ${lossEffect} / latency effect ${latencyEffect}`);
1861
1880
 
1862
1881
  report.rFactor = Math.max(0, 100 - lossEffect - latencyEffect);
1863
- report.mos = 1 + 0.035 * report.rFactor + 0.000007 * report.rFactor * (report.rFactor - 60) * (100 - report.rFactor);
1882
+ report.mos =
1883
+ 1 + 0.035 * report.rFactor + 0.000007 * report.rFactor * (report.rFactor - 60) * (100 - report.rFactor);
1864
1884
 
1865
1885
  // Quality string
1866
1886
  switch (true) {
1867
1887
  case report.rFactor &lt; 50:
1868
- report.qualityString = "Bad";
1888
+ report.qualityString = 'Bad';
1869
1889
  break;
1870
1890
  case report.rFactor &lt; 70:
1871
- report.qualityString = "Poor";
1891
+ report.qualityString = 'Poor';
1872
1892
  break;
1873
1893
  case report.rFactor &lt; 80:
1874
- report.qualityString = "Fair";
1894
+ report.qualityString = 'Fair';
1875
1895
  break;
1876
1896
  case report.rFactor &lt; 90:
1877
- report.qualityString = "Good";
1897
+ report.qualityString = 'Good';
1878
1898
  break;
1879
1899
  case report.rFactor &lt;= 100:
1880
- report.qualityString = "Excellent";
1900
+ report.qualityString = 'Excellent';
1881
1901
  break;
1882
1902
  default:
1883
- report.qualityString = "Error";
1903
+ report.qualityString = 'Error';
1884
1904
  }
1885
1905
 
1886
1906
  return report;
@@ -1914,7 +1934,7 @@ export class Session extends EventEmitter {
1914
1934
  *
1915
1935
  */
1916
1936
 
1917
- this.log.debug("Session state: " + state);
1937
+ this.log.debug('Session state: ' + state);
1918
1938
  if (info) {
1919
1939
  this.log.debug(info);
1920
1940
  }
@@ -1922,7 +1942,7 @@ export class Session extends EventEmitter {
1922
1942
  this._sessionState = state;
1923
1943
  try {
1924
1944
  this.emit(
1925
- "sessionStateChange",
1945
+ 'sessionStateChange',
1926
1946
  Object.assign(
1927
1947
  {
1928
1948
  state: state,
@@ -1932,51 +1952,51 @@ export class Session extends EventEmitter {
1932
1952
  ),
1933
1953
  );
1934
1954
  } catch (e) {
1935
- this.log.error("Exception in sessionStateChange event:" + e);
1955
+ this.log.error('Exception in sessionStateChange event:' + e);
1936
1956
  }
1937
1957
 
1938
1958
  // Trigger callDataAvailable dummy event
1939
- if (state === "TERMINATED") {
1940
- this._callDisposition = this._manualDisposition || "NORMAL";
1959
+ if (state === 'TERMINATED') {
1960
+ this._callDisposition = this._manualDisposition || 'NORMAL';
1941
1961
  this._callFinished();
1942
1962
  }
1943
1963
 
1944
- if (state === "FAILED") {
1945
- if (info.cause === "Unavailable") {
1946
- this._callDisposition = "TEMP_UNAVAIL";
1964
+ if (state === 'FAILED') {
1965
+ if (info.cause === 'Unavailable') {
1966
+ this._callDisposition = 'TEMP_UNAVAIL';
1947
1967
  if (this._phone.options.playSignalTones) {
1948
1968
  this._phone._startRepeatTone(ST_TEMP_UNAVAIL);
1949
1969
  }
1950
1970
  }
1951
1971
 
1952
- if (info.cause === "Not Found") {
1953
- this._callDisposition = "INVALID_NUMBER";
1972
+ if (info.cause === 'Not Found') {
1973
+ this._callDisposition = 'INVALID_NUMBER';
1954
1974
  if (this._phone.options.playSignalTones) {
1955
1975
  this._phone._startRepeatTone(ST_INVALID_NUMBER);
1956
1976
  }
1957
1977
  }
1958
1978
 
1959
- if (info.cause === "Canceled") {
1960
- this._callDisposition = this._manualDisposition || "NO_ANSWER";
1979
+ if (info.cause === 'Canceled') {
1980
+ this._callDisposition = this._manualDisposition || 'NO_ANSWER';
1961
1981
  }
1962
1982
 
1963
- if (info.cause === "Rejected") {
1964
- if (this.direction === "INBOUND") {
1965
- this._callDisposition = "REJECTED";
1983
+ if (info.cause === 'Rejected') {
1984
+ if (this.direction === 'INBOUND') {
1985
+ this._callDisposition = 'REJECTED';
1966
1986
  } else {
1967
- this._callDisposition = "BARRED";
1987
+ this._callDisposition = 'BARRED';
1968
1988
  }
1969
1989
  }
1970
1990
 
1971
- if (info.cause === "Busy") {
1972
- this._callDisposition = "BUSY";
1991
+ if (info.cause === 'Busy') {
1992
+ this._callDisposition = 'BUSY';
1973
1993
  if (this._phone.options.playSignalTones) {
1974
1994
  this._phone._startRepeatTone(ST_BUSY);
1975
1995
  }
1976
1996
  }
1977
1997
 
1978
1998
  // If session is incoming and failed, we don't fire calldataAvailable event
1979
- if (this._webRTCSession.direction === "incoming") {
1999
+ if (this._webRTCSession.direction === 'incoming') {
1980
2000
  // return;
1981
2001
  }
1982
2002
 
@@ -2006,7 +2026,7 @@ export class Session extends EventEmitter {
2006
2026
  * @property {string} REJECTED Incoming call was rejected
2007
2027
  */
2008
2028
  _callFinished() {
2009
- this.log.info("Call finished");
2029
+ this.log.info('Call finished');
2010
2030
 
2011
2031
  // Fire callEnded event
2012
2032
  this._fireCallEndedEvent();
@@ -2023,7 +2043,7 @@ export class Session extends EventEmitter {
2023
2043
 
2024
2044
  // Set answer call timeout
2025
2045
  _setAnswerCallTimeout(timeout) {
2026
- this.log.debug("Setting answer call timeout to: " + timeout);
2046
+ this.log.debug('Setting answer call timeout to: ' + timeout);
2027
2047
  this._answerCallTimeout = timeout;
2028
2048
  }
2029
2049
 
@@ -2035,9 +2055,9 @@ export class Session extends EventEmitter {
2035
2055
  * @property {boolean} state - New recording state
2036
2056
  */
2037
2057
  try {
2038
- this.emit("recordingStateChange", { state: this._isRecording, error: this._recordingError });
2058
+ this.emit('recordingStateChange', { state: this._isRecording, error: this._recordingError });
2039
2059
  } catch (e) {
2040
- this.log.error("Exception in recording state change event: " + e);
2060
+ this.log.error('Exception in recording state change event: ' + e);
2041
2061
  }
2042
2062
  }
2043
2063
 
@@ -2049,9 +2069,9 @@ export class Session extends EventEmitter {
2049
2069
  * @property {boolean} state - Mute state (true = muted / false = unmuted)
2050
2070
  */
2051
2071
  try {
2052
- this.emit("muteStateChange", { state: this._isMuted });
2072
+ this.emit('muteStateChange', { state: this._isMuted });
2053
2073
  } catch (e) {
2054
- this.log.error("Exception in mute state change event: " + e);
2074
+ this.log.error('Exception in mute state change event: ' + e);
2055
2075
  }
2056
2076
  }
2057
2077
 
@@ -2063,9 +2083,9 @@ export class Session extends EventEmitter {
2063
2083
  * @property {boolean} state - New hold state
2064
2084
  */
2065
2085
  try {
2066
- this.emit("holdStateChange", { state: this._isOnHold });
2086
+ this.emit('holdStateChange', { state: this._isOnHold });
2067
2087
  } catch (e) {
2068
- this.log.error("Exception in hold state change event: " + e);
2088
+ this.log.error('Exception in hold state change event: ' + e);
2069
2089
  }
2070
2090
  }
2071
2091
 
@@ -2077,9 +2097,9 @@ export class Session extends EventEmitter {
2077
2097
  * @property {boolean} mode - New whisper mode (0 = No whisper / 1 = Local only / 2 = Three way)
2078
2098
  */
2079
2099
  try {
2080
- this.emit("whisperModeChange", { mode: this._whisperMode });
2100
+ this.emit('whisperModeChange', { mode: this._whisperMode });
2081
2101
  } catch (e) {
2082
- this.log.error("Exception in whisper mode change event: " + e);
2102
+ this.log.error('Exception in whisper mode change event: ' + e);
2083
2103
  }
2084
2104
  }
2085
2105
 
@@ -2128,14 +2148,14 @@ export class Session extends EventEmitter {
2128
2148
 
2129
2149
  // Add some extra convenience fields
2130
2150
  e.durationStr = Tools.createDurationString(e.duration);
2131
- e.answerDurationStr = e.answerDuration ? Tools.createDurationString(e.answerDuration) : "";
2132
- e.activeDurationStr = e.activeDuration ? Tools.createDurationString(e.activeDuration) : "";
2151
+ e.answerDurationStr = e.answerDuration ? Tools.createDurationString(e.answerDuration) : '';
2152
+ e.activeDurationStr = e.activeDuration ? Tools.createDurationString(e.activeDuration) : '';
2133
2153
  e.callQualityReport = this._currentReport;
2134
2154
 
2135
2155
  try {
2136
- this.emit("callEnded", e);
2156
+ this.emit('callEnded', e);
2137
2157
  } catch (e) {
2138
- this.log.error("Exception in callEnded event: " + e);
2158
+ this.log.error('Exception in callEnded event: ' + e);
2139
2159
  }
2140
2160
  }
2141
2161
 
@@ -2146,10 +2166,10 @@ export class Session extends EventEmitter {
2146
2166
 
2147
2167
  const self = this;
2148
2168
  session.connection.ontrack = function (event) {
2149
- self.log.debug("Start media output (track):");
2169
+ self.log.debug('Start media output (track):');
2150
2170
  self.log.debug(event);
2151
2171
  self._phone._remoteAudioElement.srcObject = event.streams[0];
2152
2172
  };
2153
2173
  }
2154
2174
  }
2155
- </code></pre></article></section></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><div class="mobile-nav-links"></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="EventClient.html">EventClient</a></div><div class="sidebar-section-children"><a href="InvalidMediaDevice.html">InvalidMediaDevice</a></div><div class="sidebar-section-children"><a href="InvalidOptions.html">InvalidOptions</a></div><div class="sidebar-section-children"><a href="InvalidParameter.html">InvalidParameter</a></div><div class="sidebar-section-children"><a href="LogHandler.html">LogHandler</a></div><div class="sidebar-section-children"><a href="MediaNotPrepared.html">MediaNotPrepared</a></div><div class="sidebar-section-children"><a href="NoActiveSession.html">NoActiveSession</a></div><div class="sidebar-section-children"><a href="NotAllowed.html">NotAllowed</a></div><div class="sidebar-section-children"><a href="NotReady.html">NotReady</a></div><div class="sidebar-section-children"><a href="Phone.html">Phone</a></div><div class="sidebar-section-children"><a href="Request.html">Request</a></div><div class="sidebar-section-children"><a href="Requestor.html">Requestor</a></div><div class="sidebar-section-children"><a href="Session.html">Session</a></div><div class="sidebar-section-children"><a href="UnableToConnect.html">UnableToConnect</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-events"><div>Events</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#event:callDataInfo">callDataInfo</a></div><div class="sidebar-section-children"><a href="global.html#event:callDurationUpdate">callDurationUpdate</a></div><div class="sidebar-section-children"><a href="global.html#event:callEnded">callEnded</a></div><div class="sidebar-section-children"><a href="global.html#event:callQualityReportUpdate">callQualityReportUpdate</a></div><div class="sidebar-section-children"><a href="global.html#event:connectionStateChange">connectionStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:holdStateChange">holdStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:incomingCall">incomingCall</a></div><div class="sidebar-section-children"><a href="global.html#event:muteStateChange">muteStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:recordingStateChange">recordingStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionCreated">sessionCreated</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionRemoved">sessionRemoved</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionStateChange">sessionStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:whisperModeChange">whisperModeChange</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#CALL_DIRECTION">CALL_DIRECTION</a></div><div class="sidebar-section-children"><a href="global.html#CALL_DISPOSITION">CALL_DISPOSITION</a></div><div class="sidebar-section-children"><a href="global.html#CONNECTION_STATE">CONNECTION_STATE</a></div><div class="sidebar-section-children"><a href="global.html#LOGLVL">LOGLVL</a></div><div class="sidebar-section-children"><a href="global.html#SESSION_STATE">SESSION_STATE</a></div></div></div><div class="mobile-navbar-actions"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>
2175
+ </code></pre></article></section></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><div class="mobile-nav-links"></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="EventClient.html">EventClient</a></div><div class="sidebar-section-children"><a href="EventServiceNotConnected.html">EventServiceNotConnected</a></div><div class="sidebar-section-children"><a href="InvalidMediaDevice.html">InvalidMediaDevice</a></div><div class="sidebar-section-children"><a href="InvalidOptions.html">InvalidOptions</a></div><div class="sidebar-section-children"><a href="InvalidParameter.html">InvalidParameter</a></div><div class="sidebar-section-children"><a href="LogHandler.html">LogHandler</a></div><div class="sidebar-section-children"><a href="MediaNotPrepared.html">MediaNotPrepared</a></div><div class="sidebar-section-children"><a href="NoActiveSession.html">NoActiveSession</a></div><div class="sidebar-section-children"><a href="NotAllowed.html">NotAllowed</a></div><div class="sidebar-section-children"><a href="NotReady.html">NotReady</a></div><div class="sidebar-section-children"><a href="Phone.html">Phone</a></div><div class="sidebar-section-children"><a href="Request.html">Request</a></div><div class="sidebar-section-children"><a href="Requestor.html">Requestor</a></div><div class="sidebar-section-children"><a href="Session.html">Session</a></div><div class="sidebar-section-children"><a href="UnableToConnect.html">UnableToConnect</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-events"><div>Events</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#event:callDataInfo">callDataInfo</a></div><div class="sidebar-section-children"><a href="global.html#event:callDurationUpdate">callDurationUpdate</a></div><div class="sidebar-section-children"><a href="global.html#event:callEnded">callEnded</a></div><div class="sidebar-section-children"><a href="global.html#event:callQualityReportUpdate">callQualityReportUpdate</a></div><div class="sidebar-section-children"><a href="global.html#event:connectionStateChange">connectionStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:holdStateChange">holdStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:incomingCall">incomingCall</a></div><div class="sidebar-section-children"><a href="global.html#event:muteStateChange">muteStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:recordingStateChange">recordingStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionCreated">sessionCreated</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionRemoved">sessionRemoved</a></div><div class="sidebar-section-children"><a href="global.html#event:sessionStateChange">sessionStateChange</a></div><div class="sidebar-section-children"><a href="global.html#event:whisperModeChange">whisperModeChange</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#CALL_DIRECTION">CALL_DIRECTION</a></div><div class="sidebar-section-children"><a href="global.html#CALL_DISPOSITION">CALL_DISPOSITION</a></div><div class="sidebar-section-children"><a href="global.html#CONNECTION_STATE">CONNECTION_STATE</a></div><div class="sidebar-section-children"><a href="global.html#LOGLVL">LOGLVL</a></div><div class="sidebar-section-children"><a href="global.html#SESSION_STATE">SESSION_STATE</a></div></div></div><div class="mobile-navbar-actions"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>