@wazo/sdk 1.0.0-alpha.5 → 1.0.0-alpha.7

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 (66) hide show
  1. package/dist/wazo-sdk.js +2 -2
  2. package/esm/__tests__/__voice__/call.test.js +12 -0
  3. package/esm/checker/checks/webrtc.js +2 -2
  4. package/esm/domain/Phone/WebRTCPhone.js +30 -30
  5. package/esm/simple/Phone.js +3 -3
  6. package/esm/simple/room/Room.js +2 -2
  7. package/esm/simple/room/SipRoom.js +2 -2
  8. package/esm/state-machine/utils.js +8 -3
  9. package/esm/types/domain/Phone/WebRTCPhone.d.ts +1 -1
  10. package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  11. package/esm/types/simple/Phone.d.ts +1 -1
  12. package/esm/types/simple/Phone.d.ts.map +1 -1
  13. package/esm/types/state-machine/utils.d.ts +1 -1
  14. package/esm/types/state-machine/utils.d.ts.map +1 -1
  15. package/esm/types/utils/sdp.d.ts +2 -2
  16. package/esm/types/utils/sdp.d.ts.map +1 -1
  17. package/esm/types/voice/call.d.ts +1 -0
  18. package/esm/types/voice/call.d.ts.map +1 -1
  19. package/esm/types/voice/softphone.d.ts +1 -0
  20. package/esm/types/voice/softphone.d.ts.map +1 -1
  21. package/esm/types/web-rtc-client.d.ts +1 -1
  22. package/esm/types/web-rtc-client.d.ts.map +1 -1
  23. package/esm/utils/sdp.js +5 -5
  24. package/esm/utils/webrtc.js +3 -3
  25. package/esm/voice/call.js +6 -3
  26. package/esm/voice/softphone.js +11 -5
  27. package/esm/web-rtc-client.js +33 -31
  28. package/lib/__tests__/__voice__/call.test.js +12 -0
  29. package/lib/checker/checks/webrtc.js +1 -1
  30. package/lib/domain/Phone/WebRTCPhone.js +29 -29
  31. package/lib/simple/Phone.js +2 -2
  32. package/lib/simple/room/Room.js +1 -1
  33. package/lib/simple/room/SipRoom.js +1 -1
  34. package/lib/state-machine/utils.js +8 -3
  35. package/lib/types/domain/Phone/WebRTCPhone.d.ts +1 -1
  36. package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  37. package/lib/types/simple/Phone.d.ts +1 -1
  38. package/lib/types/simple/Phone.d.ts.map +1 -1
  39. package/lib/types/state-machine/utils.d.ts +1 -1
  40. package/lib/types/state-machine/utils.d.ts.map +1 -1
  41. package/lib/types/utils/sdp.d.ts +2 -2
  42. package/lib/types/utils/sdp.d.ts.map +1 -1
  43. package/lib/types/voice/call.d.ts +1 -0
  44. package/lib/types/voice/call.d.ts.map +1 -1
  45. package/lib/types/voice/softphone.d.ts +1 -0
  46. package/lib/types/voice/softphone.d.ts.map +1 -1
  47. package/lib/types/web-rtc-client.d.ts +1 -1
  48. package/lib/types/web-rtc-client.d.ts.map +1 -1
  49. package/lib/utils/sdp.js +7 -7
  50. package/lib/utils/webrtc.js +2 -2
  51. package/lib/voice/call.js +5 -2
  52. package/lib/voice/softphone.js +11 -5
  53. package/lib/web-rtc-client.js +32 -30
  54. package/package.json +1 -1
  55. package/src/__tests__/__voice__/call.test.ts +15 -0
  56. package/src/checker/checks/webrtc.ts +2 -2
  57. package/src/domain/Phone/WebRTCPhone.ts +30 -30
  58. package/src/simple/Phone.ts +3 -3
  59. package/src/simple/room/Room.ts +2 -2
  60. package/src/simple/room/SipRoom.ts +2 -2
  61. package/src/state-machine/utils.ts +10 -3
  62. package/src/utils/sdp.ts +5 -5
  63. package/src/utils/webrtc.ts +3 -3
  64. package/src/voice/call.ts +7 -3
  65. package/src/voice/softphone.ts +12 -5
  66. package/src/web-rtc-client.ts +33 -31
@@ -85,7 +85,9 @@ class WebRTCClient extends Emitter_1.default {
85
85
  this.skipRegister = config.skipRegister;
86
86
  this._buildConfig(config, session).then((newConfig) => {
87
87
  this.config = newConfig;
88
- this.userAgent = this.createUserAgent(uaConfigOverrides);
88
+ if (!this.userAgent) {
89
+ this.userAgent = this.createUserAgent(uaConfigOverrides);
90
+ }
89
91
  });
90
92
  this.audioOutputDeviceId = config.audioDeviceOutput;
91
93
  this.audioOutputVolume = config.audioOutputVolume || 1;
@@ -218,7 +220,7 @@ class WebRTCClient extends Emitter_1.default {
218
220
  // @ts-ignore: private
219
221
  this.registerer.waitingToggle(false);
220
222
  }
221
- this.eventEmitter.emit(UNREGISTERED);
223
+ this.eventEmitter.emit(UNREGISTERED, error);
222
224
  }
223
225
  });
224
226
  }
@@ -425,7 +427,7 @@ class WebRTCClient extends Emitter_1.default {
425
427
  this._setupSession(session);
426
428
  }
427
429
  if (conference) {
428
- this.conferences[(0, sdp_1.getSipSessionId)(session)] = true;
430
+ this.conferences[(0, sdp_1.getSipCallId)(session)] = true;
429
431
  }
430
432
  const inviteOptions = {
431
433
  requestDelegate: {
@@ -506,7 +508,7 @@ class WebRTCClient extends Emitter_1.default {
506
508
  try {
507
509
  this._stopSendingStats(session);
508
510
  this._cleanupMedia(session);
509
- delete this.sipSessions[(0, sdp_1.getSipSessionId)(session)];
511
+ delete this.sipSessions[(0, sdp_1.getSipCallId)(session)];
510
512
  // Check if Invitation or Inviter (Invitation = incoming call)
511
513
  const isInviter = session instanceof api_1.Inviter;
512
514
  // @see github.com/onsip/SIP.js/blob/f11dfd584bc9788ccfc94e03034020672b738975/src/platform/web/simple-user/simple-user.ts#L1004
@@ -529,7 +531,7 @@ class WebRTCClient extends Emitter_1.default {
529
531
  }
530
532
  // Fetch and emit an event at `interval` with session network stats
531
533
  startNetworkMonitoring(session, interval = 1000) {
532
- const sessionId = (0, sdp_1.getSipSessionId)(session);
534
+ const sessionId = (0, sdp_1.getSipCallId)(session);
533
535
  logger.info('starting network inspection', {
534
536
  id: sessionId,
535
537
  clientId: this.clientId,
@@ -538,7 +540,7 @@ class WebRTCClient extends Emitter_1.default {
538
540
  this.networkMonitoringInterval[sessionId] = setInterval(() => this._fetchNetworkStats(sessionId), interval);
539
541
  }
540
542
  stopNetworkMonitoring(session) {
541
- const sessionId = (0, sdp_1.getSipSessionId)(session);
543
+ const sessionId = (0, sdp_1.getSipCallId)(session);
542
544
  const exists = (sessionId in this.networkMonitoringInterval);
543
545
  logger.info('stopping network inspection', {
544
546
  clientId: this.clientId,
@@ -666,7 +668,7 @@ class WebRTCClient extends Emitter_1.default {
666
668
  (0, webrtc_1.toggleVideo)(session, true);
667
669
  }
668
670
  hold(session, isConference = false, hadVideo = false) {
669
- const sessionId = (0, sdp_1.getSipSessionId)(session);
671
+ const sessionId = (0, sdp_1.getSipCallId)(session);
670
672
  const hasVideo = hadVideo || this.hasLocalVideo(sessionId);
671
673
  logger.info('sdk webrtc hold', {
672
674
  sessionId,
@@ -714,7 +716,7 @@ class WebRTCClient extends Emitter_1.default {
714
716
  });
715
717
  }
716
718
  unhold(session, isConference = false) {
717
- const sessionId = (0, sdp_1.getSipSessionId)(session);
719
+ const sessionId = (0, sdp_1.getSipCallId)(session);
718
720
  const hasVideo = sessionId in this.heldSessions && this.heldSessions[sessionId].hasVideo;
719
721
  logger.info('sdk webrtc unhold', {
720
722
  sessionId,
@@ -729,7 +731,7 @@ class WebRTCClient extends Emitter_1.default {
729
731
  return Promise.resolve();
730
732
  }
731
733
  this.unmute(session);
732
- delete this.heldSessions[(0, sdp_1.getSipSessionId)(session)];
734
+ delete this.heldSessions[(0, sdp_1.getSipCallId)(session)];
733
735
  session.sessionDescriptionHandlerOptionsReInvite = {
734
736
  hold: false,
735
737
  conference: isConference,
@@ -754,7 +756,7 @@ class WebRTCClient extends Emitter_1.default {
754
756
  return this.heldSessions[sessionId];
755
757
  }
756
758
  isCallHeld(session) {
757
- return (0, sdp_1.getSipSessionId)(session) in this.heldSessions;
759
+ return (0, sdp_1.getSipCallId)(session) in this.heldSessions;
758
760
  }
759
761
  isVideoRemotelyHeld(sessionId) {
760
762
  return (0, webrtc_1.isVideoRemotelyHeld)(this.heldSessions[sessionId]);
@@ -764,7 +766,7 @@ class WebRTCClient extends Emitter_1.default {
764
766
  return false;
765
767
  }
766
768
  logger.info('Sending DTMF', {
767
- id: (0, sdp_1.getSipSessionId)(session),
769
+ id: (0, sdp_1.getSipCallId)(session),
768
770
  tone,
769
771
  });
770
772
  return session.sessionDescriptionHandler.sendDtmf(tone);
@@ -781,7 +783,7 @@ class WebRTCClient extends Emitter_1.default {
781
783
  transfer(session, target) {
782
784
  this.hold(session);
783
785
  logger.info('Transfering a session', {
784
- id: (0, sdp_1.getSipSessionId)(session),
786
+ id: (0, sdp_1.getSipCallId)(session),
785
787
  target,
786
788
  });
787
789
  const options = {
@@ -804,21 +806,21 @@ class WebRTCClient extends Emitter_1.default {
804
806
  atxfer(session) {
805
807
  this.hold(session);
806
808
  logger.info('webrtc transfer started', {
807
- id: (0, sdp_1.getSipSessionId)(session),
809
+ id: (0, sdp_1.getSipCallId)(session),
808
810
  });
809
811
  const result = {
810
812
  newSession: null,
811
813
  init: (target) => __awaiter(this, void 0, void 0, function* () {
812
814
  logger.info('webrtc transfer initialized', {
813
- id: (0, sdp_1.getSipSessionId)(session),
815
+ id: (0, sdp_1.getSipCallId)(session),
814
816
  target,
815
817
  });
816
818
  result.newSession = yield this.call(target);
817
819
  }),
818
820
  complete: () => {
819
821
  logger.info('webrtc transfer completed', {
820
- id: (0, sdp_1.getSipSessionId)(session),
821
- referId: (0, sdp_1.getSipSessionId)(result.newSession),
822
+ id: (0, sdp_1.getSipCallId)(session),
823
+ referId: (0, sdp_1.getSipCallId)(result.newSession),
822
824
  });
823
825
  session.refer(result.newSession);
824
826
  },
@@ -990,7 +992,7 @@ class WebRTCClient extends Emitter_1.default {
990
992
  }
991
993
  const sdh = session.sessionDescriptionHandler;
992
994
  const pc = sdh.peerConnection;
993
- const sessionId = (0, sdp_1.getSipSessionId)(session);
995
+ const sessionId = (0, sdp_1.getSipCallId)(session);
994
996
  const localStream = this.getLocalStream(sessionId);
995
997
  logger.info('changing video input device', {
996
998
  id,
@@ -1053,7 +1055,7 @@ class WebRTCClient extends Emitter_1.default {
1053
1055
  const desktop = newConstraints && newConstraints.desktop;
1054
1056
  logger.info('Sending reinvite', {
1055
1057
  clientId: this.clientId,
1056
- id: (0, sdp_1.getSipSessionId)(sipSession),
1058
+ id: (0, sdp_1.getSipCallId)(sipSession),
1057
1059
  newConstraints,
1058
1060
  conference,
1059
1061
  audioOnly,
@@ -1085,7 +1087,7 @@ class WebRTCClient extends Emitter_1.default {
1085
1087
  sipSession.incomingInviteRequest.message.body = response.message.body;
1086
1088
  }
1087
1089
  logger.info('on re-INVITE accepted', {
1088
- id: (0, sdp_1.getSipSessionId)(sipSession),
1090
+ id: (0, sdp_1.getSipCallId)(sipSession),
1089
1091
  wasMuted,
1090
1092
  shouldDoScreenSharing,
1091
1093
  });
@@ -1200,7 +1202,7 @@ class WebRTCClient extends Emitter_1.default {
1200
1202
  }
1201
1203
  onCallEnded(session) {
1202
1204
  this._cleanupMedia(session);
1203
- delete this.sipSessions[(0, sdp_1.getSipSessionId)(session)];
1205
+ delete this.sipSessions[(0, sdp_1.getSipCallId)(session)];
1204
1206
  this._stopSendingStats(session);
1205
1207
  this.stopNetworkMonitoring(session);
1206
1208
  }
@@ -1213,14 +1215,14 @@ class WebRTCClient extends Emitter_1.default {
1213
1215
  this.userAgent.attemptReconnection();
1214
1216
  }
1215
1217
  storeSipSession(session) {
1216
- const id = (0, sdp_1.getSipSessionId)(session);
1218
+ const id = (0, sdp_1.getSipCallId)(session);
1217
1219
  logger.info('storing sip session', { id, clientId: this.clientId });
1218
1220
  this.sipSessions[id] = session;
1219
1221
  }
1220
1222
  getSipSession(id) {
1221
- return id in this.sipSessions ? this.sipSessions[id.substring(0, sdp_1.SIP_ID_LENGTH)] : null;
1223
+ return id in this.sipSessions ? this.sipSessions[id.substring(0, sdp_1.SIP_ID_MIN_LENGTH)] : null;
1222
1224
  }
1223
- getSipSessionIds() {
1225
+ getSipCallIds() {
1224
1226
  return Object.keys(this.sipSessions);
1225
1227
  }
1226
1228
  updateLocalStream(sipSessionId, newStream) {
@@ -1377,7 +1379,7 @@ class WebRTCClient extends Emitter_1.default {
1377
1379
  }
1378
1380
  // Invitation and Inviter extends Session
1379
1381
  _setupSession(session) {
1380
- const sipSessionId = (0, sdp_1.getSipSessionId)(session);
1382
+ const sipSessionId = (0, sdp_1.getSipCallId)(session);
1381
1383
  // When receiving an Invitation, the delegate is not defined.
1382
1384
  if (!session.delegate) {
1383
1385
  session.delegate = {};
@@ -1441,7 +1443,7 @@ class WebRTCClient extends Emitter_1.default {
1441
1443
  _onProgress(session_1) {
1442
1444
  return __awaiter(this, arguments, void 0, function* (session, early = false) {
1443
1445
  yield this._setupMedias(session);
1444
- const sessionId = (0, sdp_1.getSipSessionId)(session).substr(0, 20);
1446
+ const sessionId = (0, sdp_1.getSipCallId)(session).substr(0, 20);
1445
1447
  (0, webrtc_1.updateRemoteStream)(session);
1446
1448
  logger.info('progress received', {
1447
1449
  sessionId,
@@ -1499,7 +1501,7 @@ class WebRTCClient extends Emitter_1.default {
1499
1501
  return;
1500
1502
  }
1501
1503
  // Safari hack, because you cannot call .play() from a non user action
1502
- const sessionId = (0, sdp_1.getSipSessionId)(session);
1504
+ const sessionId = (0, sdp_1.getSipCallId)(session);
1503
1505
  const isConference = this.isConference(sessionId);
1504
1506
  if (sessionId in this.audioElements) {
1505
1507
  logger.info('html element already exists for session', {
@@ -1545,7 +1547,7 @@ class WebRTCClient extends Emitter_1.default {
1545
1547
  });
1546
1548
  }
1547
1549
  _cleanupMedia(session) {
1548
- const sessionId = (0, sdp_1.getSipSessionId)(session);
1550
+ const sessionId = (0, sdp_1.getSipCallId)(session);
1549
1551
  const localStream = this.getLocalStream(sessionId);
1550
1552
  if (localStream) {
1551
1553
  (0, webrtc_1.cleanupStream)(localStream);
@@ -1564,7 +1566,7 @@ class WebRTCClient extends Emitter_1.default {
1564
1566
  };
1565
1567
  if (this._hasAudio() && (0, webrtc_1.isWeb)()) {
1566
1568
  if (session) {
1567
- cleanLocalElement((0, sdp_1.getSipSessionId)(session));
1569
+ cleanLocalElement((0, sdp_1.getSipCallId)(session));
1568
1570
  }
1569
1571
  else {
1570
1572
  Object.keys(this.audioElements).forEach(id => cleanLocalElement(id));
@@ -1584,7 +1586,7 @@ class WebRTCClient extends Emitter_1.default {
1584
1586
  if (!pc) {
1585
1587
  return;
1586
1588
  }
1587
- const sessionId = (0, sdp_1.getSipSessionId)(session);
1589
+ const sessionId = (0, sdp_1.getSipCallId)(session);
1588
1590
  (0, getstats_1.default)(pc, (result) => {
1589
1591
  const { results, internal, nomore } = result, stats = __rest(result, ["results", "internal", "nomore"]);
1590
1592
  this.statsIntervals[sessionId] = nomore;
@@ -1592,7 +1594,7 @@ class WebRTCClient extends Emitter_1.default {
1592
1594
  }, SEND_STATS_DELAY);
1593
1595
  }
1594
1596
  _stopSendingStats(session) {
1595
- const sessionId = (0, sdp_1.getSipSessionId)(session);
1597
+ const sessionId = (0, sdp_1.getSipCallId)(session);
1596
1598
  logger.trace('Check for stopping stats', {
1597
1599
  sessionId,
1598
1600
  ids: Object.keys(this.statsIntervals),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wazo/sdk",
3
- "version": "1.0.0-alpha.5",
3
+ "version": "1.0.0-alpha.7",
4
4
  "description": "Wazo's JavaScript Software Development Kit.",
5
5
  "main": "index.js",
6
6
  "types": "lib/types/index.d.ts",
@@ -133,4 +133,19 @@ describe('Call', () => {
133
133
  expect(softphone.client.hangup).toHaveBeenCalled();
134
134
  });
135
135
  });
136
+
137
+ describe('state propagation', () => {
138
+ it('Should update the call state in events', (done) => {
139
+ const call = new Call(sipCall, softphone);
140
+ // @ts-ignore: private method
141
+ call._sendAction(Actions.MAKE_CALL);
142
+
143
+ call.on('remotelyAccepted', () => {
144
+ expect(call.state).toStrictEqual({ [States.ESTABLISHED]: EstablishedStates.ONGOING });
145
+ done();
146
+ });
147
+
148
+ call.onAccepted();
149
+ });
150
+ });
136
151
  });
@@ -1,5 +1,5 @@
1
1
  /* global MediaStream */
2
- import { getSipSessionId } from '../../utils/sdp';
2
+ import { getSipCallId } from '../../utils/sdp';
3
3
  import WebRTCClient from '../../web-rtc-client';
4
4
 
5
5
  export default {
@@ -36,7 +36,7 @@ export default {
36
36
  client.on(client.REGISTERED, () => {
37
37
  const sipSession = client.call('*10');
38
38
 
39
- if (!sipSession || !getSipSessionId(sipSession)) {
39
+ if (!sipSession || !getSipCallId(sipSession)) {
40
40
  return handleError('Unable to make call through WebRTC');
41
41
  }
42
42
 
@@ -12,7 +12,7 @@ import WazoWebRTCClient from '../../web-rtc-client';
12
12
  import Emitter from '../../utils/Emitter';
13
13
  import IssueReporter from '../../service/IssueReporter';
14
14
  import { PeerConnection, WazoSession } from '../types';
15
- import { getCallDisplayName, getCallNumber, getSipSessionId } from '../../utils/sdp';
15
+ import { getCallDisplayName, getCallNumber, getSipCallId } from '../../utils/sdp';
16
16
  import { downgradeToAudio, getStreamFromConstraints, getWebRtcStats, setLocalMediaStream, upgradeToVideo } from '../../utils/webrtc';
17
17
 
18
18
  export const ON_USER_AGENT = 'onUserAgent';
@@ -360,7 +360,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
360
360
  content: {
361
361
  type: ON_MESSAGE_TRACK_UPDATED,
362
362
  update: isUpgrade ? 'upgrade' : 'downgrade',
363
- sipCallId: sipSession && getSipSessionId(sipSession),
363
+ sipCallId: sipSession && getSipCallId(sipSession),
364
364
  callId: callSession ? callSession.callId : null,
365
365
  number: callSession ? callSession.number : null,
366
366
  },
@@ -369,7 +369,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
369
369
  }
370
370
 
371
371
  _bindEvents(sipSession: WazoSession) {
372
- const sipSessionId = getSipSessionId(sipSession);
372
+ const sipSessionId = getSipCallId(sipSession);
373
373
 
374
374
  if (sipSession instanceof Invitation) {
375
375
  // Monkey patch to know when canceled with the CANCEL message
@@ -437,7 +437,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
437
437
  const [stream] = event.streams;
438
438
  const kind = event && event.track && event.track.kind;
439
439
  logger.info('on track stream called on the peer connection', {
440
- callId: getSipSessionId(sipSession),
440
+ callId: getSipCallId(sipSession),
441
441
  streamId: stream ? stream.id : null,
442
442
  tracks: stream ? stream.getTracks() : null,
443
443
  kind,
@@ -472,9 +472,9 @@ export default class WebRTCPhone extends Emitter implements Phone {
472
472
 
473
473
  const screenTrack = screenShareStream.getVideoTracks()[0];
474
474
  const sipSession = this.currentSipSession;
475
- const pc = sipSession && this.client.getPeerConnection(getSipSessionId(sipSession));
475
+ const pc = sipSession && this.client.getPeerConnection(getSipCallId(sipSession));
476
476
  const sender = pc && pc.getSenders && pc.getSenders().find((s) => s && s.track && s.track.kind === 'video');
477
- const localStream = sipSession && this.client.getLocalStream(getSipSessionId(sipSession));
477
+ const localStream = sipSession && this.client.getLocalStream(getSipCallId(sipSession));
478
478
  const videoTrack = localStream ? localStream.getTracks().find(track => track.kind === 'video') : null;
479
479
  const hadVideo = !!videoTrack;
480
480
 
@@ -549,12 +549,12 @@ export default class WebRTCPhone extends Emitter implements Phone {
549
549
 
550
550
  _onScreenSharing(screenStream: MediaStream, sipSession: WazoSession, callSession: CallSession | null | undefined, hadVideo: boolean, desktop?: boolean | null | undefined) {
551
551
  const screenTrack = screenStream.getVideoTracks()[0];
552
- const sipSessionId = getSipSessionId(sipSession);
552
+ const sipSessionId = getSipCallId(sipSession);
553
553
  const pc = this.client.getPeerConnection(sipSessionId);
554
554
  const sender = pc && pc.getSenders && pc.getSenders().find((s) => s && s.track && s.track.kind === 'video');
555
555
  logger.info('WebRTC phone - on screensharing', {
556
556
  hadVideo,
557
- id: getSipSessionId(sipSession),
557
+ id: getSipCallId(sipSession),
558
558
  screenTrack,
559
559
  });
560
560
 
@@ -562,7 +562,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
562
562
  screenTrack.onended = () => {
563
563
  logger.info('WebRTC phone - on screenshare ended', {
564
564
  hadVideo,
565
- id: getSipSessionId(sipSession),
565
+ id: getSipCallId(sipSession),
566
566
  screenTrack,
567
567
  });
568
568
  this.eventEmitter.emit(ON_SHARE_SCREEN_ENDING, this._createCallSession(sipSession, callSession));
@@ -602,7 +602,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
602
602
  this.currentSipSession = sipSession;
603
603
  this.currentCallSession = callSession;
604
604
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'call accepted');
605
- const sipSessionId = getSipSessionId(sipSession);
605
+ const sipSessionId = getSipCallId(sipSession);
606
606
 
607
607
  if (sipSessionId) {
608
608
  this.removeIncomingSessions(sipSessionId);
@@ -674,7 +674,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
674
674
  }
675
675
 
676
676
  _onCallTerminated(sipSession: WazoSession): boolean {
677
- const sipSessionId = getSipSessionId(sipSession);
677
+ const sipSessionId = getSipCallId(sipSession);
678
678
 
679
679
  logger.info('WebRTC phone - on call terminated', {
680
680
  sipId: sipSession.id,
@@ -788,7 +788,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
788
788
  return false;
789
789
  }
790
790
 
791
- return this.currentSipSession && getSipSessionId(this.currentSipSession) === callSession.getId();
791
+ return this.currentSipSession && getSipCallId(this.currentSipSession) === callSession.getId();
792
792
  }
793
793
 
794
794
  hasVideo(callSession: CallSession): boolean {
@@ -831,7 +831,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
831
831
  return Promise.resolve(null);
832
832
  }
833
833
 
834
- const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
834
+ const sipSessionId = this.getSipCallIdFromCallSession(callSession);
835
835
 
836
836
  if (sipSessionId && !(sipSessionId in this.callSessions)) {
837
837
  logger.warn('Call session already ended or not found, can\'t accept it.', {
@@ -872,7 +872,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
872
872
 
873
873
  logger.warn(error, {
874
874
  id: callSession ? callSession.getId() : 'n/a',
875
- ids: this.client.getSipSessionIds(),
875
+ ids: this.client.getSipCallIds(),
876
876
  });
877
877
 
878
878
  if (callSession) {
@@ -980,7 +980,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
980
980
  return new Promise((resolve, reject) => reject(new Error('No session to hold')));
981
981
  }
982
982
 
983
- const sessionId = getSipSessionId(sipSession);
983
+ const sessionId = getSipCallId(sipSession);
984
984
  const hasVideo = this.client.hasLocalVideo(sessionId);
985
985
  logger.info('WebRTC hold sip session', {
986
986
  sipId: sipSession.id,
@@ -1014,7 +1014,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1014
1014
  }
1015
1015
 
1016
1016
  const isConference = !!callSession && callSession.isConference();
1017
- const sessionId = getSipSessionId(sipSession);
1017
+ const sessionId = getSipCallId(sipSession);
1018
1018
  logger.info('WebRTC unhold sip session', {
1019
1019
  sessionId,
1020
1020
  isConference,
@@ -1296,7 +1296,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1296
1296
  console.error('Call is unknown to the WebRTC phone', callSession ? callSession.sipCallId : null, callSession ? callSession.callId : null);
1297
1297
  return false;
1298
1298
  }
1299
- const sipSessionId = getSipSessionId(sipSession);
1299
+ const sipSessionId = getSipCallId(sipSession);
1300
1300
 
1301
1301
  logger.info('WebRTC hangup', {
1302
1302
  sipId: sipSession.id,
@@ -1527,13 +1527,13 @@ export default class WebRTCPhone extends Emitter implements Phone {
1527
1527
  // if `_createCallSession` is called too soon `hasVideo` will return false because the stream doesn't exists yet
1528
1528
  setTimeout(() => {
1529
1529
  // Update callSession
1530
- this._createCallSession(sipSession, this.callSessions[getSipSessionId(sipSession)]);
1530
+ this._createCallSession(sipSession, this.callSessions[getSipCallId(sipSession)]);
1531
1531
 
1532
1532
  this.eventEmitter.emit.apply(this.eventEmitter, [this.client.ON_REINVITE, ...args]);
1533
1533
  }, 2000);
1534
1534
  });
1535
1535
  this.client.on(this.client.ACCEPTED, async (sipSession: WazoSession) => {
1536
- const sessionId = getSipSessionId(sipSession);
1536
+ const sessionId = getSipCallId(sipSession);
1537
1537
  const hasSession = (sessionId in this.callSessions);
1538
1538
  logger.info('WebRTC call accepted', {
1539
1539
  sipId: sessionId,
@@ -1565,7 +1565,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1565
1565
 
1566
1566
  // `_createCallSession` add the CallSession in `this.callSessions`.
1567
1567
  // so we have to remove it or `callCount` will always return 1 even if the call was rejected
1568
- delete this.callSessions[getSipSessionId(session)];
1568
+ delete this.callSessions[getSipCallId(session)];
1569
1569
 
1570
1570
  callSession.endTime = new Date();
1571
1571
 
@@ -1585,7 +1585,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1585
1585
  const callSession = this._createCallSession(session, null, {
1586
1586
  incoming: false,
1587
1587
  ringing: true,
1588
- callId: getSipSessionId(session),
1588
+ callId: getSipCallId(session),
1589
1589
  });
1590
1590
 
1591
1591
  this.eventEmitter.emit(ON_PROGRESS, callSession, this.audioOutputDeviceId, this.audioOutputVolume);
@@ -1596,7 +1596,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1596
1596
  const callSession = this._createCallSession(session, null, {
1597
1597
  incoming: false,
1598
1598
  ringing: true,
1599
- callId: getSipSessionId(session),
1599
+ callId: getSipCallId(session),
1600
1600
  });
1601
1601
 
1602
1602
  this.eventEmitter.emit(ON_EARLY_MEDIA, callSession, this.audioOutputDeviceId, this.audioOutputVolume);
@@ -1657,12 +1657,12 @@ export default class WebRTCPhone extends Emitter implements Phone {
1657
1657
  this.eventEmitter.emit(ON_MESSAGE, message);
1658
1658
  });
1659
1659
  this.client.on(this.client.ON_NETWORK_STATS, (session, stats, previousStats) => {
1660
- const callSession = this.getCallSession(getSipSessionId(session));
1660
+ const callSession = this.getCallSession(getSipCallId(session));
1661
1661
  this.eventEmitter.emit(ON_NETWORK_STATS, callSession, stats, previousStats);
1662
1662
  });
1663
1663
  // Used when upgrading directly in screenshare mode
1664
1664
  this.client.on(this.client.ON_SCREEN_SHARING_REINVITE, (sipSession: WazoSession, response: any, desktop: boolean) => {
1665
- const sipSessionId = getSipSessionId(sipSession);
1665
+ const sipSessionId = getSipCallId(sipSession);
1666
1666
  const localStream = this.client.getLocalStream(sipSessionId);
1667
1667
  const callSession = this.callSessions[sipSessionId];
1668
1668
  logger.info('Updrading directly in screensharing mode', {
@@ -1676,11 +1676,11 @@ export default class WebRTCPhone extends Emitter implements Phone {
1676
1676
 
1677
1677
  // Find a corresponding sipSession from a CallSession
1678
1678
  findSipSession(callSession?: CallSession): WazoSession | null | undefined {
1679
- const keys = this.client.getSipSessionIds();
1679
+ const keys = this.client.getSipCallIds();
1680
1680
  const keyIndex = keys.findIndex(sessionId => callSession && callSession.isId(sessionId));
1681
1681
 
1682
1682
  if (keyIndex === -1) {
1683
- const currentSipSessionId = this.currentSipSession ? getSipSessionId(this.currentSipSession) : this.client.getSipSessionIds()[0];
1683
+ const currentSipSessionId = this.currentSipSession ? getSipCallId(this.currentSipSession) : this.client.getSipCallIds()[0];
1684
1684
  return currentSipSessionId ? this.client.getSipSession(currentSipSessionId) : null;
1685
1685
  }
1686
1686
 
@@ -1691,13 +1691,13 @@ export default class WebRTCPhone extends Emitter implements Phone {
1691
1691
  return this.callSessions[sipSessionId];
1692
1692
  }
1693
1693
 
1694
- getSipSessionIdFromCallSession(callSession: CallSession): string | null {
1694
+ getSipCallIdFromCallSession(callSession: CallSession): string | null {
1695
1695
  const sipSession = this.findSipSession(callSession);
1696
- return sipSession ? getSipSessionId(sipSession) : null;
1696
+ return sipSession ? getSipCallId(sipSession) : null;
1697
1697
  }
1698
1698
 
1699
1699
  _updateCallSession(callSession: CallSession): void {
1700
- const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
1700
+ const sipSessionId = this.getSipCallIdFromCallSession(callSession);
1701
1701
 
1702
1702
  if (sipSessionId) {
1703
1703
  this.callSessions[sipSessionId] = callSession;
@@ -1788,7 +1788,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1788
1788
  const number = getCallNumber(sipSession);
1789
1789
  const displayName = getCallDisplayName(sipSession);
1790
1790
  const { state } = sipSession || {};
1791
- const sessionId = getSipSessionId(sipSession);
1791
+ const sessionId = getSipCallId(sipSession);
1792
1792
 
1793
1793
  fromSession = fromSession || this.callSessions[sessionId];
1794
1794
  const callSession = new CallSession({
@@ -12,7 +12,7 @@ import Emitter from '../utils/Emitter';
12
12
  import Wazo from './index';
13
13
  import SFUNotAvailableError from '../domain/SFUNotAvailableError';
14
14
  import { WazoSession, WebRtcConfig } from '../domain/types';
15
- import { getSipSessionId } from '../utils/sdp';
15
+ import { getSipCallId } from '../utils/sdp';
16
16
 
17
17
  const logger = IssueReporter.loggerFor('simple-phone');
18
18
  const sipLogger = IssueReporter.loggerFor('sip.js');
@@ -330,11 +330,11 @@ export class Phone extends Emitter {
330
330
  return this.phone ? this.phone.stopNetworkMonitoring(callSession) : null;
331
331
  }
332
332
 
333
- getSipSessionId(sipSession: WazoSession): string | null | undefined {
333
+ getSipCallId(sipSession: WazoSession): string | null | undefined {
334
334
  if (!sipSession || !this.phone) {
335
335
  return null;
336
336
  }
337
- return getSipSessionId(sipSession);
337
+ return getSipCallId(sipSession);
338
338
  }
339
339
 
340
340
  sendMessage(body: string, sipSession?: WazoSession, contentType = 'text/plain'): void {
@@ -10,7 +10,7 @@ import RemoteParticipant from './RemoteParticipant';
10
10
  import IssueReporter from '../../service/IssueReporter';
11
11
  import LocalParticipant from './LocalParticipant';
12
12
  import { PeerConnection, WazoSession } from '../../domain/types';
13
- import { getSipSessionId } from '../../utils/sdp';
13
+ import { getSipCallId } from '../../utils/sdp';
14
14
 
15
15
  export const SIGNAL_TYPE_PARTICIPANT_UPDATE = 'signal/PARTICIPANT_UPDATE';
16
16
  export const SIGNAL_TYPE_PARTICIPANT_REQUEST = 'signal/PARTICIPANT_REQUEST';
@@ -498,7 +498,7 @@ class Room extends Emitter {
498
498
  this.audioStream = stream;
499
499
 
500
500
  if (!this.roomAudioElement) {
501
- const sessionId = getSipSessionId(Wazo.Phone.phone?.currentSipSession as WazoSession);
501
+ const sessionId = getSipCallId(Wazo.Phone.phone?.currentSipSession as WazoSession);
502
502
  this.roomAudioElement = await Wazo.Phone.phone?.createAudioElementFor(sessionId as string) as HTMLAudioElement;
503
503
  this.roomAudioElement.srcObject = stream;
504
504
  } else {
@@ -4,7 +4,7 @@ import IssueReporter from '../../service/IssueReporter';
4
4
  import Wazo from '../index';
5
5
  import Room from './Room';
6
6
  import { WazoSession } from '../../domain/types';
7
- import { getSipSessionId } from '../../utils/sdp';
7
+ import { getSipCallId } from '../../utils/sdp';
8
8
 
9
9
  const logger = IssueReporter.loggerFor('sdk-sip-room');
10
10
 
@@ -157,7 +157,7 @@ class SipRoom extends Room {
157
157
  }
158
158
 
159
159
  _getCurrentSipCallIs() {
160
- return getSipSessionId(Wazo.Phone.phone?.currentSipSession as WazoSession);
160
+ return getSipCallId(Wazo.Phone.phone?.currentSipSession as WazoSession);
161
161
  }
162
162
 
163
163
  }
@@ -16,8 +16,15 @@ export const can = (actor: SoftphoneActorRef | CallActorRef, action: SoftphoneAc
16
16
  return actor.getSnapshot().can({ type: action });
17
17
  };
18
18
 
19
- export const hasState = (actor: SoftphoneActorRef | CallActorRef, state: SoftphoneStates | CallStates): boolean => {
20
- return getState(actor) === state;
19
+ export const hasState = (actor: SoftphoneActorRef | CallActorRef, state: SoftphoneStates | CallStates, innerState?: EstablishedStateTypes): boolean => {
20
+ const currentState = getState(actor);
21
+
22
+ // When using nested states, we'll have an object here
23
+ if (typeof currentState === 'object') {
24
+ return innerState ? state in currentState && currentState[state as CallStates] === innerState : state in currentState;
25
+ }
26
+
27
+ return currentState === state;
21
28
  };
22
29
 
23
30
  export const waitUntilState = (actor: SoftphoneActorRef | CallActorRef, state: SoftphoneStates | CallStates, timeout = 5000): Promise<unknown> => {
@@ -45,7 +52,7 @@ export const assertCan = (actor: SoftphoneActorRef | CallActorRef, action: Softp
45
52
 
46
53
  export const assertState = (actor: SoftphoneActorRef | CallActorRef, state: SoftphoneStates | CallStates): void => {
47
54
  if (!hasState(actor, state)) {
48
- const message = `Invalid state ${state}`;
55
+ const message = `Invalid state ${state}, has state ${getState(actor)}`;
49
56
  logger.warn(message);
50
57
 
51
58
  throw new InvalidState(message, state);
package/src/utils/sdp.ts CHANGED
@@ -6,7 +6,7 @@ import { URI } from 'sip.js/lib/grammar/uri';
6
6
 
7
7
  import type { SipCall } from '../domain/types';
8
8
 
9
- export const SIP_ID_LENGTH = 36;
9
+ export const SIP_ID_MIN_LENGTH = 20;
10
10
 
11
11
  export type Candidate = {
12
12
  foundation: string;
@@ -147,25 +147,25 @@ export const addIcesInAllBundles = (sdp: string) => {
147
147
  return sdpParser.write(parsedSdp);
148
148
  };
149
149
 
150
- export const getSipSessionId = (sipSession: SipCall | null | undefined): string => {
150
+ export const getSipCallId = (sipSession: SipCall | null | undefined): string => {
151
151
  if (!sipSession) {
152
152
  return '';
153
153
  }
154
154
 
155
155
  const message = sipSession.message as Partial<{ callId?: string }>;
156
156
  if (message?.callId) {
157
- return message.callId.substring(0, SIP_ID_LENGTH);
157
+ return message.callId.substring(0, SIP_ID_MIN_LENGTH);
158
158
  }
159
159
 
160
160
  // For Inviter
161
161
  // @ts-ignore: private
162
162
  if (sipSession instanceof Inviter && sipSession.outgoingRequestMessage) {
163
163
  // @ts-ignore: private
164
- return sipSession.outgoingRequestMessage.callId.substring(0, SIP_ID_LENGTH);
164
+ return sipSession.outgoingRequestMessage.callId.substring(0, SIP_ID_MIN_LENGTH);
165
165
  }
166
166
 
167
167
  // For Invitation
168
- return (sipSession.id || '').substring(0, SIP_ID_LENGTH);
168
+ return (sipSession.id || '').substring(0, SIP_ID_MIN_LENGTH);
169
169
  };
170
170
 
171
171
  // We need to replace 0.0.0.0 to 127.0.0.1 in the sdp to avoid MOH during a createOffer.