@wazo/sdk 1.0.0-alpha.2 → 1.0.0-alpha.3

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.
Files changed (40) hide show
  1. package/dist/wazo-sdk.js +2 -2
  2. package/esm/__tests__/__voice__/call.test.js +1 -0
  3. package/esm/domain/Phone/CTIPhone.js +2 -2
  4. package/esm/index.js +1 -1
  5. package/esm/service/CallApi.js +4 -4
  6. package/esm/types/domain/Phone/CTIPhone.d.ts.map +1 -1
  7. package/esm/types/index.d.ts +1 -1
  8. package/esm/types/index.d.ts.map +1 -1
  9. package/esm/types/service/CallApi.d.ts +5 -5
  10. package/esm/types/service/CallApi.d.ts.map +1 -1
  11. package/esm/types/state-machine/softphone-state-machine.d.ts +1 -1
  12. package/esm/types/voice/call.d.ts +9 -2
  13. package/esm/types/voice/call.d.ts.map +1 -1
  14. package/esm/types/voice/softphone.d.ts +4 -0
  15. package/esm/types/voice/softphone.d.ts.map +1 -1
  16. package/esm/voice/call.js +28 -6
  17. package/esm/voice/softphone.js +11 -2
  18. package/lib/__tests__/__voice__/call.test.js +1 -0
  19. package/lib/domain/Phone/CTIPhone.js +2 -2
  20. package/lib/index.js +2 -2
  21. package/lib/service/CallApi.js +2 -2
  22. package/lib/types/domain/Phone/CTIPhone.d.ts.map +1 -1
  23. package/lib/types/index.d.ts +1 -1
  24. package/lib/types/index.d.ts.map +1 -1
  25. package/lib/types/service/CallApi.d.ts +5 -5
  26. package/lib/types/service/CallApi.d.ts.map +1 -1
  27. package/lib/types/state-machine/softphone-state-machine.d.ts +1 -1
  28. package/lib/types/voice/call.d.ts +9 -2
  29. package/lib/types/voice/call.d.ts.map +1 -1
  30. package/lib/types/voice/softphone.d.ts +4 -0
  31. package/lib/types/voice/softphone.d.ts.map +1 -1
  32. package/lib/voice/call.js +29 -7
  33. package/lib/voice/softphone.js +14 -2
  34. package/package.json +1 -1
  35. package/src/__tests__/__voice__/call.test.ts +1 -0
  36. package/src/domain/Phone/CTIPhone.ts +3 -2
  37. package/src/index.ts +1 -1
  38. package/src/service/CallApi.ts +7 -7
  39. package/src/voice/call.ts +36 -8
  40. package/src/voice/softphone.ts +15 -2
@@ -30,6 +30,7 @@ export type CallOptions = {
30
30
  withCamera?: boolean;
31
31
  audioOnly?: boolean;
32
32
  conference?: boolean;
33
+ extraHeaders?: Record<string, any>;
33
34
  };
34
35
  export declare class Softphone extends EventEmitter {
35
36
  audioOutputDeviceId?: string;
@@ -46,6 +47,7 @@ export declare class Softphone extends EventEmitter {
46
47
  ringingEnabled: boolean;
47
48
  constructor();
48
49
  connect(options?: Partial<WebRtcConfig>): Promise<void>;
50
+ hangupAllCalls(): Promise<boolean[]>;
49
51
  disconnect(): Promise<void | null>;
50
52
  getPrimaryWebRtcLine(): SipLine | null;
51
53
  connectWithCredentials(server: string, sipLine: SipLine, displayName: string, rawOptions?: Partial<WebRtcConfig>): Promise<void>;
@@ -67,8 +69,10 @@ export declare class Softphone extends EventEmitter {
67
69
  changeAudioVolume(volume: number): void;
68
70
  changeRingVolume(volume: number): void;
69
71
  getCurrentCall(): Call | undefined;
72
+ getActiveCalls(): Call[];
70
73
  getIncomingCalls(): Call[];
71
74
  get state(): StateTypes;
75
+ get user(): string | undefined;
72
76
  getUserAgent(): string;
73
77
  isRegistered(): boolean;
74
78
  _bindEvents(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"softphone.d.ts","sourceRoot":"","sources":["../../../src/voice/softphone.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"softphone.d.ts","sourceRoot":"","sources":["../../../src/voice/softphone.ts"],"names":[],"mappings":"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"}
package/lib/voice/call.js CHANGED
@@ -35,13 +35,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
35
35
  return (mod && mod.__esModule) ? mod : { "default": mod };
36
36
  };
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.MESSAGE_TRACK_UPDATED = exports.MESSAGE_TYPE_SIGNAL = exports.MESSAGE_TYPE_CHAT = exports.EVENT_CAMERA_DISABLED = exports.EVENT_CAMERA_RESUMED = exports.EVENT_WEB_RTC_STATS = exports.EVENT_SHARE_SCREEN_ENDED = exports.EVENT_SHARE_SCREEN_STARTED = exports.EVENT_SHARE_SCREEN_ENDING = exports.EVENT_REMOVE_STREAM = exports.EVENT_VIDEO_STREAM = exports.EVENT_AUDIO_STREAM = exports.EVENT_TRACK = exports.EVENT_REINVITE = exports.EVENT_CALL_RESUMED = exports.EVENT_CALL_HELD = exports.EVENT_CALL_UN_MUTED = exports.EVENT_CALL_MUTED = exports.EVENT_CALL_ENDED = exports.EVENT_CALL_TERMINATING = exports.EVENT_CALL_REJECTED = exports.EVENT_CALL_ERROR = exports.EVENT_EARLY_MEDIA = exports.EVENT_PROGRESS = exports.EVENT_CALL_CANCELED = exports.EVENT_CALL_ACCEPTED = void 0;
38
+ exports.MESSAGE_TRACK_UPDATED = exports.MESSAGE_TYPE_SIGNAL = exports.MESSAGE_TYPE_CHAT = exports.EVENT_CAMERA_DISABLED = exports.EVENT_CAMERA_RESUMED = exports.EVENT_WEB_RTC_STATS = exports.EVENT_SHARE_SCREEN_ENDED = exports.EVENT_SHARE_SCREEN_STARTED = exports.EVENT_SHARE_SCREEN_ENDING = exports.EVENT_REMOVE_STREAM = exports.EVENT_VIDEO_STREAM = exports.EVENT_AUDIO_STREAM = exports.EVENT_TRACK = exports.EVENT_REINVITE = exports.EVENT_CALL_RESUMED = exports.EVENT_CALL_HELD = exports.EVENT_CALL_UN_MUTED = exports.EVENT_CALL_MUTED = exports.EVENT_CALL_ENDED = exports.EVENT_CALL_TERMINATING = exports.EVENT_CALL_REJECTED = exports.EVENT_CALL_ERROR = exports.EVENT_EARLY_MEDIA = exports.EVENT_PROGRESS = exports.EVENT_CALL_CANCELED = exports.EVENT_CALL_LOCALLY_ACCEPTED = exports.EVENT_CALL_REMOTLY_ACCEPTED = void 0;
39
39
  /* eslint-disable no-underscore-dangle */
40
40
  const events_1 = require("events");
41
41
  const xstate_1 = require("xstate");
42
42
  const invitation_1 = require("sip.js/lib/api/invitation");
43
43
  const session_state_1 = require("sip.js/lib/api/session-state");
44
44
  const call_state_machine_1 = __importStar(require("../state-machine/call-state-machine"));
45
+ const new_from_1 = __importDefault(require("../utils/new-from"));
46
+ const update_from_1 = __importDefault(require("../utils/update-from"));
45
47
  const IssueReporter_1 = __importDefault(require("../service/IssueReporter"));
46
48
  const softphone_1 = __importStar(require("./softphone"));
47
49
  const sdp_1 = require("../utils/sdp");
@@ -49,7 +51,8 @@ const utils_1 = require("../state-machine/utils");
49
51
  const webrtc_1 = require("../utils/webrtc");
50
52
  const logger = IssueReporter_1.default.loggerFor('call');
51
53
  // Events
52
- exports.EVENT_CALL_ACCEPTED = 'accepted';
54
+ exports.EVENT_CALL_REMOTLY_ACCEPTED = 'remotelyAccepted';
55
+ exports.EVENT_CALL_LOCALLY_ACCEPTED = 'locallyAccepted';
53
56
  exports.EVENT_CALL_CANCELED = 'canceled';
54
57
  exports.EVENT_PROGRESS = 'progress';
55
58
  exports.EVENT_EARLY_MEDIA = 'earlyMedia';
@@ -76,6 +79,9 @@ exports.MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
76
79
  exports.MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
77
80
  exports.MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
78
81
  class Call extends events_1.EventEmitter {
82
+ static newFrom(call) {
83
+ return (0, new_from_1.default)(call, Call);
84
+ }
79
85
  static parseCall(apiCall) {
80
86
  const sipCall = {
81
87
  id: apiCall.sipCallId,
@@ -141,6 +147,7 @@ class Call extends events_1.EventEmitter {
141
147
  this.answerTime = new Date();
142
148
  return this.phone.client.answer(this.sipCall, options.withCamera).then(() => {
143
149
  logger.info('call - accepted', Object.assign({ id: this.id }, options));
150
+ this.emit(exports.EVENT_CALL_LOCALLY_ACCEPTED, this);
144
151
  return this.id;
145
152
  }).catch(e => {
146
153
  logger.error(e);
@@ -279,9 +286,21 @@ class Call extends events_1.EventEmitter {
279
286
  isHeld() {
280
287
  return this._hasEstablishedState(call_state_machine_1.EstablishedStates.HELD);
281
288
  }
289
+ isEstablishing() {
290
+ return this.sipCall.state === session_state_1.SessionState.Establishing;
291
+ }
282
292
  isEstablished() {
283
293
  return call_state_machine_1.States.ESTABLISHED in this.state;
284
294
  }
295
+ isRinging() {
296
+ return this.state === call_state_machine_1.States.RINGING;
297
+ }
298
+ isOutgoing() {
299
+ return this.sipCall instanceof invitation_1.Invitation;
300
+ }
301
+ isIncoming() {
302
+ return !this.isOutgoing();
303
+ }
285
304
  isConference() {
286
305
  var _a;
287
306
  return (_a = (0, webrtc_1.getPeerConnection)(this.sipCall)) === null || _a === void 0 ? void 0 : _a.sfu;
@@ -289,7 +308,7 @@ class Call extends events_1.EventEmitter {
289
308
  transfer(target) {
290
309
  (0, utils_1.assertState)(this.callActor, call_state_machine_1.States.ESTABLISHED);
291
310
  logger.info('call - transfer', { id: this.id, target });
292
- this.phone.client.transfer(this.sipCall, target);
311
+ return this.phone.client.transfer(this.sipCall, target);
293
312
  }
294
313
  atxfer() {
295
314
  (0, utils_1.assertState)(this.callActor, call_state_machine_1.States.ESTABLISHED);
@@ -429,7 +448,7 @@ class Call extends events_1.EventEmitter {
429
448
  }
430
449
  onAccepted() {
431
450
  this._sendAction(call_state_machine_1.Actions.REMOTLY_ACCEPTED);
432
- this.emit(exports.EVENT_CALL_ACCEPTED);
451
+ this.emit(exports.EVENT_CALL_REMOTLY_ACCEPTED);
433
452
  }
434
453
  onProgress() {
435
454
  this.emit(exports.EVENT_PROGRESS);
@@ -478,12 +497,15 @@ class Call extends events_1.EventEmitter {
478
497
  isVideoRemotelyHeld() {
479
498
  return (0, webrtc_1.isVideoRemotelyHeld)(this.sipCall);
480
499
  }
481
- isRinging() {
482
- return this.state === call_state_machine_1.States.RINGING;
483
- }
484
500
  onReinvite(request, updatedCalleeName, updatedNumber, hadRemoteVideo) {
485
501
  this.emit(exports.EVENT_REINVITE, request, updatedCalleeName, updatedNumber, hadRemoteVideo);
486
502
  }
503
+ updateFrom(call) {
504
+ (0, update_from_1.default)(this, call);
505
+ }
506
+ is(otherCall) {
507
+ return otherCall && this.id && this.id === otherCall.id;
508
+ }
487
509
  get id() {
488
510
  return (0, sdp_1.getSipSessionId)(this.sipCall);
489
511
  }
@@ -91,6 +91,11 @@ class Softphone extends events_1.EventEmitter {
91
91
  this.options.userUuid = session.uuid || '';
92
92
  return this.connectWithCredentials(server, this.sipLine, session.displayName(), options);
93
93
  }
94
+ hangupAllCalls() {
95
+ return __awaiter(this, void 0, void 0, function* () {
96
+ return Promise.all(this.calls.map(call => call.hangup()));
97
+ });
98
+ }
94
99
  disconnect() {
95
100
  return __awaiter(this, void 0, void 0, function* () {
96
101
  (0, utils_1.assertCan)(this.softphoneActor, softphone_state_machine_1.Actions.UNREGISTER);
@@ -98,7 +103,7 @@ class Softphone extends events_1.EventEmitter {
98
103
  return null;
99
104
  }
100
105
  // Terminate all calls
101
- yield Promise.all(this.calls.map(call => call.hangup()));
106
+ yield this.hangupAllCalls();
102
107
  return this.client.unregister();
103
108
  });
104
109
  }
@@ -275,7 +280,10 @@ class Softphone extends events_1.EventEmitter {
275
280
  this.audioRingVolume = volume;
276
281
  }
277
282
  getCurrentCall() {
278
- return this.calls.find(call => call.isEstablished());
283
+ return this.getActiveCalls()[0];
284
+ }
285
+ getActiveCalls() {
286
+ return this.calls.filter(call => call.isEstablished());
279
287
  }
280
288
  getIncomingCalls() {
281
289
  return this.calls.filter(call => call.isRinging());
@@ -283,6 +291,10 @@ class Softphone extends events_1.EventEmitter {
283
291
  get state() {
284
292
  return (0, utils_1.getState)(this.softphoneActor);
285
293
  }
294
+ get user() {
295
+ var _a, _b, _c, _d;
296
+ return (_d = (_c = (_b = (_a = this.client) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.contact) === null || _c === void 0 ? void 0 : _c.uri) === null || _d === void 0 ? void 0 : _d.user;
297
+ }
286
298
  getUserAgent() {
287
299
  var _a, _b;
288
300
  return ((_b = (_a = this.client) === null || _a === void 0 ? void 0 : _a.config) === null || _b === void 0 ? void 0 : _b.userAgentString) || 'softphone';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wazo/sdk",
3
- "version": "1.0.0-alpha.2",
3
+ "version": "1.0.0-alpha.3",
4
4
  "description": "Wazo's JavaScript Software Development Kit.",
5
5
  "main": "index.js",
6
6
  "types": "lib/types/index.d.ts",
@@ -79,6 +79,7 @@ describe('Call', () => {
79
79
  expect(call.answerTime).toStrictEqual(apiCall.startingTime);
80
80
  expect(call.isMuted()).toBeTruthy();
81
81
  expect(call.state).toStrictEqual({ [States.ESTABLISHED]: EstablishedStates.MUTED });
82
+ expect(call.isEstablished()).toBeTruthy();
82
83
  });
83
84
  });
84
85
 
@@ -1,5 +1,6 @@
1
1
  import Session from '../Session';
2
2
  import Call from '../Call';
3
+ import SoftphoneCall from '../../voice/call';
3
4
  import Line from '../Line';
4
5
  import CallSession from '../CallSession';
5
6
  import type { Phone, AvailablePhoneOptions } from './Phone';
@@ -141,7 +142,7 @@ export default class CTIPhone extends Emitter implements Phone {
141
142
  });
142
143
 
143
144
  try {
144
- await CallApi.cancelCall(callSession);
145
+ await CallApi.cancelCall({ apiId: callSession.getId() } as SoftphoneCall);
145
146
 
146
147
  if (this.currentCall && callSession.callId === this.currentCall.id) {
147
148
  this.endCurrentCall(callSession);
@@ -167,7 +168,7 @@ export default class CTIPhone extends Emitter implements Phone {
167
168
  callId: callSession.getId(),
168
169
  number: callSession.number,
169
170
  });
170
- await CallApi.cancelCall(callSession);
171
+ await CallApi.cancelCall({ id: callSession.getId() } as SoftphoneCall);
171
172
  this.eventEmitter.emit('onCallEnded', callSession);
172
173
  }
173
174
 
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 Call } from './domain/Call';
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';
@@ -1,9 +1,9 @@
1
- import Call from '../domain/Call';
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<Call[]> {
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(callSession: CallSession): Promise<boolean> {
41
- return getApiClient().calld.cancelCall(callSession.callId);
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<Call | null | undefined> {
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 Call.parse(response);
47
+ return ApiCall.parse(response);
48
48
  }
49
49
 
50
50
  static async relocateCall(callId: string, line: number, contactIdentifier?: string): Promise<Relocation> {
package/src/voice/call.ts CHANGED
@@ -11,7 +11,8 @@ import type { IncomingRequestMessage } from 'sip.js/lib/core/messages/incoming-r
11
11
  import callStateMachine, { type ActionTypes, Actions, type EstablishedActionTypes, EstablishedActions, States, type StateTypes, EstablishedStates, type EstablishedStateTypes, type CallActorRef } from '../state-machine/call-state-machine';
12
12
  import { SipCall, PeerConnection } from '../domain/types';
13
13
  import ApiCall from '../domain/Call';
14
-
14
+ import newFrom from '../utils/new-from';
15
+ import updateFrom from '../utils/update-from';
15
16
  import IssueReporter from '../service/IssueReporter';
16
17
  import softphone, { EVENT_TERMINATE_SOUND, Softphone } from './softphone';
17
18
  import { getCallDisplayName, getCallNumber, getSipSessionId } from '../utils/sdp';
@@ -32,7 +33,8 @@ export type ReinviteOptions = {
32
33
  };
33
34
 
34
35
  // Events
35
- export const EVENT_CALL_ACCEPTED = 'accepted';
36
+ export const EVENT_CALL_REMOTLY_ACCEPTED = 'remotelyAccepted';
37
+ export const EVENT_CALL_LOCALLY_ACCEPTED = 'locallyAccepted';
36
38
  export const EVENT_CALL_CANCELED = 'canceled';
37
39
  export const EVENT_PROGRESS = 'progress';
38
40
  export const EVENT_EARLY_MEDIA = 'earlyMedia';
@@ -88,6 +90,10 @@ class Call extends EventEmitter {
88
90
 
89
91
  currentScreenShare: Record<string, any> | null;
90
92
 
93
+ static newFrom(call: Call) {
94
+ return newFrom(call, Call);
95
+ }
96
+
91
97
  static parseCall(apiCall: ApiCall): Call {
92
98
  const sipCall = {
93
99
  id: apiCall.sipCallId,
@@ -170,6 +176,8 @@ class Call extends EventEmitter {
170
176
  return this.phone.client.answer(this.sipCall as Invitation, options.withCamera).then(() => {
171
177
  logger.info('call - accepted', { id: this.id, ...options });
172
178
 
179
+ this.emit(EVENT_CALL_LOCALLY_ACCEPTED, this);
180
+
173
181
  return this.id;
174
182
  }).catch(e => {
175
183
  logger.error(e);
@@ -343,10 +351,26 @@ class Call extends EventEmitter {
343
351
  return this._hasEstablishedState(EstablishedStates.HELD);
344
352
  }
345
353
 
354
+ isEstablishing() {
355
+ return this.sipCall.state === SessionState.Establishing;
356
+ }
357
+
346
358
  isEstablished() {
347
359
  return States.ESTABLISHED in (this.state as Record<StateTypes, EstablishedStateTypes>);
348
360
  }
349
361
 
362
+ isRinging() {
363
+ return this.state === States.RINGING;
364
+ }
365
+
366
+ isOutgoing() {
367
+ return this.sipCall instanceof Invitation;
368
+ }
369
+
370
+ isIncoming() {
371
+ return !this.isOutgoing();
372
+ }
373
+
350
374
  isConference(): boolean {
351
375
  return (getPeerConnection(this.sipCall) as PeerConnection)?.sfu;
352
376
  }
@@ -355,7 +379,7 @@ class Call extends EventEmitter {
355
379
  assertState(this.callActor, States.ESTABLISHED);
356
380
  logger.info('call - transfer', { id: this.id, target });
357
381
 
358
- this.phone.client.transfer(this.sipCall, target);
382
+ return this.phone.client.transfer(this.sipCall, target);
359
383
  }
360
384
 
361
385
  atxfer(): Record<string, any> | null | undefined {
@@ -528,7 +552,7 @@ class Call extends EventEmitter {
528
552
 
529
553
  onAccepted() {
530
554
  this._sendAction(Actions.REMOTLY_ACCEPTED);
531
- this.emit(EVENT_CALL_ACCEPTED);
555
+ this.emit(EVENT_CALL_REMOTLY_ACCEPTED);
532
556
  }
533
557
 
534
558
  onProgress() {
@@ -595,14 +619,18 @@ class Call extends EventEmitter {
595
619
  return isVideoRemotelyHeld(this.sipCall);
596
620
  }
597
621
 
598
- isRinging() {
599
- return this.state === States.RINGING;
600
- }
601
-
602
622
  onReinvite(request: IncomingRequestMessage, updatedCalleeName: string, updatedNumber: string, hadRemoteVideo: boolean) {
603
623
  this.emit(EVENT_REINVITE, request, updatedCalleeName, updatedNumber, hadRemoteVideo);
604
624
  }
605
625
 
626
+ updateFrom(call: Call) {
627
+ updateFrom(this, call);
628
+ }
629
+
630
+ is(otherCall: Call) {
631
+ return otherCall && this.id && this.id === otherCall.id;
632
+ }
633
+
606
634
  get id() {
607
635
  return getSipSessionId(this.sipCall);
608
636
  }
@@ -44,6 +44,7 @@ export type CallOptions = {
44
44
  // If audioOnly is set to true, all video stream will be deactivated, even remotes ones.
45
45
  audioOnly?: boolean,
46
46
  conference?: boolean,
47
+ extraHeaders?: Record<string, any>,
47
48
  };
48
49
 
49
50
  const logger = IssueReporter.loggerFor('softphone');
@@ -107,6 +108,10 @@ export class Softphone extends EventEmitter {
107
108
  return this.connectWithCredentials(server, this.sipLine, session.displayName(), options);
108
109
  }
109
110
 
111
+ async hangupAllCalls() {
112
+ return Promise.all(this.calls.map(call => call.hangup()));
113
+ }
114
+
110
115
  async disconnect() {
111
116
  assertCan(this.softphoneActor, Actions.UNREGISTER);
112
117
  if (!this.client) {
@@ -114,7 +119,7 @@ export class Softphone extends EventEmitter {
114
119
  }
115
120
 
116
121
  // Terminate all calls
117
- await Promise.all(this.calls.map(call => call.hangup()));
122
+ await this.hangupAllCalls();
118
123
 
119
124
  return this.client.unregister();
120
125
  }
@@ -348,7 +353,11 @@ export class Softphone extends EventEmitter {
348
353
  }
349
354
 
350
355
  getCurrentCall(): Call | undefined {
351
- return this.calls.find(call => call.isEstablished());
356
+ return this.getActiveCalls()[0];
357
+ }
358
+
359
+ getActiveCalls(): Call[] {
360
+ return this.calls.filter(call => call.isEstablished());
352
361
  }
353
362
 
354
363
  getIncomingCalls(): Call[] {
@@ -359,6 +368,10 @@ export class Softphone extends EventEmitter {
359
368
  return getState(this.softphoneActor) as StateTypes;
360
369
  }
361
370
 
371
+ get user() {
372
+ return this.client?.userAgent?.contact?.uri?.user;
373
+ }
374
+
362
375
  getUserAgent() {
363
376
  return this.client?.config?.userAgentString || 'softphone';
364
377
  }