@wazo/sdk 0.37.21 → 0.37.25

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.
Files changed (118) hide show
  1. package/dist/wazo-sdk.js +5 -5
  2. package/esm/__tests__/api-client.test.js +36 -5
  3. package/esm/__tests__/web-rtc-client.test.js +77 -66
  4. package/esm/api/call-logd.js +7 -0
  5. package/esm/api/calld.js +10 -0
  6. package/esm/api/chatd.js +7 -0
  7. package/esm/api/confd.js +13 -5
  8. package/esm/api/ctid-ng.js +10 -0
  9. package/esm/api/dird.js +3 -0
  10. package/esm/api-client.js +36 -5
  11. package/esm/checker/Checker.js +77 -66
  12. package/esm/checker/checks/aor.js +36 -5
  13. package/esm/checker/checks/api.js +36 -5
  14. package/esm/checker/checks/index.js +77 -66
  15. package/esm/checker/checks/webrtc-transport.js +77 -66
  16. package/esm/checker/checks/webrtc.js +77 -66
  17. package/esm/domain/AdHocAPIConference.js +36 -5
  18. package/esm/domain/Call.js +3 -0
  19. package/esm/domain/CallLog.js +7 -0
  20. package/esm/domain/ChatMessage.js +4 -0
  21. package/esm/domain/ChatRoom.js +3 -0
  22. package/esm/domain/Contact.js +3 -0
  23. package/esm/domain/Features.js +36 -5
  24. package/esm/domain/Meeting.js +15 -5
  25. package/esm/domain/Phone/CTIPhone.js +40 -5
  26. package/esm/domain/Phone/WebRTCPhone.js +45 -16
  27. package/esm/domain/Recording.js +3 -0
  28. package/esm/domain/Voicemail.js +3 -0
  29. package/esm/domain/__tests__/Call.test.js +3 -0
  30. package/esm/domain/__tests__/CallLog.test.js +7 -0
  31. package/esm/domain/__tests__/Contact.test.js +3 -0
  32. package/esm/domain/__tests__/Meeting.test.js +144 -0
  33. package/esm/domain/__tests__/Voicemail.test.js +3 -0
  34. package/esm/index.js +125 -81
  35. package/esm/lib/WazoSessionDescriptionHandler.js +0 -38
  36. package/esm/service/CallApi.js +36 -5
  37. package/esm/service/getApiClient.js +36 -5
  38. package/esm/simple/Auth.js +125 -81
  39. package/esm/simple/Configuration.js +125 -81
  40. package/esm/simple/Directory.js +36 -5
  41. package/esm/simple/Phone.js +125 -81
  42. package/esm/simple/index.js +125 -81
  43. package/esm/simple/room/LocalParticipant.js +125 -81
  44. package/esm/simple/room/Participant.js +125 -81
  45. package/esm/simple/room/RemoteParticipant.js +125 -81
  46. package/esm/simple/room/Room.js +125 -81
  47. package/esm/simple/room/SipRoom.js +125 -81
  48. package/esm/simple/room/Stream.js +125 -81
  49. package/esm/simple/room/__tests__/RemoteParticipant.test.js +125 -81
  50. package/esm/simple/utils.js +125 -81
  51. package/esm/types/WebSocketMessage.js +1 -1
  52. package/esm/web-rtc-client.js +77 -66
  53. package/lib/__tests__/api-client.test.js +36 -5
  54. package/lib/__tests__/web-rtc-client.test.js +77 -66
  55. package/lib/api/call-logd.js +7 -0
  56. package/lib/api/calld.js +10 -0
  57. package/lib/api/chatd.js +7 -0
  58. package/lib/api/confd.js +13 -5
  59. package/lib/api/ctid-ng.js +10 -0
  60. package/lib/api/dird.js +3 -0
  61. package/lib/api-client.js +36 -5
  62. package/lib/checker/Checker.js +77 -66
  63. package/lib/checker/checks/aor.js +36 -5
  64. package/lib/checker/checks/api.js +36 -5
  65. package/lib/checker/checks/index.js +77 -66
  66. package/lib/checker/checks/webrtc-transport.js +77 -66
  67. package/lib/checker/checks/webrtc.js +77 -66
  68. package/lib/domain/AdHocAPIConference.js +36 -5
  69. package/lib/domain/Call.js +3 -0
  70. package/lib/domain/CallLog.js +7 -0
  71. package/lib/domain/ChatMessage.js +4 -0
  72. package/lib/domain/ChatRoom.js +3 -0
  73. package/lib/domain/Contact.js +3 -0
  74. package/lib/domain/Features.js +36 -5
  75. package/lib/domain/Meeting.js +19 -5
  76. package/lib/domain/Phone/CTIPhone.js +40 -5
  77. package/lib/domain/Phone/WebRTCPhone.js +45 -16
  78. package/lib/domain/Recording.js +3 -0
  79. package/lib/domain/Voicemail.js +3 -0
  80. package/lib/domain/__tests__/Call.test.js +3 -0
  81. package/lib/domain/__tests__/CallLog.test.js +7 -0
  82. package/lib/domain/__tests__/Contact.test.js +3 -0
  83. package/lib/domain/__tests__/Meeting.test.js +150 -0
  84. package/lib/domain/__tests__/Voicemail.test.js +3 -0
  85. package/lib/index.js +125 -81
  86. package/lib/lib/WazoSessionDescriptionHandler.js +0 -38
  87. package/lib/service/CallApi.js +36 -5
  88. package/lib/service/getApiClient.js +36 -5
  89. package/lib/simple/Auth.js +125 -81
  90. package/lib/simple/Configuration.js +125 -81
  91. package/lib/simple/Directory.js +36 -5
  92. package/lib/simple/Phone.js +125 -81
  93. package/lib/simple/index.js +125 -81
  94. package/lib/simple/room/LocalParticipant.js +125 -81
  95. package/lib/simple/room/Participant.js +125 -81
  96. package/lib/simple/room/RemoteParticipant.js +125 -81
  97. package/lib/simple/room/Room.js +125 -81
  98. package/lib/simple/room/SipRoom.js +125 -81
  99. package/lib/simple/room/Stream.js +125 -81
  100. package/lib/simple/room/__tests__/RemoteParticipant.test.js +125 -81
  101. package/lib/simple/utils.js +125 -81
  102. package/lib/types/WebSocketMessage.js +2 -0
  103. package/lib/web-rtc-client.js +77 -66
  104. package/package.json +1 -1
  105. package/src/domain/Call.js +3 -0
  106. package/src/domain/CallLog.js +4 -0
  107. package/src/domain/ChatMessage.js +4 -0
  108. package/src/domain/ChatRoom.js +3 -0
  109. package/src/domain/Contact.js +3 -0
  110. package/src/domain/Meeting.js +15 -5
  111. package/src/domain/Phone/CTIPhone.js +4 -0
  112. package/src/domain/Phone/Phone.js +2 -0
  113. package/src/domain/Phone/WebRTCPhone.js +45 -16
  114. package/src/domain/Recording.js +3 -0
  115. package/src/domain/Voicemail.js +3 -0
  116. package/src/domain/__tests__/Meeting.test.js +50 -0
  117. package/src/lib/WazoSessionDescriptionHandler.js +1 -35
  118. package/src/web-rtc-client.js +41 -23
@@ -1559,6 +1559,9 @@ class Contact {
1559
1559
  }
1560
1560
 
1561
1561
  static parseMany(response ) {
1562
+ if (!response || !response.results) {
1563
+ return [];
1564
+ }
1562
1565
  return response.results.map(r => Contact.parse(r, response.column_types));
1563
1566
  }
1564
1567
 
@@ -2636,8 +2639,9 @@ class ExternalApp {
2636
2639
 
2637
2640
 
2638
2641
 
2639
-
2642
+
2640
2643
 
2644
+
2641
2645
 
2642
2646
 
2643
2647
  class Meeting {
@@ -2648,9 +2652,10 @@ class Meeting {
2648
2652
 
2649
2653
 
2650
2654
 
2651
-
2655
+
2652
2656
 
2653
2657
 
2658
+
2654
2659
 
2655
2660
  static parse(plain ) {
2656
2661
  return new Meeting({
@@ -2660,12 +2665,16 @@ class Meeting {
2660
2665
  ownerUuids: plain.owner_uuids,
2661
2666
  port: plain.port,
2662
2667
  uuid: plain.uuid,
2663
- number: plain.number,
2668
+ extension: plain.exten,
2664
2669
  persistent: plain.persistent,
2670
+ creationTime: moment__default['default'](plain.creation_time).toDate(),
2665
2671
  });
2666
2672
  }
2667
2673
 
2668
2674
  static parseMany(items ) {
2675
+ if (!items) {
2676
+ return [];
2677
+ }
2669
2678
  return items.map(plain => Meeting.parse(plain));
2670
2679
  }
2671
2680
 
@@ -2680,8 +2689,9 @@ class Meeting {
2680
2689
  ownerUuids,
2681
2690
  port,
2682
2691
  uri,
2683
- number,
2692
+ extension,
2684
2693
  persistent,
2694
+ creationTime,
2685
2695
  } = {}) {
2686
2696
  this.guestSipAuthorization = guestSipAuthorization;
2687
2697
  this.uri = uri;
@@ -2689,8 +2699,9 @@ class Meeting {
2689
2699
  this.ownerUuids = ownerUuids;
2690
2700
  this.port = port;
2691
2701
  this.uuid = uuid;
2692
- this.number = number;
2702
+ this.extension = extension;
2693
2703
  this.persistent = persistent;
2704
+ this.creationTime = creationTime;
2694
2705
 
2695
2706
  // Useful to compare instead of instanceof with minified code
2696
2707
  this.type = 'Meeting';
@@ -2868,6 +2879,10 @@ class ChatMessage {
2868
2879
 
2869
2880
 
2870
2881
  static parseMany(plain ) {
2882
+ if (!plain || !plain.items) {
2883
+ return [];
2884
+ }
2885
+
2871
2886
  return plain.items.map(item => ChatMessage.parse(item));
2872
2887
  }
2873
2888
 
@@ -2977,6 +2992,9 @@ class Voicemail {
2977
2992
  }
2978
2993
 
2979
2994
  static parseMany(plain ) {
2995
+ if (!plain) {
2996
+ return [];
2997
+ }
2980
2998
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
2981
2999
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
2982
3000
 
@@ -3086,6 +3104,9 @@ class Call {
3086
3104
 
3087
3105
 
3088
3106
  static parseMany(plain ) {
3107
+ if (!plain) {
3108
+ return [];
3109
+ }
3089
3110
  return plain.map((plainCall ) => Call.parse(plainCall));
3090
3111
  }
3091
3112
 
@@ -3284,6 +3305,9 @@ class Recording {
3284
3305
 
3285
3306
 
3286
3307
  static parseMany(recordings = []) {
3308
+ if (!recordings) {
3309
+ return [];
3310
+ }
3287
3311
  return recordings.map(item => Recording.parse(item));
3288
3312
  }
3289
3313
 
@@ -3385,6 +3409,10 @@ class CallLog {
3385
3409
  }
3386
3410
 
3387
3411
  static parseMany(plain ) {
3412
+ if (!plain || !plain.items) {
3413
+ return [];
3414
+ }
3415
+
3388
3416
  return plain.items.map(item => CallLog.parse(item));
3389
3417
  }
3390
3418
 
@@ -3957,6 +3985,9 @@ class ChatRoom {
3957
3985
 
3958
3986
 
3959
3987
  static parseMany(plain ) {
3988
+ if (!plain || !plain.items) {
3989
+ return [];
3990
+ }
3960
3991
  return plain.items.map(item => ChatRoom.parse(item));
3961
3992
  }
3962
3993
 
@@ -5359,10 +5390,6 @@ const getSrflxOrRelay = (candidates ) =>
5359
5390
  candidates
5360
5391
  .filter(candidate => candidate && (candidate.type === 'srflx' || candidate.type === 'relay'));
5361
5392
 
5362
- const areCandidateValid = (candidates ) =>
5363
- getSrflxOrRelay(candidates)
5364
- .length > 0;
5365
-
5366
5393
  const getVideoDirection = (sdp ) => {
5367
5394
  const parsedSdp = sdpParser__default['default'].parse(sdp);
5368
5395
  const videoMedia = parsedSdp.media.find(media => media.type === 'video');
@@ -5415,8 +5442,6 @@ const fixSdp = (sdp , candidates , forcePort = true)
5415
5442
  /* global RTCSessionDescriptionInit, navigator */
5416
5443
 
5417
5444
  const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
5418
- const MAX_WAIT_FOR_ICE_TRIES = 20;
5419
- const WAIT_FOR_ICE_TIMEOUT = 500;
5420
5445
 
5421
5446
  // Customized mediaStreamFactory allowing to send screensharing stream directory when upgrading
5422
5447
  const wazoMediaStreamFactory = (constraints ) => {
@@ -5606,38 +5631,6 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5606
5631
  this._peerConnection = undefined;
5607
5632
  }
5608
5633
 
5609
- async _waitForValidGatheredIce() {
5610
- let tries = 0;
5611
-
5612
- while (!areCandidateValid(this.gatheredCandidates) && tries < MAX_WAIT_FOR_ICE_TRIES) {
5613
- wazoLogger.trace('SessionDescriptionHandler._waitForValidGatheredIce, waiting for ice', {
5614
- tries,
5615
- max: MAX_WAIT_FOR_ICE_TRIES,
5616
- });
5617
-
5618
- tries++;
5619
-
5620
- // eslint-disable-next-line no-await-in-loop
5621
- await new Promise(resolve => setTimeout(resolve, WAIT_FOR_ICE_TIMEOUT));
5622
- }
5623
-
5624
- if (tries >= MAX_WAIT_FOR_ICE_TRIES) {
5625
- const errorMsg = 'No valid candidates found, can\'t answer the call';
5626
- const error = new Error(errorMsg);
5627
- wazoLogger.error(errorMsg, { tries, max: MAX_WAIT_FOR_ICE_TRIES });
5628
-
5629
- // Emit an error, because sip.js catches the exception and switch to status Terminated.
5630
- this.eventEmitter.emit('error', error);
5631
-
5632
- wazoLogger.error('No valid candidates found', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
5633
- }
5634
-
5635
- // eslint-disable-next-line
5636
- wazoLogger.trace('Found valid candidates', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
5637
-
5638
- return this.getLocalSessionDescription();
5639
- }
5640
-
5641
5634
  // Overridden to send `inactive` in conference
5642
5635
  updateDirection(options , isConference = false,
5643
5636
  audioOnly = false) {
@@ -6307,7 +6300,7 @@ class WebRTCClient extends Emitter {
6307
6300
  }
6308
6301
 
6309
6302
  call(number , enableVideo , audioOnly = false, conference = false) {
6310
- logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6303
+ logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
6311
6304
  const inviterOptions = {
6312
6305
  sessionDescriptionHandlerOptionsReInvite: {
6313
6306
  conference,
@@ -7383,6 +7376,7 @@ class WebRTCClient extends Emitter {
7383
7376
  const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
7384
7377
  const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
7385
7378
  const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
7379
+ const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
7386
7380
 
7387
7381
  logger.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
7388
7382
 
@@ -7390,7 +7384,8 @@ class WebRTCClient extends Emitter {
7390
7384
  constraints: {
7391
7385
  // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
7392
7386
  audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
7393
- video: screenSharing ? (isDesktop ? ({ mandatory: { chromeMediaSource: 'desktop' } }) : { cursor: 'always' })
7387
+ video: screenSharing ? (isDesktop
7388
+ ? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
7394
7389
  : this._getVideoConstraints(enableVideo),
7395
7390
  screen: screenSharing,
7396
7391
  desktop: isDesktop,
@@ -7725,11 +7720,14 @@ class WebRTCClient extends Emitter {
7725
7720
 
7726
7721
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
7727
7722
 
7728
- pc.oniceconnectionstatechange = () => {
7729
- if (pc.iceConnectionState === 'disconnected') {
7730
- this.eventEmitter.emit(ON_DISCONNECTED);
7731
- }
7732
- };
7723
+ if (pc) {
7724
+ pc.oniceconnectionstatechange = () => {
7725
+ logger.info('on ice connection state changed', { state: pc.iceConnectionState });
7726
+ if (pc.iceConnectionState === 'disconnected') {
7727
+ this.eventEmitter.emit(ON_DISCONNECTED);
7728
+ }
7729
+ };
7730
+ }
7733
7731
 
7734
7732
  if (withEvent) {
7735
7733
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
@@ -7939,13 +7937,17 @@ class WebRTCClient extends Emitter {
7939
7937
  const nbStats = this.sessionNetworkStats[sessionId].length;
7940
7938
  const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
7941
7939
  const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
7940
+ const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
7942
7941
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
7943
7942
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
7943
+ const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
7944
7944
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
7945
7945
  const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
7946
7946
  const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
7947
- let audioBytesSent = 0;
7948
- let audioBytesReceived = 0;
7947
+ let audioBytesSent = 0; // content + header
7948
+ let audioBytesReceived = 0; // content + header
7949
+ let audioContentSent = 0; // useful to detect blank call
7950
+ let audioContentReceived = 0;
7949
7951
  let videoBytesSent = 0;
7950
7952
  let videoBytesReceived = 0;
7951
7953
  let transportSent = 0;
@@ -7954,25 +7956,27 @@ class WebRTCClient extends Emitter {
7954
7956
 
7955
7957
  stats.forEach(report => {
7956
7958
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
7957
- audioBytesSent += report.bytesSent + report.headerBytesSent;
7959
+ audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
7960
+ audioContentSent += Number(report.bytesSent);
7958
7961
  }
7959
7962
  if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
7960
- audioBytesSent += report.bytesSent;
7963
+ audioBytesSent += Number(report.bytesSent);
7961
7964
  }
7962
7965
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7963
- videoBytesSent += report.bytesSent + report.headerBytesSent;
7966
+ videoBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
7964
7967
  }
7965
7968
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
7966
- packetsLost += report.packetsLost;
7967
- networkStats.packetsReceived = report.packetsReceived;
7968
- audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
7969
+ packetsLost += Number(report.packetsLost);
7970
+ networkStats.packetsReceived = Number(report.packetsReceived);
7971
+ audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
7972
+ audioContentReceived += Number(report.bytesReceived);
7969
7973
  }
7970
7974
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
7971
- videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
7975
+ videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
7972
7976
  }
7973
7977
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7974
7978
  if ('framesPerSecond' in report) {
7975
- networkStats.framesPerSecond = report.framesPerSecond;
7979
+ networkStats.framesPerSecond = Number(report.framesPerSecond);
7976
7980
  }
7977
7981
  if ('framerateMean' in report) {
7978
7982
  // framerateMean is only available in FF
@@ -7980,24 +7984,31 @@ class WebRTCClient extends Emitter {
7980
7984
  }
7981
7985
  }
7982
7986
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
7983
- packetsLost += report.packetsLost;
7984
- networkStats.roundTripTime = report.roundTripTime;
7985
- networkStats.jitter = report.jitter;
7987
+ packetsLost += Number(report.packetsLost);
7988
+ networkStats.roundTripTime = Number(report.roundTripTime);
7989
+ networkStats.jitter = Number(report.jitter);
7986
7990
  }
7987
7991
  if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
7988
- packetsLost += report.packetsLost;
7992
+ packetsLost += Number(report.packetsLost);
7989
7993
  }
7990
7994
  if (report.type === 'transport') {
7991
- transportSent += report.bytesSent;
7992
- transportReceived += report.bytesReceived;
7995
+ transportSent += Number(report.bytesSent);
7996
+ transportReceived += Number(report.bytesReceived);
7993
7997
  }
7994
7998
  });
7995
7999
 
7996
8000
  networkStats.packetsLost = packetsLost;
8001
+
7997
8002
  networkStats.totalAudioBytesSent = audioBytesSent;
7998
8003
  networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
7999
8004
  networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
8000
8005
  networkStats.audioBytesReceived = audioBytesReceived;
8006
+
8007
+ networkStats.totalAudioContentSent = audioContentSent;
8008
+ networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
8009
+ networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
8010
+ networkStats.audioContentReceived = audioContentReceived;
8011
+
8001
8012
  networkStats.totalVideoBytesSent = videoBytesSent;
8002
8013
  networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
8003
8014
  networkStats.totalVideoBytesReceived = videoBytesReceived;
@@ -733,10 +733,6 @@ const getSrflxOrRelay = (candidates ) =>
733
733
  candidates
734
734
  .filter(candidate => candidate && (candidate.type === 'srflx' || candidate.type === 'relay'));
735
735
 
736
- const areCandidateValid = (candidates ) =>
737
- getSrflxOrRelay(candidates)
738
- .length > 0;
739
-
740
736
  const getVideoDirection = (sdp ) => {
741
737
  const parsedSdp = sdpParser__default['default'].parse(sdp);
742
738
  const videoMedia = parsedSdp.media.find(media => media.type === 'video');
@@ -789,8 +785,6 @@ const fixSdp = (sdp , candidates , forcePort = true)
789
785
  /* global RTCSessionDescriptionInit, navigator */
790
786
 
791
787
  const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
792
- const MAX_WAIT_FOR_ICE_TRIES = 20;
793
- const WAIT_FOR_ICE_TIMEOUT = 500;
794
788
 
795
789
  // Customized mediaStreamFactory allowing to send screensharing stream directory when upgrading
796
790
  const wazoMediaStreamFactory = (constraints ) => {
@@ -980,38 +974,6 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
980
974
  this._peerConnection = undefined;
981
975
  }
982
976
 
983
- async _waitForValidGatheredIce() {
984
- let tries = 0;
985
-
986
- while (!areCandidateValid(this.gatheredCandidates) && tries < MAX_WAIT_FOR_ICE_TRIES) {
987
- wazoLogger.trace('SessionDescriptionHandler._waitForValidGatheredIce, waiting for ice', {
988
- tries,
989
- max: MAX_WAIT_FOR_ICE_TRIES,
990
- });
991
-
992
- tries++;
993
-
994
- // eslint-disable-next-line no-await-in-loop
995
- await new Promise(resolve => setTimeout(resolve, WAIT_FOR_ICE_TIMEOUT));
996
- }
997
-
998
- if (tries >= MAX_WAIT_FOR_ICE_TRIES) {
999
- const errorMsg = 'No valid candidates found, can\'t answer the call';
1000
- const error = new Error(errorMsg);
1001
- wazoLogger.error(errorMsg, { tries, max: MAX_WAIT_FOR_ICE_TRIES });
1002
-
1003
- // Emit an error, because sip.js catches the exception and switch to status Terminated.
1004
- this.eventEmitter.emit('error', error);
1005
-
1006
- wazoLogger.error('No valid candidates found', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
1007
- }
1008
-
1009
- // eslint-disable-next-line
1010
- wazoLogger.trace('Found valid candidates', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
1011
-
1012
- return this.getLocalSessionDescription();
1013
- }
1014
-
1015
977
  // Overridden to send `inactive` in conference
1016
978
  updateDirection(options , isConference = false,
1017
979
  audioOnly = false) {
@@ -2121,6 +2083,9 @@ class Contact {
2121
2083
  }
2122
2084
 
2123
2085
  static parseMany(response ) {
2086
+ if (!response || !response.results) {
2087
+ return [];
2088
+ }
2124
2089
  return response.results.map(r => Contact.parse(r, response.column_types));
2125
2090
  }
2126
2091
 
@@ -3198,8 +3163,9 @@ class ExternalApp {
3198
3163
 
3199
3164
 
3200
3165
 
3201
-
3166
+
3202
3167
 
3168
+
3203
3169
 
3204
3170
 
3205
3171
  class Meeting {
@@ -3210,9 +3176,10 @@ class Meeting {
3210
3176
 
3211
3177
 
3212
3178
 
3213
-
3179
+
3214
3180
 
3215
3181
 
3182
+
3216
3183
 
3217
3184
  static parse(plain ) {
3218
3185
  return new Meeting({
@@ -3222,12 +3189,16 @@ class Meeting {
3222
3189
  ownerUuids: plain.owner_uuids,
3223
3190
  port: plain.port,
3224
3191
  uuid: plain.uuid,
3225
- number: plain.number,
3192
+ extension: plain.exten,
3226
3193
  persistent: plain.persistent,
3194
+ creationTime: moment__default['default'](plain.creation_time).toDate(),
3227
3195
  });
3228
3196
  }
3229
3197
 
3230
3198
  static parseMany(items ) {
3199
+ if (!items) {
3200
+ return [];
3201
+ }
3231
3202
  return items.map(plain => Meeting.parse(plain));
3232
3203
  }
3233
3204
 
@@ -3242,8 +3213,9 @@ class Meeting {
3242
3213
  ownerUuids,
3243
3214
  port,
3244
3215
  uri,
3245
- number,
3216
+ extension,
3246
3217
  persistent,
3218
+ creationTime,
3247
3219
  } = {}) {
3248
3220
  this.guestSipAuthorization = guestSipAuthorization;
3249
3221
  this.uri = uri;
@@ -3251,8 +3223,9 @@ class Meeting {
3251
3223
  this.ownerUuids = ownerUuids;
3252
3224
  this.port = port;
3253
3225
  this.uuid = uuid;
3254
- this.number = number;
3226
+ this.extension = extension;
3255
3227
  this.persistent = persistent;
3228
+ this.creationTime = creationTime;
3256
3229
 
3257
3230
  // Useful to compare instead of instanceof with minified code
3258
3231
  this.type = 'Meeting';
@@ -3430,6 +3403,10 @@ class ChatMessage {
3430
3403
 
3431
3404
 
3432
3405
  static parseMany(plain ) {
3406
+ if (!plain || !plain.items) {
3407
+ return [];
3408
+ }
3409
+
3433
3410
  return plain.items.map(item => ChatMessage.parse(item));
3434
3411
  }
3435
3412
 
@@ -3539,6 +3516,9 @@ class Voicemail {
3539
3516
  }
3540
3517
 
3541
3518
  static parseMany(plain ) {
3519
+ if (!plain) {
3520
+ return [];
3521
+ }
3542
3522
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
3543
3523
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
3544
3524
 
@@ -3648,6 +3628,9 @@ class Call {
3648
3628
 
3649
3629
 
3650
3630
  static parseMany(plain ) {
3631
+ if (!plain) {
3632
+ return [];
3633
+ }
3651
3634
  return plain.map((plainCall ) => Call.parse(plainCall));
3652
3635
  }
3653
3636
 
@@ -3820,6 +3803,9 @@ class Recording {
3820
3803
 
3821
3804
 
3822
3805
  static parseMany(recordings = []) {
3806
+ if (!recordings) {
3807
+ return [];
3808
+ }
3823
3809
  return recordings.map(item => Recording.parse(item));
3824
3810
  }
3825
3811
 
@@ -3921,6 +3907,10 @@ class CallLog {
3921
3907
  }
3922
3908
 
3923
3909
  static parseMany(plain ) {
3910
+ if (!plain || !plain.items) {
3911
+ return [];
3912
+ }
3913
+
3924
3914
  return plain.items.map(item => CallLog.parse(item));
3925
3915
  }
3926
3916
 
@@ -4493,6 +4483,9 @@ class ChatRoom {
4493
4483
 
4494
4484
 
4495
4485
  static parseMany(plain ) {
4486
+ if (!plain || !plain.items) {
4487
+ return [];
4488
+ }
4496
4489
  return plain.items.map(item => ChatRoom.parse(item));
4497
4490
  }
4498
4491
 
@@ -5721,7 +5714,7 @@ class WebRTCClient extends Emitter {
5721
5714
  }
5722
5715
 
5723
5716
  call(number , enableVideo , audioOnly = false, conference = false) {
5724
- logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
5717
+ logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
5725
5718
  const inviterOptions = {
5726
5719
  sessionDescriptionHandlerOptionsReInvite: {
5727
5720
  conference,
@@ -6797,6 +6790,7 @@ class WebRTCClient extends Emitter {
6797
6790
  const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
6798
6791
  const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
6799
6792
  const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
6793
+ const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
6800
6794
 
6801
6795
  logger.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
6802
6796
 
@@ -6804,7 +6798,8 @@ class WebRTCClient extends Emitter {
6804
6798
  constraints: {
6805
6799
  // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
6806
6800
  audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
6807
- video: screenSharing ? (isDesktop ? ({ mandatory: { chromeMediaSource: 'desktop' } }) : { cursor: 'always' })
6801
+ video: screenSharing ? (isDesktop
6802
+ ? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
6808
6803
  : this._getVideoConstraints(enableVideo),
6809
6804
  screen: screenSharing,
6810
6805
  desktop: isDesktop,
@@ -7139,11 +7134,14 @@ class WebRTCClient extends Emitter {
7139
7134
 
7140
7135
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
7141
7136
 
7142
- pc.oniceconnectionstatechange = () => {
7143
- if (pc.iceConnectionState === 'disconnected') {
7144
- this.eventEmitter.emit(ON_DISCONNECTED);
7145
- }
7146
- };
7137
+ if (pc) {
7138
+ pc.oniceconnectionstatechange = () => {
7139
+ logger.info('on ice connection state changed', { state: pc.iceConnectionState });
7140
+ if (pc.iceConnectionState === 'disconnected') {
7141
+ this.eventEmitter.emit(ON_DISCONNECTED);
7142
+ }
7143
+ };
7144
+ }
7147
7145
 
7148
7146
  if (withEvent) {
7149
7147
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
@@ -7353,13 +7351,17 @@ class WebRTCClient extends Emitter {
7353
7351
  const nbStats = this.sessionNetworkStats[sessionId].length;
7354
7352
  const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
7355
7353
  const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
7354
+ const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
7356
7355
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
7357
7356
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
7357
+ const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
7358
7358
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
7359
7359
  const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
7360
7360
  const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
7361
- let audioBytesSent = 0;
7362
- let audioBytesReceived = 0;
7361
+ let audioBytesSent = 0; // content + header
7362
+ let audioBytesReceived = 0; // content + header
7363
+ let audioContentSent = 0; // useful to detect blank call
7364
+ let audioContentReceived = 0;
7363
7365
  let videoBytesSent = 0;
7364
7366
  let videoBytesReceived = 0;
7365
7367
  let transportSent = 0;
@@ -7368,25 +7370,27 @@ class WebRTCClient extends Emitter {
7368
7370
 
7369
7371
  stats.forEach(report => {
7370
7372
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
7371
- audioBytesSent += report.bytesSent + report.headerBytesSent;
7373
+ audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
7374
+ audioContentSent += Number(report.bytesSent);
7372
7375
  }
7373
7376
  if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
7374
- audioBytesSent += report.bytesSent;
7377
+ audioBytesSent += Number(report.bytesSent);
7375
7378
  }
7376
7379
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7377
- videoBytesSent += report.bytesSent + report.headerBytesSent;
7380
+ videoBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
7378
7381
  }
7379
7382
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
7380
- packetsLost += report.packetsLost;
7381
- networkStats.packetsReceived = report.packetsReceived;
7382
- audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
7383
+ packetsLost += Number(report.packetsLost);
7384
+ networkStats.packetsReceived = Number(report.packetsReceived);
7385
+ audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
7386
+ audioContentReceived += Number(report.bytesReceived);
7383
7387
  }
7384
7388
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
7385
- videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
7389
+ videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
7386
7390
  }
7387
7391
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7388
7392
  if ('framesPerSecond' in report) {
7389
- networkStats.framesPerSecond = report.framesPerSecond;
7393
+ networkStats.framesPerSecond = Number(report.framesPerSecond);
7390
7394
  }
7391
7395
  if ('framerateMean' in report) {
7392
7396
  // framerateMean is only available in FF
@@ -7394,24 +7398,31 @@ class WebRTCClient extends Emitter {
7394
7398
  }
7395
7399
  }
7396
7400
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
7397
- packetsLost += report.packetsLost;
7398
- networkStats.roundTripTime = report.roundTripTime;
7399
- networkStats.jitter = report.jitter;
7401
+ packetsLost += Number(report.packetsLost);
7402
+ networkStats.roundTripTime = Number(report.roundTripTime);
7403
+ networkStats.jitter = Number(report.jitter);
7400
7404
  }
7401
7405
  if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
7402
- packetsLost += report.packetsLost;
7406
+ packetsLost += Number(report.packetsLost);
7403
7407
  }
7404
7408
  if (report.type === 'transport') {
7405
- transportSent += report.bytesSent;
7406
- transportReceived += report.bytesReceived;
7409
+ transportSent += Number(report.bytesSent);
7410
+ transportReceived += Number(report.bytesReceived);
7407
7411
  }
7408
7412
  });
7409
7413
 
7410
7414
  networkStats.packetsLost = packetsLost;
7415
+
7411
7416
  networkStats.totalAudioBytesSent = audioBytesSent;
7412
7417
  networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
7413
7418
  networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
7414
7419
  networkStats.audioBytesReceived = audioBytesReceived;
7420
+
7421
+ networkStats.totalAudioContentSent = audioContentSent;
7422
+ networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
7423
+ networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
7424
+ networkStats.audioContentReceived = audioContentReceived;
7425
+
7415
7426
  networkStats.totalVideoBytesSent = videoBytesSent;
7416
7427
  networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
7417
7428
  networkStats.totalVideoBytesReceived = videoBytesReceived;