@wazo/sdk 0.38.21 → 0.39.0-beta.1
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 +0 -293
- package/dist/wazo-sdk.js +9 -25
- package/esm/__tests__/api-client.test.js +183 -5059
- package/esm/__tests__/web-rtc-client.test.js +177 -7932
- package/esm/api/agentd.js +23 -832
- package/esm/api/amid.js +9 -411
- package/esm/api/application.js +60 -829
- package/esm/api/auth.js +164 -1213
- package/esm/api/call-logd.js +24 -733
- package/esm/api/calld.js +114 -1469
- package/esm/api/chatd.js +35 -1312
- package/esm/api/confd.js +67 -1580
- package/esm/api/ctid-ng.js +92 -1343
- package/esm/api/dird.js +100 -1590
- package/esm/api/webhookd.js +7 -513
- package/esm/api-client.js +143 -4881
- package/esm/checker/Checker.js +45 -8729
- package/esm/checker/checks/aor.js +24 -4924
- package/esm/checker/checks/api.js +70 -4968
- package/esm/checker/checks/ice-ipv4.js +63 -117
- package/esm/checker/checks/index.js +8 -8679
- package/esm/checker/checks/symmetric-nat.js +54 -102
- package/esm/checker/checks/wazo-websocket.js +34 -999
- package/esm/checker/checks/webrtc-transport.js +28 -7847
- package/esm/checker/checks/webrtc.js +31 -7854
- package/esm/domain/AdHocAPIConference.js +86 -5115
- package/esm/domain/Agent.js +27 -61
- package/esm/domain/BadResponse.js +20 -43
- package/esm/domain/Call.js +120 -210
- package/esm/domain/CallLog.js +123 -305
- package/esm/domain/CallSession.js +251 -423
- package/esm/domain/ChatMessage.js +52 -105
- package/esm/domain/ChatRoom.js +28 -60
- package/esm/domain/Contact.js +430 -741
- package/esm/domain/Country.js +17 -19
- package/esm/domain/Device/DebugDevice.js +31 -47
- package/esm/domain/Device/Device.js +1 -1
- package/esm/domain/DirectorySource.js +1 -1
- package/esm/domain/ExternalApp.js +23 -56
- package/esm/domain/Features.js +57 -5009
- package/esm/domain/ForwardOption.js +35 -70
- package/esm/domain/IndirectTransfer.js +38 -97
- package/esm/domain/Line.js +37 -88
- package/esm/domain/Meeting.js +58 -113
- package/esm/domain/MeetingAuthorization.js +38 -68
- package/esm/domain/MeetingStatus.js +13 -28
- package/esm/domain/NotificationOptions.js +43 -77
- package/esm/domain/Phone/CTIPhone.js +245 -5743
- package/esm/domain/Phone/Phone.js +1 -2
- package/esm/domain/Phone/WebRTCPhone.js +1446 -2670
- package/esm/domain/Profile.js +120 -405
- package/esm/domain/Recording.js +27 -51
- package/esm/domain/Relocation.js +16 -40
- package/esm/domain/Room.js +90 -133
- package/esm/domain/SFUNotAvailableError.js +5 -8
- package/esm/domain/ServerError.js +8 -61
- package/esm/domain/Session.js +125 -251
- package/esm/domain/SipLine.js +78 -155
- package/esm/domain/Subscription.js +39 -83
- package/esm/domain/SwitchboardCall.js +51 -143
- package/esm/domain/Voicemail.js +57 -122
- package/esm/domain/__tests__/Agent.test.js +31 -101
- package/esm/domain/__tests__/Call.test.js +24 -232
- package/esm/domain/__tests__/CallLog.test.js +60 -386
- package/esm/domain/__tests__/CallSession.test.js +74 -502
- package/esm/domain/__tests__/Contact.test.js +220 -902
- package/esm/domain/__tests__/IndirectTransfer.test.js +63 -546
- package/esm/domain/__tests__/Line.test.js +48 -156
- package/esm/domain/__tests__/Meeting.test.js +73 -226
- package/esm/domain/__tests__/MeetingAuthorization.test.js +45 -105
- package/esm/domain/__tests__/Profile.test.js +135 -496
- package/esm/domain/__tests__/Room.test.js +227 -719
- package/esm/domain/__tests__/Session.test.js +357 -1025
- package/esm/domain/__tests__/SipLine.test.js +24 -179
- package/esm/domain/__tests__/Voicemail.test.js +82 -200
- package/esm/domain/types.js +1 -1
- package/esm/index.js +63 -14987
- package/esm/lib/WazoSessionDescriptionHandler.js +406 -890
- package/esm/pubkey.js +10 -0
- package/esm/service/CallApi.js +42 -5014
- package/esm/service/IssueReporter.js +278 -360
- package/esm/service/__tests__/IssueReporter.test.js +92 -494
- package/esm/service/getApiClient.js +53 -4972
- package/esm/simple/Auth.js +211 -14749
- package/esm/simple/Configuration.js +8 -14798
- package/esm/simple/Directory.js +6 -4964
- package/esm/simple/Phone.js +309 -14729
- package/esm/simple/Websocket.js +68 -1112
- package/esm/simple/index.js +125 -14794
- package/esm/simple/room/LocalParticipant.js +1 -14799
- package/esm/simple/room/Participant.js +274 -14762
- package/esm/simple/room/RemoteParticipant.js +6 -14798
- package/esm/simple/room/Room.js +648 -14738
- package/esm/simple/room/SipRoom.js +111 -14792
- package/esm/simple/room/Stream.js +40 -14794
- package/esm/simple/room/__tests__/Participant.test.js +68 -14874
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +10 -14807
- package/esm/simple/utils.js +9 -14801
- package/esm/types/WebSocketMessage.js +1 -1
- package/esm/types/__tests__/api-client.test.d.ts +2 -0
- package/esm/types/__tests__/api-client.test.d.ts.map +1 -0
- package/esm/types/__tests__/web-rtc-client.test.d.ts +2 -0
- package/esm/types/__tests__/web-rtc-client.test.d.ts.map +1 -0
- package/esm/types/api/agentd.d.ts +17 -0
- package/esm/types/api/agentd.d.ts.map +1 -0
- package/esm/types/api/amid.d.ts +8 -0
- package/esm/types/api/amid.d.ts.map +1 -0
- package/esm/types/api/application.d.ts +34 -0
- package/esm/types/api/application.d.ts.map +1 -0
- package/esm/types/api/auth.d.ts +64 -0
- package/esm/types/api/auth.d.ts.map +1 -0
- package/esm/types/api/call-logd.d.ts +12 -0
- package/esm/types/api/call-logd.d.ts.map +1 -0
- package/esm/types/api/calld.d.ts +51 -0
- package/esm/types/api/calld.d.ts.map +1 -0
- package/esm/types/api/chatd.d.ts +42 -0
- package/esm/types/api/chatd.d.ts.map +1 -0
- package/esm/types/api/confd.d.ts +39 -0
- package/esm/types/api/confd.d.ts.map +1 -0
- package/esm/types/api/ctid-ng.d.ts +36 -0
- package/esm/types/api/ctid-ng.d.ts.map +1 -0
- package/esm/types/api/dird.d.ts +38 -0
- package/esm/types/api/dird.d.ts.map +1 -0
- package/esm/types/api/webhookd.d.ts +24 -0
- package/esm/types/api/webhookd.d.ts.map +1 -0
- package/esm/types/api-client.d.ts +63 -0
- package/esm/types/api-client.d.ts.map +1 -0
- package/esm/types/checker/Checker.d.ts +13 -0
- package/esm/types/checker/Checker.d.ts.map +1 -0
- package/esm/types/checker/checks/aor.d.ts +6 -0
- package/esm/types/checker/checks/aor.d.ts.map +1 -0
- package/esm/types/checker/checks/api.d.ts +6 -0
- package/esm/types/checker/checks/api.d.ts.map +1 -0
- package/esm/types/checker/checks/ice-ipv4.d.ts +6 -0
- package/esm/types/checker/checks/ice-ipv4.d.ts.map +1 -0
- package/esm/types/checker/checks/index.d.ts +9 -0
- package/esm/types/checker/checks/index.d.ts.map +1 -0
- package/esm/types/checker/checks/symmetric-nat.d.ts +6 -0
- package/esm/types/checker/checks/symmetric-nat.d.ts.map +1 -0
- package/esm/types/checker/checks/wazo-websocket.d.ts +6 -0
- package/esm/types/checker/checks/wazo-websocket.d.ts.map +1 -0
- package/esm/types/checker/checks/webrtc-transport.d.ts +7 -0
- package/esm/types/checker/checks/webrtc-transport.d.ts.map +1 -0
- package/esm/types/checker/checks/webrtc.d.ts +6 -0
- package/esm/types/checker/checks/webrtc.d.ts.map +1 -0
- package/esm/types/domain/AdHocAPIConference.d.ts +54 -0
- package/esm/types/domain/AdHocAPIConference.d.ts.map +1 -0
- package/esm/types/domain/Agent.d.ts +31 -0
- package/esm/types/domain/Agent.d.ts.map +1 -0
- package/esm/types/domain/BadResponse.d.ts +11 -0
- package/esm/types/domain/BadResponse.d.ts.map +1 -0
- package/esm/types/domain/Call.d.ts +79 -0
- package/esm/types/domain/Call.d.ts.map +1 -0
- package/esm/types/domain/CallLog.d.ts +91 -0
- package/esm/types/domain/CallLog.d.ts.map +1 -0
- package/esm/types/domain/CallSession.d.ts +120 -0
- package/esm/types/domain/CallSession.d.ts.map +1 -0
- package/esm/types/domain/ChatMessage.d.ts +41 -0
- package/esm/types/domain/ChatMessage.d.ts.map +1 -0
- package/esm/types/domain/ChatRoom.d.ts +22 -0
- package/esm/types/domain/ChatRoom.d.ts.map +1 -0
- package/esm/types/domain/Contact.d.ts +316 -0
- package/esm/types/domain/Contact.d.ts.map +1 -0
- package/esm/types/domain/Country.d.ts +20 -0
- package/esm/types/domain/Country.d.ts.map +1 -0
- package/esm/types/domain/Device/DebugDevice.d.ts +14 -0
- package/esm/types/domain/Device/DebugDevice.d.ts.map +1 -0
- package/esm/types/domain/Device/Device.d.ts +13 -0
- package/esm/types/domain/Device/Device.d.ts.map +1 -0
- package/esm/types/domain/DirectorySource.d.ts +13 -0
- package/esm/types/domain/DirectorySource.d.ts.map +1 -0
- package/esm/types/domain/ExternalApp.d.ts +22 -0
- package/esm/types/domain/ExternalApp.d.ts.map +1 -0
- package/esm/types/domain/Features.d.ts +24 -0
- package/esm/types/domain/Features.d.ts.map +1 -0
- package/esm/types/domain/ForwardOption.d.ts +27 -0
- package/esm/types/domain/ForwardOption.d.ts.map +1 -0
- package/esm/types/domain/IndirectTransfer.d.ts +31 -0
- package/esm/types/domain/IndirectTransfer.d.ts.map +1 -0
- package/esm/types/domain/Line.d.ts +46 -0
- package/esm/types/domain/Line.d.ts.map +1 -0
- package/esm/types/domain/Meeting.d.ts +45 -0
- package/esm/types/domain/Meeting.d.ts.map +1 -0
- package/esm/types/domain/MeetingAuthorization.d.ts +26 -0
- package/esm/types/domain/MeetingAuthorization.d.ts.map +1 -0
- package/esm/types/domain/MeetingStatus.d.ts +10 -0
- package/esm/types/domain/MeetingStatus.d.ts.map +1 -0
- package/esm/types/domain/NotificationOptions.d.ts +22 -0
- package/esm/types/domain/NotificationOptions.d.ts.map +1 -0
- package/esm/types/domain/Phone/CTIPhone.d.ts +76 -0
- package/esm/types/domain/Phone/CTIPhone.d.ts.map +1 -0
- package/esm/types/domain/Phone/Phone.d.ts +71 -0
- package/esm/types/domain/Phone/Phone.d.ts.map +1 -0
- package/esm/types/domain/Phone/WebRTCPhone.d.ts +179 -0
- package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -0
- package/esm/types/domain/Profile.d.ts +151 -0
- package/esm/types/domain/Profile.d.ts.map +1 -0
- package/esm/types/domain/Recording.d.ts +26 -0
- package/esm/types/domain/Recording.d.ts.map +1 -0
- package/esm/types/domain/Relocation.d.ts +23 -0
- package/esm/types/domain/Relocation.d.ts.map +1 -0
- package/esm/types/domain/Room.d.ts +35 -0
- package/esm/types/domain/Room.d.ts.map +1 -0
- package/esm/types/domain/SFUNotAvailableError.d.ts +4 -0
- package/esm/types/domain/SFUNotAvailableError.d.ts.map +1 -0
- package/esm/types/domain/ServerError.d.ts +6 -0
- package/esm/types/domain/ServerError.d.ts.map +1 -0
- package/esm/types/domain/Session.d.ts +90 -0
- package/esm/types/domain/Session.d.ts.map +1 -0
- package/esm/types/domain/SipLine.d.ts +54 -0
- package/esm/types/domain/SipLine.d.ts.map +1 -0
- package/esm/types/domain/Subscription.d.ts +43 -0
- package/esm/types/domain/Subscription.d.ts.map +1 -0
- package/esm/types/domain/SwitchboardCall.d.ts +62 -0
- package/esm/types/domain/SwitchboardCall.d.ts.map +1 -0
- package/esm/types/domain/Voicemail.d.ts +50 -0
- package/esm/types/domain/Voicemail.d.ts.map +1 -0
- package/esm/types/domain/__tests__/Agent.test.d.ts +2 -0
- package/esm/types/domain/__tests__/Agent.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/Call.test.d.ts +2 -0
- package/esm/types/domain/__tests__/Call.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/CallLog.test.d.ts +2 -0
- package/esm/types/domain/__tests__/CallLog.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/CallSession.test.d.ts +2 -0
- package/esm/types/domain/__tests__/CallSession.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/Contact.test.d.ts +2 -0
- package/esm/types/domain/__tests__/Contact.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/IndirectTransfer.test.d.ts +2 -0
- package/esm/types/domain/__tests__/IndirectTransfer.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/Line.test.d.ts +2 -0
- package/esm/types/domain/__tests__/Line.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/Meeting.test.d.ts +2 -0
- package/esm/types/domain/__tests__/Meeting.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/MeetingAuthorization.test.d.ts +2 -0
- package/esm/types/domain/__tests__/MeetingAuthorization.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/Profile.test.d.ts +2 -0
- package/esm/types/domain/__tests__/Profile.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/Room.test.d.ts +2 -0
- package/esm/types/domain/__tests__/Room.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/Session.test.d.ts +2 -0
- package/esm/types/domain/__tests__/Session.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/SipLine.test.d.ts +2 -0
- package/esm/types/domain/__tests__/SipLine.test.d.ts.map +1 -0
- package/esm/types/domain/__tests__/Voicemail.test.d.ts +2 -0
- package/esm/types/domain/__tests__/Voicemail.test.d.ts.map +1 -0
- package/esm/types/domain/types.d.ts +217 -0
- package/esm/types/domain/types.d.ts.map +1 -0
- package/esm/types/index.d.ts +304 -0
- package/esm/types/index.d.ts.map +1 -0
- package/esm/types/lib/WazoSessionDescriptionHandler.d.ts +30 -0
- package/esm/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -0
- package/esm/types/pubkey.d.ts +3 -0
- package/esm/types/pubkey.d.ts.map +1 -0
- package/esm/types/service/CallApi.d.ts +28 -0
- package/esm/types/service/CallApi.d.ts.map +1 -0
- package/esm/types/service/IssueReporter.d.ts +40 -0
- package/esm/types/service/IssueReporter.d.ts.map +1 -0
- package/esm/types/service/__tests__/IssueReporter.test.d.ts +2 -0
- package/esm/types/service/__tests__/IssueReporter.test.d.ts.map +1 -0
- package/esm/types/service/getApiClient.d.ts +16 -0
- package/esm/types/service/getApiClient.d.ts.map +1 -0
- package/esm/types/simple/Auth.d.ts +51 -0
- package/esm/types/simple/Auth.d.ts.map +1 -0
- package/esm/types/simple/Configuration.d.ts +3 -0
- package/esm/types/simple/Configuration.d.ts.map +1 -0
- package/esm/types/simple/Directory.d.ts +3 -0
- package/esm/types/simple/Directory.d.ts.map +1 -0
- package/esm/types/simple/Phone.d.ts +115 -0
- package/esm/types/simple/Phone.d.ts.map +1 -0
- package/esm/types/simple/Websocket.d.ts +19 -0
- package/esm/types/simple/Websocket.d.ts.map +1 -0
- package/esm/types/simple/index.d.ts +147 -0
- package/esm/types/simple/index.d.ts.map +1 -0
- package/esm/types/simple/room/LocalParticipant.d.ts +5 -0
- package/esm/types/simple/room/LocalParticipant.d.ts.map +1 -0
- package/esm/types/simple/room/Participant.d.ts +76 -0
- package/esm/types/simple/room/Participant.d.ts.map +1 -0
- package/esm/types/simple/room/RemoteParticipant.d.ts +7 -0
- package/esm/types/simple/room/RemoteParticipant.d.ts.map +1 -0
- package/esm/types/simple/room/Room.d.ts +116 -0
- package/esm/types/simple/room/Room.d.ts.map +1 -0
- package/esm/types/simple/room/SipRoom.d.ts +14 -0
- package/esm/types/simple/room/SipRoom.d.ts.map +1 -0
- package/esm/types/simple/room/Stream.d.ts +13 -0
- package/esm/types/simple/room/Stream.d.ts.map +1 -0
- package/esm/types/simple/room/__tests__/Participant.test.d.ts +2 -0
- package/esm/types/simple/room/__tests__/Participant.test.d.ts.map +1 -0
- package/esm/types/simple/room/__tests__/RemoteParticipant.test.d.ts +2 -0
- package/esm/types/simple/room/__tests__/RemoteParticipant.test.d.ts.map +1 -0
- package/esm/types/simple/utils.d.ts +3 -0
- package/esm/types/simple/utils.d.ts.map +1 -0
- package/esm/types/types/WebSocketMessage.d.ts +285 -0
- package/esm/types/types/WebSocketMessage.d.ts.map +1 -0
- package/esm/types/utils/Emitter.d.ts +18 -0
- package/esm/types/utils/Emitter.d.ts.map +1 -0
- package/esm/types/utils/Heartbeat.d.ts +21 -0
- package/esm/types/utils/Heartbeat.d.ts.map +1 -0
- package/esm/types/utils/PhoneNumberUtil.d.ts +8 -0
- package/esm/types/utils/PhoneNumberUtil.d.ts.map +1 -0
- package/esm/types/utils/__tests__/Heartbeat.test.d.ts +2 -0
- package/esm/types/utils/__tests__/Heartbeat.test.d.ts.map +1 -0
- package/esm/types/utils/__tests__/PhoneNumberUtil.test.d.ts +2 -0
- package/esm/types/utils/__tests__/PhoneNumberUtil.test.d.ts.map +1 -0
- package/esm/types/utils/__tests__/api-requester.test.d.ts +2 -0
- package/esm/types/utils/__tests__/api-requester.test.d.ts.map +1 -0
- package/esm/types/utils/__tests__/array.test.d.ts +2 -0
- package/esm/types/utils/__tests__/array.test.d.ts.map +1 -0
- package/esm/types/utils/__tests__/compare-version.test.d.ts +2 -0
- package/esm/types/utils/__tests__/compare-version.test.d.ts.map +1 -0
- package/esm/types/utils/__tests__/object.test.d.ts +2 -0
- package/esm/types/utils/__tests__/object.test.d.ts.map +1 -0
- package/esm/types/utils/__tests__/sdp.test.d.ts +2 -0
- package/esm/types/utils/__tests__/sdp.test.d.ts.map +1 -0
- package/esm/types/utils/__tests__/string.test.d.ts +2 -0
- package/esm/types/utils/__tests__/string.test.d.ts.map +1 -0
- package/esm/types/utils/api-requester.d.ts +45 -0
- package/esm/types/utils/api-requester.d.ts.map +1 -0
- package/esm/types/utils/array.d.ts +2 -0
- package/esm/types/utils/array.d.ts.map +1 -0
- package/esm/types/utils/compare-version.d.ts +3 -0
- package/esm/types/utils/compare-version.d.ts.map +1 -0
- package/esm/types/utils/isMobile.d.ts +3 -0
- package/esm/types/utils/isMobile.d.ts.map +1 -0
- package/esm/types/utils/new-from.d.ts +3 -0
- package/esm/types/utils/new-from.d.ts.map +1 -0
- package/esm/types/utils/object.d.ts +2 -0
- package/esm/types/utils/object.d.ts.map +1 -0
- package/esm/types/utils/once.d.ts +2 -0
- package/esm/types/utils/once.d.ts.map +1 -0
- package/esm/types/utils/sdp.d.ts +13 -0
- package/esm/types/utils/sdp.d.ts.map +1 -0
- package/esm/types/utils/string.d.ts +2 -0
- package/esm/types/utils/string.d.ts.map +1 -0
- package/esm/types/utils/update-from.d.ts +3 -0
- package/esm/types/utils/update-from.d.ts.map +1 -0
- package/esm/types/utils/webrtc.d.ts +15 -0
- package/esm/types/utils/webrtc.d.ts.map +1 -0
- package/esm/types/web-rtc-client.d.ts +211 -0
- package/esm/types/web-rtc-client.d.ts.map +1 -0
- package/esm/types/websocket-client.d.ts +134 -0
- package/esm/types/websocket-client.d.ts.map +1 -0
- package/esm/utils/Emitter.js +17 -27
- package/esm/utils/Heartbeat.js +60 -83
- package/esm/utils/PhoneNumberUtil.js +48 -63
- package/esm/utils/__tests__/Heartbeat.test.js +59 -168
- package/esm/utils/__tests__/PhoneNumberUtil.test.js +55 -125
- package/esm/utils/__tests__/api-requester.test.js +127 -780
- package/esm/utils/__tests__/array.test.js +16 -19
- package/esm/utils/__tests__/compare-version.test.js +8 -26
- package/esm/utils/__tests__/object.test.js +73 -54
- package/esm/utils/__tests__/sdp.test.js +87 -216
- package/esm/utils/__tests__/string.test.js +21 -27
- package/esm/utils/api-requester.js +197 -675
- package/esm/utils/array.js +7 -11
- package/esm/utils/compare-version.js +12 -15
- package/esm/utils/isMobile.js +0 -2
- package/esm/utils/new-from.js +7 -12
- package/esm/utils/object.js +9 -23
- package/esm/utils/once.js +12 -13
- package/esm/utils/sdp.js +87 -131
- package/esm/utils/string.js +5 -9
- package/esm/utils/update-from.js +9 -16
- package/esm/utils/webrtc.js +35 -36
- package/esm/web-rtc-client.js +1973 -7678
- package/esm/websocket-client.js +352 -944
- package/lib/__tests__/api-client.test.js +199 -5067
- package/lib/__tests__/web-rtc-client.test.js +191 -7943
- package/lib/api/agentd.js +27 -837
- package/lib/api/amid.js +18 -415
- package/lib/api/application.js +64 -834
- package/lib/api/auth.js +166 -1222
- package/lib/api/call-logd.js +28 -738
- package/lib/api/calld.js +126 -1473
- package/lib/api/chatd.js +49 -1316
- package/lib/api/confd.js +79 -1584
- package/lib/api/ctid-ng.js +96 -1348
- package/lib/api/dird.js +105 -1596
- package/lib/api/webhookd.js +11 -518
- package/lib/api-client.js +138 -4884
- package/lib/checker/Checker.js +61 -8741
- package/lib/checker/checks/aor.js +37 -4929
- package/lib/checker/checks/api.js +81 -4971
- package/lib/checker/checks/ice-ipv4.js +66 -118
- package/lib/checker/checks/index.js +13 -8689
- package/lib/checker/checks/symmetric-nat.js +56 -104
- package/lib/checker/checks/wazo-websocket.js +58 -1006
- package/lib/checker/checks/webrtc-transport.js +41 -7855
- package/lib/checker/checks/webrtc.js +42 -7860
- package/lib/domain/AdHocAPIConference.js +80 -5116
- package/lib/domain/Agent.js +23 -64
- package/lib/domain/BadResponse.js +17 -44
- package/lib/domain/Call.js +108 -215
- package/lib/domain/CallLog.js +117 -311
- package/lib/domain/CallSession.js +221 -424
- package/lib/domain/ChatMessage.js +49 -110
- package/lib/domain/ChatRoom.js +28 -60
- package/lib/domain/Contact.js +404 -742
- package/lib/domain/Country.js +19 -21
- package/lib/domain/Device/DebugDevice.js +34 -49
- package/lib/domain/Device/Device.js +2 -2
- package/lib/domain/DirectorySource.js +2 -2
- package/lib/domain/ExternalApp.js +24 -56
- package/lib/domain/Features.js +68 -5018
- package/lib/domain/ForwardOption.js +36 -71
- package/lib/domain/IndirectTransfer.js +39 -98
- package/lib/domain/Line.js +35 -88
- package/lib/domain/Meeting.js +51 -118
- package/lib/domain/MeetingAuthorization.js +35 -75
- package/lib/domain/MeetingStatus.js +13 -29
- package/lib/domain/NotificationOptions.js +45 -77
- package/lib/domain/Phone/CTIPhone.js +283 -5755
- package/lib/domain/Phone/Phone.js +2 -5
- package/lib/domain/Phone/WebRTCPhone.js +1446 -2715
- package/lib/domain/Profile.js +127 -406
- package/lib/domain/Recording.js +28 -57
- package/lib/domain/Relocation.js +15 -43
- package/lib/domain/Room.js +73 -134
- package/lib/domain/SFUNotAvailableError.js +7 -9
- package/lib/domain/ServerError.js +14 -63
- package/lib/domain/Session.js +118 -251
- package/lib/domain/SipLine.js +70 -155
- package/lib/domain/Subscription.js +32 -86
- package/lib/domain/SwitchboardCall.js +45 -145
- package/lib/domain/Voicemail.js +56 -127
- package/lib/domain/__tests__/Agent.test.js +36 -103
- package/lib/domain/__tests__/Call.test.js +28 -237
- package/lib/domain/__tests__/CallLog.test.js +65 -392
- package/lib/domain/__tests__/CallSession.test.js +78 -503
- package/lib/domain/__tests__/Contact.test.js +224 -903
- package/lib/domain/__tests__/IndirectTransfer.test.js +75 -546
- package/lib/domain/__tests__/Line.test.js +52 -157
- package/lib/domain/__tests__/Meeting.test.js +78 -232
- package/lib/domain/__tests__/MeetingAuthorization.test.js +50 -107
- package/lib/domain/__tests__/Profile.test.js +161 -496
- package/lib/domain/__tests__/Room.test.js +239 -719
- package/lib/domain/__tests__/Session.test.js +350 -1024
- package/lib/domain/__tests__/SipLine.test.js +28 -180
- package/lib/domain/__tests__/Voicemail.test.js +86 -205
- package/lib/domain/types.js +2 -2
- package/lib/index.js +105 -15012
- package/lib/lib/WazoSessionDescriptionHandler.js +409 -898
- package/lib/pubkey.js +12 -0
- package/lib/service/CallApi.js +88 -5015
- package/lib/service/IssueReporter.js +264 -366
- package/lib/service/__tests__/IssueReporter.test.js +97 -500
- package/lib/service/getApiClient.js +70 -4990
- package/lib/simple/Auth.js +271 -14779
- package/lib/simple/Configuration.js +23 -14807
- package/lib/simple/Directory.js +18 -4966
- package/lib/simple/Phone.js +345 -14748
- package/lib/simple/Websocket.js +98 -1117
- package/lib/simple/index.js +151 -14802
- package/lib/simple/room/LocalParticipant.js +7 -14810
- package/lib/simple/room/Participant.js +269 -14780
- package/lib/simple/room/RemoteParticipant.js +11 -14808
- package/lib/simple/room/Room.js +655 -14763
- package/lib/simple/room/SipRoom.js +136 -14807
- package/lib/simple/room/Stream.js +43 -14804
- package/lib/simple/room/__tests__/Participant.test.js +79 -14881
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +14 -14816
- package/lib/simple/utils.js +22 -14810
- package/lib/types/WebSocketMessage.js +2 -4
- package/lib/types/__tests__/api-client.test.d.ts +2 -0
- package/lib/types/__tests__/api-client.test.d.ts.map +1 -0
- package/lib/types/__tests__/web-rtc-client.test.d.ts +2 -0
- package/lib/types/__tests__/web-rtc-client.test.d.ts.map +1 -0
- package/lib/types/api/agentd.d.ts +17 -0
- package/lib/types/api/agentd.d.ts.map +1 -0
- package/lib/types/api/amid.d.ts +8 -0
- package/lib/types/api/amid.d.ts.map +1 -0
- package/lib/types/api/application.d.ts +34 -0
- package/lib/types/api/application.d.ts.map +1 -0
- package/lib/types/api/auth.d.ts +64 -0
- package/lib/types/api/auth.d.ts.map +1 -0
- package/lib/types/api/call-logd.d.ts +12 -0
- package/lib/types/api/call-logd.d.ts.map +1 -0
- package/lib/types/api/calld.d.ts +51 -0
- package/lib/types/api/calld.d.ts.map +1 -0
- package/lib/types/api/chatd.d.ts +42 -0
- package/lib/types/api/chatd.d.ts.map +1 -0
- package/lib/types/api/confd.d.ts +39 -0
- package/lib/types/api/confd.d.ts.map +1 -0
- package/lib/types/api/ctid-ng.d.ts +36 -0
- package/lib/types/api/ctid-ng.d.ts.map +1 -0
- package/lib/types/api/dird.d.ts +38 -0
- package/lib/types/api/dird.d.ts.map +1 -0
- package/lib/types/api/webhookd.d.ts +24 -0
- package/lib/types/api/webhookd.d.ts.map +1 -0
- package/lib/types/api-client.d.ts +63 -0
- package/lib/types/api-client.d.ts.map +1 -0
- package/lib/types/checker/Checker.d.ts +13 -0
- package/lib/types/checker/Checker.d.ts.map +1 -0
- package/lib/types/checker/checks/aor.d.ts +6 -0
- package/lib/types/checker/checks/aor.d.ts.map +1 -0
- package/lib/types/checker/checks/api.d.ts +6 -0
- package/lib/types/checker/checks/api.d.ts.map +1 -0
- package/lib/types/checker/checks/ice-ipv4.d.ts +6 -0
- package/lib/types/checker/checks/ice-ipv4.d.ts.map +1 -0
- package/lib/types/checker/checks/index.d.ts +9 -0
- package/lib/types/checker/checks/index.d.ts.map +1 -0
- package/lib/types/checker/checks/symmetric-nat.d.ts +6 -0
- package/lib/types/checker/checks/symmetric-nat.d.ts.map +1 -0
- package/lib/types/checker/checks/wazo-websocket.d.ts +6 -0
- package/lib/types/checker/checks/wazo-websocket.d.ts.map +1 -0
- package/lib/types/checker/checks/webrtc-transport.d.ts +7 -0
- package/lib/types/checker/checks/webrtc-transport.d.ts.map +1 -0
- package/lib/types/checker/checks/webrtc.d.ts +6 -0
- package/lib/types/checker/checks/webrtc.d.ts.map +1 -0
- package/lib/types/domain/AdHocAPIConference.d.ts +54 -0
- package/lib/types/domain/AdHocAPIConference.d.ts.map +1 -0
- package/lib/types/domain/Agent.d.ts +31 -0
- package/lib/types/domain/Agent.d.ts.map +1 -0
- package/lib/types/domain/BadResponse.d.ts +11 -0
- package/lib/types/domain/BadResponse.d.ts.map +1 -0
- package/lib/types/domain/Call.d.ts +79 -0
- package/lib/types/domain/Call.d.ts.map +1 -0
- package/lib/types/domain/CallLog.d.ts +91 -0
- package/lib/types/domain/CallLog.d.ts.map +1 -0
- package/lib/types/domain/CallSession.d.ts +120 -0
- package/lib/types/domain/CallSession.d.ts.map +1 -0
- package/lib/types/domain/ChatMessage.d.ts +41 -0
- package/lib/types/domain/ChatMessage.d.ts.map +1 -0
- package/lib/types/domain/ChatRoom.d.ts +22 -0
- package/lib/types/domain/ChatRoom.d.ts.map +1 -0
- package/lib/types/domain/Contact.d.ts +316 -0
- package/lib/types/domain/Contact.d.ts.map +1 -0
- package/lib/types/domain/Country.d.ts +20 -0
- package/lib/types/domain/Country.d.ts.map +1 -0
- package/lib/types/domain/Device/DebugDevice.d.ts +14 -0
- package/lib/types/domain/Device/DebugDevice.d.ts.map +1 -0
- package/lib/types/domain/Device/Device.d.ts +13 -0
- package/lib/types/domain/Device/Device.d.ts.map +1 -0
- package/lib/types/domain/DirectorySource.d.ts +13 -0
- package/lib/types/domain/DirectorySource.d.ts.map +1 -0
- package/lib/types/domain/ExternalApp.d.ts +22 -0
- package/lib/types/domain/ExternalApp.d.ts.map +1 -0
- package/lib/types/domain/Features.d.ts +24 -0
- package/lib/types/domain/Features.d.ts.map +1 -0
- package/lib/types/domain/ForwardOption.d.ts +27 -0
- package/lib/types/domain/ForwardOption.d.ts.map +1 -0
- package/lib/types/domain/IndirectTransfer.d.ts +31 -0
- package/lib/types/domain/IndirectTransfer.d.ts.map +1 -0
- package/lib/types/domain/Line.d.ts +46 -0
- package/lib/types/domain/Line.d.ts.map +1 -0
- package/lib/types/domain/Meeting.d.ts +45 -0
- package/lib/types/domain/Meeting.d.ts.map +1 -0
- package/lib/types/domain/MeetingAuthorization.d.ts +26 -0
- package/lib/types/domain/MeetingAuthorization.d.ts.map +1 -0
- package/lib/types/domain/MeetingStatus.d.ts +10 -0
- package/lib/types/domain/MeetingStatus.d.ts.map +1 -0
- package/lib/types/domain/NotificationOptions.d.ts +22 -0
- package/lib/types/domain/NotificationOptions.d.ts.map +1 -0
- package/lib/types/domain/Phone/CTIPhone.d.ts +76 -0
- package/lib/types/domain/Phone/CTIPhone.d.ts.map +1 -0
- package/lib/types/domain/Phone/Phone.d.ts +71 -0
- package/lib/types/domain/Phone/Phone.d.ts.map +1 -0
- package/lib/types/domain/Phone/WebRTCPhone.d.ts +179 -0
- package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -0
- package/lib/types/domain/Profile.d.ts +151 -0
- package/lib/types/domain/Profile.d.ts.map +1 -0
- package/lib/types/domain/Recording.d.ts +26 -0
- package/lib/types/domain/Recording.d.ts.map +1 -0
- package/lib/types/domain/Relocation.d.ts +23 -0
- package/lib/types/domain/Relocation.d.ts.map +1 -0
- package/lib/types/domain/Room.d.ts +35 -0
- package/lib/types/domain/Room.d.ts.map +1 -0
- package/lib/types/domain/SFUNotAvailableError.d.ts +4 -0
- package/lib/types/domain/SFUNotAvailableError.d.ts.map +1 -0
- package/lib/types/domain/ServerError.d.ts +6 -0
- package/lib/types/domain/ServerError.d.ts.map +1 -0
- package/lib/types/domain/Session.d.ts +90 -0
- package/lib/types/domain/Session.d.ts.map +1 -0
- package/lib/types/domain/SipLine.d.ts +54 -0
- package/lib/types/domain/SipLine.d.ts.map +1 -0
- package/lib/types/domain/Subscription.d.ts +43 -0
- package/lib/types/domain/Subscription.d.ts.map +1 -0
- package/lib/types/domain/SwitchboardCall.d.ts +62 -0
- package/lib/types/domain/SwitchboardCall.d.ts.map +1 -0
- package/lib/types/domain/Voicemail.d.ts +50 -0
- package/lib/types/domain/Voicemail.d.ts.map +1 -0
- package/lib/types/domain/__tests__/Agent.test.d.ts +2 -0
- package/lib/types/domain/__tests__/Agent.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/Call.test.d.ts +2 -0
- package/lib/types/domain/__tests__/Call.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/CallLog.test.d.ts +2 -0
- package/lib/types/domain/__tests__/CallLog.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/CallSession.test.d.ts +2 -0
- package/lib/types/domain/__tests__/CallSession.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/Contact.test.d.ts +2 -0
- package/lib/types/domain/__tests__/Contact.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/IndirectTransfer.test.d.ts +2 -0
- package/lib/types/domain/__tests__/IndirectTransfer.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/Line.test.d.ts +2 -0
- package/lib/types/domain/__tests__/Line.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/Meeting.test.d.ts +2 -0
- package/lib/types/domain/__tests__/Meeting.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/MeetingAuthorization.test.d.ts +2 -0
- package/lib/types/domain/__tests__/MeetingAuthorization.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/Profile.test.d.ts +2 -0
- package/lib/types/domain/__tests__/Profile.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/Room.test.d.ts +2 -0
- package/lib/types/domain/__tests__/Room.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/Session.test.d.ts +2 -0
- package/lib/types/domain/__tests__/Session.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/SipLine.test.d.ts +2 -0
- package/lib/types/domain/__tests__/SipLine.test.d.ts.map +1 -0
- package/lib/types/domain/__tests__/Voicemail.test.d.ts +2 -0
- package/lib/types/domain/__tests__/Voicemail.test.d.ts.map +1 -0
- package/lib/types/domain/types.d.ts +217 -0
- package/lib/types/domain/types.d.ts.map +1 -0
- package/lib/types/index.d.ts +304 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/lib/WazoSessionDescriptionHandler.d.ts +30 -0
- package/lib/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -0
- package/lib/types/pubkey.d.ts +3 -0
- package/lib/types/pubkey.d.ts.map +1 -0
- package/lib/types/service/CallApi.d.ts +28 -0
- package/lib/types/service/CallApi.d.ts.map +1 -0
- package/lib/types/service/IssueReporter.d.ts +40 -0
- package/lib/types/service/IssueReporter.d.ts.map +1 -0
- package/lib/types/service/__tests__/IssueReporter.test.d.ts +2 -0
- package/lib/types/service/__tests__/IssueReporter.test.d.ts.map +1 -0
- package/lib/types/service/getApiClient.d.ts +16 -0
- package/lib/types/service/getApiClient.d.ts.map +1 -0
- package/lib/types/simple/Auth.d.ts +51 -0
- package/lib/types/simple/Auth.d.ts.map +1 -0
- package/lib/types/simple/Configuration.d.ts +3 -0
- package/lib/types/simple/Configuration.d.ts.map +1 -0
- package/lib/types/simple/Directory.d.ts +3 -0
- package/lib/types/simple/Directory.d.ts.map +1 -0
- package/lib/types/simple/Phone.d.ts +115 -0
- package/lib/types/simple/Phone.d.ts.map +1 -0
- package/lib/types/simple/Websocket.d.ts +19 -0
- package/lib/types/simple/Websocket.d.ts.map +1 -0
- package/lib/types/simple/index.d.ts +147 -0
- package/lib/types/simple/index.d.ts.map +1 -0
- package/lib/types/simple/room/LocalParticipant.d.ts +5 -0
- package/lib/types/simple/room/LocalParticipant.d.ts.map +1 -0
- package/lib/types/simple/room/Participant.d.ts +76 -0
- package/lib/types/simple/room/Participant.d.ts.map +1 -0
- package/lib/types/simple/room/RemoteParticipant.d.ts +7 -0
- package/lib/types/simple/room/RemoteParticipant.d.ts.map +1 -0
- package/lib/types/simple/room/Room.d.ts +116 -0
- package/lib/types/simple/room/Room.d.ts.map +1 -0
- package/lib/types/simple/room/SipRoom.d.ts +14 -0
- package/lib/types/simple/room/SipRoom.d.ts.map +1 -0
- package/lib/types/simple/room/Stream.d.ts +13 -0
- package/lib/types/simple/room/Stream.d.ts.map +1 -0
- package/lib/types/simple/room/__tests__/Participant.test.d.ts +2 -0
- package/lib/types/simple/room/__tests__/Participant.test.d.ts.map +1 -0
- package/lib/types/simple/room/__tests__/RemoteParticipant.test.d.ts +2 -0
- package/lib/types/simple/room/__tests__/RemoteParticipant.test.d.ts.map +1 -0
- package/lib/types/simple/utils.d.ts +3 -0
- package/lib/types/simple/utils.d.ts.map +1 -0
- package/lib/types/types/WebSocketMessage.d.ts +285 -0
- package/lib/types/types/WebSocketMessage.d.ts.map +1 -0
- package/lib/types/utils/Emitter.d.ts +18 -0
- package/lib/types/utils/Emitter.d.ts.map +1 -0
- package/lib/types/utils/Heartbeat.d.ts +21 -0
- package/lib/types/utils/Heartbeat.d.ts.map +1 -0
- package/lib/types/utils/PhoneNumberUtil.d.ts +8 -0
- package/lib/types/utils/PhoneNumberUtil.d.ts.map +1 -0
- package/lib/types/utils/__tests__/Heartbeat.test.d.ts +2 -0
- package/lib/types/utils/__tests__/Heartbeat.test.d.ts.map +1 -0
- package/lib/types/utils/__tests__/PhoneNumberUtil.test.d.ts +2 -0
- package/lib/types/utils/__tests__/PhoneNumberUtil.test.d.ts.map +1 -0
- package/lib/types/utils/__tests__/api-requester.test.d.ts +2 -0
- package/lib/types/utils/__tests__/api-requester.test.d.ts.map +1 -0
- package/lib/types/utils/__tests__/array.test.d.ts +2 -0
- package/lib/types/utils/__tests__/array.test.d.ts.map +1 -0
- package/lib/types/utils/__tests__/compare-version.test.d.ts +2 -0
- package/lib/types/utils/__tests__/compare-version.test.d.ts.map +1 -0
- package/lib/types/utils/__tests__/object.test.d.ts +2 -0
- package/lib/types/utils/__tests__/object.test.d.ts.map +1 -0
- package/lib/types/utils/__tests__/sdp.test.d.ts +2 -0
- package/lib/types/utils/__tests__/sdp.test.d.ts.map +1 -0
- package/lib/types/utils/__tests__/string.test.d.ts +2 -0
- package/lib/types/utils/__tests__/string.test.d.ts.map +1 -0
- package/lib/types/utils/api-requester.d.ts +45 -0
- package/lib/types/utils/api-requester.d.ts.map +1 -0
- package/lib/types/utils/array.d.ts +2 -0
- package/lib/types/utils/array.d.ts.map +1 -0
- package/lib/types/utils/compare-version.d.ts +3 -0
- package/lib/types/utils/compare-version.d.ts.map +1 -0
- package/lib/types/utils/isMobile.d.ts +3 -0
- package/lib/types/utils/isMobile.d.ts.map +1 -0
- package/lib/types/utils/new-from.d.ts +3 -0
- package/lib/types/utils/new-from.d.ts.map +1 -0
- package/lib/types/utils/object.d.ts +2 -0
- package/lib/types/utils/object.d.ts.map +1 -0
- package/lib/types/utils/once.d.ts +2 -0
- package/lib/types/utils/once.d.ts.map +1 -0
- package/lib/types/utils/sdp.d.ts +13 -0
- package/lib/types/utils/sdp.d.ts.map +1 -0
- package/lib/types/utils/string.d.ts +2 -0
- package/lib/types/utils/string.d.ts.map +1 -0
- package/lib/types/utils/update-from.d.ts +3 -0
- package/lib/types/utils/update-from.d.ts.map +1 -0
- package/lib/types/utils/webrtc.d.ts +15 -0
- package/lib/types/utils/webrtc.d.ts.map +1 -0
- package/lib/types/web-rtc-client.d.ts +211 -0
- package/lib/types/web-rtc-client.d.ts.map +1 -0
- package/lib/types/websocket-client.d.ts +134 -0
- package/lib/types/websocket-client.d.ts.map +1 -0
- package/lib/utils/Emitter.js +22 -33
- package/lib/utils/Heartbeat.js +54 -86
- package/lib/utils/PhoneNumberUtil.js +60 -77
- package/lib/utils/__tests__/Heartbeat.test.js +73 -170
- package/lib/utils/__tests__/PhoneNumberUtil.test.js +57 -131
- package/lib/utils/__tests__/api-requester.test.js +139 -784
- package/lib/utils/__tests__/array.test.js +18 -21
- package/lib/utils/__tests__/compare-version.test.js +12 -27
- package/lib/utils/__tests__/object.test.js +75 -56
- package/lib/utils/__tests__/sdp.test.js +99 -220
- package/lib/utils/__tests__/string.test.js +23 -29
- package/lib/utils/api-requester.js +191 -685
- package/lib/utils/array.js +10 -14
- package/lib/utils/compare-version.js +15 -18
- package/lib/utils/isMobile.js +3 -5
- package/lib/utils/new-from.js +9 -14
- package/lib/utils/object.js +12 -26
- package/lib/utils/once.js +15 -15
- package/lib/utils/sdp.js +97 -150
- package/lib/utils/string.js +8 -12
- package/lib/utils/update-from.js +11 -18
- package/lib/utils/webrtc.js +38 -39
- package/lib/web-rtc-client.js +1999 -7698
- package/lib/websocket-client.js +357 -1021
- package/package.json +40 -34
- package/src/__tests__/{api-client.test.js → api-client.test.ts} +71 -29
- package/src/__tests__/{web-rtc-client.test.js → web-rtc-client.test.ts} +95 -35
- package/src/api/agentd.ts +37 -0
- package/src/api/amid.ts +16 -0
- package/src/api/application.ts +96 -0
- package/src/api/auth.ts +259 -0
- package/src/api/call-logd.ts +38 -0
- package/src/api/calld.ts +183 -0
- package/src/api/chatd.ts +83 -0
- package/src/api/confd.ts +110 -0
- package/src/api/ctid-ng.ts +152 -0
- package/src/api/dird.ts +146 -0
- package/src/api/webhookd.ts +30 -0
- package/src/{api-client.js → api-client.ts} +99 -65
- package/src/checker/{Checker.js → Checker.ts} +27 -20
- package/src/checker/checks/{aor.js → aor.ts} +10 -6
- package/src/checker/checks/{api.js → api.ts} +18 -17
- package/src/checker/checks/{ice-ipv4.js → ice-ipv4.ts} +23 -26
- package/src/checker/checks/{index.js → index.ts} +1 -9
- package/src/checker/checks/{symmetric-nat.js → symmetric-nat.ts} +14 -15
- package/src/checker/checks/{wazo-websocket.js → wazo-websocket.ts} +7 -5
- package/src/checker/checks/{webrtc-transport.js → webrtc-transport.ts} +3 -2
- package/src/checker/checks/{webrtc.js → webrtc.ts} +3 -4
- package/src/domain/{AdHocAPIConference.js → AdHocAPIConference.ts} +38 -54
- package/src/domain/{Agent.js → Agent.ts} +11 -7
- package/src/domain/BadResponse.ts +29 -0
- package/src/domain/{Call.js → Call.ts} +62 -46
- package/src/domain/{CallLog.js → CallLog.ts} +61 -63
- package/src/domain/{CallSession.js → CallSession.ts} +55 -52
- package/src/domain/{ChatMessage.js → ChatMessage.ts} +32 -21
- package/src/domain/{ChatRoom.js → ChatRoom.ts} +15 -11
- package/src/domain/{Contact.js → Contact.ts} +373 -261
- package/src/domain/{Country.js → Country.ts} +0 -0
- package/src/domain/Device/{DebugDevice.js → DebugDevice.ts} +3 -5
- package/src/domain/Device/{Device.js → Device.ts} +0 -11
- package/src/domain/DirectorySource.ts +13 -0
- package/src/domain/{ExternalApp.js → ExternalApp.ts} +14 -13
- package/src/domain/{Features.js → Features.ts} +43 -17
- package/src/domain/{ForwardOption.js → ForwardOption.ts} +16 -16
- package/src/domain/{IndirectTransfer.js → IndirectTransfer.ts} +21 -19
- package/src/domain/{Line.js → Line.ts} +39 -26
- package/src/domain/{Meeting.js → Meeting.ts} +36 -29
- package/src/domain/{MeetingAuthorization.js → MeetingAuthorization.ts} +13 -12
- package/src/domain/{MeetingStatus.js → MeetingStatus.ts} +2 -6
- package/src/domain/{NotificationOptions.js → NotificationOptions.ts} +14 -13
- package/src/domain/Phone/{CTIPhone.js → CTIPhone.ts} +90 -60
- package/src/domain/Phone/{Phone.js → Phone.ts} +27 -72
- package/src/domain/Phone/{WebRTCPhone.js → WebRTCPhone.ts} +434 -413
- package/src/domain/{Profile.js → Profile.ts} +117 -100
- package/src/domain/{Recording.js → Recording.ts} +25 -16
- package/src/domain/{Relocation.js → Relocation.ts} +15 -14
- package/src/domain/{Room.js → Room.ts} +58 -27
- package/src/domain/{SFUNotAvailableError.js → SFUNotAvailableError.ts} +2 -2
- package/src/domain/ServerError.ts +12 -0
- package/src/domain/{Session.js → Session.ts} +89 -67
- package/src/domain/{SipLine.js → SipLine.ts} +52 -45
- package/src/domain/{Subscription.js → Subscription.ts} +22 -13
- package/src/domain/{SwitchboardCall.js → SwitchboardCall.ts} +48 -43
- package/src/domain/{Voicemail.js → Voicemail.ts} +38 -34
- package/src/domain/__tests__/{Agent.test.js → Agent.test.ts} +11 -19
- package/src/domain/__tests__/{Call.test.js → Call.test.ts} +12 -9
- package/src/domain/__tests__/CallLog.test.ts +65 -0
- package/src/domain/__tests__/{CallSession.test.js → CallSession.test.ts} +15 -19
- package/src/domain/__tests__/Contact.test.ts +238 -0
- package/src/domain/__tests__/{IndirectTransfer.test.js → IndirectTransfer.test.ts} +38 -31
- package/src/domain/__tests__/Line.test.ts +53 -0
- package/src/domain/__tests__/{Meeting.test.js → Meeting.test.ts} +12 -38
- package/src/domain/__tests__/{MeetingAuthorization.test.js → MeetingAuthorization.test.ts} +13 -21
- package/src/domain/__tests__/Profile.test.ts +139 -0
- package/src/domain/__tests__/{Room.test.js → Room.test.ts} +114 -76
- package/src/domain/__tests__/{Session.test.js → Session.test.ts} +137 -162
- package/src/domain/__tests__/{SipLine.test.js → SipLine.test.ts} +7 -3
- package/src/domain/__tests__/{Voicemail.test.js → Voicemail.test.ts} +26 -20
- package/src/domain/types.ts +227 -0
- package/src/global.d.ts +5 -0
- package/src/{index.js → index.ts} +4 -28
- package/src/lib/WazoSessionDescriptionHandler.ts +534 -0
- package/{config.js → src/pubkey.ts} +3 -3
- package/src/service/{CallApi.js → CallApi.ts} +14 -18
- package/src/service/{IssueReporter.js → IssueReporter.ts} +105 -56
- package/src/service/__tests__/{IssueReporter.test.js → IssueReporter.test.ts} +27 -23
- package/src/service/getApiClient.ts +94 -0
- package/src/simple/{Auth.js → Auth.ts} +127 -100
- package/src/simple/{Configuration.js → Configuration.ts} +2 -3
- package/src/simple/{Directory.js → Directory.ts} +2 -3
- package/src/simple/Phone.ts +623 -0
- package/src/simple/Websocket.ts +119 -0
- package/src/simple/{index.js → index.ts} +51 -21
- package/src/simple/room/{LocalParticipant.js → LocalParticipant.ts} +1 -3
- package/src/simple/room/{Participant.js → Participant.ts} +108 -46
- package/src/simple/room/{RemoteParticipant.js → RemoteParticipant.ts} +5 -4
- package/src/simple/room/{Room.js → Room.ts} +266 -183
- package/src/simple/room/{SipRoom.js → SipRoom.ts} +46 -29
- package/src/simple/room/{Stream.js → Stream.ts} +8 -6
- package/src/simple/room/__tests__/{Participant.test.js → Participant.test.ts} +9 -15
- package/src/simple/room/__tests__/{RemoteParticipant.test.js → RemoteParticipant.test.ts} +5 -1
- package/src/simple/utils.ts +12 -0
- package/src/types/WebSocketMessage.ts +335 -0
- package/src/types/global.d.ts +26 -0
- package/src/utils/Emitter.ts +34 -0
- package/src/utils/{Heartbeat.js → Heartbeat.ts} +17 -11
- package/src/utils/{PhoneNumberUtil.js → PhoneNumberUtil.ts} +12 -18
- package/src/utils/__tests__/{Heartbeat.test.js → Heartbeat.test.ts} +0 -15
- package/src/utils/__tests__/{PhoneNumberUtil.test.js → PhoneNumberUtil.test.ts} +6 -4
- package/src/utils/__tests__/{api-requester.test.js → api-requester.test.ts} +75 -24
- package/src/utils/__tests__/{array.test.js → array.test.ts} +10 -2
- package/src/utils/__tests__/{compare-version.test.js → compare-version.test.ts} +0 -0
- package/src/utils/__tests__/object.test.ts +77 -0
- package/src/utils/__tests__/{sdp.test.js → sdp.test.ts} +15 -37
- package/src/utils/__tests__/{string.test.js → string.test.ts} +4 -2
- package/src/utils/{api-requester.js → api-requester.ts} +104 -83
- package/src/utils/{array.js → array.ts} +2 -2
- package/src/utils/{compare-version.js → compare-version.ts} +3 -2
- package/src/utils/{isMobile.js → isMobile.ts} +1 -1
- package/src/utils/{new-from.js → new-from.ts} +3 -6
- package/src/utils/{object.js → object.ts} +3 -6
- package/src/utils/{once.js → once.ts} +5 -5
- package/src/utils/sdp.ts +119 -0
- package/src/utils/{string.js → string.ts} +2 -3
- package/src/utils/update-from.ts +11 -0
- package/src/utils/{webrtc.js → webrtc.ts} +21 -3
- package/src/{web-rtc-client.js → web-rtc-client.ts} +786 -459
- package/src/{websocket-client.js → websocket-client.ts} +146 -144
- package/esm/simple/Softphone.js +0 -394
- package/lib/simple/Softphone.js +0 -396
- package/src/api/agentd.js +0 -74
- package/src/api/amid.js +0 -13
- package/src/api/application.js +0 -137
- package/src/api/auth.js +0 -279
- package/src/api/call-logd.js +0 -20
- package/src/api/calld.js +0 -214
- package/src/api/chatd.js +0 -80
- package/src/api/confd.js +0 -127
- package/src/api/ctid-ng.js +0 -153
- package/src/api/dird.js +0 -159
- package/src/api/webhookd.js +0 -31
- package/src/domain/BadResponse.js +0 -42
- package/src/domain/DirectorySource.js +0 -16
- package/src/domain/ServerError.js +0 -18
- package/src/domain/__tests__/CallLog.test.js +0 -75
- package/src/domain/__tests__/Contact.test.js +0 -170
- package/src/domain/__tests__/Line.test.js +0 -73
- package/src/domain/__tests__/Profile.test.js +0 -104
- package/src/domain/types.js +0 -248
- package/src/lib/WazoSessionDescriptionHandler.js +0 -467
- package/src/service/getApiClient.js +0 -122
- package/src/simple/Phone.js +0 -425
- package/src/simple/Softphone.js +0 -392
- package/src/simple/Websocket.js +0 -86
- package/src/simple/utils.js +0 -17
- package/src/types/WebSocketMessage.js +0 -232
- package/src/utils/Emitter.js +0 -26
- package/src/utils/__tests__/object.test.js +0 -35
- package/src/utils/sdp.js +0 -140
- package/src/utils/update-from.js +0 -15
|
@@ -1,2733 +1,1464 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
require('sip.js/lib/api/user-agent-state');
|
|
10
|
-
require('sip.js/lib/core/messages/parser');
|
|
11
|
-
require('sip.js/lib/core/messages/methods/constants');
|
|
12
|
-
require('sip.js/lib/grammar/uri');
|
|
13
|
-
require('sip.js/lib/api/user-agent');
|
|
14
|
-
require('sip.js/lib/platform/web/modifiers/modifiers');
|
|
15
|
-
require('sip.js/lib/api/registerer');
|
|
16
|
-
require('sip.js/lib/api/inviter');
|
|
17
|
-
require('sip.js/lib/api/messager');
|
|
18
|
-
require('sip.js/lib/api/registerer-state');
|
|
19
|
-
require('sip.js/lib/api/transport-state');
|
|
20
|
-
require('sip.js/lib/platform/web/session-description-handler/peer-connection-configuration-default');
|
|
21
|
-
require('getstats');
|
|
22
|
-
var EventEmitter = require('events');
|
|
23
|
-
require('sip.js/lib/platform/web/session-description-handler/session-description-handler');
|
|
24
|
-
require('sip.js/lib/platform/web/session-description-handler/session-description-handler-options');
|
|
25
|
-
require('js-base64');
|
|
26
|
-
require('sdp-transform');
|
|
27
|
-
var jsrsasign = require('jsrsasign');
|
|
28
|
-
require('json-to-graphql-query/lib/jsonToGraphQLQuery');
|
|
29
|
-
|
|
30
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
31
|
-
|
|
32
|
-
var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
|
|
33
|
-
var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
|
|
34
|
-
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
var newFrom = (instance , ToClass ) => {
|
|
38
|
-
const args = {};
|
|
39
|
-
Object.getOwnPropertyNames(instance).forEach(prop => {
|
|
40
|
-
args[prop] = instance[prop];
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
return new ToClass(args);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
/* eslint-disable no-param-reassign */
|
|
48
|
-
|
|
49
|
-
var updateFrom = (instance , from ) => {
|
|
50
|
-
Object.keys(from).forEach(key => {
|
|
51
|
-
// $FlowFixMe
|
|
52
|
-
if (
|
|
53
|
-
(!instance[key] && from[key])
|
|
54
|
-
|| (typeof instance[key] !== 'undefined' && typeof from[key] !== 'undefined' && instance[key] !== from[key])
|
|
55
|
-
) {
|
|
56
|
-
// $FlowFixMe
|
|
57
|
-
instance[key] = from[key];
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
class CallSession {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
// Wazo's callId, like `1594062407.xxxx`
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// Used to retrieve the real callee when doing indirect transfer
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
// = creationTime
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// Should be computed ?
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
// Asterisk callId, like `7aed6793-4405-466d-873e-92d21c2fef9f`
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
constructor({
|
|
162
|
-
answered,
|
|
163
|
-
answeredBySystem,
|
|
164
|
-
isCaller,
|
|
165
|
-
displayName,
|
|
166
|
-
callId,
|
|
167
|
-
muted,
|
|
168
|
-
videoMuted,
|
|
169
|
-
number,
|
|
170
|
-
paused,
|
|
171
|
-
ringing,
|
|
172
|
-
startTime,
|
|
173
|
-
creationTime,
|
|
174
|
-
endTime,
|
|
175
|
-
cameraEnabled,
|
|
176
|
-
dialedExtension,
|
|
177
|
-
sipCallId,
|
|
178
|
-
sipStatus,
|
|
179
|
-
callerNumber,
|
|
180
|
-
call,
|
|
181
|
-
autoAnswer,
|
|
182
|
-
ignored,
|
|
183
|
-
screensharing,
|
|
184
|
-
recording,
|
|
185
|
-
recordingPaused,
|
|
186
|
-
videoRemotelyDowngraded,
|
|
187
|
-
sipSession,
|
|
188
|
-
answerTime,
|
|
189
|
-
conference,
|
|
190
|
-
} ) {
|
|
191
|
-
this.callId = callId;
|
|
192
|
-
this.sipCallId = sipCallId;
|
|
193
|
-
this.displayName = displayName;
|
|
194
|
-
this.number = number;
|
|
195
|
-
this.creationTime = creationTime;
|
|
196
|
-
this.startTime = startTime;
|
|
197
|
-
this.endTime = endTime;
|
|
198
|
-
this.isCaller = isCaller;
|
|
199
|
-
this.answered = answered;
|
|
200
|
-
this.answeredBySystem = answeredBySystem;
|
|
201
|
-
this.ringing = ringing;
|
|
202
|
-
this.paused = paused;
|
|
203
|
-
this.muted = muted;
|
|
204
|
-
this.videoMuted = videoMuted;
|
|
205
|
-
this.callerNumber = callerNumber;
|
|
206
|
-
this.cameraEnabled = cameraEnabled;
|
|
207
|
-
this.dialedExtension = dialedExtension || '';
|
|
208
|
-
this.call = call;
|
|
209
|
-
this.sipStatus = sipStatus;
|
|
210
|
-
this.autoAnswer = autoAnswer || false;
|
|
211
|
-
this.ignored = ignored || false;
|
|
212
|
-
this.screensharing = screensharing || false;
|
|
213
|
-
this.recording = recording || false;
|
|
214
|
-
this.recordingPaused = recordingPaused || false;
|
|
215
|
-
this.videoRemotelyDowngraded = videoRemotelyDowngraded;
|
|
216
|
-
this.sipSession = sipSession;
|
|
217
|
-
this.answerTime = answerTime || this.answerTime;
|
|
218
|
-
this.conference = conference;
|
|
219
|
-
|
|
220
|
-
// Useful to compare instead of instanceof with minified code
|
|
221
|
-
this.type = 'CallSession';
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
resume() {
|
|
225
|
-
this.paused = false;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
hold() {
|
|
229
|
-
this.paused = true;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
mute() {
|
|
233
|
-
this.muted = true;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
unmute() {
|
|
237
|
-
this.muted = false;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
muteVideo() {
|
|
241
|
-
this.videoMuted = true;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
unmuteVideo() {
|
|
245
|
-
this.videoMuted = false;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
answer() {
|
|
249
|
-
this.answerTime = new Date();
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
systemAnswer() {
|
|
253
|
-
this.answeredBySystem = true;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
enableCamera() {
|
|
257
|
-
this.cameraEnabled = true;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
disableCamera() {
|
|
261
|
-
this.cameraEnabled = false;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
ignore() {
|
|
265
|
-
this.ignored = true;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
startScreenSharing() {
|
|
269
|
-
this.screensharing = true;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
stopScreenSharing() {
|
|
273
|
-
this.screensharing = false;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
setIsConference(conference ) {
|
|
277
|
-
this.conference = conference;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
isIncoming() {
|
|
281
|
-
return !this.isCaller && !this.answered;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
isOutgoing() {
|
|
285
|
-
return this.isCaller && !this.answered;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
isActive() {
|
|
289
|
-
return this.answered || this.isOutgoing();
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
isAnswered() {
|
|
293
|
-
return this.answered;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
isAnsweredBySystem() {
|
|
297
|
-
return this.answeredBySystem;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
isRinging() {
|
|
301
|
-
return this.ringing;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
isOnHold() {
|
|
305
|
-
return this.paused;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
isMuted() {
|
|
309
|
-
return this.muted;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
isVideoMuted() {
|
|
313
|
-
return this.videoMuted;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
isCameraEnabled() {
|
|
317
|
-
return this.cameraEnabled;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
isIgnored() {
|
|
321
|
-
return this.ignored;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
isScreenSharing() {
|
|
325
|
-
return this.screensharing;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
isRecording() {
|
|
329
|
-
return this.recording;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
recordingIsPaused() {
|
|
333
|
-
return this.recordingPaused;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
hasAnInitialInterceptionNumber() {
|
|
337
|
-
return this.number.startsWith('*8');
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
isAnInterception() {
|
|
341
|
-
return this.dialedExtension.startsWith('*8');
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
isEstablished() {
|
|
345
|
-
return this.sipStatus === sessionState.SessionState.Established;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
isTerminating() {
|
|
349
|
-
return this.sipStatus === sessionState.SessionState.Terminating;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
isTerminated() {
|
|
353
|
-
return this.sipStatus === sessionState.SessionState.Terminated;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
isConference() {
|
|
357
|
-
return this.conference;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
getElapsedTimeInSeconds() {
|
|
361
|
-
if (!this.startTime) {
|
|
362
|
-
return 0;
|
|
363
|
-
}
|
|
364
|
-
return (Date.now() - this.startTime) / 1000;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
getId() {
|
|
368
|
-
return this.sipCallId || this.callId;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
is(callSession ) {
|
|
372
|
-
if (!callSession) {
|
|
373
|
-
return false;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
return this.isId(callSession.sipCallId) || this.isId(callSession.callId);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
isId(id ) {
|
|
380
|
-
return (
|
|
381
|
-
this.getId() === id || (this.sipCallId && this.sipCallId === id) || (Boolean(this.callId) && this.callId === id)
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
updateFrom(session ) {
|
|
386
|
-
updateFrom(this, session);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
separateDisplayName() {
|
|
390
|
-
const names = this.displayName.split(' ');
|
|
391
|
-
const firstName = names[0];
|
|
392
|
-
const lastName = names.slice(1).join(' ');
|
|
393
|
-
|
|
394
|
-
return { firstName, lastName };
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
getTalkingToIds() {
|
|
398
|
-
return this.call ? this.call.talkingToIds : [];
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
setVideoRemotelyDowngraded(value ) {
|
|
402
|
-
this.videoRemotelyDowngraded = value;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
isVideoRemotelyDowngraded() {
|
|
406
|
-
return this.videoRemotelyDowngraded;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
static newFrom(callSession ) {
|
|
410
|
-
return newFrom(callSession, CallSession);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
|
|
414
|
-
set answered(value ) {
|
|
415
|
-
this.answerTime = value ? this.answerTime || new Date() : null;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
get answered() {
|
|
419
|
-
return !!this.answerTime;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
toJSON() {
|
|
423
|
-
const jsonObj = { ...this };
|
|
424
|
-
// $FlowFixMe
|
|
425
|
-
jsonObj.answered = this.answered;
|
|
426
|
-
|
|
427
|
-
return jsonObj;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
static parseCall(call ) {
|
|
431
|
-
return new CallSession({
|
|
432
|
-
callId: call.id,
|
|
433
|
-
sipCallId: call.sipCallId,
|
|
434
|
-
displayName: call.calleeName || call.calleeNumber,
|
|
435
|
-
number: call.calleeNumber,
|
|
436
|
-
callerNumber: call.callerNumber,
|
|
437
|
-
startTime: +call.startingTime,
|
|
438
|
-
paused: call.isOnHold(),
|
|
439
|
-
isCaller: call.isCaller,
|
|
440
|
-
muted: call.muted,
|
|
441
|
-
videoMuted: false,
|
|
442
|
-
screensharing: false,
|
|
443
|
-
recording: call.isRecording(),
|
|
444
|
-
recordingPaused: false, // @TODO
|
|
445
|
-
ringing: call.isRinging(),
|
|
446
|
-
answered: call.isUp(),
|
|
447
|
-
answeredBySystem: call.isUp() && call.talkingToIds.length === 0,
|
|
448
|
-
cameraEnabled: call.isVideo,
|
|
449
|
-
dialedExtension: call.dialedExtension,
|
|
450
|
-
call,
|
|
451
|
-
conference: false, // @FIXME?
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
452
9
|
});
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
/* */
|
|
457
|
-
/* global navigator */
|
|
458
|
-
const isMobile = () => typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
|
|
459
|
-
|
|
460
|
-
/* */
|
|
461
|
-
|
|
462
|
-
IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
|
|
463
|
-
|
|
464
|
-
// Use a function here to be able to mock it in tests
|
|
465
|
-
const realFetch = () => {
|
|
466
|
-
if (typeof document !== 'undefined' && window.fetch) {
|
|
467
|
-
// Browser
|
|
468
|
-
return window.fetch;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
if (isMobile()) {
|
|
472
|
-
// React native
|
|
473
|
-
return fetch;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// nodejs
|
|
477
|
-
// this package is disable for react-native in package.json because it requires nodejs modules
|
|
478
|
-
// Used to trick the optimizer to avoid requiring `node-fetch/lib/index` directly
|
|
479
|
-
// It causes to require it on browsers when delivered by a nodejs engine (cf: vitejs).
|
|
480
|
-
try {
|
|
481
|
-
// $FlowFixMe
|
|
482
|
-
return require(Math.random() >= 0 ? 'node-fetch/lib/index' : '');
|
|
483
|
-
} catch (e) {
|
|
484
|
-
return fetch;
|
|
485
|
-
}
|
|
486
10
|
};
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
const TRACE = 'trace';
|
|
491
|
-
const DEBUG = 'debug';
|
|
492
|
-
const INFO = 'info';
|
|
493
|
-
const LOG = 'log';
|
|
494
|
-
const WARN = 'warn';
|
|
495
|
-
const ERROR = 'error';
|
|
496
|
-
const CONSOLE_METHODS = [INFO, LOG, WARN, ERROR];
|
|
497
|
-
const LOG_LEVELS = [TRACE, DEBUG, INFO, LOG, WARN, ERROR];
|
|
498
|
-
const CATEGORY_PREFIX = 'logger-category=';
|
|
499
|
-
|
|
500
|
-
const MAX_REMOTE_RETRY = 100;
|
|
501
|
-
|
|
502
|
-
const addLevelsTo = (instance , withMethods = false) => {
|
|
503
|
-
instance.TRACE = TRACE;
|
|
504
|
-
instance.DEBUG = DEBUG;
|
|
505
|
-
instance.INFO = INFO;
|
|
506
|
-
instance.LOG = LOG;
|
|
507
|
-
instance.WARN = WARN;
|
|
508
|
-
instance.ERROR = ERROR;
|
|
509
|
-
|
|
510
|
-
if (withMethods) {
|
|
511
|
-
instance.trace = (...args) => instance.apply(null, [TRACE, ...args]);
|
|
512
|
-
instance.debug = (...args) => instance.apply(null, [DEBUG, ...args]);
|
|
513
|
-
instance.info = (...args) => instance.apply(null, [INFO, ...args]);
|
|
514
|
-
instance.log = (...args) => instance.apply(null, [LOG, ...args]);
|
|
515
|
-
instance.warn = (...args) => instance.apply(null, [WARN, ...args]);
|
|
516
|
-
instance.error = (...args) => instance.apply(null, [ERROR, ...args]);
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
return instance;
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
520
13
|
};
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.events = exports.MESSAGE_TYPE_SIGNAL = exports.MESSAGE_TYPE_CHAT = exports.ON_EARLY_MEDIA = exports.ON_DISCONNECTED = exports.ON_SIGNAL = exports.ON_CHAT = exports.ON_NETWORK_STATS = exports.ON_MESSAGE_TRACK_UPDATED = exports.ON_CALL_ERROR = exports.ON_VIDEO_INPUT_CHANGE = exports.ON_PLAY_PROGRESS_SOUND = exports.ON_PLAY_HANGUP_SOUND = exports.ON_PLAY_INBOUND_CALL_SIGNAL_SOUND = exports.ON_PLAY_RING_SOUND = exports.ON_TERMINATE_SOUND = exports.ON_SHARE_SCREEN_ENDED = exports.ON_SHARE_SCREEN_ENDING = exports.ON_SHARE_SCREEN_STARTED = exports.ON_REMOVE_STREAM = exports.ON_VIDEO_STREAM = exports.ON_AUDIO_STREAM = exports.ON_TRACK = exports.ON_REINVITE = exports.ON_MESSAGE = exports.ON_CALL_ENDING = exports.ON_CALL_ENDED = exports.ON_CALL_REJECTED = exports.ON_CALL_FAILED = exports.ON_CALL_CANCELED = exports.ON_CAMERA_RESUMED = exports.ON_CAMERA_DISABLED = exports.ON_CALL_UNHELD = exports.ON_CALL_HELD = exports.ON_CALL_RESUMED = exports.ON_CALL_UNMUTED = exports.ON_CALL_MUTED = exports.ON_CALL_OUTGOING = exports.ON_CALL_INCOMING = exports.ON_CALL_ANSWERED = exports.ON_CALL_ACCEPTED = exports.ON_PROGRESS = exports.ON_UNREGISTERED = exports.ON_REGISTERED = exports.ON_USER_AGENT = void 0;
|
|
16
|
+
const session_state_1 = require("sip.js/lib/api/session-state");
|
|
17
|
+
const api_1 = require("sip.js/lib/api");
|
|
18
|
+
const CallSession_1 = __importDefault(require("../CallSession"));
|
|
19
|
+
const Emitter_1 = __importDefault(require("../../utils/Emitter"));
|
|
20
|
+
const IssueReporter_1 = __importDefault(require("../../service/IssueReporter"));
|
|
21
|
+
exports.ON_USER_AGENT = 'onUserAgent';
|
|
22
|
+
exports.ON_REGISTERED = 'onRegistered';
|
|
23
|
+
exports.ON_UNREGISTERED = 'onUnRegistered';
|
|
24
|
+
exports.ON_PROGRESS = 'onProgress';
|
|
25
|
+
exports.ON_CALL_ACCEPTED = 'onCallAccepted';
|
|
26
|
+
exports.ON_CALL_ANSWERED = 'onCallAnswered';
|
|
27
|
+
exports.ON_CALL_INCOMING = 'onCallIncoming';
|
|
28
|
+
exports.ON_CALL_OUTGOING = 'onCallOutgoing';
|
|
29
|
+
exports.ON_CALL_MUTED = 'onCallMuted';
|
|
30
|
+
exports.ON_CALL_UNMUTED = 'onCallUnmuted';
|
|
31
|
+
exports.ON_CALL_RESUMED = 'onCallResumed';
|
|
32
|
+
exports.ON_CALL_HELD = 'onCallHeld';
|
|
33
|
+
exports.ON_CALL_UNHELD = 'onCallUnHeld';
|
|
34
|
+
exports.ON_CAMERA_DISABLED = 'onCameraDisabled';
|
|
35
|
+
exports.ON_CAMERA_RESUMED = 'onCameraResumed';
|
|
36
|
+
exports.ON_CALL_CANCELED = 'onCallCanceled';
|
|
37
|
+
exports.ON_CALL_FAILED = 'onCallFailed';
|
|
38
|
+
exports.ON_CALL_REJECTED = 'onCallRejected';
|
|
39
|
+
exports.ON_CALL_ENDED = 'onCallEnded';
|
|
40
|
+
exports.ON_CALL_ENDING = 'onCallEnding';
|
|
41
|
+
exports.ON_MESSAGE = 'onMessage';
|
|
42
|
+
exports.ON_REINVITE = 'reinvite';
|
|
43
|
+
exports.ON_TRACK = 'onTrack';
|
|
44
|
+
exports.ON_AUDIO_STREAM = 'onAudioStream';
|
|
45
|
+
exports.ON_VIDEO_STREAM = 'onVideoStream';
|
|
46
|
+
exports.ON_REMOVE_STREAM = 'onRemoveStream';
|
|
47
|
+
exports.ON_SHARE_SCREEN_STARTED = 'onScreenShareStarted';
|
|
48
|
+
exports.ON_SHARE_SCREEN_ENDING = 'onScreenShareEnding';
|
|
49
|
+
exports.ON_SHARE_SCREEN_ENDED = 'onScreenShareEnded';
|
|
50
|
+
exports.ON_TERMINATE_SOUND = 'terminateSound';
|
|
51
|
+
exports.ON_PLAY_RING_SOUND = 'playRingingSound';
|
|
52
|
+
exports.ON_PLAY_INBOUND_CALL_SIGNAL_SOUND = 'playInboundCallSignalSound';
|
|
53
|
+
exports.ON_PLAY_HANGUP_SOUND = 'playHangupSound';
|
|
54
|
+
exports.ON_PLAY_PROGRESS_SOUND = 'playProgressSound';
|
|
55
|
+
exports.ON_VIDEO_INPUT_CHANGE = 'videoInputChange';
|
|
56
|
+
exports.ON_CALL_ERROR = 'onCallError';
|
|
57
|
+
exports.ON_MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
|
|
58
|
+
exports.ON_NETWORK_STATS = 'onNetworkStats';
|
|
59
|
+
exports.ON_CHAT = 'phone/ON_CHAT';
|
|
60
|
+
exports.ON_SIGNAL = 'phone/ON_SIGNAL';
|
|
61
|
+
exports.ON_DISCONNECTED = 'onDisconnected';
|
|
62
|
+
exports.ON_EARLY_MEDIA = 'onEarlyMedia';
|
|
63
|
+
exports.MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
|
|
64
|
+
exports.MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
|
|
65
|
+
exports.events = [exports.ON_USER_AGENT, exports.ON_REGISTERED, exports.ON_UNREGISTERED, exports.ON_PROGRESS, exports.ON_CALL_ACCEPTED, exports.ON_CALL_ANSWERED, exports.ON_CALL_INCOMING, exports.ON_CALL_OUTGOING, exports.ON_CALL_MUTED, exports.ON_CALL_UNMUTED, exports.ON_CALL_RESUMED, exports.ON_CALL_HELD, exports.ON_CALL_UNHELD, exports.ON_CAMERA_DISABLED, exports.ON_CALL_FAILED, exports.ON_CALL_ENDED, exports.ON_CALL_REJECTED, exports.ON_MESSAGE, exports.ON_REINVITE, exports.ON_TRACK, exports.ON_AUDIO_STREAM, exports.ON_VIDEO_STREAM, exports.ON_REMOVE_STREAM, exports.ON_SHARE_SCREEN_ENDED, exports.ON_TERMINATE_SOUND, exports.ON_PLAY_RING_SOUND, exports.ON_PLAY_INBOUND_CALL_SIGNAL_SOUND, exports.ON_PLAY_HANGUP_SOUND, exports.ON_PLAY_PROGRESS_SOUND, exports.ON_VIDEO_INPUT_CHANGE, exports.ON_SHARE_SCREEN_STARTED, exports.ON_CALL_ERROR, exports.ON_CHAT, exports.ON_SIGNAL, exports.ON_NETWORK_STATS, exports.ON_DISCONNECTED, exports.ON_EARLY_MEDIA];
|
|
66
|
+
const logger = IssueReporter_1.default.loggerFor('webrtc-phone');
|
|
67
|
+
class WebRTCPhone extends Emitter_1.default {
|
|
68
|
+
constructor(client, audioOutputDeviceId, allowVideo = false, audioRingDeviceId) {
|
|
69
|
+
super();
|
|
70
|
+
this.client = client;
|
|
71
|
+
this.allowVideo = allowVideo;
|
|
72
|
+
this.callSessions = {};
|
|
73
|
+
this.audioOutputDeviceId = audioOutputDeviceId;
|
|
74
|
+
this.audioRingDeviceId = audioRingDeviceId || audioOutputDeviceId;
|
|
75
|
+
this.audioOutputVolume = 1;
|
|
76
|
+
this.audioRingVolume = 1;
|
|
77
|
+
this.incomingSessions = [];
|
|
78
|
+
this.ringingEnabled = true;
|
|
79
|
+
this.shouldSendReinvite = false;
|
|
80
|
+
this.bindClientEvents();
|
|
81
|
+
this.acceptedSessions = {};
|
|
82
|
+
this.rejectedSessions = {};
|
|
83
|
+
this.ignoredSessions = {};
|
|
84
|
+
}
|
|
85
|
+
register() {
|
|
86
|
+
if (!this.client) {
|
|
87
|
+
return Promise.resolve();
|
|
88
|
+
}
|
|
89
|
+
return this.client.register().then(() => {
|
|
90
|
+
return this.bindClientEvents();
|
|
91
|
+
}).catch(error => {
|
|
92
|
+
// Avoid exception on `t.server.scheme` in sip transport when losing the webrtc socket connection
|
|
93
|
+
console.error('register error', error, error.message, error.stack);
|
|
94
|
+
logger.error('WebRTC register error', {
|
|
95
|
+
message: error.message,
|
|
96
|
+
stack: error.stack,
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
unregister() {
|
|
101
|
+
if (!this.client || !this.client.isRegistered()) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
return this.client.unregister();
|
|
105
|
+
}
|
|
106
|
+
stop() {
|
|
107
|
+
if (!this.client) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
logger.info('WebRTC phone stop');
|
|
111
|
+
this.client.stop();
|
|
112
|
+
}
|
|
113
|
+
removeIncomingSessions(id) {
|
|
114
|
+
this.incomingSessions = this.incomingSessions.filter(sessionId => sessionId !== id);
|
|
115
|
+
}
|
|
116
|
+
isWebRTC() {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
sendReinvite(callSession, constraints = null, conference = false, audioOnly = false, iceRestart = false) {
|
|
120
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
+
const sipSession = this.findSipSession(callSession);
|
|
122
|
+
logger.info('WebRTC phone - send reinvite', {
|
|
123
|
+
sessionId: sipSession ? sipSession.id : null,
|
|
124
|
+
constraints,
|
|
125
|
+
audioOnly,
|
|
126
|
+
conference,
|
|
127
|
+
iceRestart,
|
|
128
|
+
});
|
|
129
|
+
if (!sipSession) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const shouldScreenShare = constraints === null || constraints === void 0 ? void 0 : constraints.screen;
|
|
133
|
+
const isUpgrade = shouldScreenShare || (constraints === null || constraints === void 0 ? void 0 : constraints.video);
|
|
134
|
+
// Downgrade
|
|
135
|
+
if (constraints && !isUpgrade) {
|
|
136
|
+
// No reinvite needed
|
|
137
|
+
this._downgradeToAudio(callSession);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (isUpgrade) {
|
|
141
|
+
const shouldReinvite = yield this._upgradeToVideo(callSession, constraints, conference);
|
|
142
|
+
if (!shouldReinvite) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return this.client.reinvite(sipSession, constraints, conference, audioOnly, iceRestart);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
getUserAgent() {
|
|
150
|
+
var _a, _b;
|
|
151
|
+
return ((_b = (_a = this.client) === null || _a === void 0 ? void 0 : _a.config) === null || _b === void 0 ? void 0 : _b.userAgentString) || 'webrtc-phone';
|
|
152
|
+
}
|
|
153
|
+
startHeartbeat() {
|
|
154
|
+
logger.info('WebRTC phone - start heartbeat', {
|
|
155
|
+
client: !!this.client,
|
|
156
|
+
hasHeartbeat: this.client.hasHeartbeat(),
|
|
157
|
+
});
|
|
158
|
+
if (!this.client || this.client.hasHeartbeat()) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
this.client.startHeartbeat();
|
|
162
|
+
}
|
|
163
|
+
stopHeartbeat() {
|
|
164
|
+
logger.info('WebRTC phone - stopHeartbeat', {
|
|
165
|
+
client: !!this.client,
|
|
166
|
+
});
|
|
167
|
+
if (!this.client) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.client.stopHeartbeat();
|
|
171
|
+
}
|
|
172
|
+
setOnHeartbeatTimeout(cb) {
|
|
173
|
+
this.client.setOnHeartbeatTimeout(cb);
|
|
174
|
+
}
|
|
175
|
+
setOnHeartbeatCallback(cb) {
|
|
176
|
+
this.client.setOnHeartbeatCallback(cb);
|
|
177
|
+
}
|
|
178
|
+
reconnect() {
|
|
179
|
+
logger.info('WebRTC phone - reconnect', {
|
|
180
|
+
client: !!this.client,
|
|
181
|
+
});
|
|
182
|
+
if (!this.client) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
this.client.attemptReconnection();
|
|
186
|
+
}
|
|
187
|
+
getOptions() {
|
|
188
|
+
return {
|
|
189
|
+
accept: true,
|
|
190
|
+
decline: true,
|
|
191
|
+
mute: true,
|
|
192
|
+
hold: true,
|
|
193
|
+
transfer: true,
|
|
194
|
+
sendKey: true,
|
|
195
|
+
addParticipant: false,
|
|
196
|
+
record: true,
|
|
197
|
+
merge: true,
|
|
623
198
|
};
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
args.splice(1, 1);
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
if (extra.skipSendToRemote) {
|
|
632
|
-
skipSendToRemote = true;
|
|
633
|
-
delete extra.skipSendToRemote;
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
const date = moment__default['default']().format('YYYY-MM-DD HH:mm:ss.SSS');
|
|
637
|
-
const message = args.join(', ');
|
|
638
|
-
let consoleMessage = message;
|
|
639
|
-
|
|
640
|
-
if (Object.keys(extra).length) {
|
|
641
|
-
const parsedExtra = safeStringify(extra);
|
|
642
|
-
consoleMessage = `${consoleMessage} (${parsedExtra})`;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
if (category) {
|
|
646
|
-
consoleMessage = `[${category}] ${consoleMessage}`;
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
// Log the message in the console anyway (but don't console.error on mobile)
|
|
650
|
-
const consoleLevel = isMobile() && level === 'error' ? WARN : level;
|
|
651
|
-
|
|
652
|
-
// eslint-disable-next-line
|
|
653
|
-
const oldMethod = this.oldConsoleMethods[consoleLevel] || this.oldConsoleMethods.log;
|
|
654
|
-
oldMethod.apply(oldMethod, [date, consoleMessage]);
|
|
655
|
-
|
|
656
|
-
if (this._callback) {
|
|
657
|
-
this._callback(level, consoleMessage);
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
if (!skipSendToRemote) {
|
|
661
|
-
this._sendToRemoteLogger(level, { date, message, category, ...extra });
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
logRequest(url , options , response , start ) {
|
|
666
|
-
if (!this.enabled) {
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
const { status } = response;
|
|
670
|
-
const duration = new Date() - start;
|
|
671
|
-
|
|
672
|
-
let level = TRACE;
|
|
673
|
-
if (status >= 400 && status < 500) {
|
|
674
|
-
level = WARN;
|
|
675
|
-
} else if (status >= 500) {
|
|
676
|
-
level = ERROR;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
this.log(level, this._makeCategory('http'), url, {
|
|
680
|
-
status,
|
|
681
|
-
body: this.removeSlashes(JSON.stringify(options.body)),
|
|
682
|
-
method: options.method,
|
|
683
|
-
headers: options.headers,
|
|
684
|
-
duration,
|
|
685
|
-
});
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
// Logs aren't stored anymore
|
|
689
|
-
getLogs() {
|
|
690
|
-
console.warn('IssueReporter\'s logs aren\'t stored anymore. Please use fluentd to store them');
|
|
691
|
-
return [];
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
getParsedLogs() {
|
|
695
|
-
console.warn('IssueReporter\'s logs aren\'t stored anymore. Please use fluentd to store them');
|
|
696
|
-
return [];
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
getReport() {
|
|
700
|
-
return this.getParsedLogs().join('\r\n');
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
_catchConsole() {
|
|
704
|
-
this.oldConsoleMethods = {};
|
|
705
|
-
CONSOLE_METHODS.forEach((methodName ) => {
|
|
706
|
-
// eslint-disable-next-line
|
|
707
|
-
this.oldConsoleMethods[methodName] = console[methodName];
|
|
708
|
-
window.console[methodName] = (...args) => {
|
|
709
|
-
// Store message
|
|
710
|
-
try {
|
|
711
|
-
this.log(methodName, args.join(' '));
|
|
712
|
-
// Use old console method to log it normally
|
|
713
|
-
this.oldConsoleMethods[methodName].apply(null, args);
|
|
714
|
-
} catch (e) {
|
|
715
|
-
// Avoid circular structure issues
|
|
199
|
+
}
|
|
200
|
+
onConnect() {
|
|
201
|
+
if (!this.client) {
|
|
202
|
+
return Promise.reject(new Error('No webrtc client'));
|
|
716
203
|
}
|
|
717
|
-
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
if (!this.remoteClientConfiguration) {
|
|
723
|
-
return;
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
const { level: minLevel, bufferSize } = this.remoteClientConfiguration;
|
|
727
|
-
if (!minLevel || this._isLevelAbove(minLevel, level)) {
|
|
728
|
-
return;
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
payload.level = level;
|
|
732
|
-
|
|
733
|
-
if (bufferSize > 0) {
|
|
734
|
-
return this._addToBuffer(payload);
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
this._sendDebugToGrafana(payload);
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
_parseLoggerBody(payload ) {
|
|
741
|
-
const { level } = payload;
|
|
742
|
-
const { maxMessageSize, extra } = this.remoteClientConfiguration || {};
|
|
743
|
-
|
|
744
|
-
delete payload.level;
|
|
745
|
-
|
|
746
|
-
if (maxMessageSize && typeof payload.message === 'string' && payload.message.length > maxMessageSize) {
|
|
747
|
-
payload.message = `${payload.message.substr(0, maxMessageSize)}...`;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
return safeStringify({
|
|
751
|
-
level,
|
|
752
|
-
...payload,
|
|
753
|
-
...extra,
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
_addToBuffer(payload ) {
|
|
758
|
-
// Reset buffer timer
|
|
759
|
-
if (this.bufferTimeout) {
|
|
760
|
-
clearTimeout(this.bufferTimeout);
|
|
761
|
-
this.bufferTimeout = null;
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
this.buffer.push(payload);
|
|
765
|
-
|
|
766
|
-
// $FlowFixMe
|
|
767
|
-
const { bufferSize, bufferTimeout } = this.remoteClientConfiguration;
|
|
768
|
-
|
|
769
|
-
if (this.buffer.length > bufferSize) {
|
|
770
|
-
return this._processBuffer();
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
if (bufferTimeout > 0) {
|
|
774
|
-
this.bufferTimeout = setTimeout(this._boundProcessBuffer, bufferTimeout);
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
_processBuffer() {
|
|
779
|
-
this._sendDebugToGrafana(this.buffer);
|
|
780
|
-
|
|
781
|
-
this.buffer = [];
|
|
782
|
-
if (this.bufferTimeout) {
|
|
783
|
-
clearTimeout(this.bufferTimeout);
|
|
784
|
-
this.bufferTimeout = null;
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
_sendDebugToGrafana(payload , retry = 0) {
|
|
789
|
-
if (!this.remoteClientConfiguration || retry >= MAX_REMOTE_RETRY) {
|
|
790
|
-
return;
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
const { tag, host, port } = this.remoteClientConfiguration;
|
|
794
|
-
const isArray = Array.isArray(payload);
|
|
795
|
-
const isSecure = +port === 443;
|
|
796
|
-
const url = `http${isSecure ? 's' : ''}://${host}${isSecure ? '' : `:${port}`}/${tag}`;
|
|
797
|
-
const body = isArray ? `[${payload.map(this._boundParseLoggerBody).join(',')}]` : this._parseLoggerBody(payload);
|
|
798
|
-
|
|
799
|
-
realFetch()(url, {
|
|
800
|
-
method: 'POST',
|
|
801
|
-
headers: {
|
|
802
|
-
Accept: 'application/json',
|
|
803
|
-
'Content-Type': 'application/json',
|
|
804
|
-
},
|
|
805
|
-
// $FlowFixMe
|
|
806
|
-
body,
|
|
807
|
-
}).catch((e ) => {
|
|
808
|
-
// $FlowFixMe
|
|
809
|
-
e.skipSendToRemote = true;
|
|
810
|
-
this.log('error', this._makeCategory('grafana'), 'Sending log to grafana, error', e);
|
|
811
|
-
|
|
812
|
-
setTimeout(() => {
|
|
813
|
-
if (isArray) {
|
|
814
|
-
payload = payload.map(message => this._writeRetryCount(message, retry + 1));
|
|
815
|
-
} else if (payload && typeof payload === 'object') {
|
|
816
|
-
payload = this._writeRetryCount(payload, retry + 1);
|
|
204
|
+
return this.client.onConnect();
|
|
205
|
+
}
|
|
206
|
+
onDisconnect() {
|
|
207
|
+
if (!this.client) {
|
|
208
|
+
return Promise.reject(new Error('No webrtc client'));
|
|
817
209
|
}
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
//
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
//
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
const
|
|
941
|
-
|
|
942
|
-
const
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
const
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
const
|
|
958
|
-
const
|
|
959
|
-
const
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
stopHeartbeat() {
|
|
1166
|
-
logger.info('WebRTC phone - stopHeartbeat', { client: !!this.client });
|
|
1167
|
-
if (!this.client) {
|
|
1168
|
-
return;
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
this.client.stopHeartbeat();
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
|
-
setOnHeartbeatTimeout(cb ) {
|
|
1175
|
-
this.client.setOnHeartbeatTimeout(cb);
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
setOnHeartbeatCallback(cb ) {
|
|
1179
|
-
this.client.setOnHeartbeatCallback(cb);
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
|
-
reconnect() {
|
|
1183
|
-
logger.info('WebRTC phone - reconnect', { client: !!this.client });
|
|
1184
|
-
if (!this.client) {
|
|
1185
|
-
return;
|
|
1186
|
-
}
|
|
1187
|
-
this.client.attemptReconnection();
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
getOptions() {
|
|
1191
|
-
return {
|
|
1192
|
-
accept: true,
|
|
1193
|
-
decline: true,
|
|
1194
|
-
mute: true,
|
|
1195
|
-
hold: true,
|
|
1196
|
-
transfer: true,
|
|
1197
|
-
sendKey: true,
|
|
1198
|
-
addParticipant: false,
|
|
1199
|
-
record: true,
|
|
1200
|
-
merge: true,
|
|
1201
|
-
};
|
|
1202
|
-
}
|
|
1203
|
-
|
|
1204
|
-
onConnect() {
|
|
1205
|
-
if (!this.client) {
|
|
1206
|
-
return Promise.reject(new Error('No webrtc client'));
|
|
1207
|
-
}
|
|
1208
|
-
return this.client.onConnect();
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
onDisconnect() {
|
|
1212
|
-
if (!this.client) {
|
|
1213
|
-
return Promise.reject(new Error('No webrtc client'));
|
|
1214
|
-
}
|
|
1215
|
-
return this.client.onDisconnect();
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
_downgradeToAudio(callSession , withMessage = true) {
|
|
1219
|
-
const sipSession = this.findSipSession(callSession);
|
|
1220
|
-
if (!sipSession) {
|
|
1221
|
-
return false;
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
logger.info('Downgrade to video', { id: callSession ? callSession.getId() : null, withMessage });
|
|
1225
|
-
|
|
1226
|
-
this.client.downgradeToAudio(sipSession);
|
|
1227
|
-
|
|
1228
|
-
if (callSession) {
|
|
1229
|
-
callSession.cameraEnabled = false;
|
|
1230
|
-
this._updateCallSession(callSession);
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
if (withMessage) {
|
|
1234
|
-
this._sendReinviteMessage(callSession, false);
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
return true;
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
// Returns true if we need to send a re-INVITE request
|
|
1241
|
-
async _upgradeToVideo(callSession , constraints , isConference ) {
|
|
1242
|
-
const sipSession = this.findSipSession(callSession);
|
|
1243
|
-
if (!sipSession) {
|
|
1244
|
-
return Promise.resolve(false);
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
logger.info('Upgrade to video', {
|
|
1248
|
-
id: callSession ? callSession.getId() : null,
|
|
1249
|
-
constraints,
|
|
1250
|
-
isConference,
|
|
1251
|
-
});
|
|
1252
|
-
|
|
1253
|
-
const shouldScreenShare = constraints && !!constraints.screen;
|
|
1254
|
-
const desktop = constraints && constraints.desktop;
|
|
1255
|
-
const options = sipSession.sessionDescriptionHandlerOptionsReInvite;
|
|
1256
|
-
const wasAudioOnly = options && options.audioOnly;
|
|
1257
|
-
|
|
1258
|
-
const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
|
|
1259
|
-
|
|
1260
|
-
if (callSession) {
|
|
1261
|
-
callSession.cameraEnabled = true;
|
|
1262
|
-
this._updateCallSession(callSession);
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
// If no stream is returned, it means we have to reinvite
|
|
1266
|
-
if (!newStream) {
|
|
1267
|
-
return true;
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
this._sendReinviteMessage(callSession, true);
|
|
1271
|
-
|
|
1272
|
-
if (shouldScreenShare) {
|
|
1273
|
-
this._onScreenSharing(newStream, sipSession, callSession, false, desktop);
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
// We have to reinvite to change the direction on the bundle when upgrading from an audioOnly conference
|
|
1277
|
-
if (isConference && wasAudioOnly) {
|
|
1278
|
-
return true;
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
// No reinvite needed here
|
|
1282
|
-
return false;
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
_sendReinviteMessage(callSession , isUpgrade ) {
|
|
1286
|
-
const sipSession = this.findSipSession(callSession);
|
|
1287
|
-
logger.info('Sending reinvite message', {
|
|
1288
|
-
id: callSession ? callSession.getId() : null,
|
|
1289
|
-
isUpgrade,
|
|
1290
|
-
});
|
|
1291
|
-
|
|
1292
|
-
// Have to send the message after a delay due to latency to update the remote peer
|
|
1293
|
-
setTimeout(() => {
|
|
1294
|
-
this.sendMessage(sipSession, JSON.stringify({
|
|
1295
|
-
type: MESSAGE_TYPE_SIGNAL,
|
|
1296
|
-
content: {
|
|
1297
|
-
type: ON_MESSAGE_TRACK_UPDATED,
|
|
1298
|
-
update: isUpgrade ? 'upgrade' : 'downgrade',
|
|
1299
|
-
sipCallId: this.getSipSessionId(sipSession),
|
|
1300
|
-
callId: callSession ? callSession.callId : null,
|
|
1301
|
-
number: callSession ? callSession.number : null,
|
|
1302
|
-
callerNumber: callSession ? callSession.callerNumber : null,
|
|
1303
|
-
},
|
|
1304
|
-
}));
|
|
1305
|
-
}, 2500);
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
|
-
_bindEvents(sipSession ) {
|
|
1309
|
-
if (sipSession._onCancel) {
|
|
1310
|
-
// Monkey patch to know when canceled with the CANCEL message
|
|
1311
|
-
const onCancel = sipSession._onCancel.bind(sipSession);
|
|
1312
|
-
sipSession._onCancel = (message ) => {
|
|
1313
|
-
logger.trace('on sip session canceled', { callId: message.callId });
|
|
1314
|
-
|
|
1315
|
-
onCancel(message);
|
|
1316
|
-
const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
|
|
210
|
+
return this.client.onDisconnect();
|
|
211
|
+
}
|
|
212
|
+
_downgradeToAudio(callSession, withMessage = true) {
|
|
213
|
+
const sipSession = this.findSipSession(callSession);
|
|
214
|
+
if (!sipSession) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
logger.info('Downgrade to video', {
|
|
218
|
+
id: callSession ? callSession.getId() : null,
|
|
219
|
+
withMessage,
|
|
220
|
+
});
|
|
221
|
+
this.client.downgradeToAudio(sipSession);
|
|
222
|
+
if (callSession) {
|
|
223
|
+
callSession.cameraEnabled = false;
|
|
224
|
+
this._updateCallSession(callSession);
|
|
225
|
+
}
|
|
226
|
+
if (withMessage) {
|
|
227
|
+
this._sendReinviteMessage(callSession, false);
|
|
228
|
+
}
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
// Returns true if we need to send a re-INVITE request
|
|
232
|
+
_upgradeToVideo(callSession, constraints, isConference) {
|
|
233
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
234
|
+
const sipSession = this.findSipSession(callSession);
|
|
235
|
+
if (!sipSession) {
|
|
236
|
+
return Promise.resolve(false);
|
|
237
|
+
}
|
|
238
|
+
logger.info('Upgrade to video', {
|
|
239
|
+
id: callSession ? callSession.getId() : null,
|
|
240
|
+
constraints,
|
|
241
|
+
isConference,
|
|
242
|
+
});
|
|
243
|
+
const shouldScreenShare = constraints && !!constraints.screen;
|
|
244
|
+
const desktop = constraints && constraints.desktop;
|
|
245
|
+
const options = sipSession.sessionDescriptionHandlerOptionsReInvite;
|
|
246
|
+
// @ts-ignore
|
|
247
|
+
const wasAudioOnly = options === null || options === void 0 ? void 0 : options.audioOnly;
|
|
248
|
+
const newStream = yield this.client.upgradeToVideo(sipSession, constraints, isConference);
|
|
249
|
+
if (callSession) {
|
|
250
|
+
callSession.cameraEnabled = true;
|
|
251
|
+
this._updateCallSession(callSession);
|
|
252
|
+
}
|
|
253
|
+
// If no stream is returned, it means we have to reinvite
|
|
254
|
+
if (!newStream) {
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
this._sendReinviteMessage(callSession, true);
|
|
258
|
+
if (shouldScreenShare) {
|
|
259
|
+
this._onScreenSharing(newStream, sipSession, callSession, false, desktop);
|
|
260
|
+
}
|
|
261
|
+
// We have to reinvite to change the direction on the bundle when upgrading from an audioOnly conference
|
|
262
|
+
if (isConference && wasAudioOnly) {
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
// No reinvite needed here
|
|
266
|
+
return false;
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
_sendReinviteMessage(callSession, isUpgrade) {
|
|
270
|
+
const sipSession = this.findSipSession(callSession);
|
|
271
|
+
logger.info('Sending reinvite message', {
|
|
272
|
+
id: callSession ? callSession.getId() : null,
|
|
273
|
+
isUpgrade,
|
|
274
|
+
});
|
|
275
|
+
// Have to send the message after a delay due to latency to update the remote peer
|
|
276
|
+
setTimeout(() => {
|
|
277
|
+
this.sendMessage(sipSession, JSON.stringify({
|
|
278
|
+
type: exports.MESSAGE_TYPE_SIGNAL,
|
|
279
|
+
content: {
|
|
280
|
+
type: exports.ON_MESSAGE_TRACK_UPDATED,
|
|
281
|
+
update: isUpgrade ? 'upgrade' : 'downgrade',
|
|
282
|
+
sipCallId: sipSession && this.getSipSessionId(sipSession),
|
|
283
|
+
callId: callSession ? callSession.callId : null,
|
|
284
|
+
number: callSession ? callSession.number : null,
|
|
285
|
+
callerNumber: callSession ? callSession.callerNumber : null,
|
|
286
|
+
},
|
|
287
|
+
}));
|
|
288
|
+
}, 2500);
|
|
289
|
+
}
|
|
290
|
+
_bindEvents(sipSession) {
|
|
291
|
+
if (sipSession instanceof api_1.Invitation) {
|
|
292
|
+
// Monkey patch to know when canceled with the CANCEL message
|
|
293
|
+
const onCancel = sipSession._onCancel.bind(sipSession);
|
|
294
|
+
sipSession._onCancel = (message) => {
|
|
295
|
+
logger.trace('on sip session canceled', {
|
|
296
|
+
callId: message.callId,
|
|
297
|
+
});
|
|
298
|
+
onCancel(message);
|
|
299
|
+
const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
|
|
300
|
+
const callSession = this._createCallSession(sipSession);
|
|
301
|
+
delete this.callSessions[callSession.getId()];
|
|
302
|
+
this.eventEmitter.emit(exports.ON_CALL_CANCELED, callSession, elsewhere);
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
else if (sipSession instanceof api_1.Invitation) {
|
|
306
|
+
console.warn('sipSession._onCancel not found, please update the wazo SDK accordingly');
|
|
307
|
+
}
|
|
308
|
+
sipSession.stateChange.addListener((newState) => {
|
|
309
|
+
switch (newState) {
|
|
310
|
+
case session_state_1.SessionState.Establishing:
|
|
311
|
+
if (sipSession instanceof api_1.Invitation) {
|
|
312
|
+
// No need to trigger progress for an invitation (eg: when we answer the call).
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
// When receiving a progress event, we know we are the caller so we have to force incoming to false
|
|
316
|
+
return this.eventEmitter.emit(exports.ON_PROGRESS, this._createCallSession(sipSession, null, {
|
|
317
|
+
incoming: false,
|
|
318
|
+
ringing: true,
|
|
319
|
+
}), this.audioOutputDeviceId, this.audioOutputVolume);
|
|
320
|
+
case session_state_1.SessionState.Terminating:
|
|
321
|
+
logger.info('WebRTC phone - call terminating', {
|
|
322
|
+
sipId: sipSession.id,
|
|
323
|
+
});
|
|
324
|
+
this.eventEmitter.emit(exports.ON_CALL_ENDING, this._createCallSession(sipSession));
|
|
325
|
+
break;
|
|
326
|
+
case session_state_1.SessionState.Terminated:
|
|
327
|
+
{
|
|
328
|
+
logger.info('WebRTC phone - call terminated', {
|
|
329
|
+
sipId: sipSession.id,
|
|
330
|
+
});
|
|
331
|
+
// Should be called before `_onCallTerminated` or the callCount will not decrement...
|
|
332
|
+
const callSession = this._createCallSession(sipSession);
|
|
333
|
+
callSession.endTime = new Date();
|
|
334
|
+
const wasCurrentSession = this._onCallTerminated(sipSession);
|
|
335
|
+
return this.eventEmitter.emit(exports.ON_CALL_ENDED, callSession, wasCurrentSession);
|
|
336
|
+
}
|
|
337
|
+
default:
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
if (!sipSession.sessionDescriptionHandler) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
// Video events
|
|
345
|
+
const {
|
|
346
|
+
// @ts-ignore
|
|
347
|
+
peerConnection, } = sipSession.sessionDescriptionHandler;
|
|
348
|
+
peerConnection.ontrack = (rawEvent) => {
|
|
349
|
+
const event = rawEvent;
|
|
350
|
+
const [stream] = event.streams;
|
|
351
|
+
const kind = event && event.track && event.track.kind;
|
|
352
|
+
logger.info('on track stream called on the peer connection', {
|
|
353
|
+
callId: this.getSipSessionId(sipSession),
|
|
354
|
+
streamId: stream ? stream.id : null,
|
|
355
|
+
tracks: stream ? stream.getTracks() : null,
|
|
356
|
+
kind,
|
|
357
|
+
});
|
|
358
|
+
if (kind === 'audio') {
|
|
359
|
+
return this.eventEmitter.emit(exports.ON_AUDIO_STREAM, stream);
|
|
360
|
+
}
|
|
361
|
+
// not sure this does anything
|
|
362
|
+
if (kind === 'video') {
|
|
363
|
+
event.track.enabled = false;
|
|
364
|
+
}
|
|
365
|
+
return this.eventEmitter.emit(exports.ON_VIDEO_STREAM, stream, event.track.id, event, sipSession);
|
|
366
|
+
};
|
|
367
|
+
peerConnection.onremovestream = (event) => {
|
|
368
|
+
logger.info('on remove stream called on the peer connection', {
|
|
369
|
+
id: event.stream.id,
|
|
370
|
+
tracks: event.stream.getTracks(),
|
|
371
|
+
});
|
|
372
|
+
this.eventEmitter.emit(exports.ON_REMOVE_STREAM, event.stream);
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
startScreenSharing(constraints, callSession) {
|
|
376
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
377
|
+
logger.info('WebRTC - start screen sharing', {
|
|
378
|
+
constraints,
|
|
379
|
+
id: callSession ? callSession.getId() : null,
|
|
380
|
+
});
|
|
381
|
+
const screenShareStream = yield this.client.getStreamFromConstraints(constraints);
|
|
382
|
+
if (!screenShareStream) {
|
|
383
|
+
throw new Error(`Can't create media stream for screensharing with: ${JSON.stringify(constraints)}`);
|
|
384
|
+
}
|
|
385
|
+
const screenTrack = screenShareStream.getVideoTracks()[0];
|
|
386
|
+
const sipSession = this.currentSipSession;
|
|
387
|
+
const pc = sipSession && this.client.getPeerConnection(this.getSipSessionId(sipSession));
|
|
388
|
+
const sender = pc && pc.getSenders && pc.getSenders().find((s) => s && s.track && s.track.kind === 'video');
|
|
389
|
+
const localStream = sipSession && this.client.getLocalStream(this.getSipSessionId(sipSession));
|
|
390
|
+
const videoTrack = localStream ? localStream.getTracks().find(track => track.kind === 'video') : null;
|
|
391
|
+
const hadVideo = !!videoTrack;
|
|
392
|
+
// Stop local video tracks
|
|
393
|
+
if (videoTrack && localStream) {
|
|
394
|
+
videoTrack.enabled = false;
|
|
395
|
+
videoTrack.stop();
|
|
396
|
+
localStream.removeTrack(videoTrack);
|
|
397
|
+
}
|
|
398
|
+
if (localStream) {
|
|
399
|
+
localStream.addTrack(screenTrack);
|
|
400
|
+
}
|
|
401
|
+
if (sender) {
|
|
402
|
+
sender.replaceTrack(screenTrack);
|
|
403
|
+
}
|
|
404
|
+
this._onScreenSharing(screenShareStream, sipSession, callSession, hadVideo, constraints.desktop);
|
|
405
|
+
return screenShareStream;
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
stopScreenSharing(restoreLocalStream = true, callSession) {
|
|
409
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
410
|
+
if (!this.currentScreenShare) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
logger.info('WebRTC phone - stop screen sharing', {
|
|
414
|
+
restoreLocalStream,
|
|
415
|
+
});
|
|
416
|
+
let reinvited;
|
|
417
|
+
try {
|
|
418
|
+
if (this.currentScreenShare.stream) {
|
|
419
|
+
this.currentScreenShare.stream.getTracks().forEach((track) => track.stop());
|
|
420
|
+
}
|
|
421
|
+
if (restoreLocalStream) {
|
|
422
|
+
const targetCallSession = callSession || this.currentCallSession;
|
|
423
|
+
const conference = this.isConference(targetCallSession);
|
|
424
|
+
// When stopping screenshare and we had video before that, we have to re-upgrade
|
|
425
|
+
// When upgrading directly to screenshare (eg: we don't have a videoLocalStream to replace)
|
|
426
|
+
// We have to downgrade to audio.
|
|
427
|
+
const screenshareStopped = this.currentScreenShare.hadVideo;
|
|
428
|
+
const constraints = {
|
|
429
|
+
audio: false,
|
|
430
|
+
video: screenshareStopped,
|
|
431
|
+
};
|
|
432
|
+
// We have to remove the video sender to be able to re-upgrade to video in `sendReinvite` below
|
|
433
|
+
this._downgradeToAudio(targetCallSession, false);
|
|
434
|
+
// Wait for the track to be removed, unless the video sender won't have a null track in `_upgradeToVideo`.
|
|
435
|
+
yield new Promise(resolve => setTimeout(resolve, 500));
|
|
436
|
+
reinvited = yield this.sendReinvite(targetCallSession, constraints, conference);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
catch (e) {
|
|
440
|
+
console.warn(e);
|
|
441
|
+
}
|
|
442
|
+
const sipSession = this.currentSipSession;
|
|
443
|
+
this.eventEmitter.emit(exports.ON_SHARE_SCREEN_ENDED, callSession && sipSession ? this._createCallSession(sipSession, callSession, {
|
|
444
|
+
screensharing: false,
|
|
445
|
+
}) : null);
|
|
446
|
+
this.currentScreenShare = null;
|
|
447
|
+
return reinvited;
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
_onScreenSharing(screenStream, sipSession, callSession, hadVideo, desktop) {
|
|
451
|
+
const screenTrack = screenStream.getVideoTracks()[0];
|
|
452
|
+
const sipSessionId = this.getSipSessionId(sipSession);
|
|
453
|
+
const pc = this.client.getPeerConnection(sipSessionId);
|
|
454
|
+
const sender = pc && pc.getSenders && pc.getSenders().find((s) => s && s.track && s.track.kind === 'video');
|
|
455
|
+
logger.info('WebRTC phone - on screensharing', {
|
|
456
|
+
hadVideo,
|
|
457
|
+
id: this.getSipSessionId(sipSession),
|
|
458
|
+
screenTrack,
|
|
459
|
+
});
|
|
460
|
+
if (screenTrack) {
|
|
461
|
+
screenTrack.onended = () => {
|
|
462
|
+
logger.info('WebRTC phone - on screenshare ended', {
|
|
463
|
+
hadVideo,
|
|
464
|
+
id: this.getSipSessionId(sipSession),
|
|
465
|
+
screenTrack,
|
|
466
|
+
});
|
|
467
|
+
this.eventEmitter.emit(exports.ON_SHARE_SCREEN_ENDING, this._createCallSession(sipSession, callSession));
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
this.currentScreenShare = {
|
|
471
|
+
stream: screenStream,
|
|
472
|
+
hadVideo,
|
|
473
|
+
sender,
|
|
474
|
+
sipSessionId,
|
|
475
|
+
desktop,
|
|
476
|
+
};
|
|
477
|
+
this.client.setLocalMediaStream(this.getSipSessionId(sipSession), screenStream);
|
|
478
|
+
this.eventEmitter.emit(exports.ON_SHARE_SCREEN_STARTED, this._createCallSession(sipSession, callSession, {
|
|
479
|
+
screensharing: true,
|
|
480
|
+
}), screenStream);
|
|
481
|
+
}
|
|
482
|
+
_onCallAccepted(sipSession, cameraEnabled) {
|
|
483
|
+
logger.info('WebRTC phone - on call accepted', {
|
|
484
|
+
sipId: sipSession.id,
|
|
485
|
+
cameraEnabled,
|
|
486
|
+
});
|
|
487
|
+
const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
|
|
488
|
+
this.currentSipSession = sipSession;
|
|
489
|
+
this.currentCallSession = callSession;
|
|
490
|
+
this.eventEmitter.emit(exports.ON_TERMINATE_SOUND, callSession, 'call accepted');
|
|
491
|
+
const sipSessionId = this.getSipSessionId(sipSession);
|
|
492
|
+
if (sipSessionId) {
|
|
493
|
+
this.removeIncomingSessions(sipSessionId);
|
|
494
|
+
}
|
|
495
|
+
callSession.answerTime = new Date();
|
|
496
|
+
this._updateCallSession(callSession);
|
|
497
|
+
this.eventEmitter.emit(exports.ON_CALL_ACCEPTED, callSession, cameraEnabled);
|
|
498
|
+
return callSession;
|
|
499
|
+
}
|
|
500
|
+
changeAudioDevice(id) {
|
|
501
|
+
logger.info('WebRTC phone - change audio device', {
|
|
502
|
+
deviceId: id,
|
|
503
|
+
});
|
|
504
|
+
this.audioOutputDeviceId = id;
|
|
505
|
+
this.client.changeAudioOutputDevice(id);
|
|
506
|
+
}
|
|
507
|
+
createAudioElementFor(sessionId) {
|
|
508
|
+
return this.client.createAudioElementFor(sessionId);
|
|
509
|
+
}
|
|
510
|
+
changeRingDevice(id) {
|
|
511
|
+
logger.info('WebRTC phone - changing ring device', {
|
|
512
|
+
id,
|
|
513
|
+
});
|
|
514
|
+
this.audioRingDeviceId = id;
|
|
515
|
+
}
|
|
516
|
+
// volume is a value between 0 and 1
|
|
517
|
+
changeAudioVolume(volume) {
|
|
518
|
+
logger.info('WebRTC phone - changing audio volume', {
|
|
519
|
+
volume,
|
|
520
|
+
});
|
|
521
|
+
this.audioOutputVolume = volume;
|
|
522
|
+
this.client.changeAudioOutputVolume(volume);
|
|
523
|
+
}
|
|
524
|
+
// volume is a value between 0 and 1
|
|
525
|
+
changeRingVolume(volume) {
|
|
526
|
+
logger.info('WebRTC phone - changing ring volume', {
|
|
527
|
+
volume,
|
|
528
|
+
});
|
|
529
|
+
this.audioRingVolume = volume;
|
|
530
|
+
}
|
|
531
|
+
changeAudioInputDevice(id, force) {
|
|
532
|
+
logger.info('WebRTC phone - changeAudio input device', {
|
|
533
|
+
deviceId: id,
|
|
534
|
+
});
|
|
535
|
+
return this.client.changeAudioInputDevice(id, this.currentSipSession, force);
|
|
536
|
+
}
|
|
537
|
+
changeVideoInputDevice(id) {
|
|
538
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
539
|
+
logger.info('WebRTC phone - change video input device', {
|
|
540
|
+
deviceId: id,
|
|
541
|
+
});
|
|
542
|
+
return this.client.changeVideoInputDevice(id, this.currentSipSession);
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
changeSessionVideoInputDevice(id) {
|
|
546
|
+
logger.info('WebRTC phone - change session video input device', {
|
|
547
|
+
deviceId: id,
|
|
548
|
+
});
|
|
549
|
+
return this.currentSipSession && this.client.changeSessionVideoInputDevice(id, this.currentSipSession);
|
|
550
|
+
}
|
|
551
|
+
_onCallTerminated(sipSession) {
|
|
552
|
+
logger.info('WebRTC phone - on call terminated', {
|
|
553
|
+
sipId: sipSession.id,
|
|
554
|
+
});
|
|
555
|
+
const sipSessionId = this.getSipSessionId(sipSession);
|
|
1317
556
|
const callSession = this._createCallSession(sipSession);
|
|
557
|
+
const isCurrentSession = this.isCurrentCallSipSession(callSession);
|
|
558
|
+
const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
|
|
559
|
+
// If the terminated call was an incoming call, we have to re-trigger if it's was the first incoming call
|
|
560
|
+
// Otherwise, we have to re-trigger an incoming call event if another call is incoming
|
|
561
|
+
const shouldRetrigger = isCurrentSession ? this.incomingSessions.length : isCurrentIncomingCall;
|
|
562
|
+
// Terminate incoming sound only for the ringing call
|
|
563
|
+
// (so another terminated call won't stop the incoming call sound)
|
|
564
|
+
if (isCurrentIncomingCall) {
|
|
565
|
+
setTimeout(() => {
|
|
566
|
+
// Avoid race condition when the other is calling and hanging up immediately
|
|
567
|
+
this.eventEmitter.emit(exports.ON_TERMINATE_SOUND, callSession, 'call terminated');
|
|
568
|
+
}, 5);
|
|
569
|
+
}
|
|
570
|
+
if (sipSessionId) {
|
|
571
|
+
this.removeIncomingSessions(sipSessionId);
|
|
572
|
+
}
|
|
1318
573
|
delete this.callSessions[callSession.getId()];
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
574
|
+
if (isCurrentSession) {
|
|
575
|
+
this.currentSipSession = undefined;
|
|
576
|
+
this.currentCallSession = undefined;
|
|
577
|
+
}
|
|
578
|
+
const hasIncomingCallSession = this.hasIncomingCallSession();
|
|
579
|
+
// Re-trigger incoming call event for remaining incoming calls
|
|
580
|
+
logger.info('WebRTC phone - check to re-trigger incoming call', {
|
|
581
|
+
sipId: sipSession.id,
|
|
582
|
+
shouldRetrigger,
|
|
583
|
+
hasIncomingCallSession,
|
|
584
|
+
});
|
|
585
|
+
this.client.onCallEnded(sipSession);
|
|
586
|
+
if (hasIncomingCallSession && shouldRetrigger) {
|
|
587
|
+
const nextCallSession = this.getIncomingCallSession();
|
|
588
|
+
// Avoid race condition
|
|
589
|
+
setTimeout(() => {
|
|
590
|
+
if (this.ringingEnabled) {
|
|
591
|
+
if (!this.currentCallSession) {
|
|
592
|
+
this.eventEmitter.emit(exports.ON_PLAY_RING_SOUND, this.audioRingDeviceId, this.audioRingVolume, nextCallSession);
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
this.eventEmitter.emit(exports.ON_PLAY_INBOUND_CALL_SIGNAL_SOUND, this.audioOutputDeviceId, this.audioOutputVolume, nextCallSession);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
this.eventEmitter.emit(exports.ON_CALL_INCOMING, nextCallSession, nextCallSession === null || nextCallSession === void 0 ? void 0 : nextCallSession.cameraEnabled);
|
|
599
|
+
}, 100);
|
|
600
|
+
}
|
|
601
|
+
if (callSession.getId() in this.ignoredSessions) {
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
// @ts-ignore
|
|
605
|
+
if (!sipSession.isCanceled) {
|
|
606
|
+
setTimeout(() => {
|
|
607
|
+
this.eventEmitter.emit(exports.ON_PLAY_HANGUP_SOUND, this.audioOutputDeviceId, this.audioOutputVolume, callSession);
|
|
608
|
+
}, 10);
|
|
609
|
+
}
|
|
610
|
+
return isCurrentSession;
|
|
611
|
+
}
|
|
612
|
+
setActiveSipSession(callSession) {
|
|
613
|
+
const sipSessionId = this.findSipSession(callSession);
|
|
614
|
+
if (!sipSessionId) {
|
|
1331
615
|
return;
|
|
1332
|
-
}
|
|
1333
|
-
// When receiving a progress event, we know we are the caller so we have to force incoming to false
|
|
1334
|
-
return this.eventEmitter.emit(
|
|
1335
|
-
ON_PROGRESS,
|
|
1336
|
-
this._createCallSession(sipSession, null, { incoming: false, ringing: true }),
|
|
1337
|
-
this.audioOutputDeviceId,
|
|
1338
|
-
this.audioOutputVolume,
|
|
1339
|
-
);
|
|
1340
|
-
case sessionState.SessionState.Terminating:
|
|
1341
|
-
logger.info('WebRTC phone - call terminating', { sipId: sipSession.id });
|
|
1342
|
-
|
|
1343
|
-
this.eventEmitter.emit(ON_CALL_ENDING, this._createCallSession(sipSession));
|
|
1344
|
-
|
|
1345
|
-
break;
|
|
1346
|
-
case sessionState.SessionState.Terminated: {
|
|
1347
|
-
logger.info('WebRTC phone - call terminated', { sipId: sipSession.id });
|
|
1348
|
-
|
|
1349
|
-
// Should be called before `_onCallTerminated` or the callCount will not decrement...
|
|
1350
|
-
const callSession = this._createCallSession(sipSession);
|
|
1351
|
-
callSession.endTime = new Date();
|
|
1352
|
-
const wasCurrentSession = this._onCallTerminated(sipSession);
|
|
1353
|
-
|
|
1354
|
-
return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
|
|
1355
616
|
}
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
}
|
|
1362
|
-
|
|
1363
|
-
//
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
// not sure this does anything
|
|
1382
|
-
if (kind === 'video') {
|
|
1383
|
-
event.track.enabled = false;
|
|
1384
|
-
}
|
|
1385
|
-
|
|
1386
|
-
return this.eventEmitter.emit(ON_VIDEO_STREAM, stream, event.track.id, event, sipSession);
|
|
1387
|
-
};
|
|
1388
|
-
|
|
1389
|
-
peerConnection.onremovestream = event => {
|
|
1390
|
-
logger.info('on remove stream called on the peer connection', {
|
|
1391
|
-
id: event.stream.id,
|
|
1392
|
-
tracks: event.stream.getTracks(),
|
|
1393
|
-
});
|
|
1394
|
-
|
|
1395
|
-
this.eventEmitter.emit(ON_REMOVE_STREAM, event.stream);
|
|
1396
|
-
};
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
async startScreenSharing(constraints , callSession ) {
|
|
1400
|
-
logger.info('WebRTC - start screen sharing', { constraints, id: callSession ? callSession.getId() : null });
|
|
1401
|
-
|
|
1402
|
-
const screenShareStream = await this.client.getStreamFromConstraints(constraints);
|
|
1403
|
-
if (!screenShareStream) {
|
|
1404
|
-
throw new Error(`Can't create media stream for screensharing with: ${JSON.stringify(constraints)}`);
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
const screenTrack = screenShareStream.getVideoTracks()[0];
|
|
1408
|
-
const sipSession = this.currentSipSession;
|
|
1409
|
-
const pc = this.client.getPeerConnection(this.getSipSessionId(sipSession));
|
|
1410
|
-
const sender = pc && pc.getSenders && pc.getSenders().find(s => s && s.track && s.track.kind === 'video');
|
|
1411
|
-
const localStream = this.client.getLocalStream(this.getSipSessionId(sipSession));
|
|
1412
|
-
const videoTrack = localStream ? localStream.getTracks().find(track => track.kind === 'video') : null;
|
|
1413
|
-
const hadVideo = !!videoTrack;
|
|
1414
|
-
|
|
1415
|
-
// Stop local video tracks
|
|
1416
|
-
if (videoTrack && localStream) {
|
|
1417
|
-
videoTrack.enabled = false;
|
|
1418
|
-
videoTrack.stop();
|
|
1419
|
-
localStream.removeTrack(videoTrack);
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
if (localStream) {
|
|
1423
|
-
localStream.addTrack(screenTrack);
|
|
1424
|
-
}
|
|
1425
|
-
|
|
1426
|
-
if (sender) {
|
|
1427
|
-
sender.replaceTrack(screenTrack);
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
this._onScreenSharing(screenShareStream, sipSession, callSession, hadVideo, constraints.desktop);
|
|
1431
|
-
|
|
1432
|
-
return screenShareStream;
|
|
1433
|
-
}
|
|
1434
|
-
|
|
1435
|
-
async stopScreenSharing(restoreLocalStream = true, callSession ) {
|
|
1436
|
-
if (!this.currentScreenShare) {
|
|
1437
|
-
return;
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
logger.info('WebRTC phone - stop screen sharing', {
|
|
1441
|
-
restoreLocalStream,
|
|
1442
|
-
});
|
|
1443
|
-
|
|
1444
|
-
let reinvited = false;
|
|
1445
|
-
|
|
1446
|
-
try {
|
|
1447
|
-
if (this.currentScreenShare.stream) {
|
|
1448
|
-
this.currentScreenShare.stream.getTracks().forEach(track => track.stop());
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
if (restoreLocalStream) {
|
|
1452
|
-
const targetCallSession = callSession || this.currentCallSession;
|
|
1453
|
-
const conference = this.isConference(targetCallSession);
|
|
1454
|
-
|
|
1455
|
-
// When stopping screenshare and we had video before that, we have to re-upgrade
|
|
1456
|
-
// When upgrading directly to screenshare (eg: we don't have a videoLocalStream to replace)
|
|
1457
|
-
// We have to downgrade to audio.
|
|
1458
|
-
const screenshareStopped = this.currentScreenShare.hadVideo;
|
|
1459
|
-
const constraints = { audio: false, video: screenshareStopped };
|
|
1460
|
-
|
|
1461
|
-
// We have to remove the video sender to be able to re-upgrade to video in `sendReinvite` below
|
|
1462
|
-
this._downgradeToAudio(targetCallSession, false);
|
|
1463
|
-
// Wait for the track to be removed, unless the video sender won't have a null track in `_upgradeToVideo`.
|
|
1464
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
1465
|
-
|
|
1466
|
-
reinvited = await this.sendReinvite(targetCallSession, constraints, conference);
|
|
1467
|
-
}
|
|
1468
|
-
} catch (e) {
|
|
1469
|
-
console.warn(e);
|
|
1470
|
-
}
|
|
1471
|
-
|
|
1472
|
-
const sipSession = this.currentSipSession;
|
|
1473
|
-
|
|
1474
|
-
this.eventEmitter.emit(
|
|
1475
|
-
ON_SHARE_SCREEN_ENDED,
|
|
1476
|
-
callSession ? this._createCallSession(sipSession, callSession, { screensharing: false }) : null,
|
|
1477
|
-
);
|
|
1478
|
-
|
|
1479
|
-
this.currentScreenShare = null;
|
|
1480
|
-
|
|
1481
|
-
return reinvited;
|
|
1482
|
-
}
|
|
1483
|
-
|
|
1484
|
-
_onScreenSharing(screenStream ,
|
|
1485
|
-
sipSession ,
|
|
1486
|
-
callSession ,
|
|
1487
|
-
hadVideo ,
|
|
1488
|
-
desktop = false) {
|
|
1489
|
-
const screenTrack = screenStream.getVideoTracks()[0];
|
|
1490
|
-
const sipSessionId = this.getSipSessionId(sipSession);
|
|
1491
|
-
const pc = this.client.getPeerConnection(sipSessionId);
|
|
1492
|
-
const sender = pc && pc.getSenders && pc.getSenders().find(s => s && s.track && s.track.kind === 'video');
|
|
1493
|
-
|
|
1494
|
-
logger.info('WebRTC phone - on screensharing', {
|
|
1495
|
-
hadVideo,
|
|
1496
|
-
id: this.getSipSessionId(sipSession),
|
|
1497
|
-
screenTrack,
|
|
1498
|
-
});
|
|
1499
|
-
|
|
1500
|
-
if (screenTrack) {
|
|
1501
|
-
screenTrack.onended = () => {
|
|
1502
|
-
logger.info('WebRTC phone - on screenshare ended', {
|
|
1503
|
-
hadVideo,
|
|
1504
|
-
id: this.getSipSessionId(sipSession),
|
|
1505
|
-
screenTrack,
|
|
1506
|
-
});
|
|
1507
|
-
|
|
1508
|
-
this.eventEmitter.emit(
|
|
1509
|
-
ON_SHARE_SCREEN_ENDING,
|
|
1510
|
-
this._createCallSession(sipSession, callSession),
|
|
1511
|
-
);
|
|
1512
|
-
};
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
this.currentScreenShare = {
|
|
1516
|
-
stream: screenStream,
|
|
1517
|
-
hadVideo,
|
|
1518
|
-
sender,
|
|
1519
|
-
sipSessionId,
|
|
1520
|
-
desktop,
|
|
1521
|
-
};
|
|
1522
|
-
|
|
1523
|
-
this.client.setLocalMediaStream(this.getSipSessionId(sipSession), screenStream);
|
|
1524
|
-
|
|
1525
|
-
this.eventEmitter.emit(
|
|
1526
|
-
ON_SHARE_SCREEN_STARTED,
|
|
1527
|
-
this._createCallSession(sipSession, callSession, { screensharing: true }),
|
|
1528
|
-
screenStream,
|
|
1529
|
-
);
|
|
1530
|
-
}
|
|
1531
|
-
|
|
1532
|
-
_onCallAccepted(sipSession , cameraEnabled ) {
|
|
1533
|
-
logger.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
|
|
1534
|
-
|
|
1535
|
-
const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
|
|
1536
|
-
this.currentSipSession = sipSession;
|
|
1537
|
-
this.currentCallSession = callSession;
|
|
1538
|
-
|
|
1539
|
-
this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'call accepted');
|
|
1540
|
-
const sipSessionId = this.getSipSessionId(sipSession);
|
|
1541
|
-
if (sipSessionId) {
|
|
1542
|
-
this.removeIncomingSessions(sipSessionId);
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
|
-
callSession.answerTime = new Date();
|
|
1546
|
-
this._updateCallSession(callSession);
|
|
1547
|
-
this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
|
|
1548
|
-
|
|
1549
|
-
return callSession;
|
|
1550
|
-
}
|
|
1551
|
-
|
|
1552
|
-
changeAudioDevice(id ) {
|
|
1553
|
-
logger.info('WebRTC phone - change audio device', { deviceId: id });
|
|
1554
|
-
this.audioOutputDeviceId = id;
|
|
1555
|
-
this.client.changeAudioOutputDevice(id);
|
|
1556
|
-
}
|
|
1557
|
-
|
|
1558
|
-
createAudioElementFor(sessionId ) {
|
|
1559
|
-
return this.client.createAudioElementFor(sessionId);
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
changeRingDevice(id ) {
|
|
1563
|
-
logger.info('WebRTC phone - changing ring device', { id });
|
|
1564
|
-
|
|
1565
|
-
this.audioRingDeviceId = id;
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
// volume is a value between 0 and 1
|
|
1569
|
-
changeAudioVolume(volume ) {
|
|
1570
|
-
logger.info('WebRTC phone - changing audio volume', { volume });
|
|
1571
|
-
|
|
1572
|
-
this.audioOutputVolume = volume;
|
|
1573
|
-
this.client.changeAudioOutputVolume(volume);
|
|
1574
|
-
}
|
|
1575
|
-
|
|
1576
|
-
// volume is a value between 0 and 1
|
|
1577
|
-
changeRingVolume(volume ) {
|
|
1578
|
-
logger.info('WebRTC phone - changing ring volume', { volume });
|
|
1579
|
-
|
|
1580
|
-
this.audioRingVolume = volume;
|
|
1581
|
-
}
|
|
1582
|
-
|
|
1583
|
-
changeAudioInputDevice(id , force ) {
|
|
1584
|
-
logger.info('WebRTC phone - changeAudio input device', { deviceId: id });
|
|
1585
|
-
|
|
1586
|
-
return this.client.changeAudioInputDevice(id, this.currentSipSession, force);
|
|
1587
|
-
}
|
|
1588
|
-
|
|
1589
|
-
changeVideoInputDevice(id ) {
|
|
1590
|
-
logger.info('WebRTC phone - change video input device', { deviceId: id });
|
|
1591
|
-
|
|
1592
|
-
return this.client.changeVideoInputDevice(id, this.currentSipSession);
|
|
1593
|
-
}
|
|
1594
|
-
|
|
1595
|
-
changeSessionVideoInputDevice(id ) {
|
|
1596
|
-
logger.info('WebRTC phone - change session video input device', { deviceId: id });
|
|
1597
|
-
|
|
1598
|
-
return this.client.changeSessionVideoInputDevice(id, this.currentSipSession);
|
|
1599
|
-
}
|
|
1600
|
-
|
|
1601
|
-
_onCallTerminated(sipSession ) {
|
|
1602
|
-
logger.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
|
|
1603
|
-
|
|
1604
|
-
const sipSessionId = this.getSipSessionId(sipSession);
|
|
1605
|
-
const callSession = this._createCallSession(sipSession);
|
|
1606
|
-
const isCurrentSession = this.isCurrentCallSipSession(callSession);
|
|
1607
|
-
const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
|
|
1608
|
-
|
|
1609
|
-
// If the terminated call was an incoming call, we have to re-trigger if it's was the first incoming call
|
|
1610
|
-
// Otherwise, we have to re-trigger an incoming call event if another call is incoming
|
|
1611
|
-
const shouldRetrigger = isCurrentSession ? this.incomingSessions.length : isCurrentIncomingCall;
|
|
1612
|
-
|
|
1613
|
-
// Terminate incoming sound only for the ringing call
|
|
1614
|
-
// (so another terminated call won't stop the incoming call sound)
|
|
1615
|
-
if (isCurrentIncomingCall) {
|
|
1616
|
-
setTimeout(() => {
|
|
1617
|
-
// Avoid race condition when the other is calling and hanging up immediately
|
|
1618
|
-
this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'call terminated');
|
|
1619
|
-
}, 5);
|
|
1620
|
-
}
|
|
1621
|
-
|
|
1622
|
-
if (sipSessionId) {
|
|
1623
|
-
this.removeIncomingSessions(sipSessionId);
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
delete this.callSessions[callSession.getId()];
|
|
1627
|
-
|
|
1628
|
-
if (isCurrentSession) {
|
|
1629
|
-
this.currentSipSession = undefined;
|
|
1630
|
-
this.currentCallSession = undefined;
|
|
1631
|
-
}
|
|
1632
|
-
|
|
1633
|
-
const hasIncomingCallSession = this.hasIncomingCallSession();
|
|
1634
|
-
|
|
1635
|
-
// Re-trigger incoming call event for remaining incoming calls
|
|
1636
|
-
logger.info('WebRTC phone - check to re-trigger incoming call', {
|
|
1637
|
-
sipId: sipSession.id,
|
|
1638
|
-
shouldRetrigger,
|
|
1639
|
-
hasIncomingCallSession,
|
|
1640
|
-
});
|
|
1641
|
-
|
|
1642
|
-
this.client.onCallEnded(sipSession);
|
|
1643
|
-
|
|
1644
|
-
if (hasIncomingCallSession && shouldRetrigger) {
|
|
1645
|
-
const nextCallSession = this.getIncomingCallSession();
|
|
1646
|
-
// Avoid race condition
|
|
1647
|
-
setTimeout(() => {
|
|
1648
|
-
if (this.ringingEnabled) {
|
|
1649
|
-
if (!this.currentCallSession) {
|
|
1650
|
-
this.eventEmitter.emit(ON_PLAY_RING_SOUND, this.audioRingDeviceId, this.audioRingVolume, nextCallSession);
|
|
1651
|
-
} else {
|
|
1652
|
-
this.eventEmitter.emit(ON_PLAY_INBOUND_CALL_SIGNAL_SOUND,
|
|
1653
|
-
this.audioOutputDeviceId,
|
|
1654
|
-
this.audioOutputVolume,
|
|
1655
|
-
nextCallSession);
|
|
1656
|
-
}
|
|
617
|
+
this.currentSipSession = sipSessionId;
|
|
618
|
+
this.currentCallSession = callSession;
|
|
619
|
+
}
|
|
620
|
+
hasAnActiveCall() {
|
|
621
|
+
return !!this.currentSipSession;
|
|
622
|
+
}
|
|
623
|
+
// /!\ In some case with react-native webrtc the session will have only one audio stream set
|
|
624
|
+
// Maybe due to https://github.com/react-native-webrtc/react-native-webrtc/issues/401
|
|
625
|
+
hasActiveRemoteVideoStream() {
|
|
626
|
+
const sipSession = this.currentSipSession;
|
|
627
|
+
if (!sipSession) {
|
|
628
|
+
return false;
|
|
629
|
+
}
|
|
630
|
+
const {
|
|
631
|
+
// @ts-ignore
|
|
632
|
+
peerConnection, } = sipSession.sessionDescriptionHandler;
|
|
633
|
+
const remoteStream = peerConnection.getRemoteStreams().find((stream) => !!stream.getVideoTracks().length);
|
|
634
|
+
return remoteStream && remoteStream.getVideoTracks().some(track => !track.muted);
|
|
635
|
+
}
|
|
636
|
+
callCount() {
|
|
637
|
+
return Object.keys(this.callSessions).length;
|
|
638
|
+
}
|
|
639
|
+
isCurrentCallSipSession(callSession) {
|
|
640
|
+
if (!this.currentSipSession) {
|
|
641
|
+
return false;
|
|
1657
642
|
}
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
}
|
|
1731
|
-
|
|
1732
|
-
// Deprecated
|
|
1733
|
-
getRemoteStreamForCall(callSession ) {
|
|
1734
|
-
logger.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
|
|
1735
|
-
|
|
1736
|
-
return this.getRemoteVideoStream(callSession);
|
|
1737
|
-
}
|
|
1738
|
-
|
|
1739
|
-
getRemoteStreamsForCall(callSession ) {
|
|
1740
|
-
logger.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
|
|
1741
|
-
|
|
1742
|
-
return this.getRemoteStream(callSession);
|
|
1743
|
-
}
|
|
1744
|
-
|
|
1745
|
-
accept(callSession , cameraEnabled ) {
|
|
1746
|
-
logger.info('WebRTC phone - accept call', { id: callSession ? callSession.getId() : 'n/a', cameraEnabled });
|
|
1747
|
-
if (this.currentSipSession) {
|
|
1748
|
-
this.holdSipSession(
|
|
1749
|
-
this.currentSipSession,
|
|
1750
|
-
this.currentCallSession,
|
|
1751
|
-
true,
|
|
1752
|
-
);
|
|
1753
|
-
}
|
|
1754
|
-
|
|
1755
|
-
if (!callSession) {
|
|
1756
|
-
logger.warn('no CallSession to accept.');
|
|
1757
|
-
return Promise.resolve(null);
|
|
1758
|
-
}
|
|
1759
|
-
|
|
1760
|
-
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
1761
|
-
if (sipSessionId && !(sipSessionId in this.callSessions)) {
|
|
1762
|
-
logger.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
|
|
1763
|
-
return Promise.resolve(null);
|
|
1764
|
-
}
|
|
1765
|
-
|
|
1766
|
-
if (callSession.getId() in this.acceptedSessions) {
|
|
1767
|
-
logger.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
|
|
1768
|
-
return Promise.resolve(callSession.sipCallId);
|
|
1769
|
-
}
|
|
1770
|
-
|
|
1771
|
-
this.shouldSendReinvite = false;
|
|
1772
|
-
callSession.answerTime = new Date();
|
|
1773
|
-
this._updateCallSession(callSession);
|
|
1774
|
-
this.acceptedSessions[callSession.getId()] = true;
|
|
1775
|
-
|
|
1776
|
-
this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
|
|
1777
|
-
|
|
1778
|
-
const sipSession = this.client.getSipSession(callSession.getId());
|
|
1779
|
-
if (sipSession) {
|
|
1780
|
-
if (sipSession.state === sessionState.SessionState.Terminated || sipSession.state === sessionState.SessionState.Terminating) {
|
|
1781
|
-
logger.warn('Trying to answer a terminated sipSession.');
|
|
1782
|
-
|
|
643
|
+
return this.currentSipSession && this.getSipSessionId(this.currentSipSession) === callSession.getId();
|
|
644
|
+
}
|
|
645
|
+
hasVideo(callSession) {
|
|
646
|
+
return this.client.hasVideo(callSession.getId());
|
|
647
|
+
}
|
|
648
|
+
hasAVideoTrack(callSession) {
|
|
649
|
+
return this.client.hasAVideoTrack(callSession.getId());
|
|
650
|
+
}
|
|
651
|
+
// Deprecated
|
|
652
|
+
getLocalStreamForCall(callSession) {
|
|
653
|
+
logger.warn('WebRTCPhone.getLocalStreamForCall is deprecated, use WebRTCPhone.getLocalStream instead');
|
|
654
|
+
return this.getLocalStream(callSession);
|
|
655
|
+
}
|
|
656
|
+
// Deprecated
|
|
657
|
+
getRemoteStreamForCall(callSession) {
|
|
658
|
+
logger.warn('WebRTCPhone.getRemoteStreamForCall is deprecated, use WebRTCPhone.getRemoteStream instead');
|
|
659
|
+
return this.getRemoteVideoStream(callSession);
|
|
660
|
+
}
|
|
661
|
+
getRemoteStreamsForCall(callSession) {
|
|
662
|
+
logger.warn('WebRTCPhone.getRemoteStreamsForCall is deprecated, use WebRTCPhone.getRemoteStreams instead');
|
|
663
|
+
return this.getRemoteStream(callSession);
|
|
664
|
+
}
|
|
665
|
+
accept(callSession, cameraEnabled) {
|
|
666
|
+
logger.info('WebRTC phone - accept call', {
|
|
667
|
+
id: callSession ? callSession.getId() : 'n/a',
|
|
668
|
+
cameraEnabled,
|
|
669
|
+
});
|
|
670
|
+
if (this.currentSipSession) {
|
|
671
|
+
this.holdSipSession(this.currentSipSession, this.currentCallSession, true);
|
|
672
|
+
}
|
|
673
|
+
if (!callSession) {
|
|
674
|
+
logger.warn('no CallSession to accept.');
|
|
675
|
+
return Promise.resolve(null);
|
|
676
|
+
}
|
|
677
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
678
|
+
if (sipSessionId && !(sipSessionId in this.callSessions)) {
|
|
679
|
+
logger.warn('Call session already ended or not found, can\'t accept it.', {
|
|
680
|
+
sipSessionId,
|
|
681
|
+
});
|
|
682
|
+
return Promise.resolve(null);
|
|
683
|
+
}
|
|
684
|
+
if (callSession.getId() in this.acceptedSessions) {
|
|
685
|
+
logger.warn('CallSession already accepted.', {
|
|
686
|
+
id: callSession ? callSession.getId() : 'n/a',
|
|
687
|
+
});
|
|
688
|
+
return Promise.resolve(callSession.sipCallId);
|
|
689
|
+
}
|
|
690
|
+
this.shouldSendReinvite = false;
|
|
691
|
+
callSession.answerTime = new Date();
|
|
692
|
+
this._updateCallSession(callSession);
|
|
693
|
+
this.acceptedSessions[callSession.getId()] = true;
|
|
694
|
+
this.eventEmitter.emit(exports.ON_CALL_ANSWERED, callSession);
|
|
695
|
+
const sipSession = this.client.getSipSession(callSession.getId());
|
|
696
|
+
if (sipSession) {
|
|
697
|
+
if (sipSession.state === session_state_1.SessionState.Terminated || sipSession.state === session_state_1.SessionState.Terminating) {
|
|
698
|
+
logger.warn('Trying to answer a terminated sipSession.');
|
|
699
|
+
return Promise.resolve(null);
|
|
700
|
+
}
|
|
701
|
+
logger.info('accept call, session found', {
|
|
702
|
+
sipId: sipSession.id,
|
|
703
|
+
});
|
|
704
|
+
return this.client.answer(sipSession, this.allowVideo ? cameraEnabled : false).then(() => {
|
|
705
|
+
return callSession.sipCallId;
|
|
706
|
+
}).catch(e => {
|
|
707
|
+
logger.error(e);
|
|
708
|
+
this.endCurrentCall(callSession);
|
|
709
|
+
throw e;
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
logger.warn('no CallSession found to accept.', {
|
|
713
|
+
id: callSession ? callSession.getId() : 'n/a',
|
|
714
|
+
});
|
|
1783
715
|
return Promise.resolve(null);
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
716
|
+
}
|
|
717
|
+
isAccepted(callSession) {
|
|
718
|
+
return callSession && callSession.getId() in this.acceptedSessions;
|
|
719
|
+
}
|
|
720
|
+
reject(callSession) {
|
|
721
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
722
|
+
logger.info('reject WebRTC called', {
|
|
723
|
+
id: callSession.getId(),
|
|
724
|
+
});
|
|
725
|
+
this.eventEmitter.emit(exports.ON_TERMINATE_SOUND, callSession, 'call rejected locally');
|
|
726
|
+
if (!callSession || callSession.getId() in this.rejectedSessions) {
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
this.shouldSendReinvite = false;
|
|
730
|
+
this.rejectedSessions[callSession.getId()] = true;
|
|
731
|
+
const sipSession = this.findSipSession(callSession);
|
|
732
|
+
if (sipSession) {
|
|
733
|
+
logger.info('WebRTC rejecting', {
|
|
734
|
+
sipId: sipSession.id,
|
|
735
|
+
});
|
|
736
|
+
this.client.hangup(sipSession);
|
|
737
|
+
}
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
ignore(callSession) {
|
|
741
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
742
|
+
logger.info('WebRTC ignore', {
|
|
743
|
+
id: callSession.getId(),
|
|
744
|
+
});
|
|
745
|
+
// kill the ring
|
|
746
|
+
this.eventEmitter.emit(exports.ON_TERMINATE_SOUND, callSession, 'ignoring call');
|
|
747
|
+
this.ignoredSessions[callSession.getId()] = true;
|
|
748
|
+
callSession.ignore();
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
atxfer(callSession) {
|
|
752
|
+
const sipSession = this.findSipSession(callSession);
|
|
753
|
+
if (sipSession) {
|
|
754
|
+
logger.info('WebRTC atxfer', {
|
|
755
|
+
sipId: sipSession.id,
|
|
756
|
+
});
|
|
757
|
+
return this.client.atxfer(sipSession);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
hold(callSession, withEvent = true) {
|
|
761
|
+
logger.info('WebRTC hold', {
|
|
762
|
+
id: callSession.getId(),
|
|
763
|
+
});
|
|
764
|
+
const sipSession = this.findSipSession(callSession);
|
|
765
|
+
return sipSession ? this.holdSipSession(sipSession, callSession, withEvent) : null;
|
|
766
|
+
}
|
|
767
|
+
// @Deprecated
|
|
768
|
+
unhold(callSession, withEvent = true) {
|
|
769
|
+
console.warn('Please note that `phone.unhold()` is being deprecated; `phone.resume()` is the preferred method');
|
|
770
|
+
return this.resume(callSession, withEvent);
|
|
771
|
+
}
|
|
772
|
+
resume(callSession, withEvent = true) {
|
|
773
|
+
logger.info('WebRTC resume called', {
|
|
774
|
+
id: callSession ? callSession.getId() : null,
|
|
775
|
+
});
|
|
776
|
+
const sipSession = this.findSipSession(callSession);
|
|
777
|
+
if (!sipSession) {
|
|
778
|
+
return new Promise((resolve, reject) => reject(new Error('No session to resume')));
|
|
779
|
+
}
|
|
780
|
+
logger.info('WebRTC resuming', {
|
|
781
|
+
sipId: sipSession.id,
|
|
782
|
+
});
|
|
783
|
+
// Hold current session if different from the current one (we don't want 2 sessions active at the same time).
|
|
784
|
+
if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
|
|
785
|
+
logger.info('WebRTC hold call after resume', {
|
|
786
|
+
id: this.currentSipSession.id,
|
|
787
|
+
});
|
|
788
|
+
this.holdSipSession(this.currentSipSession, this.currentCallSession, withEvent);
|
|
789
|
+
}
|
|
790
|
+
const promise = this.unholdSipSession(sipSession, callSession, withEvent);
|
|
791
|
+
this.currentSipSession = sipSession;
|
|
792
|
+
if (callSession) {
|
|
793
|
+
this.currentCallSession = callSession;
|
|
794
|
+
}
|
|
795
|
+
return promise;
|
|
796
|
+
}
|
|
797
|
+
holdSipSession(sipSession, callSession, withEvent = true) {
|
|
798
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
799
|
+
if (!sipSession) {
|
|
800
|
+
return new Promise((resolve, reject) => reject(new Error('No session to hold')));
|
|
801
|
+
}
|
|
802
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
803
|
+
const hasVideo = this.client.hasLocalVideo(sessionId);
|
|
804
|
+
logger.info('WebRTC hold sip session', {
|
|
805
|
+
sipId: sipSession.id,
|
|
806
|
+
hasVideo,
|
|
807
|
+
});
|
|
808
|
+
// Stop screenshare if needed
|
|
809
|
+
if (this.currentScreenShare && this.currentScreenShare.sipSessionId === sessionId) {
|
|
810
|
+
this.lastScreenShare = this.currentScreenShare;
|
|
811
|
+
yield this.stopScreenSharing(false, callSession);
|
|
812
|
+
}
|
|
813
|
+
// Downgrade to audio if needed
|
|
814
|
+
if (hasVideo) {
|
|
815
|
+
yield this.client.downgradeToAudio(sipSession);
|
|
816
|
+
}
|
|
817
|
+
const isConference = !!callSession && callSession.isConference();
|
|
818
|
+
const promise = this.client.hold(sipSession, isConference, hasVideo);
|
|
819
|
+
if (withEvent) {
|
|
820
|
+
this.eventEmitter.emit(exports.ON_CALL_HELD, this._createCallSession(sipSession, callSession));
|
|
821
|
+
}
|
|
822
|
+
return promise;
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
unholdSipSession(sipSession, callSession, withEvent = true) {
|
|
826
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
827
|
+
if (!sipSession) {
|
|
828
|
+
return new Promise((resolve, reject) => reject(new Error('No session to unhold')));
|
|
829
|
+
}
|
|
830
|
+
const isConference = !!callSession && callSession.isConference();
|
|
831
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
832
|
+
logger.info('WebRTC unhold sip session', {
|
|
833
|
+
sessionId,
|
|
834
|
+
isConference,
|
|
835
|
+
});
|
|
836
|
+
const { hasVideo, } = this.client.getHeldSession(sessionId) || {};
|
|
837
|
+
const wasScreensharing = this.lastScreenShare && this.lastScreenShare.sipSessionId === sessionId;
|
|
838
|
+
const wasDesktop = this.lastScreenShare && this.lastScreenShare.desktop;
|
|
839
|
+
const promise = this.client.unhold(sipSession, isConference);
|
|
840
|
+
if (hasVideo) {
|
|
841
|
+
const constraints = {
|
|
842
|
+
audio: false,
|
|
843
|
+
video: true,
|
|
844
|
+
screen: wasScreensharing,
|
|
845
|
+
desktop: wasDesktop,
|
|
846
|
+
};
|
|
847
|
+
yield this.client.upgradeToVideo(sipSession, constraints, isConference);
|
|
848
|
+
}
|
|
849
|
+
const onScreenSharing = (stream) => {
|
|
850
|
+
const hadVideo = this.lastScreenShare && this.lastScreenShare.hadVideo;
|
|
851
|
+
if (stream) {
|
|
852
|
+
this._onScreenSharing(stream, sipSession, callSession, hadVideo);
|
|
853
|
+
}
|
|
854
|
+
this.lastScreenShare = null;
|
|
855
|
+
};
|
|
856
|
+
if (withEvent) {
|
|
857
|
+
const updatedCallSession = this._createCallSession(sipSession, callSession);
|
|
858
|
+
// Deprecated event
|
|
859
|
+
this.eventEmitter.emit(exports.ON_CALL_UNHELD, updatedCallSession);
|
|
860
|
+
this.eventEmitter.emit(exports.ON_CALL_RESUMED, updatedCallSession);
|
|
861
|
+
}
|
|
862
|
+
return promise.then(() => {
|
|
863
|
+
const stream = callSession ? this.getLocalVideoStream(callSession) : null;
|
|
864
|
+
if (wasScreensharing) {
|
|
865
|
+
onScreenSharing(stream);
|
|
866
|
+
}
|
|
867
|
+
return stream;
|
|
868
|
+
});
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
mute(callSession, withEvent = true) {
|
|
872
|
+
logger.info('WebRTC mute called', {
|
|
873
|
+
id: callSession ? callSession.getId() : null,
|
|
874
|
+
});
|
|
875
|
+
const sipSession = this.findSipSession(callSession);
|
|
876
|
+
if (!sipSession) {
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
logger.info('WebRTC muting', {
|
|
880
|
+
sipId: sipSession.id,
|
|
881
|
+
});
|
|
882
|
+
this.client.mute(sipSession);
|
|
883
|
+
const newCallSession = this._createCallSession(sipSession, callSession, {
|
|
884
|
+
muted: true,
|
|
885
|
+
});
|
|
886
|
+
if (this.currentCallSession && newCallSession.is(this.currentCallSession)) {
|
|
887
|
+
this.currentCallSession = newCallSession;
|
|
888
|
+
}
|
|
889
|
+
if (withEvent) {
|
|
890
|
+
this.eventEmitter.emit(exports.ON_CALL_MUTED, newCallSession);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
unmute(callSession, withEvent = true) {
|
|
894
|
+
logger.info('WebRTC unmute called', {
|
|
895
|
+
id: callSession ? callSession.getId() : null,
|
|
896
|
+
});
|
|
897
|
+
const sipSession = this.findSipSession(callSession);
|
|
898
|
+
if (!sipSession) {
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
logger.info('WebRTC unmuting', {
|
|
902
|
+
sipId: sipSession.id,
|
|
903
|
+
});
|
|
904
|
+
this.client.unmute(sipSession);
|
|
905
|
+
const newCallSession = this._createCallSession(sipSession, callSession, {
|
|
906
|
+
muted: false,
|
|
907
|
+
});
|
|
908
|
+
if (this.currentCallSession && newCallSession.is(this.currentCallSession)) {
|
|
909
|
+
this.currentCallSession = newCallSession;
|
|
910
|
+
}
|
|
911
|
+
if (withEvent) {
|
|
912
|
+
this.eventEmitter.emit(exports.ON_CALL_UNMUTED, newCallSession);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
isAudioMuted(callSession) {
|
|
916
|
+
const sipSession = this.findSipSession(callSession);
|
|
917
|
+
if (!sipSession) {
|
|
918
|
+
return true;
|
|
919
|
+
}
|
|
920
|
+
return this.client.isAudioMuted(sipSession);
|
|
921
|
+
}
|
|
922
|
+
turnCameraOn(callSession) {
|
|
923
|
+
const sipSession = this.findSipSession(callSession);
|
|
924
|
+
if (!sipSession) {
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
logger.info('WebRTC turn camera on', {
|
|
928
|
+
sipId: sipSession.id,
|
|
929
|
+
});
|
|
930
|
+
this.client.toggleCameraOn(sipSession);
|
|
931
|
+
this.eventEmitter.emit(exports.ON_CAMERA_RESUMED, this._createCameraResumedCallSession(sipSession, callSession));
|
|
932
|
+
}
|
|
933
|
+
turnCameraOff(callSession) {
|
|
934
|
+
const sipSession = this.findSipSession(callSession);
|
|
935
|
+
if (!sipSession) {
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
938
|
+
logger.info('WebRTC turn camera off', {
|
|
939
|
+
sipId: sipSession.id,
|
|
940
|
+
});
|
|
941
|
+
this.client.toggleCameraOff(sipSession);
|
|
942
|
+
this.eventEmitter.emit(exports.ON_CAMERA_DISABLED, this._createCameraDisabledCallSession(sipSession, callSession));
|
|
943
|
+
}
|
|
944
|
+
sendKey(callSession, tone) {
|
|
945
|
+
const sipSession = this.findSipSession(callSession);
|
|
946
|
+
if (!sipSession) {
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
logger.info('WebRTC send key', {
|
|
950
|
+
sipId: sipSession.id,
|
|
951
|
+
tone,
|
|
952
|
+
});
|
|
953
|
+
this.client.sendDTMF(sipSession, tone);
|
|
954
|
+
}
|
|
955
|
+
// Should be async to match CTIPhone definition
|
|
956
|
+
// @TODO: line is not used here
|
|
957
|
+
makeCall(number, line, cameraEnabled, audioOnly = false, conference = false) {
|
|
958
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
959
|
+
logger.info('make WebRTC call', {
|
|
960
|
+
number,
|
|
961
|
+
lineId: line ? line.id : null,
|
|
962
|
+
cameraEnabled,
|
|
963
|
+
audioOnly,
|
|
964
|
+
conference,
|
|
965
|
+
});
|
|
966
|
+
if (!number) {
|
|
967
|
+
return Promise.resolve(null);
|
|
968
|
+
}
|
|
969
|
+
if (!this.client.isRegistered()) {
|
|
970
|
+
yield this.client.register();
|
|
971
|
+
}
|
|
972
|
+
if (this.currentSipSession) {
|
|
973
|
+
this.holdSipSession(this.currentSipSession, this.currentCallSession, true).catch(e => {
|
|
974
|
+
logger.warn('Unable to hold current session when making another call', e);
|
|
975
|
+
});
|
|
976
|
+
}
|
|
977
|
+
let sipSession;
|
|
978
|
+
try {
|
|
979
|
+
sipSession = this.client.call(number, this.allowVideo ? cameraEnabled : false, audioOnly, conference);
|
|
980
|
+
this._bindEvents(sipSession);
|
|
981
|
+
}
|
|
982
|
+
catch (error) {
|
|
983
|
+
console.warn(error);
|
|
984
|
+
logger.warn('make WebRTC call, error', {
|
|
985
|
+
message: error.message,
|
|
986
|
+
stack: error.stack,
|
|
987
|
+
});
|
|
988
|
+
return Promise.resolve(null);
|
|
989
|
+
}
|
|
990
|
+
const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
|
|
991
|
+
callSession.setIsConference(conference);
|
|
992
|
+
callSession.creationTime = new Date();
|
|
993
|
+
this._updateCallSession(callSession);
|
|
994
|
+
this.eventEmitter.emit(exports.ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
|
|
995
|
+
this.currentSipSession = sipSession;
|
|
996
|
+
this.currentCallSession = callSession;
|
|
997
|
+
this.eventEmitter.emit(exports.ON_CALL_OUTGOING, callSession);
|
|
998
|
+
// If an invite promise exists, catch exceptions on it to trigger error like OverConstraintsError.
|
|
999
|
+
// @ts-ignore
|
|
1000
|
+
if (sipSession.invitePromise) {
|
|
1001
|
+
// @ts-ignore
|
|
1002
|
+
sipSession.invitePromise.catch(error => {
|
|
1003
|
+
this.eventEmitter.emit(exports.ON_CALL_ERROR, error, callSession);
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
return Promise.resolve(callSession);
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
transfer(callSession, target) {
|
|
1010
|
+
const sipSession = this.findSipSession(callSession);
|
|
1011
|
+
if (!sipSession) {
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
logger.info('WebRTC transfer', {
|
|
1015
|
+
sipId: sipSession.id,
|
|
1016
|
+
target,
|
|
1017
|
+
});
|
|
1018
|
+
this.client.transfer(sipSession, target);
|
|
1019
|
+
}
|
|
1020
|
+
indirectTransfer(source, destination) {
|
|
1021
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1022
|
+
const sipSession = this.client.getSipSession(source.sipCallId);
|
|
1023
|
+
const sipSessionTarget = this.client.getSipSession(destination.sipCallId);
|
|
1024
|
+
logger.info('WebRTC indirect transfer', {
|
|
1025
|
+
sipId: sipSession ? sipSession.id : null,
|
|
1026
|
+
target: sipSessionTarget ? sipSessionTarget.id : null,
|
|
1027
|
+
});
|
|
1028
|
+
if (!sipSessionTarget) {
|
|
1029
|
+
return Promise.reject();
|
|
1030
|
+
}
|
|
1031
|
+
return new Promise(resolve => {
|
|
1032
|
+
const options = {
|
|
1033
|
+
requestDelegate: {
|
|
1034
|
+
onAccept: () => {
|
|
1035
|
+
// Wait a little so the REFER will take effect
|
|
1036
|
+
setTimeout(() => {
|
|
1037
|
+
this.hangup(destination).then(resolve);
|
|
1038
|
+
}, 200);
|
|
1039
|
+
},
|
|
1040
|
+
},
|
|
1041
|
+
};
|
|
1042
|
+
return sipSessionTarget.refer(sipSession, options);
|
|
1043
|
+
});
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
initiateCTIIndirectTransfer() { }
|
|
1047
|
+
cancelCTIIndirectTransfer() { }
|
|
1048
|
+
confirmCTIIndirectTransfer() { }
|
|
1049
|
+
hangup(callSession) {
|
|
1050
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1051
|
+
const sipSession = this.findSipSession(callSession);
|
|
1052
|
+
if (!sipSession) {
|
|
1053
|
+
console.error('Call is unknown to the WebRTC phone', callSession ? callSession.sipCallId : null, callSession ? callSession.callId : null);
|
|
1054
|
+
return false;
|
|
1055
|
+
}
|
|
1056
|
+
logger.info('WebRTC hangup', {
|
|
1057
|
+
sipId: sipSession.id,
|
|
1058
|
+
});
|
|
1059
|
+
const sipSessionId = this.getSipSessionId(sipSession);
|
|
1060
|
+
yield this.client.hangup(sipSession);
|
|
1061
|
+
if (callSession) {
|
|
1062
|
+
// Removal of `this.callSessions` will be done in `_onCallTerminated`.
|
|
1063
|
+
this.endCurrentCall(callSession);
|
|
1064
|
+
}
|
|
1065
|
+
else if (sipSessionId) {
|
|
1066
|
+
if (callSession) {
|
|
1067
|
+
delete this.callSessions[sipSessionId];
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
this.shouldSendReinvite = false;
|
|
1071
|
+
return true;
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
getStats(callSession) {
|
|
1075
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1076
|
+
const sipSession = this.findSipSession(callSession);
|
|
1077
|
+
return sipSession ? this.client.getStats(sipSession) : null;
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
startNetworkMonitoring(callSession, interval = 1000) {
|
|
1081
|
+
const sipSession = this.findSipSession(callSession);
|
|
1082
|
+
return sipSession ? this.client.startNetworkMonitoring(sipSession, interval) : null;
|
|
1083
|
+
}
|
|
1084
|
+
stopNetworkMonitoring(callSession) {
|
|
1085
|
+
const sipSession = this.findSipSession(callSession);
|
|
1086
|
+
return sipSession ? this.client.stopNetworkMonitoring(sipSession) : null;
|
|
1087
|
+
}
|
|
1088
|
+
forceCancel(sipSession) {
|
|
1089
|
+
// @ts-ignore
|
|
1090
|
+
if (!sipSession || !sipSession.outgoingInviteRequest) {
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1093
|
+
// @ts-ignore
|
|
1094
|
+
sipSession.outgoingInviteRequest.cancel();
|
|
1095
|
+
}
|
|
1096
|
+
endCurrentCall(callSession) {
|
|
1097
|
+
const isCurrent = this.isCurrentCallSipSession(callSession);
|
|
1098
|
+
logger.info('Ending current call', {
|
|
1099
|
+
id: callSession ? callSession.getId() : null,
|
|
1100
|
+
isCurrent,
|
|
1101
|
+
});
|
|
1102
|
+
if (isCurrent) {
|
|
1103
|
+
this.currentSipSession = undefined;
|
|
1104
|
+
this.currentCallSession = null;
|
|
1105
|
+
}
|
|
1106
|
+
this.eventEmitter.emit(exports.ON_TERMINATE_SOUND, callSession, 'locally ended');
|
|
1107
|
+
}
|
|
1108
|
+
onConnectionMade() { }
|
|
1109
|
+
isConference(callSession) {
|
|
1110
|
+
if (!callSession) {
|
|
1111
|
+
return false;
|
|
1112
|
+
}
|
|
1113
|
+
return this.client && this.client.isConference(callSession.sipCallId);
|
|
1114
|
+
}
|
|
1115
|
+
close(force = false) {
|
|
1116
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1117
|
+
logger.info('WebRTC close');
|
|
1118
|
+
try {
|
|
1119
|
+
yield Promise.race([this.unregister(), new Promise((resolve, reject) => setTimeout(() => reject(new Error('Unregister, timed out')), 3000))]);
|
|
1120
|
+
}
|
|
1121
|
+
catch (e) {
|
|
1122
|
+
logger.error('WebRTC close, unregister error', e);
|
|
1123
|
+
}
|
|
1124
|
+
this.client.close(force);
|
|
1125
|
+
this.unbind();
|
|
1126
|
+
this.incomingSessions = [];
|
|
1127
|
+
this.currentSipSession = undefined;
|
|
1128
|
+
this.currentCallSession = null;
|
|
1129
|
+
this.shouldSendReinvite = false;
|
|
1130
|
+
this.rejectedSessions = {};
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
isRegistered() {
|
|
1134
|
+
return this.client && this.client.isRegistered();
|
|
1135
|
+
}
|
|
1136
|
+
enableRinging() {
|
|
1137
|
+
logger.info('WebRTC enable ringing');
|
|
1138
|
+
this.ringingEnabled = true;
|
|
1139
|
+
}
|
|
1140
|
+
disableRinging() {
|
|
1141
|
+
logger.info('WebRTC disable ringing');
|
|
1142
|
+
this.ringingEnabled = false;
|
|
1143
|
+
}
|
|
1144
|
+
getCurrentCallSession() {
|
|
1145
|
+
if (!this.currentSipSession) {
|
|
1146
|
+
return null;
|
|
1147
|
+
}
|
|
1148
|
+
return this._createCallSession(this.currentSipSession, this.currentCallSession);
|
|
1149
|
+
}
|
|
1150
|
+
hasIncomingCallSession() {
|
|
1151
|
+
return this.incomingSessions.length > 0;
|
|
1152
|
+
}
|
|
1153
|
+
getIncomingCallSession() {
|
|
1154
|
+
if (!this.hasIncomingCallSession()) {
|
|
1155
|
+
return null;
|
|
1156
|
+
}
|
|
1157
|
+
const sessionId = this.incomingSessions[0];
|
|
1158
|
+
const sipSession = this.client.getSipSession(sessionId);
|
|
1159
|
+
if (!sipSession) {
|
|
1160
|
+
return null;
|
|
1161
|
+
}
|
|
1162
|
+
return this._createCallSession(sipSession);
|
|
1163
|
+
}
|
|
1164
|
+
// eslint-disable-next-line @typescript-eslint/default-param-last
|
|
1165
|
+
sendMessage(sipSession = null, body, contentType = 'text/plain') {
|
|
1166
|
+
return this.client.sendMessage(sipSession, body, contentType);
|
|
1167
|
+
}
|
|
1168
|
+
getLocalStream(callSession) {
|
|
1169
|
+
return callSession ? this.client.getLocalStream(callSession.sipCallId) : null;
|
|
1170
|
+
}
|
|
1171
|
+
getLocalVideoStream(callSession) {
|
|
1172
|
+
return callSession ? this.client.getLocalVideoStream(callSession.sipCallId) : null;
|
|
1173
|
+
}
|
|
1174
|
+
// Deprecated
|
|
1175
|
+
getLocalMediaStream(callSession) {
|
|
1176
|
+
logger.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
|
|
1177
|
+
return this.getLocalStream(callSession);
|
|
1178
|
+
}
|
|
1179
|
+
hasLocalVideo(callSession) {
|
|
1180
|
+
return callSession ? this.client.hasLocalVideo(callSession.sipCallId) : false;
|
|
1181
|
+
}
|
|
1182
|
+
hasALocalVideoTrack(callSession) {
|
|
1183
|
+
return callSession ? this.client.hasALocalVideoTrack(callSession.sipCallId) : false;
|
|
1184
|
+
}
|
|
1185
|
+
getRemoteStream(callSession) {
|
|
1186
|
+
return callSession ? this.client.getRemoteStream(callSession.sipCallId) : null;
|
|
1187
|
+
}
|
|
1188
|
+
getRemoteVideoStream(callSession) {
|
|
1189
|
+
return callSession ? this.client.getRemoteVideoStream(callSession.sipCallId) : null;
|
|
1190
|
+
}
|
|
1191
|
+
getRemoteVideoStreamFromPc(callSession) {
|
|
1192
|
+
return callSession ? this.client.getRemoteVideoStreamFromPc(callSession.sipCallId) : null;
|
|
1193
|
+
}
|
|
1194
|
+
hasRemoteVideo(callSession) {
|
|
1195
|
+
return callSession ? this.client.hasRemoteVideo(callSession.sipCallId) : false;
|
|
1196
|
+
}
|
|
1197
|
+
setMediaConstraints(media) {
|
|
1198
|
+
this.client.setMediaConstraints(media);
|
|
1199
|
+
}
|
|
1200
|
+
isVideoRemotelyHeld(callSession) {
|
|
1201
|
+
return callSession ? this.client.isVideoRemotelyHeld(callSession.sipCallId) : false;
|
|
1202
|
+
}
|
|
1203
|
+
bindClientEvents() {
|
|
1204
|
+
this.client.unbind();
|
|
1205
|
+
this.client.on(this.client.INVITE, (sipSession, wantsToDoVideo) => {
|
|
1206
|
+
const autoAnswer = sipSession.request.getHeader('Answer-Mode') === 'Auto';
|
|
1207
|
+
const withVideo = this.allowVideo ? wantsToDoVideo : false;
|
|
1208
|
+
logger.info('WebRTC invite received', {
|
|
1209
|
+
sipId: sipSession.id,
|
|
1210
|
+
withVideo,
|
|
1211
|
+
autoAnswer,
|
|
1212
|
+
});
|
|
1213
|
+
const callSession = this._createIncomingCallSession(sipSession, withVideo, null, autoAnswer);
|
|
1214
|
+
this.incomingSessions.push(callSession.getId());
|
|
1215
|
+
this._bindEvents(sipSession);
|
|
1216
|
+
this.client.storeSipSession(sipSession);
|
|
1217
|
+
if (!this.currentSipSession) {
|
|
1218
|
+
if (this.ringingEnabled) {
|
|
1219
|
+
this.eventEmitter.emit(exports.ON_PLAY_RING_SOUND, this.audioRingDeviceId, this.audioRingVolume, callSession);
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
else {
|
|
1223
|
+
this.eventEmitter.emit(exports.ON_PLAY_INBOUND_CALL_SIGNAL_SOUND, this.audioOutputDeviceId, this.audioOutputVolume, callSession);
|
|
1224
|
+
}
|
|
1225
|
+
callSession.creationTime = new Date();
|
|
1226
|
+
this._updateCallSession(callSession);
|
|
1227
|
+
this.eventEmitter.emit(exports.ON_CALL_INCOMING, callSession, wantsToDoVideo);
|
|
1228
|
+
});
|
|
1229
|
+
this.client.on(this.client.ON_REINVITE, (...args) => {
|
|
1230
|
+
logger.info('WebRTC on reinvite', {
|
|
1231
|
+
sessionId: args[0].id,
|
|
1232
|
+
inviteId: args[1].id,
|
|
1233
|
+
updatedCalleeName: args[2],
|
|
1234
|
+
updatedNumber: args[3],
|
|
1235
|
+
});
|
|
1236
|
+
const sipSession = args[0];
|
|
1237
|
+
// Give some time for the stream to be mounted.
|
|
1238
|
+
// if `_createCallSession` is called too soon `hasVideo` will return false because the stream doesn't exists yet
|
|
2144
1239
|
setTimeout(() => {
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
disableRinging() {
|
|
2270
|
-
logger.info('WebRTC disable ringing');
|
|
2271
|
-
this.ringingEnabled = false;
|
|
2272
|
-
}
|
|
2273
|
-
|
|
2274
|
-
getCurrentCallSession() {
|
|
2275
|
-
if (!this.currentSipSession) {
|
|
2276
|
-
return null;
|
|
2277
|
-
}
|
|
2278
|
-
|
|
2279
|
-
return this._createCallSession(this.currentSipSession, this.currentCallSession);
|
|
2280
|
-
}
|
|
2281
|
-
|
|
2282
|
-
hasIncomingCallSession() {
|
|
2283
|
-
return this.incomingSessions.length > 0;
|
|
2284
|
-
}
|
|
2285
|
-
|
|
2286
|
-
getIncomingCallSession() {
|
|
2287
|
-
if (!this.hasIncomingCallSession()) {
|
|
2288
|
-
return null;
|
|
2289
|
-
}
|
|
2290
|
-
|
|
2291
|
-
const sessionId = this.incomingSessions[0];
|
|
2292
|
-
const sipSession = this.client.getSipSession(sessionId);
|
|
2293
|
-
if (!sipSession) {
|
|
2294
|
-
return null;
|
|
2295
|
-
}
|
|
2296
|
-
|
|
2297
|
-
return this._createCallSession(sipSession);
|
|
2298
|
-
}
|
|
2299
|
-
|
|
2300
|
-
sendMessage(sipSession = null, body , contentType = 'text/plain') {
|
|
2301
|
-
return this.client.sendMessage(sipSession, body, contentType);
|
|
2302
|
-
}
|
|
2303
|
-
|
|
2304
|
-
getLocalStream(callSession ) {
|
|
2305
|
-
return callSession ? this.client.getLocalStream(callSession.sipCallId) : null;
|
|
2306
|
-
}
|
|
2307
|
-
|
|
2308
|
-
getLocalVideoStream(callSession ) {
|
|
2309
|
-
return callSession ? this.client.getLocalVideoStream(callSession.sipCallId) : null;
|
|
2310
|
-
}
|
|
2311
|
-
|
|
2312
|
-
// Deprecated
|
|
2313
|
-
getLocalMediaStream(callSession ) {
|
|
2314
|
-
logger.warn('WebRTCPhone.getLocalMediaStream is deprecated, use WebRTCPhone.getLocalStream instead');
|
|
2315
|
-
return this.getLocalStream(callSession);
|
|
2316
|
-
}
|
|
2317
|
-
|
|
2318
|
-
hasLocalVideo(callSession ) {
|
|
2319
|
-
return callSession ? this.client.hasLocalVideo(callSession.sipCallId) : null;
|
|
2320
|
-
}
|
|
2321
|
-
|
|
2322
|
-
hasALocalVideoTrack(callSession ) {
|
|
2323
|
-
return callSession ? this.client.hasALocalVideoTrack(callSession.sipCallId) : null;
|
|
2324
|
-
}
|
|
2325
|
-
|
|
2326
|
-
getRemoteStream(callSession ) {
|
|
2327
|
-
return callSession ? this.client.getRemoteStream(callSession.sipCallId) : null;
|
|
2328
|
-
}
|
|
2329
|
-
|
|
2330
|
-
getRemoteVideoStream(callSession ) {
|
|
2331
|
-
return callSession ? this.client.getRemoteVideoStream(callSession.sipCallId) : null;
|
|
2332
|
-
}
|
|
2333
|
-
|
|
2334
|
-
getRemoteVideoStreamFromPc(callSession ) {
|
|
2335
|
-
return callSession ? this.client.getRemoteVideoStreamFromPc(callSession.sipCallId) : null;
|
|
2336
|
-
}
|
|
2337
|
-
|
|
2338
|
-
hasRemoteVideo(callSession ) {
|
|
2339
|
-
return callSession ? this.client.hasRemoteVideo(callSession.sipCallId) : false;
|
|
2340
|
-
}
|
|
2341
|
-
|
|
2342
|
-
setMediaConstraints(media ) {
|
|
2343
|
-
this.client.setMediaConstraints(media);
|
|
2344
|
-
}
|
|
2345
|
-
|
|
2346
|
-
isVideoRemotelyHeld(callSession ) {
|
|
2347
|
-
return callSession ? this.client.isVideoRemotelyHeld(callSession.sipCallId) : null;
|
|
2348
|
-
}
|
|
2349
|
-
|
|
2350
|
-
bindClientEvents() {
|
|
2351
|
-
this.client.unbind();
|
|
2352
|
-
|
|
2353
|
-
this.client.on(this.client.INVITE, (sipSession , wantsToDoVideo ) => {
|
|
2354
|
-
const autoAnswer = sipSession.request.getHeader('Answer-Mode') === 'Auto';
|
|
2355
|
-
const withVideo = this.allowVideo ? wantsToDoVideo : false;
|
|
2356
|
-
logger.info('WebRTC invite received', { sipId: sipSession.id, withVideo, autoAnswer });
|
|
2357
|
-
|
|
2358
|
-
const callSession = this._createIncomingCallSession(sipSession, withVideo, null, autoAnswer);
|
|
2359
|
-
this.incomingSessions.push(callSession.getId());
|
|
2360
|
-
this._bindEvents(sipSession);
|
|
2361
|
-
|
|
2362
|
-
this.client.storeSipSession(sipSession);
|
|
2363
|
-
|
|
2364
|
-
if (!this.currentSipSession) {
|
|
2365
|
-
if (this.ringingEnabled) {
|
|
2366
|
-
this.eventEmitter.emit(ON_PLAY_RING_SOUND, this.audioRingDeviceId, this.audioRingVolume, callSession);
|
|
1240
|
+
// Update callSession
|
|
1241
|
+
this._createCallSession(sipSession, this.callSessions[this.getSipSessionId(sipSession)]);
|
|
1242
|
+
this.eventEmitter.emit.apply(this.eventEmitter, [this.client.ON_REINVITE, ...args]);
|
|
1243
|
+
}, 2000);
|
|
1244
|
+
});
|
|
1245
|
+
this.client.on(this.client.ACCEPTED, (sipSession) => {
|
|
1246
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
1247
|
+
const hasSession = (sessionId in this.callSessions);
|
|
1248
|
+
logger.info('WebRTC call accepted', {
|
|
1249
|
+
sipId: sessionId,
|
|
1250
|
+
hasSession,
|
|
1251
|
+
});
|
|
1252
|
+
if (!hasSession) {
|
|
1253
|
+
logger.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', {
|
|
1254
|
+
sessionId,
|
|
1255
|
+
});
|
|
1256
|
+
return;
|
|
1257
|
+
}
|
|
1258
|
+
this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
|
|
1259
|
+
if (this.audioOutputDeviceId) {
|
|
1260
|
+
this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
|
|
1261
|
+
}
|
|
1262
|
+
});
|
|
1263
|
+
this.client.on('ended', () => { });
|
|
1264
|
+
this.client.on(this.client.ON_ERROR, e => {
|
|
1265
|
+
logger.error('WebRTC error', e);
|
|
1266
|
+
this.eventEmitter.emit(exports.ON_CALL_ERROR, e);
|
|
1267
|
+
});
|
|
1268
|
+
this.client.on(this.client.REJECTED, session => {
|
|
1269
|
+
logger.info('WebRTC call rejected', session.id);
|
|
1270
|
+
const callSession = this._createCallSession(session);
|
|
1271
|
+
callSession.endTime = new Date();
|
|
1272
|
+
this._updateCallSession(callSession);
|
|
1273
|
+
this.eventEmitter.emit(exports.ON_CALL_REJECTED, callSession);
|
|
1274
|
+
});
|
|
1275
|
+
this.client.on(this.client.UNREGISTERED, () => {
|
|
1276
|
+
logger.info('WebRTC unregistered');
|
|
1277
|
+
this.eventEmitter.emit(exports.ON_UNREGISTERED);
|
|
1278
|
+
});
|
|
1279
|
+
this.client.on(this.client.ON_DISCONNECTED, () => {
|
|
1280
|
+
logger.info('WebRTC disconnected');
|
|
1281
|
+
this.eventEmitter.emit(exports.ON_DISCONNECTED);
|
|
1282
|
+
});
|
|
1283
|
+
this.client.on(this.client.ON_EARLY_MEDIA, session => {
|
|
1284
|
+
logger.info('WebRTC early media');
|
|
1285
|
+
const callSession = this._createCallSession(session);
|
|
1286
|
+
this.eventEmitter.emit(exports.ON_EARLY_MEDIA, callSession);
|
|
1287
|
+
});
|
|
1288
|
+
this.client.on(this.client.REGISTERED, () => {
|
|
1289
|
+
var _a, _b;
|
|
1290
|
+
logger.info('WebRTC registered', {
|
|
1291
|
+
shouldSendReinvite: this.shouldSendReinvite,
|
|
1292
|
+
state: this.currentSipSession ? this.currentSipSession.state : null,
|
|
1293
|
+
currentSipSession: !!this.currentSipSession,
|
|
1294
|
+
});
|
|
1295
|
+
this.stopHeartbeat();
|
|
1296
|
+
this.eventEmitter.emit(exports.ON_REGISTERED);
|
|
1297
|
+
// If the phone registered with a current callSession (eg: when switching network):
|
|
1298
|
+
// send a reinvite to renegociate ICE with new IP
|
|
1299
|
+
if (this.shouldSendReinvite && this.currentSipSession && this.currentSipSession.state === session_state_1.SessionState.Established) {
|
|
1300
|
+
this.shouldSendReinvite = false;
|
|
1301
|
+
// @ts-ignore
|
|
1302
|
+
const pc = (_b = (_a = this.currentSipSession) === null || _a === void 0 ? void 0 : _a.sessionDescriptionHandler) === null || _b === void 0 ? void 0 : _b.peerConnection;
|
|
1303
|
+
const isConference = pc ? pc.sfu : false;
|
|
1304
|
+
const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
|
|
1305
|
+
try {
|
|
1306
|
+
// Send reinvite with iceRestart
|
|
1307
|
+
this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
|
|
1308
|
+
}
|
|
1309
|
+
catch (e) {
|
|
1310
|
+
logger.error('WebRTC reinvite after register, error', {
|
|
1311
|
+
message: e.message,
|
|
1312
|
+
stack: e.stack,
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
});
|
|
1317
|
+
this.client.on(this.client.CONNECTED, () => {
|
|
1318
|
+
logger.info('WebRTC client connected');
|
|
1319
|
+
this.stopHeartbeat();
|
|
1320
|
+
});
|
|
1321
|
+
this.client.on(this.client.DISCONNECTED, () => {
|
|
1322
|
+
logger.info('WebRTC client disconnected');
|
|
1323
|
+
this.eventEmitter.emit(exports.ON_UNREGISTERED);
|
|
1324
|
+
// Do not trigger heartbeat if already running
|
|
1325
|
+
if (!this.client.hasHeartbeat()) {
|
|
1326
|
+
this.startHeartbeat();
|
|
1327
|
+
}
|
|
1328
|
+
// Tell to send reinvite when reconnecting
|
|
1329
|
+
this.shouldSendReinvite = true;
|
|
1330
|
+
});
|
|
1331
|
+
this.client.on(this.client.ON_TRACK, (session, event) => {
|
|
1332
|
+
this.eventEmitter.emit(exports.ON_TRACK, session, event);
|
|
1333
|
+
});
|
|
1334
|
+
this.client.on('onVideoInputChange', stream => {
|
|
1335
|
+
this.eventEmitter.emit(exports.ON_VIDEO_INPUT_CHANGE, stream);
|
|
1336
|
+
});
|
|
1337
|
+
this.client.on(this.client.MESSAGE, (message) => {
|
|
1338
|
+
this._onMessage(message);
|
|
1339
|
+
this.eventEmitter.emit(exports.ON_MESSAGE, message);
|
|
1340
|
+
});
|
|
1341
|
+
this.client.on(this.client.ON_NETWORK_STATS, (session, stats, previousStats) => {
|
|
1342
|
+
const callSession = this.getCallSession(this.getSipSessionId(session));
|
|
1343
|
+
this.eventEmitter.emit(exports.ON_NETWORK_STATS, callSession, stats, previousStats);
|
|
1344
|
+
});
|
|
1345
|
+
// Used when upgrading directly in screenshare mode
|
|
1346
|
+
this.client.on(this.client.ON_SCREEN_SHARING_REINVITE, (sipSession, response, desktop) => {
|
|
1347
|
+
const sipSessionId = this.getSipSessionId(sipSession);
|
|
1348
|
+
const localStream = this.client.getLocalStream(sipSessionId);
|
|
1349
|
+
const callSession = this.callSessions[sipSessionId];
|
|
1350
|
+
logger.info('Updrading directly in screensharing mode', {
|
|
1351
|
+
sipSessionId,
|
|
1352
|
+
tracks: (localStream === null || localStream === void 0 ? void 0 : localStream.getTracks()) || null,
|
|
1353
|
+
});
|
|
1354
|
+
this._onScreenSharing(localStream, sipSession, callSession, false, desktop);
|
|
1355
|
+
});
|
|
1356
|
+
}
|
|
1357
|
+
// Find a corresponding sipSession from a CallSession
|
|
1358
|
+
findSipSession(callSession) {
|
|
1359
|
+
const keys = this.client.getSipSessionIds();
|
|
1360
|
+
const keyIndex = keys.findIndex(sessionId => callSession && callSession.isId(sessionId));
|
|
1361
|
+
if (keyIndex === -1) {
|
|
1362
|
+
const currentSipSessionId = this.currentSipSession ? this.getSipSessionId(this.currentSipSession) : this.client.getSipSessionIds()[0];
|
|
1363
|
+
return currentSipSessionId ? this.client.getSipSession(currentSipSessionId) : null;
|
|
2367
1364
|
}
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
}
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
// if `_createCallSession` is called too soon `hasVideo` will return false because the stream doesn't exists yet
|
|
2393
|
-
setTimeout(() => {
|
|
2394
|
-
// Update callSession
|
|
2395
|
-
this._createCallSession(sipSession, this.callSessions[this.getSipSessionId(sipSession)]);
|
|
2396
|
-
|
|
2397
|
-
this.eventEmitter.emit.apply(this.eventEmitter, [this.client.ON_REINVITE, ...args]);
|
|
2398
|
-
}, 2000);
|
|
2399
|
-
});
|
|
2400
|
-
|
|
2401
|
-
this.client.on(this.client.ACCEPTED, (sipSession ) => {
|
|
2402
|
-
const sessionId = this.getSipSessionId(sipSession);
|
|
2403
|
-
const hasSession = sessionId in this.callSessions;
|
|
2404
|
-
|
|
2405
|
-
logger.info('WebRTC call accepted', { sipId: sessionId, hasSession });
|
|
2406
|
-
|
|
2407
|
-
if (!hasSession) {
|
|
2408
|
-
logger.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
|
|
2409
|
-
return;
|
|
2410
|
-
}
|
|
2411
|
-
|
|
2412
|
-
this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
|
|
2413
|
-
|
|
2414
|
-
if (this.audioOutputDeviceId) {
|
|
2415
|
-
this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
|
|
2416
|
-
}
|
|
2417
|
-
});
|
|
2418
|
-
this.client.on('ended', () => {});
|
|
2419
|
-
|
|
2420
|
-
this.client.on(this.client.ON_ERROR, e => {
|
|
2421
|
-
logger.error('WebRTC error', e);
|
|
2422
|
-
this.eventEmitter.emit(ON_CALL_ERROR, e);
|
|
2423
|
-
});
|
|
2424
|
-
|
|
2425
|
-
this.client.on(this.client.REJECTED, session => {
|
|
2426
|
-
logger.info('WebRTC call rejected', session.id);
|
|
2427
|
-
const callSession = this._createCallSession(session);
|
|
2428
|
-
callSession.endTime = new Date();
|
|
2429
|
-
this._updateCallSession(callSession);
|
|
2430
|
-
|
|
2431
|
-
this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
|
|
2432
|
-
});
|
|
2433
|
-
|
|
2434
|
-
this.client.on(this.client.UNREGISTERED, () => {
|
|
2435
|
-
logger.info('WebRTC unregistered');
|
|
2436
|
-
this.eventEmitter.emit(ON_UNREGISTERED);
|
|
2437
|
-
});
|
|
2438
|
-
|
|
2439
|
-
this.client.on(this.client.ON_DISCONNECTED, () => {
|
|
2440
|
-
logger.info('WebRTC disconnected');
|
|
2441
|
-
this.eventEmitter.emit(ON_DISCONNECTED);
|
|
2442
|
-
});
|
|
2443
|
-
this.client.on(this.client.ON_EARLY_MEDIA, session => {
|
|
2444
|
-
logger.info('WebRTC early media');
|
|
2445
|
-
const callSession = this._createCallSession(session);
|
|
2446
|
-
this.eventEmitter.emit(ON_EARLY_MEDIA, callSession);
|
|
2447
|
-
});
|
|
2448
|
-
|
|
2449
|
-
this.client.on(this.client.REGISTERED, () => {
|
|
2450
|
-
logger.info('WebRTC registered', {
|
|
2451
|
-
shouldSendReinvite: this.shouldSendReinvite,
|
|
2452
|
-
state: this.currentSipSession ? this.currentSipSession.state : null,
|
|
2453
|
-
currentSipSession: !!this.currentSipSession,
|
|
2454
|
-
});
|
|
2455
|
-
this.stopHeartbeat();
|
|
2456
|
-
this.eventEmitter.emit(ON_REGISTERED);
|
|
2457
|
-
|
|
2458
|
-
// If the phone registered with a current callSession (eg: when switching network):
|
|
2459
|
-
// send a reinvite to renegociate ICE with new IP
|
|
2460
|
-
if (this.shouldSendReinvite && this.currentSipSession
|
|
2461
|
-
&& this.currentSipSession.state === sessionState.SessionState.Established) {
|
|
2462
|
-
this.shouldSendReinvite = false;
|
|
2463
|
-
const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
|
|
2464
|
-
const isConference = pc ? pc.sfu : false;
|
|
2465
|
-
const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
|
|
2466
|
-
|
|
1365
|
+
return this.client.getSipSession(keys[keyIndex]);
|
|
1366
|
+
}
|
|
1367
|
+
getCallSession(sipSessionId) {
|
|
1368
|
+
return this.callSessions[sipSessionId];
|
|
1369
|
+
}
|
|
1370
|
+
getSipSessionId(sipSession) {
|
|
1371
|
+
return this.client.getSipSessionId(sipSession);
|
|
1372
|
+
}
|
|
1373
|
+
getSipSessionIdFromCallSession(callSession) {
|
|
1374
|
+
const sipSession = this.findSipSession(callSession);
|
|
1375
|
+
return sipSession ? this.getSipSessionId(sipSession) : null;
|
|
1376
|
+
}
|
|
1377
|
+
_updateCallSession(callSession) {
|
|
1378
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
1379
|
+
if (sipSessionId) {
|
|
1380
|
+
this.callSessions[sipSessionId] = callSession;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
_onMessage(message) {
|
|
1384
|
+
// @ts-ignore
|
|
1385
|
+
if (!message || message.method !== 'MESSAGE') {
|
|
1386
|
+
return;
|
|
1387
|
+
}
|
|
1388
|
+
let body;
|
|
2467
1389
|
try {
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
} catch (e) {
|
|
2471
|
-
logger.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
|
|
1390
|
+
// @ts-ignore
|
|
1391
|
+
body = JSON.parse(message.body);
|
|
2472
1392
|
}
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
}
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
}
|
|
2544
|
-
|
|
2545
|
-
getCallSession(sipSessionId ) {
|
|
2546
|
-
return this.callSessions[sipSessionId];
|
|
2547
|
-
}
|
|
2548
|
-
|
|
2549
|
-
getSipSessionId(sipSession ) {
|
|
2550
|
-
return this.client.getSipSessionId(sipSession);
|
|
2551
|
-
}
|
|
2552
|
-
|
|
2553
|
-
getSipSessionIdFromCallSession(callSession ) {
|
|
2554
|
-
const sipSession = this.findSipSession(callSession);
|
|
2555
|
-
|
|
2556
|
-
return sipSession ? this.getSipSessionId(sipSession) : null;
|
|
2557
|
-
}
|
|
2558
|
-
|
|
2559
|
-
_updateCallSession(callSession ) {
|
|
2560
|
-
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
2561
|
-
|
|
2562
|
-
if (sipSessionId) {
|
|
2563
|
-
this.callSessions[sipSessionId] = callSession;
|
|
2564
|
-
}
|
|
2565
|
-
}
|
|
2566
|
-
|
|
2567
|
-
_onMessage(message ) {
|
|
2568
|
-
if (!message || message.method !== 'MESSAGE') {
|
|
2569
|
-
return;
|
|
2570
|
-
}
|
|
2571
|
-
|
|
2572
|
-
let body;
|
|
2573
|
-
|
|
2574
|
-
try {
|
|
2575
|
-
body = JSON.parse(message.body);
|
|
2576
|
-
} catch (e) {
|
|
2577
|
-
return;
|
|
2578
|
-
}
|
|
2579
|
-
|
|
2580
|
-
const { type, content } = body;
|
|
2581
|
-
|
|
2582
|
-
switch (type) {
|
|
2583
|
-
case MESSAGE_TYPE_CHAT:
|
|
2584
|
-
this.eventEmitter.emit(ON_CHAT, content);
|
|
2585
|
-
break;
|
|
2586
|
-
|
|
2587
|
-
case MESSAGE_TYPE_SIGNAL: {
|
|
2588
|
-
this.eventEmitter.emit(ON_SIGNAL, content);
|
|
2589
|
-
break;
|
|
2590
|
-
}
|
|
2591
|
-
}
|
|
2592
|
-
}
|
|
2593
|
-
|
|
2594
|
-
_createIncomingCallSession(
|
|
2595
|
-
sipSession ,
|
|
2596
|
-
cameraEnabled ,
|
|
2597
|
-
fromSession ,
|
|
2598
|
-
autoAnswer = false,
|
|
2599
|
-
) {
|
|
2600
|
-
return this._createCallSession(sipSession, fromSession, {
|
|
2601
|
-
incoming: true,
|
|
2602
|
-
ringing: true,
|
|
2603
|
-
cameraEnabled,
|
|
2604
|
-
autoAnswer,
|
|
2605
|
-
});
|
|
2606
|
-
}
|
|
2607
|
-
|
|
2608
|
-
_createOutgoingCallSession(
|
|
2609
|
-
sipSession ,
|
|
2610
|
-
cameraEnabled ,
|
|
2611
|
-
fromSession ,
|
|
2612
|
-
) {
|
|
2613
|
-
return this._createCallSession(sipSession, fromSession, { incoming: false, ringing: true, cameraEnabled });
|
|
2614
|
-
}
|
|
2615
|
-
|
|
2616
|
-
_createAcceptedCallSession(
|
|
2617
|
-
sipSession ,
|
|
2618
|
-
cameraEnabled ,
|
|
2619
|
-
fromSession ,
|
|
2620
|
-
) {
|
|
2621
|
-
return this._createCallSession(sipSession, fromSession, {
|
|
2622
|
-
cameraEnabled: cameraEnabled !== undefined ? cameraEnabled : false,
|
|
2623
|
-
});
|
|
2624
|
-
}
|
|
2625
|
-
|
|
2626
|
-
_createMutedCallSession(sipSession , fromSession ) {
|
|
2627
|
-
return this._createCallSession(sipSession, fromSession, {
|
|
2628
|
-
muted: true,
|
|
2629
|
-
});
|
|
2630
|
-
}
|
|
2631
|
-
|
|
2632
|
-
_createUnmutedCallSession(sipSession , fromSession ) {
|
|
2633
|
-
return this._createCallSession(sipSession, fromSession, {
|
|
2634
|
-
muted: false,
|
|
2635
|
-
});
|
|
2636
|
-
}
|
|
2637
|
-
|
|
2638
|
-
_createCameraResumedCallSession(sipSession , fromSession ) {
|
|
2639
|
-
return this._createCallSession(sipSession, fromSession, {
|
|
2640
|
-
videoMuted: false,
|
|
2641
|
-
});
|
|
2642
|
-
}
|
|
2643
|
-
|
|
2644
|
-
_createCameraDisabledCallSession(sipSession , fromSession ) {
|
|
2645
|
-
return this._createCallSession(sipSession, fromSession, {
|
|
2646
|
-
videoMuted: true,
|
|
2647
|
-
});
|
|
2648
|
-
}
|
|
2649
|
-
|
|
2650
|
-
_createCallSession(sipSession , fromSession , extra = {}) {
|
|
2651
|
-
// eslint-disable-next-line
|
|
2652
|
-
const identity = sipSession ? sipSession.remoteIdentity || sipSession.assertedIdentity : null;
|
|
2653
|
-
const number = identity ? identity.uri._normal.user : null;
|
|
2654
|
-
const { state } = sipSession || {};
|
|
2655
|
-
const sessionId = this.getSipSessionId(sipSession);
|
|
2656
|
-
fromSession = fromSession || this.callSessions[sessionId];
|
|
2657
|
-
|
|
2658
|
-
const callSession = new CallSession({
|
|
2659
|
-
callId: fromSession && fromSession.callId,
|
|
2660
|
-
sipCallId: sessionId,
|
|
2661
|
-
sipStatus: state,
|
|
2662
|
-
displayName: identity ? identity.displayName || number : number,
|
|
2663
|
-
startTime: fromSession ? fromSession.startTime : new Date(),
|
|
2664
|
-
creationTime: fromSession ? fromSession.creationTime : null,
|
|
2665
|
-
answerTime: fromSession ? fromSession.answerTime : null,
|
|
2666
|
-
endTime: fromSession ? fromSession.endTime : null,
|
|
2667
|
-
answered: state === sessionState.SessionState.Established,
|
|
2668
|
-
paused: this.client.isCallHeld(sipSession),
|
|
2669
|
-
isCaller: fromSession ? fromSession.isCaller : ('incoming' in extra ? !extra.incoming : false),
|
|
2670
|
-
cameraEnabled: fromSession ? fromSession.isCameraEnabled() : this.client.hasVideo(sessionId),
|
|
2671
|
-
number,
|
|
2672
|
-
ringing: false,
|
|
2673
|
-
muted: fromSession ? fromSession.isMuted() : this.client.isAudioMuted(sipSession),
|
|
2674
|
-
videoMuted: fromSession ? fromSession.isVideoMuted() : false,
|
|
2675
|
-
recording: fromSession ? fromSession.isRecording() : false,
|
|
2676
|
-
recordingPaused: false, // @TODO
|
|
2677
|
-
sipSession,
|
|
2678
|
-
conference: !!fromSession && fromSession.isConference(),
|
|
2679
|
-
...extra,
|
|
2680
|
-
});
|
|
2681
|
-
|
|
2682
|
-
this.callSessions[callSession.getId()] = callSession;
|
|
2683
|
-
|
|
2684
|
-
return callSession;
|
|
2685
|
-
}
|
|
1393
|
+
catch (e) {
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
const { type, content, } = body;
|
|
1397
|
+
switch (type) {
|
|
1398
|
+
case exports.MESSAGE_TYPE_CHAT:
|
|
1399
|
+
this.eventEmitter.emit(exports.ON_CHAT, content);
|
|
1400
|
+
break;
|
|
1401
|
+
case exports.MESSAGE_TYPE_SIGNAL:
|
|
1402
|
+
{
|
|
1403
|
+
this.eventEmitter.emit(exports.ON_SIGNAL, content);
|
|
1404
|
+
break;
|
|
1405
|
+
}
|
|
1406
|
+
default:
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
_createIncomingCallSession(sipSession, cameraEnabled, fromSession, autoAnswer = false) {
|
|
1410
|
+
return this._createCallSession(sipSession, fromSession, {
|
|
1411
|
+
incoming: true,
|
|
1412
|
+
ringing: true,
|
|
1413
|
+
cameraEnabled,
|
|
1414
|
+
autoAnswer,
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
_createOutgoingCallSession(sipSession, cameraEnabled, fromSession) {
|
|
1418
|
+
return this._createCallSession(sipSession, fromSession, {
|
|
1419
|
+
incoming: false,
|
|
1420
|
+
ringing: true,
|
|
1421
|
+
cameraEnabled,
|
|
1422
|
+
});
|
|
1423
|
+
}
|
|
1424
|
+
_createAcceptedCallSession(sipSession, cameraEnabled, fromSession) {
|
|
1425
|
+
return this._createCallSession(sipSession, fromSession, {
|
|
1426
|
+
cameraEnabled: cameraEnabled !== undefined ? cameraEnabled : false,
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1429
|
+
_createMutedCallSession(sipSession, fromSession) {
|
|
1430
|
+
return this._createCallSession(sipSession, fromSession, {
|
|
1431
|
+
muted: true,
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
_createUnmutedCallSession(sipSession, fromSession) {
|
|
1435
|
+
return this._createCallSession(sipSession, fromSession, {
|
|
1436
|
+
muted: false,
|
|
1437
|
+
});
|
|
1438
|
+
}
|
|
1439
|
+
_createCameraResumedCallSession(sipSession, fromSession) {
|
|
1440
|
+
return this._createCallSession(sipSession, fromSession, {
|
|
1441
|
+
videoMuted: false,
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
_createCameraDisabledCallSession(sipSession, fromSession) {
|
|
1445
|
+
return this._createCallSession(sipSession, fromSession, {
|
|
1446
|
+
videoMuted: true,
|
|
1447
|
+
});
|
|
1448
|
+
}
|
|
1449
|
+
_createCallSession(sipSession, fromSession, extra = {}) {
|
|
1450
|
+
// eslint-disable-next-line
|
|
1451
|
+
const identity = sipSession ? sipSession.remoteIdentity || sipSession.assertedIdentity : null;
|
|
1452
|
+
// @ts-ignore
|
|
1453
|
+
const number = identity ? identity.uri._normal.user : null;
|
|
1454
|
+
const { state, } = sipSession || {};
|
|
1455
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
1456
|
+
fromSession = fromSession || this.callSessions[sessionId];
|
|
1457
|
+
const callSession = new CallSession_1.default(Object.assign({ callId: fromSession && fromSession.callId, sipCallId: sessionId, sipStatus: state, displayName: identity ? identity.displayName || number : number,
|
|
1458
|
+
// @ts-ignore: @HEADSUP: startTime should be a number, not a date
|
|
1459
|
+
startTime: fromSession ? fromSession.startTime : new Date(), creationTime: fromSession ? fromSession.creationTime : null, answerTime: fromSession ? fromSession.answerTime : null, endTime: fromSession ? fromSession.endTime : null, answered: state === session_state_1.SessionState.Established, paused: this.client.isCallHeld(sipSession), isCaller: fromSession ? fromSession.isCaller : 'incoming' in extra ? !extra.incoming : false, cameraEnabled: fromSession ? fromSession.isCameraEnabled() : this.client.hasVideo(sessionId), number, ringing: false, muted: fromSession ? fromSession.isMuted() : this.client.isAudioMuted(sipSession), videoMuted: fromSession ? fromSession.isVideoMuted() : false, recording: fromSession ? fromSession.isRecording() : false, recordingPaused: false, sipSession, conference: !!fromSession && fromSession.isConference() }, extra));
|
|
1460
|
+
this.callSessions[callSession.getId()] = callSession;
|
|
1461
|
+
return callSession;
|
|
1462
|
+
}
|
|
2686
1463
|
}
|
|
2687
|
-
|
|
2688
|
-
exports.MESSAGE_TYPE_CHAT = MESSAGE_TYPE_CHAT;
|
|
2689
|
-
exports.MESSAGE_TYPE_SIGNAL = MESSAGE_TYPE_SIGNAL;
|
|
2690
|
-
exports.ON_AUDIO_STREAM = ON_AUDIO_STREAM;
|
|
2691
|
-
exports.ON_CALL_ACCEPTED = ON_CALL_ACCEPTED;
|
|
2692
|
-
exports.ON_CALL_ANSWERED = ON_CALL_ANSWERED;
|
|
2693
|
-
exports.ON_CALL_CANCELED = ON_CALL_CANCELED;
|
|
2694
|
-
exports.ON_CALL_ENDED = ON_CALL_ENDED;
|
|
2695
|
-
exports.ON_CALL_ENDING = ON_CALL_ENDING;
|
|
2696
|
-
exports.ON_CALL_ERROR = ON_CALL_ERROR;
|
|
2697
|
-
exports.ON_CALL_FAILED = ON_CALL_FAILED;
|
|
2698
|
-
exports.ON_CALL_HELD = ON_CALL_HELD;
|
|
2699
|
-
exports.ON_CALL_INCOMING = ON_CALL_INCOMING;
|
|
2700
|
-
exports.ON_CALL_MUTED = ON_CALL_MUTED;
|
|
2701
|
-
exports.ON_CALL_OUTGOING = ON_CALL_OUTGOING;
|
|
2702
|
-
exports.ON_CALL_REJECTED = ON_CALL_REJECTED;
|
|
2703
|
-
exports.ON_CALL_RESUMED = ON_CALL_RESUMED;
|
|
2704
|
-
exports.ON_CALL_UNHELD = ON_CALL_UNHELD;
|
|
2705
|
-
exports.ON_CALL_UNMUTED = ON_CALL_UNMUTED;
|
|
2706
|
-
exports.ON_CAMERA_DISABLED = ON_CAMERA_DISABLED;
|
|
2707
|
-
exports.ON_CAMERA_RESUMED = ON_CAMERA_RESUMED;
|
|
2708
|
-
exports.ON_CHAT = ON_CHAT;
|
|
2709
|
-
exports.ON_DISCONNECTED = ON_DISCONNECTED;
|
|
2710
|
-
exports.ON_EARLY_MEDIA = ON_EARLY_MEDIA;
|
|
2711
|
-
exports.ON_MESSAGE = ON_MESSAGE;
|
|
2712
|
-
exports.ON_MESSAGE_TRACK_UPDATED = ON_MESSAGE_TRACK_UPDATED;
|
|
2713
|
-
exports.ON_NETWORK_STATS = ON_NETWORK_STATS;
|
|
2714
|
-
exports.ON_PLAY_HANGUP_SOUND = ON_PLAY_HANGUP_SOUND;
|
|
2715
|
-
exports.ON_PLAY_INBOUND_CALL_SIGNAL_SOUND = ON_PLAY_INBOUND_CALL_SIGNAL_SOUND;
|
|
2716
|
-
exports.ON_PLAY_PROGRESS_SOUND = ON_PLAY_PROGRESS_SOUND;
|
|
2717
|
-
exports.ON_PLAY_RING_SOUND = ON_PLAY_RING_SOUND;
|
|
2718
|
-
exports.ON_PROGRESS = ON_PROGRESS;
|
|
2719
|
-
exports.ON_REGISTERED = ON_REGISTERED;
|
|
2720
|
-
exports.ON_REINVITE = ON_REINVITE;
|
|
2721
|
-
exports.ON_REMOVE_STREAM = ON_REMOVE_STREAM;
|
|
2722
|
-
exports.ON_SHARE_SCREEN_ENDED = ON_SHARE_SCREEN_ENDED;
|
|
2723
|
-
exports.ON_SHARE_SCREEN_ENDING = ON_SHARE_SCREEN_ENDING;
|
|
2724
|
-
exports.ON_SHARE_SCREEN_STARTED = ON_SHARE_SCREEN_STARTED;
|
|
2725
|
-
exports.ON_SIGNAL = ON_SIGNAL;
|
|
2726
|
-
exports.ON_TERMINATE_SOUND = ON_TERMINATE_SOUND;
|
|
2727
|
-
exports.ON_TRACK = ON_TRACK;
|
|
2728
|
-
exports.ON_UNREGISTERED = ON_UNREGISTERED;
|
|
2729
|
-
exports.ON_USER_AGENT = ON_USER_AGENT;
|
|
2730
|
-
exports.ON_VIDEO_INPUT_CHANGE = ON_VIDEO_INPUT_CHANGE;
|
|
2731
|
-
exports.ON_VIDEO_STREAM = ON_VIDEO_STREAM;
|
|
2732
1464
|
exports.default = WebRTCPhone;
|
|
2733
|
-
exports.events = events;
|