24#include <dhtnet/ice_transport.h>
43#include <pjsip/sip_config.h>
45struct pjsip_inv_session;
46struct pjmedia_sdp_session;
47struct pj_ice_sess_cand;
74 using clock = std::chrono::steady_clock;
75 using time_point = clock::time_point;
103 const std::string&
id,
105 const std::vector<libjami::MediaMap>&
mediaList);
112 void merge(
Call& call)
override;
123 void transfer(
const std::string& to)
override;
133 const std::string& from)
override;
135 void muteMedia(
const std::string& mediaType,
bool isMuted)
override;
139 std::shared_ptr<SystemCodecInfo>
getAudioCodec()
const override;
140 std::shared_ptr<SystemCodecInfo>
getVideoCodec()
const override;
143 std::map<std::string, std::string>
getDetails()
const override;
147 std::mutex sinksMtx_;
149 std::map<std::string, std::shared_ptr<video::SinkClient>>
callSinksMap_ {};
237 return sipTransport_.get();
253 std::lock_guard
lk(transportMtx_);
254 return reinvIceMedia_ ? reinvIceMedia_ : iceMedia_;
280 void setRotation(
int streamIdx,
int rotation);
287 const std::string& deviceId,
288 const std::string& streamId,
293 peerRegisteredName_ = name;
313 std::optional<dhtnet::IceTransportOptions>
options = std::nullopt);
321 inline std::weak_ptr<const SIPCall>
weak()
const
323 return std::weak_ptr<const SIPCall>(shared());
325 inline std::weak_ptr<SIPCall>
weak()
327 return std::weak_ptr<SIPCall>(shared());
337 void generateMediaPorts();
339 void openPortsUPnP();
341 bool isIceRunning()
const;
343 std::unique_ptr<dhtnet::IceSocket> newIceSocket(
unsigned compId);
345 void deinitRecorder();
347 void rtpSetupSuccess();
349 void setupVoiceCallback(
const std::shared_ptr<RtpSession>&
rtpSession);
351 void sendMuteState(
bool state);
352 void sendVoiceActivity(std::string_view streamId,
bool state);
354 void resetTransport(std::shared_ptr<dhtnet::IceTransport>&& transport);
361 void setVideoOrientation(
int streamIdx,
int rotation);
363 mutable std::mutex transportMtx_ {};
394 std::map<std::string, std::shared_ptr<MediaStreamSubject>>
callAVStreams;
397 void setCallMediaLocal();
398 void startIceMedia();
399 void onIceNegoSucceed();
400 void setupNegotiatedMedia();
401 void startAllMedia();
403 void updateRemoteMedia();
410 bool internalOffHold(
const std::function<
void()>&
SDPUpdateFunc);
420 bool isReinviteRequired(
const std::vector<MediaAttribute>&
mediaAttrList);
422 bool isNewIceMediaRequired(
const std::vector<MediaAttribute>&
mediaAttrList);
425 int SIPSessionReinvite();
427 void addMediaStream(
const MediaAttribute&
mediaAttr);
429 size_t initMediaStreams(
const std::vector<MediaAttribute>&
mediaAttrList);
431 void createRtpSession(RtpStream&
rtpStream);
433 void configureRtpSession(
const std::shared_ptr<RtpSession>&
rtpSession,
434 const std::shared_ptr<MediaAttribute>&
mediaAttr,
438 int findRtpStreamIndex(
const std::string&
label)
const;
440 std::vector<IceCandidate> getAllRemoteCandidates(dhtnet::IceTransport& transport)
const;
442 inline std::shared_ptr<const SIPCall> shared()
const
446 inline std::shared_ptr<SIPCall> shared()
452 std::string peerUserAgent_ {};
454 bool peerSupportMultiStream_ {
false};
456 bool peerSupportMultiAudioStream_ {
false};
458 bool peerSupportMultiIce_ {
false};
462 bool peerSupportReuseIceInReinv_ {
false};
465 std::vector<std::string> peerAllowedMethods_;
468 std::vector<RtpStream> rtpStreams_;
475 std::shared_ptr<SipTransport> sipTransport_ {};
480 std::unique_ptr<Sdp> sdp_ {};
481 bool peerHolding_ {
false};
483 bool isWaitingForIceAndMedia_ {
false};
484 enum class Request { HoldingOn, HoldingOff, SwitchInput, NoRequest };
485 Request remainingRequest_ {Request::NoRequest};
487 std::string peerRegisteredName_ {};
489 std::string contactHeader_ {};
491 std::shared_ptr<dhtnet::upnp::Controller> upnp_;
494 unsigned int localAudioPort_ {0};
496 unsigned int localVideoPort_ {0};
498 bool mediaRestartRequired_ {
true};
499 bool enableIce_ {
true};
500 bool srtpEnabled_ {
false};
501 bool rtcpMuxEnabled_ {
false};
504 std::shared_ptr<dhtnet::IceTransport> iceMedia_;
506 std::shared_ptr<dhtnet::IceTransport> reinvIceMedia_;
508 std::string peerUri_ {};
510 bool readyToRecord_ {
false};
511 bool pendingRecord_ {
false};
513 time_point lastKeyFrameReq_ {time_point::min()};
518 std::atomic_bool waitForIceInit_ {
false};
520 void detachAudioFromConference();
522 std::mutex setupSuccessMutex_;
527 std::string mediaPlayerId_ {};
535inline std::shared_ptr<SIPCall>
538 return std::static_pointer_cast<SIPCall>(call.shared_from_this());
std::function< void(bool)> OnReadyCb
CallType
This determines if the call originated from the local user (OUTGOING) or from some remote peer (INCOM...
std::vector< MediaAttribute > getMediaAttributeList() const override
bool hasVideo() const override
void terminateSipSession(int status)
void answerMediaChangeRequest(const std::vector< libjami::MediaMap > &mediaList, bool isRemote=false) override
Answer to a media update request.
std::map< std::string, std::string > getDetails() const override
void setIceMedia(std::shared_ptr< dhtnet::IceTransport > ice, bool isReinvite=false)
void refuse() override
Refuse incoming call.
void onBusyHere()
Peer answered busy.
void switchInput(const std::string &resource={}) override
bool isIceEnabled() const override
Check wether ICE is enabled for media.
std::string_view peerUri() const
void onMediaNegotiationComplete()
Called when the media negotiation (SDP offer/answer) has completed.
bool isSrtpEnabled() const
static constexpr LinkType LINK_TYPE
void setPeerUaVersion(std::string_view ua)
Set peer's User-Agent found in the message header.
void answer() override
Answer the call.
void muteMedia(const std::string &mediaType, bool isMuted) override
mute/unmute a media of a call
void reportMediaNegotiationStatus()
Announce to the client that medias are successfully negotiated.
void handleMediaChangeRequest(const std::vector< libjami::MediaMap > &remoteMediaList) override
Process incoming media change request.
std::vector< std::shared_ptr< RtpSession > > getRtpSessionList(MediaType type=MediaType::MEDIA_ALL) const
void onFailure(signed cause=0)
Called to report server/internal errors.
pj_status_t onReceiveReinvite(const pjmedia_sdp_session *offer, pjsip_rx_data *rdata)
void setActiveMediaStream(const std::string &accountUri, const std::string &deviceId, const std::string &streamId, const bool &state)
bool toggleRecording() override
This method must be implemented for this interface as calls and conferences have different behavior.
void setSipTransport(const std::shared_ptr< SipTransport > &transport, const std::string &contactHdr={})
void onReceiveOfferIn200OK(const pjmedia_sdp_session *offer)
bool createIceMediaTransport(bool isReinvite)
void monitor() const override
Sdp & getSDP()
Return the SDP's manager of this call.
std::vector< libjami::MediaMap > currentMediaList() const override
Retrieve current medias list.
void restartMediaSender() override
std::weak_ptr< SIPCall > weak()
bool offhold(OnReadyCb &&cb) override
Resume a call from hold state.
bool onhold(OnReadyCb &&cb) override
Put a call on hold.
void sendTextMessage(const std::map< std::string, std::string > &messages, const std::string &from) override
Send a message to a call identified by its callid.
void sendKeyframe(int streamIdx=-1) override
std::shared_ptr< SystemCodecInfo > getAudioCodec() const override
const std::vector< RtpStream > & getRtpStreams() const
static size_t getActiveMediaStreamCount(const std::vector< MediaAttribute > &mediaAttrList)
void hangup(int reason) override
Hang up the call.
std::shared_ptr< dhtnet::IceTransport > getIceMedia() const
void peerMuted(bool state, int streamIdx) override
bool initIceMediaTransport(bool master, std::optional< dhtnet::IceTransportOptions > options=std::nullopt)
bool remoteHasValidIceAttributes() const
void exitConference() override
void onClosed()
Peer closed the connection.
void setupIceResponse(bool isReinvite=false)
Setup ICE locally to answer to an ICE offer.
std::shared_ptr< SystemCodecInfo > getVideoCodec() const override
void addLocalIceAttributes()
bool checkMediaChangeRequest(const std::vector< libjami::MediaMap > &remoteMediaList) override
Check the media of an incoming media change request.
bool isCaptureDeviceMuted(const MediaType &mediaType) const override
void onPeerRinging()
Call is in ringing state on peer's side.
void updateRecState(bool state) override
Update recording state.
std::vector< std::string > getLocalIceCandidates(unsigned compId) const
SipTransport * getTransport()
bool attendedTransfer(const std::string &to) override
Attended transfer.
void carryingDTMFdigits(char code) override
Send DTMF.
const std::string & getContactHeader() const
std::shared_ptr< SIPAccountBase > getSIPAccount() const
void transfer(const std::string &to) override
Transfer a call to specified URI.
bool isSipMethodAllowedByPeer(const std::string_view method) const
Check if a SIP method is allowed by peer.
std::map< std::string, bool > getAudioStreams() const override
void setPeerUri(const std::string &peerUri)
void sendSIPInfo(std::string_view body, std::string_view subtype)
std::unique_ptr< pjsip_inv_session, InvSessionDeleter > inviteSession_
void peerVoice(bool state) override
void onAnswered()
Peer answered the call.
void setPeerRegisteredName(const std::string &name)
void removeCall() override
void setPeerAllowMethods(std::vector< std::string > methods)
Set peer's allowed methods.
void switchToIceReinviteIfNeeded()
void enterConference(std::shared_ptr< Conference > conference) override
void peerHungup() override
Peer has hung up a call.
LinkType getLinkType() const override
void peerRecording(bool state) override
std::weak_ptr< const SIPCall > weak() const
void requestKeyframe(int streamIdx=-1)
bool requestMediaChange(const std::vector< libjami::MediaMap > &mediaList) override
Make a change request of the current media with the provided media.
void setInviteSession(pjsip_inv_session *inviteSession=nullptr)
SIP transport wraps pjsip_transport.
void emitSignal(Args... args)
std::shared_ptr< Call > getPtr(Call &call)
Obtain a shared smart pointer of instance.
pj_ice_sess_cand IceCandidate
Simple macro to hide class' copy constructor and assignment operator.
#define NON_COPYABLE(ClassName)
Contains information about an AV subject.
The invite session to be reused in case of transfer.
void operator()(pjsip_inv_session *) const noexcept
std::shared_ptr< MediaAttribute > remoteMediaAttribute_
std::unique_ptr< dhtnet::IceSocket > rtpSocket_
std::unique_ptr< dhtnet::IceSocket > rtcpSocket_
std::shared_ptr< RtpSession > rtpSession_
std::shared_ptr< MediaAttribute > mediaAttribute_