@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.
- package/dist/wazo-sdk.js +2 -2
- package/esm/__tests__/__voice__/call.test.js +12 -0
- package/esm/checker/checks/webrtc.js +2 -2
- package/esm/domain/Phone/WebRTCPhone.js +30 -30
- package/esm/simple/Phone.js +3 -3
- package/esm/simple/room/Room.js +2 -2
- package/esm/simple/room/SipRoom.js +2 -2
- package/esm/state-machine/utils.js +8 -3
- package/esm/types/domain/Phone/WebRTCPhone.d.ts +1 -1
- package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
- package/esm/types/simple/Phone.d.ts +1 -1
- package/esm/types/simple/Phone.d.ts.map +1 -1
- package/esm/types/state-machine/utils.d.ts +1 -1
- package/esm/types/state-machine/utils.d.ts.map +1 -1
- package/esm/types/utils/sdp.d.ts +2 -2
- package/esm/types/utils/sdp.d.ts.map +1 -1
- package/esm/types/voice/call.d.ts +1 -0
- package/esm/types/voice/call.d.ts.map +1 -1
- package/esm/types/voice/softphone.d.ts +1 -0
- package/esm/types/voice/softphone.d.ts.map +1 -1
- package/esm/types/web-rtc-client.d.ts +1 -1
- package/esm/types/web-rtc-client.d.ts.map +1 -1
- package/esm/utils/sdp.js +5 -5
- package/esm/utils/webrtc.js +3 -3
- package/esm/voice/call.js +6 -3
- package/esm/voice/softphone.js +11 -5
- package/esm/web-rtc-client.js +33 -31
- package/lib/__tests__/__voice__/call.test.js +12 -0
- package/lib/checker/checks/webrtc.js +1 -1
- package/lib/domain/Phone/WebRTCPhone.js +29 -29
- package/lib/simple/Phone.js +2 -2
- package/lib/simple/room/Room.js +1 -1
- package/lib/simple/room/SipRoom.js +1 -1
- package/lib/state-machine/utils.js +8 -3
- package/lib/types/domain/Phone/WebRTCPhone.d.ts +1 -1
- package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
- package/lib/types/simple/Phone.d.ts +1 -1
- package/lib/types/simple/Phone.d.ts.map +1 -1
- package/lib/types/state-machine/utils.d.ts +1 -1
- package/lib/types/state-machine/utils.d.ts.map +1 -1
- package/lib/types/utils/sdp.d.ts +2 -2
- package/lib/types/utils/sdp.d.ts.map +1 -1
- package/lib/types/voice/call.d.ts +1 -0
- package/lib/types/voice/call.d.ts.map +1 -1
- package/lib/types/voice/softphone.d.ts +1 -0
- package/lib/types/voice/softphone.d.ts.map +1 -1
- package/lib/types/web-rtc-client.d.ts +1 -1
- package/lib/types/web-rtc-client.d.ts.map +1 -1
- package/lib/utils/sdp.js +7 -7
- package/lib/utils/webrtc.js +2 -2
- package/lib/voice/call.js +5 -2
- package/lib/voice/softphone.js +11 -5
- package/lib/web-rtc-client.js +32 -30
- package/package.json +1 -1
- package/src/__tests__/__voice__/call.test.ts +15 -0
- package/src/checker/checks/webrtc.ts +2 -2
- package/src/domain/Phone/WebRTCPhone.ts +30 -30
- package/src/simple/Phone.ts +3 -3
- package/src/simple/room/Room.ts +2 -2
- package/src/simple/room/SipRoom.ts +2 -2
- package/src/state-machine/utils.ts +10 -3
- package/src/utils/sdp.ts +5 -5
- package/src/utils/webrtc.ts +3 -3
- package/src/voice/call.ts +7 -3
- package/src/voice/softphone.ts +12 -5
- package/src/web-rtc-client.ts +33 -31
package/lib/web-rtc-client.js
CHANGED
|
@@ -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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
821
|
-
referId: (0, sdp_1.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
1223
|
+
return id in this.sipSessions ? this.sipSessions[id.substring(0, sdp_1.SIP_ID_MIN_LENGTH)] : null;
|
|
1222
1224
|
}
|
|
1223
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
@@ -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 {
|
|
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 || !
|
|
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,
|
|
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 &&
|
|
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 =
|
|
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:
|
|
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(
|
|
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(
|
|
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 =
|
|
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:
|
|
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:
|
|
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 =
|
|
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 =
|
|
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 &&
|
|
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.
|
|
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.
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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[
|
|
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 =
|
|
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[
|
|
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:
|
|
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:
|
|
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(
|
|
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 =
|
|
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.
|
|
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 ?
|
|
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
|
-
|
|
1694
|
+
getSipCallIdFromCallSession(callSession: CallSession): string | null {
|
|
1695
1695
|
const sipSession = this.findSipSession(callSession);
|
|
1696
|
-
return sipSession ?
|
|
1696
|
+
return sipSession ? getSipCallId(sipSession) : null;
|
|
1697
1697
|
}
|
|
1698
1698
|
|
|
1699
1699
|
_updateCallSession(callSession: CallSession): void {
|
|
1700
|
-
const sipSessionId = this.
|
|
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 =
|
|
1791
|
+
const sessionId = getSipCallId(sipSession);
|
|
1792
1792
|
|
|
1793
1793
|
fromSession = fromSession || this.callSessions[sessionId];
|
|
1794
1794
|
const callSession = new CallSession({
|
package/src/simple/Phone.ts
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
333
|
+
getSipCallId(sipSession: WazoSession): string | null | undefined {
|
|
334
334
|
if (!sipSession || !this.phone) {
|
|
335
335
|
return null;
|
|
336
336
|
}
|
|
337
|
-
return
|
|
337
|
+
return getSipCallId(sipSession);
|
|
338
338
|
}
|
|
339
339
|
|
|
340
340
|
sendMessage(body: string, sipSession?: WazoSession, contentType = 'text/plain'): void {
|
package/src/simple/room/Room.ts
CHANGED
|
@@ -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 {
|
|
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 =
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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.
|