Ring Daemon
Loading...
Searching...
No Matches
sdp.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2026 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 "media/media_codec.h"
22
23#include <dhtnet/ip_utils.h>
24#include <dhtnet/ice_transport.h>
25
26#include <pjmedia/sdp.h>
27#include <pjmedia/sdp_neg.h>
28#include <pjsip/sip_transport.h>
29#include <pjlib.h>
30#include <pjsip_ua.h>
31#include <pjmedia/errno.h>
32#include <pj/pool.h>
33#include <pj/assert.h>
34
35#include <vector>
36#include <string>
37#include <stdexcept>
38
39namespace jami {
40
41namespace test {
42class SDPTest;
43}
44
45class AudioCodec;
46
47class SdpException : public std::runtime_error
48{
49public:
50 SdpException(const std::string& str = "")
51 : std::runtime_error("SDP: SdpException occurred: " + str)
52 {}
53};
54
56
57class Sdp
58{
59public:
60 /*
61 * Class Constructor.
62 *
63 * @param memory pool
64 */
65 Sdp(const std::string& id);
66
67 ~Sdp();
68
73 void setLocalMediaCapabilities(MediaType type, const std::vector<std::shared_ptr<SystemCodecInfo>>& selectedCodecs);
74
80 pjmedia_sdp_session* getLocalSdpSession() { return localSession_; }
81
82 const pjmedia_sdp_session* getActiveLocalSdpSession() const { return activeLocalSession_; }
83
89 pjmedia_sdp_session* getRemoteSdpSession() { return remoteSession_; }
90
91 const pjmedia_sdp_session* getActiveRemoteSdpSession() const { return activeRemoteSession_; }
92
99
106
107 /*
108 * On building an invite outside a dialog, build the local offer and create the
109 * SDP negotiator instance with it.
110 * @returns true if offer was created, false otherwise
111 */
112 bool createOffer(const std::vector<MediaAttribute>& mediaList);
113
114 void setReceivedOffer(const pjmedia_sdp_session* remote);
115
121 bool processIncomingOffer(const std::vector<MediaAttribute>& mediaList);
122
126 bool startNegotiation();
127
132
133 /*
134 * Write accessor. Set the local IP address that will be used in the sdp session
135 */
136 void setPublishedIP(const std::string& addr, pj_uint16_t addr_type = pj_AF_UNSPEC());
137 void setPublishedIP(const dhtnet::IpAddr& addr);
138
139 /*
140 * Read accessor. Get the local IP address
141 */
142 dhtnet::IpAddr getPublishedIPAddr() const { return std::string_view(publishedIpAddr_); }
143
144 std::string_view getPublishedIP() const { return publishedIpAddr_; }
145
147 {
148 localAudioRtpPort_ = audio_port;
149 localAudioRtcpPort_ = control_port;
150 }
151
153 {
154 localVideoRtpPort_ = video_port;
155 localVideoRtcpPort_ = control_port;
156 }
157
158 uint16_t getLocalVideoPort() const { return localVideoRtpPort_; }
159
160 uint16_t getLocalVideoControlPort() const { return localVideoRtcpPort_; }
161
162 uint16_t getLocalAudioPort() const { return localAudioRtpPort_; }
163
164 uint16_t getLocalAudioControlPort() const { return localAudioRtcpPort_; }
165
166 std::vector<MediaDescription> getActiveMediaDescription(bool remote) const;
167
168 std::vector<MediaDescription> getMediaDescriptions(const pjmedia_sdp_session* session, bool remote) const;
169
170 static std::vector<MediaAttribute> getMediaAttributeListFromSdp(const pjmedia_sdp_session* sdpSession,
171 bool ignoreDisabled = false);
172
173 using MediaSlot = std::pair<MediaDescription, MediaDescription>;
174 std::vector<MediaSlot> getMediaSlots() const;
175
176 unsigned int getTelephoneEventType() const { return telephoneEventPayload_; }
177
178 void addIceAttributes(const dhtnet::IceTransport::Attribute&& ice_attrs);
179 dhtnet::IceTransport::Attribute getIceAttributes() const;
180 static dhtnet::IceTransport::Attribute getIceAttributes(const pjmedia_sdp_session* session);
181
182 void addIceCandidates(unsigned media_index, const std::vector<std::string>& cands);
183
184 std::vector<std::string> getIceCandidates(unsigned media_index) const;
185
186 void clearIce();
187
188 SdpDirection getSdpDirection() const { return sdpDirection_; };
189 static constexpr std::string_view getSdpDirectionStr(SdpDirection direction);
190
193 static void printSession(const pjmedia_sdp_session* session, const char* header, SdpDirection direction);
194
195private:
196 friend class test::SDPTest;
197
199
200 void getProfileLevelID(const pjmedia_sdp_session* session, std::string& dest, int payload) const;
201
206 static std::string getFilteredSdp(const pjmedia_sdp_session* session, unsigned media_keep, unsigned pt_keep);
207
209
210 /*
211 * Build the sdp media section
212 * Add rtpmap field if necessary
213 */
214 pjmedia_sdp_media* addMediaDescription(const MediaAttribute& mediaAttr);
215
216 // Determine media direction
217 char const* mediaDirection(const MediaAttribute& mediaAttr);
218
219 // Get media direction
220 static MediaDirection getMediaDirection(pjmedia_sdp_media* media);
221
222 // Get the transport type
223 static MediaTransport getMediaTransport(pjmedia_sdp_media* media);
224
225 // Get the crypto materials
226 static std::vector<std::string> getCrypto(pjmedia_sdp_media* media);
227
228 pjmedia_sdp_attr* generateSdesAttribute();
229
230 void setTelephoneEventRtpmap(pjmedia_sdp_media* med);
231
232 /*
233 * Create a new SDP
234 */
235 void createLocalSession(SdpDirection direction);
236
237 /*
238 * Validate SDP
239 */
240 int validateSession() const;
241
242 /*
243 * Adds a sdes attribute to the given media section.
244 *
245 * @param media The media to add the srtp attribute to
246 * @throw SdpException
247 */
248 void addSdesAttribute(const std::vector<std::string>& crypto);
249
250 void addRTCPAttribute(pjmedia_sdp_media* med, uint16_t port);
251
252 std::shared_ptr<SystemCodecInfo> findCodecByPayload(const unsigned payloadType);
253 std::shared_ptr<SystemCodecInfo> findCodecBySpec(std::string_view codecName, const unsigned clockrate = 0) const;
254
255 // Data members
256 std::unique_ptr<pj_pool_t, std::function<void(pj_pool_t*)>> memPool_;
257 pjmedia_sdp_neg* negotiator_ {nullptr};
258 pjmedia_sdp_session* localSession_ {nullptr};
259 pjmedia_sdp_session* remoteSession_ {nullptr};
260
266 const pjmedia_sdp_session* activeLocalSession_ {nullptr};
267
273 const pjmedia_sdp_session* activeRemoteSession_ {nullptr};
274
278 std::vector<std::shared_ptr<SystemCodecInfo>> audio_codec_list_;
279 std::vector<std::shared_ptr<SystemCodecInfo>> video_codec_list_;
280
281 std::string publishedIpAddr_;
282 pj_uint16_t publishedIpAddrType_;
283
284 uint16_t localAudioRtpPort_ {0};
285 uint16_t localAudioRtcpPort_ {0};
286 uint16_t localVideoRtpPort_ {0};
287 uint16_t localVideoRtcpPort_ {0};
288
289 unsigned int telephoneEventPayload_;
290
291 // The call Id of the SDP owner
292 std::string sessionName_ {};
293
294 // Offer/Answer flag.
295 SdpDirection sdpDirection_ {SdpDirection::NONE};
296};
297
298} // namespace jami
SdpException(const std::string &str="")
Definition sdp.h:50
void setReceivedOffer(const pjmedia_sdp_session *remote)
Definition sdp.cpp:548
bool processIncomingOffer(const std::vector< MediaAttribute > &mediaList)
Build a new SDP answer using mediaList.
Definition sdp.cpp:558
std::vector< MediaDescription > getActiveMediaDescription(bool remote) const
Definition sdp.cpp:708
std::string_view getPublishedIP() const
Definition sdp.h:144
void addIceCandidates(unsigned media_index, const std::vector< std::string > &cands)
Definition sdp.cpp:837
bool startNegotiation()
Start the sdp negotiation.
Definition sdp.cpp:598
void setLocalMediaCapabilities(MediaType type, const std::vector< std::shared_ptr< SystemCodecInfo > > &selectedCodecs)
Set the local media capabilities.
Definition sdp.cpp:395
dhtnet::IpAddr getPublishedIPAddr() const
Definition sdp.h:142
void setLocalPublishedAudioPorts(uint16_t audio_port, uint16_t control_port)
Definition sdp.h:146
SdpDirection getSdpDirection() const
Definition sdp.h:188
std::vector< MediaDescription > getMediaDescriptions(const pjmedia_sdp_session *session, bool remote) const
Definition sdp.cpp:717
bool createOffer(const std::vector< MediaAttribute > &mediaList)
Definition sdp.cpp:510
~Sdp()
Definition sdp.cpp:70
std::pair< MediaDescription, MediaDescription > MediaSlot
Definition sdp.h:173
friend class test::SDPTest
Definition sdp.h:196
pjmedia_sdp_session * getRemoteSdpSession()
Read accessor.
Definition sdp.h:89
uint16_t getLocalVideoPort() const
Definition sdp.h:158
uint16_t getLocalAudioControlPort() const
Definition sdp.h:164
const pjmedia_sdp_session * getActiveLocalSdpSession() const
Definition sdp.h:82
static std::vector< MediaAttribute > getMediaAttributeListFromSdp(const pjmedia_sdp_session *sdpSession, bool ignoreDisabled=false)
Definition sdp.cpp:974
void setLocalPublishedVideoPorts(uint16_t video_port, uint16_t control_port)
Definition sdp.h:152
std::vector< std::string > getIceCandidates(unsigned media_index) const
Definition sdp.cpp:856
void setPublishedIP(const std::string &addr, pj_uint16_t addr_type=pj_AF_UNSPEC())
Definition sdp.cpp:351
void addIceAttributes(const dhtnet::IceTransport::Attribute &&ice_attrs)
Definition sdp.cpp:894
dhtnet::IceTransport::Attribute getIceAttributes() const
Definition sdp.cpp:910
pjmedia_sdp_session * getLocalSdpSession()
Read accessor.
Definition sdp.h:80
unsigned int getTelephoneEventType() const
Definition sdp.h:176
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:122
uint16_t getLocalAudioPort() const
Definition sdp.h:162
static constexpr std::string_view getSdpDirectionStr(SdpDirection direction)
Definition sdp.cpp:426
void clearIce()
Definition sdp.cpp:950
void setActiveRemoteSdpSession(const pjmedia_sdp_session *sdp)
Retrieve the negotiated sdp offer from the sip payload.
Definition sdp.cpp:130
uint16_t getLocalVideoControlPort() const
Definition sdp.h:160
static void printSession(const pjmedia_sdp_session *session, const char *header, SdpDirection direction)
Log the given session.
Definition sdp.cpp:436
const pjmedia_sdp_session * getActiveRemoteSdpSession() const
Definition sdp.h:91
std::vector< MediaSlot > getMediaSlots() const
Definition sdp.cpp:824
void emitSignal(Args... args)
Definition jami_signal.h:64
MediaDirection
SdpDirection
Definition sdp.h:55
MediaTransport
Simple macro to hide class' copy constructor and assignment operator.
#define NON_COPYABLE(ClassName)
Definition noncopyable.h:30