25#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;
119 void hangup(
int code)
override;
121 void transfer(
const std::string& to)
override;
132 void muteMedia(
const std::string& mediaType,
bool isMuted)
override;
137 std::shared_ptr<SystemCodecInfo>
getAudioCodec()
const override;
138 std::shared_ptr<SystemCodecInfo>
getVideoCodec()
const override;
141 std::map<std::string, std::string>
getDetails()
const override;
145 std::mutex sinksMtx_;
147 std::map<std::string, std::shared_ptr<video::SinkClient>>
callSinksMap_ {};
241 std::lock_guard
lk(transportMtx_);
242 return reinvIceMedia_ ? reinvIceMedia_ : iceMedia_;
268 void setRotation(
int streamIdx,
int rotation);
274 const std::string& deviceId,
275 const std::string& streamId,
282 std::string_view
peerUri()
const {
return peerUri_; }
299 inline std::weak_ptr<const SIPCall>
weak()
const {
return std::weak_ptr<const SIPCall>(shared()); }
300 inline std::weak_ptr<SIPCall>
weak() {
return std::weak_ptr<SIPCall>(shared()); }
309 void generateMediaPorts();
311 void openPortsUPnP();
313 bool isIceRunning()
const;
315 std::unique_ptr<dhtnet::IceSocket> newIceSocket(
unsigned compId);
317 void deinitRecorder();
319 void rtpSetupSuccess();
321 void setupVoiceCallback(
const std::shared_ptr<RtpSession>&
rtpSession);
323 void sendMuteState(
bool state);
324 void sendVoiceActivity(std::string_view streamId,
bool state);
326 void resetTransport(std::shared_ptr<dhtnet::IceTransport>&& transport);
333 void setVideoOrientation(
int streamIdx,
int rotation);
335 mutable std::mutex transportMtx_ {};
366 std::map<std::string, std::shared_ptr<MediaStreamSubject>>
callAVStreams;
369 void setCallMediaLocal();
370 void startIceMedia();
371 void onIceNegoSucceed();
372 void setupNegotiatedMedia();
373 void startAllMedia();
381 bool internalResume(
const std::function<
void()>&
SDPUpdateFunc);
391 bool isReinviteRequired(
const std::vector<MediaAttribute>&
mediaAttrList);
393 bool isNewIceMediaRequired(
const std::vector<MediaAttribute>&
mediaAttrList);
396 int SIPSessionReinvite();
398 void addMediaStream(
const MediaAttribute&
mediaAttr);
400 size_t initMediaStreams(
const std::vector<MediaAttribute>&
mediaAttrList);
402 void createRtpSession(RtpStream&
rtpStream);
404 void configureRtpSession(
const std::shared_ptr<RtpSession>&
rtpSession,
405 const std::shared_ptr<MediaAttribute>&
mediaAttr,
409 int findRtpStreamIndex(
const std::string&
label)
const;
411 std::vector<IceCandidate> getAllRemoteCandidates(dhtnet::IceTransport& transport)
const;
413 inline std::shared_ptr<const SIPCall> shared()
const
417 inline std::shared_ptr<SIPCall> shared() {
return std::static_pointer_cast<SIPCall>(
shared_from_this()); }
420 std::string peerUserAgent_ {};
422 bool peerSupportMultiStream_ {
false};
424 bool peerSupportMultiAudioStream_ {
false};
426 bool peerSupportMultiIce_ {
false};
430 bool peerSupportReuseIceInReinv_ {
false};
433 std::vector<std::string> peerAllowedMethods_;
436 std::vector<RtpStream> rtpStreams_;
443 std::shared_ptr<SipTransport> sipTransport_ {};
448 std::unique_ptr<Sdp> sdp_ {};
449 bool peerHold_ {
false};
451 bool isWaitingForIceAndMedia_ {
false};
452 enum class Request :
uint8_t { Hold, Resume, SwitchInput, NoRequest };
453 Request remainingRequest_ {Request::NoRequest};
455 std::string peerRegisteredName_ {};
457 std::string contactHeader_ {};
459 std::shared_ptr<dhtnet::upnp::Controller> upnp_;
462 unsigned int localAudioPort_ {0};
464 unsigned int localVideoPort_ {0};
466 bool mediaRestartRequired_ {
true};
467 bool enableIce_ {
true};
468 bool srtpEnabled_ {
false};
469 bool rtcpMuxEnabled_ {
false};
472 std::shared_ptr<dhtnet::IceTransport> iceMedia_;
474 std::shared_ptr<dhtnet::IceTransport> reinvIceMedia_;
476 std::string peerUri_ {};
478 bool readyToRecord_ {
false};
479 bool pendingRecord_ {
false};
481 time_point lastKeyFrameReq_ {time_point::min()};
486 std::atomic_bool waitForIceInit_ {
false};
488 void detachAudioFromConference();
490 std::mutex mediaStateMutex_;
495 std::string mediaPlayerId_ {};
503inline std::shared_ptr<SIPCall>
506 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.
std::map< std::string, bool > getRemoteAudioStreams() const override
Return a map of audio stream IDs to their remote (peer-side) muted state.
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 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
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 onFailure(int code=0)
Called to report server/internal errors.
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()
void removeCall(int code=0) override
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
void hangup(int code) override
Hang up the call.
const std::vector< RtpStream > & getRtpStreams() const
static size_t getActiveMediaStreamCount(const std::vector< MediaAttribute > &mediaAttrList)
std::shared_ptr< dhtnet::IceTransport > getIceMedia() const
void peerMuted(bool state, int streamIdx) override
bool resume(OnReadyCb &&cb) override
Resume call from hold state.
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()
void answer(const std::vector< libjami::MediaMap > &mediaList) override
Answer a call with a list of media attributes.
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 setPeerAllowMethods(std::vector< std::string > methods)
Set peer's allowed methods.
void switchToIceReinviteIfNeeded()
void enterConference(std::shared_ptr< Conference > conference) override
bool hold(OnReadyCb &&cb) override
Hold call.
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_