@wazo/sdk 0.37.22 → 0.37.26
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 +5 -5
- package/esm/__tests__/api-client.test.js +37 -6
- package/esm/__tests__/web-rtc-client.test.js +78 -68
- package/esm/api/call-logd.js +7 -0
- package/esm/api/calld.js +10 -0
- package/esm/api/chatd.js +7 -0
- package/esm/api/confd.js +13 -5
- package/esm/api/ctid-ng.js +10 -0
- package/esm/api/dird.js +4 -1
- package/esm/api-client.js +37 -6
- package/esm/checker/Checker.js +78 -68
- package/esm/checker/checks/aor.js +37 -6
- package/esm/checker/checks/api.js +37 -6
- package/esm/checker/checks/index.js +78 -68
- package/esm/checker/checks/webrtc-transport.js +78 -68
- package/esm/checker/checks/webrtc.js +78 -68
- package/esm/domain/AdHocAPIConference.js +37 -6
- package/esm/domain/Call.js +3 -0
- package/esm/domain/CallLog.js +7 -0
- package/esm/domain/ChatMessage.js +4 -0
- package/esm/domain/ChatRoom.js +3 -0
- package/esm/domain/Contact.js +4 -1
- package/esm/domain/Features.js +37 -6
- package/esm/domain/Meeting.js +15 -5
- package/esm/domain/Phone/CTIPhone.js +41 -6
- package/esm/domain/Phone/WebRTCPhone.js +41 -15
- package/esm/domain/Recording.js +3 -0
- package/esm/domain/Voicemail.js +3 -0
- package/esm/domain/__tests__/Call.test.js +3 -0
- package/esm/domain/__tests__/CallLog.test.js +7 -0
- package/esm/domain/__tests__/Contact.test.js +4 -1
- package/esm/domain/__tests__/Meeting.test.js +144 -0
- package/esm/domain/__tests__/Voicemail.test.js +3 -0
- package/esm/index.js +122 -82
- package/esm/lib/WazoSessionDescriptionHandler.js +0 -38
- package/esm/service/CallApi.js +37 -6
- package/esm/service/getApiClient.js +37 -6
- package/esm/simple/Auth.js +122 -82
- package/esm/simple/Configuration.js +122 -82
- package/esm/simple/Directory.js +37 -6
- package/esm/simple/Phone.js +122 -82
- package/esm/simple/index.js +122 -82
- package/esm/simple/room/LocalParticipant.js +122 -82
- package/esm/simple/room/Participant.js +122 -82
- package/esm/simple/room/RemoteParticipant.js +122 -82
- package/esm/simple/room/Room.js +122 -82
- package/esm/simple/room/SipRoom.js +122 -82
- package/esm/simple/room/Stream.js +122 -82
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +122 -82
- package/esm/simple/utils.js +122 -82
- package/esm/types/WebSocketMessage.js +1 -1
- package/esm/web-rtc-client.js +78 -68
- package/lib/__tests__/api-client.test.js +37 -6
- package/lib/__tests__/web-rtc-client.test.js +78 -68
- package/lib/api/call-logd.js +7 -0
- package/lib/api/calld.js +10 -0
- package/lib/api/chatd.js +7 -0
- package/lib/api/confd.js +13 -5
- package/lib/api/ctid-ng.js +10 -0
- package/lib/api/dird.js +4 -1
- package/lib/api-client.js +37 -6
- package/lib/checker/Checker.js +78 -68
- package/lib/checker/checks/aor.js +37 -6
- package/lib/checker/checks/api.js +37 -6
- package/lib/checker/checks/index.js +78 -68
- package/lib/checker/checks/webrtc-transport.js +78 -68
- package/lib/checker/checks/webrtc.js +78 -68
- package/lib/domain/AdHocAPIConference.js +37 -6
- package/lib/domain/Call.js +3 -0
- package/lib/domain/CallLog.js +7 -0
- package/lib/domain/ChatMessage.js +4 -0
- package/lib/domain/ChatRoom.js +3 -0
- package/lib/domain/Contact.js +4 -1
- package/lib/domain/Features.js +37 -6
- package/lib/domain/Meeting.js +19 -5
- package/lib/domain/Phone/CTIPhone.js +41 -6
- package/lib/domain/Phone/WebRTCPhone.js +41 -15
- package/lib/domain/Recording.js +3 -0
- package/lib/domain/Voicemail.js +3 -0
- package/lib/domain/__tests__/Call.test.js +3 -0
- package/lib/domain/__tests__/CallLog.test.js +7 -0
- package/lib/domain/__tests__/Contact.test.js +4 -1
- package/lib/domain/__tests__/Meeting.test.js +150 -0
- package/lib/domain/__tests__/Voicemail.test.js +3 -0
- package/lib/index.js +122 -82
- package/lib/lib/WazoSessionDescriptionHandler.js +0 -38
- package/lib/service/CallApi.js +37 -6
- package/lib/service/getApiClient.js +37 -6
- package/lib/simple/Auth.js +122 -82
- package/lib/simple/Configuration.js +122 -82
- package/lib/simple/Directory.js +37 -6
- package/lib/simple/Phone.js +122 -82
- package/lib/simple/index.js +122 -82
- package/lib/simple/room/LocalParticipant.js +122 -82
- package/lib/simple/room/Participant.js +122 -82
- package/lib/simple/room/RemoteParticipant.js +122 -82
- package/lib/simple/room/Room.js +122 -82
- package/lib/simple/room/SipRoom.js +122 -82
- package/lib/simple/room/Stream.js +122 -82
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +122 -82
- package/lib/simple/utils.js +122 -82
- package/lib/types/WebSocketMessage.js +2 -0
- package/lib/web-rtc-client.js +78 -68
- package/package.json +1 -1
- package/src/domain/Call.js +3 -0
- package/src/domain/CallLog.js +4 -0
- package/src/domain/ChatMessage.js +4 -0
- package/src/domain/ChatRoom.js +3 -0
- package/src/domain/Contact.js +4 -1
- package/src/domain/Meeting.js +15 -5
- package/src/domain/Phone/CTIPhone.js +4 -0
- package/src/domain/Phone/Phone.js +2 -0
- package/src/domain/Phone/WebRTCPhone.js +41 -15
- package/src/domain/Recording.js +3 -0
- package/src/domain/Voicemail.js +3 -0
- package/src/domain/__tests__/Meeting.test.js +50 -0
- package/src/lib/WazoSessionDescriptionHandler.js +1 -35
- package/src/web-rtc-client.js +41 -24
|
@@ -54,6 +54,9 @@ class Recording {
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
static parseMany(recordings = []) {
|
|
57
|
+
if (!recordings) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
57
60
|
return recordings.map(item => Recording.parse(item));
|
|
58
61
|
}
|
|
59
62
|
|
|
@@ -155,6 +158,10 @@ class CallLog {
|
|
|
155
158
|
}
|
|
156
159
|
|
|
157
160
|
static parseMany(plain ) {
|
|
161
|
+
if (!plain || !plain.items) {
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
|
|
158
165
|
return plain.items.map(item => CallLog.parse(item));
|
|
159
166
|
}
|
|
160
167
|
|
|
@@ -325,6 +325,9 @@ class Contact {
|
|
|
325
325
|
}
|
|
326
326
|
|
|
327
327
|
static parseMany(response ) {
|
|
328
|
+
if (!response || !response.results) {
|
|
329
|
+
return [];
|
|
330
|
+
}
|
|
328
331
|
return response.results.map(r => Contact.parse(r, response.column_types));
|
|
329
332
|
}
|
|
330
333
|
|
|
@@ -695,7 +698,7 @@ class Contact {
|
|
|
695
698
|
this[key] = old[key] || this[key];
|
|
696
699
|
});
|
|
697
700
|
|
|
698
|
-
if (old.lineState
|
|
701
|
+
if (old.lineState) {
|
|
699
702
|
this.lineState = old.lineState;
|
|
700
703
|
}
|
|
701
704
|
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import moment from 'moment';
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
var newFrom = (instance , ToClass ) => {
|
|
6
|
+
const args = {};
|
|
7
|
+
Object.getOwnPropertyNames(instance).forEach(prop => {
|
|
8
|
+
args[prop] = instance[prop];
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
return new ToClass(args);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Meeting {
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
static parse(plain ) {
|
|
42
|
+
return new Meeting({
|
|
43
|
+
guestSipAuthorization: plain.guest_sip_authorization,
|
|
44
|
+
uri: plain.ingress_http_uri,
|
|
45
|
+
name: plain.name,
|
|
46
|
+
ownerUuids: plain.owner_uuids,
|
|
47
|
+
port: plain.port,
|
|
48
|
+
uuid: plain.uuid,
|
|
49
|
+
extension: plain.exten,
|
|
50
|
+
persistent: plain.persistent,
|
|
51
|
+
creationTime: moment(plain.creation_time).toDate(),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static parseMany(items ) {
|
|
56
|
+
if (!items) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
return items.map(plain => Meeting.parse(plain));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static newFrom(meeting ) {
|
|
63
|
+
return newFrom(meeting, Meeting);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
constructor({
|
|
67
|
+
uuid,
|
|
68
|
+
name,
|
|
69
|
+
guestSipAuthorization,
|
|
70
|
+
ownerUuids,
|
|
71
|
+
port,
|
|
72
|
+
uri,
|
|
73
|
+
extension,
|
|
74
|
+
persistent,
|
|
75
|
+
creationTime,
|
|
76
|
+
} = {}) {
|
|
77
|
+
this.guestSipAuthorization = guestSipAuthorization;
|
|
78
|
+
this.uri = uri;
|
|
79
|
+
this.name = name;
|
|
80
|
+
this.ownerUuids = ownerUuids;
|
|
81
|
+
this.port = port;
|
|
82
|
+
this.uuid = uuid;
|
|
83
|
+
this.extension = extension;
|
|
84
|
+
this.persistent = persistent;
|
|
85
|
+
this.creationTime = creationTime;
|
|
86
|
+
|
|
87
|
+
// Useful to compare instead of instanceof with minified code
|
|
88
|
+
this.type = 'Meeting';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
getGuestSipCredentials() {
|
|
92
|
+
// eslint-disable-next-line no-undef
|
|
93
|
+
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
94
|
+
return { username, secret };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
//
|
|
99
|
+
|
|
100
|
+
describe('Meeting domain', () => {
|
|
101
|
+
it('can return username and secret from an base64 encrypted string', () => {
|
|
102
|
+
const USERNAME = 'username';
|
|
103
|
+
const SECRET = 'secret';
|
|
104
|
+
|
|
105
|
+
const args = {
|
|
106
|
+
guest_sip_authorization: btoa(`${USERNAME}:${SECRET}`),
|
|
107
|
+
creation_time: '',
|
|
108
|
+
ingress_http_uri: '',
|
|
109
|
+
name: '',
|
|
110
|
+
owner_uuids: [],
|
|
111
|
+
port: '',
|
|
112
|
+
uuid: '',
|
|
113
|
+
exten: '',
|
|
114
|
+
persistent: false,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const meeting = Meeting.parse(args);
|
|
118
|
+
|
|
119
|
+
const { username, secret } = meeting.getGuestSipCredentials();
|
|
120
|
+
|
|
121
|
+
expect(username).toEqual(USERNAME);
|
|
122
|
+
expect(secret).toEqual(SECRET);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should return a date from a string', () => {
|
|
126
|
+
const args = {
|
|
127
|
+
creation_time: '2021-12-21T15:56:42.880Z',
|
|
128
|
+
guest_sip_authorization: '',
|
|
129
|
+
ingress_http_uri: '',
|
|
130
|
+
name: '',
|
|
131
|
+
owner_uuids: [],
|
|
132
|
+
port: '',
|
|
133
|
+
uuid: '',
|
|
134
|
+
exten: '',
|
|
135
|
+
persistent: false,
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const { creationTime } = Meeting.parse(args);
|
|
139
|
+
|
|
140
|
+
expect(creationTime.getDate()).toEqual(21);
|
|
141
|
+
expect(creationTime.getFullYear()).toEqual(2021);
|
|
142
|
+
expect(creationTime.getMonth()).toEqual(11);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -71,6 +71,9 @@ class Voicemail {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
static parseMany(plain ) {
|
|
74
|
+
if (!plain) {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
74
77
|
const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
|
|
75
78
|
const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
|
|
76
79
|
|
package/esm/index.js
CHANGED
|
@@ -1551,6 +1551,9 @@ class Contact {
|
|
|
1551
1551
|
}
|
|
1552
1552
|
|
|
1553
1553
|
static parseMany(response ) {
|
|
1554
|
+
if (!response || !response.results) {
|
|
1555
|
+
return [];
|
|
1556
|
+
}
|
|
1554
1557
|
return response.results.map(r => Contact.parse(r, response.column_types));
|
|
1555
1558
|
}
|
|
1556
1559
|
|
|
@@ -1921,7 +1924,7 @@ class Contact {
|
|
|
1921
1924
|
this[key] = old[key] || this[key];
|
|
1922
1925
|
});
|
|
1923
1926
|
|
|
1924
|
-
if (old.lineState
|
|
1927
|
+
if (old.lineState) {
|
|
1925
1928
|
this.lineState = old.lineState;
|
|
1926
1929
|
}
|
|
1927
1930
|
|
|
@@ -2628,8 +2631,9 @@ class ExternalApp {
|
|
|
2628
2631
|
|
|
2629
2632
|
|
|
2630
2633
|
|
|
2631
|
-
|
|
2634
|
+
|
|
2632
2635
|
|
|
2636
|
+
|
|
2633
2637
|
|
|
2634
2638
|
|
|
2635
2639
|
class Meeting {
|
|
@@ -2640,9 +2644,10 @@ class Meeting {
|
|
|
2640
2644
|
|
|
2641
2645
|
|
|
2642
2646
|
|
|
2643
|
-
|
|
2647
|
+
|
|
2644
2648
|
|
|
2645
2649
|
|
|
2650
|
+
|
|
2646
2651
|
|
|
2647
2652
|
static parse(plain ) {
|
|
2648
2653
|
return new Meeting({
|
|
@@ -2652,12 +2657,16 @@ class Meeting {
|
|
|
2652
2657
|
ownerUuids: plain.owner_uuids,
|
|
2653
2658
|
port: plain.port,
|
|
2654
2659
|
uuid: plain.uuid,
|
|
2655
|
-
|
|
2660
|
+
extension: plain.exten,
|
|
2656
2661
|
persistent: plain.persistent,
|
|
2662
|
+
creationTime: moment(plain.creation_time).toDate(),
|
|
2657
2663
|
});
|
|
2658
2664
|
}
|
|
2659
2665
|
|
|
2660
2666
|
static parseMany(items ) {
|
|
2667
|
+
if (!items) {
|
|
2668
|
+
return [];
|
|
2669
|
+
}
|
|
2661
2670
|
return items.map(plain => Meeting.parse(plain));
|
|
2662
2671
|
}
|
|
2663
2672
|
|
|
@@ -2672,8 +2681,9 @@ class Meeting {
|
|
|
2672
2681
|
ownerUuids,
|
|
2673
2682
|
port,
|
|
2674
2683
|
uri,
|
|
2675
|
-
|
|
2684
|
+
extension,
|
|
2676
2685
|
persistent,
|
|
2686
|
+
creationTime,
|
|
2677
2687
|
} = {}) {
|
|
2678
2688
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
2679
2689
|
this.uri = uri;
|
|
@@ -2681,8 +2691,9 @@ class Meeting {
|
|
|
2681
2691
|
this.ownerUuids = ownerUuids;
|
|
2682
2692
|
this.port = port;
|
|
2683
2693
|
this.uuid = uuid;
|
|
2684
|
-
this.
|
|
2694
|
+
this.extension = extension;
|
|
2685
2695
|
this.persistent = persistent;
|
|
2696
|
+
this.creationTime = creationTime;
|
|
2686
2697
|
|
|
2687
2698
|
// Useful to compare instead of instanceof with minified code
|
|
2688
2699
|
this.type = 'Meeting';
|
|
@@ -2860,6 +2871,10 @@ class ChatMessage {
|
|
|
2860
2871
|
|
|
2861
2872
|
|
|
2862
2873
|
static parseMany(plain ) {
|
|
2874
|
+
if (!plain || !plain.items) {
|
|
2875
|
+
return [];
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2863
2878
|
return plain.items.map(item => ChatMessage.parse(item));
|
|
2864
2879
|
}
|
|
2865
2880
|
|
|
@@ -2969,6 +2984,9 @@ class Voicemail {
|
|
|
2969
2984
|
}
|
|
2970
2985
|
|
|
2971
2986
|
static parseMany(plain ) {
|
|
2987
|
+
if (!plain) {
|
|
2988
|
+
return [];
|
|
2989
|
+
}
|
|
2972
2990
|
const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
|
|
2973
2991
|
const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
|
|
2974
2992
|
|
|
@@ -3078,6 +3096,9 @@ class Call {
|
|
|
3078
3096
|
|
|
3079
3097
|
|
|
3080
3098
|
static parseMany(plain ) {
|
|
3099
|
+
if (!plain) {
|
|
3100
|
+
return [];
|
|
3101
|
+
}
|
|
3081
3102
|
return plain.map((plainCall ) => Call.parse(plainCall));
|
|
3082
3103
|
}
|
|
3083
3104
|
|
|
@@ -3621,6 +3642,9 @@ class Recording {
|
|
|
3621
3642
|
|
|
3622
3643
|
|
|
3623
3644
|
static parseMany(recordings = []) {
|
|
3645
|
+
if (!recordings) {
|
|
3646
|
+
return [];
|
|
3647
|
+
}
|
|
3624
3648
|
return recordings.map(item => Recording.parse(item));
|
|
3625
3649
|
}
|
|
3626
3650
|
|
|
@@ -3722,6 +3746,10 @@ class CallLog {
|
|
|
3722
3746
|
}
|
|
3723
3747
|
|
|
3724
3748
|
static parseMany(plain ) {
|
|
3749
|
+
if (!plain || !plain.items) {
|
|
3750
|
+
return [];
|
|
3751
|
+
}
|
|
3752
|
+
|
|
3725
3753
|
return plain.items.map(item => CallLog.parse(item));
|
|
3726
3754
|
}
|
|
3727
3755
|
|
|
@@ -4374,6 +4402,10 @@ class CTIPhone extends Emitter {
|
|
|
4374
4402
|
return false;
|
|
4375
4403
|
}
|
|
4376
4404
|
|
|
4405
|
+
hasAVideoTrack() {
|
|
4406
|
+
return false;
|
|
4407
|
+
}
|
|
4408
|
+
|
|
4377
4409
|
getLocalStreamForCall() {
|
|
4378
4410
|
return null;
|
|
4379
4411
|
}
|
|
@@ -4767,6 +4799,9 @@ class ChatRoom {
|
|
|
4767
4799
|
|
|
4768
4800
|
|
|
4769
4801
|
static parseMany(plain ) {
|
|
4802
|
+
if (!plain || !plain.items) {
|
|
4803
|
+
return [];
|
|
4804
|
+
}
|
|
4770
4805
|
return plain.items.map(item => ChatRoom.parse(item));
|
|
4771
4806
|
}
|
|
4772
4807
|
|
|
@@ -5490,10 +5525,6 @@ const getSrflxOrRelay = (candidates ) =>
|
|
|
5490
5525
|
candidates
|
|
5491
5526
|
.filter(candidate => candidate && (candidate.type === 'srflx' || candidate.type === 'relay'));
|
|
5492
5527
|
|
|
5493
|
-
const areCandidateValid = (candidates ) =>
|
|
5494
|
-
getSrflxOrRelay(candidates)
|
|
5495
|
-
.length > 0;
|
|
5496
|
-
|
|
5497
5528
|
const getVideoDirection = (sdp ) => {
|
|
5498
5529
|
const parsedSdp = sdpParser.parse(sdp);
|
|
5499
5530
|
const videoMedia = parsedSdp.media.find(media => media.type === 'video');
|
|
@@ -5546,8 +5577,6 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
5546
5577
|
/* global RTCSessionDescriptionInit, navigator */
|
|
5547
5578
|
|
|
5548
5579
|
const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
|
|
5549
|
-
const MAX_WAIT_FOR_ICE_TRIES = 20;
|
|
5550
|
-
const WAIT_FOR_ICE_TIMEOUT = 500;
|
|
5551
5580
|
|
|
5552
5581
|
// Customized mediaStreamFactory allowing to send screensharing stream directory when upgrading
|
|
5553
5582
|
const wazoMediaStreamFactory = (constraints ) => {
|
|
@@ -5737,38 +5766,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
5737
5766
|
this._peerConnection = undefined;
|
|
5738
5767
|
}
|
|
5739
5768
|
|
|
5740
|
-
async _waitForValidGatheredIce() {
|
|
5741
|
-
let tries = 0;
|
|
5742
|
-
|
|
5743
|
-
while (!areCandidateValid(this.gatheredCandidates) && tries < MAX_WAIT_FOR_ICE_TRIES) {
|
|
5744
|
-
wazoLogger.trace('SessionDescriptionHandler._waitForValidGatheredIce, waiting for ice', {
|
|
5745
|
-
tries,
|
|
5746
|
-
max: MAX_WAIT_FOR_ICE_TRIES,
|
|
5747
|
-
});
|
|
5748
|
-
|
|
5749
|
-
tries++;
|
|
5750
|
-
|
|
5751
|
-
// eslint-disable-next-line no-await-in-loop
|
|
5752
|
-
await new Promise(resolve => setTimeout(resolve, WAIT_FOR_ICE_TIMEOUT));
|
|
5753
|
-
}
|
|
5754
|
-
|
|
5755
|
-
if (tries >= MAX_WAIT_FOR_ICE_TRIES) {
|
|
5756
|
-
const errorMsg = 'No valid candidates found, can\'t answer the call';
|
|
5757
|
-
const error = new Error(errorMsg);
|
|
5758
|
-
wazoLogger.error(errorMsg, { tries, max: MAX_WAIT_FOR_ICE_TRIES });
|
|
5759
|
-
|
|
5760
|
-
// Emit an error, because sip.js catches the exception and switch to status Terminated.
|
|
5761
|
-
this.eventEmitter.emit('error', error);
|
|
5762
|
-
|
|
5763
|
-
wazoLogger.error('No valid candidates found', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
|
|
5764
|
-
}
|
|
5765
|
-
|
|
5766
|
-
// eslint-disable-next-line
|
|
5767
|
-
wazoLogger.trace('Found valid candidates', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
|
|
5768
|
-
|
|
5769
|
-
return this.getLocalSessionDescription();
|
|
5770
|
-
}
|
|
5771
|
-
|
|
5772
5769
|
// Overridden to send `inactive` in conference
|
|
5773
5770
|
updateDirection(options , isConference = false,
|
|
5774
5771
|
audioOnly = false) {
|
|
@@ -6536,7 +6533,7 @@ class WebRTCClient extends Emitter {
|
|
|
6536
6533
|
}
|
|
6537
6534
|
|
|
6538
6535
|
call(number , enableVideo , audioOnly = false, conference = false) {
|
|
6539
|
-
logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
|
|
6536
|
+
logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
|
|
6540
6537
|
const inviterOptions = {
|
|
6541
6538
|
sessionDescriptionHandlerOptionsReInvite: {
|
|
6542
6539
|
conference,
|
|
@@ -7612,6 +7609,7 @@ class WebRTCClient extends Emitter {
|
|
|
7612
7609
|
const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
|
|
7613
7610
|
const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
|
|
7614
7611
|
const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
|
|
7612
|
+
const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
|
|
7615
7613
|
|
|
7616
7614
|
logger$9.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
|
|
7617
7615
|
|
|
@@ -7619,7 +7617,8 @@ class WebRTCClient extends Emitter {
|
|
|
7619
7617
|
constraints: {
|
|
7620
7618
|
// Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
|
|
7621
7619
|
audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
|
|
7622
|
-
video: screenSharing ? (isDesktop
|
|
7620
|
+
video: screenSharing ? (isDesktop
|
|
7621
|
+
? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
|
|
7623
7622
|
: this._getVideoConstraints(enableVideo),
|
|
7624
7623
|
screen: screenSharing,
|
|
7625
7624
|
desktop: isDesktop,
|
|
@@ -7954,12 +7953,14 @@ class WebRTCClient extends Emitter {
|
|
|
7954
7953
|
|
|
7955
7954
|
session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
|
|
7956
7955
|
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7956
|
+
if (pc) {
|
|
7957
|
+
pc.oniceconnectionstatechange = () => {
|
|
7958
|
+
logger$9.info('on ice connection state changed', { state: pc.iceConnectionState });
|
|
7959
|
+
if (pc.iceConnectionState === 'disconnected') {
|
|
7960
|
+
this.eventEmitter.emit(ON_DISCONNECTED$1);
|
|
7961
|
+
}
|
|
7962
|
+
};
|
|
7963
|
+
}
|
|
7963
7964
|
|
|
7964
7965
|
if (withEvent) {
|
|
7965
7966
|
this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
|
|
@@ -8169,13 +8170,17 @@ class WebRTCClient extends Emitter {
|
|
|
8169
8170
|
const nbStats = this.sessionNetworkStats[sessionId].length;
|
|
8170
8171
|
const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
|
|
8171
8172
|
const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
|
|
8173
|
+
const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
|
|
8172
8174
|
const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
|
|
8173
8175
|
const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
|
|
8176
|
+
const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
|
|
8174
8177
|
const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
|
|
8175
8178
|
const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
|
|
8176
8179
|
const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
|
|
8177
|
-
let audioBytesSent = 0;
|
|
8178
|
-
let audioBytesReceived = 0;
|
|
8180
|
+
let audioBytesSent = 0; // content + header
|
|
8181
|
+
let audioBytesReceived = 0; // content + header
|
|
8182
|
+
let audioContentSent = 0; // useful to detect blank call
|
|
8183
|
+
let audioContentReceived = 0;
|
|
8179
8184
|
let videoBytesSent = 0;
|
|
8180
8185
|
let videoBytesReceived = 0;
|
|
8181
8186
|
let transportSent = 0;
|
|
@@ -8184,25 +8189,27 @@ class WebRTCClient extends Emitter {
|
|
|
8184
8189
|
|
|
8185
8190
|
stats.forEach(report => {
|
|
8186
8191
|
if (report.type === 'outbound-rtp' && report.kind === 'audio') {
|
|
8187
|
-
audioBytesSent += report.bytesSent + report.headerBytesSent;
|
|
8192
|
+
audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
|
|
8193
|
+
audioContentSent += Number(report.bytesSent);
|
|
8188
8194
|
}
|
|
8189
8195
|
if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
|
|
8190
|
-
audioBytesSent += report.bytesSent;
|
|
8196
|
+
audioBytesSent += Number(report.bytesSent);
|
|
8191
8197
|
}
|
|
8192
8198
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
8193
|
-
videoBytesSent += report.bytesSent + report.headerBytesSent;
|
|
8199
|
+
videoBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
|
|
8194
8200
|
}
|
|
8195
8201
|
if (report.type === 'inbound-rtp' && report.kind === 'audio') {
|
|
8196
|
-
packetsLost += report.packetsLost;
|
|
8197
|
-
networkStats.packetsReceived = report.packetsReceived;
|
|
8198
|
-
audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
8202
|
+
packetsLost += Number(report.packetsLost);
|
|
8203
|
+
networkStats.packetsReceived = Number(report.packetsReceived);
|
|
8204
|
+
audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
|
|
8205
|
+
audioContentReceived += Number(report.bytesReceived);
|
|
8199
8206
|
}
|
|
8200
8207
|
if (report.type === 'inbound-rtp' && report.kind === 'video') {
|
|
8201
|
-
videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
|
|
8208
|
+
videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
|
|
8202
8209
|
}
|
|
8203
8210
|
if (report.type === 'outbound-rtp' && report.kind === 'video') {
|
|
8204
8211
|
if ('framesPerSecond' in report) {
|
|
8205
|
-
networkStats.framesPerSecond = report.framesPerSecond;
|
|
8212
|
+
networkStats.framesPerSecond = Number(report.framesPerSecond);
|
|
8206
8213
|
}
|
|
8207
8214
|
if ('framerateMean' in report) {
|
|
8208
8215
|
// framerateMean is only available in FF
|
|
@@ -8210,24 +8217,31 @@ class WebRTCClient extends Emitter {
|
|
|
8210
8217
|
}
|
|
8211
8218
|
}
|
|
8212
8219
|
if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
|
|
8213
|
-
packetsLost += report.packetsLost;
|
|
8214
|
-
networkStats.roundTripTime = report.roundTripTime;
|
|
8215
|
-
networkStats.jitter = report.jitter;
|
|
8220
|
+
packetsLost += Number(report.packetsLost);
|
|
8221
|
+
networkStats.roundTripTime = Number(report.roundTripTime);
|
|
8222
|
+
networkStats.jitter = Number(report.jitter);
|
|
8216
8223
|
}
|
|
8217
8224
|
if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
|
|
8218
|
-
packetsLost += report.packetsLost;
|
|
8225
|
+
packetsLost += Number(report.packetsLost);
|
|
8219
8226
|
}
|
|
8220
8227
|
if (report.type === 'transport') {
|
|
8221
|
-
transportSent += report.bytesSent;
|
|
8222
|
-
transportReceived += report.bytesReceived;
|
|
8228
|
+
transportSent += Number(report.bytesSent);
|
|
8229
|
+
transportReceived += Number(report.bytesReceived);
|
|
8223
8230
|
}
|
|
8224
8231
|
});
|
|
8225
8232
|
|
|
8226
8233
|
networkStats.packetsLost = packetsLost;
|
|
8234
|
+
|
|
8227
8235
|
networkStats.totalAudioBytesSent = audioBytesSent;
|
|
8228
8236
|
networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
|
|
8229
8237
|
networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
|
|
8230
8238
|
networkStats.audioBytesReceived = audioBytesReceived;
|
|
8239
|
+
|
|
8240
|
+
networkStats.totalAudioContentSent = audioContentSent;
|
|
8241
|
+
networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
|
|
8242
|
+
networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
|
|
8243
|
+
networkStats.audioContentReceived = audioContentReceived;
|
|
8244
|
+
|
|
8231
8245
|
networkStats.totalVideoBytesSent = videoBytesSent;
|
|
8232
8246
|
networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
|
|
8233
8247
|
networkStats.totalVideoBytesReceived = videoBytesReceived;
|
|
@@ -9332,6 +9346,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9332
9346
|
constraints,
|
|
9333
9347
|
audioOnly,
|
|
9334
9348
|
conference,
|
|
9349
|
+
iceRestart,
|
|
9335
9350
|
});
|
|
9336
9351
|
|
|
9337
9352
|
if (!sipSession) {
|
|
@@ -9435,6 +9450,11 @@ class WebRTCPhone extends Emitter {
|
|
|
9435
9450
|
|
|
9436
9451
|
this.client.downgradeToAudio(sipSession);
|
|
9437
9452
|
|
|
9453
|
+
if (callSession) {
|
|
9454
|
+
callSession.cameraEnabled = false;
|
|
9455
|
+
this._updateCallSession(callSession);
|
|
9456
|
+
}
|
|
9457
|
+
|
|
9438
9458
|
if (withMessage) {
|
|
9439
9459
|
this._sendReinviteMessage(callSession, false);
|
|
9440
9460
|
}
|
|
@@ -9462,6 +9482,11 @@ class WebRTCPhone extends Emitter {
|
|
|
9462
9482
|
|
|
9463
9483
|
const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
|
|
9464
9484
|
|
|
9485
|
+
if (callSession) {
|
|
9486
|
+
callSession.cameraEnabled = true;
|
|
9487
|
+
this._updateCallSession(callSession);
|
|
9488
|
+
}
|
|
9489
|
+
|
|
9465
9490
|
// If no stream is returned, it means we have to reinvite
|
|
9466
9491
|
if (!newStream) {
|
|
9467
9492
|
return true;
|
|
@@ -9698,18 +9723,20 @@ class WebRTCPhone extends Emitter {
|
|
|
9698
9723
|
screenTrack,
|
|
9699
9724
|
});
|
|
9700
9725
|
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9726
|
+
if (screenTrack) {
|
|
9727
|
+
screenTrack.onended = () => {
|
|
9728
|
+
logger$7.info('WebRTC phone - on screenshare ended', {
|
|
9729
|
+
hadVideo,
|
|
9730
|
+
id: this.getSipSessionId(sipSession),
|
|
9731
|
+
screenTrack,
|
|
9732
|
+
});
|
|
9707
9733
|
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9734
|
+
this.eventEmitter.emit(
|
|
9735
|
+
ON_SHARE_SCREEN_ENDING,
|
|
9736
|
+
this._createCallSession(sipSession, callSession),
|
|
9737
|
+
);
|
|
9738
|
+
};
|
|
9739
|
+
}
|
|
9713
9740
|
|
|
9714
9741
|
this.currentScreenShare = {
|
|
9715
9742
|
stream: screenStream,
|
|
@@ -9729,7 +9756,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9729
9756
|
}
|
|
9730
9757
|
|
|
9731
9758
|
_onCallAccepted(sipSession , cameraEnabled ) {
|
|
9732
|
-
logger$7.info('WebRTC phone -
|
|
9759
|
+
logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
|
|
9733
9760
|
|
|
9734
9761
|
const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
|
|
9735
9762
|
this.currentSipSession = sipSession;
|
|
@@ -10241,7 +10268,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10241
10268
|
// @TODO: line is not used here
|
|
10242
10269
|
async makeCall(number , line , cameraEnabled ,
|
|
10243
10270
|
audioOnly = false, conference = false) {
|
|
10244
|
-
logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
|
|
10271
|
+
logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled, audioOnly, conference });
|
|
10245
10272
|
if (!number) {
|
|
10246
10273
|
return Promise.resolve(null);
|
|
10247
10274
|
}
|
|
@@ -10602,9 +10629,13 @@ class WebRTCPhone extends Emitter {
|
|
|
10602
10629
|
if (this.shouldSendReinvite && this.currentSipSession
|
|
10603
10630
|
&& this.currentSipSession.state === SessionState.Established) {
|
|
10604
10631
|
this.shouldSendReinvite = false;
|
|
10632
|
+
const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
|
|
10633
|
+
const isConference = pc ? pc.sfu : false;
|
|
10634
|
+
const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
|
|
10635
|
+
|
|
10605
10636
|
try {
|
|
10606
10637
|
// Send reinvite with iceRestart
|
|
10607
|
-
this.sendReinvite(this.currentCallSession, null,
|
|
10638
|
+
this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
|
|
10608
10639
|
} catch (e) {
|
|
10609
10640
|
logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
|
|
10610
10641
|
}
|
|
@@ -10688,6 +10719,15 @@ class WebRTCPhone extends Emitter {
|
|
|
10688
10719
|
return this.client.getSipSessionId(sipSession);
|
|
10689
10720
|
}
|
|
10690
10721
|
|
|
10722
|
+
_updateCallSession(callSession ) {
|
|
10723
|
+
const sipSession = this.findSipSession(callSession);
|
|
10724
|
+
const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
|
|
10725
|
+
|
|
10726
|
+
if (sipSessionId) {
|
|
10727
|
+
this.callSessions[sipSessionId] = callSession;
|
|
10728
|
+
}
|
|
10729
|
+
}
|
|
10730
|
+
|
|
10691
10731
|
_onMessage(message ) {
|
|
10692
10732
|
if (!message || message.method !== 'MESSAGE') {
|
|
10693
10733
|
return;
|