Call.js

  1. /**
  2. * This class describes the information and current status of a call.
  3. */
  4. export default class Call {
  5. constructor({
  6. id, callId, accountId,
  7. localContact, localUri, remoteContact, remoteUri,
  8. state, stateText, held, muted, speaker,
  9. connectDuration, totalDuration,
  10. remoteOfferer, remoteAudioCount, remoteVideoCount, audioCount, videoCount,
  11. lastStatusCode, lastReason, media, provisionalMedia
  12. }) {
  13. let remoteNumber = null;
  14. let remoteName = null;
  15. if (remoteUri) {
  16. let match = remoteUri.match(/"([^"]+)" <sip:([^@]+)@/);
  17. if (match) {
  18. remoteName = match[1];
  19. remoteNumber = match[2];
  20. } else {
  21. match = remoteUri.match(/sip:([^@]+)@/);
  22. if (match) {
  23. remoteNumber = match[1];
  24. }
  25. }
  26. }
  27. this._id = id;
  28. this._callId = callId;
  29. this._accountId = accountId;
  30. this._localContact = localContact;
  31. this._localUri = localUri;
  32. this._remoteContact = remoteContact;
  33. this._remoteUri = remoteUri;
  34. this._state = state;
  35. this._stateText = stateText;
  36. this._held = held;
  37. this._muted = muted;
  38. this._speaker = speaker;
  39. this._connectDuration = connectDuration;
  40. this._totalDuration = totalDuration;
  41. this._remoteOfferer = remoteOfferer;
  42. this._remoteAudioCount = remoteAudioCount;
  43. this._remoteVideoCount = remoteVideoCount;
  44. this._remoteNumber = remoteNumber;
  45. this._remoteName = remoteName;
  46. this._audioCount = audioCount;
  47. this._videoCount = videoCount;
  48. this._lastStatusCode = lastStatusCode;
  49. this._lastReason = lastReason;
  50. this._media = media;
  51. this._provisionalMedia = provisionalMedia;
  52. this._constructionTime = Math.round(new Date().getTime() / 1000);
  53. }
  54. /**
  55. * Call identification.
  56. * @returns {int}
  57. */
  58. getId() {
  59. return this._id;
  60. }
  61. /**
  62. * The account ID where this call belongs.
  63. * @returns {int}
  64. */
  65. getAccountId() {
  66. return this._accountId;
  67. }
  68. /**
  69. * Dialog Call-ID string.
  70. *
  71. * @returns {String}
  72. */
  73. getCallId() {
  74. return this._callId;
  75. }
  76. /**
  77. * Up-to-date call duration in seconds.
  78. * Use local time to calculate actual call duration.
  79. *
  80. * @public
  81. * @returns {int}
  82. */
  83. getTotalDuration() {
  84. let time = Math.round(new Date().getTime() / 1000);
  85. let offset = time - this._constructionTime;
  86. return this._totalDuration + offset;
  87. };
  88. /**
  89. * Up-to-date call connected duration (zero when call is not established)
  90. *
  91. * @returns {int}
  92. */
  93. getConnectDuration() {
  94. if (this._connectDuration < 0 || this._state == "PJSIP_INV_STATE_DISCONNECTED") {
  95. return this._connectDuration;
  96. }
  97. let time = Math.round(new Date().getTime() / 1000);
  98. let offset = time - this._constructionTime;
  99. return this._connectDuration + offset;
  100. }
  101. /**
  102. * Call duration in "MM:SS" format.
  103. *
  104. * @public
  105. * @returns {string}
  106. */
  107. getFormattedTotalDuration() {
  108. return this._formatTime(this.getTotalDuration());
  109. };
  110. /**
  111. * Call duration in "MM:SS" format.
  112. *
  113. * @public
  114. * @returns {string}
  115. */
  116. getFormattedConnectDuration() {
  117. return this._formatTime(this.getConnectDuration());
  118. };
  119. /**
  120. * Local Contact.
  121. * TODO: Provide example
  122. * @returns {String}
  123. */
  124. getLocalContact() {
  125. return this._localContact;
  126. }
  127. /**
  128. * Local URI.
  129. * TODO: Provide example
  130. * @returns {String}
  131. */
  132. getLocalUri() {
  133. return this._localUri;
  134. }
  135. /**
  136. * Remote contact.
  137. * TODO: Provide example
  138. * @returns {String}
  139. */
  140. getRemoteContact() {
  141. return this._remoteContact;
  142. }
  143. /**
  144. * Remote URI.
  145. * TODO: Provide example
  146. * @returns {String}
  147. */
  148. getRemoteUri() {
  149. return this._remoteUri;
  150. }
  151. /**
  152. * Callee name. Could be null if no name specified in URI.
  153. * @returns {String}
  154. */
  155. getRemoteName() {
  156. return this._remoteName;
  157. }
  158. /**
  159. * Callee number
  160. * @returns {String}
  161. */
  162. getRemoteNumber() {
  163. return this._remoteNumber;
  164. }
  165. /**
  166. * @returns {String}
  167. */
  168. getRemoteFormattedNumber() {
  169. if (this._remoteName && this._remoteNumber) {
  170. return `${this._remoteName} <${this._remoteNumber}>`;
  171. } else if (this._remoteNumber) {
  172. return this._remoteNumber;
  173. } else {
  174. return this._remoteUri
  175. }
  176. }
  177. /**
  178. * Invite session state.
  179. *
  180. * PJSIP_INV_STATE_NULL Before INVITE is sent or received
  181. * PJSIP_INV_STATE_CALLING After INVITE is sent
  182. * PJSIP_INV_STATE_INCOMING After INVITE is received.
  183. * PJSIP_INV_STATE_EARLY After response with To tag.
  184. * PJSIP_INV_STATE_CONNECTING After 2xx is sent/received.
  185. * PJSIP_INV_STATE_CONFIRMED After ACK is sent/received.
  186. * PJSIP_INV_STATE_DISCONNECTED Session is terminated.
  187. *
  188. * @returns {String}
  189. */
  190. getState() {
  191. return this._state;
  192. }
  193. /**
  194. * Text describing the state.
  195. *
  196. * @returns {String}
  197. */
  198. getStateText() {
  199. return this._stateText;
  200. }
  201. isHeld() {
  202. return this._held;
  203. }
  204. isMuted() {
  205. return this._muted;
  206. }
  207. isSpeaker() {
  208. return this._speaker;
  209. }
  210. isTerminated() {
  211. return this._state === 'PJSIP_INV_STATE_DISCONNECTED';
  212. }
  213. /**
  214. * Flag if remote was SDP offerer
  215. * @returns {boolean}
  216. */
  217. getRemoteOfferer() {
  218. // TODO Verify whether boolean value
  219. return this._remoteOfferer;
  220. }
  221. /**
  222. * Number of audio streams offered by remote.
  223. * @returns {int}
  224. */
  225. getRemoteAudioCount() {
  226. return this._remoteAudioCount;
  227. }
  228. /**
  229. * Number of video streams offered by remote.
  230. * @returns {int}
  231. */
  232. getRemoteVideoCount() {
  233. return this._remoteVideoCount;
  234. }
  235. /**
  236. * Number of simultaneous active audio streams for this call. If zero - audio is disabled in this call.
  237. * @returns {int}
  238. */
  239. getAudioCount() {
  240. return this._audioCount;
  241. }
  242. /**
  243. * Number of simultaneous active video streams for this call. If zero - video is disabled in this call.
  244. * @returns {*}
  245. */
  246. getVideoCount() {
  247. return this._videoCount;
  248. }
  249. /**
  250. * Last status code heard, which can be used as cause code.
  251. * Possible values:
  252. * - PJSIP_SC_TRYING / 100
  253. * - PJSIP_SC_RINGING / 180
  254. * - PJSIP_SC_CALL_BEING_FORWARDED / 181
  255. * - PJSIP_SC_QUEUED / 182
  256. * - PJSIP_SC_PROGRESS / 183
  257. * - PJSIP_SC_OK / 200
  258. * - PJSIP_SC_ACCEPTED / 202
  259. * - PJSIP_SC_MULTIPLE_CHOICES / 300
  260. * - PJSIP_SC_MOVED_PERMANENTLY / 301
  261. * - PJSIP_SC_MOVED_TEMPORARILY / 302
  262. * - PJSIP_SC_USE_PROXY / 305
  263. * - PJSIP_SC_ALTERNATIVE_SERVICE / 380
  264. * - PJSIP_SC_BAD_REQUEST / 400
  265. * - PJSIP_SC_UNAUTHORIZED / 401
  266. * - PJSIP_SC_PAYMENT_REQUIRED / 402
  267. * - PJSIP_SC_FORBIDDEN / 403
  268. * - PJSIP_SC_NOT_FOUND / 404
  269. * - PJSIP_SC_METHOD_NOT_ALLOWED / 405
  270. * - PJSIP_SC_NOT_ACCEPTABLE / 406
  271. * - PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED / 407
  272. * - PJSIP_SC_REQUEST_TIMEOUT / 408
  273. * - PJSIP_SC_GONE / 410
  274. * - PJSIP_SC_REQUEST_ENTITY_TOO_LARGE / 413
  275. * - PJSIP_SC_REQUEST_URI_TOO_LONG / 414
  276. * - PJSIP_SC_UNSUPPORTED_MEDIA_TYPE / 415
  277. * - PJSIP_SC_UNSUPPORTED_URI_SCHEME / 416
  278. * - PJSIP_SC_BAD_EXTENSION / 420
  279. * - PJSIP_SC_EXTENSION_REQUIRED / 421
  280. * - PJSIP_SC_SESSION_TIMER_TOO_SMALL / 422
  281. * - PJSIP_SC_INTERVAL_TOO_BRIEF / 423
  282. * - PJSIP_SC_TEMPORARILY_UNAVAILABLE / 480
  283. * - PJSIP_SC_CALL_TSX_DOES_NOT_EXIST / 481
  284. * - PJSIP_SC_LOOP_DETECTED / 482
  285. * - PJSIP_SC_TOO_MANY_HOPS / 483
  286. * - PJSIP_SC_ADDRESS_INCOMPLETE / 484
  287. * - PJSIP_AC_AMBIGUOUS / 485
  288. * - PJSIP_SC_BUSY_HERE / 486
  289. * - PJSIP_SC_REQUEST_TERMINATED / 487
  290. * - PJSIP_SC_NOT_ACCEPTABLE_HERE / 488
  291. * - PJSIP_SC_BAD_EVENT / 489
  292. * - PJSIP_SC_REQUEST_UPDATED / 490
  293. * - PJSIP_SC_REQUEST_PENDING / 491
  294. * - PJSIP_SC_UNDECIPHERABLE / 493
  295. * - PJSIP_SC_INTERNAL_SERVER_ERROR / 500
  296. * - PJSIP_SC_NOT_IMPLEMENTED / 501
  297. * - PJSIP_SC_BAD_GATEWAY / 502
  298. * - PJSIP_SC_SERVICE_UNAVAILABLE / 503
  299. * - PJSIP_SC_SERVER_TIMEOUT / 504
  300. * - PJSIP_SC_VERSION_NOT_SUPPORTED / 505
  301. * - PJSIP_SC_MESSAGE_TOO_LARGE / 513
  302. * - PJSIP_SC_PRECONDITION_FAILURE / 580
  303. * - PJSIP_SC_BUSY_EVERYWHERE / 600
  304. * - PJSIP_SC_DECLINE / 603
  305. * - PJSIP_SC_DOES_NOT_EXIST_ANYWHERE / 604
  306. * - PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE / 606
  307. * - PJSIP_SC_TSX_TIMEOUT / PJSIP_SC_REQUEST_TIMEOUT
  308. * - PJSIP_SC_TSX_TRANSPORT_ERROR / PJSIP_SC_SERVICE_UNAVAILABLE
  309. *
  310. * @returns {string}
  311. */
  312. getLastStatusCode() {
  313. return this._lastStatusCode;
  314. }
  315. /**
  316. * The reason phrase describing the last status.
  317. *
  318. * @returns {string}
  319. */
  320. getLastReason() {
  321. return this._lastReason;
  322. }
  323. getMedia() {
  324. return this._media;
  325. }
  326. getProvisionalMedia() {
  327. return this._provisionalMedia;
  328. }
  329. /**
  330. * Format seconds to "MM:SS" format.
  331. *
  332. * @public
  333. * @returns {string}
  334. */
  335. _formatTime(seconds) {
  336. if (isNaN(seconds) || seconds < 0) {
  337. return "00:00";
  338. }
  339. var hours = parseInt( seconds / 3600 ) % 24;
  340. var minutes = parseInt( seconds / 60 ) % 60;
  341. var result = "";
  342. seconds = seconds % 60;
  343. if (hours > 0) {
  344. result += (hours < 10 ? "0" + hours : hours) + ":";
  345. }
  346. result += (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds < 10 ? "0" + seconds : seconds);
  347. return result;
  348. };
  349. }