@wazo/sdk 0.37.23 → 0.37.27

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/README.md +95 -57
  2. package/dist/wazo-sdk.js +3 -3
  3. package/esm/__tests__/api-client.test.js +12 -7
  4. package/esm/__tests__/web-rtc-client.test.js +47 -20
  5. package/esm/api/agentd.js +1 -1
  6. package/esm/api/amid.js +1 -1
  7. package/esm/api/application.js +1 -1
  8. package/esm/api/auth.js +1 -1
  9. package/esm/api/call-logd.js +1 -1
  10. package/esm/api/calld.js +1 -1
  11. package/esm/api/chatd.js +1 -1
  12. package/esm/api/confd.js +11 -6
  13. package/esm/api/ctid-ng.js +1 -1
  14. package/esm/api/dird.js +2 -2
  15. package/esm/api/webhookd.js +1 -1
  16. package/esm/api-client.js +12 -7
  17. package/esm/checker/Checker.js +47 -20
  18. package/esm/checker/checks/aor.js +12 -7
  19. package/esm/checker/checks/api.js +12 -7
  20. package/esm/checker/checks/index.js +47 -20
  21. package/esm/checker/checks/wazo-websocket.js +1 -1
  22. package/esm/checker/checks/webrtc-transport.js +47 -20
  23. package/esm/checker/checks/webrtc.js +47 -20
  24. package/esm/domain/AdHocAPIConference.js +12 -7
  25. package/esm/domain/Contact.js +1 -1
  26. package/esm/domain/Features.js +12 -7
  27. package/esm/domain/Meeting.js +12 -5
  28. package/esm/domain/Phone/CTIPhone.js +12 -7
  29. package/esm/domain/Phone/WebRTCPhone.js +34 -6
  30. package/esm/domain/__tests__/Contact.test.js +1 -1
  31. package/esm/domain/__tests__/Meeting.test.js +144 -0
  32. package/esm/index.js +80 -25
  33. package/esm/lib/WazoSessionDescriptionHandler.js +9 -4
  34. package/esm/service/CallApi.js +12 -7
  35. package/esm/service/IssueReporter.js +1 -1
  36. package/esm/service/__tests__/IssueReporter.test.js +1 -1
  37. package/esm/service/getApiClient.js +12 -7
  38. package/esm/simple/Auth.js +80 -25
  39. package/esm/simple/Configuration.js +80 -25
  40. package/esm/simple/Directory.js +12 -7
  41. package/esm/simple/Phone.js +80 -25
  42. package/esm/simple/Websocket.js +1 -1
  43. package/esm/simple/index.js +80 -25
  44. package/esm/simple/room/LocalParticipant.js +80 -25
  45. package/esm/simple/room/Participant.js +80 -25
  46. package/esm/simple/room/RemoteParticipant.js +80 -25
  47. package/esm/simple/room/Room.js +80 -25
  48. package/esm/simple/room/SipRoom.js +80 -25
  49. package/esm/simple/room/Stream.js +80 -25
  50. package/esm/simple/room/__tests__/RemoteParticipant.test.js +80 -25
  51. package/esm/simple/utils.js +80 -25
  52. package/esm/types/WebSocketMessage.js +1 -1
  53. package/esm/utils/__tests__/api-requester.test.js +1 -1
  54. package/esm/utils/api-requester.js +1 -1
  55. package/esm/web-rtc-client.js +47 -20
  56. package/esm/websocket-client.js +1 -1
  57. package/lib/__tests__/api-client.test.js +12 -7
  58. package/lib/__tests__/web-rtc-client.test.js +47 -20
  59. package/lib/api/agentd.js +1 -1
  60. package/lib/api/amid.js +1 -1
  61. package/lib/api/application.js +1 -1
  62. package/lib/api/auth.js +1 -1
  63. package/lib/api/call-logd.js +1 -1
  64. package/lib/api/calld.js +1 -1
  65. package/lib/api/chatd.js +1 -1
  66. package/lib/api/confd.js +11 -6
  67. package/lib/api/ctid-ng.js +1 -1
  68. package/lib/api/dird.js +2 -2
  69. package/lib/api/webhookd.js +1 -1
  70. package/lib/api-client.js +12 -7
  71. package/lib/checker/Checker.js +47 -20
  72. package/lib/checker/checks/aor.js +12 -7
  73. package/lib/checker/checks/api.js +12 -7
  74. package/lib/checker/checks/index.js +47 -20
  75. package/lib/checker/checks/wazo-websocket.js +1 -1
  76. package/lib/checker/checks/webrtc-transport.js +47 -20
  77. package/lib/checker/checks/webrtc.js +47 -20
  78. package/lib/domain/AdHocAPIConference.js +12 -7
  79. package/lib/domain/Contact.js +1 -1
  80. package/lib/domain/Features.js +12 -7
  81. package/lib/domain/Meeting.js +16 -5
  82. package/lib/domain/Phone/CTIPhone.js +12 -7
  83. package/lib/domain/Phone/WebRTCPhone.js +34 -6
  84. package/lib/domain/__tests__/Contact.test.js +1 -1
  85. package/lib/domain/__tests__/Meeting.test.js +150 -0
  86. package/lib/index.js +80 -25
  87. package/lib/lib/WazoSessionDescriptionHandler.js +9 -4
  88. package/lib/service/CallApi.js +12 -7
  89. package/lib/service/IssueReporter.js +1 -1
  90. package/lib/service/__tests__/IssueReporter.test.js +1 -1
  91. package/lib/service/getApiClient.js +12 -7
  92. package/lib/simple/Auth.js +80 -25
  93. package/lib/simple/Configuration.js +80 -25
  94. package/lib/simple/Directory.js +12 -7
  95. package/lib/simple/Phone.js +80 -25
  96. package/lib/simple/Websocket.js +1 -1
  97. package/lib/simple/index.js +80 -25
  98. package/lib/simple/room/LocalParticipant.js +80 -25
  99. package/lib/simple/room/Participant.js +80 -25
  100. package/lib/simple/room/RemoteParticipant.js +80 -25
  101. package/lib/simple/room/Room.js +80 -25
  102. package/lib/simple/room/SipRoom.js +80 -25
  103. package/lib/simple/room/Stream.js +80 -25
  104. package/lib/simple/room/__tests__/RemoteParticipant.test.js +80 -25
  105. package/lib/simple/utils.js +80 -25
  106. package/lib/types/WebSocketMessage.js +2 -0
  107. package/lib/utils/__tests__/api-requester.test.js +1 -1
  108. package/lib/utils/api-requester.js +1 -1
  109. package/lib/web-rtc-client.js +47 -20
  110. package/lib/websocket-client.js +1 -1
  111. package/package.json +1 -1
  112. package/src/domain/Contact.js +1 -1
  113. package/src/domain/Meeting.js +12 -5
  114. package/src/domain/Phone/WebRTCPhone.js +33 -5
  115. package/src/domain/__tests__/Meeting.test.js +50 -0
  116. package/src/lib/WazoSessionDescriptionHandler.js +8 -3
  117. package/src/utils/api-requester.js +1 -1
  118. package/src/web-rtc-client.js +27 -10
@@ -142,7 +142,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
142
142
 
143
143
  // Use a function here to be able to mock it in tests
144
144
  const realFetch = () => {
145
- if (typeof document !== 'undefined') {
145
+ if (typeof document !== 'undefined' && window.fetch) {
146
146
  // Browser
147
147
  return window.fetch;
148
148
  }
@@ -1959,7 +1959,7 @@ class Contact {
1959
1959
  this[key] = old[key] || this[key];
1960
1960
  });
1961
1961
 
1962
- if (old.lineState && !this.lineState) {
1962
+ if (old.lineState) {
1963
1963
  this.lineState = old.lineState;
1964
1964
  }
1965
1965
 
@@ -2666,8 +2666,9 @@ class ExternalApp {
2666
2666
 
2667
2667
 
2668
2668
 
2669
-
2669
+
2670
2670
 
2671
+
2671
2672
 
2672
2673
 
2673
2674
  class Meeting {
@@ -2678,9 +2679,10 @@ class Meeting {
2678
2679
 
2679
2680
 
2680
2681
 
2681
-
2682
+
2682
2683
 
2683
2684
 
2685
+
2684
2686
 
2685
2687
  static parse(plain ) {
2686
2688
  return new Meeting({
@@ -2690,8 +2692,9 @@ class Meeting {
2690
2692
  ownerUuids: plain.owner_uuids,
2691
2693
  port: plain.port,
2692
2694
  uuid: plain.uuid,
2693
- number: plain.number,
2695
+ extension: plain.exten,
2694
2696
  persistent: plain.persistent,
2697
+ creationTime: moment__default['default'](plain.creation_time).toDate(),
2695
2698
  });
2696
2699
  }
2697
2700
 
@@ -2713,8 +2716,9 @@ class Meeting {
2713
2716
  ownerUuids,
2714
2717
  port,
2715
2718
  uri,
2716
- number,
2719
+ extension,
2717
2720
  persistent,
2721
+ creationTime,
2718
2722
  } = {}) {
2719
2723
  this.guestSipAuthorization = guestSipAuthorization;
2720
2724
  this.uri = uri;
@@ -2722,8 +2726,9 @@ class Meeting {
2722
2726
  this.ownerUuids = ownerUuids;
2723
2727
  this.port = port;
2724
2728
  this.uuid = uuid;
2725
- this.number = number;
2729
+ this.extension = extension;
2726
2730
  this.persistent = persistent;
2731
+ this.creationTime = creationTime;
2727
2732
 
2728
2733
  // Useful to compare instead of instanceof with minified code
2729
2734
  this.type = 'Meeting';
@@ -6067,11 +6072,16 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
6067
6072
 
6068
6073
  // $FlowFixMe
6069
6074
  setRemoteSessionDescription(sessionDescription ) {
6070
- const result = super.setRemoteSessionDescription(sessionDescription);
6075
+ try {
6076
+ const result = super.setRemoteSessionDescription(sessionDescription);
6071
6077
 
6072
- this.eventEmitter.emit('setDescription', sessionDescription);
6078
+ this.eventEmitter.emit('setDescription', sessionDescription);
6073
6079
 
6074
- return result;
6080
+ return result;
6081
+ } catch (error) {
6082
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
6083
+ throw error;
6084
+ }
6075
6085
  }
6076
6086
 
6077
6087
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -6976,7 +6986,7 @@ class WebRTCClient extends Emitter {
6976
6986
  }
6977
6987
 
6978
6988
  call(number , enableVideo , audioOnly = false, conference = false) {
6979
- logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6989
+ logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
6980
6990
  const inviterOptions = {
6981
6991
  sessionDescriptionHandlerOptionsReInvite: {
6982
6992
  conference,
@@ -8052,6 +8062,7 @@ class WebRTCClient extends Emitter {
8052
8062
  const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
8053
8063
  const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
8054
8064
  const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
8065
+ const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
8055
8066
 
8056
8067
  logger$8.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
8057
8068
 
@@ -8059,7 +8070,8 @@ class WebRTCClient extends Emitter {
8059
8070
  constraints: {
8060
8071
  // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
8061
8072
  audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
8062
- video: screenSharing ? (isDesktop ? ({ mandatory: { chromeMediaSource: 'desktop' } }) : { cursor: 'always' })
8073
+ video: screenSharing ? (isDesktop
8074
+ ? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
8063
8075
  : this._getVideoConstraints(enableVideo),
8064
8076
  screen: screenSharing,
8065
8077
  desktop: isDesktop,
@@ -8394,12 +8406,14 @@ class WebRTCClient extends Emitter {
8394
8406
 
8395
8407
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
8396
8408
 
8397
- pc.oniceconnectionstatechange = () => {
8398
- logger$8.info('on ice connection state changed', { state: pc.iceConnectionState });
8399
- if (pc.iceConnectionState === 'disconnected') {
8400
- this.eventEmitter.emit(ON_DISCONNECTED$1);
8401
- }
8402
- };
8409
+ if (pc) {
8410
+ pc.oniceconnectionstatechange = () => {
8411
+ logger$8.info('on ice connection state changed', { state: pc.iceConnectionState });
8412
+ if (pc.iceConnectionState === 'disconnected') {
8413
+ this.eventEmitter.emit(ON_DISCONNECTED$1);
8414
+ }
8415
+ };
8416
+ }
8403
8417
 
8404
8418
  if (withEvent) {
8405
8419
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
@@ -8609,13 +8623,17 @@ class WebRTCClient extends Emitter {
8609
8623
  const nbStats = this.sessionNetworkStats[sessionId].length;
8610
8624
  const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
8611
8625
  const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
8626
+ const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
8612
8627
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8613
8628
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8629
+ const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
8614
8630
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8615
8631
  const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8616
8632
  const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8617
- let audioBytesSent = 0;
8618
- let audioBytesReceived = 0;
8633
+ let audioBytesSent = 0; // content + header
8634
+ let audioBytesReceived = 0; // content + header
8635
+ let audioContentSent = 0; // useful to detect blank call
8636
+ let audioContentReceived = 0;
8619
8637
  let videoBytesSent = 0;
8620
8638
  let videoBytesReceived = 0;
8621
8639
  let transportSent = 0;
@@ -8625,6 +8643,7 @@ class WebRTCClient extends Emitter {
8625
8643
  stats.forEach(report => {
8626
8644
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
8627
8645
  audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
8646
+ audioContentSent += Number(report.bytesSent);
8628
8647
  }
8629
8648
  if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
8630
8649
  audioBytesSent += Number(report.bytesSent);
@@ -8636,6 +8655,7 @@ class WebRTCClient extends Emitter {
8636
8655
  packetsLost += Number(report.packetsLost);
8637
8656
  networkStats.packetsReceived = Number(report.packetsReceived);
8638
8657
  audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
8658
+ audioContentReceived += Number(report.bytesReceived);
8639
8659
  }
8640
8660
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
8641
8661
  videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
@@ -8664,10 +8684,17 @@ class WebRTCClient extends Emitter {
8664
8684
  });
8665
8685
 
8666
8686
  networkStats.packetsLost = packetsLost;
8687
+
8667
8688
  networkStats.totalAudioBytesSent = audioBytesSent;
8668
8689
  networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
8669
8690
  networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
8670
8691
  networkStats.audioBytesReceived = audioBytesReceived;
8692
+
8693
+ networkStats.totalAudioContentSent = audioContentSent;
8694
+ networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
8695
+ networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
8696
+ networkStats.audioContentReceived = audioContentReceived;
8697
+
8671
8698
  networkStats.totalVideoBytesSent = videoBytesSent;
8672
8699
  networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
8673
8700
  networkStats.totalVideoBytesReceived = videoBytesReceived;
@@ -8879,6 +8906,7 @@ class WebRTCPhone extends Emitter {
8879
8906
  constraints,
8880
8907
  audioOnly,
8881
8908
  conference,
8909
+ iceRestart,
8882
8910
  });
8883
8911
 
8884
8912
  if (!sipSession) {
@@ -8982,6 +9010,11 @@ class WebRTCPhone extends Emitter {
8982
9010
 
8983
9011
  this.client.downgradeToAudio(sipSession);
8984
9012
 
9013
+ if (callSession) {
9014
+ callSession.cameraEnabled = false;
9015
+ this._updateCallSession(callSession);
9016
+ }
9017
+
8985
9018
  if (withMessage) {
8986
9019
  this._sendReinviteMessage(callSession, false);
8987
9020
  }
@@ -9009,6 +9042,11 @@ class WebRTCPhone extends Emitter {
9009
9042
 
9010
9043
  const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
9011
9044
 
9045
+ if (callSession) {
9046
+ callSession.cameraEnabled = true;
9047
+ this._updateCallSession(callSession);
9048
+ }
9049
+
9012
9050
  // If no stream is returned, it means we have to reinvite
9013
9051
  if (!newStream) {
9014
9052
  return true;
@@ -9278,7 +9316,7 @@ class WebRTCPhone extends Emitter {
9278
9316
  }
9279
9317
 
9280
9318
  _onCallAccepted(sipSession , cameraEnabled ) {
9281
- logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9319
+ logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9282
9320
 
9283
9321
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
9284
9322
  this.currentSipSession = sipSession;
@@ -9347,6 +9385,7 @@ class WebRTCPhone extends Emitter {
9347
9385
  _onCallTerminated(sipSession ) {
9348
9386
  logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9349
9387
 
9388
+ const sipSessionId = this.getSipSessionId(sipSession);
9350
9389
  const callSession = this._createCallSession(sipSession);
9351
9390
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9352
9391
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9364,7 +9403,6 @@ class WebRTCPhone extends Emitter {
9364
9403
  }, 5);
9365
9404
  }
9366
9405
 
9367
- const sipSessionId = this.getSipSessionId(sipSession);
9368
9406
  if (sipSessionId) {
9369
9407
  this.removeIncomingSessions(sipSessionId);
9370
9408
  }
@@ -9790,7 +9828,7 @@ class WebRTCPhone extends Emitter {
9790
9828
  // @TODO: line is not used here
9791
9829
  async makeCall(number , line , cameraEnabled ,
9792
9830
  audioOnly = false, conference = false) {
9793
- logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9831
+ logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled, audioOnly, conference });
9794
9832
  if (!number) {
9795
9833
  return Promise.resolve(null);
9796
9834
  }
@@ -10009,8 +10047,12 @@ class WebRTCPhone extends Emitter {
10009
10047
  }
10010
10048
 
10011
10049
  const sessionId = this.incomingSessions[0];
10050
+ const sipSession = this.client.getSipSession(sessionId);
10051
+ if (!sipSession) {
10052
+ return null;
10053
+ }
10012
10054
 
10013
- return this._createCallSession(this.client.getSipSession(sessionId));
10055
+ return this._createCallSession(sipSession);
10014
10056
  }
10015
10057
 
10016
10058
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -10151,9 +10193,13 @@ class WebRTCPhone extends Emitter {
10151
10193
  if (this.shouldSendReinvite && this.currentSipSession
10152
10194
  && this.currentSipSession.state === sessionState.SessionState.Established) {
10153
10195
  this.shouldSendReinvite = false;
10196
+ const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
10197
+ const isConference = pc ? pc.sfu : false;
10198
+ const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
10199
+
10154
10200
  try {
10155
10201
  // Send reinvite with iceRestart
10156
- this.sendReinvite(this.currentCallSession, null, false, false, true);
10202
+ this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
10157
10203
  } catch (e) {
10158
10204
  logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
10159
10205
  }
@@ -10237,6 +10283,15 @@ class WebRTCPhone extends Emitter {
10237
10283
  return this.client.getSipSessionId(sipSession);
10238
10284
  }
10239
10285
 
10286
+ _updateCallSession(callSession ) {
10287
+ const sipSession = this.findSipSession(callSession);
10288
+ const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
10289
+
10290
+ if (sipSessionId) {
10291
+ this.callSessions[sipSessionId] = callSession;
10292
+ }
10293
+ }
10294
+
10240
10295
  _onMessage(message ) {
10241
10296
  if (!message || message.method !== 'MESSAGE') {
10242
10297
  return;
@@ -142,7 +142,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
142
142
 
143
143
  // Use a function here to be able to mock it in tests
144
144
  const realFetch = () => {
145
- if (typeof document !== 'undefined') {
145
+ if (typeof document !== 'undefined' && window.fetch) {
146
146
  // Browser
147
147
  return window.fetch;
148
148
  }
@@ -1959,7 +1959,7 @@ class Contact {
1959
1959
  this[key] = old[key] || this[key];
1960
1960
  });
1961
1961
 
1962
- if (old.lineState && !this.lineState) {
1962
+ if (old.lineState) {
1963
1963
  this.lineState = old.lineState;
1964
1964
  }
1965
1965
 
@@ -2666,8 +2666,9 @@ class ExternalApp {
2666
2666
 
2667
2667
 
2668
2668
 
2669
-
2669
+
2670
2670
 
2671
+
2671
2672
 
2672
2673
 
2673
2674
  class Meeting {
@@ -2678,9 +2679,10 @@ class Meeting {
2678
2679
 
2679
2680
 
2680
2681
 
2681
-
2682
+
2682
2683
 
2683
2684
 
2685
+
2684
2686
 
2685
2687
  static parse(plain ) {
2686
2688
  return new Meeting({
@@ -2690,8 +2692,9 @@ class Meeting {
2690
2692
  ownerUuids: plain.owner_uuids,
2691
2693
  port: plain.port,
2692
2694
  uuid: plain.uuid,
2693
- number: plain.number,
2695
+ extension: plain.exten,
2694
2696
  persistent: plain.persistent,
2697
+ creationTime: moment__default['default'](plain.creation_time).toDate(),
2695
2698
  });
2696
2699
  }
2697
2700
 
@@ -2713,8 +2716,9 @@ class Meeting {
2713
2716
  ownerUuids,
2714
2717
  port,
2715
2718
  uri,
2716
- number,
2719
+ extension,
2717
2720
  persistent,
2721
+ creationTime,
2718
2722
  } = {}) {
2719
2723
  this.guestSipAuthorization = guestSipAuthorization;
2720
2724
  this.uri = uri;
@@ -2722,8 +2726,9 @@ class Meeting {
2722
2726
  this.ownerUuids = ownerUuids;
2723
2727
  this.port = port;
2724
2728
  this.uuid = uuid;
2725
- this.number = number;
2729
+ this.extension = extension;
2726
2730
  this.persistent = persistent;
2731
+ this.creationTime = creationTime;
2727
2732
 
2728
2733
  // Useful to compare instead of instanceof with minified code
2729
2734
  this.type = 'Meeting';
@@ -6067,11 +6072,16 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
6067
6072
 
6068
6073
  // $FlowFixMe
6069
6074
  setRemoteSessionDescription(sessionDescription ) {
6070
- const result = super.setRemoteSessionDescription(sessionDescription);
6075
+ try {
6076
+ const result = super.setRemoteSessionDescription(sessionDescription);
6071
6077
 
6072
- this.eventEmitter.emit('setDescription', sessionDescription);
6078
+ this.eventEmitter.emit('setDescription', sessionDescription);
6073
6079
 
6074
- return result;
6080
+ return result;
6081
+ } catch (error) {
6082
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
6083
+ throw error;
6084
+ }
6075
6085
  }
6076
6086
 
6077
6087
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -6976,7 +6986,7 @@ class WebRTCClient extends Emitter {
6976
6986
  }
6977
6987
 
6978
6988
  call(number , enableVideo , audioOnly = false, conference = false) {
6979
- logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6989
+ logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
6980
6990
  const inviterOptions = {
6981
6991
  sessionDescriptionHandlerOptionsReInvite: {
6982
6992
  conference,
@@ -8052,6 +8062,7 @@ class WebRTCClient extends Emitter {
8052
8062
  const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
8053
8063
  const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
8054
8064
  const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
8065
+ const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
8055
8066
 
8056
8067
  logger$8.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
8057
8068
 
@@ -8059,7 +8070,8 @@ class WebRTCClient extends Emitter {
8059
8070
  constraints: {
8060
8071
  // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
8061
8072
  audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
8062
- video: screenSharing ? (isDesktop ? ({ mandatory: { chromeMediaSource: 'desktop' } }) : { cursor: 'always' })
8073
+ video: screenSharing ? (isDesktop
8074
+ ? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
8063
8075
  : this._getVideoConstraints(enableVideo),
8064
8076
  screen: screenSharing,
8065
8077
  desktop: isDesktop,
@@ -8394,12 +8406,14 @@ class WebRTCClient extends Emitter {
8394
8406
 
8395
8407
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
8396
8408
 
8397
- pc.oniceconnectionstatechange = () => {
8398
- logger$8.info('on ice connection state changed', { state: pc.iceConnectionState });
8399
- if (pc.iceConnectionState === 'disconnected') {
8400
- this.eventEmitter.emit(ON_DISCONNECTED$1);
8401
- }
8402
- };
8409
+ if (pc) {
8410
+ pc.oniceconnectionstatechange = () => {
8411
+ logger$8.info('on ice connection state changed', { state: pc.iceConnectionState });
8412
+ if (pc.iceConnectionState === 'disconnected') {
8413
+ this.eventEmitter.emit(ON_DISCONNECTED$1);
8414
+ }
8415
+ };
8416
+ }
8403
8417
 
8404
8418
  if (withEvent) {
8405
8419
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
@@ -8609,13 +8623,17 @@ class WebRTCClient extends Emitter {
8609
8623
  const nbStats = this.sessionNetworkStats[sessionId].length;
8610
8624
  const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
8611
8625
  const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
8626
+ const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
8612
8627
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8613
8628
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8629
+ const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
8614
8630
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8615
8631
  const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8616
8632
  const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8617
- let audioBytesSent = 0;
8618
- let audioBytesReceived = 0;
8633
+ let audioBytesSent = 0; // content + header
8634
+ let audioBytesReceived = 0; // content + header
8635
+ let audioContentSent = 0; // useful to detect blank call
8636
+ let audioContentReceived = 0;
8619
8637
  let videoBytesSent = 0;
8620
8638
  let videoBytesReceived = 0;
8621
8639
  let transportSent = 0;
@@ -8625,6 +8643,7 @@ class WebRTCClient extends Emitter {
8625
8643
  stats.forEach(report => {
8626
8644
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
8627
8645
  audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
8646
+ audioContentSent += Number(report.bytesSent);
8628
8647
  }
8629
8648
  if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
8630
8649
  audioBytesSent += Number(report.bytesSent);
@@ -8636,6 +8655,7 @@ class WebRTCClient extends Emitter {
8636
8655
  packetsLost += Number(report.packetsLost);
8637
8656
  networkStats.packetsReceived = Number(report.packetsReceived);
8638
8657
  audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
8658
+ audioContentReceived += Number(report.bytesReceived);
8639
8659
  }
8640
8660
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
8641
8661
  videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
@@ -8664,10 +8684,17 @@ class WebRTCClient extends Emitter {
8664
8684
  });
8665
8685
 
8666
8686
  networkStats.packetsLost = packetsLost;
8687
+
8667
8688
  networkStats.totalAudioBytesSent = audioBytesSent;
8668
8689
  networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
8669
8690
  networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
8670
8691
  networkStats.audioBytesReceived = audioBytesReceived;
8692
+
8693
+ networkStats.totalAudioContentSent = audioContentSent;
8694
+ networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
8695
+ networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
8696
+ networkStats.audioContentReceived = audioContentReceived;
8697
+
8671
8698
  networkStats.totalVideoBytesSent = videoBytesSent;
8672
8699
  networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
8673
8700
  networkStats.totalVideoBytesReceived = videoBytesReceived;
@@ -8879,6 +8906,7 @@ class WebRTCPhone extends Emitter {
8879
8906
  constraints,
8880
8907
  audioOnly,
8881
8908
  conference,
8909
+ iceRestart,
8882
8910
  });
8883
8911
 
8884
8912
  if (!sipSession) {
@@ -8982,6 +9010,11 @@ class WebRTCPhone extends Emitter {
8982
9010
 
8983
9011
  this.client.downgradeToAudio(sipSession);
8984
9012
 
9013
+ if (callSession) {
9014
+ callSession.cameraEnabled = false;
9015
+ this._updateCallSession(callSession);
9016
+ }
9017
+
8985
9018
  if (withMessage) {
8986
9019
  this._sendReinviteMessage(callSession, false);
8987
9020
  }
@@ -9009,6 +9042,11 @@ class WebRTCPhone extends Emitter {
9009
9042
 
9010
9043
  const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
9011
9044
 
9045
+ if (callSession) {
9046
+ callSession.cameraEnabled = true;
9047
+ this._updateCallSession(callSession);
9048
+ }
9049
+
9012
9050
  // If no stream is returned, it means we have to reinvite
9013
9051
  if (!newStream) {
9014
9052
  return true;
@@ -9278,7 +9316,7 @@ class WebRTCPhone extends Emitter {
9278
9316
  }
9279
9317
 
9280
9318
  _onCallAccepted(sipSession , cameraEnabled ) {
9281
- logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9319
+ logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9282
9320
 
9283
9321
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
9284
9322
  this.currentSipSession = sipSession;
@@ -9347,6 +9385,7 @@ class WebRTCPhone extends Emitter {
9347
9385
  _onCallTerminated(sipSession ) {
9348
9386
  logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9349
9387
 
9388
+ const sipSessionId = this.getSipSessionId(sipSession);
9350
9389
  const callSession = this._createCallSession(sipSession);
9351
9390
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9352
9391
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9364,7 +9403,6 @@ class WebRTCPhone extends Emitter {
9364
9403
  }, 5);
9365
9404
  }
9366
9405
 
9367
- const sipSessionId = this.getSipSessionId(sipSession);
9368
9406
  if (sipSessionId) {
9369
9407
  this.removeIncomingSessions(sipSessionId);
9370
9408
  }
@@ -9790,7 +9828,7 @@ class WebRTCPhone extends Emitter {
9790
9828
  // @TODO: line is not used here
9791
9829
  async makeCall(number , line , cameraEnabled ,
9792
9830
  audioOnly = false, conference = false) {
9793
- logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9831
+ logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled, audioOnly, conference });
9794
9832
  if (!number) {
9795
9833
  return Promise.resolve(null);
9796
9834
  }
@@ -10009,8 +10047,12 @@ class WebRTCPhone extends Emitter {
10009
10047
  }
10010
10048
 
10011
10049
  const sessionId = this.incomingSessions[0];
10050
+ const sipSession = this.client.getSipSession(sessionId);
10051
+ if (!sipSession) {
10052
+ return null;
10053
+ }
10012
10054
 
10013
- return this._createCallSession(this.client.getSipSession(sessionId));
10055
+ return this._createCallSession(sipSession);
10014
10056
  }
10015
10057
 
10016
10058
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -10151,9 +10193,13 @@ class WebRTCPhone extends Emitter {
10151
10193
  if (this.shouldSendReinvite && this.currentSipSession
10152
10194
  && this.currentSipSession.state === sessionState.SessionState.Established) {
10153
10195
  this.shouldSendReinvite = false;
10196
+ const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
10197
+ const isConference = pc ? pc.sfu : false;
10198
+ const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
10199
+
10154
10200
  try {
10155
10201
  // Send reinvite with iceRestart
10156
- this.sendReinvite(this.currentCallSession, null, false, false, true);
10202
+ this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
10157
10203
  } catch (e) {
10158
10204
  logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
10159
10205
  }
@@ -10237,6 +10283,15 @@ class WebRTCPhone extends Emitter {
10237
10283
  return this.client.getSipSessionId(sipSession);
10238
10284
  }
10239
10285
 
10286
+ _updateCallSession(callSession ) {
10287
+ const sipSession = this.findSipSession(callSession);
10288
+ const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
10289
+
10290
+ if (sipSessionId) {
10291
+ this.callSessions[sipSessionId] = callSession;
10292
+ }
10293
+ }
10294
+
10240
10295
  _onMessage(message ) {
10241
10296
  if (!message || message.method !== 'MESSAGE') {
10242
10297
  return;