@wazo/sdk 0.37.27 → 0.37.31
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 +3 -2
- package/dist/wazo-sdk.js +4 -4
- package/esm/__tests__/web-rtc-client.test.js +9 -1
- package/esm/checker/Checker.js +9 -1
- package/esm/checker/checks/index.js +9 -1
- package/esm/checker/checks/webrtc-transport.js +9 -1
- package/esm/checker/checks/webrtc.js +9 -1
- package/esm/domain/CallSession.js +29 -2
- package/esm/domain/Phone/CTIPhone.js +29 -2
- package/esm/domain/Phone/WebRTCPhone.js +57 -4
- package/esm/domain/SFUNotAvailableError.js +9 -0
- package/esm/domain/__tests__/CallSession.test.js +46 -2
- package/esm/domain/__tests__/IndirectTransfer.test.js +29 -2
- package/esm/domain/__tests__/Room.test.js +29 -2
- package/esm/index.js +77 -5
- package/esm/simple/Auth.js +76 -5
- package/esm/simple/Configuration.js +76 -5
- package/esm/simple/Phone.js +76 -5
- package/esm/simple/index.js +76 -5
- package/esm/simple/room/LocalParticipant.js +76 -5
- package/esm/simple/room/Participant.js +76 -5
- package/esm/simple/room/RemoteParticipant.js +76 -5
- package/esm/simple/room/Room.js +76 -5
- package/esm/simple/room/SipRoom.js +76 -5
- package/esm/simple/room/Stream.js +76 -5
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +76 -5
- package/esm/simple/utils.js +76 -5
- package/esm/web-rtc-client.js +9 -1
- package/lib/__tests__/web-rtc-client.test.js +9 -1
- package/lib/checker/Checker.js +9 -1
- package/lib/checker/checks/index.js +9 -1
- package/lib/checker/checks/webrtc-transport.js +9 -1
- package/lib/checker/checks/webrtc.js +9 -1
- package/lib/domain/CallSession.js +29 -2
- package/lib/domain/Phone/CTIPhone.js +29 -2
- package/lib/domain/Phone/WebRTCPhone.js +57 -3
- package/lib/domain/SFUNotAvailableError.js +11 -0
- package/lib/domain/__tests__/CallSession.test.js +46 -2
- package/lib/domain/__tests__/IndirectTransfer.test.js +29 -2
- package/lib/domain/__tests__/Room.test.js +29 -2
- package/lib/index.js +77 -5
- package/lib/simple/Auth.js +76 -5
- package/lib/simple/Configuration.js +76 -5
- package/lib/simple/Phone.js +76 -5
- package/lib/simple/index.js +76 -5
- package/lib/simple/room/LocalParticipant.js +76 -5
- package/lib/simple/room/Participant.js +76 -5
- package/lib/simple/room/RemoteParticipant.js +76 -5
- package/lib/simple/room/Room.js +76 -5
- package/lib/simple/room/SipRoom.js +76 -5
- package/lib/simple/room/Stream.js +76 -5
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +76 -5
- package/lib/simple/utils.js +76 -5
- package/lib/web-rtc-client.js +9 -1
- package/package.json +1 -1
- package/src/domain/CallSession.js +32 -4
- package/src/domain/Phone/WebRTCPhone.js +27 -1
- package/src/domain/SFUNotAvailableError.js +7 -0
- package/src/domain/__tests__/CallSession.test.js +17 -0
- package/src/index.js +2 -0
- package/src/simple/Phone.js +2 -1
- package/src/simple/index.js +2 -0
- package/src/web-rtc-client.js +9 -1
|
@@ -5353,6 +5353,7 @@ const MAX_REGISTER_TRIES = 10;
|
|
|
5353
5353
|
|
|
5354
5354
|
|
|
5355
5355
|
|
|
5356
|
+
|
|
5356
5357
|
|
|
5357
5358
|
|
|
5358
5359
|
|
|
@@ -6969,6 +6970,13 @@ class WebRTCClient extends Emitter {
|
|
|
6969
6970
|
}
|
|
6970
6971
|
|
|
6971
6972
|
_createWebRTCConfiguration(configOverrides = {}) {
|
|
6973
|
+
let { host } = this.config;
|
|
6974
|
+
let port = this.config.port || 443;
|
|
6975
|
+
|
|
6976
|
+
if (this.config.websocketSip) {
|
|
6977
|
+
[host, port = 443] = this.config.websocketSip.split(':');
|
|
6978
|
+
}
|
|
6979
|
+
|
|
6972
6980
|
const config = {
|
|
6973
6981
|
authorizationUsername: this.config.authorizationUser,
|
|
6974
6982
|
authorizationPassword: this.config.password,
|
|
@@ -7004,7 +7012,7 @@ class WebRTCClient extends Emitter {
|
|
|
7004
7012
|
},
|
|
7005
7013
|
transportOptions: {
|
|
7006
7014
|
traceSip: configOverrides.traceSip || false,
|
|
7007
|
-
wsServers: `wss://${
|
|
7015
|
+
wsServers: `wss://${host}:${port}/api/asterisk/ws`,
|
|
7008
7016
|
},
|
|
7009
7017
|
sessionDescriptionHandlerFactoryOptions: {
|
|
7010
7018
|
modifiers: [replaceLocalIpModifier],
|
|
@@ -5353,6 +5353,7 @@ const MAX_REGISTER_TRIES = 10;
|
|
|
5353
5353
|
|
|
5354
5354
|
|
|
5355
5355
|
|
|
5356
|
+
|
|
5356
5357
|
|
|
5357
5358
|
|
|
5358
5359
|
|
|
@@ -6969,6 +6970,13 @@ class WebRTCClient extends Emitter {
|
|
|
6969
6970
|
}
|
|
6970
6971
|
|
|
6971
6972
|
_createWebRTCConfiguration(configOverrides = {}) {
|
|
6973
|
+
let { host } = this.config;
|
|
6974
|
+
let port = this.config.port || 443;
|
|
6975
|
+
|
|
6976
|
+
if (this.config.websocketSip) {
|
|
6977
|
+
[host, port = 443] = this.config.websocketSip.split(':');
|
|
6978
|
+
}
|
|
6979
|
+
|
|
6972
6980
|
const config = {
|
|
6973
6981
|
authorizationUsername: this.config.authorizationUser,
|
|
6974
6982
|
authorizationPassword: this.config.password,
|
|
@@ -7004,7 +7012,7 @@ class WebRTCClient extends Emitter {
|
|
|
7004
7012
|
},
|
|
7005
7013
|
transportOptions: {
|
|
7006
7014
|
traceSip: configOverrides.traceSip || false,
|
|
7007
|
-
wsServers: `wss://${
|
|
7015
|
+
wsServers: `wss://${host}:${port}/api/asterisk/ws`,
|
|
7008
7016
|
},
|
|
7009
7017
|
sessionDescriptionHandlerFactoryOptions: {
|
|
7010
7018
|
modifiers: [replaceLocalIpModifier],
|
|
@@ -34,13 +34,16 @@ var updateFrom = (instance , from ) => {
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
|
|
41
42
|
|
|
43
|
+
|
|
42
44
|
|
|
43
45
|
|
|
46
|
+
|
|
44
47
|
|
|
45
48
|
|
|
46
49
|
|
|
@@ -57,6 +60,7 @@ var updateFrom = (instance , from ) => {
|
|
|
57
60
|
|
|
58
61
|
|
|
59
62
|
|
|
63
|
+
|
|
60
64
|
|
|
61
65
|
|
|
62
66
|
class CallSession {
|
|
@@ -76,10 +80,14 @@ class CallSession {
|
|
|
76
80
|
|
|
77
81
|
|
|
78
82
|
|
|
79
|
-
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
// = creationTime
|
|
80
86
|
|
|
81
87
|
|
|
82
88
|
|
|
89
|
+
|
|
90
|
+
|
|
83
91
|
|
|
84
92
|
|
|
85
93
|
|
|
@@ -115,6 +123,8 @@ class CallSession {
|
|
|
115
123
|
|
|
116
124
|
|
|
117
125
|
|
|
126
|
+
|
|
127
|
+
|
|
118
128
|
|
|
119
129
|
constructor({
|
|
120
130
|
answered,
|
|
@@ -128,6 +138,8 @@ class CallSession {
|
|
|
128
138
|
paused,
|
|
129
139
|
ringing,
|
|
130
140
|
startTime,
|
|
141
|
+
creationTime,
|
|
142
|
+
endTime,
|
|
131
143
|
cameraEnabled,
|
|
132
144
|
dialedExtension,
|
|
133
145
|
sipCallId,
|
|
@@ -140,12 +152,16 @@ class CallSession {
|
|
|
140
152
|
recording,
|
|
141
153
|
recordingPaused,
|
|
142
154
|
videoRemotelyDowngraded,
|
|
155
|
+
sipSession,
|
|
156
|
+
answerTime,
|
|
143
157
|
} ) {
|
|
144
158
|
this.callId = callId;
|
|
145
159
|
this.sipCallId = sipCallId;
|
|
146
160
|
this.displayName = displayName;
|
|
147
161
|
this.number = number;
|
|
162
|
+
this.creationTime = creationTime;
|
|
148
163
|
this.startTime = startTime;
|
|
164
|
+
this.endTime = endTime;
|
|
149
165
|
this.isCaller = isCaller;
|
|
150
166
|
this.answered = answered;
|
|
151
167
|
this.answeredBySystem = answeredBySystem;
|
|
@@ -164,6 +180,8 @@ class CallSession {
|
|
|
164
180
|
this.recording = recording || false;
|
|
165
181
|
this.recordingPaused = recordingPaused || false;
|
|
166
182
|
this.videoRemotelyDowngraded = videoRemotelyDowngraded;
|
|
183
|
+
this.sipSession = sipSession;
|
|
184
|
+
this.answerTime = answerTime || this.answerTime;
|
|
167
185
|
|
|
168
186
|
// Useful to compare instead of instanceof with minified code
|
|
169
187
|
this.type = 'CallSession';
|
|
@@ -194,7 +212,7 @@ class CallSession {
|
|
|
194
212
|
}
|
|
195
213
|
|
|
196
214
|
answer() {
|
|
197
|
-
this.
|
|
215
|
+
this.answerTime = new Date();
|
|
198
216
|
}
|
|
199
217
|
|
|
200
218
|
systemAnswer() {
|
|
@@ -350,6 +368,15 @@ class CallSession {
|
|
|
350
368
|
return newFrom(callSession, CallSession);
|
|
351
369
|
}
|
|
352
370
|
|
|
371
|
+
// Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
|
|
372
|
+
set answered(value ) {
|
|
373
|
+
this.answerTime = value ? this.answerTime || new Date() : null;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
get answered() {
|
|
377
|
+
return !!this.answerTime;
|
|
378
|
+
}
|
|
379
|
+
|
|
353
380
|
static parseCall(call ) {
|
|
354
381
|
return new CallSession({
|
|
355
382
|
callId: call.id,
|
|
@@ -1715,13 +1715,16 @@ var updateFrom = (instance , from ) => {
|
|
|
1715
1715
|
|
|
1716
1716
|
|
|
1717
1717
|
|
|
1718
|
+
|
|
1718
1719
|
|
|
1719
1720
|
|
|
1720
1721
|
|
|
1721
1722
|
|
|
1722
1723
|
|
|
1724
|
+
|
|
1723
1725
|
|
|
1724
1726
|
|
|
1727
|
+
|
|
1725
1728
|
|
|
1726
1729
|
|
|
1727
1730
|
|
|
@@ -1738,6 +1741,7 @@ var updateFrom = (instance , from ) => {
|
|
|
1738
1741
|
|
|
1739
1742
|
|
|
1740
1743
|
|
|
1744
|
+
|
|
1741
1745
|
|
|
1742
1746
|
|
|
1743
1747
|
class CallSession {
|
|
@@ -1757,10 +1761,14 @@ class CallSession {
|
|
|
1757
1761
|
|
|
1758
1762
|
|
|
1759
1763
|
|
|
1760
|
-
|
|
1764
|
+
|
|
1765
|
+
|
|
1766
|
+
// = creationTime
|
|
1761
1767
|
|
|
1762
1768
|
|
|
1763
1769
|
|
|
1770
|
+
|
|
1771
|
+
|
|
1764
1772
|
|
|
1765
1773
|
|
|
1766
1774
|
|
|
@@ -1796,6 +1804,8 @@ class CallSession {
|
|
|
1796
1804
|
|
|
1797
1805
|
|
|
1798
1806
|
|
|
1807
|
+
|
|
1808
|
+
|
|
1799
1809
|
|
|
1800
1810
|
constructor({
|
|
1801
1811
|
answered,
|
|
@@ -1809,6 +1819,8 @@ class CallSession {
|
|
|
1809
1819
|
paused,
|
|
1810
1820
|
ringing,
|
|
1811
1821
|
startTime,
|
|
1822
|
+
creationTime,
|
|
1823
|
+
endTime,
|
|
1812
1824
|
cameraEnabled,
|
|
1813
1825
|
dialedExtension,
|
|
1814
1826
|
sipCallId,
|
|
@@ -1821,12 +1833,16 @@ class CallSession {
|
|
|
1821
1833
|
recording,
|
|
1822
1834
|
recordingPaused,
|
|
1823
1835
|
videoRemotelyDowngraded,
|
|
1836
|
+
sipSession,
|
|
1837
|
+
answerTime,
|
|
1824
1838
|
} ) {
|
|
1825
1839
|
this.callId = callId;
|
|
1826
1840
|
this.sipCallId = sipCallId;
|
|
1827
1841
|
this.displayName = displayName;
|
|
1828
1842
|
this.number = number;
|
|
1843
|
+
this.creationTime = creationTime;
|
|
1829
1844
|
this.startTime = startTime;
|
|
1845
|
+
this.endTime = endTime;
|
|
1830
1846
|
this.isCaller = isCaller;
|
|
1831
1847
|
this.answered = answered;
|
|
1832
1848
|
this.answeredBySystem = answeredBySystem;
|
|
@@ -1845,6 +1861,8 @@ class CallSession {
|
|
|
1845
1861
|
this.recording = recording || false;
|
|
1846
1862
|
this.recordingPaused = recordingPaused || false;
|
|
1847
1863
|
this.videoRemotelyDowngraded = videoRemotelyDowngraded;
|
|
1864
|
+
this.sipSession = sipSession;
|
|
1865
|
+
this.answerTime = answerTime || this.answerTime;
|
|
1848
1866
|
|
|
1849
1867
|
// Useful to compare instead of instanceof with minified code
|
|
1850
1868
|
this.type = 'CallSession';
|
|
@@ -1875,7 +1893,7 @@ class CallSession {
|
|
|
1875
1893
|
}
|
|
1876
1894
|
|
|
1877
1895
|
answer() {
|
|
1878
|
-
this.
|
|
1896
|
+
this.answerTime = new Date();
|
|
1879
1897
|
}
|
|
1880
1898
|
|
|
1881
1899
|
systemAnswer() {
|
|
@@ -2031,6 +2049,15 @@ class CallSession {
|
|
|
2031
2049
|
return newFrom(callSession, CallSession);
|
|
2032
2050
|
}
|
|
2033
2051
|
|
|
2052
|
+
// Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
|
|
2053
|
+
set answered(value ) {
|
|
2054
|
+
this.answerTime = value ? this.answerTime || new Date() : null;
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2057
|
+
get answered() {
|
|
2058
|
+
return !!this.answerTime;
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2034
2061
|
static parseCall(call ) {
|
|
2035
2062
|
return new CallSession({
|
|
2036
2063
|
callId: call.id,
|
|
@@ -63,13 +63,16 @@ var updateFrom = (instance , from ) => {
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
|
|
66
|
+
|
|
66
67
|
|
|
67
68
|
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
|
|
72
|
+
|
|
71
73
|
|
|
72
74
|
|
|
75
|
+
|
|
73
76
|
|
|
74
77
|
|
|
75
78
|
|
|
@@ -86,6 +89,7 @@ var updateFrom = (instance , from ) => {
|
|
|
86
89
|
|
|
87
90
|
|
|
88
91
|
|
|
92
|
+
|
|
89
93
|
|
|
90
94
|
|
|
91
95
|
class CallSession {
|
|
@@ -105,10 +109,14 @@ class CallSession {
|
|
|
105
109
|
|
|
106
110
|
|
|
107
111
|
|
|
108
|
-
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
// = creationTime
|
|
109
115
|
|
|
110
116
|
|
|
111
117
|
|
|
118
|
+
|
|
119
|
+
|
|
112
120
|
|
|
113
121
|
|
|
114
122
|
|
|
@@ -144,6 +152,8 @@ class CallSession {
|
|
|
144
152
|
|
|
145
153
|
|
|
146
154
|
|
|
155
|
+
|
|
156
|
+
|
|
147
157
|
|
|
148
158
|
constructor({
|
|
149
159
|
answered,
|
|
@@ -157,6 +167,8 @@ class CallSession {
|
|
|
157
167
|
paused,
|
|
158
168
|
ringing,
|
|
159
169
|
startTime,
|
|
170
|
+
creationTime,
|
|
171
|
+
endTime,
|
|
160
172
|
cameraEnabled,
|
|
161
173
|
dialedExtension,
|
|
162
174
|
sipCallId,
|
|
@@ -169,12 +181,16 @@ class CallSession {
|
|
|
169
181
|
recording,
|
|
170
182
|
recordingPaused,
|
|
171
183
|
videoRemotelyDowngraded,
|
|
184
|
+
sipSession,
|
|
185
|
+
answerTime,
|
|
172
186
|
} ) {
|
|
173
187
|
this.callId = callId;
|
|
174
188
|
this.sipCallId = sipCallId;
|
|
175
189
|
this.displayName = displayName;
|
|
176
190
|
this.number = number;
|
|
191
|
+
this.creationTime = creationTime;
|
|
177
192
|
this.startTime = startTime;
|
|
193
|
+
this.endTime = endTime;
|
|
178
194
|
this.isCaller = isCaller;
|
|
179
195
|
this.answered = answered;
|
|
180
196
|
this.answeredBySystem = answeredBySystem;
|
|
@@ -193,6 +209,8 @@ class CallSession {
|
|
|
193
209
|
this.recording = recording || false;
|
|
194
210
|
this.recordingPaused = recordingPaused || false;
|
|
195
211
|
this.videoRemotelyDowngraded = videoRemotelyDowngraded;
|
|
212
|
+
this.sipSession = sipSession;
|
|
213
|
+
this.answerTime = answerTime || this.answerTime;
|
|
196
214
|
|
|
197
215
|
// Useful to compare instead of instanceof with minified code
|
|
198
216
|
this.type = 'CallSession';
|
|
@@ -223,7 +241,7 @@ class CallSession {
|
|
|
223
241
|
}
|
|
224
242
|
|
|
225
243
|
answer() {
|
|
226
|
-
this.
|
|
244
|
+
this.answerTime = new Date();
|
|
227
245
|
}
|
|
228
246
|
|
|
229
247
|
systemAnswer() {
|
|
@@ -379,6 +397,15 @@ class CallSession {
|
|
|
379
397
|
return newFrom(callSession, CallSession);
|
|
380
398
|
}
|
|
381
399
|
|
|
400
|
+
// Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
|
|
401
|
+
set answered(value ) {
|
|
402
|
+
this.answerTime = value ? this.answerTime || new Date() : null;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
get answered() {
|
|
406
|
+
return !!this.answerTime;
|
|
407
|
+
}
|
|
408
|
+
|
|
382
409
|
static parseCall(call ) {
|
|
383
410
|
return new CallSession({
|
|
384
411
|
callId: call.id,
|
|
@@ -887,6 +914,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
|
|
|
887
914
|
const ON_CAMERA_RESUMED = 'onCameraResumed';
|
|
888
915
|
const ON_CALL_CANCELED = 'onCallCanceled';
|
|
889
916
|
const ON_CALL_FAILED = 'onCallFailed';
|
|
917
|
+
const ON_CALL_REJECTED = 'onCallRejected';
|
|
890
918
|
const ON_CALL_ENDED = 'onCallEnded';
|
|
891
919
|
const ON_CALL_ENDING = 'onCallEnding';
|
|
892
920
|
const ON_MESSAGE = 'onMessage';
|
|
@@ -931,6 +959,7 @@ const events = [
|
|
|
931
959
|
ON_CAMERA_DISABLED,
|
|
932
960
|
ON_CALL_FAILED,
|
|
933
961
|
ON_CALL_ENDED,
|
|
962
|
+
ON_CALL_REJECTED,
|
|
934
963
|
ON_MESSAGE,
|
|
935
964
|
ON_REINVITE,
|
|
936
965
|
ON_TRACK,
|
|
@@ -1287,6 +1316,7 @@ class WebRTCPhone extends Emitter {
|
|
|
1287
1316
|
|
|
1288
1317
|
// Should be called before `_onCallTerminated` or the callCount will not decrement...
|
|
1289
1318
|
const callSession = this._createCallSession(sipSession);
|
|
1319
|
+
callSession.endTime = new Date();
|
|
1290
1320
|
const wasCurrentSession = this._onCallTerminated(sipSession);
|
|
1291
1321
|
|
|
1292
1322
|
return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
|
|
@@ -1482,6 +1512,8 @@ class WebRTCPhone extends Emitter {
|
|
|
1482
1512
|
this.removeIncomingSessions(sipSessionId);
|
|
1483
1513
|
}
|
|
1484
1514
|
|
|
1515
|
+
callSession.answerTime = new Date();
|
|
1516
|
+
this._updateCallSession(callSession);
|
|
1485
1517
|
this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
|
|
1486
1518
|
|
|
1487
1519
|
return callSession;
|
|
@@ -1697,6 +1729,8 @@ class WebRTCPhone extends Emitter {
|
|
|
1697
1729
|
}
|
|
1698
1730
|
|
|
1699
1731
|
this.shouldSendReinvite = false;
|
|
1732
|
+
callSession.answerTime = new Date();
|
|
1733
|
+
this._updateCallSession(callSession);
|
|
1700
1734
|
this.acceptedSessions[callSession.getId()] = true;
|
|
1701
1735
|
|
|
1702
1736
|
this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
|
|
@@ -1796,7 +1830,7 @@ class WebRTCPhone extends Emitter {
|
|
|
1796
1830
|
// Hold current session if different from the current one (we don't want 2 sessions active at the same time).
|
|
1797
1831
|
if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
|
|
1798
1832
|
logger.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
|
|
1799
|
-
this.holdSipSession(this.currentSipSession,
|
|
1833
|
+
this.holdSipSession(this.currentSipSession, this.currentCallSession);
|
|
1800
1834
|
}
|
|
1801
1835
|
|
|
1802
1836
|
const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
|
|
@@ -2006,6 +2040,8 @@ class WebRTCPhone extends Emitter {
|
|
|
2006
2040
|
return Promise.resolve(null);
|
|
2007
2041
|
}
|
|
2008
2042
|
const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
|
|
2043
|
+
callSession.creationTime = new Date();
|
|
2044
|
+
this._updateCallSession(callSession);
|
|
2009
2045
|
|
|
2010
2046
|
this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
|
|
2011
2047
|
|
|
@@ -2284,6 +2320,9 @@ class WebRTCPhone extends Emitter {
|
|
|
2284
2320
|
callSession);
|
|
2285
2321
|
}
|
|
2286
2322
|
|
|
2323
|
+
callSession.creationTime = new Date();
|
|
2324
|
+
this._updateCallSession(callSession);
|
|
2325
|
+
|
|
2287
2326
|
this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
|
|
2288
2327
|
});
|
|
2289
2328
|
|
|
@@ -2323,6 +2362,15 @@ class WebRTCPhone extends Emitter {
|
|
|
2323
2362
|
this.eventEmitter.emit(ON_CALL_ERROR, e);
|
|
2324
2363
|
});
|
|
2325
2364
|
|
|
2365
|
+
this.client.on(this.client.REJECTED, session => {
|
|
2366
|
+
logger.info('WebRTC call rejected', session.id);
|
|
2367
|
+
const callSession = this._createCallSession(session);
|
|
2368
|
+
callSession.endTime = new Date();
|
|
2369
|
+
this._updateCallSession(callSession);
|
|
2370
|
+
|
|
2371
|
+
this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
|
|
2372
|
+
});
|
|
2373
|
+
|
|
2326
2374
|
this.client.on(this.client.UNREGISTERED, () => {
|
|
2327
2375
|
logger.info('WebRTC unregistered');
|
|
2328
2376
|
this.eventEmitter.emit(ON_UNREGISTERED);
|
|
@@ -2535,6 +2583,7 @@ class WebRTCPhone extends Emitter {
|
|
|
2535
2583
|
const number = identity ? identity.uri._normal.user : null;
|
|
2536
2584
|
const { state } = sipSession || {};
|
|
2537
2585
|
const sessionId = this.getSipSessionId(sipSession);
|
|
2586
|
+
fromSession = fromSession || this.callSessions[sessionId];
|
|
2538
2587
|
|
|
2539
2588
|
const callSession = new CallSession({
|
|
2540
2589
|
callId: fromSession && fromSession.callId,
|
|
@@ -2542,6 +2591,9 @@ class WebRTCPhone extends Emitter {
|
|
|
2542
2591
|
sipStatus: state,
|
|
2543
2592
|
displayName: identity ? identity.displayName || number : number,
|
|
2544
2593
|
startTime: fromSession ? fromSession.startTime : new Date(),
|
|
2594
|
+
creationTime: fromSession ? fromSession.creationTime : null,
|
|
2595
|
+
answerTime: fromSession ? fromSession.answerTime : null,
|
|
2596
|
+
endTime: fromSession ? fromSession.endTime : null,
|
|
2545
2597
|
answered: state === sessionState.SessionState.Established,
|
|
2546
2598
|
paused: this.client.isCallHeld(sipSession),
|
|
2547
2599
|
isCaller: 'incoming' in extra ? !extra.incoming : false,
|
|
@@ -2552,6 +2604,7 @@ class WebRTCPhone extends Emitter {
|
|
|
2552
2604
|
videoMuted: fromSession ? fromSession.isVideoMuted() : false,
|
|
2553
2605
|
recording: fromSession ? fromSession.isRecording() : false,
|
|
2554
2606
|
recordingPaused: false, // @TODO
|
|
2607
|
+
sipSession,
|
|
2555
2608
|
...extra,
|
|
2556
2609
|
});
|
|
2557
2610
|
|
|
@@ -2575,6 +2628,7 @@ exports.ON_CALL_HELD = ON_CALL_HELD;
|
|
|
2575
2628
|
exports.ON_CALL_INCOMING = ON_CALL_INCOMING;
|
|
2576
2629
|
exports.ON_CALL_MUTED = ON_CALL_MUTED;
|
|
2577
2630
|
exports.ON_CALL_OUTGOING = ON_CALL_OUTGOING;
|
|
2631
|
+
exports.ON_CALL_REJECTED = ON_CALL_REJECTED;
|
|
2578
2632
|
exports.ON_CALL_RESUMED = ON_CALL_RESUMED;
|
|
2579
2633
|
exports.ON_CALL_UNHELD = ON_CALL_UNHELD;
|
|
2580
2634
|
exports.ON_CALL_UNMUTED = ON_CALL_UNMUTED;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/* */
|
|
4
|
+
class SFUNotAvailableError extends Error {
|
|
5
|
+
constructor(message = 'Sorry your user is not configured to support video conference') {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'SFUNotAvailableError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = SFUNotAvailableError;
|
|
@@ -34,13 +34,16 @@ var updateFrom = (instance , from ) => {
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
|
|
41
42
|
|
|
43
|
+
|
|
42
44
|
|
|
43
45
|
|
|
46
|
+
|
|
44
47
|
|
|
45
48
|
|
|
46
49
|
|
|
@@ -57,6 +60,7 @@ var updateFrom = (instance , from ) => {
|
|
|
57
60
|
|
|
58
61
|
|
|
59
62
|
|
|
63
|
+
|
|
60
64
|
|
|
61
65
|
|
|
62
66
|
class CallSession {
|
|
@@ -76,10 +80,14 @@ class CallSession {
|
|
|
76
80
|
|
|
77
81
|
|
|
78
82
|
|
|
79
|
-
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
// = creationTime
|
|
80
86
|
|
|
81
87
|
|
|
82
88
|
|
|
89
|
+
|
|
90
|
+
|
|
83
91
|
|
|
84
92
|
|
|
85
93
|
|
|
@@ -115,6 +123,8 @@ class CallSession {
|
|
|
115
123
|
|
|
116
124
|
|
|
117
125
|
|
|
126
|
+
|
|
127
|
+
|
|
118
128
|
|
|
119
129
|
constructor({
|
|
120
130
|
answered,
|
|
@@ -128,6 +138,8 @@ class CallSession {
|
|
|
128
138
|
paused,
|
|
129
139
|
ringing,
|
|
130
140
|
startTime,
|
|
141
|
+
creationTime,
|
|
142
|
+
endTime,
|
|
131
143
|
cameraEnabled,
|
|
132
144
|
dialedExtension,
|
|
133
145
|
sipCallId,
|
|
@@ -140,12 +152,16 @@ class CallSession {
|
|
|
140
152
|
recording,
|
|
141
153
|
recordingPaused,
|
|
142
154
|
videoRemotelyDowngraded,
|
|
155
|
+
sipSession,
|
|
156
|
+
answerTime,
|
|
143
157
|
} ) {
|
|
144
158
|
this.callId = callId;
|
|
145
159
|
this.sipCallId = sipCallId;
|
|
146
160
|
this.displayName = displayName;
|
|
147
161
|
this.number = number;
|
|
162
|
+
this.creationTime = creationTime;
|
|
148
163
|
this.startTime = startTime;
|
|
164
|
+
this.endTime = endTime;
|
|
149
165
|
this.isCaller = isCaller;
|
|
150
166
|
this.answered = answered;
|
|
151
167
|
this.answeredBySystem = answeredBySystem;
|
|
@@ -164,6 +180,8 @@ class CallSession {
|
|
|
164
180
|
this.recording = recording || false;
|
|
165
181
|
this.recordingPaused = recordingPaused || false;
|
|
166
182
|
this.videoRemotelyDowngraded = videoRemotelyDowngraded;
|
|
183
|
+
this.sipSession = sipSession;
|
|
184
|
+
this.answerTime = answerTime || this.answerTime;
|
|
167
185
|
|
|
168
186
|
// Useful to compare instead of instanceof with minified code
|
|
169
187
|
this.type = 'CallSession';
|
|
@@ -194,7 +212,7 @@ class CallSession {
|
|
|
194
212
|
}
|
|
195
213
|
|
|
196
214
|
answer() {
|
|
197
|
-
this.
|
|
215
|
+
this.answerTime = new Date();
|
|
198
216
|
}
|
|
199
217
|
|
|
200
218
|
systemAnswer() {
|
|
@@ -350,6 +368,15 @@ class CallSession {
|
|
|
350
368
|
return newFrom(callSession, CallSession);
|
|
351
369
|
}
|
|
352
370
|
|
|
371
|
+
// Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
|
|
372
|
+
set answered(value ) {
|
|
373
|
+
this.answerTime = value ? this.answerTime || new Date() : null;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
get answered() {
|
|
377
|
+
return !!this.answerTime;
|
|
378
|
+
}
|
|
379
|
+
|
|
353
380
|
static parseCall(call ) {
|
|
354
381
|
return new CallSession({
|
|
355
382
|
callId: call.id,
|
|
@@ -412,4 +439,21 @@ describe('CallSession domain', () => {
|
|
|
412
439
|
expect(cs1.is(cs2)).toBeTruthy();
|
|
413
440
|
expect(cs2.is(cs1)).toBeTruthy();
|
|
414
441
|
});
|
|
442
|
+
|
|
443
|
+
it('should set answerTime when setting answered', () => {
|
|
444
|
+
const cs1 = new CallSession({});
|
|
445
|
+
cs1.answered = true;
|
|
446
|
+
|
|
447
|
+
const cs2 = new CallSession({});
|
|
448
|
+
cs2.answer();
|
|
449
|
+
|
|
450
|
+
const cs3 = new CallSession({ answered: true });
|
|
451
|
+
|
|
452
|
+
expect(cs1.answered).toBeTruthy();
|
|
453
|
+
expect(cs1.answerTime).not.toBeNull();
|
|
454
|
+
expect(cs2.answered).toBeTruthy();
|
|
455
|
+
expect(cs2.answerTime).not.toBeNull();
|
|
456
|
+
expect(cs3.answered).toBeTruthy();
|
|
457
|
+
expect(cs3.answerTime).not.toBeNull();
|
|
458
|
+
});
|
|
415
459
|
});
|