@wazo/sdk 0.38.4 → 0.38.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/README.md +4 -4
- package/dist/wazo-sdk.js +2 -2
- package/esm/__tests__/api-client.test.js +6 -0
- package/esm/__tests__/web-rtc-client.test.js +88 -3
- package/esm/api/calld.js +6 -0
- package/esm/api/ctid-ng.js +6 -0
- package/esm/api-client.js +6 -0
- package/esm/checker/Checker.js +38 -3
- package/esm/checker/checks/aor.js +6 -0
- package/esm/checker/checks/api.js +6 -0
- package/esm/checker/checks/index.js +38 -3
- package/esm/checker/checks/webrtc-transport.js +38 -3
- package/esm/checker/checks/webrtc.js +38 -3
- package/esm/domain/AdHocAPIConference.js +6 -0
- package/esm/domain/Call.js +6 -0
- package/esm/domain/CallSession.js +1 -1
- package/esm/domain/Features.js +6 -0
- package/esm/domain/Phone/CTIPhone.js +7 -1
- package/esm/domain/Phone/WebRTCPhone.js +3 -3
- package/esm/domain/__tests__/Call.test.js +6 -0
- package/esm/domain/__tests__/CallSession.test.js +1 -1
- package/esm/domain/__tests__/IndirectTransfer.test.js +1 -1
- package/esm/domain/__tests__/Line.test.js +5 -5
- package/esm/domain/__tests__/Room.test.js +1 -1
- package/esm/index.js +42 -8
- package/esm/lib/WazoSessionDescriptionHandler.js +30 -1
- package/esm/service/CallApi.js +6 -0
- package/esm/service/getApiClient.js +6 -0
- package/esm/simple/Auth.js +42 -8
- package/esm/simple/Configuration.js +42 -8
- package/esm/simple/Directory.js +6 -0
- package/esm/simple/Phone.js +42 -8
- package/esm/simple/Softphone.js +1 -2
- package/esm/simple/index.js +42 -8
- package/esm/simple/room/LocalParticipant.js +42 -8
- package/esm/simple/room/Participant.js +42 -8
- package/esm/simple/room/RemoteParticipant.js +42 -8
- package/esm/simple/room/Room.js +42 -8
- package/esm/simple/room/SipRoom.js +42 -8
- package/esm/simple/room/Stream.js +42 -8
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +42 -8
- package/esm/simple/utils.js +42 -8
- package/esm/utils/__tests__/sdp.test.js +50 -0
- package/esm/utils/sdp.js +19 -1
- package/esm/web-rtc-client.js +38 -3
- package/lib/__tests__/api-client.test.js +6 -0
- package/lib/__tests__/web-rtc-client.test.js +88 -3
- package/lib/api/calld.js +6 -0
- package/lib/api/ctid-ng.js +6 -0
- package/lib/api-client.js +6 -0
- package/lib/checker/Checker.js +38 -3
- package/lib/checker/checks/aor.js +6 -0
- package/lib/checker/checks/api.js +6 -0
- package/lib/checker/checks/index.js +38 -3
- package/lib/checker/checks/webrtc-transport.js +38 -3
- package/lib/checker/checks/webrtc.js +38 -3
- package/lib/domain/AdHocAPIConference.js +6 -0
- package/lib/domain/Call.js +6 -0
- package/lib/domain/CallSession.js +1 -1
- package/lib/domain/Features.js +6 -0
- package/lib/domain/Phone/CTIPhone.js +7 -1
- package/lib/domain/Phone/WebRTCPhone.js +3 -3
- package/lib/domain/__tests__/Call.test.js +6 -0
- package/lib/domain/__tests__/CallSession.test.js +1 -1
- package/lib/domain/__tests__/IndirectTransfer.test.js +1 -1
- package/lib/domain/__tests__/Line.test.js +5 -5
- package/lib/domain/__tests__/Room.test.js +1 -1
- package/lib/index.js +42 -8
- package/lib/lib/WazoSessionDescriptionHandler.js +30 -1
- package/lib/service/CallApi.js +6 -0
- package/lib/service/getApiClient.js +6 -0
- package/lib/simple/Auth.js +42 -8
- package/lib/simple/Configuration.js +42 -8
- package/lib/simple/Directory.js +6 -0
- package/lib/simple/Phone.js +42 -8
- package/lib/simple/Softphone.js +1 -2
- package/lib/simple/index.js +42 -8
- package/lib/simple/room/LocalParticipant.js +42 -8
- package/lib/simple/room/Participant.js +42 -8
- package/lib/simple/room/RemoteParticipant.js +42 -8
- package/lib/simple/room/Room.js +42 -8
- package/lib/simple/room/SipRoom.js +42 -8
- package/lib/simple/room/Stream.js +42 -8
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +42 -8
- package/lib/simple/utils.js +42 -8
- package/lib/utils/__tests__/sdp.test.js +50 -0
- package/lib/utils/sdp.js +19 -0
- package/lib/web-rtc-client.js +38 -3
- package/package.json +1 -1
- package/src/__tests__/web-rtc-client.test.js +50 -0
- package/src/domain/Call.js +6 -0
- package/src/domain/CallSession.js +1 -1
- package/src/domain/Phone/WebRTCPhone.js +2 -2
- package/src/domain/__tests__/Line.test.js +5 -5
- package/src/lib/WazoSessionDescriptionHandler.js +13 -2
- package/src/simple/Softphone.js +1 -2
- package/src/utils/__tests__/sdp.test.js +33 -1
- package/src/utils/sdp.js +18 -0
- package/src/web-rtc-client.js +2 -2
|
@@ -3081,6 +3081,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
3081
3081
|
|
|
3082
3082
|
|
|
3083
3083
|
|
|
3084
|
+
|
|
3084
3085
|
|
|
3085
3086
|
|
|
3086
3087
|
|
|
@@ -3091,6 +3092,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
3091
3092
|
|
|
3092
3093
|
|
|
3093
3094
|
|
|
3095
|
+
|
|
3094
3096
|
|
|
3095
3097
|
|
|
3096
3098
|
|
|
@@ -3119,6 +3121,7 @@ class Call {
|
|
|
3119
3121
|
|
|
3120
3122
|
|
|
3121
3123
|
|
|
3124
|
+
|
|
3122
3125
|
|
|
3123
3126
|
|
|
3124
3127
|
|
|
@@ -3143,6 +3146,7 @@ class Call {
|
|
|
3143
3146
|
calleeNumber: plain.peer_caller_id_number,
|
|
3144
3147
|
dialedExtension: plain.dialed_extension,
|
|
3145
3148
|
isCaller: plain.is_caller,
|
|
3149
|
+
isVideo: plain.is_video,
|
|
3146
3150
|
muted: plain.muted,
|
|
3147
3151
|
onHold: plain.on_hold,
|
|
3148
3152
|
status: plain.status,
|
|
@@ -3166,6 +3170,7 @@ class Call {
|
|
|
3166
3170
|
calleeNumber,
|
|
3167
3171
|
dialedExtension,
|
|
3168
3172
|
isCaller,
|
|
3173
|
+
isVideo,
|
|
3169
3174
|
lineId,
|
|
3170
3175
|
muted,
|
|
3171
3176
|
onHold,
|
|
@@ -3189,6 +3194,7 @@ class Call {
|
|
|
3189
3194
|
this.startingTime = startingTime;
|
|
3190
3195
|
this.talkingToIds = talkingToIds || [];
|
|
3191
3196
|
this.recording = recording;
|
|
3197
|
+
this.isVideo = !!isVideo;
|
|
3192
3198
|
|
|
3193
3199
|
// Useful to compare instead of instanceof with minified code
|
|
3194
3200
|
this.type = 'Call';
|
|
@@ -3662,7 +3668,7 @@ class CallSession {
|
|
|
3662
3668
|
ringing: call.isRinging(),
|
|
3663
3669
|
answered: call.isUp(),
|
|
3664
3670
|
answeredBySystem: call.isUp() && call.talkingToIds.length === 0,
|
|
3665
|
-
cameraEnabled:
|
|
3671
|
+
cameraEnabled: call.isVideo,
|
|
3666
3672
|
dialedExtension: call.dialedExtension,
|
|
3667
3673
|
call,
|
|
3668
3674
|
conference: false, // @FIXME?
|
|
@@ -6208,6 +6214,24 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
6208
6214
|
return fixed;
|
|
6209
6215
|
};
|
|
6210
6216
|
|
|
6217
|
+
const addIcesInAllBundles = (sdp ) => {
|
|
6218
|
+
const parsedSdp = sdpParser__default['default'].parse(sdp);
|
|
6219
|
+
|
|
6220
|
+
const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
|
|
6221
|
+
if (!mediaWithCandidate) {
|
|
6222
|
+
return sdp;
|
|
6223
|
+
}
|
|
6224
|
+
|
|
6225
|
+
const { candidates } = mediaWithCandidate;
|
|
6226
|
+
|
|
6227
|
+
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
6228
|
+
...media,
|
|
6229
|
+
candidates: media.candidates || candidates,
|
|
6230
|
+
}));
|
|
6231
|
+
|
|
6232
|
+
return sdpParser__default['default'].write(parsedSdp);
|
|
6233
|
+
};
|
|
6234
|
+
|
|
6211
6235
|
/* global RTCSessionDescriptionInit, navigator */
|
|
6212
6236
|
|
|
6213
6237
|
const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
|
|
@@ -6306,6 +6330,14 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
6306
6330
|
wazoLogger.trace('onicecandidate', event.candidate ? event.candidate.candidate : { done: true });
|
|
6307
6331
|
if (event.candidate) {
|
|
6308
6332
|
this.gatheredCandidates.push(parseCandidate$1(event.candidate.candidate));
|
|
6333
|
+
|
|
6334
|
+
// When receiving a `srflx` or a `relay` candidate, consider the negotiation done.
|
|
6335
|
+
if (event.candidate.candidate.indexOf('srflx') !== -1 || event.candidate.candidate.indexOf('relay') !== -1) {
|
|
6336
|
+
wazoLogger.info('A valid ice was found, triggering ice gathering complete callback.', {
|
|
6337
|
+
ice: event.candidate.candidate,
|
|
6338
|
+
});
|
|
6339
|
+
this.iceGatheringComplete();
|
|
6340
|
+
}
|
|
6309
6341
|
}
|
|
6310
6342
|
};
|
|
6311
6343
|
|
|
@@ -6329,7 +6361,10 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
6329
6361
|
|
|
6330
6362
|
// Check if we got ICEs
|
|
6331
6363
|
if (sdp.indexOf('a=candidate') !== -1) {
|
|
6332
|
-
return
|
|
6364
|
+
return {
|
|
6365
|
+
type: description.type,
|
|
6366
|
+
sdp: addIcesInAllBundles(sdp),
|
|
6367
|
+
};
|
|
6333
6368
|
}
|
|
6334
6369
|
|
|
6335
6370
|
wazoLogger.info('No ICE candidates found in SDP, fixing it with gathered ices', this.gatheredCandidates);
|
|
@@ -7789,11 +7824,11 @@ class WebRTCClient extends Emitter {
|
|
|
7789
7824
|
});
|
|
7790
7825
|
}
|
|
7791
7826
|
|
|
7792
|
-
changeAudioInputDevice(id , session ) {
|
|
7827
|
+
changeAudioInputDevice(id , session , force ) {
|
|
7793
7828
|
const currentId = this.getAudioDeviceId();
|
|
7794
7829
|
logger$8.info('setting audio input device', { id, currentId, session: !!session });
|
|
7795
7830
|
|
|
7796
|
-
if (id === currentId) {
|
|
7831
|
+
if (!force && id === currentId) {
|
|
7797
7832
|
return null;
|
|
7798
7833
|
}
|
|
7799
7834
|
|
|
@@ -9589,10 +9624,10 @@ class WebRTCPhone extends Emitter {
|
|
|
9589
9624
|
this.audioRingVolume = volume;
|
|
9590
9625
|
}
|
|
9591
9626
|
|
|
9592
|
-
changeAudioInputDevice(id ) {
|
|
9627
|
+
changeAudioInputDevice(id , force ) {
|
|
9593
9628
|
logger$7.info('WebRTC phone - changeAudio input device', { deviceId: id });
|
|
9594
9629
|
|
|
9595
|
-
return this.client.changeAudioInputDevice(id, this.currentSipSession);
|
|
9630
|
+
return this.client.changeAudioInputDevice(id, this.currentSipSession, force);
|
|
9596
9631
|
}
|
|
9597
9632
|
|
|
9598
9633
|
changeVideoInputDevice(id ) {
|
|
@@ -13962,8 +13997,7 @@ class Softphone {
|
|
|
13962
13997
|
window.addEventListener('message', this._onMessage.bind(this), false);
|
|
13963
13998
|
|
|
13964
13999
|
if (!server) {
|
|
13965
|
-
|
|
13966
|
-
server = 'stack.dev.wazo.io';
|
|
14000
|
+
throw new Error('`server` is not set');
|
|
13967
14001
|
}
|
|
13968
14002
|
|
|
13969
14003
|
const config = { server };
|
|
@@ -3081,6 +3081,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
3081
3081
|
|
|
3082
3082
|
|
|
3083
3083
|
|
|
3084
|
+
|
|
3084
3085
|
|
|
3085
3086
|
|
|
3086
3087
|
|
|
@@ -3091,6 +3092,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
3091
3092
|
|
|
3092
3093
|
|
|
3093
3094
|
|
|
3095
|
+
|
|
3094
3096
|
|
|
3095
3097
|
|
|
3096
3098
|
|
|
@@ -3119,6 +3121,7 @@ class Call {
|
|
|
3119
3121
|
|
|
3120
3122
|
|
|
3121
3123
|
|
|
3124
|
+
|
|
3122
3125
|
|
|
3123
3126
|
|
|
3124
3127
|
|
|
@@ -3143,6 +3146,7 @@ class Call {
|
|
|
3143
3146
|
calleeNumber: plain.peer_caller_id_number,
|
|
3144
3147
|
dialedExtension: plain.dialed_extension,
|
|
3145
3148
|
isCaller: plain.is_caller,
|
|
3149
|
+
isVideo: plain.is_video,
|
|
3146
3150
|
muted: plain.muted,
|
|
3147
3151
|
onHold: plain.on_hold,
|
|
3148
3152
|
status: plain.status,
|
|
@@ -3166,6 +3170,7 @@ class Call {
|
|
|
3166
3170
|
calleeNumber,
|
|
3167
3171
|
dialedExtension,
|
|
3168
3172
|
isCaller,
|
|
3173
|
+
isVideo,
|
|
3169
3174
|
lineId,
|
|
3170
3175
|
muted,
|
|
3171
3176
|
onHold,
|
|
@@ -3189,6 +3194,7 @@ class Call {
|
|
|
3189
3194
|
this.startingTime = startingTime;
|
|
3190
3195
|
this.talkingToIds = talkingToIds || [];
|
|
3191
3196
|
this.recording = recording;
|
|
3197
|
+
this.isVideo = !!isVideo;
|
|
3192
3198
|
|
|
3193
3199
|
// Useful to compare instead of instanceof with minified code
|
|
3194
3200
|
this.type = 'Call';
|
|
@@ -3662,7 +3668,7 @@ class CallSession {
|
|
|
3662
3668
|
ringing: call.isRinging(),
|
|
3663
3669
|
answered: call.isUp(),
|
|
3664
3670
|
answeredBySystem: call.isUp() && call.talkingToIds.length === 0,
|
|
3665
|
-
cameraEnabled:
|
|
3671
|
+
cameraEnabled: call.isVideo,
|
|
3666
3672
|
dialedExtension: call.dialedExtension,
|
|
3667
3673
|
call,
|
|
3668
3674
|
conference: false, // @FIXME?
|
|
@@ -6208,6 +6214,24 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
6208
6214
|
return fixed;
|
|
6209
6215
|
};
|
|
6210
6216
|
|
|
6217
|
+
const addIcesInAllBundles = (sdp ) => {
|
|
6218
|
+
const parsedSdp = sdpParser__default['default'].parse(sdp);
|
|
6219
|
+
|
|
6220
|
+
const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
|
|
6221
|
+
if (!mediaWithCandidate) {
|
|
6222
|
+
return sdp;
|
|
6223
|
+
}
|
|
6224
|
+
|
|
6225
|
+
const { candidates } = mediaWithCandidate;
|
|
6226
|
+
|
|
6227
|
+
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
6228
|
+
...media,
|
|
6229
|
+
candidates: media.candidates || candidates,
|
|
6230
|
+
}));
|
|
6231
|
+
|
|
6232
|
+
return sdpParser__default['default'].write(parsedSdp);
|
|
6233
|
+
};
|
|
6234
|
+
|
|
6211
6235
|
/* global RTCSessionDescriptionInit, navigator */
|
|
6212
6236
|
|
|
6213
6237
|
const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
|
|
@@ -6306,6 +6330,14 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
6306
6330
|
wazoLogger.trace('onicecandidate', event.candidate ? event.candidate.candidate : { done: true });
|
|
6307
6331
|
if (event.candidate) {
|
|
6308
6332
|
this.gatheredCandidates.push(parseCandidate$1(event.candidate.candidate));
|
|
6333
|
+
|
|
6334
|
+
// When receiving a `srflx` or a `relay` candidate, consider the negotiation done.
|
|
6335
|
+
if (event.candidate.candidate.indexOf('srflx') !== -1 || event.candidate.candidate.indexOf('relay') !== -1) {
|
|
6336
|
+
wazoLogger.info('A valid ice was found, triggering ice gathering complete callback.', {
|
|
6337
|
+
ice: event.candidate.candidate,
|
|
6338
|
+
});
|
|
6339
|
+
this.iceGatheringComplete();
|
|
6340
|
+
}
|
|
6309
6341
|
}
|
|
6310
6342
|
};
|
|
6311
6343
|
|
|
@@ -6329,7 +6361,10 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
6329
6361
|
|
|
6330
6362
|
// Check if we got ICEs
|
|
6331
6363
|
if (sdp.indexOf('a=candidate') !== -1) {
|
|
6332
|
-
return
|
|
6364
|
+
return {
|
|
6365
|
+
type: description.type,
|
|
6366
|
+
sdp: addIcesInAllBundles(sdp),
|
|
6367
|
+
};
|
|
6333
6368
|
}
|
|
6334
6369
|
|
|
6335
6370
|
wazoLogger.info('No ICE candidates found in SDP, fixing it with gathered ices', this.gatheredCandidates);
|
|
@@ -7789,11 +7824,11 @@ class WebRTCClient extends Emitter {
|
|
|
7789
7824
|
});
|
|
7790
7825
|
}
|
|
7791
7826
|
|
|
7792
|
-
changeAudioInputDevice(id , session ) {
|
|
7827
|
+
changeAudioInputDevice(id , session , force ) {
|
|
7793
7828
|
const currentId = this.getAudioDeviceId();
|
|
7794
7829
|
logger$8.info('setting audio input device', { id, currentId, session: !!session });
|
|
7795
7830
|
|
|
7796
|
-
if (id === currentId) {
|
|
7831
|
+
if (!force && id === currentId) {
|
|
7797
7832
|
return null;
|
|
7798
7833
|
}
|
|
7799
7834
|
|
|
@@ -9589,10 +9624,10 @@ class WebRTCPhone extends Emitter {
|
|
|
9589
9624
|
this.audioRingVolume = volume;
|
|
9590
9625
|
}
|
|
9591
9626
|
|
|
9592
|
-
changeAudioInputDevice(id ) {
|
|
9627
|
+
changeAudioInputDevice(id , force ) {
|
|
9593
9628
|
logger$7.info('WebRTC phone - changeAudio input device', { deviceId: id });
|
|
9594
9629
|
|
|
9595
|
-
return this.client.changeAudioInputDevice(id, this.currentSipSession);
|
|
9630
|
+
return this.client.changeAudioInputDevice(id, this.currentSipSession, force);
|
|
9596
9631
|
}
|
|
9597
9632
|
|
|
9598
9633
|
changeVideoInputDevice(id ) {
|
|
@@ -14043,8 +14078,7 @@ class Softphone {
|
|
|
14043
14078
|
window.addEventListener('message', this._onMessage.bind(this), false);
|
|
14044
14079
|
|
|
14045
14080
|
if (!server) {
|
|
14046
|
-
|
|
14047
|
-
server = 'stack.dev.wazo.io';
|
|
14081
|
+
throw new Error('`server` is not set');
|
|
14048
14082
|
}
|
|
14049
14083
|
|
|
14050
14084
|
const config = { server };
|
|
@@ -3081,6 +3081,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
3081
3081
|
|
|
3082
3082
|
|
|
3083
3083
|
|
|
3084
|
+
|
|
3084
3085
|
|
|
3085
3086
|
|
|
3086
3087
|
|
|
@@ -3091,6 +3092,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
3091
3092
|
|
|
3092
3093
|
|
|
3093
3094
|
|
|
3095
|
+
|
|
3094
3096
|
|
|
3095
3097
|
|
|
3096
3098
|
|
|
@@ -3119,6 +3121,7 @@ class Call {
|
|
|
3119
3121
|
|
|
3120
3122
|
|
|
3121
3123
|
|
|
3124
|
+
|
|
3122
3125
|
|
|
3123
3126
|
|
|
3124
3127
|
|
|
@@ -3143,6 +3146,7 @@ class Call {
|
|
|
3143
3146
|
calleeNumber: plain.peer_caller_id_number,
|
|
3144
3147
|
dialedExtension: plain.dialed_extension,
|
|
3145
3148
|
isCaller: plain.is_caller,
|
|
3149
|
+
isVideo: plain.is_video,
|
|
3146
3150
|
muted: plain.muted,
|
|
3147
3151
|
onHold: plain.on_hold,
|
|
3148
3152
|
status: plain.status,
|
|
@@ -3166,6 +3170,7 @@ class Call {
|
|
|
3166
3170
|
calleeNumber,
|
|
3167
3171
|
dialedExtension,
|
|
3168
3172
|
isCaller,
|
|
3173
|
+
isVideo,
|
|
3169
3174
|
lineId,
|
|
3170
3175
|
muted,
|
|
3171
3176
|
onHold,
|
|
@@ -3189,6 +3194,7 @@ class Call {
|
|
|
3189
3194
|
this.startingTime = startingTime;
|
|
3190
3195
|
this.talkingToIds = talkingToIds || [];
|
|
3191
3196
|
this.recording = recording;
|
|
3197
|
+
this.isVideo = !!isVideo;
|
|
3192
3198
|
|
|
3193
3199
|
// Useful to compare instead of instanceof with minified code
|
|
3194
3200
|
this.type = 'Call';
|
|
@@ -3662,7 +3668,7 @@ class CallSession {
|
|
|
3662
3668
|
ringing: call.isRinging(),
|
|
3663
3669
|
answered: call.isUp(),
|
|
3664
3670
|
answeredBySystem: call.isUp() && call.talkingToIds.length === 0,
|
|
3665
|
-
cameraEnabled:
|
|
3671
|
+
cameraEnabled: call.isVideo,
|
|
3666
3672
|
dialedExtension: call.dialedExtension,
|
|
3667
3673
|
call,
|
|
3668
3674
|
conference: false, // @FIXME?
|
|
@@ -6208,6 +6214,24 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
6208
6214
|
return fixed;
|
|
6209
6215
|
};
|
|
6210
6216
|
|
|
6217
|
+
const addIcesInAllBundles = (sdp ) => {
|
|
6218
|
+
const parsedSdp = sdpParser__default['default'].parse(sdp);
|
|
6219
|
+
|
|
6220
|
+
const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
|
|
6221
|
+
if (!mediaWithCandidate) {
|
|
6222
|
+
return sdp;
|
|
6223
|
+
}
|
|
6224
|
+
|
|
6225
|
+
const { candidates } = mediaWithCandidate;
|
|
6226
|
+
|
|
6227
|
+
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
6228
|
+
...media,
|
|
6229
|
+
candidates: media.candidates || candidates,
|
|
6230
|
+
}));
|
|
6231
|
+
|
|
6232
|
+
return sdpParser__default['default'].write(parsedSdp);
|
|
6233
|
+
};
|
|
6234
|
+
|
|
6211
6235
|
/* global RTCSessionDescriptionInit, navigator */
|
|
6212
6236
|
|
|
6213
6237
|
const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
|
|
@@ -6306,6 +6330,14 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
6306
6330
|
wazoLogger.trace('onicecandidate', event.candidate ? event.candidate.candidate : { done: true });
|
|
6307
6331
|
if (event.candidate) {
|
|
6308
6332
|
this.gatheredCandidates.push(parseCandidate$1(event.candidate.candidate));
|
|
6333
|
+
|
|
6334
|
+
// When receiving a `srflx` or a `relay` candidate, consider the negotiation done.
|
|
6335
|
+
if (event.candidate.candidate.indexOf('srflx') !== -1 || event.candidate.candidate.indexOf('relay') !== -1) {
|
|
6336
|
+
wazoLogger.info('A valid ice was found, triggering ice gathering complete callback.', {
|
|
6337
|
+
ice: event.candidate.candidate,
|
|
6338
|
+
});
|
|
6339
|
+
this.iceGatheringComplete();
|
|
6340
|
+
}
|
|
6309
6341
|
}
|
|
6310
6342
|
};
|
|
6311
6343
|
|
|
@@ -6329,7 +6361,10 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
6329
6361
|
|
|
6330
6362
|
// Check if we got ICEs
|
|
6331
6363
|
if (sdp.indexOf('a=candidate') !== -1) {
|
|
6332
|
-
return
|
|
6364
|
+
return {
|
|
6365
|
+
type: description.type,
|
|
6366
|
+
sdp: addIcesInAllBundles(sdp),
|
|
6367
|
+
};
|
|
6333
6368
|
}
|
|
6334
6369
|
|
|
6335
6370
|
wazoLogger.info('No ICE candidates found in SDP, fixing it with gathered ices', this.gatheredCandidates);
|
|
@@ -7789,11 +7824,11 @@ class WebRTCClient extends Emitter {
|
|
|
7789
7824
|
});
|
|
7790
7825
|
}
|
|
7791
7826
|
|
|
7792
|
-
changeAudioInputDevice(id , session ) {
|
|
7827
|
+
changeAudioInputDevice(id , session , force ) {
|
|
7793
7828
|
const currentId = this.getAudioDeviceId();
|
|
7794
7829
|
logger$8.info('setting audio input device', { id, currentId, session: !!session });
|
|
7795
7830
|
|
|
7796
|
-
if (id === currentId) {
|
|
7831
|
+
if (!force && id === currentId) {
|
|
7797
7832
|
return null;
|
|
7798
7833
|
}
|
|
7799
7834
|
|
|
@@ -9589,10 +9624,10 @@ class WebRTCPhone extends Emitter {
|
|
|
9589
9624
|
this.audioRingVolume = volume;
|
|
9590
9625
|
}
|
|
9591
9626
|
|
|
9592
|
-
changeAudioInputDevice(id ) {
|
|
9627
|
+
changeAudioInputDevice(id , force ) {
|
|
9593
9628
|
logger$7.info('WebRTC phone - changeAudio input device', { deviceId: id });
|
|
9594
9629
|
|
|
9595
|
-
return this.client.changeAudioInputDevice(id, this.currentSipSession);
|
|
9630
|
+
return this.client.changeAudioInputDevice(id, this.currentSipSession, force);
|
|
9596
9631
|
}
|
|
9597
9632
|
|
|
9598
9633
|
changeVideoInputDevice(id ) {
|
|
@@ -14101,8 +14136,7 @@ class Softphone {
|
|
|
14101
14136
|
window.addEventListener('message', this._onMessage.bind(this), false);
|
|
14102
14137
|
|
|
14103
14138
|
if (!server) {
|
|
14104
|
-
|
|
14105
|
-
server = 'stack.dev.wazo.io';
|
|
14139
|
+
throw new Error('`server` is not set');
|
|
14106
14140
|
}
|
|
14107
14141
|
|
|
14108
14142
|
const config = { server };
|
package/lib/simple/utils.js
CHANGED
|
@@ -3083,6 +3083,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
3083
3083
|
|
|
3084
3084
|
|
|
3085
3085
|
|
|
3086
|
+
|
|
3086
3087
|
|
|
3087
3088
|
|
|
3088
3089
|
|
|
@@ -3093,6 +3094,7 @@ const RECORD_STATE_ACTIVE = 'active';
|
|
|
3093
3094
|
|
|
3094
3095
|
|
|
3095
3096
|
|
|
3097
|
+
|
|
3096
3098
|
|
|
3097
3099
|
|
|
3098
3100
|
|
|
@@ -3121,6 +3123,7 @@ class Call {
|
|
|
3121
3123
|
|
|
3122
3124
|
|
|
3123
3125
|
|
|
3126
|
+
|
|
3124
3127
|
|
|
3125
3128
|
|
|
3126
3129
|
|
|
@@ -3145,6 +3148,7 @@ class Call {
|
|
|
3145
3148
|
calleeNumber: plain.peer_caller_id_number,
|
|
3146
3149
|
dialedExtension: plain.dialed_extension,
|
|
3147
3150
|
isCaller: plain.is_caller,
|
|
3151
|
+
isVideo: plain.is_video,
|
|
3148
3152
|
muted: plain.muted,
|
|
3149
3153
|
onHold: plain.on_hold,
|
|
3150
3154
|
status: plain.status,
|
|
@@ -3168,6 +3172,7 @@ class Call {
|
|
|
3168
3172
|
calleeNumber,
|
|
3169
3173
|
dialedExtension,
|
|
3170
3174
|
isCaller,
|
|
3175
|
+
isVideo,
|
|
3171
3176
|
lineId,
|
|
3172
3177
|
muted,
|
|
3173
3178
|
onHold,
|
|
@@ -3191,6 +3196,7 @@ class Call {
|
|
|
3191
3196
|
this.startingTime = startingTime;
|
|
3192
3197
|
this.talkingToIds = talkingToIds || [];
|
|
3193
3198
|
this.recording = recording;
|
|
3199
|
+
this.isVideo = !!isVideo;
|
|
3194
3200
|
|
|
3195
3201
|
// Useful to compare instead of instanceof with minified code
|
|
3196
3202
|
this.type = 'Call';
|
|
@@ -3664,7 +3670,7 @@ class CallSession {
|
|
|
3664
3670
|
ringing: call.isRinging(),
|
|
3665
3671
|
answered: call.isUp(),
|
|
3666
3672
|
answeredBySystem: call.isUp() && call.talkingToIds.length === 0,
|
|
3667
|
-
cameraEnabled:
|
|
3673
|
+
cameraEnabled: call.isVideo,
|
|
3668
3674
|
dialedExtension: call.dialedExtension,
|
|
3669
3675
|
call,
|
|
3670
3676
|
conference: false, // @FIXME?
|
|
@@ -6210,6 +6216,24 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
6210
6216
|
return fixed;
|
|
6211
6217
|
};
|
|
6212
6218
|
|
|
6219
|
+
const addIcesInAllBundles = (sdp ) => {
|
|
6220
|
+
const parsedSdp = sdpParser__default['default'].parse(sdp);
|
|
6221
|
+
|
|
6222
|
+
const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
|
|
6223
|
+
if (!mediaWithCandidate) {
|
|
6224
|
+
return sdp;
|
|
6225
|
+
}
|
|
6226
|
+
|
|
6227
|
+
const { candidates } = mediaWithCandidate;
|
|
6228
|
+
|
|
6229
|
+
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
6230
|
+
...media,
|
|
6231
|
+
candidates: media.candidates || candidates,
|
|
6232
|
+
}));
|
|
6233
|
+
|
|
6234
|
+
return sdpParser__default['default'].write(parsedSdp);
|
|
6235
|
+
};
|
|
6236
|
+
|
|
6213
6237
|
/* global RTCSessionDescriptionInit, navigator */
|
|
6214
6238
|
|
|
6215
6239
|
const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
|
|
@@ -6308,6 +6332,14 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
6308
6332
|
wazoLogger.trace('onicecandidate', event.candidate ? event.candidate.candidate : { done: true });
|
|
6309
6333
|
if (event.candidate) {
|
|
6310
6334
|
this.gatheredCandidates.push(parseCandidate$1(event.candidate.candidate));
|
|
6335
|
+
|
|
6336
|
+
// When receiving a `srflx` or a `relay` candidate, consider the negotiation done.
|
|
6337
|
+
if (event.candidate.candidate.indexOf('srflx') !== -1 || event.candidate.candidate.indexOf('relay') !== -1) {
|
|
6338
|
+
wazoLogger.info('A valid ice was found, triggering ice gathering complete callback.', {
|
|
6339
|
+
ice: event.candidate.candidate,
|
|
6340
|
+
});
|
|
6341
|
+
this.iceGatheringComplete();
|
|
6342
|
+
}
|
|
6311
6343
|
}
|
|
6312
6344
|
};
|
|
6313
6345
|
|
|
@@ -6331,7 +6363,10 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
6331
6363
|
|
|
6332
6364
|
// Check if we got ICEs
|
|
6333
6365
|
if (sdp.indexOf('a=candidate') !== -1) {
|
|
6334
|
-
return
|
|
6366
|
+
return {
|
|
6367
|
+
type: description.type,
|
|
6368
|
+
sdp: addIcesInAllBundles(sdp),
|
|
6369
|
+
};
|
|
6335
6370
|
}
|
|
6336
6371
|
|
|
6337
6372
|
wazoLogger.info('No ICE candidates found in SDP, fixing it with gathered ices', this.gatheredCandidates);
|
|
@@ -7791,11 +7826,11 @@ class WebRTCClient extends Emitter {
|
|
|
7791
7826
|
});
|
|
7792
7827
|
}
|
|
7793
7828
|
|
|
7794
|
-
changeAudioInputDevice(id , session ) {
|
|
7829
|
+
changeAudioInputDevice(id , session , force ) {
|
|
7795
7830
|
const currentId = this.getAudioDeviceId();
|
|
7796
7831
|
logger$8.info('setting audio input device', { id, currentId, session: !!session });
|
|
7797
7832
|
|
|
7798
|
-
if (id === currentId) {
|
|
7833
|
+
if (!force && id === currentId) {
|
|
7799
7834
|
return null;
|
|
7800
7835
|
}
|
|
7801
7836
|
|
|
@@ -9591,10 +9626,10 @@ class WebRTCPhone extends Emitter {
|
|
|
9591
9626
|
this.audioRingVolume = volume;
|
|
9592
9627
|
}
|
|
9593
9628
|
|
|
9594
|
-
changeAudioInputDevice(id ) {
|
|
9629
|
+
changeAudioInputDevice(id , force ) {
|
|
9595
9630
|
logger$7.info('WebRTC phone - changeAudio input device', { deviceId: id });
|
|
9596
9631
|
|
|
9597
|
-
return this.client.changeAudioInputDevice(id, this.currentSipSession);
|
|
9632
|
+
return this.client.changeAudioInputDevice(id, this.currentSipSession, force);
|
|
9598
9633
|
}
|
|
9599
9634
|
|
|
9600
9635
|
changeVideoInputDevice(id ) {
|
|
@@ -14087,8 +14122,7 @@ class Softphone {
|
|
|
14087
14122
|
window.addEventListener('message', this._onMessage.bind(this), false);
|
|
14088
14123
|
|
|
14089
14124
|
if (!server) {
|
|
14090
|
-
|
|
14091
|
-
server = 'stack.dev.wazo.io';
|
|
14125
|
+
throw new Error('`server` is not set');
|
|
14092
14126
|
}
|
|
14093
14127
|
|
|
14094
14128
|
const config = { server };
|
|
@@ -104,6 +104,24 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
104
104
|
return fixed;
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
+
const addIcesInAllBundles = (sdp ) => {
|
|
108
|
+
const parsedSdp = sdpParser__default['default'].parse(sdp);
|
|
109
|
+
|
|
110
|
+
const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
|
|
111
|
+
if (!mediaWithCandidate) {
|
|
112
|
+
return sdp;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const { candidates } = mediaWithCandidate;
|
|
116
|
+
|
|
117
|
+
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
118
|
+
...media,
|
|
119
|
+
candidates: media.candidates || candidates,
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
return sdpParser__default['default'].write(parsedSdp);
|
|
123
|
+
};
|
|
124
|
+
|
|
107
125
|
/* eslint-disable max-len */
|
|
108
126
|
|
|
109
127
|
const goodSdp = `
|
|
@@ -268,4 +286,36 @@ describe('SDP utils', () => {
|
|
|
268
286
|
expect(hasAnActiveVideo(inactiveVideo)).toBeFalsy();
|
|
269
287
|
});
|
|
270
288
|
});
|
|
289
|
+
|
|
290
|
+
describe('Adding candidate in all bundles ', () => {
|
|
291
|
+
it('should add candidate everywhere', async () => {
|
|
292
|
+
const audioWithoutCandidate = `
|
|
293
|
+
c=IN IP4 203.0.113.1
|
|
294
|
+
m=audio 54400 RTP/SAVPF 0 96
|
|
295
|
+
m=video 54400 RTP/SAVPF 0 96
|
|
296
|
+
a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
|
|
297
|
+
a=candidate:3996450952 1 udp 41819903 14.72.21.2 65092 typ relay raddr 0.0.0.0 rport 0 generation 0 network-id 3 network-cost 10
|
|
298
|
+
`;
|
|
299
|
+
const fixedAudioWithoutCandidate = sdpParser__default['default'].parse(addIcesInAllBundles(audioWithoutCandidate));
|
|
300
|
+
|
|
301
|
+
expect(fixedAudioWithoutCandidate.media[0].candidates[0].type).toBe('host');
|
|
302
|
+
expect(fixedAudioWithoutCandidate.media[0].candidates[1].type).toBe('relay');
|
|
303
|
+
expect(fixedAudioWithoutCandidate.media[1].candidates[0].type).toBe('host');
|
|
304
|
+
expect(fixedAudioWithoutCandidate.media[1].candidates[1].type).toBe('relay');
|
|
305
|
+
|
|
306
|
+
// It should not add candidate if already present
|
|
307
|
+
const audioWithCandidate = `
|
|
308
|
+
c=IN IP4 203.0.113.1
|
|
309
|
+
m=audio 54400 RTP/SAVPF 0 96
|
|
310
|
+
a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ srflx
|
|
311
|
+
|
|
312
|
+
m=video 54400 RTP/SAVPF 0 96
|
|
313
|
+
a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
|
|
314
|
+
`;
|
|
315
|
+
const fixedAudioWithCandidate = sdpParser__default['default'].parse(addIcesInAllBundles(audioWithCandidate));
|
|
316
|
+
|
|
317
|
+
expect(fixedAudioWithCandidate.media[0].candidates[0].type).toBe('srflx');
|
|
318
|
+
expect(fixedAudioWithCandidate.media[1].candidates[0].type).toBe('host');
|
|
319
|
+
});
|
|
320
|
+
});
|
|
271
321
|
});
|
package/lib/utils/sdp.js
CHANGED
|
@@ -130,7 +130,26 @@ const fixSdp = (sdp , candidates , forcePort = true)
|
|
|
130
130
|
return fixed;
|
|
131
131
|
};
|
|
132
132
|
|
|
133
|
+
const addIcesInAllBundles = (sdp ) => {
|
|
134
|
+
const parsedSdp = sdpParser__default['default'].parse(sdp);
|
|
135
|
+
|
|
136
|
+
const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
|
|
137
|
+
if (!mediaWithCandidate) {
|
|
138
|
+
return sdp;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const { candidates } = mediaWithCandidate;
|
|
142
|
+
|
|
143
|
+
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
144
|
+
...media,
|
|
145
|
+
candidates: media.candidates || candidates,
|
|
146
|
+
}));
|
|
147
|
+
|
|
148
|
+
return sdpParser__default['default'].write(parsedSdp);
|
|
149
|
+
};
|
|
150
|
+
|
|
133
151
|
exports.activateVideoModifier = activateVideoModifier;
|
|
152
|
+
exports.addIcesInAllBundles = addIcesInAllBundles;
|
|
134
153
|
exports.areCandidateValid = areCandidateValid;
|
|
135
154
|
exports.deactivateVideoModifier = deactivateVideoModifier;
|
|
136
155
|
exports.fixBundle = fixBundle;
|