@wazo/sdk 0.37.16 → 0.37.20

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 (114) hide show
  1. package/dist/wazo-sdk.js +5 -5
  2. package/esm/__tests__/api-client.test.js +9 -5
  3. package/esm/__tests__/web-rtc-client.test.js +69 -19
  4. package/esm/api/agentd.js +1 -1
  5. package/esm/api/amid.js +1 -1
  6. package/esm/api/application.js +1 -1
  7. package/esm/api/auth.js +1 -1
  8. package/esm/api/call-logd.js +3 -3
  9. package/esm/api/calld.js +1 -1
  10. package/esm/api/chatd.js +1 -1
  11. package/esm/api/confd.js +7 -3
  12. package/esm/api/ctid-ng.js +1 -1
  13. package/esm/api/dird.js +1 -1
  14. package/esm/api/webhookd.js +1 -1
  15. package/esm/api-client.js +9 -5
  16. package/esm/checker/Checker.js +69 -19
  17. package/esm/checker/checks/aor.js +9 -5
  18. package/esm/checker/checks/api.js +9 -5
  19. package/esm/checker/checks/index.js +69 -19
  20. package/esm/checker/checks/wazo-websocket.js +1 -1
  21. package/esm/checker/checks/webrtc-transport.js +69 -19
  22. package/esm/checker/checks/webrtc.js +69 -19
  23. package/esm/domain/AdHocAPIConference.js +9 -5
  24. package/esm/domain/CallLog.js +2 -2
  25. package/esm/domain/Features.js +9 -5
  26. package/esm/domain/Meeting.js +6 -2
  27. package/esm/domain/Phone/CTIPhone.js +9 -5
  28. package/esm/domain/Phone/WebRTCPhone.js +9 -2
  29. package/esm/domain/Recording.js +1 -1
  30. package/esm/domain/__tests__/CallLog.test.js +2 -2
  31. package/esm/index.js +77 -19
  32. package/esm/lib/WazoSessionDescriptionHandler.js +1 -1
  33. package/esm/service/CallApi.js +9 -5
  34. package/esm/service/IssueReporter.js +1 -1
  35. package/esm/service/__tests__/IssueReporter.test.js +1 -1
  36. package/esm/service/getApiClient.js +9 -5
  37. package/esm/simple/Auth.js +77 -19
  38. package/esm/simple/Configuration.js +77 -19
  39. package/esm/simple/Directory.js +9 -5
  40. package/esm/simple/Phone.js +77 -19
  41. package/esm/simple/Websocket.js +1 -1
  42. package/esm/simple/index.js +77 -19
  43. package/esm/simple/room/LocalParticipant.js +77 -19
  44. package/esm/simple/room/Participant.js +77 -19
  45. package/esm/simple/room/RemoteParticipant.js +77 -19
  46. package/esm/simple/room/Room.js +77 -19
  47. package/esm/simple/room/SipRoom.js +77 -19
  48. package/esm/simple/room/Stream.js +77 -19
  49. package/esm/simple/room/__tests__/RemoteParticipant.test.js +77 -19
  50. package/esm/simple/utils.js +77 -19
  51. package/esm/utils/__tests__/api-requester.test.js +1 -1
  52. package/esm/utils/api-requester.js +1 -1
  53. package/esm/web-rtc-client.js +69 -19
  54. package/esm/websocket-client.js +1 -1
  55. package/lib/__tests__/api-client.test.js +9 -5
  56. package/lib/__tests__/web-rtc-client.test.js +69 -19
  57. package/lib/api/agentd.js +1 -1
  58. package/lib/api/amid.js +1 -1
  59. package/lib/api/application.js +1 -1
  60. package/lib/api/auth.js +1 -1
  61. package/lib/api/call-logd.js +3 -3
  62. package/lib/api/calld.js +1 -1
  63. package/lib/api/chatd.js +1 -1
  64. package/lib/api/confd.js +7 -3
  65. package/lib/api/ctid-ng.js +1 -1
  66. package/lib/api/dird.js +1 -1
  67. package/lib/api/webhookd.js +1 -1
  68. package/lib/api-client.js +9 -5
  69. package/lib/checker/Checker.js +69 -19
  70. package/lib/checker/checks/aor.js +9 -5
  71. package/lib/checker/checks/api.js +9 -5
  72. package/lib/checker/checks/index.js +69 -19
  73. package/lib/checker/checks/wazo-websocket.js +1 -1
  74. package/lib/checker/checks/webrtc-transport.js +69 -19
  75. package/lib/checker/checks/webrtc.js +69 -19
  76. package/lib/domain/AdHocAPIConference.js +9 -5
  77. package/lib/domain/CallLog.js +2 -2
  78. package/lib/domain/Features.js +9 -5
  79. package/lib/domain/Meeting.js +6 -2
  80. package/lib/domain/Phone/CTIPhone.js +9 -5
  81. package/lib/domain/Phone/WebRTCPhone.js +9 -1
  82. package/lib/domain/Recording.js +1 -1
  83. package/lib/domain/__tests__/CallLog.test.js +2 -2
  84. package/lib/index.js +77 -19
  85. package/lib/lib/WazoSessionDescriptionHandler.js +1 -1
  86. package/lib/service/CallApi.js +9 -5
  87. package/lib/service/IssueReporter.js +1 -1
  88. package/lib/service/__tests__/IssueReporter.test.js +1 -1
  89. package/lib/service/getApiClient.js +9 -5
  90. package/lib/simple/Auth.js +77 -19
  91. package/lib/simple/Configuration.js +77 -19
  92. package/lib/simple/Directory.js +9 -5
  93. package/lib/simple/Phone.js +77 -19
  94. package/lib/simple/Websocket.js +1 -1
  95. package/lib/simple/index.js +77 -19
  96. package/lib/simple/room/LocalParticipant.js +77 -19
  97. package/lib/simple/room/Participant.js +77 -19
  98. package/lib/simple/room/RemoteParticipant.js +77 -19
  99. package/lib/simple/room/Room.js +77 -19
  100. package/lib/simple/room/SipRoom.js +77 -19
  101. package/lib/simple/room/Stream.js +77 -19
  102. package/lib/simple/room/__tests__/RemoteParticipant.test.js +77 -19
  103. package/lib/simple/utils.js +77 -19
  104. package/lib/utils/__tests__/api-requester.test.js +1 -1
  105. package/lib/utils/api-requester.js +1 -1
  106. package/lib/web-rtc-client.js +69 -19
  107. package/lib/websocket-client.js +1 -1
  108. package/package.json +2 -2
  109. package/src/domain/CallLog.js +1 -1
  110. package/src/domain/Meeting.js +6 -2
  111. package/src/domain/Phone/WebRTCPhone.js +7 -0
  112. package/src/domain/Recording.js +1 -1
  113. package/src/service/IssueReporter.js +1 -1
  114. package/src/web-rtc-client.js +60 -14
@@ -664,7 +664,7 @@ class IssueReporter {
664
664
  payload._retry = retry + 1;
665
665
  }
666
666
 
667
- this._sendDebugToGrafana(body, retry + 1);
667
+ this._sendDebugToGrafana(payload, retry + 1);
668
668
  }, 5000 + retry * 1000);
669
669
  });
670
670
  }
@@ -3166,7 +3166,8 @@ class ExternalApp {
3166
3166
 
3167
3167
 
3168
3168
 
3169
-
3169
+
3170
+
3170
3171
 
3171
3172
 
3172
3173
  class Meeting {
@@ -3178,6 +3179,7 @@ class Meeting {
3178
3179
 
3179
3180
 
3180
3181
 
3182
+
3181
3183
 
3182
3184
 
3183
3185
  static parse(plain ) {
@@ -3189,6 +3191,7 @@ class Meeting {
3189
3191
  port: plain.port,
3190
3192
  uuid: plain.uuid,
3191
3193
  number: plain.number,
3194
+ persistent: plain.persistent,
3192
3195
  });
3193
3196
  }
3194
3197
 
@@ -3196,7 +3199,7 @@ class Meeting {
3196
3199
  return newFrom(meeting, Meeting);
3197
3200
  }
3198
3201
 
3199
- constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
3202
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
3200
3203
  this.guestSipAuthorization = guestSipAuthorization;
3201
3204
  this.uri = uri;
3202
3205
  this.name = name;
@@ -3204,6 +3207,7 @@ class Meeting {
3204
3207
  this.port = port;
3205
3208
  this.uuid = uuid;
3206
3209
  this.number = number;
3210
+ this.persistent = persistent;
3207
3211
 
3208
3212
  // Useful to compare instead of instanceof with minified code
3209
3213
  this.type = 'Meeting';
@@ -3767,7 +3771,7 @@ class Recording {
3767
3771
 
3768
3772
 
3769
3773
 
3770
- static parseMany(recordings ) {
3774
+ static parseMany(recordings = []) {
3771
3775
  return recordings.map(item => Recording.parse(item));
3772
3776
  }
3773
3777
 
@@ -3893,7 +3897,7 @@ class CallLog {
3893
3897
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3894
3898
  start: moment(plain.start).toDate(),
3895
3899
  end: plain.end ? moment(plain.end).toDate() : null,
3896
- recordings: Recording.parseMany(plain.recordings),
3900
+ recordings: Recording.parseMany(plain.recordings || []),
3897
3901
  });
3898
3902
  }
3899
3903
 
@@ -5288,6 +5292,7 @@ const ON_REINVITE = 'reinvite';
5288
5292
  const ON_ERROR = 'onError';
5289
5293
  const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
5290
5294
  const ON_NETWORK_STATS = 'onNetworkStats';
5295
+ const ON_DISCONNECTED = 'onDisconnected';
5291
5296
  class CanceledCallError extends Error {}
5292
5297
 
5293
5298
  const MAX_REGISTER_TRIES = 10;
@@ -5361,6 +5366,7 @@ class WebRTCClient extends Emitter {
5361
5366
 
5362
5367
 
5363
5368
 
5369
+
5364
5370
 
5365
5371
  static isAPrivateIp(ip ) {
5366
5372
  const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
@@ -5426,6 +5432,7 @@ class WebRTCClient extends Emitter {
5426
5432
  this.ON_ERROR = ON_ERROR;
5427
5433
  this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
5428
5434
  this.ON_NETWORK_STATS = ON_NETWORK_STATS;
5435
+ this.ON_DISCONNECTED = ON_DISCONNECTED;
5429
5436
  }
5430
5437
 
5431
5438
  configureMedia(media ) {
@@ -6027,7 +6034,7 @@ class WebRTCClient extends Emitter {
6027
6034
  // We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
6028
6035
  const transceivers = pc.getTransceivers();
6029
6036
  const transceiverIdx = lastIndexOf(transceivers, transceiver =>
6030
- transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
6037
+ transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
6031
6038
 
6032
6039
  videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
6033
6040
  } else {
@@ -6273,10 +6280,13 @@ class WebRTCClient extends Emitter {
6273
6280
  return null;
6274
6281
  }
6275
6282
 
6276
- // let's update the local value
6277
- if (this.audio && this.audio.deviceId) {
6278
- // $FlowFixMe
6279
- this.audio.deviceId.exact = id;
6283
+ // let's update the local audio value
6284
+ if (this.audio) {
6285
+ this.audio = {
6286
+ deviceId: {
6287
+ exact: id,
6288
+ },
6289
+ };
6280
6290
  }
6281
6291
 
6282
6292
  if (session) {
@@ -6289,6 +6299,9 @@ class WebRTCClient extends Emitter {
6289
6299
  const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
6290
6300
 
6291
6301
  if (sender) {
6302
+ if (sender.track) {
6303
+ audioTrack.enabled = sender.track.enabled;
6304
+ }
6292
6305
  sender.replaceTrack(audioTrack);
6293
6306
  }
6294
6307
 
@@ -6313,7 +6326,7 @@ class WebRTCClient extends Emitter {
6313
6326
  return null;
6314
6327
  }
6315
6328
 
6316
- // let's update the local value
6329
+ // let's update the local video value
6317
6330
  if (this.video) {
6318
6331
  this.video = {
6319
6332
  deviceId: {
@@ -6348,12 +6361,21 @@ class WebRTCClient extends Emitter {
6348
6361
  return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
6349
6362
  const videoTrack = stream.getVideoTracks()[0];
6350
6363
  let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
6364
+ let wasTrackEnabled = false;
6351
6365
  if (!sender) {
6352
6366
  sender = pc && pc.getSenders().find(s => !s.track);
6353
6367
  }
6354
6368
 
6355
6369
  if (sender) {
6356
- sender.replaceTrack(videoTrack);
6370
+ // No video track means video not enabled
6371
+ wasTrackEnabled = sender.track ? sender.track.enabled : false;
6372
+ videoTrack.enabled = wasTrackEnabled;
6373
+
6374
+ if (!wasTrackEnabled) {
6375
+ videoTrack.stop();
6376
+ }
6377
+
6378
+ sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
6357
6379
  }
6358
6380
 
6359
6381
  // let's update the local stream
@@ -7037,6 +7059,7 @@ class WebRTCClient extends Emitter {
7037
7059
 
7038
7060
  this.updateRemoteStream(this.getSipSessionId(session));
7039
7061
 
7062
+ const pc = session.sessionDescriptionHandler.peerConnection;
7040
7063
  const onTrack = (event ) => {
7041
7064
  const isAudioOnly = this._isAudioOnly(session);
7042
7065
  const { kind, label, readyState, id, muted } = event.track;
@@ -7056,6 +7079,12 @@ class WebRTCClient extends Emitter {
7056
7079
 
7057
7080
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
7058
7081
 
7082
+ pc.oniceconnectionstatechange = () => {
7083
+ if (pc.iceConnectionState === 'disconnected') {
7084
+ this.eventEmitter.emit(ON_DISCONNECTED);
7085
+ }
7086
+ };
7087
+
7059
7088
  if (withEvent) {
7060
7089
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
7061
7090
  }
@@ -7267,25 +7296,33 @@ class WebRTCClient extends Emitter {
7267
7296
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
7268
7297
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
7269
7298
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
7299
+ const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
7300
+ const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
7270
7301
  let audioBytesSent = 0;
7271
7302
  let audioBytesReceived = 0;
7272
7303
  let videoBytesSent = 0;
7273
7304
  let videoBytesReceived = 0;
7305
+ let transportSent = 0;
7306
+ let transportReceived = 0;
7307
+ let packetsLost = 0;
7274
7308
 
7275
7309
  stats.forEach(report => {
7276
7310
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
7311
+ audioBytesSent += report.bytesSent + report.headerBytesSent;
7312
+ }
7313
+ if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
7277
7314
  audioBytesSent += report.bytesSent;
7278
7315
  }
7279
7316
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7280
- videoBytesSent += report.bytesSent;
7317
+ videoBytesSent += report.bytesSent + report.headerBytesSent;
7281
7318
  }
7282
7319
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
7283
- networkStats.packetsLost = report.packetsLost;
7320
+ packetsLost += report.packetsLost;
7284
7321
  networkStats.packetsReceived = report.packetsReceived;
7285
- audioBytesReceived += report.bytesReceived;
7322
+ audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
7286
7323
  }
7287
7324
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
7288
- videoBytesReceived += report.bytesReceived;
7325
+ videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
7289
7326
  }
7290
7327
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7291
7328
  if ('framesPerSecond' in report) {
@@ -7297,19 +7334,32 @@ class WebRTCClient extends Emitter {
7297
7334
  }
7298
7335
  }
7299
7336
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
7337
+ packetsLost += report.packetsLost;
7300
7338
  networkStats.roundTripTime = report.roundTripTime;
7301
7339
  networkStats.jitter = report.jitter;
7302
7340
  }
7341
+ if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
7342
+ packetsLost += report.packetsLost;
7343
+ }
7344
+ if (report.type === 'transport') {
7345
+ transportSent += report.bytesSent;
7346
+ transportReceived += report.bytesReceived;
7347
+ }
7303
7348
  });
7304
7349
 
7350
+ networkStats.packetsLost = packetsLost;
7305
7351
  networkStats.audioBytesSent = audioBytesSent;
7306
7352
  networkStats.audioBytesReceived = audioBytesReceived;
7307
7353
  networkStats.videoBytesSent = videoBytesSent;
7308
7354
  networkStats.videoBytesReceived = videoBytesReceived;
7355
+ networkStats.transportSent = transportSent;
7356
+ networkStats.transportReceived = transportReceived;
7357
+
7358
+ const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
7359
+ + (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
7360
+ + (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
7309
7361
 
7310
- networkStats.bandwidth = (networkStats.audioBytesSent - lastAudioSent)
7311
- + (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
7312
- + (networkStats.videoBytesReceived - lastVideoReceived);
7362
+ networkStats.bandwidth = bandwidth;
7313
7363
 
7314
7364
  this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
7315
7365
  this.sessionNetworkStats[sessionId].push(networkStats);
@@ -664,7 +664,7 @@ class IssueReporter {
664
664
  payload._retry = retry + 1;
665
665
  }
666
666
 
667
- this._sendDebugToGrafana(body, retry + 1);
667
+ this._sendDebugToGrafana(payload, retry + 1);
668
668
  }, 5000 + retry * 1000);
669
669
  });
670
670
  }
@@ -3166,7 +3166,8 @@ class ExternalApp {
3166
3166
 
3167
3167
 
3168
3168
 
3169
-
3169
+
3170
+
3170
3171
 
3171
3172
 
3172
3173
  class Meeting {
@@ -3178,6 +3179,7 @@ class Meeting {
3178
3179
 
3179
3180
 
3180
3181
 
3182
+
3181
3183
 
3182
3184
 
3183
3185
  static parse(plain ) {
@@ -3189,6 +3191,7 @@ class Meeting {
3189
3191
  port: plain.port,
3190
3192
  uuid: plain.uuid,
3191
3193
  number: plain.number,
3194
+ persistent: plain.persistent,
3192
3195
  });
3193
3196
  }
3194
3197
 
@@ -3196,7 +3199,7 @@ class Meeting {
3196
3199
  return newFrom(meeting, Meeting);
3197
3200
  }
3198
3201
 
3199
- constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
3202
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
3200
3203
  this.guestSipAuthorization = guestSipAuthorization;
3201
3204
  this.uri = uri;
3202
3205
  this.name = name;
@@ -3204,6 +3207,7 @@ class Meeting {
3204
3207
  this.port = port;
3205
3208
  this.uuid = uuid;
3206
3209
  this.number = number;
3210
+ this.persistent = persistent;
3207
3211
 
3208
3212
  // Useful to compare instead of instanceof with minified code
3209
3213
  this.type = 'Meeting';
@@ -3767,7 +3771,7 @@ class Recording {
3767
3771
 
3768
3772
 
3769
3773
 
3770
- static parseMany(recordings ) {
3774
+ static parseMany(recordings = []) {
3771
3775
  return recordings.map(item => Recording.parse(item));
3772
3776
  }
3773
3777
 
@@ -3893,7 +3897,7 @@ class CallLog {
3893
3897
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3894
3898
  start: moment(plain.start).toDate(),
3895
3899
  end: plain.end ? moment(plain.end).toDate() : null,
3896
- recordings: Recording.parseMany(plain.recordings),
3900
+ recordings: Recording.parseMany(plain.recordings || []),
3897
3901
  });
3898
3902
  }
3899
3903
 
@@ -5288,6 +5292,7 @@ const ON_REINVITE = 'reinvite';
5288
5292
  const ON_ERROR = 'onError';
5289
5293
  const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
5290
5294
  const ON_NETWORK_STATS = 'onNetworkStats';
5295
+ const ON_DISCONNECTED = 'onDisconnected';
5291
5296
  class CanceledCallError extends Error {}
5292
5297
 
5293
5298
  const MAX_REGISTER_TRIES = 10;
@@ -5361,6 +5366,7 @@ class WebRTCClient extends Emitter {
5361
5366
 
5362
5367
 
5363
5368
 
5369
+
5364
5370
 
5365
5371
  static isAPrivateIp(ip ) {
5366
5372
  const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
@@ -5426,6 +5432,7 @@ class WebRTCClient extends Emitter {
5426
5432
  this.ON_ERROR = ON_ERROR;
5427
5433
  this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
5428
5434
  this.ON_NETWORK_STATS = ON_NETWORK_STATS;
5435
+ this.ON_DISCONNECTED = ON_DISCONNECTED;
5429
5436
  }
5430
5437
 
5431
5438
  configureMedia(media ) {
@@ -6027,7 +6034,7 @@ class WebRTCClient extends Emitter {
6027
6034
  // We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
6028
6035
  const transceivers = pc.getTransceivers();
6029
6036
  const transceiverIdx = lastIndexOf(transceivers, transceiver =>
6030
- transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
6037
+ transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
6031
6038
 
6032
6039
  videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
6033
6040
  } else {
@@ -6273,10 +6280,13 @@ class WebRTCClient extends Emitter {
6273
6280
  return null;
6274
6281
  }
6275
6282
 
6276
- // let's update the local value
6277
- if (this.audio && this.audio.deviceId) {
6278
- // $FlowFixMe
6279
- this.audio.deviceId.exact = id;
6283
+ // let's update the local audio value
6284
+ if (this.audio) {
6285
+ this.audio = {
6286
+ deviceId: {
6287
+ exact: id,
6288
+ },
6289
+ };
6280
6290
  }
6281
6291
 
6282
6292
  if (session) {
@@ -6289,6 +6299,9 @@ class WebRTCClient extends Emitter {
6289
6299
  const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
6290
6300
 
6291
6301
  if (sender) {
6302
+ if (sender.track) {
6303
+ audioTrack.enabled = sender.track.enabled;
6304
+ }
6292
6305
  sender.replaceTrack(audioTrack);
6293
6306
  }
6294
6307
 
@@ -6313,7 +6326,7 @@ class WebRTCClient extends Emitter {
6313
6326
  return null;
6314
6327
  }
6315
6328
 
6316
- // let's update the local value
6329
+ // let's update the local video value
6317
6330
  if (this.video) {
6318
6331
  this.video = {
6319
6332
  deviceId: {
@@ -6348,12 +6361,21 @@ class WebRTCClient extends Emitter {
6348
6361
  return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
6349
6362
  const videoTrack = stream.getVideoTracks()[0];
6350
6363
  let sender = pc && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
6364
+ let wasTrackEnabled = false;
6351
6365
  if (!sender) {
6352
6366
  sender = pc && pc.getSenders().find(s => !s.track);
6353
6367
  }
6354
6368
 
6355
6369
  if (sender) {
6356
- sender.replaceTrack(videoTrack);
6370
+ // No video track means video not enabled
6371
+ wasTrackEnabled = sender.track ? sender.track.enabled : false;
6372
+ videoTrack.enabled = wasTrackEnabled;
6373
+
6374
+ if (!wasTrackEnabled) {
6375
+ videoTrack.stop();
6376
+ }
6377
+
6378
+ sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
6357
6379
  }
6358
6380
 
6359
6381
  // let's update the local stream
@@ -7037,6 +7059,7 @@ class WebRTCClient extends Emitter {
7037
7059
 
7038
7060
  this.updateRemoteStream(this.getSipSessionId(session));
7039
7061
 
7062
+ const pc = session.sessionDescriptionHandler.peerConnection;
7040
7063
  const onTrack = (event ) => {
7041
7064
  const isAudioOnly = this._isAudioOnly(session);
7042
7065
  const { kind, label, readyState, id, muted } = event.track;
@@ -7056,6 +7079,12 @@ class WebRTCClient extends Emitter {
7056
7079
 
7057
7080
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
7058
7081
 
7082
+ pc.oniceconnectionstatechange = () => {
7083
+ if (pc.iceConnectionState === 'disconnected') {
7084
+ this.eventEmitter.emit(ON_DISCONNECTED);
7085
+ }
7086
+ };
7087
+
7059
7088
  if (withEvent) {
7060
7089
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
7061
7090
  }
@@ -7267,25 +7296,33 @@ class WebRTCClient extends Emitter {
7267
7296
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
7268
7297
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
7269
7298
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
7299
+ const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
7300
+ const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
7270
7301
  let audioBytesSent = 0;
7271
7302
  let audioBytesReceived = 0;
7272
7303
  let videoBytesSent = 0;
7273
7304
  let videoBytesReceived = 0;
7305
+ let transportSent = 0;
7306
+ let transportReceived = 0;
7307
+ let packetsLost = 0;
7274
7308
 
7275
7309
  stats.forEach(report => {
7276
7310
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
7311
+ audioBytesSent += report.bytesSent + report.headerBytesSent;
7312
+ }
7313
+ if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
7277
7314
  audioBytesSent += report.bytesSent;
7278
7315
  }
7279
7316
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7280
- videoBytesSent += report.bytesSent;
7317
+ videoBytesSent += report.bytesSent + report.headerBytesSent;
7281
7318
  }
7282
7319
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
7283
- networkStats.packetsLost = report.packetsLost;
7320
+ packetsLost += report.packetsLost;
7284
7321
  networkStats.packetsReceived = report.packetsReceived;
7285
- audioBytesReceived += report.bytesReceived;
7322
+ audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
7286
7323
  }
7287
7324
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
7288
- videoBytesReceived += report.bytesReceived;
7325
+ videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
7289
7326
  }
7290
7327
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7291
7328
  if ('framesPerSecond' in report) {
@@ -7297,19 +7334,32 @@ class WebRTCClient extends Emitter {
7297
7334
  }
7298
7335
  }
7299
7336
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
7337
+ packetsLost += report.packetsLost;
7300
7338
  networkStats.roundTripTime = report.roundTripTime;
7301
7339
  networkStats.jitter = report.jitter;
7302
7340
  }
7341
+ if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
7342
+ packetsLost += report.packetsLost;
7343
+ }
7344
+ if (report.type === 'transport') {
7345
+ transportSent += report.bytesSent;
7346
+ transportReceived += report.bytesReceived;
7347
+ }
7303
7348
  });
7304
7349
 
7350
+ networkStats.packetsLost = packetsLost;
7305
7351
  networkStats.audioBytesSent = audioBytesSent;
7306
7352
  networkStats.audioBytesReceived = audioBytesReceived;
7307
7353
  networkStats.videoBytesSent = videoBytesSent;
7308
7354
  networkStats.videoBytesReceived = videoBytesReceived;
7355
+ networkStats.transportSent = transportSent;
7356
+ networkStats.transportReceived = transportReceived;
7357
+
7358
+ const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
7359
+ + (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
7360
+ + (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
7309
7361
 
7310
- networkStats.bandwidth = (networkStats.audioBytesSent - lastAudioSent)
7311
- + (networkStats.videoBytesSent - lastVideoSent) + (networkStats.audioBytesReceived - lastAudioReceived)
7312
- + (networkStats.videoBytesReceived - lastVideoReceived);
7362
+ networkStats.bandwidth = bandwidth;
7313
7363
 
7314
7364
  this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
7315
7365
  this.sessionNetworkStats[sessionId].push(networkStats);
@@ -599,7 +599,7 @@ class IssueReporter {
599
599
  payload._retry = retry + 1;
600
600
  }
601
601
 
602
- this._sendDebugToGrafana(body, retry + 1);
602
+ this._sendDebugToGrafana(payload, retry + 1);
603
603
  }, 5000 + retry * 1000);
604
604
  });
605
605
  }
@@ -2791,7 +2791,8 @@ class ExternalApp {
2791
2791
 
2792
2792
 
2793
2793
 
2794
-
2794
+
2795
+
2795
2796
 
2796
2797
 
2797
2798
  class Meeting {
@@ -2803,6 +2804,7 @@ class Meeting {
2803
2804
 
2804
2805
 
2805
2806
 
2807
+
2806
2808
 
2807
2809
 
2808
2810
  static parse(plain ) {
@@ -2814,6 +2816,7 @@ class Meeting {
2814
2816
  port: plain.port,
2815
2817
  uuid: plain.uuid,
2816
2818
  number: plain.number,
2819
+ persistent: plain.persistent,
2817
2820
  });
2818
2821
  }
2819
2822
 
@@ -2821,7 +2824,7 @@ class Meeting {
2821
2824
  return newFrom(meeting, Meeting);
2822
2825
  }
2823
2826
 
2824
- constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
2827
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
2825
2828
  this.guestSipAuthorization = guestSipAuthorization;
2826
2829
  this.uri = uri;
2827
2830
  this.name = name;
@@ -2829,6 +2832,7 @@ class Meeting {
2829
2832
  this.port = port;
2830
2833
  this.uuid = uuid;
2831
2834
  this.number = number;
2835
+ this.persistent = persistent;
2832
2836
 
2833
2837
  // Useful to compare instead of instanceof with minified code
2834
2838
  this.type = 'Meeting';
@@ -3186,7 +3190,7 @@ class Recording {
3186
3190
 
3187
3191
 
3188
3192
 
3189
- static parseMany(recordings ) {
3193
+ static parseMany(recordings = []) {
3190
3194
  return recordings.map(item => Recording.parse(item));
3191
3195
  }
3192
3196
 
@@ -3312,7 +3316,7 @@ class CallLog {
3312
3316
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3313
3317
  start: moment(plain.start).toDate(),
3314
3318
  end: plain.end ? moment(plain.end).toDate() : null,
3315
- recordings: Recording.parseMany(plain.recordings),
3319
+ recordings: Recording.parseMany(plain.recordings || []),
3316
3320
  });
3317
3321
  }
3318
3322
 
@@ -53,7 +53,7 @@ class Recording {
53
53
 
54
54
 
55
55
 
56
- static parseMany(recordings ) {
56
+ static parseMany(recordings = []) {
57
57
  return recordings.map(item => Recording.parse(item));
58
58
  }
59
59
 
@@ -179,7 +179,7 @@ class CallLog {
179
179
  duration: (plain.duration || 0) * 1000, // duration is in seconds
180
180
  start: moment(plain.start).toDate(),
181
181
  end: plain.end ? moment(plain.end).toDate() : null,
182
- recordings: Recording.parseMany(plain.recordings),
182
+ recordings: Recording.parseMany(plain.recordings || []),
183
183
  });
184
184
  }
185
185
 
@@ -382,7 +382,7 @@ class IssueReporter {
382
382
  payload._retry = retry + 1;
383
383
  }
384
384
 
385
- this._sendDebugToGrafana(body, retry + 1);
385
+ this._sendDebugToGrafana(payload, retry + 1);
386
386
  }, 5000 + retry * 1000);
387
387
  });
388
388
  }
@@ -2585,7 +2585,8 @@ class ExternalApp {
2585
2585
 
2586
2586
 
2587
2587
 
2588
-
2588
+
2589
+
2589
2590
 
2590
2591
 
2591
2592
  class Meeting {
@@ -2597,6 +2598,7 @@ class Meeting {
2597
2598
 
2598
2599
 
2599
2600
 
2601
+
2600
2602
 
2601
2603
 
2602
2604
  static parse(plain ) {
@@ -2608,6 +2610,7 @@ class Meeting {
2608
2610
  port: plain.port,
2609
2611
  uuid: plain.uuid,
2610
2612
  number: plain.number,
2613
+ persistent: plain.persistent,
2611
2614
  });
2612
2615
  }
2613
2616
 
@@ -2615,7 +2618,7 @@ class Meeting {
2615
2618
  return newFrom(meeting, Meeting);
2616
2619
  }
2617
2620
 
2618
- constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
2621
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number, persistent } = {}) {
2619
2622
  this.guestSipAuthorization = guestSipAuthorization;
2620
2623
  this.uri = uri;
2621
2624
  this.name = name;
@@ -2623,6 +2626,7 @@ class Meeting {
2623
2626
  this.port = port;
2624
2627
  this.uuid = uuid;
2625
2628
  this.number = number;
2629
+ this.persistent = persistent;
2626
2630
 
2627
2631
  // Useful to compare instead of instanceof with minified code
2628
2632
  this.type = 'Meeting';
@@ -3186,7 +3190,7 @@ class Recording {
3186
3190
 
3187
3191
 
3188
3192
 
3189
- static parseMany(recordings ) {
3193
+ static parseMany(recordings = []) {
3190
3194
  return recordings.map(item => Recording.parse(item));
3191
3195
  }
3192
3196
 
@@ -3312,7 +3316,7 @@ class CallLog {
3312
3316
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3313
3317
  start: moment(plain.start).toDate(),
3314
3318
  end: plain.end ? moment(plain.end).toDate() : null,
3315
- recordings: Recording.parseMany(plain.recordings),
3319
+ recordings: Recording.parseMany(plain.recordings || []),
3316
3320
  });
3317
3321
  }
3318
3322