@wazo/sdk 0.37.23 → 0.37.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -57
- package/dist/wazo-sdk.js +3 -3
- package/esm/__tests__/api-client.test.js +12 -7
- package/esm/__tests__/web-rtc-client.test.js +47 -20
- package/esm/api/agentd.js +1 -1
- package/esm/api/amid.js +1 -1
- package/esm/api/application.js +1 -1
- package/esm/api/auth.js +1 -1
- package/esm/api/call-logd.js +1 -1
- package/esm/api/calld.js +1 -1
- package/esm/api/chatd.js +1 -1
- package/esm/api/confd.js +11 -6
- package/esm/api/ctid-ng.js +1 -1
- package/esm/api/dird.js +2 -2
- package/esm/api/webhookd.js +1 -1
- package/esm/api-client.js +12 -7
- package/esm/checker/Checker.js +47 -20
- package/esm/checker/checks/aor.js +12 -7
- package/esm/checker/checks/api.js +12 -7
- package/esm/checker/checks/index.js +47 -20
- package/esm/checker/checks/wazo-websocket.js +1 -1
- package/esm/checker/checks/webrtc-transport.js +47 -20
- package/esm/checker/checks/webrtc.js +47 -20
- package/esm/domain/AdHocAPIConference.js +12 -7
- package/esm/domain/Contact.js +1 -1
- package/esm/domain/Features.js +12 -7
- package/esm/domain/Meeting.js +12 -5
- package/esm/domain/Phone/CTIPhone.js +12 -7
- package/esm/domain/Phone/WebRTCPhone.js +34 -6
- package/esm/domain/__tests__/Contact.test.js +1 -1
- package/esm/domain/__tests__/Meeting.test.js +144 -0
- package/esm/index.js +80 -25
- package/esm/lib/WazoSessionDescriptionHandler.js +9 -4
- package/esm/service/CallApi.js +12 -7
- package/esm/service/IssueReporter.js +1 -1
- package/esm/service/__tests__/IssueReporter.test.js +1 -1
- package/esm/service/getApiClient.js +12 -7
- package/esm/simple/Auth.js +80 -25
- package/esm/simple/Configuration.js +80 -25
- package/esm/simple/Directory.js +12 -7
- package/esm/simple/Phone.js +80 -25
- package/esm/simple/Websocket.js +1 -1
- package/esm/simple/index.js +80 -25
- package/esm/simple/room/LocalParticipant.js +80 -25
- package/esm/simple/room/Participant.js +80 -25
- package/esm/simple/room/RemoteParticipant.js +80 -25
- package/esm/simple/room/Room.js +80 -25
- package/esm/simple/room/SipRoom.js +80 -25
- package/esm/simple/room/Stream.js +80 -25
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +80 -25
- package/esm/simple/utils.js +80 -25
- package/esm/types/WebSocketMessage.js +1 -1
- package/esm/utils/__tests__/api-requester.test.js +1 -1
- package/esm/utils/api-requester.js +1 -1
- package/esm/web-rtc-client.js +47 -20
- package/esm/websocket-client.js +1 -1
- package/lib/__tests__/api-client.test.js +12 -7
- package/lib/__tests__/web-rtc-client.test.js +47 -20
- package/lib/api/agentd.js +1 -1
- package/lib/api/amid.js +1 -1
- package/lib/api/application.js +1 -1
- package/lib/api/auth.js +1 -1
- package/lib/api/call-logd.js +1 -1
- package/lib/api/calld.js +1 -1
- package/lib/api/chatd.js +1 -1
- package/lib/api/confd.js +11 -6
- package/lib/api/ctid-ng.js +1 -1
- package/lib/api/dird.js +2 -2
- package/lib/api/webhookd.js +1 -1
- package/lib/api-client.js +12 -7
- package/lib/checker/Checker.js +47 -20
- package/lib/checker/checks/aor.js +12 -7
- package/lib/checker/checks/api.js +12 -7
- package/lib/checker/checks/index.js +47 -20
- package/lib/checker/checks/wazo-websocket.js +1 -1
- package/lib/checker/checks/webrtc-transport.js +47 -20
- package/lib/checker/checks/webrtc.js +47 -20
- package/lib/domain/AdHocAPIConference.js +12 -7
- package/lib/domain/Contact.js +1 -1
- package/lib/domain/Features.js +12 -7
- package/lib/domain/Meeting.js +16 -5
- package/lib/domain/Phone/CTIPhone.js +12 -7
- package/lib/domain/Phone/WebRTCPhone.js +34 -6
- package/lib/domain/__tests__/Contact.test.js +1 -1
- package/lib/domain/__tests__/Meeting.test.js +150 -0
- package/lib/index.js +80 -25
- package/lib/lib/WazoSessionDescriptionHandler.js +9 -4
- package/lib/service/CallApi.js +12 -7
- package/lib/service/IssueReporter.js +1 -1
- package/lib/service/__tests__/IssueReporter.test.js +1 -1
- package/lib/service/getApiClient.js +12 -7
- package/lib/simple/Auth.js +80 -25
- package/lib/simple/Configuration.js +80 -25
- package/lib/simple/Directory.js +12 -7
- package/lib/simple/Phone.js +80 -25
- package/lib/simple/Websocket.js +1 -1
- package/lib/simple/index.js +80 -25
- package/lib/simple/room/LocalParticipant.js +80 -25
- package/lib/simple/room/Participant.js +80 -25
- package/lib/simple/room/RemoteParticipant.js +80 -25
- package/lib/simple/room/Room.js +80 -25
- package/lib/simple/room/SipRoom.js +80 -25
- package/lib/simple/room/Stream.js +80 -25
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +80 -25
- package/lib/simple/utils.js +80 -25
- package/lib/types/WebSocketMessage.js +2 -0
- package/lib/utils/__tests__/api-requester.test.js +1 -1
- package/lib/utils/api-requester.js +1 -1
- package/lib/web-rtc-client.js +47 -20
- package/lib/websocket-client.js +1 -1
- package/package.json +1 -1
- package/src/domain/Contact.js +1 -1
- package/src/domain/Meeting.js +12 -5
- package/src/domain/Phone/WebRTCPhone.js +33 -5
- package/src/domain/__tests__/Meeting.test.js +50 -0
- package/src/lib/WazoSessionDescriptionHandler.js +8 -3
- package/src/utils/api-requester.js +1 -1
- package/src/web-rtc-client.js +27 -10
|
@@ -414,7 +414,7 @@ IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
|
|
|
414
414
|
|
|
415
415
|
// Use a function here to be able to mock it in tests
|
|
416
416
|
const realFetch = () => {
|
|
417
|
-
if (typeof document !== 'undefined') {
|
|
417
|
+
if (typeof document !== 'undefined' && window.fetch) {
|
|
418
418
|
// Browser
|
|
419
419
|
return window.fetch;
|
|
420
420
|
}
|
|
@@ -1060,6 +1060,7 @@ class WebRTCPhone extends Emitter {
|
|
|
1060
1060
|
constraints,
|
|
1061
1061
|
audioOnly,
|
|
1062
1062
|
conference,
|
|
1063
|
+
iceRestart,
|
|
1063
1064
|
});
|
|
1064
1065
|
|
|
1065
1066
|
if (!sipSession) {
|
|
@@ -1163,6 +1164,11 @@ class WebRTCPhone extends Emitter {
|
|
|
1163
1164
|
|
|
1164
1165
|
this.client.downgradeToAudio(sipSession);
|
|
1165
1166
|
|
|
1167
|
+
if (callSession) {
|
|
1168
|
+
callSession.cameraEnabled = false;
|
|
1169
|
+
this._updateCallSession(callSession);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1166
1172
|
if (withMessage) {
|
|
1167
1173
|
this._sendReinviteMessage(callSession, false);
|
|
1168
1174
|
}
|
|
@@ -1190,6 +1196,11 @@ class WebRTCPhone extends Emitter {
|
|
|
1190
1196
|
|
|
1191
1197
|
const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
|
|
1192
1198
|
|
|
1199
|
+
if (callSession) {
|
|
1200
|
+
callSession.cameraEnabled = true;
|
|
1201
|
+
this._updateCallSession(callSession);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1193
1204
|
// If no stream is returned, it means we have to reinvite
|
|
1194
1205
|
if (!newStream) {
|
|
1195
1206
|
return true;
|
|
@@ -1459,7 +1470,7 @@ class WebRTCPhone extends Emitter {
|
|
|
1459
1470
|
}
|
|
1460
1471
|
|
|
1461
1472
|
_onCallAccepted(sipSession , cameraEnabled ) {
|
|
1462
|
-
logger.info('WebRTC phone -
|
|
1473
|
+
logger.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
|
|
1463
1474
|
|
|
1464
1475
|
const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
|
|
1465
1476
|
this.currentSipSession = sipSession;
|
|
@@ -1528,6 +1539,7 @@ class WebRTCPhone extends Emitter {
|
|
|
1528
1539
|
_onCallTerminated(sipSession ) {
|
|
1529
1540
|
logger.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
|
|
1530
1541
|
|
|
1542
|
+
const sipSessionId = this.getSipSessionId(sipSession);
|
|
1531
1543
|
const callSession = this._createCallSession(sipSession);
|
|
1532
1544
|
const isCurrentSession = this.isCurrentCallSipSession(callSession);
|
|
1533
1545
|
const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
|
|
@@ -1545,7 +1557,6 @@ class WebRTCPhone extends Emitter {
|
|
|
1545
1557
|
}, 5);
|
|
1546
1558
|
}
|
|
1547
1559
|
|
|
1548
|
-
const sipSessionId = this.getSipSessionId(sipSession);
|
|
1549
1560
|
if (sipSessionId) {
|
|
1550
1561
|
this.removeIncomingSessions(sipSessionId);
|
|
1551
1562
|
}
|
|
@@ -1971,7 +1982,7 @@ class WebRTCPhone extends Emitter {
|
|
|
1971
1982
|
// @TODO: line is not used here
|
|
1972
1983
|
async makeCall(number , line , cameraEnabled ,
|
|
1973
1984
|
audioOnly = false, conference = false) {
|
|
1974
|
-
logger.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
|
|
1985
|
+
logger.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled, audioOnly, conference });
|
|
1975
1986
|
if (!number) {
|
|
1976
1987
|
return Promise.resolve(null);
|
|
1977
1988
|
}
|
|
@@ -2190,8 +2201,12 @@ class WebRTCPhone extends Emitter {
|
|
|
2190
2201
|
}
|
|
2191
2202
|
|
|
2192
2203
|
const sessionId = this.incomingSessions[0];
|
|
2204
|
+
const sipSession = this.client.getSipSession(sessionId);
|
|
2205
|
+
if (!sipSession) {
|
|
2206
|
+
return null;
|
|
2207
|
+
}
|
|
2193
2208
|
|
|
2194
|
-
return this._createCallSession(
|
|
2209
|
+
return this._createCallSession(sipSession);
|
|
2195
2210
|
}
|
|
2196
2211
|
|
|
2197
2212
|
sendMessage(sipSession = null, body , contentType = 'text/plain') {
|
|
@@ -2332,9 +2347,13 @@ class WebRTCPhone extends Emitter {
|
|
|
2332
2347
|
if (this.shouldSendReinvite && this.currentSipSession
|
|
2333
2348
|
&& this.currentSipSession.state === sessionState.SessionState.Established) {
|
|
2334
2349
|
this.shouldSendReinvite = false;
|
|
2350
|
+
const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
|
|
2351
|
+
const isConference = pc ? pc.sfu : false;
|
|
2352
|
+
const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
|
|
2353
|
+
|
|
2335
2354
|
try {
|
|
2336
2355
|
// Send reinvite with iceRestart
|
|
2337
|
-
this.sendReinvite(this.currentCallSession, null,
|
|
2356
|
+
this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
|
|
2338
2357
|
} catch (e) {
|
|
2339
2358
|
logger.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
|
|
2340
2359
|
}
|
|
@@ -2418,6 +2437,15 @@ class WebRTCPhone extends Emitter {
|
|
|
2418
2437
|
return this.client.getSipSessionId(sipSession);
|
|
2419
2438
|
}
|
|
2420
2439
|
|
|
2440
|
+
_updateCallSession(callSession ) {
|
|
2441
|
+
const sipSession = this.findSipSession(callSession);
|
|
2442
|
+
const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
|
|
2443
|
+
|
|
2444
|
+
if (sipSessionId) {
|
|
2445
|
+
this.callSessions[sipSessionId] = callSession;
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2421
2449
|
_onMessage(message ) {
|
|
2422
2450
|
if (!message || message.method !== 'MESSAGE') {
|
|
2423
2451
|
return;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var moment = require('moment');
|
|
4
|
+
|
|
5
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
6
|
+
|
|
7
|
+
var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
|
|
8
|
+
|
|
9
|
+
//
|
|
10
|
+
|
|
11
|
+
var newFrom = (instance , ToClass ) => {
|
|
12
|
+
const args = {};
|
|
13
|
+
Object.getOwnPropertyNames(instance).forEach(prop => {
|
|
14
|
+
args[prop] = instance[prop];
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return new ToClass(args);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
//
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Meeting {
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
static parse(plain ) {
|
|
48
|
+
return new Meeting({
|
|
49
|
+
guestSipAuthorization: plain.guest_sip_authorization,
|
|
50
|
+
uri: plain.ingress_http_uri,
|
|
51
|
+
name: plain.name,
|
|
52
|
+
ownerUuids: plain.owner_uuids,
|
|
53
|
+
port: plain.port,
|
|
54
|
+
uuid: plain.uuid,
|
|
55
|
+
extension: plain.exten,
|
|
56
|
+
persistent: plain.persistent,
|
|
57
|
+
creationTime: moment__default['default'](plain.creation_time).toDate(),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static parseMany(items ) {
|
|
62
|
+
if (!items) {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
return items.map(plain => Meeting.parse(plain));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static newFrom(meeting ) {
|
|
69
|
+
return newFrom(meeting, Meeting);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
constructor({
|
|
73
|
+
uuid,
|
|
74
|
+
name,
|
|
75
|
+
guestSipAuthorization,
|
|
76
|
+
ownerUuids,
|
|
77
|
+
port,
|
|
78
|
+
uri,
|
|
79
|
+
extension,
|
|
80
|
+
persistent,
|
|
81
|
+
creationTime,
|
|
82
|
+
} = {}) {
|
|
83
|
+
this.guestSipAuthorization = guestSipAuthorization;
|
|
84
|
+
this.uri = uri;
|
|
85
|
+
this.name = name;
|
|
86
|
+
this.ownerUuids = ownerUuids;
|
|
87
|
+
this.port = port;
|
|
88
|
+
this.uuid = uuid;
|
|
89
|
+
this.extension = extension;
|
|
90
|
+
this.persistent = persistent;
|
|
91
|
+
this.creationTime = creationTime;
|
|
92
|
+
|
|
93
|
+
// Useful to compare instead of instanceof with minified code
|
|
94
|
+
this.type = 'Meeting';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
getGuestSipCredentials() {
|
|
98
|
+
// eslint-disable-next-line no-undef
|
|
99
|
+
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
100
|
+
return { username, secret };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//
|
|
105
|
+
|
|
106
|
+
describe('Meeting domain', () => {
|
|
107
|
+
it('can return username and secret from an base64 encrypted string', () => {
|
|
108
|
+
const USERNAME = 'username';
|
|
109
|
+
const SECRET = 'secret';
|
|
110
|
+
|
|
111
|
+
const args = {
|
|
112
|
+
guest_sip_authorization: btoa(`${USERNAME}:${SECRET}`),
|
|
113
|
+
creation_time: '',
|
|
114
|
+
ingress_http_uri: '',
|
|
115
|
+
name: '',
|
|
116
|
+
owner_uuids: [],
|
|
117
|
+
port: '',
|
|
118
|
+
uuid: '',
|
|
119
|
+
exten: '',
|
|
120
|
+
persistent: false,
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const meeting = Meeting.parse(args);
|
|
124
|
+
|
|
125
|
+
const { username, secret } = meeting.getGuestSipCredentials();
|
|
126
|
+
|
|
127
|
+
expect(username).toEqual(USERNAME);
|
|
128
|
+
expect(secret).toEqual(SECRET);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should return a date from a string', () => {
|
|
132
|
+
const args = {
|
|
133
|
+
creation_time: '2021-12-21T15:56:42.880Z',
|
|
134
|
+
guest_sip_authorization: '',
|
|
135
|
+
ingress_http_uri: '',
|
|
136
|
+
name: '',
|
|
137
|
+
owner_uuids: [],
|
|
138
|
+
port: '',
|
|
139
|
+
uuid: '',
|
|
140
|
+
exten: '',
|
|
141
|
+
persistent: false,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const { creationTime } = Meeting.parse(args);
|
|
145
|
+
|
|
146
|
+
expect(creationTime.getDate()).toEqual(21);
|
|
147
|
+
expect(creationTime.getFullYear()).toEqual(2021);
|
|
148
|
+
expect(creationTime.getMonth()).toEqual(11);
|
|
149
|
+
});
|
|
150
|
+
});
|
package/lib/index.js
CHANGED
|
@@ -475,7 +475,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
|
|
|
475
475
|
|
|
476
476
|
// Use a function here to be able to mock it in tests
|
|
477
477
|
const realFetch = () => {
|
|
478
|
-
if (typeof document !== 'undefined') {
|
|
478
|
+
if (typeof document !== 'undefined' && window.fetch) {
|
|
479
479
|
// Browser
|
|
480
480
|
return window.fetch;
|
|
481
481
|
}
|
|
@@ -1935,7 +1935,7 @@ class Contact {
|
|
|
1935
1935
|
this[key] = old[key] || this[key];
|
|
1936
1936
|
});
|
|
1937
1937
|
|
|
1938
|
-
if (old.lineState
|
|
1938
|
+
if (old.lineState) {
|
|
1939
1939
|
this.lineState = old.lineState;
|
|
1940
1940
|
}
|
|
1941
1941
|
|
|
@@ -2642,8 +2642,9 @@ class ExternalApp {
|
|
|
2642
2642
|
|
|
2643
2643
|
|
|
2644
2644
|
|
|
2645
|
-
|
|
2645
|
+
|
|
2646
2646
|
|
|
2647
|
+
|
|
2647
2648
|
|
|
2648
2649
|
|
|
2649
2650
|
class Meeting {
|
|
@@ -2654,9 +2655,10 @@ class Meeting {
|
|
|
2654
2655
|
|
|
2655
2656
|
|
|
2656
2657
|
|
|
2657
|
-
|
|
2658
|
+
|
|
2658
2659
|
|
|
2659
2660
|
|
|
2661
|
+
|
|
2660
2662
|
|
|
2661
2663
|
static parse(plain ) {
|
|
2662
2664
|
return new Meeting({
|
|
@@ -2666,8 +2668,9 @@ class Meeting {
|
|
|
2666
2668
|
ownerUuids: plain.owner_uuids,
|
|
2667
2669
|
port: plain.port,
|
|
2668
2670
|
uuid: plain.uuid,
|
|
2669
|
-
|
|
2671
|
+
extension: plain.exten,
|
|
2670
2672
|
persistent: plain.persistent,
|
|
2673
|
+
creationTime: moment__default['default'](plain.creation_time).toDate(),
|
|
2671
2674
|
});
|
|
2672
2675
|
}
|
|
2673
2676
|
|
|
@@ -2689,8 +2692,9 @@ class Meeting {
|
|
|
2689
2692
|
ownerUuids,
|
|
2690
2693
|
port,
|
|
2691
2694
|
uri,
|
|
2692
|
-
|
|
2695
|
+
extension,
|
|
2693
2696
|
persistent,
|
|
2697
|
+
creationTime,
|
|
2694
2698
|
} = {}) {
|
|
2695
2699
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2696
2700
|
this.uri = uri;
|
|
@@ -2698,8 +2702,9 @@ class Meeting {
|
|
|
2698
2702
|
this.ownerUuids = ownerUuids;
|
|
2699
2703
|
this.port = port;
|
|
2700
2704
|
this.uuid = uuid;
|
|
2701
|
-
this.
|
|
2705
|
+
this.extension = extension;
|
|
2702
2706
|
this.persistent = persistent;
|
|
2707
|
+
this.creationTime = creationTime;
|
|
2703
2708
|
|
|
2704
2709
|
// Useful to compare instead of instanceof with minified code
|
|
2705
2710
|
this.type = 'Meeting';
|
|
@@ -5630,11 +5635,16 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
5630
5635
|
|
|
5631
5636
|
// $FlowFixMe
|
|
5632
5637
|
setRemoteSessionDescription(sessionDescription ) {
|
|
5633
|
-
|
|
5638
|
+
try {
|
|
5639
|
+
const result = super.setRemoteSessionDescription(sessionDescription);
|
|
5634
5640
|
|
|
5635
|
-
|
|
5641
|
+
this.eventEmitter.emit('setDescription', sessionDescription);
|
|
5636
5642
|
|
|
5637
|
-
|
|
5643
|
+
return result;
|
|
5644
|
+
} catch (error) {
|
|
5645
|
+
this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
|
|
5646
|
+
throw error;
|
|
5647
|
+
}
|
|
5638
5648
|
}
|
|
5639
5649
|
|
|
5640
5650
|
// Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
|
|
@@ -6539,7 +6549,7 @@ class WebRTCClient extends Emitter {
|
|
|
6539
6549
|
}
|
|
6540
6550
|
|
|
6541
6551
|
call(number , enableVideo , audioOnly = false, conference = false) {
|
|
6542
|
-
logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
|
|
6552
|
+
logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
|
|
6543
6553
|
const inviterOptions = {
|
|
6544
6554
|
sessionDescriptionHandlerOptionsReInvite: {
|
|
6545
6555
|
conference,
|
|
@@ -7615,6 +7625,7 @@ class WebRTCClient extends Emitter {
|
|
|
7615
7625
|
const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
|
|
7616
7626
|
const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
|
|
7617
7627
|
const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
|
|
7628
|
+
const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
|
|
7618
7629
|
|
|
7619
7630
|
logger$9.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
|
|
7620
7631
|
|
|
@@ -7622,7 +7633,8 @@ class WebRTCClient extends Emitter {
|
|
|
7622
7633
|
constraints: {
|
|
7623
7634
|
// Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
|
|
7624
7635
|
audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
|
|
7625
|
-
video: screenSharing ? (isDesktop
|
|
7636
|
+
video: screenSharing ? (isDesktop
|
|
7637
|
+
? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
|
|
7626
7638
|
: this._getVideoConstraints(enableVideo),
|
|
7627
7639
|
screen: screenSharing,
|
|
7628
7640
|
desktop: isDesktop,
|
|
@@ -7957,12 +7969,14 @@ class WebRTCClient extends Emitter {
|
|
|
7957
7969
|
|
|
7958
7970
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
7959
7971
|
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7972
|
+
if (pc) {
|
|
7973
|
+
pc.oniceconnectionstatechange = () => {
|
|
7974
|
+
logger$9.info('on ice connection state changed', { state: pc.iceConnectionState });
|
|
7975
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
7976
|
+
this.eventEmitter.emit(ON_DISCONNECTED$1);
|
|
7977
|
+
}
|
|
7978
|
+
};
|
|
7979
|
+
}
|
|
7966
7980
|
|
|
7967
7981
|
if (withEvent) {
|
|
7968
7982
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
@@ -8172,13 +8186,17 @@ class WebRTCClient extends Emitter {
|
|
|
8172
8186
|
const nbStats = this.sessionNetworkStats[sessionId].length;
|
|
8173
8187
|
const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
|
|
8174
8188
|
const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
|
|
8189
|
+
const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
|
|
8175
8190
|
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
8176
8191
|
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
8192
|
+
const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
|
|
8177
8193
|
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
8178
8194
|
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
8179
8195
|
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
8180
|
-
let audioBytesSent = 0;
|
|
8181
|
-
let audioBytesReceived = 0;
|
|
8196
|
+
let audioBytesSent = 0; // content + header
|
|
8197
|
+
let audioBytesReceived = 0; // content + header
|
|
8198
|
+
let audioContentSent = 0; // useful to detect blank call
|
|
8199
|
+
let audioContentReceived = 0;
|
|
8182
8200
|
let videoBytesSent = 0;
|
|
8183
8201
|
let videoBytesReceived = 0;
|
|
8184
8202
|
let transportSent = 0;
|
|
@@ -8188,6 +8206,7 @@ class WebRTCClient extends Emitter {
|
|
|
8188
8206
|
stats.forEach(report => {
|
|
8189
8207
|
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
8190
8208
|
audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
|
|
8209
|
+
audioContentSent += Number(report.bytesSent);
|
|
8191
8210
|
}
|
|
8192
8211
|
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
8193
8212
|
audioBytesSent += Number(report.bytesSent);
|
|
@@ -8199,6 +8218,7 @@ class WebRTCClient extends Emitter {
|
|
|
8199
8218
|
packetsLost += Number(report.packetsLost);
|
|
8200
8219
|
networkStats.packetsReceived = Number(report.packetsReceived);
|
|
8201
8220
|
audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
|
|
8221
|
+
audioContentReceived += Number(report.bytesReceived);
|
|
8202
8222
|
}
|
|
8203
8223
|
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
8204
8224
|
videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
|
|
@@ -8227,10 +8247,17 @@ class WebRTCClient extends Emitter {
|
|
|
8227
8247
|
});
|
|
8228
8248
|
|
|
8229
8249
|
networkStats.packetsLost = packetsLost;
|
|
8250
|
+
|
|
8230
8251
|
networkStats.totalAudioBytesSent = audioBytesSent;
|
|
8231
8252
|
networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
|
|
8232
8253
|
networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
|
|
8233
8254
|
networkStats.audioBytesReceived = audioBytesReceived;
|
|
8255
|
+
|
|
8256
|
+
networkStats.totalAudioContentSent = audioContentSent;
|
|
8257
|
+
networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
|
|
8258
|
+
networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
|
|
8259
|
+
networkStats.audioContentReceived = audioContentReceived;
|
|
8260
|
+
|
|
8234
8261
|
networkStats.totalVideoBytesSent = videoBytesSent;
|
|
8235
8262
|
networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
|
|
8236
8263
|
networkStats.totalVideoBytesReceived = videoBytesReceived;
|
|
@@ -9335,6 +9362,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9335
9362
|
constraints,
|
|
9336
9363
|
audioOnly,
|
|
9337
9364
|
conference,
|
|
9365
|
+
iceRestart,
|
|
9338
9366
|
});
|
|
9339
9367
|
|
|
9340
9368
|
if (!sipSession) {
|
|
@@ -9438,6 +9466,11 @@ class WebRTCPhone extends Emitter {
|
|
|
9438
9466
|
|
|
9439
9467
|
this.client.downgradeToAudio(sipSession);
|
|
9440
9468
|
|
|
9469
|
+
if (callSession) {
|
|
9470
|
+
callSession.cameraEnabled = false;
|
|
9471
|
+
this._updateCallSession(callSession);
|
|
9472
|
+
}
|
|
9473
|
+
|
|
9441
9474
|
if (withMessage) {
|
|
9442
9475
|
this._sendReinviteMessage(callSession, false);
|
|
9443
9476
|
}
|
|
@@ -9465,6 +9498,11 @@ class WebRTCPhone extends Emitter {
|
|
|
9465
9498
|
|
|
9466
9499
|
const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
|
|
9467
9500
|
|
|
9501
|
+
if (callSession) {
|
|
9502
|
+
callSession.cameraEnabled = true;
|
|
9503
|
+
this._updateCallSession(callSession);
|
|
9504
|
+
}
|
|
9505
|
+
|
|
9468
9506
|
// If no stream is returned, it means we have to reinvite
|
|
9469
9507
|
if (!newStream) {
|
|
9470
9508
|
return true;
|
|
@@ -9734,7 +9772,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9734
9772
|
}
|
|
9735
9773
|
|
|
9736
9774
|
_onCallAccepted(sipSession , cameraEnabled ) {
|
|
9737
|
-
logger$7.info('WebRTC phone -
|
|
9775
|
+
logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
|
|
9738
9776
|
|
|
9739
9777
|
const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
|
|
9740
9778
|
this.currentSipSession = sipSession;
|
|
@@ -9803,6 +9841,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9803
9841
|
_onCallTerminated(sipSession ) {
|
|
9804
9842
|
logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
|
|
9805
9843
|
|
|
9844
|
+
const sipSessionId = this.getSipSessionId(sipSession);
|
|
9806
9845
|
const callSession = this._createCallSession(sipSession);
|
|
9807
9846
|
const isCurrentSession = this.isCurrentCallSipSession(callSession);
|
|
9808
9847
|
const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
|
|
@@ -9820,7 +9859,6 @@ class WebRTCPhone extends Emitter {
|
|
|
9820
9859
|
}, 5);
|
|
9821
9860
|
}
|
|
9822
9861
|
|
|
9823
|
-
const sipSessionId = this.getSipSessionId(sipSession);
|
|
9824
9862
|
if (sipSessionId) {
|
|
9825
9863
|
this.removeIncomingSessions(sipSessionId);
|
|
9826
9864
|
}
|
|
@@ -10246,7 +10284,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10246
10284
|
// @TODO: line is not used here
|
|
10247
10285
|
async makeCall(number , line , cameraEnabled ,
|
|
10248
10286
|
audioOnly = false, conference = false) {
|
|
10249
|
-
logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
|
|
10287
|
+
logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled, audioOnly, conference });
|
|
10250
10288
|
if (!number) {
|
|
10251
10289
|
return Promise.resolve(null);
|
|
10252
10290
|
}
|
|
@@ -10465,8 +10503,12 @@ class WebRTCPhone extends Emitter {
|
|
|
10465
10503
|
}
|
|
10466
10504
|
|
|
10467
10505
|
const sessionId = this.incomingSessions[0];
|
|
10506
|
+
const sipSession = this.client.getSipSession(sessionId);
|
|
10507
|
+
if (!sipSession) {
|
|
10508
|
+
return null;
|
|
10509
|
+
}
|
|
10468
10510
|
|
|
10469
|
-
return this._createCallSession(
|
|
10511
|
+
return this._createCallSession(sipSession);
|
|
10470
10512
|
}
|
|
10471
10513
|
|
|
10472
10514
|
sendMessage(sipSession = null, body , contentType = 'text/plain') {
|
|
@@ -10607,9 +10649,13 @@ class WebRTCPhone extends Emitter {
|
|
|
10607
10649
|
if (this.shouldSendReinvite && this.currentSipSession
|
|
10608
10650
|
&& this.currentSipSession.state === sessionState.SessionState.Established) {
|
|
10609
10651
|
this.shouldSendReinvite = false;
|
|
10652
|
+
const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
|
|
10653
|
+
const isConference = pc ? pc.sfu : false;
|
|
10654
|
+
const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
|
|
10655
|
+
|
|
10610
10656
|
try {
|
|
10611
10657
|
// Send reinvite with iceRestart
|
|
10612
|
-
this.sendReinvite(this.currentCallSession, null,
|
|
10658
|
+
this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
|
|
10613
10659
|
} catch (e) {
|
|
10614
10660
|
logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
|
|
10615
10661
|
}
|
|
@@ -10693,6 +10739,15 @@ class WebRTCPhone extends Emitter {
|
|
|
10693
10739
|
return this.client.getSipSessionId(sipSession);
|
|
10694
10740
|
}
|
|
10695
10741
|
|
|
10742
|
+
_updateCallSession(callSession ) {
|
|
10743
|
+
const sipSession = this.findSipSession(callSession);
|
|
10744
|
+
const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
|
|
10745
|
+
|
|
10746
|
+
if (sipSessionId) {
|
|
10747
|
+
this.callSessions[sipSessionId] = callSession;
|
|
10748
|
+
}
|
|
10749
|
+
}
|
|
10750
|
+
|
|
10696
10751
|
_onMessage(message ) {
|
|
10697
10752
|
if (!message || message.method !== 'MESSAGE') {
|
|
10698
10753
|
return;
|
|
@@ -25,7 +25,7 @@ IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
|
|
|
25
25
|
|
|
26
26
|
// Use a function here to be able to mock it in tests
|
|
27
27
|
const realFetch = () => {
|
|
28
|
-
if (typeof document !== 'undefined') {
|
|
28
|
+
if (typeof document !== 'undefined' && window.fetch) {
|
|
29
29
|
// Browser
|
|
30
30
|
return window.fetch;
|
|
31
31
|
}
|
|
@@ -497,11 +497,16 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
497
497
|
|
|
498
498
|
// $FlowFixMe
|
|
499
499
|
setRemoteSessionDescription(sessionDescription ) {
|
|
500
|
-
|
|
500
|
+
try {
|
|
501
|
+
const result = super.setRemoteSessionDescription(sessionDescription);
|
|
501
502
|
|
|
502
|
-
|
|
503
|
+
this.eventEmitter.emit('setDescription', sessionDescription);
|
|
503
504
|
|
|
504
|
-
|
|
505
|
+
return result;
|
|
506
|
+
} catch (error) {
|
|
507
|
+
this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
|
|
508
|
+
throw error;
|
|
509
|
+
}
|
|
505
510
|
}
|
|
506
511
|
|
|
507
512
|
// Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
|
package/lib/service/CallApi.js
CHANGED
|
@@ -1416,7 +1416,7 @@ class Contact {
|
|
|
1416
1416
|
this[key] = old[key] || this[key];
|
|
1417
1417
|
});
|
|
1418
1418
|
|
|
1419
|
-
if (old.lineState
|
|
1419
|
+
if (old.lineState) {
|
|
1420
1420
|
this.lineState = old.lineState;
|
|
1421
1421
|
}
|
|
1422
1422
|
|
|
@@ -2472,7 +2472,7 @@ const logger$1 = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
|
|
|
2472
2472
|
|
|
2473
2473
|
// Use a function here to be able to mock it in tests
|
|
2474
2474
|
const realFetch = () => {
|
|
2475
|
-
if (typeof document !== 'undefined') {
|
|
2475
|
+
if (typeof document !== 'undefined' && window.fetch) {
|
|
2476
2476
|
// Browser
|
|
2477
2477
|
return window.fetch;
|
|
2478
2478
|
}
|
|
@@ -3151,8 +3151,9 @@ class ExternalApp {
|
|
|
3151
3151
|
|
|
3152
3152
|
|
|
3153
3153
|
|
|
3154
|
-
|
|
3154
|
+
|
|
3155
3155
|
|
|
3156
|
+
|
|
3156
3157
|
|
|
3157
3158
|
|
|
3158
3159
|
class Meeting {
|
|
@@ -3163,9 +3164,10 @@ class Meeting {
|
|
|
3163
3164
|
|
|
3164
3165
|
|
|
3165
3166
|
|
|
3166
|
-
|
|
3167
|
+
|
|
3167
3168
|
|
|
3168
3169
|
|
|
3170
|
+
|
|
3169
3171
|
|
|
3170
3172
|
static parse(plain ) {
|
|
3171
3173
|
return new Meeting({
|
|
@@ -3175,8 +3177,9 @@ class Meeting {
|
|
|
3175
3177
|
ownerUuids: plain.owner_uuids,
|
|
3176
3178
|
port: plain.port,
|
|
3177
3179
|
uuid: plain.uuid,
|
|
3178
|
-
|
|
3180
|
+
extension: plain.exten,
|
|
3179
3181
|
persistent: plain.persistent,
|
|
3182
|
+
creationTime: moment__default['default'](plain.creation_time).toDate(),
|
|
3180
3183
|
});
|
|
3181
3184
|
}
|
|
3182
3185
|
|
|
@@ -3198,8 +3201,9 @@ class Meeting {
|
|
|
3198
3201
|
ownerUuids,
|
|
3199
3202
|
port,
|
|
3200
3203
|
uri,
|
|
3201
|
-
|
|
3204
|
+
extension,
|
|
3202
3205
|
persistent,
|
|
3206
|
+
creationTime,
|
|
3203
3207
|
} = {}) {
|
|
3204
3208
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
3205
3209
|
this.uri = uri;
|
|
@@ -3207,8 +3211,9 @@ class Meeting {
|
|
|
3207
3211
|
this.ownerUuids = ownerUuids;
|
|
3208
3212
|
this.port = port;
|
|
3209
3213
|
this.uuid = uuid;
|
|
3210
|
-
this.
|
|
3214
|
+
this.extension = extension;
|
|
3211
3215
|
this.persistent = persistent;
|
|
3216
|
+
this.creationTime = creationTime;
|
|
3212
3217
|
|
|
3213
3218
|
// Useful to compare instead of instanceof with minified code
|
|
3214
3219
|
this.type = 'Meeting';
|
|
@@ -17,7 +17,7 @@ IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
|
|
|
17
17
|
|
|
18
18
|
// Use a function here to be able to mock it in tests
|
|
19
19
|
const realFetch = () => {
|
|
20
|
-
if (typeof document !== 'undefined') {
|
|
20
|
+
if (typeof document !== 'undefined' && window.fetch) {
|
|
21
21
|
// Browser
|
|
22
22
|
return window.fetch;
|
|
23
23
|
}
|