Ring Daemon 16.0.0
Loading...
Searching...
No Matches
sdp.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2025 Savoir-faire Linux Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17#pragma once
18
19#include "noncopyable.h"
20#include "sdes_negotiator.h"
21#include "media/media_codec.h"
24
25#include <dhtnet/ip_utils.h>
26#include <dhtnet/ice_transport.h>
27
28#include <pjmedia/sdp.h>
29#include <pjmedia/sdp_neg.h>
30#include <pjsip/sip_transport.h>
31#include <pjlib.h>
32#include <pjsip_ua.h>
33#include <pjmedia/errno.h>
34#include <pj/pool.h>
35#include <pj/assert.h>
36
37#include <map>
38#include <vector>
39#include <string>
40#include <stdexcept>
41
42namespace jami {
43
44namespace test {
45class SDPTest;
46}
47
48class AudioCodec;
49
50class SdpException : public std::runtime_error
51{
52public:
53 SdpException(const std::string& str = "")
54 : std::runtime_error("SDP: SdpException occurred: " + str)
55 {}
56};
57
58enum class SdpDirection { OFFER, ANSWER, NONE };
59
60class Sdp
61{
62public:
63 /*
64 * Class Constructor.
65 *
66 * @param memory pool
67 */
68 Sdp(const std::string& id);
69
70 ~Sdp();
71
77 MediaType type, const std::vector<std::shared_ptr<SystemCodecInfo>>& selectedCodecs);
78
84 pjmedia_sdp_session* getLocalSdpSession() { return localSession_; }
85
86 const pjmedia_sdp_session* getActiveLocalSdpSession() const { return activeLocalSession_; }
87
93 pjmedia_sdp_session* getRemoteSdpSession() { return remoteSession_; }
94
95 const pjmedia_sdp_session* getActiveRemoteSdpSession() const { return activeRemoteSession_; }
96
103
110
111 /*
112 * On building an invite outside a dialog, build the local offer and create the
113 * SDP negotiator instance with it.
114 * @returns true if offer was created, false otherwise
115 */
116 bool createOffer(const std::vector<MediaAttribute>& mediaList);
117
118 void setReceivedOffer(const pjmedia_sdp_session* remote);
119
125 bool processIncomingOffer(const std::vector<MediaAttribute>& mediaList);
126
130 bool startNegotiation();
131
136
137 /*
138 * Write accessor. Set the local IP address that will be used in the sdp session
139 */
140 void setPublishedIP(const std::string& addr, pj_uint16_t addr_type = pj_AF_UNSPEC());
141 void setPublishedIP(const dhtnet::IpAddr& addr);
142
143 /*
144 * Read accessor. Get the local IP address
145 */
146 dhtnet::IpAddr getPublishedIPAddr() const { return std::string_view(publishedIpAddr_); }
147
148 std::string_view getPublishedIP() const { return publishedIpAddr_; }
149
151 {
152 localAudioRtpPort_ = audio_port;
153 localAudioRtcpPort_ = control_port;
154 }
155
157 {
158 localVideoRtpPort_ = video_port;
159 localVideoRtcpPort_ = control_port;
160 }
161
162 uint16_t getLocalVideoPort() const { return localVideoRtpPort_; }
163
164 uint16_t getLocalVideoControlPort() const { return localVideoRtcpPort_; }
165
166 uint16_t getLocalAudioPort() const { return localAudioRtpPort_; }
167
168 uint16_t getLocalAudioControlPort() const { return localAudioRtcpPort_; }
169
170 std::vector<MediaDescription> getActiveMediaDescription(bool remote) const;
171
172 std::vector<MediaDescription> getMediaDescriptions(const pjmedia_sdp_session* session,
173 bool remote) const;
174
175 static std::vector<MediaAttribute> getMediaAttributeListFromSdp(
176 const pjmedia_sdp_session* sdpSession, bool ignoreDisabled = false);
177
178 using MediaSlot = std::pair<MediaDescription, MediaDescription>;
179 std::vector<MediaSlot> getMediaSlots() const;
180
181 unsigned int getTelephoneEventType() const { return telephoneEventPayload_; }
182
183 void addIceAttributes(const dhtnet::IceTransport::Attribute&& ice_attrs);
184 dhtnet::IceTransport::Attribute getIceAttributes() const;
185 static dhtnet::IceTransport::Attribute getIceAttributes(const pjmedia_sdp_session* session);
186
187 void addIceCandidates(unsigned media_index, const std::vector<std::string>& cands);
188
189 std::vector<std::string> getIceCandidates(unsigned media_index) const;
190
191 void clearIce();
192
193 SdpDirection getSdpDirection() const { return sdpDirection_; };
194 static constexpr std::string_view getSdpDirectionStr(SdpDirection direction);
195
198 static void printSession(const pjmedia_sdp_session* session,
199 const char* header,
201
202private:
203 friend class test::SDPTest;
204
206
207 void getProfileLevelID(const pjmedia_sdp_session* session, std::string& dest, int payload) const;
208
213 static std::string getFilteredSdp(const pjmedia_sdp_session* session,
214 unsigned media_keep,
215 unsigned pt_keep);
216
218
219 /*
220 * Build the sdp media section
221 * Add rtpmap field if necessary
222 */
223 pjmedia_sdp_media* addMediaDescription(const MediaAttribute& mediaAttr);
224
225 // Determine media direction
226 char const* mediaDirection(const MediaAttribute& mediaAttr);
227
228 // Get media direction
229 static MediaDirection getMediaDirection(pjmedia_sdp_media* media);
230
231 // Get the transport type
232 static MediaTransport getMediaTransport(pjmedia_sdp_media* media);
233
234 // Get the crypto materials
235 static std::vector<std::string> getCrypto(pjmedia_sdp_media* media);
236
237 pjmedia_sdp_attr* generateSdesAttribute();
238
239 void setTelephoneEventRtpmap(pjmedia_sdp_media* med);
240
241 /*
242 * Create a new SDP
243 */
244 void createLocalSession(SdpDirection direction);
245
246 /*
247 * Validate SDP
248 */
249 int validateSession() const;
250
251 /*
252 * Adds a sdes attribute to the given media section.
253 *
254 * @param media The media to add the srtp attribute to
255 * @throw SdpException
256 */
257 void addSdesAttribute(const std::vector<std::string>& crypto);
258
259 void addRTCPAttribute(pjmedia_sdp_media* med, uint16_t port);
260
261 std::shared_ptr<SystemCodecInfo> findCodecByPayload(const unsigned payloadType);
262 std::shared_ptr<SystemCodecInfo> findCodecBySpec(std::string_view codecName,
263 const unsigned clockrate = 0) const;
264
265 // Data members
266 std::unique_ptr<pj_pool_t, std::function<void(pj_pool_t*)>> memPool_;
267 pjmedia_sdp_neg* negotiator_ {nullptr};
268 pjmedia_sdp_session* localSession_ {nullptr};
269 pjmedia_sdp_session* remoteSession_ {nullptr};
270
276 const pjmedia_sdp_session* activeLocalSession_ {nullptr};
277
283 const pjmedia_sdp_session* activeRemoteSession_ {nullptr};
284
288 std::vector<std::shared_ptr<SystemCodecInfo>> audio_codec_list_;
289 std::vector<std::shared_ptr<SystemCodecInfo>> video_codec_list_;
290
291 std::string publishedIpAddr_;
292 pj_uint16_t publishedIpAddrType_;
293
294 uint16_t localAudioRtpPort_ {0};
295 uint16_t localAudioRtcpPort_ {0};
296 uint16_t localVideoRtpPort_ {0};
297 uint16_t localVideoRtcpPort_ {0};
298
299 unsigned int telephoneEventPayload_;
300
301 // The call Id of the SDP owner
302 std::string sessionName_ {};
303
304 // Offer/Answer flag.
305 SdpDirection sdpDirection_ {SdpDirection::NONE};
306};
307
308} // namespace jami
SdpException(const std::string &str="")
Definition sdp.h:53
void setReceivedOffer(const pjmedia_sdp_session *remote)
Definition sdp.cpp:578
bool processIncomingOffer(const std::vector< MediaAttribute > &mediaList)
Build a new SDP answer using mediaList.
Definition sdp.cpp:588
std::vector< MediaDescription > getActiveMediaDescription(bool remote) const
Definition sdp.cpp:751
std::string_view getPublishedIP() const
Definition sdp.h:148
void addIceCandidates(unsigned media_index, const std::vector< std::string > &cands)
Definition sdp.cpp:889
bool startNegotiation()
Start the sdp negotiation.
Definition sdp.cpp:633
void setLocalMediaCapabilities(MediaType type, const std::vector< std::shared_ptr< SystemCodecInfo > > &selectedCodecs)
Set the local media capabilities.
Definition sdp.cpp:420
dhtnet::IpAddr getPublishedIPAddr() const
Definition sdp.h:146
void setLocalPublishedAudioPorts(uint16_t audio_port, uint16_t control_port)
Definition sdp.h:150
SdpDirection getSdpDirection() const
Definition sdp.h:193
std::vector< MediaDescription > getMediaDescriptions(const pjmedia_sdp_session *session, bool remote) const
Definition sdp.cpp:760
bool createOffer(const std::vector< MediaAttribute > &mediaList)
Definition sdp.cpp:539
~Sdp()
Definition sdp.cpp:72
std::pair< MediaDescription, MediaDescription > MediaSlot
Definition sdp.h:178
friend class test::SDPTest
Definition sdp.h:203
pjmedia_sdp_session * getRemoteSdpSession()
Read accessor.
Definition sdp.h:93
uint16_t getLocalVideoPort() const
Definition sdp.h:162
uint16_t getLocalAudioControlPort() const
Definition sdp.h:168
const pjmedia_sdp_session * getActiveLocalSdpSession() const
Definition sdp.h:86
static std::vector< MediaAttribute > getMediaAttributeListFromSdp(const pjmedia_sdp_session *sdpSession, bool ignoreDisabled=false)
Definition sdp.cpp:1028
void setLocalPublishedVideoPorts(uint16_t video_port, uint16_t control_port)
Definition sdp.h:156
std::vector< std::string > getIceCandidates(unsigned media_index) const
Definition sdp.cpp:909
void setPublishedIP(const std::string &addr, pj_uint16_t addr_type=pj_AF_UNSPEC())
Definition sdp.cpp:374
void addIceAttributes(const dhtnet::IceTransport::Attribute &&ice_attrs)
Definition sdp.cpp:948
dhtnet::IceTransport::Attribute getIceAttributes() const
Definition sdp.cpp:964
pjmedia_sdp_session * getLocalSdpSession()
Read accessor.
Definition sdp.h:84
unsigned int getTelephoneEventType() const
Definition sdp.h:181
void cleanSessionMedia()
Remove all media in the session media vector.
void setActiveLocalSdpSession(const pjmedia_sdp_session *sdp)
Set the negotiated sdp offer from the sip payload.
Definition sdp.cpp:124
uint16_t getLocalAudioPort() const
Definition sdp.h:166
static constexpr std::string_view getSdpDirectionStr(SdpDirection direction)
Definition sdp.cpp:452
void clearIce()
Definition sdp.cpp:1004
void setActiveRemoteSdpSession(const pjmedia_sdp_session *sdp)
Retrieve the negotiated sdp offer from the sip payload.
Definition sdp.cpp:132
uint16_t getLocalVideoControlPort() const
Definition sdp.h:164
static void printSession(const pjmedia_sdp_session *session, const char *header, SdpDirection direction)
Log the given session.
Definition sdp.cpp:462
const pjmedia_sdp_session * getActiveRemoteSdpSession() const
Definition sdp.h:95
std::vector< MediaSlot > getMediaSlots() const
Definition sdp.cpp:876
direction
0: outgoing, 1: incoming
void emitSignal(Args... args)
Definition ring_signal.h:64
MediaTransport
SdpDirection
Definition sdp.h:58
MediaDirection
Simple macro to hide class' copy constructor and assignment operator.
#define NON_COPYABLE(ClassName)
Definition noncopyable.h:30