@wazo/sdk 1.0.0-alpha.1 → 1.0.0-alpha.10
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 +6 -6
- package/esm/__tests__/__voice__/call.test.js +57 -2
- 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 +64 -63
- 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 +6 -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 +2 -2
- package/esm/state-machine/softphone-state-machine.js +1 -2
- package/esm/state-machine/utils.js +8 -3
- 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/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 +2 -2
- package/esm/types/state-machine/utils.d.ts.map +1 -1
- package/esm/types/utils/sdp.d.ts +3 -2
- package/esm/types/utils/sdp.d.ts.map +1 -1
- package/esm/types/utils/webrtc.d.ts +1 -0
- package/esm/types/utils/webrtc.d.ts.map +1 -1
- package/esm/types/voice/call.d.ts +30 -12
- package/esm/types/voice/call.d.ts.map +1 -1
- package/esm/types/voice/softphone.d.ts +25 -13
- 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 +22 -9
- package/esm/utils/webrtc.js +23 -3
- package/esm/voice/call.js +130 -38
- package/esm/voice/softphone.js +145 -35
- package/esm/web-rtc-client.js +61 -58
- package/lib/__tests__/__voice__/call.test.js +56 -1
- 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 +63 -62
- 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 +3 -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 +2 -2
- package/lib/state-machine/softphone-state-machine.js +1 -2
- package/lib/state-machine/utils.js +8 -3
- 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/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 +2 -2
- package/lib/types/state-machine/utils.d.ts.map +1 -1
- package/lib/types/utils/sdp.d.ts +3 -2
- package/lib/types/utils/sdp.d.ts.map +1 -1
- package/lib/types/utils/webrtc.d.ts +1 -0
- package/lib/types/utils/webrtc.d.ts.map +1 -1
- package/lib/types/voice/call.d.ts +30 -12
- package/lib/types/voice/call.d.ts.map +1 -1
- package/lib/types/voice/softphone.d.ts +25 -13
- 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 +25 -10
- package/lib/utils/webrtc.js +24 -3
- package/lib/voice/call.js +131 -36
- package/lib/voice/softphone.js +150 -35
- package/lib/web-rtc-client.js +59 -57
- package/package.json +1 -1
- package/src/__tests__/__voice__/call.test.ts +63 -2
- 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 +95 -93
- 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 +12 -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 +2 -2
- package/src/state-machine/softphone-state-machine.ts +1 -2
- package/src/state-machine/utils.ts +12 -5
- package/src/utils/sdp.ts +26 -11
- package/src/utils/webrtc.ts +26 -4
- package/src/voice/call.ts +169 -50
- package/src/voice/softphone.ts +180 -41
- package/src/web-rtc-client.ts +106 -99
package/src/domain/types.ts
CHANGED
|
@@ -264,11 +264,6 @@ export type PeerConnection = RTCPeerConnection & {
|
|
|
264
264
|
addStream: (stream: MediaStream) => void;
|
|
265
265
|
sfu: any;
|
|
266
266
|
};
|
|
267
|
-
// @TODO, rename it to SipCall
|
|
268
|
-
export type WazoSession = (Invitation | Inviter) & {
|
|
269
|
-
remoteTag?: any;
|
|
270
|
-
callId?: string;
|
|
271
|
-
};
|
|
272
267
|
|
|
273
268
|
export type SipCall = (Invitation | Inviter) & {
|
|
274
269
|
remoteTag?: any;
|
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,21 +6,22 @@ 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');
|
|
19
19
|
const protocolLogger = IssueReporter.loggerFor('sip');
|
|
20
20
|
const protocolDebugMessages = ['Received WebSocket text message:', 'Sending WebSocket message:'];
|
|
21
21
|
|
|
22
|
+
// @deprecated: Use Wazo.Voice.Softphone instead
|
|
22
23
|
export class Phone extends Emitter {
|
|
23
|
-
client:
|
|
24
|
+
client: WebRTCClient;
|
|
24
25
|
|
|
25
26
|
phone: WebRTCPhone | null | undefined;
|
|
26
27
|
|
|
@@ -187,7 +188,7 @@ export class Phone extends Emitter {
|
|
|
187
188
|
options.log.connector = this._logConnector;
|
|
188
189
|
}
|
|
189
190
|
|
|
190
|
-
this.client = new
|
|
191
|
+
this.client = new WebRTCClient({
|
|
191
192
|
host,
|
|
192
193
|
port: typeof port === 'string' ? parseInt(port, 10) : port,
|
|
193
194
|
displayName,
|
|
@@ -329,14 +330,14 @@ export class Phone extends Emitter {
|
|
|
329
330
|
return this.phone ? this.phone.stopNetworkMonitoring(callSession) : null;
|
|
330
331
|
}
|
|
331
332
|
|
|
332
|
-
|
|
333
|
+
getSipCallId(sipSession: SipCall): string | null | undefined {
|
|
333
334
|
if (!sipSession || !this.phone) {
|
|
334
335
|
return null;
|
|
335
336
|
}
|
|
336
|
-
return
|
|
337
|
+
return getSipCallId(sipSession);
|
|
337
338
|
}
|
|
338
339
|
|
|
339
|
-
sendMessage(body: string, sipSession?:
|
|
340
|
+
sendMessage(body: string, sipSession?: SipCall, contentType = 'text/plain'): void {
|
|
340
341
|
const toSipSession = sipSession || this.getCurrentSipSession();
|
|
341
342
|
|
|
342
343
|
if (!toSipSession || !this.phone) {
|
|
@@ -346,14 +347,14 @@ export class Phone extends Emitter {
|
|
|
346
347
|
this.phone.sendMessage(toSipSession, body, contentType);
|
|
347
348
|
}
|
|
348
349
|
|
|
349
|
-
sendChat(content: string, sipSession?:
|
|
350
|
+
sendChat(content: string, sipSession?: SipCall): void {
|
|
350
351
|
this.sendMessage(JSON.stringify({
|
|
351
352
|
type: MESSAGE_TYPE_CHAT,
|
|
352
353
|
content,
|
|
353
354
|
}), sipSession, 'application/json');
|
|
354
355
|
}
|
|
355
356
|
|
|
356
|
-
sendSignal(content: any, sipSession?:
|
|
357
|
+
sendSignal(content: any, sipSession?: SipCall): void {
|
|
357
358
|
this.sendMessage(JSON.stringify({
|
|
358
359
|
type: MESSAGE_TYPE_SIGNAL,
|
|
359
360
|
content,
|
|
@@ -446,7 +447,7 @@ export class Phone extends Emitter {
|
|
|
446
447
|
return this.phone ? this.phone.hasAVideoTrack(callSession) : false;
|
|
447
448
|
}
|
|
448
449
|
|
|
449
|
-
getCurrentSipSession():
|
|
450
|
+
getCurrentSipSession(): SipCall | null {
|
|
450
451
|
return this.phone?.currentSipSession || null;
|
|
451
452
|
}
|
|
452
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
|
}
|
|
@@ -43,7 +43,7 @@ export type EstablishedActionTypes = typeof EstablishedActions[keyof typeof Esta
|
|
|
43
43
|
|
|
44
44
|
const callMachine = setup({
|
|
45
45
|
guards: {
|
|
46
|
-
isRegistered: () => softphone.
|
|
46
|
+
isRegistered: () => softphone.state === SoftphoneStates.REGISTERED,
|
|
47
47
|
},
|
|
48
48
|
}).createMachine({
|
|
49
49
|
id: 'call',
|
|
@@ -53,7 +53,7 @@ const callMachine = setup({
|
|
|
53
53
|
[States.IDLE]: {
|
|
54
54
|
on: {
|
|
55
55
|
[Actions.INCOMING_CALL]: {
|
|
56
|
-
|
|
56
|
+
guard: 'isRegistered',
|
|
57
57
|
target: States.RINGING,
|
|
58
58
|
},
|
|
59
59
|
[Actions.MAKE_CALL]: {
|
|
@@ -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]: {
|
|
@@ -8,16 +8,23 @@ import IssueReporter from '../service/IssueReporter';
|
|
|
8
8
|
|
|
9
9
|
const logger = IssueReporter.loggerFor('state-machine');
|
|
10
10
|
|
|
11
|
-
export const getState = (actor: SoftphoneActorRef | CallActorRef): SoftphoneStates | CallStates | EstablishedStateTypes => {
|
|
12
|
-
return actor.getSnapshot().value as SoftphoneStates | CallStates | EstablishedStateTypes
|
|
11
|
+
export const getState = (actor: SoftphoneActorRef | CallActorRef): SoftphoneStates | CallStates | EstablishedStateTypes | Record<CallStates, EstablishedStateTypes> => {
|
|
12
|
+
return actor.getSnapshot().value as SoftphoneStates | CallStates | EstablishedStateTypes | Record<CallStates, EstablishedStateTypes>;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export const can = (actor: SoftphoneActorRef | CallActorRef, action: SoftphoneActions | CallActions | EstablishedCallActions): boolean => {
|
|
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> => {
|
|
@@ -45,7 +52,7 @@ export const assertCan = (actor: SoftphoneActorRef | CallActorRef, action: Softp
|
|
|
45
52
|
|
|
46
53
|
export const assertState = (actor: SoftphoneActorRef | CallActorRef, state: SoftphoneStates | CallStates): void => {
|
|
47
54
|
if (!hasState(actor, state)) {
|
|
48
|
-
const message = `Invalid state ${state}`;
|
|
55
|
+
const message = `Invalid state ${state}, has state ${getState(actor)}`;
|
|
49
56
|
logger.warn(message);
|
|
50
57
|
|
|
51
58
|
throw new InvalidState(message, state);
|
package/src/utils/sdp.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
/* eslint-disable no-underscore-dangle */
|
|
1
2
|
import sdpParser from 'sdp-transform';
|
|
2
3
|
import { UserAgent } from 'sip.js/lib/api/user-agent';
|
|
3
|
-
import { Inviter } from 'sip.js/lib/api';
|
|
4
|
+
import { Inviter, Invitation } from 'sip.js/lib/api';
|
|
4
5
|
import { URI } from 'sip.js/lib/grammar/uri';
|
|
5
6
|
|
|
6
7
|
import type { SipCall } from '../domain/types';
|
|
7
8
|
|
|
8
|
-
export const SIP_ID_LENGTH = 36;
|
|
9
|
-
|
|
10
9
|
export type Candidate = {
|
|
11
10
|
foundation: string;
|
|
12
11
|
component: number;
|
|
@@ -146,25 +145,26 @@ export const addIcesInAllBundles = (sdp: string) => {
|
|
|
146
145
|
return sdpParser.write(parsedSdp);
|
|
147
146
|
};
|
|
148
147
|
|
|
149
|
-
export const
|
|
148
|
+
export const getSipCallId = (sipSession: SipCall | null | undefined): string => {
|
|
150
149
|
if (!sipSession) {
|
|
151
150
|
return '';
|
|
152
151
|
}
|
|
153
152
|
|
|
154
|
-
const message = sipSession.message as Partial<{ callId?: string }>;
|
|
155
|
-
if (message?.callId) {
|
|
156
|
-
return message.callId.substring(0, SIP_ID_LENGTH);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
153
|
// For Inviter
|
|
160
154
|
// @ts-ignore: private
|
|
161
155
|
if (sipSession instanceof Inviter && sipSession.outgoingRequestMessage) {
|
|
162
156
|
// @ts-ignore: private
|
|
163
|
-
return sipSession.outgoingRequestMessage.callId
|
|
157
|
+
return sipSession.outgoingRequestMessage.callId;
|
|
164
158
|
}
|
|
165
159
|
|
|
166
160
|
// For Invitation
|
|
167
|
-
|
|
161
|
+
// @ts-ignore: private
|
|
162
|
+
if (sipSession instanceof Invitation && sipSession.incomingInviteRequest.message) {
|
|
163
|
+
// @ts-ignore: private
|
|
164
|
+
return sipSession.incomingInviteRequest.message.callId;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return sipSession.id;
|
|
168
168
|
};
|
|
169
169
|
|
|
170
170
|
// We need to replace 0.0.0.0 to 127.0.0.1 in the sdp to avoid MOH during a createOffer.
|
|
@@ -174,3 +174,18 @@ export const replaceLocalIpModifier = (description: Record<string, any>) => Prom
|
|
|
174
174
|
});
|
|
175
175
|
|
|
176
176
|
export const makeURI = (target: string, host: string): URI | undefined => UserAgent.makeURI(`sip:${target}@${host}`);
|
|
177
|
+
|
|
178
|
+
export const getCallNumber = (sipCall: SipCall): string => {
|
|
179
|
+
// eslint-disable-next-line
|
|
180
|
+
const identity = sipCall ? sipCall.remoteIdentity || sipCall.assertedIdentity : null;
|
|
181
|
+
// @ts-ignore: private
|
|
182
|
+
return identity ? identity.uri._normal.user : null;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export const getCallDisplayName = (sipCall: SipCall): string => {
|
|
186
|
+
// eslint-disable-next-line
|
|
187
|
+
const identity = sipCall ? sipCall.remoteIdentity || sipCall.assertedIdentity : null;
|
|
188
|
+
const number = getCallNumber(sipCall);
|
|
189
|
+
|
|
190
|
+
return identity ? identity.displayName || number : number;
|
|
191
|
+
};
|
package/src/utils/webrtc.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* eslint-disable no-underscore-dangle, no-param-reassign */
|
|
1
|
+
/* eslint-disable no-underscore-dangle, no-param-reassign, no-restricted-syntax */
|
|
2
2
|
import type { SessionDescriptionHandler } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler';
|
|
3
3
|
import type { SessionDescriptionHandlerFactoryOptions } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-factory-options';
|
|
4
4
|
import type { SessionDescriptionHandlerConfiguration } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-configuration';
|
|
@@ -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
|
|
|
@@ -246,13 +246,35 @@ export const toggleVideo = (sipCall: SipCall, muteCamera: boolean): void => {
|
|
|
246
246
|
}
|
|
247
247
|
};
|
|
248
248
|
|
|
249
|
+
export const isVideoMuted = (sipCall: SipCall): boolean => {
|
|
250
|
+
const sdh = sipCall.sessionDescriptionHandler as SessionDescriptionHandler;
|
|
251
|
+
const pc = sdh?.peerConnection as PeerConnection;
|
|
252
|
+
|
|
253
|
+
if (pc?.getSenders) {
|
|
254
|
+
for (const sender of pc.getSenders()) {
|
|
255
|
+
if (sender && sender.track && sender.track.kind === 'video') {
|
|
256
|
+
return !sender.track.enabled;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
260
|
+
for (const stream of pc.getLocalStreams()) {
|
|
261
|
+
// eslint-disable-next-line no-unreachable-loop
|
|
262
|
+
for (const track of stream.getVideoTracks()) {
|
|
263
|
+
return !track.enabled;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return true;
|
|
269
|
+
};
|
|
270
|
+
|
|
249
271
|
export const cleanupStream = (stream: MediaStream): void => {
|
|
250
272
|
stream.getTracks().filter(track => track.enabled).forEach(track => track.stop());
|
|
251
273
|
};
|
|
252
274
|
|
|
253
275
|
export const setLocalMediaStream = (sipCall: SipCall, newStream: MediaStream): void => {
|
|
254
276
|
logger.info('setting local media stream', {
|
|
255
|
-
id: sipCall
|
|
277
|
+
id: getSipCallId(sipCall),
|
|
256
278
|
tracks: newStream ? newStream.getTracks() : null,
|
|
257
279
|
});
|
|
258
280
|
|
|
@@ -268,7 +290,7 @@ export const updateRemoteStream = (sipCall: SipCall, allTracks = true): void =>
|
|
|
268
290
|
const pc = getPeerConnection(sipCall);
|
|
269
291
|
|
|
270
292
|
logger.info('Updating remote stream', {
|
|
271
|
-
id: sipCall
|
|
293
|
+
id: getSipCallId(sipCall),
|
|
272
294
|
tracks: remoteStream ? remoteStream.getTracks() : null,
|
|
273
295
|
receiverTracks: pc && pc.getReceivers ? pc.getReceivers().map((receiver) => receiver.track) : null,
|
|
274
296
|
});
|