@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
@@ -1246,7 +1246,7 @@ class Contact {
1246
1246
  this[key] = old[key] || this[key];
1247
1247
  });
1248
1248
 
1249
- if (old.lineState && !this.lineState) {
1249
+ if (old.lineState) {
1250
1250
  this.lineState = old.lineState;
1251
1251
  }
1252
1252
 
@@ -1961,7 +1961,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1961
1961
 
1962
1962
  // Use a function here to be able to mock it in tests
1963
1963
  const realFetch = () => {
1964
- if (typeof document !== 'undefined') {
1964
+ if (typeof document !== 'undefined' && window.fetch) {
1965
1965
  // Browser
1966
1966
  return window.fetch;
1967
1967
  }
@@ -2640,8 +2640,9 @@ class ExternalApp {
2640
2640
 
2641
2641
 
2642
2642
 
2643
-
2643
+
2644
2644
 
2645
+
2645
2646
 
2646
2647
 
2647
2648
  class Meeting {
@@ -2652,9 +2653,10 @@ class Meeting {
2652
2653
 
2653
2654
 
2654
2655
 
2655
-
2656
+
2656
2657
 
2657
2658
 
2659
+
2658
2660
 
2659
2661
  static parse(plain ) {
2660
2662
  return new Meeting({
@@ -2664,8 +2666,9 @@ class Meeting {
2664
2666
  ownerUuids: plain.owner_uuids,
2665
2667
  port: plain.port,
2666
2668
  uuid: plain.uuid,
2667
- number: plain.number,
2669
+ extension: plain.exten,
2668
2670
  persistent: plain.persistent,
2671
+ creationTime: moment__default['default'](plain.creation_time).toDate(),
2669
2672
  });
2670
2673
  }
2671
2674
 
@@ -2687,8 +2690,9 @@ class Meeting {
2687
2690
  ownerUuids,
2688
2691
  port,
2689
2692
  uri,
2690
- number,
2693
+ extension,
2691
2694
  persistent,
2695
+ creationTime,
2692
2696
  } = {}) {
2693
2697
  this.guestSipAuthorization = guestSipAuthorization;
2694
2698
  this.uri = uri;
@@ -2696,8 +2700,9 @@ class Meeting {
2696
2700
  this.ownerUuids = ownerUuids;
2697
2701
  this.port = port;
2698
2702
  this.uuid = uuid;
2699
- this.number = number;
2703
+ this.extension = extension;
2700
2704
  this.persistent = persistent;
2705
+ this.creationTime = creationTime;
2701
2706
 
2702
2707
  // Useful to compare instead of instanceof with minified code
2703
2708
  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;
@@ -1248,7 +1248,7 @@ class Contact {
1248
1248
  this[key] = old[key] || this[key];
1249
1249
  });
1250
1250
 
1251
- if (old.lineState && !this.lineState) {
1251
+ if (old.lineState) {
1252
1252
  this.lineState = old.lineState;
1253
1253
  }
1254
1254
 
@@ -1963,7 +1963,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1963
1963
 
1964
1964
  // Use a function here to be able to mock it in tests
1965
1965
  const realFetch = () => {
1966
- if (typeof document !== 'undefined') {
1966
+ if (typeof document !== 'undefined' && window.fetch) {
1967
1967
  // Browser
1968
1968
  return window.fetch;
1969
1969
  }
@@ -2642,8 +2642,9 @@ class ExternalApp {
2642
2642
 
2643
2643
 
2644
2644
 
2645
-
2645
+
2646
2646
 
2647
+
2647
2648
 
2648
2649
 
2649
2650
  class Meeting {
@@ -2654,9 +2655,10 @@ class Meeting {
2654
2655
 
2655
2656
 
2656
2657
 
2657
-
2658
+
2658
2659
 
2659
2660
 
2661
+
2660
2662
 
2661
2663
  static parse(plain ) {
2662
2664
  return new Meeting({
@@ -2666,8 +2668,9 @@ class Meeting {
2666
2668
  ownerUuids: plain.owner_uuids,
2667
2669
  port: plain.port,
2668
2670
  uuid: plain.uuid,
2669
- number: plain.number,
2671
+ extension: plain.exten,
2670
2672
  persistent: plain.persistent,
2673
+ creationTime: moment__default['default'](plain.creation_time).toDate(),
2671
2674
  });
2672
2675
  }
2673
2676
 
@@ -2689,8 +2692,9 @@ class Meeting {
2689
2692
  ownerUuids,
2690
2693
  port,
2691
2694
  uri,
2692
- number,
2695
+ extension,
2693
2696
  persistent,
2697
+ creationTime,
2694
2698
  } = {}) {
2695
2699
  this.guestSipAuthorization = guestSipAuthorization;
2696
2700
  this.uri = uri;
@@ -2698,8 +2702,9 @@ class Meeting {
2698
2702
  this.ownerUuids = ownerUuids;
2699
2703
  this.port = port;
2700
2704
  this.uuid = uuid;
2701
- this.number = number;
2705
+ this.extension = extension;
2702
2706
  this.persistent = persistent;
2707
+ this.creationTime = creationTime;
2703
2708
 
2704
2709
  // Useful to compare instead of instanceof with minified code
2705
2710
  this.type = 'Meeting';
@@ -6069,11 +6074,16 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
6069
6074
 
6070
6075
  // $FlowFixMe
6071
6076
  setRemoteSessionDescription(sessionDescription ) {
6072
- const result = super.setRemoteSessionDescription(sessionDescription);
6077
+ try {
6078
+ const result = super.setRemoteSessionDescription(sessionDescription);
6073
6079
 
6074
- this.eventEmitter.emit('setDescription', sessionDescription);
6080
+ this.eventEmitter.emit('setDescription', sessionDescription);
6075
6081
 
6076
- return result;
6082
+ return result;
6083
+ } catch (error) {
6084
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
6085
+ throw error;
6086
+ }
6077
6087
  }
6078
6088
 
6079
6089
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -6978,7 +6988,7 @@ class WebRTCClient extends Emitter {
6978
6988
  }
6979
6989
 
6980
6990
  call(number , enableVideo , audioOnly = false, conference = false) {
6981
- logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6991
+ logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
6982
6992
  const inviterOptions = {
6983
6993
  sessionDescriptionHandlerOptionsReInvite: {
6984
6994
  conference,
@@ -8054,6 +8064,7 @@ class WebRTCClient extends Emitter {
8054
8064
  const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
8055
8065
  const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
8056
8066
  const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
8067
+ const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
8057
8068
 
8058
8069
  logger$8.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
8059
8070
 
@@ -8061,7 +8072,8 @@ class WebRTCClient extends Emitter {
8061
8072
  constraints: {
8062
8073
  // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
8063
8074
  audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
8064
- video: screenSharing ? (isDesktop ? ({ mandatory: { chromeMediaSource: 'desktop' } }) : { cursor: 'always' })
8075
+ video: screenSharing ? (isDesktop
8076
+ ? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
8065
8077
  : this._getVideoConstraints(enableVideo),
8066
8078
  screen: screenSharing,
8067
8079
  desktop: isDesktop,
@@ -8396,12 +8408,14 @@ class WebRTCClient extends Emitter {
8396
8408
 
8397
8409
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
8398
8410
 
8399
- pc.oniceconnectionstatechange = () => {
8400
- logger$8.info('on ice connection state changed', { state: pc.iceConnectionState });
8401
- if (pc.iceConnectionState === 'disconnected') {
8402
- this.eventEmitter.emit(ON_DISCONNECTED$1);
8403
- }
8404
- };
8411
+ if (pc) {
8412
+ pc.oniceconnectionstatechange = () => {
8413
+ logger$8.info('on ice connection state changed', { state: pc.iceConnectionState });
8414
+ if (pc.iceConnectionState === 'disconnected') {
8415
+ this.eventEmitter.emit(ON_DISCONNECTED$1);
8416
+ }
8417
+ };
8418
+ }
8405
8419
 
8406
8420
  if (withEvent) {
8407
8421
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
@@ -8611,13 +8625,17 @@ class WebRTCClient extends Emitter {
8611
8625
  const nbStats = this.sessionNetworkStats[sessionId].length;
8612
8626
  const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
8613
8627
  const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
8628
+ const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
8614
8629
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8615
8630
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8631
+ const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
8616
8632
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8617
8633
  const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8618
8634
  const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8619
- let audioBytesSent = 0;
8620
- let audioBytesReceived = 0;
8635
+ let audioBytesSent = 0; // content + header
8636
+ let audioBytesReceived = 0; // content + header
8637
+ let audioContentSent = 0; // useful to detect blank call
8638
+ let audioContentReceived = 0;
8621
8639
  let videoBytesSent = 0;
8622
8640
  let videoBytesReceived = 0;
8623
8641
  let transportSent = 0;
@@ -8627,6 +8645,7 @@ class WebRTCClient extends Emitter {
8627
8645
  stats.forEach(report => {
8628
8646
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
8629
8647
  audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
8648
+ audioContentSent += Number(report.bytesSent);
8630
8649
  }
8631
8650
  if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
8632
8651
  audioBytesSent += Number(report.bytesSent);
@@ -8638,6 +8657,7 @@ class WebRTCClient extends Emitter {
8638
8657
  packetsLost += Number(report.packetsLost);
8639
8658
  networkStats.packetsReceived = Number(report.packetsReceived);
8640
8659
  audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
8660
+ audioContentReceived += Number(report.bytesReceived);
8641
8661
  }
8642
8662
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
8643
8663
  videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
@@ -8666,10 +8686,17 @@ class WebRTCClient extends Emitter {
8666
8686
  });
8667
8687
 
8668
8688
  networkStats.packetsLost = packetsLost;
8689
+
8669
8690
  networkStats.totalAudioBytesSent = audioBytesSent;
8670
8691
  networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
8671
8692
  networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
8672
8693
  networkStats.audioBytesReceived = audioBytesReceived;
8694
+
8695
+ networkStats.totalAudioContentSent = audioContentSent;
8696
+ networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
8697
+ networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
8698
+ networkStats.audioContentReceived = audioContentReceived;
8699
+
8673
8700
  networkStats.totalVideoBytesSent = videoBytesSent;
8674
8701
  networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
8675
8702
  networkStats.totalVideoBytesReceived = videoBytesReceived;
@@ -8881,6 +8908,7 @@ class WebRTCPhone extends Emitter {
8881
8908
  constraints,
8882
8909
  audioOnly,
8883
8910
  conference,
8911
+ iceRestart,
8884
8912
  });
8885
8913
 
8886
8914
  if (!sipSession) {
@@ -8984,6 +9012,11 @@ class WebRTCPhone extends Emitter {
8984
9012
 
8985
9013
  this.client.downgradeToAudio(sipSession);
8986
9014
 
9015
+ if (callSession) {
9016
+ callSession.cameraEnabled = false;
9017
+ this._updateCallSession(callSession);
9018
+ }
9019
+
8987
9020
  if (withMessage) {
8988
9021
  this._sendReinviteMessage(callSession, false);
8989
9022
  }
@@ -9011,6 +9044,11 @@ class WebRTCPhone extends Emitter {
9011
9044
 
9012
9045
  const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
9013
9046
 
9047
+ if (callSession) {
9048
+ callSession.cameraEnabled = true;
9049
+ this._updateCallSession(callSession);
9050
+ }
9051
+
9014
9052
  // If no stream is returned, it means we have to reinvite
9015
9053
  if (!newStream) {
9016
9054
  return true;
@@ -9280,7 +9318,7 @@ class WebRTCPhone extends Emitter {
9280
9318
  }
9281
9319
 
9282
9320
  _onCallAccepted(sipSession , cameraEnabled ) {
9283
- logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9321
+ logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9284
9322
 
9285
9323
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
9286
9324
  this.currentSipSession = sipSession;
@@ -9349,6 +9387,7 @@ class WebRTCPhone extends Emitter {
9349
9387
  _onCallTerminated(sipSession ) {
9350
9388
  logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9351
9389
 
9390
+ const sipSessionId = this.getSipSessionId(sipSession);
9352
9391
  const callSession = this._createCallSession(sipSession);
9353
9392
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9354
9393
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9366,7 +9405,6 @@ class WebRTCPhone extends Emitter {
9366
9405
  }, 5);
9367
9406
  }
9368
9407
 
9369
- const sipSessionId = this.getSipSessionId(sipSession);
9370
9408
  if (sipSessionId) {
9371
9409
  this.removeIncomingSessions(sipSessionId);
9372
9410
  }
@@ -9792,7 +9830,7 @@ class WebRTCPhone extends Emitter {
9792
9830
  // @TODO: line is not used here
9793
9831
  async makeCall(number , line , cameraEnabled ,
9794
9832
  audioOnly = false, conference = false) {
9795
- logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9833
+ logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled, audioOnly, conference });
9796
9834
  if (!number) {
9797
9835
  return Promise.resolve(null);
9798
9836
  }
@@ -10011,8 +10049,12 @@ class WebRTCPhone extends Emitter {
10011
10049
  }
10012
10050
 
10013
10051
  const sessionId = this.incomingSessions[0];
10052
+ const sipSession = this.client.getSipSession(sessionId);
10053
+ if (!sipSession) {
10054
+ return null;
10055
+ }
10014
10056
 
10015
- return this._createCallSession(this.client.getSipSession(sessionId));
10057
+ return this._createCallSession(sipSession);
10016
10058
  }
10017
10059
 
10018
10060
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -10153,9 +10195,13 @@ class WebRTCPhone extends Emitter {
10153
10195
  if (this.shouldSendReinvite && this.currentSipSession
10154
10196
  && this.currentSipSession.state === sessionState.SessionState.Established) {
10155
10197
  this.shouldSendReinvite = false;
10198
+ const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
10199
+ const isConference = pc ? pc.sfu : false;
10200
+ const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
10201
+
10156
10202
  try {
10157
10203
  // Send reinvite with iceRestart
10158
- this.sendReinvite(this.currentCallSession, null, false, false, true);
10204
+ this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
10159
10205
  } catch (e) {
10160
10206
  logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
10161
10207
  }
@@ -10239,6 +10285,15 @@ class WebRTCPhone extends Emitter {
10239
10285
  return this.client.getSipSessionId(sipSession);
10240
10286
  }
10241
10287
 
10288
+ _updateCallSession(callSession ) {
10289
+ const sipSession = this.findSipSession(callSession);
10290
+ const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
10291
+
10292
+ if (sipSessionId) {
10293
+ this.callSessions[sipSessionId] = callSession;
10294
+ }
10295
+ }
10296
+
10242
10297
  _onMessage(message ) {
10243
10298
  if (!message || message.method !== 'MESSAGE') {
10244
10299
  return;
@@ -1,2 +1,4 @@
1
1
  'use strict';
2
2
 
3
+ require('moment');
4
+
@@ -446,7 +446,7 @@ const logger = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
446
446
 
447
447
  // Use a function here to be able to mock it in tests
448
448
  const realFetch = () => {
449
- if (typeof document !== 'undefined') {
449
+ if (typeof document !== 'undefined' && window.fetch) {
450
450
  // Browser
451
451
  return window.fetch;
452
452
  }
@@ -448,7 +448,7 @@ const logger = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
448
448
 
449
449
  // Use a function here to be able to mock it in tests
450
450
  const realFetch = () => {
451
- if (typeof document !== 'undefined') {
451
+ if (typeof document !== 'undefined' && window.fetch) {
452
452
  // Browser
453
453
  return window.fetch;
454
454
  }