@wazo/sdk 1.0.0-alpha.2 → 1.0.0-alpha.20
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 +16 -7
- package/dist/wazo-sdk.js +2 -2
- package/esm/__tests__/__voice__/call.test.js +52 -3
- package/esm/api/auth.js +3 -0
- package/esm/checker/checks/webrtc.js +2 -2
- package/esm/domain/CallLog.js +2 -3
- package/esm/domain/Phone/CTIPhone.js +2 -2
- package/esm/domain/Phone/WebRTCPhone.js +59 -57
- package/esm/index.js +3 -1
- package/esm/service/CallApi.js +4 -4
- package/esm/simple/Auth.js +13 -3
- package/esm/simple/Phone.js +5 -5
- package/esm/simple/index.js +2 -1
- package/esm/simple/room/Room.js +2 -2
- package/esm/simple/room/SipRoom.js +2 -2
- package/esm/state-machine/call-state-machine.js +34 -19
- package/esm/state-machine/softphone-state-machine.js +1 -2
- package/esm/state-machine/utils.js +10 -4
- package/esm/types/api/auth.d.ts +3 -0
- package/esm/types/api/auth.d.ts.map +1 -1
- package/esm/types/checker/checks/index.d.ts +1 -1
- package/esm/types/checker/checks/webrtc-transport.d.ts +2 -2
- package/esm/types/checker/checks/webrtc-transport.d.ts.map +1 -1
- package/esm/types/domain/CallLog.d.ts.map +1 -1
- package/esm/types/domain/CallSession.d.ts +3 -3
- package/esm/types/domain/CallSession.d.ts.map +1 -1
- package/esm/types/domain/Phone/CTIPhone.d.ts.map +1 -1
- package/esm/types/domain/Phone/WebRTCPhone.d.ts +22 -22
- package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
- package/esm/types/domain/types.d.ts +0 -4
- package/esm/types/domain/types.d.ts.map +1 -1
- package/esm/types/index.d.ts +3 -1
- package/esm/types/index.d.ts.map +1 -1
- package/esm/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
- package/esm/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
- package/esm/types/service/CallApi.d.ts +5 -5
- package/esm/types/service/CallApi.d.ts.map +1 -1
- package/esm/types/simple/Auth.d.ts +6 -1
- package/esm/types/simple/Auth.d.ts.map +1 -1
- package/esm/types/simple/Phone.d.ts +8 -8
- package/esm/types/simple/Phone.d.ts.map +1 -1
- package/esm/types/simple/index.d.ts +3 -1
- package/esm/types/simple/index.d.ts.map +1 -1
- package/esm/types/state-machine/call-state-machine.d.ts +12 -1
- package/esm/types/state-machine/call-state-machine.d.ts.map +1 -1
- package/esm/types/state-machine/softphone-state-machine.d.ts +1 -2
- package/esm/types/state-machine/softphone-state-machine.d.ts.map +1 -1
- package/esm/types/state-machine/utils.d.ts +1 -1
- package/esm/types/state-machine/utils.d.ts.map +1 -1
- package/esm/types/utils/sdp.d.ts +1 -2
- package/esm/types/utils/sdp.d.ts.map +1 -1
- package/esm/types/utils/update-from.d.ts +1 -1
- package/esm/types/utils/update-from.d.ts.map +1 -1
- package/esm/types/utils/webrtc.d.ts.map +1 -1
- package/esm/types/voice/call.d.ts +15 -3
- package/esm/types/voice/call.d.ts.map +1 -1
- package/esm/types/voice/softphone.d.ts +7 -0
- package/esm/types/voice/softphone.d.ts.map +1 -1
- package/esm/types/web-rtc-client.d.ts +39 -38
- package/esm/types/web-rtc-client.d.ts.map +1 -1
- package/esm/utils/sdp.js +16 -9
- package/esm/utils/update-from.js +2 -2
- package/esm/utils/webrtc.js +10 -4
- package/esm/voice/call.js +86 -28
- package/esm/voice/softphone.js +58 -17
- package/esm/web-rtc-client.js +67 -58
- package/lib/__tests__/__voice__/call.test.js +51 -2
- package/lib/api/auth.js +3 -0
- package/lib/checker/checks/webrtc.js +1 -1
- package/lib/domain/CallLog.js +2 -3
- package/lib/domain/Phone/CTIPhone.js +2 -2
- package/lib/domain/Phone/WebRTCPhone.js +58 -56
- package/lib/index.js +7 -3
- package/lib/service/CallApi.js +2 -2
- package/lib/simple/Auth.js +15 -3
- package/lib/simple/Phone.js +2 -2
- package/lib/simple/index.js +2 -1
- package/lib/simple/room/Room.js +1 -1
- package/lib/simple/room/SipRoom.js +1 -1
- package/lib/state-machine/call-state-machine.js +35 -20
- package/lib/state-machine/softphone-state-machine.js +1 -2
- package/lib/state-machine/utils.js +10 -4
- package/lib/types/api/auth.d.ts +3 -0
- package/lib/types/api/auth.d.ts.map +1 -1
- package/lib/types/checker/checks/index.d.ts +1 -1
- package/lib/types/checker/checks/webrtc-transport.d.ts +2 -2
- package/lib/types/checker/checks/webrtc-transport.d.ts.map +1 -1
- package/lib/types/domain/CallLog.d.ts.map +1 -1
- package/lib/types/domain/CallSession.d.ts +3 -3
- package/lib/types/domain/CallSession.d.ts.map +1 -1
- package/lib/types/domain/Phone/CTIPhone.d.ts.map +1 -1
- package/lib/types/domain/Phone/WebRTCPhone.d.ts +22 -22
- package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
- package/lib/types/domain/types.d.ts +0 -4
- package/lib/types/domain/types.d.ts.map +1 -1
- package/lib/types/index.d.ts +3 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
- package/lib/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
- package/lib/types/service/CallApi.d.ts +5 -5
- package/lib/types/service/CallApi.d.ts.map +1 -1
- package/lib/types/simple/Auth.d.ts +6 -1
- package/lib/types/simple/Auth.d.ts.map +1 -1
- package/lib/types/simple/Phone.d.ts +8 -8
- package/lib/types/simple/Phone.d.ts.map +1 -1
- package/lib/types/simple/index.d.ts +3 -1
- package/lib/types/simple/index.d.ts.map +1 -1
- package/lib/types/state-machine/call-state-machine.d.ts +12 -1
- package/lib/types/state-machine/call-state-machine.d.ts.map +1 -1
- package/lib/types/state-machine/softphone-state-machine.d.ts +1 -2
- package/lib/types/state-machine/softphone-state-machine.d.ts.map +1 -1
- package/lib/types/state-machine/utils.d.ts +1 -1
- package/lib/types/state-machine/utils.d.ts.map +1 -1
- package/lib/types/utils/sdp.d.ts +1 -2
- package/lib/types/utils/sdp.d.ts.map +1 -1
- package/lib/types/utils/update-from.d.ts +1 -1
- package/lib/types/utils/update-from.d.ts.map +1 -1
- package/lib/types/utils/webrtc.d.ts.map +1 -1
- package/lib/types/voice/call.d.ts +15 -3
- package/lib/types/voice/call.d.ts.map +1 -1
- package/lib/types/voice/softphone.d.ts +7 -0
- package/lib/types/voice/softphone.d.ts.map +1 -1
- package/lib/types/web-rtc-client.d.ts +39 -38
- package/lib/types/web-rtc-client.d.ts.map +1 -1
- package/lib/utils/sdp.js +17 -10
- package/lib/utils/update-from.js +2 -2
- package/lib/utils/webrtc.js +11 -4
- package/lib/voice/call.js +89 -27
- package/lib/voice/softphone.js +62 -17
- package/lib/web-rtc-client.js +66 -57
- package/package.json +1 -1
- package/src/__tests__/__voice__/call.test.ts +61 -3
- package/src/api/auth.ts +5 -0
- package/src/checker/checks/webrtc-transport.ts +2 -2
- package/src/checker/checks/webrtc.ts +2 -2
- package/src/domain/CallLog.ts +2 -3
- package/src/domain/CallSession.ts +3 -3
- package/src/domain/Phone/CTIPhone.ts +3 -2
- package/src/domain/Phone/WebRTCPhone.ts +87 -85
- package/src/domain/__tests__/CallSession.test.ts +4 -0
- package/src/domain/types.ts +0 -5
- package/src/index.ts +4 -1
- package/src/lib/WazoSessionDescriptionHandler.ts +3 -3
- package/src/service/CallApi.ts +7 -7
- package/src/simple/Auth.ts +15 -3
- package/src/simple/Phone.ts +11 -11
- package/src/simple/index.ts +2 -1
- package/src/simple/room/Room.ts +3 -3
- package/src/simple/room/SipRoom.ts +3 -3
- package/src/state-machine/call-state-machine.ts +38 -19
- package/src/state-machine/softphone-state-machine.ts +1 -2
- package/src/state-machine/utils.ts +12 -4
- package/src/utils/sdp.ts +18 -11
- package/src/utils/update-from.ts +2 -2
- package/src/utils/webrtc.ts +11 -4
- package/src/voice/call.ts +109 -36
- package/src/voice/softphone.ts +75 -18
- package/src/web-rtc-client.ts +112 -98
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { default as ServerError } from './domain/ServerError';
|
|
|
7
7
|
export { default as InvalidStateTransition } from './domain/InvalidStateTransition';
|
|
8
8
|
export { default as InvalidState } from './domain/InvalidState';
|
|
9
9
|
export { default as SFUNotAvailableError } from './domain/SFUNotAvailableError';
|
|
10
|
-
export { default as
|
|
10
|
+
export { default as ApiCall } from './domain/Call';
|
|
11
11
|
export { default as CallLog } from './domain/CallLog';
|
|
12
12
|
export { default as Recording } from './domain/Recording';
|
|
13
13
|
export { default as ChatMessage } from './domain/ChatMessage';
|
|
@@ -53,6 +53,9 @@ export { default as WazoApiClient } from './api-client';
|
|
|
53
53
|
export { default as Agent, AgentResponse, AgentArguments } from './domain/Agent';
|
|
54
54
|
export { default as ExternalApp } from './domain/ExternalApp';
|
|
55
55
|
export { default as SessionDescriptionHandler } from './lib/WazoSessionDescriptionHandler';
|
|
56
|
+
export { default as Call } from './voice/call';
|
|
57
|
+
export { Softphone } from './voice/softphone';
|
|
58
|
+
|
|
56
59
|
export * from './types/WebSocketMessage';
|
|
57
60
|
export * from './utils/PhoneNumberUtil';
|
|
58
61
|
export * from './utils/string';
|
|
@@ -5,7 +5,7 @@ import type { MediaStreamFactory } from 'sip.js/lib/platform/web/session-descrip
|
|
|
5
5
|
import type { SessionDescriptionHandlerConfiguration } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-configuration';
|
|
6
6
|
import { SessionDescriptionHandler } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler';
|
|
7
7
|
import { SessionDescriptionHandlerOptions } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-options';
|
|
8
|
-
import { PeerConnection,
|
|
8
|
+
import { PeerConnection, SipCall } from '../domain/types';
|
|
9
9
|
import IssueReporter from '../service/IssueReporter';
|
|
10
10
|
import { type Candidate, addIcesInAllBundles, fixSdp, parseCandidate } from '../utils/sdp';
|
|
11
11
|
|
|
@@ -36,10 +36,10 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
36
36
|
|
|
37
37
|
isWeb: boolean;
|
|
38
38
|
|
|
39
|
-
session:
|
|
39
|
+
session: SipCall;
|
|
40
40
|
|
|
41
41
|
// eslint-disable-next-line @typescript-eslint/default-param-last
|
|
42
|
-
constructor(logger: Logger, mediaStreamFactory: MediaStreamFactory, sessionDescriptionHandlerConfiguration: SessionDescriptionHandlerConfiguration, isWeb: boolean, session:
|
|
42
|
+
constructor(logger: Logger, mediaStreamFactory: MediaStreamFactory, sessionDescriptionHandlerConfiguration: SessionDescriptionHandlerConfiguration, isWeb: boolean, session: SipCall) {
|
|
43
43
|
super(logger, mediaStreamFactory, sessionDescriptionHandlerConfiguration);
|
|
44
44
|
this.eventEmitter = new EventEmitter();
|
|
45
45
|
this.isWeb = isWeb;
|
package/src/service/CallApi.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ApiCall from '../domain/Call';
|
|
2
|
+
import Call from '../voice/call';
|
|
2
3
|
import CallLog from '../domain/CallLog';
|
|
3
4
|
import Line from '../domain/Line';
|
|
4
5
|
import Session from '../domain/Session';
|
|
5
6
|
import Relocation from '../domain/Relocation';
|
|
6
|
-
import CallSession from '../domain/CallSession';
|
|
7
7
|
import getApiClient from './getApiClient';
|
|
8
8
|
import Transfer from '../domain/IndirectTransfer';
|
|
9
9
|
|
|
@@ -16,7 +16,7 @@ export default class CallApi {
|
|
|
16
16
|
return getApiClient().callLogd.listDistinctCallLogs(offset, limit, distinct);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
static async fetchActiveCalls(): Promise<
|
|
19
|
+
static async fetchActiveCalls(): Promise<ApiCall[]> {
|
|
20
20
|
return getApiClient().calld.listCalls();
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -37,14 +37,14 @@ export default class CallApi {
|
|
|
37
37
|
return getApiClient().confd.getUserLineSip(session.uuid as string, lineToUse ? <unknown>lineToUse.id as string : '');
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
static async cancelCall(
|
|
41
|
-
return getApiClient().calld.cancelCall(
|
|
40
|
+
static async cancelCall(call: Call): Promise<boolean> {
|
|
41
|
+
return getApiClient().calld.cancelCall(call.apiId || '');
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
static async makeCall(callFromLine: Line, extension: string, isMobile = false, callbackAllLines = false): Promise<
|
|
44
|
+
static async makeCall(callFromLine: Line, extension: string, isMobile = false, callbackAllLines = false): Promise<ApiCall | null | undefined> {
|
|
45
45
|
const lineId = callFromLine ? callFromLine.id : null;
|
|
46
46
|
const response = await getApiClient().calld.makeCall(extension, isMobile, lineId, callbackAllLines);
|
|
47
|
-
return
|
|
47
|
+
return ApiCall.parse(response);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
static async relocateCall(callId: string, line: number, contactIdentifier?: string): Promise<Relocation> {
|
package/src/simple/Auth.ts
CHANGED
|
@@ -167,6 +167,10 @@ export class Auth {
|
|
|
167
167
|
return this._onAuthenticated(rawSession as Session);
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
+
async samlLogOut(): Promise<void | { location: string }> {
|
|
171
|
+
return await this.logout(false, true);
|
|
172
|
+
}
|
|
173
|
+
|
|
170
174
|
async initiateIdpAuthentication(domain: string, redirectUrl: string): Promise<{ location: string, saml_session_id: string } | undefined> {
|
|
171
175
|
try {
|
|
172
176
|
return await getApiClient().auth.initiateIdpAuthentication(domain, redirectUrl);
|
|
@@ -218,20 +222,26 @@ export class Auth {
|
|
|
218
222
|
return getApiClient().auth.refreshToken(refreshToken, '', this.expiration);
|
|
219
223
|
}
|
|
220
224
|
|
|
221
|
-
async logout(deleteRefreshToken = true): Promise<void> {
|
|
225
|
+
async logout(deleteRefreshToken = true, saml = false): Promise<void | { location: string }> {
|
|
222
226
|
try {
|
|
223
227
|
Wazo.Websocket.close(true);
|
|
224
228
|
|
|
225
|
-
if (this.clientId && deleteRefreshToken) {
|
|
229
|
+
if (!saml && this.clientId && deleteRefreshToken) {
|
|
226
230
|
await getApiClient().auth.deleteRefreshToken(this.clientId);
|
|
227
231
|
}
|
|
228
232
|
} catch (e: any) {
|
|
229
233
|
// Nothing to
|
|
230
234
|
}
|
|
231
235
|
|
|
236
|
+
let response;
|
|
237
|
+
|
|
232
238
|
try {
|
|
233
239
|
if (this.session?.token) {
|
|
234
|
-
|
|
240
|
+
if (saml) {
|
|
241
|
+
response = await getApiClient().auth.samlLogOut();
|
|
242
|
+
} else {
|
|
243
|
+
await getApiClient().auth.logOut(this.session.token);
|
|
244
|
+
}
|
|
235
245
|
}
|
|
236
246
|
} catch (e: any) {
|
|
237
247
|
// Nothing to
|
|
@@ -243,6 +253,8 @@ export class Auth {
|
|
|
243
253
|
this.authenticated = false;
|
|
244
254
|
this.usingEdgeServer = undefined;
|
|
245
255
|
setFetchOptions({});
|
|
256
|
+
|
|
257
|
+
return response;
|
|
246
258
|
}
|
|
247
259
|
|
|
248
260
|
setOnHostFromHeaders(callback: (hostFromHeaders: string) => void) {
|
package/src/simple/Phone.ts
CHANGED
|
@@ -6,13 +6,13 @@ import type CallSession from '../domain/CallSession';
|
|
|
6
6
|
import AdHocAPIConference from '../domain/AdHocAPIConference';
|
|
7
7
|
import WebRTCPhone, * as PHONE_EVENTS from '../domain/Phone/WebRTCPhone';
|
|
8
8
|
import { MESSAGE_TYPE_CHAT, MESSAGE_TYPE_SIGNAL } from '../domain/Phone/WebRTCPhone';
|
|
9
|
-
import
|
|
9
|
+
import WebRTCClient, { events as clientEvents, transportEvents } from '../web-rtc-client';
|
|
10
10
|
import IssueReporter from '../service/IssueReporter';
|
|
11
11
|
import Emitter from '../utils/Emitter';
|
|
12
12
|
import Wazo from './index';
|
|
13
13
|
import SFUNotAvailableError from '../domain/SFUNotAvailableError';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
14
|
+
import { SipCall, WebRtcConfig } from '../domain/types';
|
|
15
|
+
import { getSipCallId } from '../utils/sdp';
|
|
16
16
|
|
|
17
17
|
const logger = IssueReporter.loggerFor('simple-phone');
|
|
18
18
|
const sipLogger = IssueReporter.loggerFor('sip.js');
|
|
@@ -21,7 +21,7 @@ const protocolDebugMessages = ['Received WebSocket text message:', 'Sending WebS
|
|
|
21
21
|
|
|
22
22
|
// @deprecated: Use Wazo.Voice.Softphone instead
|
|
23
23
|
export class Phone extends Emitter {
|
|
24
|
-
client:
|
|
24
|
+
client: WebRTCClient;
|
|
25
25
|
|
|
26
26
|
phone: WebRTCPhone | null | undefined;
|
|
27
27
|
|
|
@@ -188,7 +188,7 @@ export class Phone extends Emitter {
|
|
|
188
188
|
options.log.connector = this._logConnector;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
this.client = new
|
|
191
|
+
this.client = new WebRTCClient({
|
|
192
192
|
host,
|
|
193
193
|
port: typeof port === 'string' ? parseInt(port, 10) : port,
|
|
194
194
|
displayName,
|
|
@@ -330,14 +330,14 @@ export class Phone extends Emitter {
|
|
|
330
330
|
return this.phone ? this.phone.stopNetworkMonitoring(callSession) : null;
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
-
|
|
333
|
+
getSipCallId(sipSession: SipCall): string | null | undefined {
|
|
334
334
|
if (!sipSession || !this.phone) {
|
|
335
335
|
return null;
|
|
336
336
|
}
|
|
337
|
-
return
|
|
337
|
+
return getSipCallId(sipSession);
|
|
338
338
|
}
|
|
339
339
|
|
|
340
|
-
sendMessage(body: string, sipSession?:
|
|
340
|
+
sendMessage(body: string, sipSession?: SipCall, contentType = 'text/plain'): void {
|
|
341
341
|
const toSipSession = sipSession || this.getCurrentSipSession();
|
|
342
342
|
|
|
343
343
|
if (!toSipSession || !this.phone) {
|
|
@@ -347,14 +347,14 @@ export class Phone extends Emitter {
|
|
|
347
347
|
this.phone.sendMessage(toSipSession, body, contentType);
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
-
sendChat(content: string, sipSession?:
|
|
350
|
+
sendChat(content: string, sipSession?: SipCall): void {
|
|
351
351
|
this.sendMessage(JSON.stringify({
|
|
352
352
|
type: MESSAGE_TYPE_CHAT,
|
|
353
353
|
content,
|
|
354
354
|
}), sipSession, 'application/json');
|
|
355
355
|
}
|
|
356
356
|
|
|
357
|
-
sendSignal(content: any, sipSession?:
|
|
357
|
+
sendSignal(content: any, sipSession?: SipCall): void {
|
|
358
358
|
this.sendMessage(JSON.stringify({
|
|
359
359
|
type: MESSAGE_TYPE_SIGNAL,
|
|
360
360
|
content,
|
|
@@ -447,7 +447,7 @@ export class Phone extends Emitter {
|
|
|
447
447
|
return this.phone ? this.phone.hasAVideoTrack(callSession) : false;
|
|
448
448
|
}
|
|
449
449
|
|
|
450
|
-
getCurrentSipSession():
|
|
450
|
+
getCurrentSipSession(): SipCall | null {
|
|
451
451
|
return this.phone?.currentSipSession || null;
|
|
452
452
|
}
|
|
453
453
|
|
package/src/simple/index.ts
CHANGED
|
@@ -41,7 +41,7 @@ import Features from '../domain/Features';
|
|
|
41
41
|
import Meeting from '../domain/Meeting';
|
|
42
42
|
import Checker from '../checker/Checker';
|
|
43
43
|
|
|
44
|
-
import Softphone from '../voice/softphone';
|
|
44
|
+
import Softphone, { Softphone as SoftphoneClass } from '../voice/softphone';
|
|
45
45
|
import Call from '../voice/call';
|
|
46
46
|
|
|
47
47
|
const Wazo = {
|
|
@@ -91,6 +91,7 @@ const Wazo = {
|
|
|
91
91
|
SwitchboardCall,
|
|
92
92
|
WebRTCPhone,
|
|
93
93
|
Meeting,
|
|
94
|
+
SoftphoneClass,
|
|
94
95
|
},
|
|
95
96
|
|
|
96
97
|
// Api
|
package/src/simple/room/Room.ts
CHANGED
|
@@ -9,8 +9,8 @@ import Participant, { RawParticipant } from './Participant';
|
|
|
9
9
|
import RemoteParticipant from './RemoteParticipant';
|
|
10
10
|
import IssueReporter from '../../service/IssueReporter';
|
|
11
11
|
import LocalParticipant from './LocalParticipant';
|
|
12
|
-
import { PeerConnection,
|
|
13
|
-
import {
|
|
12
|
+
import { PeerConnection, SipCall } from '../../domain/types';
|
|
13
|
+
import { getSipCallId } from '../../utils/sdp';
|
|
14
14
|
|
|
15
15
|
export const SIGNAL_TYPE_PARTICIPANT_UPDATE = 'signal/PARTICIPANT_UPDATE';
|
|
16
16
|
export const SIGNAL_TYPE_PARTICIPANT_REQUEST = 'signal/PARTICIPANT_REQUEST';
|
|
@@ -498,7 +498,7 @@ class Room extends Emitter {
|
|
|
498
498
|
this.audioStream = stream;
|
|
499
499
|
|
|
500
500
|
if (!this.roomAudioElement) {
|
|
501
|
-
const sessionId =
|
|
501
|
+
const sessionId = getSipCallId(Wazo.Phone.phone?.currentSipSession as SipCall);
|
|
502
502
|
this.roomAudioElement = await Wazo.Phone.phone?.createAudioElementFor(sessionId as string) as HTMLAudioElement;
|
|
503
503
|
this.roomAudioElement.srcObject = stream;
|
|
504
504
|
} else {
|
|
@@ -3,8 +3,8 @@ import CallSession from '../../domain/CallSession';
|
|
|
3
3
|
import IssueReporter from '../../service/IssueReporter';
|
|
4
4
|
import Wazo from '../index';
|
|
5
5
|
import Room from './Room';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { SipCall } from '../../domain/types';
|
|
7
|
+
import { getSipCallId } from '../../utils/sdp';
|
|
8
8
|
|
|
9
9
|
const logger = IssueReporter.loggerFor('sdk-sip-room');
|
|
10
10
|
|
|
@@ -157,7 +157,7 @@ class SipRoom extends Room {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
_getCurrentSipCallIs() {
|
|
160
|
-
return
|
|
160
|
+
return getSipCallId(Wazo.Phone.phone?.currentSipSession as SipCall);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
}
|
|
@@ -15,11 +15,19 @@ export const EstablishedStates = {
|
|
|
15
15
|
ONGOING: 'ongoing',
|
|
16
16
|
HELD: 'held',
|
|
17
17
|
MUTED: 'muted',
|
|
18
|
+
UN_MUTED: 'unMuted',
|
|
19
|
+
UN_HELD: 'unHeld',
|
|
20
|
+
} as const;
|
|
21
|
+
|
|
22
|
+
export const EstablishedSubStates = {
|
|
23
|
+
MUTE: 'muteState',
|
|
24
|
+
HOLD: 'holdState',
|
|
18
25
|
} as const;
|
|
19
26
|
|
|
20
27
|
export type StateTypes = typeof States[keyof typeof States];
|
|
21
28
|
|
|
22
29
|
export type EstablishedStateTypes = typeof EstablishedStates[keyof typeof EstablishedStates];
|
|
30
|
+
export type EstablishedSubStateTypes = typeof EstablishedSubStates[keyof typeof EstablishedSubStates];
|
|
23
31
|
|
|
24
32
|
export const Actions = {
|
|
25
33
|
INCOMING_CALL: 'incomingCall',
|
|
@@ -53,7 +61,7 @@ const callMachine = setup({
|
|
|
53
61
|
[States.IDLE]: {
|
|
54
62
|
on: {
|
|
55
63
|
[Actions.INCOMING_CALL]: {
|
|
56
|
-
|
|
64
|
+
guard: 'isRegistered',
|
|
57
65
|
target: States.RINGING,
|
|
58
66
|
},
|
|
59
67
|
[Actions.MAKE_CALL]: {
|
|
@@ -88,35 +96,46 @@ const callMachine = setup({
|
|
|
88
96
|
},
|
|
89
97
|
[States.ESTABLISHED]: {
|
|
90
98
|
initial: EstablishedStates.ONGOING,
|
|
99
|
+
type: 'parallel',
|
|
91
100
|
on: {
|
|
92
101
|
[Actions.HANGUP]: {
|
|
93
102
|
guard: 'isRegistered',
|
|
94
103
|
target: States.TERMINATED,
|
|
95
104
|
},
|
|
96
|
-
[EstablishedActions.HOLD]: {
|
|
97
|
-
guard: 'isRegistered',
|
|
98
|
-
target: `.${EstablishedStates.HELD}`,
|
|
99
|
-
},
|
|
100
|
-
[EstablishedActions.MUTE]: {
|
|
101
|
-
guard: 'isRegistered',
|
|
102
|
-
target: `.${EstablishedStates.MUTED}`,
|
|
103
|
-
},
|
|
104
105
|
},
|
|
105
106
|
states: {
|
|
106
107
|
[EstablishedStates.ONGOING]: { },
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
|
|
109
|
+
// Mute / Unmute
|
|
110
|
+
[EstablishedSubStates.MUTE]: {
|
|
111
|
+
initial: EstablishedStates.UN_MUTED,
|
|
112
|
+
states: {
|
|
113
|
+
[EstablishedStates.MUTED]: {
|
|
114
|
+
on: {
|
|
115
|
+
unMute: EstablishedStates.UN_MUTED,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
[EstablishedStates.UN_MUTED]: {
|
|
119
|
+
on: {
|
|
120
|
+
mute: EstablishedStates.MUTED,
|
|
121
|
+
},
|
|
112
122
|
},
|
|
113
123
|
},
|
|
114
124
|
},
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
125
|
+
|
|
126
|
+
// Hold / Resume
|
|
127
|
+
[EstablishedSubStates.HOLD]: {
|
|
128
|
+
initial: EstablishedStates.UN_HELD,
|
|
129
|
+
states: {
|
|
130
|
+
[EstablishedStates.HELD]: {
|
|
131
|
+
on: {
|
|
132
|
+
[EstablishedActions.RESUME]: EstablishedStates.UN_HELD,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
[EstablishedStates.UN_HELD]: {
|
|
136
|
+
on: {
|
|
137
|
+
[EstablishedActions.HOLD]: EstablishedStates.HELD,
|
|
138
|
+
},
|
|
120
139
|
},
|
|
121
140
|
},
|
|
122
141
|
},
|
|
@@ -12,7 +12,6 @@ export const Actions = {
|
|
|
12
12
|
REGISTER: 'register',
|
|
13
13
|
REGISTER_DONE: 'registerDone',
|
|
14
14
|
UNREGISTER: 'unregister',
|
|
15
|
-
UNREGISTERED: 'unregistered',
|
|
16
15
|
TRANSPORT_CLOSED: 'transportClosed',
|
|
17
16
|
} as const;
|
|
18
17
|
|
|
@@ -32,7 +31,7 @@ const softphoneMachine = setup({}).createMachine({
|
|
|
32
31
|
on: {
|
|
33
32
|
[Actions.REGISTER_DONE]: States.REGISTERED,
|
|
34
33
|
[Actions.TRANSPORT_CLOSED]: States.UNREGISTERED,
|
|
35
|
-
[Actions.
|
|
34
|
+
[Actions.UNREGISTER]: States.UNREGISTERED,
|
|
36
35
|
},
|
|
37
36
|
},
|
|
38
37
|
[States.REGISTERED]: {
|
|
@@ -16,8 +16,15 @@ export const can = (actor: SoftphoneActorRef | CallActorRef, action: SoftphoneAc
|
|
|
16
16
|
return actor.getSnapshot().can({ type: action });
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
export const hasState = (actor: SoftphoneActorRef | CallActorRef, state: SoftphoneStates | CallStates): boolean => {
|
|
20
|
-
|
|
19
|
+
export const hasState = (actor: SoftphoneActorRef | CallActorRef, state: SoftphoneStates | CallStates, innerState?: EstablishedStateTypes): boolean => {
|
|
20
|
+
const currentState = getState(actor);
|
|
21
|
+
|
|
22
|
+
// When using nested states, we'll have an object here
|
|
23
|
+
if (typeof currentState === 'object') {
|
|
24
|
+
return innerState ? state in currentState && currentState[state as CallStates] === innerState : state in currentState;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return currentState === state;
|
|
21
28
|
};
|
|
22
29
|
|
|
23
30
|
export const waitUntilState = (actor: SoftphoneActorRef | CallActorRef, state: SoftphoneStates | CallStates, timeout = 5000): Promise<unknown> => {
|
|
@@ -36,7 +43,8 @@ export const waitUntilState = (actor: SoftphoneActorRef | CallActorRef, state: S
|
|
|
36
43
|
export const assertCan = (actor: SoftphoneActorRef | CallActorRef, action: SoftphoneActions | CallActions | EstablishedCallActions): void => {
|
|
37
44
|
if (!can(actor, action)) {
|
|
38
45
|
const currentState = actor.getSnapshot().value;
|
|
39
|
-
const
|
|
46
|
+
const currentStateString = typeof currentState === 'object' ? JSON.stringify(currentState) : currentState;
|
|
47
|
+
const message = `Invalid state transition from ${currentStateString} with action ${action}`;
|
|
40
48
|
logger.warn(message);
|
|
41
49
|
|
|
42
50
|
throw new InvalidStateTransition(message, action, currentState as string);
|
|
@@ -45,7 +53,7 @@ export const assertCan = (actor: SoftphoneActorRef | CallActorRef, action: Softp
|
|
|
45
53
|
|
|
46
54
|
export const assertState = (actor: SoftphoneActorRef | CallActorRef, state: SoftphoneStates | CallStates): void => {
|
|
47
55
|
if (!hasState(actor, state)) {
|
|
48
|
-
const message = `Invalid state ${state}`;
|
|
56
|
+
const message = `Invalid state ${state}, has state ${getState(actor)}`;
|
|
49
57
|
logger.warn(message);
|
|
50
58
|
|
|
51
59
|
throw new InvalidState(message, state);
|
package/src/utils/sdp.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/* eslint-disable no-underscore-dangle */
|
|
2
2
|
import sdpParser from 'sdp-transform';
|
|
3
3
|
import { UserAgent } from 'sip.js/lib/api/user-agent';
|
|
4
|
-
import { Inviter } from 'sip.js/lib/api';
|
|
4
|
+
import { Inviter, Invitation } from 'sip.js/lib/api';
|
|
5
|
+
import { SessionDialog } from 'sip.js/lib/core/dialogs/session-dialog';
|
|
5
6
|
import { URI } from 'sip.js/lib/grammar/uri';
|
|
6
7
|
|
|
7
8
|
import type { SipCall } from '../domain/types';
|
|
8
9
|
|
|
9
|
-
export const SIP_ID_LENGTH = 36;
|
|
10
|
-
|
|
11
10
|
export type Candidate = {
|
|
12
11
|
foundation: string;
|
|
13
12
|
component: number;
|
|
@@ -147,25 +146,33 @@ export const addIcesInAllBundles = (sdp: string) => {
|
|
|
147
146
|
return sdpParser.write(parsedSdp);
|
|
148
147
|
};
|
|
149
148
|
|
|
150
|
-
export const
|
|
149
|
+
export const getSipCallId = (sipSession: SipCall | null | undefined): string => {
|
|
151
150
|
if (!sipSession) {
|
|
152
151
|
return '';
|
|
153
152
|
}
|
|
154
153
|
|
|
155
|
-
const message = sipSession.message as Partial<{ callId?: string }>;
|
|
156
|
-
if (message?.callId) {
|
|
157
|
-
return message.callId.substring(0, SIP_ID_LENGTH);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
154
|
// For Inviter
|
|
161
155
|
// @ts-ignore: private
|
|
162
156
|
if (sipSession instanceof Inviter && sipSession.outgoingRequestMessage) {
|
|
163
157
|
// @ts-ignore: private
|
|
164
|
-
return sipSession.outgoingRequestMessage.callId
|
|
158
|
+
return sipSession.outgoingRequestMessage.callId;
|
|
165
159
|
}
|
|
166
160
|
|
|
167
161
|
// For Invitation
|
|
168
|
-
|
|
162
|
+
// @ts-ignore: private
|
|
163
|
+
if (sipSession instanceof Invitation && sipSession.incomingInviteRequest.message) {
|
|
164
|
+
// @ts-ignore: private
|
|
165
|
+
return sipSession.incomingInviteRequest.message.callId;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// For EarlyMedia
|
|
169
|
+
// @ts-ignore: private
|
|
170
|
+
if (sipSession instanceof SessionDialog) {
|
|
171
|
+
// @ts-ignore: private
|
|
172
|
+
return sipSession.dialogState.callId;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return sipSession.id;
|
|
169
176
|
};
|
|
170
177
|
|
|
171
178
|
// We need to replace 0.0.0.0 to 127.0.0.1 in the sdp to avoid MOH during a createOffer.
|
package/src/utils/update-from.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-param-reassign */
|
|
2
|
-
export default ((instance: any, from: any) => {
|
|
3
|
-
Object.keys(from)
|
|
2
|
+
export default ((instance: any, from: any, attributes: string[] | null = null) => {
|
|
3
|
+
(attributes || Object.keys(from))
|
|
4
4
|
.forEach(key => {
|
|
5
5
|
if ((!instance[key] && from[key])
|
|
6
6
|
|| (typeof instance[key] !== 'undefined' && typeof from[key] !== 'undefined' && instance[key] !== from[key])
|
package/src/utils/webrtc.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { stripVideo } from 'sip.js/lib/platform/web';
|
|
|
7
7
|
|
|
8
8
|
import WazoSessionDescriptionHandler, { wazoMediaStreamFactory } from '../lib/WazoSessionDescriptionHandler';
|
|
9
9
|
import { SipCall, PeerConnection, UserAgentOptions, WebRtcConfig, UserAgentConfigOverrides } from '../domain/types';
|
|
10
|
-
import { getVideoDirection, hasAnActiveVideo, makeURI, replaceLocalIpModifier } from './sdp';
|
|
10
|
+
import { getSipCallId, getVideoDirection, hasAnActiveVideo, makeURI, replaceLocalIpModifier } from './sdp';
|
|
11
11
|
import IssueReporter from '../service/IssueReporter';
|
|
12
12
|
import { lastIndexOf } from './array';
|
|
13
13
|
|
|
@@ -187,6 +187,10 @@ export const sessionWantsToDoVideo = (sipCall: SipCall): boolean => {
|
|
|
187
187
|
} = sipCall.request || sipCall;
|
|
188
188
|
// Sometimes with InviteClientContext the body is in the body attribute ...
|
|
189
189
|
const sdp = typeof body === 'object' && body ? body.body : body;
|
|
190
|
+
if (!sdp) {
|
|
191
|
+
return (sipCall.sessionDescriptionHandler as any)?.localMediaStreamConstraints?.video;
|
|
192
|
+
}
|
|
193
|
+
|
|
190
194
|
return hasAnActiveVideo(sdp);
|
|
191
195
|
};
|
|
192
196
|
|
|
@@ -249,6 +253,9 @@ export const toggleVideo = (sipCall: SipCall, muteCamera: boolean): void => {
|
|
|
249
253
|
export const isVideoMuted = (sipCall: SipCall): boolean => {
|
|
250
254
|
const sdh = sipCall.sessionDescriptionHandler as SessionDescriptionHandler;
|
|
251
255
|
const pc = sdh?.peerConnection as PeerConnection;
|
|
256
|
+
if (!pc) {
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
252
259
|
|
|
253
260
|
if (pc?.getSenders) {
|
|
254
261
|
for (const sender of pc.getSenders()) {
|
|
@@ -274,7 +281,7 @@ export const cleanupStream = (stream: MediaStream): void => {
|
|
|
274
281
|
|
|
275
282
|
export const setLocalMediaStream = (sipCall: SipCall, newStream: MediaStream): void => {
|
|
276
283
|
logger.info('setting local media stream', {
|
|
277
|
-
id: sipCall
|
|
284
|
+
id: getSipCallId(sipCall),
|
|
278
285
|
tracks: newStream ? newStream.getTracks() : null,
|
|
279
286
|
});
|
|
280
287
|
|
|
@@ -290,7 +297,7 @@ export const updateRemoteStream = (sipCall: SipCall, allTracks = true): void =>
|
|
|
290
297
|
const pc = getPeerConnection(sipCall);
|
|
291
298
|
|
|
292
299
|
logger.info('Updating remote stream', {
|
|
293
|
-
id: sipCall
|
|
300
|
+
id: getSipCallId(sipCall),
|
|
294
301
|
tracks: remoteStream ? remoteStream.getTracks() : null,
|
|
295
302
|
receiverTracks: pc && pc.getReceivers ? pc.getReceivers().map((receiver) => receiver.track) : null,
|
|
296
303
|
});
|
|
@@ -327,7 +334,7 @@ export const getVideoConstraints = (video: Constraint = false): MediaTrackConstr
|
|
|
327
334
|
}
|
|
328
335
|
|
|
329
336
|
// @ts-ignore: media constraints
|
|
330
|
-
return
|
|
337
|
+
return video?.deviceId?.exact ? video : true;
|
|
331
338
|
};
|
|
332
339
|
|
|
333
340
|
// eslint-disable-next-line no-unused-vars
|