37#include <opendht/rng.h>
59 , publishedIpAddrType_()
60 , telephoneEventPayload_(101)
61 , sessionName_(
"Call ID " +
id)
69 throw std::runtime_error(
"pj_pool_create() failed");
80std::shared_ptr<SystemCodecInfo>
81Sdp::findCodecBySpec(std::string_view codec,
const unsigned clockrate)
const
99std::shared_ptr<SystemCodecInfo>
100Sdp::findCodecByPayload(
const unsigned payloadType)
118 std::uniform_int_distribution<int>
rand_byte {0, std::numeric_limits<uint8_t>::max()};
119 std::random_device
rdev;
126 if (activeLocalSession_ !=
sdp)
127 JAMI_DBG(
"Set active local session to [%p]. Was [%p]",
sdp, activeLocalSession_);
128 activeLocalSession_ =
sdp;
134 if (activeLocalSession_ !=
sdp)
135 JAMI_DBG(
"Set active remote session to [%p]. Was [%p]",
sdp, activeRemoteSession_);
136 activeRemoteSession_ =
sdp;
140Sdp::generateSdesAttribute()
156Sdp::mediaDirection(
const MediaAttribute&
mediaAttr)
232std::vector<std::string>
235 std::vector<std::string> crypto;
236 for (
unsigned j = 0;
j <
media->attr_count;
j++) {
246Sdp::addMediaDescription(
const MediaAttribute&
mediaAttr)
258 med->desc.port =
mediaAttr.enabled_ ? localAudioRtpPort_ : 0;
259 med->desc.fmt_count = audio_codec_list_.size();
263 med->desc.port =
mediaAttr.enabled_ ? localVideoRtpPort_ : 0;
264 med->desc.fmt_count = video_codec_list_.size();
267 throw SdpException(
"Unsupported media type! Only audio and video are supported");
271 med->desc.port_count = 1;
279 for (
unsigned i = 0;
i <
med->desc.fmt_count;
i++) {
283 std::string channels;
289 audio_codec_list_[
i]);
308 rtpmap.clock_rate = 90000;
330 video_codec_list_[
i]);
343 setTelephoneEventRtpmap(
med);
344 if (localAudioRtcpPort_) {
345 addRTCPAttribute(
med, localAudioRtcpPort_);
348 addRTCPAttribute(
med, localVideoRtcpPort_);
357 throw SdpException(
"Unable to add sdes attribute to media");
366 dhtnet::IpAddr addr {publishedIpAddr_};
376 publishedIpAddr_ = addr;
384 localSession_->conn->addr = localSession_->origin.addr;
399 ++
med->desc.fmt_count;
401 &
med->desc.fmt[
med->desc.fmt_count - 1],
402 std::to_string(telephoneEventPayload_).c_str());
421 const std::vector<std::shared_ptr<SystemCodecInfo>>&
selectedCodecs)
433 video_codec_list_.erase(std::remove_if(video_codec_list_.begin(),
434 video_codec_list_.end(),
435 [](
const std::shared_ptr<SystemCodecInfo>&
i) {
436 return i->name ==
"H265";
438 video_codec_list_.end());
451constexpr std::string_view
464 static constexpr size_t BUF_SZ = 4095;
475 JAMI_ERROR(
"Unable to clone SDP for printing");
484 std::array<char, BUF_SZ + 1>
buffer;
487 JAMI_ERROR(
"SDP too big for dump: {}", header);
492 std::string_view(
buffer.data(), size));
503 localSession_->origin.version = 0;
510 localSession_->origin.id =
tv.sec + 2208988800UL;
521 localSession_->conn->net_type = localSession_->origin.net_type;
522 localSession_->conn->addr_type = localSession_->origin.addr_type;
523 localSession_->conn->addr = localSession_->origin.addr;
528 localSession_->time.start = 0;
529 localSession_->time.stop = 0;
533Sdp::validateSession()
const
542 throw SdpException(
"Media list size exceeds SDP media maximum size");
549 JAMI_ERR(
"Failed to create initial offer");
553 localSession_->media_count = 0;
556 if (
media.enabled_) {
557 localSession_->media[localSession_->media_count++] = addMediaDescription(
media);
568 JAMI_ERR(
"Failed to create an initial SDP negotiator");
572 printSession(localSession_,
"Local session (initial):", sdpDirection_);
580 if (remote ==
nullptr) {
590 if (
not remoteSession_)
593 JAMI_DEBUG(
"Processing received offer for [{:s}] with {:d} media",
601 JAMI_ERR(
"Failed to create local session");
605 localSession_->media_count = 0;
608 if (
media.enabled_) {
609 localSession_->media[localSession_->media_count++] = addMediaDescription(
media);
613 printSession(localSession_,
"Local session:\n", sdpDirection_);
625 JAMI_ERR(
"Failed to initialize media negotiation");
635 JAMI_DBG(
"Starting media negotiation for [%s]", sessionName_.c_str());
637 if (negotiator_ ==
NULL) {
638 JAMI_ERR(
"Unable to start negotiation with invalid negotiator");
646 JAMI_WARN(
"Negotiator not in right state for negotiation");
651 JAMI_ERR(
"Failed to start media negotiation");
656 JAMI_ERR(
"Unable to retrieve local active session");
666 JAMI_ERR(
"Unable to retrieve remote active session");
680 static constexpr size_t BUF_SZ = 4096;
696 for (
unsigned i = 0;
i <
cloned->media_count;
i++)
699 JAMI_ERR(
"Unable to deactivate media");
705 JAMI_DBG(
"No media to keep present in SDP");
710 for (
unsigned i = 0;
i <
cloned->media_count;
i++)
711 if (
cloned->media[
i]->desc.port == 0) {
717 for (
unsigned i = 0;
i <
cloned->media_count;
i++) {
721 for (
unsigned c = 0; c <
media->desc.fmt_count; c++) {
722 auto& pt =
media->desc.fmt[c];
732 std::move(
media->desc.fmt + c + 1,
734 media->desc.fmt + c);
735 media->desc.fmt_count--;
750std::vector<MediaDescription>
759std::vector<MediaDescription>
767 std::vector<MediaDescription>
ret;
768 for (
unsigned i = 0;
i <
session->media_count;
i++) {
786 JAMI_ERR(
"Unable to find connection information for media");
789 descr.addr = std::string_view(
conn->addr.ptr,
conn->addr.slen);
799 descr.rtcp_addr = std::string_view(
rtcp.addr.ptr,
rtcp.addr.slen);
815 JAMI_ERR(
"Did not find media direction attribute in remote SDP");
819 for (
unsigned j = 0;
j <
media->desc.fmt_count;
j++) {
824 JAMI_ERR(
"Unable to find rtpmap attribute");
825 descr.enabled =
false;
830 ||
rtpmap.enc_name.slen == 0) {
831 JAMI_ERROR(
"Unable to find payload type {} in SDP",
833 descr.enabled =
false;
841 descr.enabled =
false;
852 descr.parameters = std::string(v.ptr, v.ptr + v.slen);
856 descr.enabled =
true;
864 std::vector<std::string> crypto;
865 for (
unsigned j = 0;
j <
media->attr_count;
j++) {
875std::vector<Sdp::MediaSlot>
881 std::vector<MediaSlot> s;
884 s.emplace_back(std::move(
loc[
i]), std::move(
rem[
i]));
892 JAMI_ERR(
"addIceCandidates failed: unable to access media#%u (may be deactivated)",
904 throw SdpException(
"Unable to add ICE candidates attribute to media");
908std::vector<std::string>
911 auto remoteSession = activeRemoteSession_ ? activeRemoteSession_ : remoteSession_;
912 auto localSession = activeLocalSession_ ? activeLocalSession_ : localSession_;
914 JAMI_ERR(
"getIceCandidates failed: no remote session");
918 JAMI_ERR(
"getIceCandidates failed: no local session");
922 JAMI_ERR(
"getIceCandidates failed: unable to access media#%u (may be deactivated)",
929 JAMI_WARN(
"Media#%u is disabled. Media ports: local %u, remote %u",
938 for (
unsigned i = 0;
i <
media->attr_count;
i++) {
954 throw SdpException(
"Unable to add ICE.ufrag attribute to local SDP");
960 throw SdpException(
"Unable to add ICE.pwd attribute to local SDP");
963dhtnet::IceTransport::Attribute
966 if (
auto session = activeRemoteSession_ ? activeRemoteSession_ : remoteSession_)
971dhtnet::IceTransport::Attribute
974 dhtnet::IceTransport::Attribute
ice_attrs;
978 for (
unsigned i = 0;
i <
session->attr_count;
i++) {
987 for (
unsigned i = 0;
i <
session->media_count;
i++) {
989 for (
unsigned j = 0;
j <
media->attr_count;
j++) {
1021 for (
unsigned i = 0;
i <
session->media_count;
i++) {
1027std::vector<MediaAttribute>
1037 for (
unsigned idx = 0; idx <
sdpSession->media_count; idx++) {
1049 JAMI_WARN(
"Media#%u only 'audio' and 'video' types are supported!", idx);
1071 JAMI_WARN(
"Media#%u is unable to determine transport type!", idx);
static LIBJAMI_TEST_EXPORT Manager & instance()
static void releasePort(uint16_t port) noexcept
static CryptoAttribute negotiate(const std::vector< std::string > &attributes)
void setReceivedOffer(const pjmedia_sdp_session *remote)
bool processIncomingOffer(const std::vector< MediaAttribute > &mediaList)
Build a new SDP answer using mediaList.
std::vector< MediaDescription > getActiveMediaDescription(bool remote) const
void addIceCandidates(unsigned media_index, const std::vector< std::string > &cands)
bool startNegotiation()
Start the sdp negotiation.
void setLocalMediaCapabilities(MediaType type, const std::vector< std::shared_ptr< SystemCodecInfo > > &selectedCodecs)
Set the local media capabilities.
std::vector< MediaDescription > getMediaDescriptions(const pjmedia_sdp_session *session, bool remote) const
bool createOffer(const std::vector< MediaAttribute > &mediaList)
static std::vector< MediaAttribute > getMediaAttributeListFromSdp(const pjmedia_sdp_session *sdpSession, bool ignoreDisabled=false)
std::vector< std::string > getIceCandidates(unsigned media_index) const
void setPublishedIP(const std::string &addr, pj_uint16_t addr_type=pj_AF_UNSPEC())
void addIceAttributes(const dhtnet::IceTransport::Attribute &&ice_attrs)
dhtnet::IceTransport::Attribute getIceAttributes() const
void setActiveLocalSdpSession(const pjmedia_sdp_session *sdp)
Set the negotiated sdp offer from the sip payload.
Sdp(const std::string &id)
static constexpr std::string_view getSdpDirectionStr(SdpDirection direction)
void setActiveRemoteSdpSession(const pjmedia_sdp_session *sdp)
Retrieve the negotiated sdp offer from the sip payload.
static void printSession(const pjmedia_sdp_session *session, const char *header, SdpDirection direction)
Log the given session.
std::vector< MediaSlot > getMediaSlots() const
direction
0: outgoing, 1: incoming
#define JAMI_ERROR(formatstr,...)
#define JAMI_DEBUG(formatstr,...)
#define JAMI_LOG(formatstr,...)
std::string encode(std::string_view dat)
int64_t size(const std::filesystem::path &path)
const char *const DEFAULT_H264_PROFILE_LEVEL_ID
constexpr std::string_view as_view(const pj_str_t &str) noexcept
constexpr const pj_str_t CONST_PJ_STR(T(&a)[N]) noexcept
static std::map< MediaDirection, const char * > DIRECTION_STR
void emitSignal(Args... args)
static std::vector< CryptoSuiteDefinition > CryptoSuites
List of accepted Crypto-Suites as defined in RFC4568 (6.2)
static constexpr int POOL_INITIAL_SIZE
static constexpr int POOL_INCREMENT_SIZE
static void randomFill(std::vector< uint8_t > &dest)
A SIP Account specify SIP specific functions and object = SIPCall/SIPVoIPLink)
Specific VoIPLink for SIP (SIP core for incoming and outgoing events).