@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.
- package/demos/event_client.html +225 -210
- package/demos/phone_client.html +539 -519
- package/dist/telegenta.js +326 -290
- package/dist/telegenta.min.js +1 -1
- package/docs/EventClient.html +1 -1
- package/docs/EventServiceNotConnected.html +3 -0
- package/docs/InvalidMediaDevice.html +1 -1
- package/docs/InvalidOptions.html +1 -1
- package/docs/InvalidParameter.html +1 -1
- package/docs/LogHandler.html +2 -2
- package/docs/MediaNotPrepared.html +1 -1
- package/docs/NoActiveSession.html +1 -1
- package/docs/NotAllowed.html +1 -1
- package/docs/NotReady.html +1 -1
- package/docs/Phone.html +2 -2
- package/docs/Request.html +1 -1
- package/docs/Requestor.html +1 -1
- package/docs/Session.html +1 -1
- package/docs/UnableToConnect.html +1 -1
- package/docs/data/search.json +1 -1
- package/docs/event-client.js.html +44 -38
- package/docs/exceptions.js.html +12 -2
- package/docs/global.html +3 -3
- package/docs/index.html +1 -1
- package/docs/logger.js.html +2 -2
- package/docs/phone-client.js.html +284 -264
- package/docs/requestor.js.html +3 -3
- package/package.json +45 -45
|
@@ -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
|
|
5
|
-
import JsSIP from
|
|
6
|
-
import { LogHandler, LOGLVL } from
|
|
7
|
-
import * as Exceptions from
|
|
8
|
-
import * as Tools from
|
|
9
|
-
import { EventClient } from
|
|
10
|
-
import camelcaseKeys from
|
|
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:
|
|
14
|
-
eventServer:
|
|
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
|
-
|
|
47
|
+
'*': [1209, 941],
|
|
48
48
|
0: [1336, 941],
|
|
49
|
-
|
|
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(
|
|
120
|
+
this._remoteAudioElement = document.createElement('AUDIO');
|
|
121
121
|
this._remoteAudioElement.autoplay = true;
|
|
122
122
|
|
|
123
123
|
// Tone generator
|
|
124
|
-
this._toneAudioElement = document.createElement(
|
|
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(
|
|
139
|
+
JsSIP.debug.disable('JsSIP:*');
|
|
140
140
|
} else {
|
|
141
|
-
JsSIP.debug.disable(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
217
|
+
throw new Exceptions.InvalidOptions('provisionToken', 'Invalid token');
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
this.log.info(
|
|
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(
|
|
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(
|
|
231
|
+
throw new Exceptions.InvalidOptions('authorizationUsername', 'Missing username');
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
if (!this._options.password) {
|
|
235
|
-
throw new Exceptions.InvalidOptions(
|
|
235
|
+
throw new Exceptions.InvalidOptions('password', 'Missing password');
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
if (!this._options.callToken) {
|
|
239
|
-
throw new Exceptions.InvalidOptions(
|
|
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:
|
|
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(
|
|
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(
|
|
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(
|
|
296
|
+
throw new Exceptions.UnableToConnect('Unable to connect phone websocket: ' + err);
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
-
this.log.info(
|
|
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 +
|
|
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(
|
|
315
|
-
self.log.debug(
|
|
316
|
-
if (data.originator ===
|
|
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(
|
|
330
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
349
|
-
self._setConnectionState(
|
|
350
|
+
this._UA.on('connecting', function (/* data */) {
|
|
351
|
+
self._setConnectionState('CONNECTING');
|
|
350
352
|
});
|
|
351
353
|
|
|
352
|
-
this._UA.on(
|
|
353
|
-
self._setConnectionState(
|
|
354
|
+
this._UA.on('connected', function (/* data */) {
|
|
355
|
+
self._setConnectionState('CONNECTED');
|
|
354
356
|
});
|
|
355
357
|
|
|
356
|
-
this._UA.on(
|
|
357
|
-
self._setConnectionState(
|
|
358
|
+
this._UA.on('disconnected', function (/* data */) {
|
|
359
|
+
self._setConnectionState('DISCONNECTED');
|
|
358
360
|
});
|
|
359
361
|
|
|
360
|
-
this._UA.on(
|
|
361
|
-
self._setConnectionState(
|
|
362
|
+
this._UA.on('registered', function (/* data */) {
|
|
363
|
+
self._setConnectionState('REGISTERED');
|
|
362
364
|
});
|
|
363
365
|
|
|
364
|
-
this._UA.on(
|
|
365
|
-
self._setConnectionState(
|
|
366
|
+
this._UA.on('unregistered', function (/* data */) {
|
|
367
|
+
self._setConnectionState('UNREGISTERED');
|
|
366
368
|
});
|
|
367
369
|
|
|
368
|
-
this._UA.on(
|
|
369
|
-
self._setConnectionState(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
405
|
+
this.log.warning('Unable to disconnect event client');
|
|
404
406
|
}
|
|
405
407
|
|
|
406
408
|
this._isStarted = false;
|
|
407
|
-
this.log.info(
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
476
|
+
let mediaSwitch = 'sip:' + s[1];
|
|
475
477
|
|
|
476
|
-
this.log.debug(
|
|
477
|
-
return this.call(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 ===
|
|
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(
|
|
713
|
+
this.emit('sessionCreated', { session: session });
|
|
712
714
|
} catch (e) {
|
|
713
|
-
this.log.error(
|
|
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(
|
|
731
|
+
this.emit('sessionRemoved', { session: session });
|
|
730
732
|
} catch (e) {
|
|
731
|
-
this.log.error(
|
|
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 (
|
|
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(
|
|
788
|
+
this.log.info('Connection state: ' + state);
|
|
782
789
|
this._connectionState = state;
|
|
783
790
|
try {
|
|
784
|
-
this.emit(
|
|
791
|
+
this.emit('connectionStateChange', { state: state });
|
|
785
792
|
} catch (e) {
|
|
786
|
-
this.log.error(
|
|
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(
|
|
804
|
+
this.emit('incomingCall', session);
|
|
798
805
|
} catch (e) {
|
|
799
|
-
this.log.error(
|
|
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(
|
|
862
|
+
this.emit('callDataInfo', e);
|
|
856
863
|
} catch (e) {
|
|
857
|
-
this.log.error(
|
|
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: [
|
|
945
|
+
iceServers: [{ urls: ['stun:stun.l.google.com:19302'] }],
|
|
939
946
|
},
|
|
940
|
-
extraHeaders: [
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
976
|
-
options.extraHeaders.push(
|
|
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(
|
|
985
|
-
options.extraHeaders.push(
|
|
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(
|
|
998
|
+
this.log.warning('Other sessions exist but media switch address is invalid');
|
|
988
999
|
}
|
|
989
1000
|
} else {
|
|
990
|
-
this.log.debug(
|
|
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 =
|
|
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(
|
|
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(
|
|
1013
|
-
this._destinationNumber = newSessionRequest.request.getHeader(
|
|
1014
|
-
this._localNumberName = unescape(newSessionRequest.request.getHeader(
|
|
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(
|
|
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(
|
|
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 ===
|
|
1069
|
+
if (c.type === 'srflx' && c.relatedAddress !== null && 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(
|
|
1092
|
+
this._webRTCSession.on('connecting', function (/* data */) {
|
|
1082
1093
|
self._startDurationUpdateTimer();
|
|
1083
1094
|
self._startRTCPStatsUpdateTimer();
|
|
1084
|
-
self._setSessionState(
|
|
1095
|
+
self._setSessionState('INITIALIZING');
|
|
1085
1096
|
});
|
|
1086
1097
|
|
|
1087
|
-
this._webRTCSession.on(
|
|
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(
|
|
1104
|
+
self._setSessionState('CALLING');
|
|
1094
1105
|
});
|
|
1095
1106
|
|
|
1096
|
-
this._webRTCSession.on(
|
|
1097
|
-
if (data.originator ===
|
|
1098
|
-
self._setSessionState(
|
|
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(
|
|
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(
|
|
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 ===
|
|
1134
|
-
const recState = data.response.getHeader(
|
|
1135
|
-
if (recState ===
|
|
1136
|
-
self.log.debug(
|
|
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(
|
|
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(
|
|
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(
|
|
1150
|
-
self._setSessionState(
|
|
1160
|
+
this._webRTCSession.on('confirmed', function (/* data */) {
|
|
1161
|
+
self._setSessionState('ACTIVE');
|
|
1151
1162
|
});
|
|
1152
1163
|
|
|
1153
|
-
this._webRTCSession.on(
|
|
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(
|
|
1175
|
+
self._setSessionState('TERMINATED');
|
|
1165
1176
|
});
|
|
1166
1177
|
|
|
1167
|
-
this._webRTCSession.on(
|
|
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(
|
|
1199
|
+
self._setSessionState('FAILED', { cause: data.cause, message: m });
|
|
1189
1200
|
});
|
|
1190
1201
|
|
|
1191
|
-
this._webRTCSession.on(
|
|
1192
|
-
self.log.debug(
|
|
1202
|
+
this._webRTCSession.on('dtmf', function (data) {
|
|
1203
|
+
self.log.debug('Session DTMF', data);
|
|
1193
1204
|
});
|
|
1194
1205
|
|
|
1195
|
-
this._webRTCSession.on(
|
|
1196
|
-
self.log.debug(
|
|
1206
|
+
this._webRTCSession.on('newInfo', function (data) {
|
|
1207
|
+
self.log.debug('New session info', data);
|
|
1197
1208
|
});
|
|
1198
1209
|
|
|
1199
|
-
this._webRTCSession.on(
|
|
1210
|
+
this._webRTCSession.on('hold', function (/* data */) {
|
|
1200
1211
|
self._isOnHold = true;
|
|
1201
1212
|
self._fireHoldStateEvent();
|
|
1202
|
-
self._setSessionState(
|
|
1213
|
+
self._setSessionState('ON_HOLD');
|
|
1203
1214
|
});
|
|
1204
1215
|
|
|
1205
|
-
this._webRTCSession.on(
|
|
1216
|
+
this._webRTCSession.on('unhold', function (/* data */) {
|
|
1206
1217
|
self._isOnHold = false;
|
|
1207
1218
|
self._fireHoldStateEvent();
|
|
1208
|
-
self._setSessionState(
|
|
1219
|
+
self._setSessionState('ACTIVE');
|
|
1209
1220
|
});
|
|
1210
1221
|
|
|
1211
|
-
this._webRTCSession.on(
|
|
1212
|
-
self.log.debug(
|
|
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(
|
|
1218
|
-
self.log.debug(
|
|
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(
|
|
1224
|
-
self.log.debug(
|
|
1234
|
+
this._webRTCSession.on('reinvite', function (data) {
|
|
1235
|
+
self.log.debug('Session reinvite', data);
|
|
1225
1236
|
});
|
|
1226
1237
|
|
|
1227
|
-
this._webRTCSession.on(
|
|
1228
|
-
self.log.debug(
|
|
1238
|
+
this._webRTCSession.on('update', function (data) {
|
|
1239
|
+
self.log.debug('Session update', data);
|
|
1229
1240
|
});
|
|
1230
1241
|
|
|
1231
|
-
this._webRTCSession.on(
|
|
1232
|
-
self.log.error(
|
|
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(
|
|
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(
|
|
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: [
|
|
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: [
|
|
1282
|
+
iceServers: [{ urls: ['stun:stun.l.google.com:19302'] }],
|
|
1272
1283
|
},
|
|
1273
|
-
extraHeaders: [
|
|
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(
|
|
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 =
|
|
1293
|
-
this.log.info(
|
|
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(
|
|
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(
|
|
1353
|
-
return
|
|
1354
|
-
} else if (this._webRTCSession.direction ===
|
|
1355
|
-
this.log.debug(
|
|
1356
|
-
return
|
|
1357
|
-
} else if (this._webRTCSession.direction ===
|
|
1358
|
-
this.log.debug(
|
|
1359
|
-
return
|
|
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(
|
|
1362
|
-
return
|
|
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: [
|
|
1383
|
+
extraHeaders: ['Record: on'],
|
|
1373
1384
|
};
|
|
1374
1385
|
|
|
1375
|
-
this.log.debug(
|
|
1386
|
+
this.log.debug('Request start recording');
|
|
1376
1387
|
|
|
1377
1388
|
const self = this;
|
|
1378
|
-
this._webRTCSession.once(
|
|
1379
|
-
if (data.originator ===
|
|
1380
|
-
data.info.on(
|
|
1381
|
-
self.log.info(
|
|
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(
|
|
1395
|
+
self.emit('recordingStateChange', { state: true, error: null });
|
|
1385
1396
|
} catch (e) {
|
|
1386
|
-
self.log.error(
|
|
1397
|
+
self.log.error('Exception in recordingStateChange event: ' + e);
|
|
1387
1398
|
}
|
|
1388
1399
|
});
|
|
1389
1400
|
|
|
1390
|
-
data.info.on(
|
|
1401
|
+
data.info.on('failed', function (data) {
|
|
1391
1402
|
self._recordingError = data.response.reason_phrase;
|
|
1392
|
-
self.log.error(
|
|
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(
|
|
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: [
|
|
1417
|
+
extraHeaders: ['Record: off'],
|
|
1407
1418
|
};
|
|
1408
1419
|
|
|
1409
|
-
this.log.debug(
|
|
1420
|
+
this.log.debug('Request stop recording');
|
|
1410
1421
|
|
|
1411
1422
|
const self = this;
|
|
1412
1423
|
|
|
1413
|
-
this._webRTCSession.once(
|
|
1414
|
-
data.info.on(
|
|
1415
|
-
self.log.info(
|
|
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(
|
|
1429
|
+
self.emit('recordingStateChange', { state: false, error: null });
|
|
1419
1430
|
} catch (e) {
|
|
1420
|
-
self.log.error(
|
|
1431
|
+
self.log.error('Exception in recordingStateChange event: ' + e);
|
|
1421
1432
|
}
|
|
1422
1433
|
});
|
|
1423
1434
|
|
|
1424
|
-
data.info.on(
|
|
1425
|
-
self.log.error(
|
|
1435
|
+
data.info.on('failed', function (data) {
|
|
1436
|
+
self.log.error('Recording stopped failed: ' + data.response.reason_phrase);
|
|
1426
1437
|
try {
|
|
1427
|
-
self.emit(
|
|
1438
|
+
self.emit('recordingStateChange', { state: self._isRecording, error: data.response.reason_phrase });
|
|
1428
1439
|
} catch (e) {
|
|
1429
|
-
self.log.error(
|
|
1440
|
+
self.log.error('Exception in recordingStateChange event: ' + e);
|
|
1430
1441
|
}
|
|
1431
1442
|
});
|
|
1432
1443
|
});
|
|
1433
1444
|
|
|
1434
|
-
this._webRTCSession.sendInfo(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
1551
|
+
throw new Exceptions.InvalidParameter('Invalid DTMF code');
|
|
1541
1552
|
}
|
|
1542
1553
|
|
|
1543
|
-
this.log.info(
|
|
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(
|
|
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(
|
|
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(
|
|
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, {
|
|
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(
|
|
1581
|
-
self.log.info(
|
|
1593
|
+
referSubscriber.on('requestSucceeded', function () {
|
|
1594
|
+
self.log.info('Transfer completed successfully');
|
|
1582
1595
|
});
|
|
1583
1596
|
|
|
1584
|
-
referSubscriber.on(
|
|
1597
|
+
referSubscriber.on('requestFailed', function (cause) {
|
|
1585
1598
|
self.log.error(`Transfer rejected: ${cause}`);
|
|
1586
1599
|
});
|
|
1587
1600
|
|
|
1588
|
-
referSubscriber.on(
|
|
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(
|
|
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(
|
|
1624
|
+
const p = this._phone._eventClient.fireEvent('call_command', {
|
|
1612
1625
|
call_uuid: this.uuid,
|
|
1613
|
-
call_command:
|
|
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(
|
|
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 ===
|
|
1646
|
-
throw new Exceptions.NotAllowed(
|
|
1658
|
+
if (!this.direction === 'LISTEN') {
|
|
1659
|
+
throw new Exceptions.NotAllowed('Call is not correct type (listen)');
|
|
1647
1660
|
}
|
|
1648
1661
|
|
|
1649
1662
|
if (mode < 0 || mode > 2) {
|
|
1650
|
-
throw new Exceptions.InvalidOptions(
|
|
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(
|
|
1725
|
+
self.emit('callDurationUpdate', e);
|
|
1713
1726
|
} catch (e) {
|
|
1714
|
-
self.log.error(
|
|
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
|
|
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 =
|
|
1796
|
+
deltaReport.outboundPacketsSent =
|
|
1797
|
+
report.packetsSent - this._currentReport.outboundPacketsSent;
|
|
1784
1798
|
// Bytes
|
|
1785
1799
|
totalReport.outboundBytesSent = report.bytesSent;
|
|
1786
|
-
deltaReport.outboundBytesSent =
|
|
1800
|
+
deltaReport.outboundBytesSent =
|
|
1801
|
+
report.bytesSent - this._currentReport.outboundBytesSent;
|
|
1787
1802
|
break;
|
|
1788
1803
|
|
|
1789
|
-
case
|
|
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 =
|
|
1809
|
+
deltaReport.inboundPacketsReceived =
|
|
1810
|
+
report.packetsReceived - this._currentReport.inboundPacketsReceived;
|
|
1795
1811
|
// Bytes
|
|
1796
1812
|
totalReport.inboundBytesReceived = report.bytesReceived;
|
|
1797
|
-
deltaReport.inboundBytesReceived =
|
|
1813
|
+
deltaReport.inboundBytesReceived =
|
|
1814
|
+
report.bytesReceived - this._currentReport.inboundBytesReceived;
|
|
1798
1815
|
// Loss
|
|
1799
1816
|
totalReport.inboundPacketsLost = report.packetsLost;
|
|
1800
|
-
deltaReport.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
|
|
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 =
|
|
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(
|
|
1856
|
+
this.emit('callQualityReportUpdate', finalReport);
|
|
1838
1857
|
} catch (e) {
|
|
1839
|
-
this.log.error(
|
|
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 =
|
|
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 < 50:
|
|
1868
|
-
report.qualityString =
|
|
1888
|
+
report.qualityString = 'Bad';
|
|
1869
1889
|
break;
|
|
1870
1890
|
case report.rFactor < 70:
|
|
1871
|
-
report.qualityString =
|
|
1891
|
+
report.qualityString = 'Poor';
|
|
1872
1892
|
break;
|
|
1873
1893
|
case report.rFactor < 80:
|
|
1874
|
-
report.qualityString =
|
|
1894
|
+
report.qualityString = 'Fair';
|
|
1875
1895
|
break;
|
|
1876
1896
|
case report.rFactor < 90:
|
|
1877
|
-
report.qualityString =
|
|
1897
|
+
report.qualityString = 'Good';
|
|
1878
1898
|
break;
|
|
1879
1899
|
case report.rFactor <= 100:
|
|
1880
|
-
report.qualityString =
|
|
1900
|
+
report.qualityString = 'Excellent';
|
|
1881
1901
|
break;
|
|
1882
1902
|
default:
|
|
1883
|
-
report.qualityString =
|
|
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(
|
|
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
|
-
|
|
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(
|
|
1955
|
+
this.log.error('Exception in sessionStateChange event:' + e);
|
|
1936
1956
|
}
|
|
1937
1957
|
|
|
1938
1958
|
// Trigger callDataAvailable dummy event
|
|
1939
|
-
if (state ===
|
|
1940
|
-
this._callDisposition = this._manualDisposition ||
|
|
1959
|
+
if (state === 'TERMINATED') {
|
|
1960
|
+
this._callDisposition = this._manualDisposition || 'NORMAL';
|
|
1941
1961
|
this._callFinished();
|
|
1942
1962
|
}
|
|
1943
1963
|
|
|
1944
|
-
if (state ===
|
|
1945
|
-
if (info.cause ===
|
|
1946
|
-
this._callDisposition =
|
|
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 ===
|
|
1953
|
-
this._callDisposition =
|
|
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 ===
|
|
1960
|
-
this._callDisposition = this._manualDisposition ||
|
|
1979
|
+
if (info.cause === 'Canceled') {
|
|
1980
|
+
this._callDisposition = this._manualDisposition || 'NO_ANSWER';
|
|
1961
1981
|
}
|
|
1962
1982
|
|
|
1963
|
-
if (info.cause ===
|
|
1964
|
-
if (this.direction ===
|
|
1965
|
-
this._callDisposition =
|
|
1983
|
+
if (info.cause === 'Rejected') {
|
|
1984
|
+
if (this.direction === 'INBOUND') {
|
|
1985
|
+
this._callDisposition = 'REJECTED';
|
|
1966
1986
|
} else {
|
|
1967
|
-
this._callDisposition =
|
|
1987
|
+
this._callDisposition = 'BARRED';
|
|
1968
1988
|
}
|
|
1969
1989
|
}
|
|
1970
1990
|
|
|
1971
|
-
if (info.cause ===
|
|
1972
|
-
this._callDisposition =
|
|
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 ===
|
|
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(
|
|
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(
|
|
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(
|
|
2058
|
+
this.emit('recordingStateChange', { state: this._isRecording, error: this._recordingError });
|
|
2039
2059
|
} catch (e) {
|
|
2040
|
-
this.log.error(
|
|
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(
|
|
2072
|
+
this.emit('muteStateChange', { state: this._isMuted });
|
|
2053
2073
|
} catch (e) {
|
|
2054
|
-
this.log.error(
|
|
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(
|
|
2086
|
+
this.emit('holdStateChange', { state: this._isOnHold });
|
|
2067
2087
|
} catch (e) {
|
|
2068
|
-
this.log.error(
|
|
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(
|
|
2100
|
+
this.emit('whisperModeChange', { mode: this._whisperMode });
|
|
2081
2101
|
} catch (e) {
|
|
2082
|
-
this.log.error(
|
|
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(
|
|
2156
|
+
this.emit('callEnded', e);
|
|
2137
2157
|
} catch (e) {
|
|
2138
|
-
this.log.error(
|
|
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(
|
|
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>
|