blob: f74cfe02a4a44a62261f6bc353507ba2aef6c51a [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file sdp/session.c SDP Session
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6#include <re_types.h>
7#include <re_fmt.h>
8#include <re_mem.h>
9#include <re_mbuf.h>
10#include <re_list.h>
11#include <re_tmr.h>
12#include <re_sa.h>
13#include <re_sdp.h>
14#include <re_sys.h>
15#include "sdp.h"
16
17
18static void destructor(void *arg)
19{
20 struct sdp_session *sess = arg;
21
22 list_flush(&sess->lmedial);
23 list_flush(&sess->medial);
24 list_flush(&sess->rattrl);
25 list_flush(&sess->lattrl);
26}
27
28
29/**
30 * Allocate a new SDP Session
31 *
32 * @param sessp Pointer to allocated SDP Session object
33 * @param laddr Local network address
34 *
35 * @return 0 if success, otherwise errorcode
36 */
37int sdp_session_alloc(struct sdp_session **sessp, const struct sa *laddr)
38{
39 struct sdp_session *sess;
40 int err = 0, i;
41
42 if (!sessp || !laddr)
43 return EINVAL;
44
45 sess = mem_zalloc(sizeof(*sess), destructor);
46 if (!sess)
47 return ENOMEM;
48
49 sess->laddr = *laddr;
50 sess->id = rand_u32();
51 sess->ver = rand_u32() & 0x7fffffff;
52 sess->rdir = SDP_SENDRECV;
53
54 sa_init(&sess->raddr, AF_INET);
55
56 for (i=0; i<SDP_BANDWIDTH_MAX; i++) {
57 sess->lbwv[i] = -1;
58 sess->rbwv[i] = -1;
59 }
60
61 if (err)
62 mem_deref(sess);
63 else
64 *sessp = sess;
65
66 return err;
67}
68
69
70/**
71 * Reset the remote side of an SDP Session
72 *
73 * @param sess SDP Session
74 */
75void sdp_session_rreset(struct sdp_session *sess)
76{
77 int i;
78
79 if (!sess)
80 return;
81
82 sa_init(&sess->raddr, AF_INET);
83
84 list_flush(&sess->rattrl);
85
86 sess->rdir = SDP_SENDRECV;
87
88 for (i=0; i<SDP_BANDWIDTH_MAX; i++)
89 sess->rbwv[i] = -1;
90}
91
92
93/**
94 * Set the local network address of an SDP Session
95 *
96 * @param sess SDP Session
97 * @param laddr Local network address
98 */
99void sdp_session_set_laddr(struct sdp_session *sess, const struct sa *laddr)
100{
101 if (!sess || !laddr)
102 return;
103
104 sess->laddr = *laddr;
105}
106
107
108/**
109 * Set the local bandwidth of an SDP Session
110 *
111 * @param sess SDP Session
112 * @param type Bandwidth type
113 * @param bw Bandwidth value
114 */
115void sdp_session_set_lbandwidth(struct sdp_session *sess,
116 enum sdp_bandwidth type, int32_t bw)
117{
118 if (!sess || type >= SDP_BANDWIDTH_MAX)
119 return;
120
121 sess->lbwv[type] = bw;
122}
123
124
125/**
126 * Set a local attribute of an SDP Session
127 *
128 * @param sess SDP Session
129 * @param replace True to replace any existing attributes, false to append
130 * @param name Attribute name
131 * @param value Formatted attribute value
132 *
133 * @return 0 if success, otherwise errorcode
134 */
135int sdp_session_set_lattr(struct sdp_session *sess, bool replace,
136 const char *name, const char *value, ...)
137{
138 va_list ap;
139 int err;
140
141 if (!sess || !name)
142 return EINVAL;
143
144 if (replace)
145 sdp_attr_del(&sess->lattrl, name);
146
147 va_start(ap, value);
148 err = sdp_attr_addv(&sess->lattrl, name, value, ap);
149 va_end(ap);
150
151 return err;
152}
153
154
155/**
156 * Delete a local attribute of an SDP Session
157 *
158 * @param sess SDP Session
159 * @param name Attribute name
160 */
161void sdp_session_del_lattr(struct sdp_session *sess, const char *name)
162{
163 if (!sess || !name)
164 return;
165
166 sdp_attr_del(&sess->lattrl, name);
167}
168
169
170/**
171 * Get the local bandwidth of an SDP Session
172 *
173 * @param sess SDP Session
174 * @param type Bandwidth type
175 *
176 * @return Bandwidth value
177 */
178int32_t sdp_session_lbandwidth(const struct sdp_session *sess,
179 enum sdp_bandwidth type)
180{
181 if (!sess || type >= SDP_BANDWIDTH_MAX)
182 return 0;
183
184 return sess->lbwv[type];
185}
186
187
188/**
189 * Get the remote bandwidth of an SDP Session
190 *
191 * @param sess SDP Session
192 * @param type Bandwidth type
193 *
194 * @return Bandwidth value
195 */
196int32_t sdp_session_rbandwidth(const struct sdp_session *sess,
197 enum sdp_bandwidth type)
198{
199 if (!sess || type >= SDP_BANDWIDTH_MAX)
200 return 0;
201
202 return sess->rbwv[type];
203}
204
205
206/**
207 * Get a remote attribute of an SDP Session
208 *
209 * @param sess SDP Session
210 * @param name Attribute name
211 *
212 * @return Attribute value if exist, NULL if not exist
213 */
214const char *sdp_session_rattr(const struct sdp_session *sess, const char *name)
215{
216 if (!sess || !name)
217 return NULL;
218
219 return sdp_attr_apply(&sess->rattrl, name, NULL, NULL);
220}
221
222
223/**
224 * Apply a function handler of all matching remote attributes
225 *
226 * @param sess SDP Session
227 * @param name Attribute name
228 * @param attrh Attribute handler
229 * @param arg Handler argument
230 *
231 * @return Attribute value if match
232 */
233const char *sdp_session_rattr_apply(const struct sdp_session *sess,
234 const char *name,
235 sdp_attr_h *attrh, void *arg)
236{
237 if (!sess)
238 return NULL;
239
240 return sdp_attr_apply(&sess->rattrl, name, attrh, arg);
241}
242
243
244/**
245 * Get the list of media-lines from an SDP Session
246 *
247 * @param sess SDP Session
248 * @param local True for local, False for remote
249 *
250 * @return List of media-lines
251 */
252const struct list *sdp_session_medial(const struct sdp_session *sess,
253 bool local)
254{
255 if (!sess)
256 return NULL;
257
258 return local ? &sess->lmedial : &sess->medial;
259}
260
261
262/**
263 * Print SDP Session debug information
264 *
265 * @param pf Print function for output
266 * @param sess SDP Session
267 *
268 * @return 0 if success, otherwise errorcode
269 */
270int sdp_session_debug(struct re_printf *pf, const struct sdp_session *sess)
271{
272 struct le *le;
273 int err;
274
275 if (!sess)
276 return 0;
277
278 err = re_hprintf(pf, "SDP session\n");
279
280 err |= re_hprintf(pf, " local attributes:\n");
281
282 for (le=sess->lattrl.head; le; le=le->next)
283 err |= re_hprintf(pf, " %H\n", sdp_attr_debug, le->data);
284
285 err |= re_hprintf(pf, " remote attributes:\n");
286
287 for (le=sess->rattrl.head; le; le=le->next)
288 err |= re_hprintf(pf, " %H\n", sdp_attr_debug, le->data);
289
290 err |= re_hprintf(pf, "session media:\n");
291
292 for (le=sess->medial.head; le; le=le->next)
293 err |= sdp_media_debug(pf, le->data);
294
295 err |= re_hprintf(pf, "local media:\n");
296
297 for (le=sess->lmedial.head; le; le=le->next)
298 err |= sdp_media_debug(pf, le->data);
299
300 return err;
301}