1 /*
2 belle-sdp - SIP (RFC4566) library.
3 Copyright (C) 2010 Belledonne Communications SARL
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "belle-sip/belle-sip.h"
19 #include "grammars/belle_sdpParser.h"
20 #include "grammars/belle_sdpLexer.h"
21 #include "belle_sip_internal.h"
22
23
24 struct _belle_sdp_mime_parameter {
25 belle_sip_object_t base;
26 int rate;
27 int channel_count;
28 int ptime;
29 int max_ptime;
30 int media_format;
31 const char* type;
32 const char* parameters;
33
34 };
35
36
belle_sip_object_freefunc(void * obj)37 static void belle_sip_object_freefunc(void* obj) {
38 belle_sip_object_unref(BELLE_SIP_OBJECT(obj));
39 }
belle_sip_object_copyfunc(void * obj)40 static void* belle_sip_object_copyfunc(void* obj) {
41 return belle_sip_object_clone_and_ref(BELLE_SIP_OBJECT(obj));
42 }
belle_sip_string_copyfunc(void * obj)43 static void * belle_sip_string_copyfunc(void *obj) {
44 return (void *)belle_sip_strdup((const char *)obj);
45 }
46
47
48 /***************************************************************************************
49 * Attribute
50 *
51 **************************************************************************************/
52 typedef belle_sdp_attribute_t* (*attribute_parse_func)(const char*) ;
53 struct attribute_name_func_pair {
54 const char* name;
55 attribute_parse_func func;
56 };
57 static struct attribute_name_func_pair attribute_table[] = {
58 { "rtcp-fb", (attribute_parse_func)belle_sdp_rtcp_fb_attribute_parse },
59 { "rtcp-xr", (attribute_parse_func)belle_sdp_rtcp_xr_attribute_parse }
60 };
61 struct _belle_sdp_attribute {
62 belle_sip_object_t base;
63 const char* name;
64 char *unparsed_value;
65 };
belle_sdp_attribute_destroy(belle_sdp_attribute_t * attribute)66 void belle_sdp_attribute_destroy(belle_sdp_attribute_t* attribute) {
67 DESTROY_STRING(attribute,name)
68 DESTROY_STRING(attribute,unparsed_value)
69 }
belle_sdp_attribute_clone(belle_sdp_attribute_t * attribute,const belle_sdp_attribute_t * orig)70 void belle_sdp_attribute_clone(belle_sdp_attribute_t *attribute, const belle_sdp_attribute_t *orig){
71 CLONE_STRING(belle_sdp_attribute,name,attribute,orig)
72 }
belle_sdp_attribute_marshal(belle_sdp_attribute_t * attribute,char * buff,size_t buff_size,size_t * offset)73 belle_sip_error_code belle_sdp_attribute_marshal(belle_sdp_attribute_t* attribute, char* buff, size_t buff_size, size_t *offset) {
74 return belle_sip_snprintf(buff, buff_size, offset, "a=%s", attribute->name);
75 }
belle_sdp_attribute_create(const char * name,const char * value)76 belle_sdp_attribute_t* belle_sdp_attribute_create(const char* name, const char* value) {
77 belle_sdp_attribute_t* ret;
78 size_t i;
79 size_t elements = sizeof(attribute_table) / sizeof(attribute_table[0]);
80
81 if (!name || name[0] == '\0') {
82 belle_sip_error("Cannot create SDP attribute without name");
83 return NULL;
84 }
85
86 for (i = 0; i < elements; i++) {
87 if (strcasecmp(attribute_table[i].name, name) == 0) {
88 char* raw;
89 if (value)
90 raw = belle_sip_strdup_printf("a=%s:%s", name, value);
91 else
92 raw = belle_sip_strdup_printf("a=%s", name);
93 ret = attribute_table[i].func(raw);
94 belle_sip_free(raw);
95 return ret;
96 }
97 }
98 /* Not a specialized SDP attribute */
99 return BELLE_SDP_ATTRIBUTE(belle_sdp_raw_attribute_create(name, value));
100 }
belle_sdp_attribute_get_value(belle_sdp_attribute_t * attribute)101 const char *belle_sdp_attribute_get_value(belle_sdp_attribute_t *attribute) {
102 char *ret;
103 char *end;
104
105
106 if (attribute->unparsed_value) {
107 belle_sip_free(attribute->unparsed_value);
108 attribute->unparsed_value = NULL;
109 }
110 attribute->unparsed_value = belle_sip_object_to_string(attribute);
111
112 ret = attribute->unparsed_value;
113 ret += strlen(attribute->name) + 2; /* "a=" + name*/
114 if (*ret==':') ret++;
115 for (; *ret == ' '; ret++) {}; /* skip eventual spaces */
116 return ret;
117 }
belle_sdp_attribute_has_value(belle_sdp_attribute_t * attribute)118 unsigned int belle_sdp_attribute_has_value(belle_sdp_attribute_t* attribute) {
119 return belle_sdp_attribute_get_value(attribute) != NULL;
120 }
121 BELLE_SDP_NEW(attribute,belle_sip_object)
122 BELLE_SDP_PARSE(attribute)
123 GET_SET_STRING(belle_sdp_attribute,name);
124 /***************************************************************************************
125 * RAW Attribute
126 *
127 **************************************************************************************/
128 struct _belle_sdp_raw_attribute {
129 belle_sdp_attribute_t base;
130 const char* value;
131 };
belle_sdp_raw_attribute_destroy(belle_sdp_raw_attribute_t * attribute)132 void belle_sdp_raw_attribute_destroy(belle_sdp_raw_attribute_t* attribute) {
133 DESTROY_STRING(attribute,value)
134 }
belle_sdp_raw_attribute_clone(belle_sdp_raw_attribute_t * attribute,const belle_sdp_raw_attribute_t * orig)135 void belle_sdp_raw_attribute_clone(belle_sdp_raw_attribute_t* attribute, const belle_sdp_raw_attribute_t* orig) {
136 if (belle_sdp_attribute_get_value(BELLE_SDP_ATTRIBUTE(orig))) {
137 belle_sdp_raw_attribute_set_value(attribute, belle_sdp_attribute_get_value(BELLE_SDP_ATTRIBUTE(orig)));
138 }
139 }
belle_sdp_raw_attribute_marshal(belle_sdp_raw_attribute_t * attribute,char * buff,size_t buff_size,size_t * offset)140 belle_sip_error_code belle_sdp_raw_attribute_marshal(belle_sdp_raw_attribute_t* attribute, char* buff, size_t buff_size, size_t* offset) {
141 belle_sip_error_code error = belle_sdp_attribute_marshal(BELLE_SDP_ATTRIBUTE(attribute), buff, buff_size, offset);
142 if (error != BELLE_SIP_OK) return error;
143 if (attribute->value) {
144 error = belle_sip_snprintf(buff, buff_size, offset, ":%s", attribute->value);
145 if (error != BELLE_SIP_OK) return error;
146 }
147 return error;
148 }
BELLE_SDP_NEW(raw_attribute,belle_sdp_attribute)149 BELLE_SDP_NEW(raw_attribute,belle_sdp_attribute)
150 belle_sdp_raw_attribute_t* belle_sdp_raw_attribute_create(const char* name, const char* value) {
151 belle_sdp_raw_attribute_t* attribute = belle_sdp_raw_attribute_new();
152 belle_sdp_attribute_set_name(BELLE_SDP_ATTRIBUTE(attribute), name);
153 belle_sdp_raw_attribute_set_value(attribute, value);
154 return attribute;
155 }
belle_sdp_raw_attribute_set_value(belle_sdp_raw_attribute_t * attribute,const char * value)156 void belle_sdp_raw_attribute_set_value(belle_sdp_raw_attribute_t* attribute, const char* value) {
157 if (attribute->value != NULL) belle_sip_free((void*)attribute->value);
158 if (value) {
159 attribute->value = belle_sip_strdup(value);
160 } else attribute->value = NULL;
161 }
162 /***************************************************************************************
163 * RTCP-FB Attribute
164 *
165 **************************************************************************************/
166 struct _belle_sdp_rtcp_fb_attribute {
167 belle_sdp_attribute_t base;
168 belle_sdp_rtcp_fb_val_type_t type;
169 belle_sdp_rtcp_fb_val_param_t param;
170 uint32_t smaxpr;
171 uint16_t trr_int;
172 int8_t id;
173 };
174 BELLESIP_EXPORT unsigned int belle_sdp_rtcp_fb_attribute_has_pli(const belle_sdp_rtcp_fb_attribute_t* attribute);
175 BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_pli(belle_sdp_rtcp_fb_attribute_t* attribute, unsigned int enable);
176 BELLESIP_EXPORT unsigned int belle_sdp_rtcp_fb_attribute_has_sli(const belle_sdp_rtcp_fb_attribute_t* attribute);
177 BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_sli(belle_sdp_rtcp_fb_attribute_t* attribute, unsigned int enable);
178 BELLESIP_EXPORT unsigned int belle_sdp_rtcp_fb_attribute_has_rpsi(const belle_sdp_rtcp_fb_attribute_t* attribute);
179 BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_rpsi(belle_sdp_rtcp_fb_attribute_t* attribute, unsigned int enable);
180 BELLESIP_EXPORT unsigned int belle_sdp_rtcp_fb_attribute_has_app(const belle_sdp_rtcp_fb_attribute_t* attribute);
181 BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_app(belle_sdp_rtcp_fb_attribute_t* attribute, unsigned int enable);
belle_sdp_rtcp_fb_attribute_destroy(belle_sdp_rtcp_fb_attribute_t * attribute)182 void belle_sdp_rtcp_fb_attribute_destroy(belle_sdp_rtcp_fb_attribute_t* attribute) {
183 }
belle_sdp_rtcp_fb_attribute_clone(belle_sdp_rtcp_fb_attribute_t * attribute,const belle_sdp_rtcp_fb_attribute_t * orig)184 void belle_sdp_rtcp_fb_attribute_clone(belle_sdp_rtcp_fb_attribute_t* attribute, const belle_sdp_rtcp_fb_attribute_t *orig) {
185 attribute->type = orig->type;
186 attribute->param = orig->param;
187 attribute->trr_int = orig->trr_int;
188 attribute->id = orig->id;
189 attribute->smaxpr = orig->smaxpr;
190 }
belle_sdp_rtcp_fb_attribute_marshal(belle_sdp_rtcp_fb_attribute_t * attribute,char * buff,size_t buff_size,size_t * offset)191 belle_sip_error_code belle_sdp_rtcp_fb_attribute_marshal(belle_sdp_rtcp_fb_attribute_t* attribute, char * buff, size_t buff_size, size_t *offset) {
192 int8_t id = belle_sdp_rtcp_fb_attribute_get_id(attribute);
193 belle_sdp_rtcp_fb_val_type_t type = belle_sdp_rtcp_fb_attribute_get_type(attribute);
194 belle_sdp_rtcp_fb_val_param_t param = belle_sdp_rtcp_fb_attribute_get_param(attribute);
195 belle_sip_error_code error = belle_sdp_attribute_marshal(BELLE_SDP_ATTRIBUTE(attribute), buff, buff_size, offset);
196 if (error != BELLE_SIP_OK) return error;
197 if (id < 0) {
198 error = belle_sip_snprintf(buff, buff_size, offset, ":* ");
199 } else {
200 error = belle_sip_snprintf(buff, buff_size, offset, ":%u ", id);
201 }
202 if (error != BELLE_SIP_OK) return error;
203 switch (type) {
204 case BELLE_SDP_RTCP_FB_ACK:
205 error = belle_sip_snprintf(buff, buff_size, offset, "ack");
206 if (error != BELLE_SIP_OK) return error;
207 switch (param) {
208 default:
209 case BELLE_SDP_RTCP_FB_NONE:
210 break;
211 case BELLE_SDP_RTCP_FB_RPSI:
212 error = belle_sip_snprintf(buff, buff_size, offset, " rpsi");
213 break;
214 case BELLE_SDP_RTCP_FB_APP:
215 error = belle_sip_snprintf(buff, buff_size, offset, " app");
216 break;
217 }
218 break;
219 case BELLE_SDP_RTCP_FB_NACK:
220 error = belle_sip_snprintf(buff, buff_size, offset, "nack");
221 if (error != BELLE_SIP_OK) return error;
222 switch (param) {
223 default:
224 case BELLE_SDP_RTCP_FB_NONE:
225 break;
226 case BELLE_SDP_RTCP_FB_PLI:
227 error = belle_sip_snprintf(buff, buff_size, offset, " pli");
228 break;
229 case BELLE_SDP_RTCP_FB_SLI:
230 error = belle_sip_snprintf(buff, buff_size, offset, " sli");
231 break;
232 case BELLE_SDP_RTCP_FB_RPSI:
233 error = belle_sip_snprintf(buff, buff_size, offset, " rpsi");
234 break;
235 case BELLE_SDP_RTCP_FB_APP:
236 error = belle_sip_snprintf(buff, buff_size, offset, " app");
237 break;
238 }
239 break;
240 case BELLE_SDP_RTCP_FB_TRR_INT:
241 error = belle_sip_snprintf(buff, buff_size, offset, "trr-int %u", belle_sdp_rtcp_fb_attribute_get_trr_int(attribute));
242 break;
243 case BELLE_SDP_RTCP_FB_CCM:
244 error = belle_sip_snprintf(buff, buff_size, offset, "ccm");
245 if (error != BELLE_SIP_OK) return error;
246 switch (param) {
247 case BELLE_SDP_RTCP_FB_FIR:
248 error = belle_sip_snprintf(buff, buff_size, offset, " fir");
249 break;
250 case BELLE_SDP_RTCP_FB_TMMBR:
251 error = belle_sip_snprintf(buff, buff_size, offset, " tmmbr");
252 if (belle_sdp_rtcp_fb_attribute_get_smaxpr(attribute) > 0) {
253 error = belle_sip_snprintf(buff, buff_size, offset, " smaxpr=%u", belle_sdp_rtcp_fb_attribute_get_smaxpr(attribute));
254 }
255 break;
256 default:
257 break;
258 }
259 break;
260 }
261 return error;
262 }
belle_sdp_rtcp_fb_attribute_init(belle_sdp_rtcp_fb_attribute_t * attribute)263 static void belle_sdp_rtcp_fb_attribute_init(belle_sdp_rtcp_fb_attribute_t* attribute) {
264 belle_sdp_attribute_set_name(BELLE_SDP_ATTRIBUTE(attribute), "rtcp-fb");
265 attribute->id = -1;
266 attribute->type = BELLE_SDP_RTCP_FB_TRR_INT;
267 attribute->param = BELLE_SDP_RTCP_FB_NONE;
268 attribute->trr_int = 0;
269 attribute->smaxpr = 0;
270 }
271 BELLE_SDP_NEW_WITH_CTR(rtcp_fb_attribute,belle_sdp_attribute)
272 BELLE_SDP_PARSE(rtcp_fb_attribute)
273 GET_SET_INT(belle_sdp_rtcp_fb_attribute,id,int8_t)
274 GET_SET_INT(belle_sdp_rtcp_fb_attribute,type,belle_sdp_rtcp_fb_val_type_t)
275 GET_SET_INT(belle_sdp_rtcp_fb_attribute,param,belle_sdp_rtcp_fb_val_param_t)
276 GET_SET_INT(belle_sdp_rtcp_fb_attribute,trr_int,uint16_t)
277 GET_SET_INT(belle_sdp_rtcp_fb_attribute,smaxpr,uint32_t)
278 /***************************************************************************************
279 * RTCP-XR Attribute
280 *
281 **************************************************************************************/
282 struct _belle_sdp_rtcp_xr_attribute {
283 belle_sdp_attribute_t base;
284 const char* rcvr_rtt_mode;
285 int rcvr_rtt_max_size;
286 unsigned int stat_summary;
287 belle_sip_list_t* stat_summary_flags;
288 unsigned int voip_metrics;
289 };
belle_sdp_rtcp_xr_attribute_get_stat_summary_flags(const belle_sdp_rtcp_xr_attribute_t * attribute)290 const belle_sip_list_t* belle_sdp_rtcp_xr_attribute_get_stat_summary_flags(const belle_sdp_rtcp_xr_attribute_t* attribute) {
291 return attribute->stat_summary_flags;
292 }
belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(belle_sdp_rtcp_xr_attribute_t * attribute,const char * flag)293 void belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(belle_sdp_rtcp_xr_attribute_t* attribute, const char* flag) {
294 attribute->stat_summary_flags = belle_sip_list_append(attribute->stat_summary_flags, belle_sip_strdup(flag));
295 }
belle_sdp_rtcp_xr_attribute_destroy(belle_sdp_rtcp_xr_attribute_t * attribute)296 void belle_sdp_rtcp_xr_attribute_destroy(belle_sdp_rtcp_xr_attribute_t* attribute) {
297 DESTROY_STRING(attribute,rcvr_rtt_mode)
298 belle_sip_list_free_with_data(attribute->stat_summary_flags, belle_sip_free);
299 }
belle_sdp_rtcp_xr_attribute_clone(belle_sdp_rtcp_xr_attribute_t * attribute,const belle_sdp_rtcp_xr_attribute_t * orig)300 void belle_sdp_rtcp_xr_attribute_clone(belle_sdp_rtcp_xr_attribute_t* attribute, const belle_sdp_rtcp_xr_attribute_t *orig) {
301 CLONE_STRING(belle_sdp_rtcp_xr_attribute,rcvr_rtt_mode,attribute,orig)
302 attribute->rcvr_rtt_max_size = orig->rcvr_rtt_max_size;
303 attribute->stat_summary = orig->stat_summary;
304 attribute->stat_summary_flags = belle_sip_list_copy_with_data(orig->stat_summary_flags, belle_sip_string_copyfunc);
305 attribute->voip_metrics = orig->voip_metrics;
306 }
belle_sdp_rtcp_xr_attribute_marshal(belle_sdp_rtcp_xr_attribute_t * attribute,char * buff,size_t buff_size,size_t * offset)307 belle_sip_error_code belle_sdp_rtcp_xr_attribute_marshal(belle_sdp_rtcp_xr_attribute_t* attribute, char * buff, size_t buff_size, size_t *offset) {
308 const char *rcvr_rtt_mode = NULL;
309 int rcvr_rtt_max_size = -1;
310 int nb_xr_formats = 0;
311 belle_sip_error_code error = belle_sdp_attribute_marshal(BELLE_SDP_ATTRIBUTE(attribute), buff, buff_size, offset);
312 if (error != BELLE_SIP_OK) return error;
313 rcvr_rtt_mode = belle_sdp_rtcp_xr_attribute_get_rcvr_rtt_mode(attribute);
314 if (rcvr_rtt_mode != NULL) {
315 error = belle_sip_snprintf(buff, buff_size, offset, "%srcvr-rtt=%s", nb_xr_formats++ == 0 ? ":" : " ", rcvr_rtt_mode);
316 if (error != BELLE_SIP_OK) return error;
317 rcvr_rtt_max_size = belle_sdp_rtcp_xr_attribute_get_rcvr_rtt_max_size(attribute);
318 if (rcvr_rtt_max_size > 0) {
319 error = belle_sip_snprintf(buff, buff_size, offset, ":%u", rcvr_rtt_max_size);
320 if (error != BELLE_SIP_OK) return error;
321 }
322 }
323 if (belle_sdp_rtcp_xr_attribute_has_stat_summary(attribute)) {
324 belle_sip_list_t* list;
325 int nb_stat_flags = 0;
326 error = belle_sip_snprintf(buff, buff_size, offset, "%sstat-summary", nb_xr_formats++ == 0 ? ":" : " ");
327 if (error != BELLE_SIP_OK) return error;
328 for (list = attribute->stat_summary_flags; list != NULL; list = list->next) {
329 error = belle_sip_snprintf(buff, buff_size, offset, "%s%s", nb_stat_flags++ == 0 ? "=" : ",", (const char*)list->data);
330 if (error != BELLE_SIP_OK) return error;
331 }
332 }
333 if (belle_sdp_rtcp_xr_attribute_has_voip_metrics(attribute)) {
334 error = belle_sip_snprintf(buff, buff_size, offset, "%svoip-metrics", nb_xr_formats++ == 0 ? ":" : " ");
335 if (error != BELLE_SIP_OK) return error;
336 }
337 return error;
338 }
belle_sdp_rtcp_xr_attribute_init(belle_sdp_rtcp_xr_attribute_t * attribute)339 static void belle_sdp_rtcp_xr_attribute_init(belle_sdp_rtcp_xr_attribute_t* attribute) {
340 belle_sdp_attribute_set_name(BELLE_SDP_ATTRIBUTE(attribute), "rtcp-xr");
341 }
342 BELLE_SDP_NEW_WITH_CTR(rtcp_xr_attribute,belle_sdp_attribute)
343 BELLE_SDP_PARSE(rtcp_xr_attribute)
344 GET_SET_STRING(belle_sdp_rtcp_xr_attribute,rcvr_rtt_mode)
345 GET_SET_INT(belle_sdp_rtcp_xr_attribute,rcvr_rtt_max_size,int)
346 GET_SET_BOOL(belle_sdp_rtcp_xr_attribute,stat_summary,has)
347 GET_SET_BOOL(belle_sdp_rtcp_xr_attribute,voip_metrics,has)
348 /***************************************************************************************
349 * Bandwidth
350 *
351 **************************************************************************************/
352 struct _belle_sdp_bandwidth {
353 belle_sip_object_t base;
354 const char* type;
355 int value;
356 };
belle_sdp_bandwidth_destroy(belle_sdp_bandwidth_t * bandwidth)357 void belle_sdp_bandwidth_destroy(belle_sdp_bandwidth_t* bandwidth) {
358 if (bandwidth->type) belle_sip_free((void*)bandwidth->type);
359 }
360
belle_sdp_bandwidth_clone(belle_sdp_bandwidth_t * bandwidth,const belle_sdp_bandwidth_t * orig)361 void belle_sdp_bandwidth_clone(belle_sdp_bandwidth_t *bandwidth, const belle_sdp_bandwidth_t *orig){
362 CLONE_STRING(belle_sdp_bandwidth,type,bandwidth,orig)
363 bandwidth->value=orig->value;
364 }
365
belle_sdp_bandwidth_marshal(belle_sdp_bandwidth_t * bandwidth,char * buff,size_t buff_size,size_t * offset)366 belle_sip_error_code belle_sdp_bandwidth_marshal(belle_sdp_bandwidth_t* bandwidth, char* buff, size_t buff_size, size_t *offset) {
367 return belle_sip_snprintf(buff,buff_size,offset,"b=%s:%i",bandwidth->type,bandwidth->value);
368 }
369
370 BELLE_SDP_NEW(bandwidth,belle_sip_object)
371 BELLE_SDP_PARSE(bandwidth)
372 GET_SET_STRING(belle_sdp_bandwidth,type);
373 GET_SET_INT(belle_sdp_bandwidth,value,int)
374
375 /************************
376 * connection
377 ***********************/
378 struct _belle_sdp_connection {
379 belle_sip_object_t base;
380 const char* network_type;
381 const char* address_type;
382 const char* address;
383 int ttl;
384 int range;
385 };
386
belle_sdp_connection_destroy(belle_sdp_connection_t * connection)387 void belle_sdp_connection_destroy(belle_sdp_connection_t* connection) {
388 DESTROY_STRING(connection,network_type)
389 DESTROY_STRING(connection,address_type)
390 DESTROY_STRING(connection,address)
391 }
392
belle_sdp_connection_clone(belle_sdp_connection_t * connection,const belle_sdp_connection_t * orig)393 void belle_sdp_connection_clone(belle_sdp_connection_t *connection, const belle_sdp_connection_t *orig){
394 CLONE_STRING(belle_sdp_connection,network_type,connection,orig)
395 CLONE_STRING(belle_sdp_connection,address_type,connection,orig)
396 CLONE_STRING(belle_sdp_connection,address,connection,orig)
397 connection->range=orig->range;
398 connection->ttl=orig->ttl;
399 }
400
belle_sdp_connection_marshal(belle_sdp_connection_t * connection,char * buff,size_t buff_size,size_t * offset)401 belle_sip_error_code belle_sdp_connection_marshal(belle_sdp_connection_t* connection, char* buff, size_t buff_size, size_t *offset) {
402 belle_sip_error_code error = belle_sip_snprintf(buff,buff_size,offset,"c=%s %s %s",connection->network_type,connection->address_type,connection->address);
403 if (error!=BELLE_SIP_OK) return error;
404 if (connection->ttl>0)
405 error = belle_sip_snprintf(buff,buff_size,offset,"/%i",connection->ttl);
406 if (error!=BELLE_SIP_OK) return error;
407 if (connection->range>0)
408 error = belle_sip_snprintf(buff,buff_size,offset,"/%i",connection->range);
409 return error;
410 }
411
BELLE_SDP_NEW(connection,belle_sip_object)412 BELLE_SDP_NEW(connection,belle_sip_object)
413 BELLE_SDP_PARSE(connection)
414 belle_sdp_connection_t* belle_sdp_connection_create(const char* net_type, const char* addr_type, const char* addr) {
415 belle_sdp_connection_t* connection = belle_sdp_connection_new();
416 belle_sdp_connection_set_network_type(connection,net_type);
417 belle_sdp_connection_set_address_type(connection,addr_type);
418 belle_sdp_connection_set_address(connection,addr);
419 return connection;
420 }
421 GET_SET_STRING(belle_sdp_connection,network_type);
422 GET_SET_STRING(belle_sdp_connection,address_type);
423 GET_SET_STRING(belle_sdp_connection,address);
424 GET_SET_INT(belle_sdp_connection,ttl,int);
425 GET_SET_INT(belle_sdp_connection,range,int);
426 /************************
427 * email
428 ***********************/
429 struct _belle_sdp_email {
430 belle_sip_object_t base;
431 char* value;
432 };
433
belle_sdp_email_destroy(belle_sdp_email_t * email)434 void belle_sdp_email_destroy(belle_sdp_email_t* email) {
435 DESTROY_STRING(email,value)
436 }
437
belle_sdp_email_clone(belle_sdp_email_t * email,const belle_sdp_email_t * orig)438 void belle_sdp_email_clone(belle_sdp_email_t *email, const belle_sdp_email_t *orig){
439 CLONE_STRING(belle_sdp_email,value,email,orig)
440 }
441
belle_sdp_email_marshal(belle_sdp_email_t * email,char * buff,size_t buff_size,size_t * offset)442 belle_sip_error_code belle_sdp_email_marshal(belle_sdp_email_t* email, char* buff, size_t buff_size, size_t *offset) {
443 return belle_sip_snprintf(buff,buff_size,offset,"e=%s",email->value);
444 }
445
446 BELLE_SDP_NEW(email,belle_sip_object)
447 BELLE_SDP_PARSE(email)
448 GET_SET_STRING(belle_sdp_email,value);
449 /************************
450 * info
451 ***********************/
452 struct _belle_sdp_info {
453 belle_sip_object_t base;
454 const char* value;
455 };
456
belle_sdp_info_destroy(belle_sdp_info_t * info)457 void belle_sdp_info_destroy(belle_sdp_info_t* info) {
458 DESTROY_STRING(info,value)
459 }
460
belle_sdp_info_clone(belle_sdp_info_t * info,const belle_sdp_info_t * orig)461 void belle_sdp_info_clone(belle_sdp_info_t *info, const belle_sdp_info_t *orig){
462 CLONE_STRING(belle_sdp_info,value,info,orig)
463 }
464
belle_sdp_info_marshal(belle_sdp_info_t * info,char * buff,size_t buff_size,size_t * offset)465 belle_sip_error_code belle_sdp_info_marshal(belle_sdp_info_t* info, char* buff, size_t buff_size, size_t *offset) {
466 return belle_sip_snprintf(buff,buff_size,offset,"i=%s",info->value);
467 }
468
469 BELLE_SDP_NEW(info,belle_sip_object)
470 BELLE_SDP_PARSE(info)
471 GET_SET_STRING(belle_sdp_info,value);
472 /************************
473 * media
474 ***********************/
475 struct _belle_sdp_media {
476 belle_sip_object_t base;
477 const char* media_type;
478 int media_port;
479 belle_sip_list_t* media_formats;
480 int port_count;
481 const char* protocol;
482 const char* raw_fmt;
483 };
belle_sdp_media_get_media_formats(const belle_sdp_media_t * media)484 belle_sip_list_t* belle_sdp_media_get_media_formats(const belle_sdp_media_t* media) {
485 return media->media_formats;
486 }
belle_sdp_media_set_media_formats(belle_sdp_media_t * media,belle_sip_list_t * formats)487 void belle_sdp_media_set_media_formats( belle_sdp_media_t* media, belle_sip_list_t* formats) {
488 /*belle_sip_list_free(media->media_formats); to allow easy list management might be better to add an append format method*/
489 media->media_formats = formats;
490 }
belle_sdp_media_destroy(belle_sdp_media_t * media)491 void belle_sdp_media_destroy(belle_sdp_media_t* media) {
492 DESTROY_STRING(media,media_type)
493 belle_sip_list_free(media->media_formats);
494 DESTROY_STRING(media,protocol)
495 }
belle_sdp_media_init(belle_sdp_media_t * media)496 static void belle_sdp_media_init(belle_sdp_media_t* media) {
497 media->port_count=1;
498 }
499
belle_sdp_media_clone(belle_sdp_media_t * media,const belle_sdp_media_t * orig)500 void belle_sdp_media_clone(belle_sdp_media_t *media, const belle_sdp_media_t *orig){
501 CLONE_STRING(belle_sdp_media,media_type,media,orig)
502 media->media_port=orig->media_port;
503 media->media_formats = belle_sip_list_copy(orig->media_formats);
504 media->port_count=orig->port_count;
505 CLONE_STRING(belle_sdp_media,protocol,media,orig)
506 }
507
belle_sdp_media_marshal(belle_sdp_media_t * media,char * buff,size_t buff_size,size_t * offset)508 belle_sip_error_code belle_sdp_media_marshal(belle_sdp_media_t* media, char* buff, size_t buff_size, size_t *offset) {
509 belle_sip_list_t* list=media->media_formats;
510 belle_sip_error_code error=belle_sip_snprintf(buff,buff_size,offset,"m=%s %i",media->media_type,media->media_port);
511 if (error!=BELLE_SIP_OK) return error;
512 if (media->port_count>1) {
513 error=belle_sip_snprintf(buff,buff_size,offset,"/%i",media->port_count);
514 if (error!=BELLE_SIP_OK) return error;
515 }
516 error=belle_sip_snprintf(buff,buff_size,offset," %s",media->protocol);
517 if (error!=BELLE_SIP_OK) return error;
518 for(;list!=NULL;list=list->next){
519 error=belle_sip_snprintf(buff,buff_size,offset," %li",(long)(intptr_t)list->data);
520 if (error!=BELLE_SIP_OK) return error;
521 }
522 return error;
523 }
524
BELLE_SDP_NEW_WITH_CTR(media,belle_sip_object)525 BELLE_SDP_NEW_WITH_CTR(media,belle_sip_object)
526 BELLE_SDP_PARSE(media)
527 belle_sdp_media_t* belle_sdp_media_create(const char* media_type
528 ,int media_port
529 ,int port_count
530 ,const char* protocol
531 ,belle_sip_list_t* static_media_formats) {
532 belle_sdp_media_t* media= belle_sdp_media_new();
533 belle_sdp_media_set_media_type(media,media_type);
534 belle_sdp_media_set_media_port(media,media_port);
535 belle_sdp_media_set_port_count(media,port_count);
536 belle_sdp_media_set_protocol(media,protocol);
537 if (static_media_formats) belle_sdp_media_set_media_formats(media,static_media_formats);
538 return media;
539 }
540 GET_SET_STRING(belle_sdp_media,media_type);
541 GET_SET_STRING(belle_sdp_media,protocol);
542 GET_SET_INT(belle_sdp_media,media_port,int)
543 GET_SET_INT(belle_sdp_media,port_count,int)
544
545 /************************
546 * base_description
547 ***********************/
548 typedef struct _belle_sdp_base_description {
549 belle_sip_object_t base;
550 belle_sdp_info_t* info;
551 belle_sdp_connection_t* connection;
552 belle_sip_list_t* bandwidths;
553 belle_sip_list_t* attributes;
554 } belle_sdp_base_description_t;
555
belle_sdp_base_description_destroy(belle_sdp_base_description_t * base_description)556 static void belle_sdp_base_description_destroy(belle_sdp_base_description_t* base_description) {
557 if (base_description->info) belle_sip_object_unref(BELLE_SIP_OBJECT(base_description->info));
558 if (base_description->connection) belle_sip_object_unref(BELLE_SIP_OBJECT(base_description->connection));
559 belle_sip_list_free_with_data(base_description->bandwidths,belle_sip_object_freefunc);
560 belle_sip_list_free_with_data(base_description->attributes,belle_sip_object_freefunc);
561 }
belle_sdp_base_description_init(belle_sdp_base_description_t * base_description)562 static void belle_sdp_base_description_init(belle_sdp_base_description_t* base_description) {
563 }
belle_sdp_base_description_clone(belle_sdp_base_description_t * base_description,const belle_sdp_base_description_t * orig)564 static void belle_sdp_base_description_clone(belle_sdp_base_description_t *base_description, const belle_sdp_base_description_t *orig){
565 if (orig->info) base_description->info = BELLE_SDP_INFO(belle_sip_object_clone_and_ref(BELLE_SIP_OBJECT(orig->info)));
566 if (orig->connection) base_description->connection = BELLE_SDP_CONNECTION(belle_sip_object_clone_and_ref(BELLE_SIP_OBJECT(orig->connection)));
567 base_description->bandwidths = belle_sip_list_copy_with_data(orig->bandwidths,belle_sip_object_copyfunc);
568 base_description->attributes = belle_sip_list_copy_with_data(orig->attributes,belle_sip_object_copyfunc);
569
570 }
571
belle_sdp_base_description_marshal(belle_sdp_base_description_t * base_description,char * buff,size_t buff_size,size_t * offset)572 belle_sip_error_code belle_sdp_base_description_marshal(belle_sdp_base_description_t* base_description, char* buff, size_t buff_size, size_t *offset) {
573 belle_sip_error_code error=BELLE_SIP_OK;
574 belle_sip_list_t* bandwidths;
575 // belle_sip_list_t* attributes;
576 if (base_description->info) {
577 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(base_description->info),buff,buff_size,offset);
578 if (error!=BELLE_SIP_OK) return error;
579 error=belle_sip_snprintf(buff, buff_size, offset, "\r\n");
580 if (error!=BELLE_SIP_OK) return error;
581 }
582 if (base_description->connection) {
583 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(base_description->connection),buff,buff_size,offset);
584 if (error!=BELLE_SIP_OK) return error;
585 error=belle_sip_snprintf(buff, buff_size, offset, "\r\n");
586 if (error!=BELLE_SIP_OK) return error;
587 }
588 for(bandwidths=base_description->bandwidths;bandwidths!=NULL;bandwidths=bandwidths->next){
589 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(bandwidths->data),buff,buff_size,offset);
590 if (error!=BELLE_SIP_OK) return error;
591 error=belle_sip_snprintf(buff, buff_size, offset, "\r\n");
592 if (error!=BELLE_SIP_OK) return error;
593 }
594 // for(attributes=base_description->attributes;attributes!=NULL;attributes=attributes->next){
595 // error=belle_sip_object_marshal(BELLE_SIP_OBJECT(attributes->data),buff,buff_size,offset);
596 // error=belle_sip_snprintf(buff, buff_size, offset, "\r\n");
597 // }
598 return error;
599 }
600
601 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sdp_base_description_t);
602 BELLE_SIP_INSTANCIATE_VPTR(belle_sdp_base_description_t
603 ,belle_sip_object_t
604 ,belle_sdp_base_description_destroy
605 ,belle_sdp_base_description_clone
606 ,belle_sdp_base_description_marshal
607 ,FALSE);
608
belle_sdp_base_description_attribute_comp_func(const belle_sdp_attribute_t * a,const char * b)609 static int belle_sdp_base_description_attribute_comp_func(const belle_sdp_attribute_t* a, const char*b) {
610 return strcmp(a->name,b);
611 }
belle_sdp_base_description_get_attribute(const belle_sdp_base_description_t * base_description,const char * name)612 belle_sdp_attribute_t* belle_sdp_base_description_get_attribute(const belle_sdp_base_description_t* base_description, const char* name) {
613 belle_sip_list_t* attribute;
614 attribute = belle_sip_list_find_custom(base_description->attributes, (belle_sip_compare_func)belle_sdp_base_description_attribute_comp_func, name);
615 if (attribute) {
616 return ((belle_sdp_attribute_t*)attribute->data);
617 } else {
618 return NULL;
619 }
620 }
belle_sdp_base_description_get_attribute_value(const belle_sdp_base_description_t * base_description,const char * name)621 const char* belle_sdp_base_description_get_attribute_value(const belle_sdp_base_description_t* base_description, const char* name) {
622 belle_sdp_attribute_t* attribute = belle_sdp_base_description_get_attribute(base_description,name);
623 if (attribute) {
624 return belle_sdp_attribute_get_value(attribute);
625 } else return NULL;
626
627 }
belle_sdp_base_description_get_attributes(const belle_sdp_base_description_t * base_description)628 belle_sip_list_t* belle_sdp_base_description_get_attributes(const belle_sdp_base_description_t* base_description) {
629 return base_description->attributes;
630 }
belle_sdp_base_description_bandwidth_comp_func(const belle_sdp_bandwidth_t * a,const char * b)631 static int belle_sdp_base_description_bandwidth_comp_func(const belle_sdp_bandwidth_t* a, const char*b) {
632 return strcmp(a->type,b);
633 }
634
635
belle_sdp_base_description_get_bandwidth(const belle_sdp_base_description_t * base_description,const char * name)636 belle_sdp_bandwidth_t* belle_sdp_base_description_get_bandwidth(const belle_sdp_base_description_t *base_description, const char *name){
637 belle_sip_list_t* found = belle_sip_list_find_custom(base_description->bandwidths, (belle_sip_compare_func)belle_sdp_base_description_bandwidth_comp_func, name);
638 if( found ){
639 return ((belle_sdp_bandwidth_t*)found->data);
640 } else {
641 return NULL;
642 }
643 }
644
belle_sdp_base_description_get_bandwidth_value(const belle_sdp_base_description_t * base_description,const char * name)645 int belle_sdp_base_description_get_bandwidth_value(const belle_sdp_base_description_t* base_description, const char* name) {
646 belle_sip_list_t* bandwidth;
647 bandwidth = belle_sip_list_find_custom(base_description->bandwidths, (belle_sip_compare_func)belle_sdp_base_description_bandwidth_comp_func, name);
648 if (bandwidth) {
649 return ((belle_sdp_bandwidth_t*)bandwidth->data)->value;
650 } else {
651 return -1;
652 }
653 }
belle_sdp_base_description_remove_attribute(belle_sdp_base_description_t * base_description,const char * name)654 void belle_sdp_base_description_remove_attribute(belle_sdp_base_description_t* base_description,const char* name) {
655 belle_sip_list_t* attribute;
656 attribute = belle_sip_list_find_custom(base_description->attributes, (belle_sip_compare_func)belle_sdp_base_description_attribute_comp_func, name);
657 if (attribute) {
658 belle_sip_object_unref(BELLE_SIP_OBJECT(attribute->data));
659 base_description->attributes = belle_sip_list_delete_link(base_description->attributes,attribute);
660 }
661
662 }
belle_sdp_base_description_remove_bandwidth(belle_sdp_base_description_t * base_description,const char * name)663 void belle_sdp_base_description_remove_bandwidth(belle_sdp_base_description_t* base_description,const char* name) {
664 belle_sip_list_t* bandwidth;
665 bandwidth = belle_sip_list_find_custom(base_description->bandwidths, (belle_sip_compare_func)belle_sdp_base_description_bandwidth_comp_func, name);
666 if (bandwidth) {
667 belle_sip_object_unref(BELLE_SIP_OBJECT(bandwidth->data));
668 base_description->bandwidths = belle_sip_list_delete_link(base_description->bandwidths,bandwidth);
669 }
670 }
belle_sdp_base_description_set_attribute_value(belle_sdp_base_description_t * base_description,const char * name,const char * value)671 void belle_sdp_base_description_set_attribute_value(belle_sdp_base_description_t* base_description, const char* name, const char* value) {
672 belle_sdp_raw_attribute_t* attribute = belle_sdp_raw_attribute_new();
673 belle_sdp_attribute_set_name(BELLE_SDP_ATTRIBUTE(attribute),name);
674 belle_sdp_raw_attribute_set_value(attribute,value);
675 base_description->attributes = belle_sip_list_append(base_description->attributes,belle_sip_object_ref(attribute));
676 }
belle_sdp_base_description_add_attribute(belle_sdp_base_description_t * base_description,const belle_sdp_attribute_t * attribute)677 void belle_sdp_base_description_add_attribute(belle_sdp_base_description_t* base_description, const belle_sdp_attribute_t* attribute) {
678 base_description->attributes = belle_sip_list_append(base_description->attributes,(void*)belle_sip_object_ref(BELLE_SIP_OBJECT(attribute)));
679 }
680
681 #define SET_LIST(list_name,value) \
682 belle_sip_list_t* list;\
683 if (list_name) {\
684 belle_sip_list_free_with_data(list_name,belle_sip_object_unref);\
685 } \
686 for (list=value;list !=NULL; list=list->next) {\
687 belle_sip_object_ref(BELLE_SIP_OBJECT(list->data));\
688 }\
689 list_name=value;
690
691
belle_sdp_base_description_set_attributes(belle_sdp_base_description_t * base_description,belle_sip_list_t * attributes)692 void belle_sdp_base_description_set_attributes(belle_sdp_base_description_t* base_description, belle_sip_list_t* attributes) {
693 SET_LIST(base_description->attributes,attributes)
694 }
belle_sdp_base_description_set_bandwidth(belle_sdp_base_description_t * base_description,const char * type,int value)695 void belle_sdp_base_description_set_bandwidth(belle_sdp_base_description_t* base_description, const char* type, int value) {
696
697 belle_sdp_bandwidth_t* bandwidth = BELLE_SDP_BANDWIDTH(belle_sdp_base_description_get_bandwidth(base_description, type));
698 if( bandwidth == NULL ){
699 bandwidth= belle_sdp_bandwidth_new();
700 belle_sdp_bandwidth_set_type(bandwidth,type);
701 belle_sdp_bandwidth_set_value(bandwidth,value);
702 base_description->bandwidths = belle_sip_list_append(base_description->bandwidths,belle_sip_object_ref(bandwidth));
703 } else {
704 belle_sdp_bandwidth_set_value(bandwidth,value);
705 }
706 }
belle_sdp_base_description_add_bandwidth(belle_sdp_base_description_t * base_description,const belle_sdp_bandwidth_t * bandwidth)707 void belle_sdp_base_description_add_bandwidth(belle_sdp_base_description_t* base_description, const belle_sdp_bandwidth_t* bandwidth) {
708
709 base_description->bandwidths = belle_sip_list_append(base_description->bandwidths,(void *)belle_sip_object_ref((void *)bandwidth));
710 }
belle_sdp_base_description_set_bandwidths(belle_sdp_base_description_t * base_description,belle_sip_list_t * bandwidths)711 void belle_sdp_base_description_set_bandwidths(belle_sdp_base_description_t* base_description, belle_sip_list_t* bandwidths) {
712 SET_LIST(base_description->bandwidths,bandwidths)
713 }
714
715 /************************
716 * media_description
717 ***********************/
718 struct _belle_sdp_media_description {
719 belle_sdp_base_description_t base_description;
720 belle_sdp_media_t* media;
721 };
belle_sdp_media_description_destroy(belle_sdp_media_description_t * media_description)722 void belle_sdp_media_description_destroy(belle_sdp_media_description_t* media_description) {
723 if (media_description->media) belle_sip_object_unref(BELLE_SIP_OBJECT((media_description->media)));
724 }
725
belle_sdp_media_description_clone(belle_sdp_media_description_t * media_description,const belle_sdp_media_description_t * orig)726 void belle_sdp_media_description_clone(belle_sdp_media_description_t *media_description, const belle_sdp_media_description_t *orig){
727 if (orig->media) media_description->media = BELLE_SDP_MEDIA(belle_sip_object_clone_and_ref(BELLE_SIP_OBJECT((orig->media))));
728 }
729
belle_sdp_media_description_marshal(belle_sdp_media_description_t * media_description,char * buff,size_t buff_size,size_t * offset)730 belle_sip_error_code belle_sdp_media_description_marshal(belle_sdp_media_description_t* media_description, char* buff, size_t buff_size, size_t *offset) {
731 belle_sip_list_t* attributes;
732 belle_sip_error_code error=belle_sip_object_marshal(BELLE_SIP_OBJECT(media_description->media),buff,buff_size,offset);
733 if (error!=BELLE_SIP_OK) return error;
734 error=belle_sip_snprintf(buff, buff_size, offset, "\r\n");
735 if (error!=BELLE_SIP_OK) return error;
736 error=belle_sdp_base_description_marshal(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),buff,buff_size,offset);
737 if (error!=BELLE_SIP_OK) return error;
738
739 for(attributes=media_description->base_description.attributes;attributes!=NULL;attributes=attributes->next){
740 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(attributes->data),buff,buff_size,offset);
741 if (error!=BELLE_SIP_OK) return error;
742 error=belle_sip_snprintf(buff, buff_size, offset, "\r\n");
743 if (error!=BELLE_SIP_OK) return error;
744 }
745 return error;
746 }
747
BELLE_SDP_NEW(media_description,belle_sdp_base_description)748 BELLE_SDP_NEW(media_description,belle_sdp_base_description)
749 belle_sdp_media_description_t* belle_sdp_media_description_create(const char* media_type
750 ,int media_port
751 ,int port_count
752 ,const char* protocol
753 ,belle_sip_list_t* static_media_formats) {
754 belle_sdp_media_description_t* media_desc=belle_sdp_media_description_new();
755 belle_sdp_media_description_set_media(media_desc,belle_sdp_media_create(media_type,media_port,port_count,protocol,static_media_formats));
756 return media_desc;
757 }
BELLE_SDP_PARSE(media_description)758 BELLE_SDP_PARSE(media_description)
759 void belle_sdp_media_description_add_dynamic_payloads(belle_sdp_media_description_t* media_description, belle_sip_list_t* payloadNames, belle_sip_list_t* payloadValues) {
760 belle_sip_error("belle_sdp_media_description_add_dynamic_payloads not implemented yet");
761 }
belle_sdp_media_description_get_attribute(const belle_sdp_media_description_t * media_description,const char * name)762 belle_sdp_attribute_t* belle_sdp_media_description_get_attribute(const belle_sdp_media_description_t* media_description, const char* name) {
763 return belle_sdp_base_description_get_attribute(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),name);
764 }
belle_sdp_media_description_get_attribute_value(const belle_sdp_media_description_t * media_description,const char * name)765 const char* belle_sdp_media_description_get_attribute_value(const belle_sdp_media_description_t* media_description, const char* name) {
766 return belle_sdp_base_description_get_attribute_value(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),name);
767 }
belle_sdp_media_description_get_attributes(const belle_sdp_media_description_t * media_description)768 belle_sip_list_t* belle_sdp_media_description_get_attributes(const belle_sdp_media_description_t* media_description) {
769 return BELLE_SIP_CAST(media_description,belle_sdp_base_description_t)->attributes;
770 }
771
belle_sdp_media_description_get_bandwidth(const belle_sdp_media_description_t * media_description,const char * name)772 int belle_sdp_media_description_get_bandwidth(const belle_sdp_media_description_t* media_description, const char* name) {
773 return belle_sdp_base_description_get_bandwidth_value(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),name);
774 }
belle_sdp_media_description_get_bandwidths(const belle_sdp_media_description_t * media_description)775 belle_sip_list_t* belle_sdp_media_description_get_bandwidths(const belle_sdp_media_description_t* media_description) {
776 return BELLE_SIP_CAST(media_description,belle_sdp_base_description_t)->bandwidths;
777 }
belle_sdp_media_description_get_connection(const belle_sdp_media_description_t * media_description)778 belle_sdp_connection_t* belle_sdp_media_description_get_connection(const belle_sdp_media_description_t* media_description) {
779 return BELLE_SIP_CAST(media_description,belle_sdp_base_description_t)->connection;
780 }
belle_sdp_media_description_get_info(const belle_sdp_media_description_t * media_description)781 belle_sdp_info_t* belle_sdp_media_description_get_info(const belle_sdp_media_description_t* media_description) {
782 return BELLE_SIP_CAST(media_description,belle_sdp_base_description_t)->info;
783 }
784 /*belle_sdp_key_t* belle_sdp_media_description_get_key(const belle_sdp_media_description_t* media_description);*/
belle_sdp_media_description_get_media(const belle_sdp_media_description_t * media_description)785 belle_sdp_media_t* belle_sdp_media_description_get_media(const belle_sdp_media_description_t* media_description) {
786 return media_description->media;
787 }
788
789 struct static_payload {
790 unsigned char number;
791 int channel_count;
792 const char* type;
793 int rate;
794 };
795 #define STATIC_PAYLOAD_LIST_LENTH 8
796 /*
797 * rfc 3551
798 * PT encoding media type clock rate channels
799 name (Hz)
800 ___________________________________________________
801 0 PCMU A 8,000 1
802 1 reserved A
803 2 reserved A
804 3 GSM A 8,000 1
805 4 G723 A 8,000 1
806 5 DVI4 A 8,000 1
807 6 DVI4 A 16,000 1
808 7 LPC A 8,000 1
809 8 PCMA A 8,000 1
810 9 G722 A 8,000 1
811 10 L16 A 44,100 2
812 11 L16 A 44,100 1
813 12 QCELP A 8,000 1
814 13 CN A 8,000 1
815 14 MPA A 90,000 (see text)
816 15 G728 A 8,000 1
817 16 DVI4 A 11,025 1
818 17 DVI4 A 22,050 1
819 18 G729 A 8,000 1
820 Table 4: Payload types (PT) for audio encodings
821
822 PT encoding media type clock rate
823 name (Hz)
824 _____________________________________________
825 24 unassigned V
826 25 CelB V 90,000
827 26 JPEG V 90,000
828 27 unassigned V
829 28 nv V 90,000
830 29 unassigned V
831 30 unassigned V
832 31 H261 V 90,000
833 32 MPV V 90,000
834 33 MP2T AV 90,000
835 34 H263 V 90,000
836
837 Table 5: Payload types (PT) for video and combined
838 encodings
839
840
841 *
842 * */
843
844 const struct static_payload static_payload_list [] ={
845 /*audio*/
846 {0,1,"PCMU",8000},
847 {3,1,"GSM",8000},
848 {4,1,"G723",8000},
849 {5,1,"DVI4",8000},
850 {6,1,"DVI4",16000},
851 {7,1,"LPC",8000},
852 {8,1,"PCMA",8000},
853 {9,1,"G722",8000},
854 {10,2,"L16",44100},
855 {11,1,"L16",44100},
856 {12,1,"QCELP",8000},
857 {13,1,"CN",8000},
858 {14,1,"MPA",90000},
859 {15,1,"G728",8000},
860 {16,1,"DVI4",11025},
861 {17,1,"DVI4",22050},
862 {18,1,"G729",8000},
863 /*video*/
864 {25,0,"CelB",90000},
865 {26,0,"JPEG",90000},
866 {28,0,"nv",90000},
867 {31,0,"H261",90000},
868 {32,0,"MPV",90000},
869 {33,0,"MP2T",90000},
870 {34,0,"H263",90000}
871 };
872
873 static const size_t payload_list_elements=sizeof(static_payload_list)/sizeof(struct static_payload);
874
mime_parameter_is_static(const belle_sdp_mime_parameter_t * param)875 static int mime_parameter_is_static(const belle_sdp_mime_parameter_t *param){
876 const struct static_payload* iterator;
877 size_t i;
878
879 for (iterator = static_payload_list,i=0;i<payload_list_elements;i++,iterator++) {
880 if (iterator->number == param->media_format &&
881 strcasecmp(iterator->type,param->type)==0 &&
882 iterator->channel_count==param->channel_count &&
883 iterator->rate==param->rate ) {
884 return TRUE;
885 }
886 }
887 return FALSE;
888 }
889
mime_parameter_fill_from_static(belle_sdp_mime_parameter_t * mime_parameter,int format)890 static int mime_parameter_fill_from_static(belle_sdp_mime_parameter_t *mime_parameter,int format) {
891 const struct static_payload* iterator;
892 size_t i;
893
894 for (iterator = static_payload_list,i=0;i<payload_list_elements;i++,iterator++) {
895 if (iterator->number == format) {
896 belle_sdp_mime_parameter_set_type(mime_parameter,iterator->type);
897 belle_sdp_mime_parameter_set_rate(mime_parameter,iterator->rate);
898 belle_sdp_mime_parameter_set_channel_count(mime_parameter,iterator->channel_count);
899 break;
900 }
901 }
902 return 0;
903 }
904
mime_parameter_fill_from_rtpmap(belle_sdp_mime_parameter_t * mime_parameter,const char * rtpmap,int is_audio)905 static int mime_parameter_fill_from_rtpmap(belle_sdp_mime_parameter_t *mime_parameter, const char *rtpmap, int is_audio){
906 char *mime=belle_sip_strdup(rtpmap);
907 char *p=strchr(mime,'/');
908 if (p){
909 char *chans;
910 *p='\0';
911 p++;
912 chans=strchr(p,'/');
913 if (chans){
914 *chans='\0';
915 chans++;
916 belle_sdp_mime_parameter_set_channel_count(mime_parameter,atoi(chans));
917 }else if (is_audio) belle_sdp_mime_parameter_set_channel_count(mime_parameter,1); /*in absence of channel count, 1 is implicit for audio streams*/
918 belle_sdp_mime_parameter_set_rate(mime_parameter,atoi(p));
919 }
920 belle_sdp_mime_parameter_set_type(mime_parameter,mime);
921 belle_sip_free(mime);
922 return 0;
923 }
924 /* return the value of attr "field" for payload pt at line pos (field=rtpmap,fmtp...)*/
belle_sdp_media_description_a_attr_value_get_with_pt(const belle_sdp_media_description_t * media_description,int pt,const char * field)925 static const char *belle_sdp_media_description_a_attr_value_get_with_pt(const belle_sdp_media_description_t* media_description,int pt,const char *field)
926 {
927 int tmppt=0,scanned=0;
928 const char *tmp;
929 belle_sdp_attribute_t *attr;
930 belle_sip_list_t* attribute_list;
931 for ( attribute_list =belle_sdp_media_description_get_attributes(media_description)
932 ;attribute_list!=NULL
933 ;attribute_list=attribute_list->next) {
934
935 attr = BELLE_SDP_ATTRIBUTE(attribute_list->data);
936 if (strcmp(field,belle_sdp_attribute_get_name(attr))==0 && belle_sdp_attribute_get_value(attr)!=NULL){
937 int nb = sscanf(belle_sdp_attribute_get_value(attr),"%i %n",&tmppt,&scanned);
938 /* the return value may depend on how %n is interpreted by the libc: see manpage*/
939 if (nb == 1 || nb==2 ){
940 if (pt==tmppt){
941 tmp=belle_sdp_attribute_get_value(attr)+scanned;
942 if (strlen(tmp)>0)
943 return tmp;
944 }
945 }else belle_sip_warning("sdp has a strange a= line (%s) nb=%i",belle_sdp_attribute_get_value(attr),nb);
946 }
947 }
948 return NULL;
949 }
950
belle_sdp_media_description_build_mime_parameters(const belle_sdp_media_description_t * media_description)951 belle_sip_list_t* belle_sdp_media_description_build_mime_parameters(const belle_sdp_media_description_t* media_description) {
952 /*First, get media type*/
953 belle_sdp_media_t* media = belle_sdp_media_description_get_media(media_description);
954 belle_sip_list_t* mime_parameter_list=NULL;
955 belle_sip_list_t* media_formats=NULL;
956 belle_sdp_mime_parameter_t* mime_parameter;
957 const char* rtpmap=NULL;
958 const char* fmtp=NULL;
959 const char* ptime=NULL;
960 const char* max_ptime=NULL;
961 int ptime_as_int=-1;
962 int max_ptime_as_int=-1;
963 int is_audio=0;
964
965 if (!media) {
966 belle_sip_error("belle_sdp_media_description_build_mime_parameters: no media");
967 return NULL;
968 }
969 if (strcasecmp(belle_sdp_media_get_media_type(media),"audio")==0) is_audio=1;
970 ptime = belle_sdp_media_description_get_attribute_value(media_description,"ptime");
971 ptime?ptime_as_int=atoi(ptime):-1;
972 max_ptime = belle_sdp_media_description_get_attribute_value(media_description,"maxptime");
973 max_ptime?max_ptime_as_int=atoi(max_ptime):-1;
974
975 for (media_formats = belle_sdp_media_get_media_formats(media);media_formats!=NULL;media_formats=media_formats->next) {
976 /*create mime parameters with format*/
977 mime_parameter = belle_sdp_mime_parameter_new();
978 belle_sdp_mime_parameter_set_ptime(mime_parameter,ptime_as_int);
979 belle_sdp_mime_parameter_set_max_ptime(mime_parameter,max_ptime_as_int);
980 belle_sdp_mime_parameter_set_media_format(mime_parameter,(int)(intptr_t)media_formats->data);
981
982 /*get rtpmap*/
983 rtpmap = belle_sdp_media_description_a_attr_value_get_with_pt(media_description
984 ,belle_sdp_mime_parameter_get_media_format(mime_parameter)
985 ,"rtpmap");
986 if (rtpmap) {
987 mime_parameter_fill_from_rtpmap(mime_parameter,rtpmap,is_audio);
988 }else{
989 mime_parameter_fill_from_static(mime_parameter,belle_sdp_mime_parameter_get_media_format(mime_parameter));
990 }
991 fmtp = belle_sdp_media_description_a_attr_value_get_with_pt(media_description
992 ,belle_sdp_mime_parameter_get_media_format(mime_parameter)
993 ,"fmtp");
994 if (fmtp) {
995 belle_sdp_mime_parameter_set_parameters(mime_parameter,fmtp);
996 }
997
998 mime_parameter_list=belle_sip_list_append(mime_parameter_list,mime_parameter);
999 }
1000 return mime_parameter_list;
1001 }
1002 #define MAX_FMTP_LENGTH 512
1003
belle_sdp_media_description_append_values_from_mime_parameter(belle_sdp_media_description_t * media_description,const belle_sdp_mime_parameter_t * mime_parameter)1004 void belle_sdp_media_description_append_values_from_mime_parameter(belle_sdp_media_description_t* media_description, const belle_sdp_mime_parameter_t* mime_parameter) {
1005 belle_sdp_media_t* media = belle_sdp_media_description_get_media(media_description);
1006 char atribute_value [MAX_FMTP_LENGTH];
1007 int current_ptime=0;
1008 int current_max_ptime=0;
1009
1010 belle_sdp_media_set_media_formats(media,belle_sip_list_append(belle_sdp_media_get_media_formats(media)
1011 ,(void*)(intptr_t)(belle_sdp_mime_parameter_get_media_format(mime_parameter))));
1012
1013 if (belle_sdp_media_description_get_attribute_value(media_description,"ptime")) {
1014 current_ptime=atoi(belle_sdp_media_description_get_attribute_value(media_description,"ptime"));
1015 belle_sdp_media_description_remove_attribute(media_description,"ptime");
1016 }
1017
1018 if (belle_sdp_media_description_get_attribute_value(media_description,"maxptime")) {
1019 current_max_ptime=atoi(belle_sdp_media_description_get_attribute_value(media_description,"maxptime"));
1020 belle_sdp_media_description_remove_attribute(media_description,"maxptime");
1021 }
1022
1023 #ifndef BELLE_SDP_FORCE_RTP_MAP /* defined to for RTP map even for static codec*/
1024 if (!mime_parameter_is_static(mime_parameter)) {
1025 /*dynamic payload*/
1026 #endif
1027 if (belle_sdp_mime_parameter_get_channel_count(mime_parameter)>1) {
1028 snprintf(atribute_value,MAX_FMTP_LENGTH,"%i %s/%i/%i"
1029 ,belle_sdp_mime_parameter_get_media_format(mime_parameter)
1030 ,belle_sdp_mime_parameter_get_type(mime_parameter)
1031 ,belle_sdp_mime_parameter_get_rate(mime_parameter)
1032 ,belle_sdp_mime_parameter_get_channel_count(mime_parameter));
1033 } else {
1034 snprintf(atribute_value,MAX_FMTP_LENGTH,"%i %s/%i"
1035 ,belle_sdp_mime_parameter_get_media_format(mime_parameter)
1036 ,belle_sdp_mime_parameter_get_type(mime_parameter)
1037 ,belle_sdp_mime_parameter_get_rate(mime_parameter));
1038 }
1039 belle_sdp_media_description_set_attribute_value(media_description,"rtpmap",atribute_value);
1040 #ifndef BELLE_SDP_FORCE_RTP_MAP
1041 }
1042 #endif
1043
1044 // always include fmtp parameters if available
1045 if (belle_sdp_mime_parameter_get_parameters(mime_parameter)) {
1046 snprintf(atribute_value,MAX_FMTP_LENGTH,"%i %s"
1047 ,belle_sdp_mime_parameter_get_media_format(mime_parameter)
1048 ,belle_sdp_mime_parameter_get_parameters(mime_parameter));
1049 belle_sdp_media_description_set_attribute_value(media_description,"fmtp",atribute_value);
1050 }
1051
1052 if (belle_sdp_mime_parameter_get_ptime(mime_parameter)>current_ptime) {
1053 current_ptime=belle_sdp_mime_parameter_get_ptime(mime_parameter);
1054 }
1055 if (current_ptime>0){
1056 char ptime[10];
1057 snprintf(ptime,sizeof(ptime),"%i",current_ptime);
1058 belle_sdp_media_description_set_attribute_value(media_description,"ptime",ptime);
1059 }
1060
1061 if (belle_sdp_mime_parameter_get_max_ptime(mime_parameter)>current_max_ptime) {
1062 current_max_ptime=belle_sdp_mime_parameter_get_max_ptime(mime_parameter);
1063 }
1064 if (current_max_ptime>0){
1065 char max_ptime[10];
1066 snprintf(max_ptime,sizeof(max_ptime),"%i",current_max_ptime);
1067 belle_sdp_media_description_set_attribute_value(media_description,"maxptime",max_ptime);
1068 }
1069
1070 }
belle_sdp_media_description_get_mime_types(const belle_sdp_media_description_t * media_description)1071 belle_sip_list_t* belle_sdp_media_description_get_mime_types(const belle_sdp_media_description_t* media_description) {
1072 belle_sip_error("belle_sdp_media_description_get_mime_types: not implemented yet");
1073 return NULL;
1074 }
1075
belle_sdp_media_description_remove_attribute(belle_sdp_media_description_t * media_description,const char * name)1076 void belle_sdp_media_description_remove_attribute(belle_sdp_media_description_t* media_description,const char* name) {
1077 belle_sdp_base_description_remove_attribute(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),name);
1078 }
belle_sdp_media_description_remove_bandwidth(belle_sdp_media_description_t * media_description,const char * name)1079 void belle_sdp_media_description_remove_bandwidth(belle_sdp_media_description_t* media_description,const char* name) {
1080 belle_sdp_base_description_remove_bandwidth(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),name);
1081 }
belle_sdp_media_description_set_attribute_value(belle_sdp_media_description_t * media_description,const char * name,const char * value)1082 void belle_sdp_media_description_set_attribute_value(belle_sdp_media_description_t* media_description, const char* name, const char* value) {
1083 belle_sdp_base_description_set_attribute_value(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),name,value);
1084 }
belle_sdp_media_description_set_attributes(belle_sdp_media_description_t * media_description,belle_sip_list_t * value)1085 void belle_sdp_media_description_set_attributes(belle_sdp_media_description_t* media_description, belle_sip_list_t* value) {
1086 belle_sdp_base_description_set_attributes(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),value);
1087 }
1088
belle_sdp_media_description_add_attribute(belle_sdp_media_description_t * media_description,const belle_sdp_attribute_t * attribute)1089 void belle_sdp_media_description_add_attribute(belle_sdp_media_description_t* media_description, const belle_sdp_attribute_t* attribute) {
1090 belle_sdp_base_description_add_attribute(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),attribute);
1091 }
belle_sdp_media_description_set_bandwidth(belle_sdp_media_description_t * media_description,const char * type,int value)1092 void belle_sdp_media_description_set_bandwidth(belle_sdp_media_description_t* media_description, const char* type, int value) {
1093 belle_sdp_base_description_set_bandwidth(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),type,value);
1094 }
belle_sdp_media_description_add_bandwidth(belle_sdp_media_description_t * media_description,const belle_sdp_bandwidth_t * bandwidth)1095 void belle_sdp_media_description_add_bandwidth(belle_sdp_media_description_t* media_description, const belle_sdp_bandwidth_t* bandwidth) {
1096 belle_sdp_base_description_add_bandwidth(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),bandwidth);
1097 }
belle_sdp_media_description_set_bandwidths(belle_sdp_media_description_t * media_description,belle_sip_list_t * bandwidths)1098 void belle_sdp_media_description_set_bandwidths(belle_sdp_media_description_t* media_description, belle_sip_list_t* bandwidths) {
1099 belle_sdp_base_description_set_bandwidths(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),bandwidths);
1100 }
1101 #define SET_OBJECT(object,param,param_type) \
1102 param_type** current = &object->param; \
1103 if (param) belle_sip_object_ref(param); \
1104 if (*current) { \
1105 belle_sip_object_unref(BELLE_SIP_OBJECT(*current)); \
1106 } \
1107 *current=param; \
1108
1109
belle_sdp_media_description_set_connection(belle_sdp_media_description_t * media_description,belle_sdp_connection_t * connection)1110 void belle_sdp_media_description_set_connection(belle_sdp_media_description_t* media_description, belle_sdp_connection_t* connection) {
1111 SET_OBJECT(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),connection,belle_sdp_connection_t)
1112 }
belle_sdp_media_description_set_info(belle_sdp_media_description_t * media_description,belle_sdp_info_t * info)1113 void belle_sdp_media_description_set_info(belle_sdp_media_description_t* media_description,belle_sdp_info_t* info) {
1114 SET_OBJECT(BELLE_SIP_CAST(media_description,belle_sdp_base_description_t),info,belle_sdp_info_t)
1115 }
1116 /*void belle_sdp_media_description_set_key(belle_sdp_media_description_t* media_description,belle_sdp_key_t* key);*/
belle_sdp_media_description_set_media(belle_sdp_media_description_t * media_description,belle_sdp_media_t * media)1117 void belle_sdp_media_description_set_media(belle_sdp_media_description_t* media_description, belle_sdp_media_t* media) {
1118 SET_OBJECT(media_description,media,belle_sdp_media_t)
1119 }
1120
1121 /************************
1122 * origin
1123 ***********************/
1124 struct _belle_sdp_origin {
1125 belle_sip_object_t base;
1126 const char* address;
1127 const char* address_type;
1128 const char* network_type;
1129 const char* username;
1130 unsigned int session_id;
1131 unsigned int session_version;
1132
1133 };
1134
belle_sdp_origin_destroy(belle_sdp_origin_t * origin)1135 void belle_sdp_origin_destroy(belle_sdp_origin_t* origin) {
1136 DESTROY_STRING(origin,address)
1137 DESTROY_STRING(origin,address_type)
1138 DESTROY_STRING(origin,network_type)
1139 DESTROY_STRING(origin,username)
1140 }
1141
belle_sdp_origin_clone(belle_sdp_origin_t * origin,const belle_sdp_origin_t * orig)1142 void belle_sdp_origin_clone(belle_sdp_origin_t *origin, const belle_sdp_origin_t *orig){
1143 CLONE_STRING(belle_sdp_origin,username,origin,orig);
1144 CLONE_STRING(belle_sdp_origin,address,origin,orig);
1145 CLONE_STRING(belle_sdp_origin,address_type,origin,orig);
1146 CLONE_STRING(belle_sdp_origin,network_type,origin,orig);
1147 origin->session_id = orig->session_id;
1148 origin->session_version = orig->session_version;
1149 }
1150
belle_sdp_origin_marshal(belle_sdp_origin_t * origin,char * buff,size_t buff_size,size_t * offset)1151 belle_sip_error_code belle_sdp_origin_marshal(belle_sdp_origin_t* origin, char* buff, size_t buff_size, size_t *offset) {
1152 return belle_sip_snprintf( buff
1153 ,buff_size
1154 ,offset
1155 ,"o=%s %u %u %s %s %s"
1156 ,origin->username
1157 ,origin->session_id
1158 ,origin->session_version
1159 ,origin->network_type
1160 ,origin->address_type
1161 ,origin->address);
1162 }
1163
BELLE_SDP_NEW(origin,belle_sip_object)1164 BELLE_SDP_NEW(origin,belle_sip_object)
1165 belle_sdp_origin_t* belle_sdp_origin_create(const char* user_name
1166 , unsigned int session_id
1167 , unsigned int session_version
1168 , const char* network_type
1169 , const char* addr_type
1170 , const char* address) {
1171 belle_sdp_origin_t* origin=belle_sdp_origin_new();
1172 belle_sdp_origin_set_username(origin,user_name);
1173 belle_sdp_origin_set_session_id(origin,session_id);
1174 belle_sdp_origin_set_session_version(origin,session_version);
1175 belle_sdp_origin_set_network_type(origin,network_type);
1176 belle_sdp_origin_set_address_type(origin,addr_type);
1177 belle_sdp_origin_set_address(origin,address);
1178 return origin;
1179 }
1180 BELLE_SDP_PARSE(origin)
1181 GET_SET_STRING(belle_sdp_origin,username);
1182 GET_SET_STRING(belle_sdp_origin,address);
1183 GET_SET_STRING(belle_sdp_origin,address_type);
1184 GET_SET_STRING(belle_sdp_origin,network_type);
1185 GET_SET_INT(belle_sdp_origin,session_id,unsigned int);
1186 GET_SET_INT(belle_sdp_origin,session_version,unsigned int);
1187 /************************
1188 * session_name
1189 ***********************/
1190 struct _belle_sdp_session_name {
1191 belle_sip_object_t base;
1192 const char* value;
1193 };
1194
belle_sdp_session_name_destroy(belle_sdp_session_name_t * session_name)1195 void belle_sdp_session_name_destroy(belle_sdp_session_name_t* session_name) {
1196 DESTROY_STRING(session_name,value)
1197 }
1198
belle_sdp_session_name_clone(belle_sdp_session_name_t * session_name,const belle_sdp_session_name_t * orig)1199 void belle_sdp_session_name_clone(belle_sdp_session_name_t *session_name, const belle_sdp_session_name_t *orig){
1200 CLONE_STRING(belle_sdp_session_name,value,session_name,orig);
1201 }
1202
belle_sdp_session_name_marshal(belle_sdp_session_name_t * session_name,char * buff,size_t buff_size,size_t * offset)1203 belle_sip_error_code belle_sdp_session_name_marshal(belle_sdp_session_name_t* session_name, char* buff, size_t buff_size, size_t *offset) {
1204 return belle_sip_snprintf(buff,buff_size,offset,"s=%s",session_name->value);
1205 }
1206
BELLE_SDP_NEW(session_name,belle_sip_object)1207 BELLE_SDP_NEW(session_name,belle_sip_object)
1208 belle_sdp_session_name_t* belle_sdp_session_name_create (const char* name) {
1209 belle_sdp_session_name_t* n=belle_sdp_session_name_new();
1210 belle_sdp_session_name_set_value(n,name);
1211 return n;
1212 }
1213 //BELLE_SDP_PARSE(session_name)
1214 GET_SET_STRING(belle_sdp_session_name,value);
1215
1216
1217 /************************
1218 * session_description
1219 ***********************/
1220 struct _belle_sdp_session_description {
1221 belle_sdp_base_description_t base_description;
1222 belle_sdp_version_t* version;
1223 belle_sip_list_t* emails;
1224 belle_sdp_origin_t* origin;
1225 belle_sdp_session_name_t* session_name;
1226 belle_sip_list_t* phones;
1227 belle_sip_list_t* times;
1228 belle_sdp_uri_t* uri;
1229 belle_sdp_uri_t* zone_adjustments;
1230 belle_sip_list_t* media_descriptions;
1231
1232 };
belle_sdp_session_description_destroy(belle_sdp_session_description_t * session_description)1233 void belle_sdp_session_description_destroy(belle_sdp_session_description_t* session_description) {
1234 if (session_description->version) belle_sip_object_unref(BELLE_SIP_OBJECT(session_description->version));
1235 belle_sip_list_free_with_data(session_description->emails,belle_sip_object_freefunc);
1236 if (session_description->origin) belle_sip_object_unref(BELLE_SIP_OBJECT(session_description->origin));
1237 if (session_description->session_name) belle_sip_object_unref(BELLE_SIP_OBJECT(session_description->session_name));
1238 belle_sip_list_free_with_data(session_description->phones,belle_sip_object_freefunc);
1239 belle_sip_list_free_with_data(session_description->times,belle_sip_object_freefunc);
1240 if (session_description->uri) belle_sip_object_unref(BELLE_SIP_OBJECT(session_description->uri));
1241 if (session_description->zone_adjustments) belle_sip_object_unref(BELLE_SIP_OBJECT(session_description->zone_adjustments));
1242 belle_sip_list_free_with_data(session_description->media_descriptions,belle_sip_object_freefunc);
1243 }
1244
belle_sdp_session_description_clone(belle_sdp_session_description_t * session_description,const belle_sdp_session_description_t * orig)1245 void belle_sdp_session_description_clone(belle_sdp_session_description_t *session_description, const belle_sdp_session_description_t *orig){
1246 if (orig->version) session_description->version = BELLE_SDP_VERSION(belle_sip_object_clone_and_ref(BELLE_SIP_OBJECT(orig->version)));
1247 session_description->emails = belle_sip_list_copy_with_data(orig->emails,belle_sip_object_copyfunc);
1248 if (orig->origin) session_description->origin = BELLE_SDP_ORIGIN(belle_sip_object_clone_and_ref(BELLE_SIP_OBJECT(orig->origin)));
1249 if (orig->session_name) session_description->session_name = BELLE_SDP_SESSION_NAME(belle_sip_object_clone_and_ref(BELLE_SIP_OBJECT(orig->session_name)));
1250 session_description->phones = belle_sip_list_copy_with_data(orig->phones,belle_sip_object_copyfunc);
1251 session_description->times = belle_sip_list_copy_with_data(orig->times,belle_sip_object_copyfunc);
1252 if (orig->uri) session_description->uri = BELLE_SDP_URI(belle_sip_object_clone_and_ref(BELLE_SIP_OBJECT(orig->uri)));
1253 if (orig->zone_adjustments) session_description->zone_adjustments = BELLE_SDP_URI(belle_sip_object_clone_and_ref(BELLE_SIP_OBJECT(orig->zone_adjustments)));
1254 session_description->media_descriptions = belle_sip_list_copy_with_data(orig->media_descriptions,belle_sip_object_copyfunc);
1255 }
1256
belle_sdp_session_description_marshal(belle_sdp_session_description_t * session_description,char * buff,size_t buff_size,size_t * offset)1257 belle_sip_error_code belle_sdp_session_description_marshal(belle_sdp_session_description_t* session_description, char* buff, size_t buff_size, size_t *offset) {
1258 /*session_description: proto_version CR LF
1259 origin_field
1260 session_name_field
1261 (info CR LF)?
1262 uri_field?
1263 (email CR LF)*
1264 phone_field*
1265 (connection CR LF)?
1266 (bandwidth CR LF)*
1267 time_field
1268 (repeat_time CR LF)?
1269 (zone_adjustments CR LF)?
1270 (key_field CR LF)?
1271 (attribute CR LF)*
1272 media_descriptions;
1273 */
1274 belle_sip_error_code error=BELLE_SIP_OK;
1275 belle_sip_list_t* media_descriptions;
1276 belle_sip_list_t* times;
1277 belle_sip_list_t* attributes;
1278
1279 if (session_description->version) {
1280 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(session_description->version),buff,buff_size,offset);
1281 if (error!=BELLE_SIP_OK) return error;
1282 error=belle_sip_snprintf(buff, buff_size, offset, "\r\n");
1283 if (error!=BELLE_SIP_OK) return error;
1284 }
1285
1286 if (session_description->origin) {
1287 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(session_description->origin),buff,buff_size,offset);
1288 if (error!=BELLE_SIP_OK) return error;
1289 error=belle_sip_snprintf(buff, buff_size, offset, "\r\n");
1290 if (error!=BELLE_SIP_OK) return error;
1291 }
1292
1293 if (session_description->session_name) {
1294 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(session_description->session_name),buff,buff_size,offset);
1295 if (error!=BELLE_SIP_OK) return error;
1296 error=belle_sip_snprintf(buff, buff_size, offset, "\r\n");
1297 if (error!=BELLE_SIP_OK) return error;
1298 }
1299
1300 error=belle_sdp_base_description_marshal((belle_sdp_base_description_t*)(&session_description->base_description),buff,buff_size, offset);
1301 if (error!=BELLE_SIP_OK) return error;
1302
1303 error=belle_sip_snprintf(buff, buff_size, offset, "t=");
1304 if (error!=BELLE_SIP_OK) return error;
1305 for(times=session_description->times;times!=NULL;times=times->next){
1306 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(times->data),buff,buff_size,offset);
1307 if (error!=BELLE_SIP_OK) return error;
1308 error=belle_sip_snprintf(buff, buff_size, offset, "\r\n");
1309 if (error!=BELLE_SIP_OK) return error;
1310 }
1311
1312 for(attributes=session_description->base_description.attributes;attributes!=NULL;attributes=attributes->next){
1313 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(attributes->data),buff,buff_size,offset);
1314 if (error!=BELLE_SIP_OK) return error;
1315 error=belle_sip_snprintf(buff, buff_size, offset, "\r\n");
1316 if (error!=BELLE_SIP_OK) return error;
1317 }
1318
1319 for(media_descriptions=session_description->media_descriptions;media_descriptions!=NULL;media_descriptions=media_descriptions->next){
1320 error=belle_sip_object_marshal(BELLE_SIP_OBJECT(media_descriptions->data),buff,buff_size,offset);
1321 if (error!=BELLE_SIP_OK) return error;
1322 }
1323 return error;
1324 }
1325
BELLE_SDP_NEW(session_description,belle_sdp_base_description)1326 BELLE_SDP_NEW(session_description,belle_sdp_base_description)
1327 BELLE_SDP_PARSE(session_description)
1328
1329
1330 belle_sip_list_t * belle_sdp_session_description_get_attributes(const belle_sdp_session_description_t *session_description) {
1331 return belle_sdp_base_description_get_attributes(BELLE_SIP_CAST(session_description, belle_sdp_base_description_t));
1332 }
1333
belle_sdp_session_description_get_attribute_value(const belle_sdp_session_description_t * session_description,const char * name)1334 const char* belle_sdp_session_description_get_attribute_value(const belle_sdp_session_description_t* session_description, const char* name) {
1335 return belle_sdp_base_description_get_attribute_value(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),name);
1336 }
belle_sdp_session_description_get_attribute(const belle_sdp_session_description_t * session_description,const char * name)1337 const belle_sdp_attribute_t* belle_sdp_session_description_get_attribute(const belle_sdp_session_description_t* session_description, const char* name) {
1338 return belle_sdp_base_description_get_attribute(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),name);
1339 }
belle_sdp_session_description_get_bandwidth(const belle_sdp_session_description_t * session_description,const char * name)1340 int belle_sdp_session_description_get_bandwidth(const belle_sdp_session_description_t* session_description, const char* name) {
1341 return belle_sdp_base_description_get_bandwidth_value(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),name);
1342 }
belle_sdp_session_description_get_bandwidths(const belle_sdp_session_description_t * session_description)1343 belle_sip_list_t* belle_sdp_session_description_get_bandwidths(const belle_sdp_session_description_t* session_description) {
1344 return BELLE_SIP_CAST(session_description,belle_sdp_base_description_t)->bandwidths;
1345 }
belle_sdp_session_description_get_connection(const belle_sdp_session_description_t * session_description)1346 belle_sdp_connection_t* belle_sdp_session_description_get_connection(const belle_sdp_session_description_t* session_description) {
1347 return BELLE_SIP_CAST(session_description,belle_sdp_base_description_t)->connection;
1348 }
belle_sdp_session_description_get_emails(const belle_sdp_session_description_t * session_description)1349 belle_sip_list_t* belle_sdp_session_description_get_emails(const belle_sdp_session_description_t* session_description){
1350 return session_description->emails;
1351 }
belle_sdp_session_description_get_info(const belle_sdp_session_description_t * session_description)1352 belle_sdp_info_t* belle_sdp_session_description_get_info(const belle_sdp_session_description_t* session_description) {
1353 return BELLE_SIP_CAST(session_description,belle_sdp_base_description_t)->info;
1354 }
1355 /*belle_sdp_key_t* belle_sdp_session_description_get_key(const belle_sdp_session_description_t* session_description);*/
belle_sdp_session_description_get_media_descriptions(const belle_sdp_session_description_t * session_description)1356 belle_sip_list_t* belle_sdp_session_description_get_media_descriptions(const belle_sdp_session_description_t* session_description) {
1357 return session_description->media_descriptions;
1358 }
belle_sdp_session_description_get_origin(const belle_sdp_session_description_t * session_description)1359 belle_sdp_origin_t* belle_sdp_session_description_get_origin(const belle_sdp_session_description_t* session_description){
1360 return session_description->origin;
1361 }
belle_sdp_session_description_get_phones(const belle_sdp_session_description_t * session_description)1362 belle_sip_list_t* belle_sdp_session_description_get_phones(const belle_sdp_session_description_t* session_description) {
1363 return session_description->phones;
1364 }
belle_sdp_session_description_get_session_name(const belle_sdp_session_description_t * session_description)1365 belle_sdp_session_name_t* belle_sdp_session_description_get_session_name(const belle_sdp_session_description_t* session_description) {
1366 return session_description->session_name;
1367 }
belle_sdp_session_description_get_time_descriptions(const belle_sdp_session_description_t * session_description)1368 belle_sip_list_t* belle_sdp_session_description_get_time_descriptions(const belle_sdp_session_description_t* session_description) {
1369 return session_description->times;
1370 }
belle_sdp_session_description_get_uri(const belle_sdp_session_description_t * session_description)1371 belle_sdp_uri_t* belle_sdp_session_description_get_uri(const belle_sdp_session_description_t* session_description) {
1372 return session_description->uri;
1373 }
belle_sdp_session_description_get_version(const belle_sdp_session_description_t * session_description)1374 belle_sdp_version_t* belle_sdp_session_description_get_version(const belle_sdp_session_description_t* session_description) {
1375 return session_description->version;
1376 }
belle_sdp_session_description_get_zone_adjustments(const belle_sdp_session_description_t * session_description)1377 belle_sdp_uri_t* belle_sdp_session_description_get_zone_adjustments(const belle_sdp_session_description_t* session_description) {
1378 return session_description->zone_adjustments;
1379 }
belle_sdp_session_description_remove_attribute(belle_sdp_session_description_t * session_description,const char * name)1380 void belle_sdp_session_description_remove_attribute(belle_sdp_session_description_t* session_description, const char* name) {
1381 belle_sdp_base_description_remove_attribute(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),name);
1382 }
belle_sdp_session_description_remove_bandwidth(belle_sdp_session_description_t * session_description,const char * name)1383 void belle_sdp_session_description_remove_bandwidth(belle_sdp_session_description_t* session_description, const char* name) {
1384 belle_sdp_base_description_remove_bandwidth(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),name);
1385 }
belle_sdp_session_description_set_attribute_value(belle_sdp_session_description_t * session_description,const char * name,const char * value)1386 void belle_sdp_session_description_set_attribute_value(belle_sdp_session_description_t* session_description, const char* name, const char* value) {
1387 belle_sdp_base_description_set_attribute_value(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),name,value);
1388 }
belle_sdp_session_description_set_attributes(belle_sdp_session_description_t * session_description,belle_sip_list_t * attributes)1389 void belle_sdp_session_description_set_attributes(belle_sdp_session_description_t* session_description, belle_sip_list_t* attributes) {
1390 belle_sdp_base_description_set_attributes(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),attributes);
1391 }
belle_sdp_session_description_add_attribute(belle_sdp_session_description_t * session_description,const belle_sdp_attribute_t * attribute)1392 void belle_sdp_session_description_add_attribute(belle_sdp_session_description_t* session_description, const belle_sdp_attribute_t* attribute) {
1393 belle_sdp_base_description_add_attribute(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),attribute);
1394 }
belle_sdp_session_description_set_bandwidth(belle_sdp_session_description_t * session_description,const char * type,int value)1395 void belle_sdp_session_description_set_bandwidth(belle_sdp_session_description_t* session_description, const char* type, int value) {
1396 belle_sdp_base_description_set_bandwidth(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),type,value);
1397 }
belle_sdp_session_description_set_bandwidths(belle_sdp_session_description_t * session_description,belle_sip_list_t * bandwidths)1398 void belle_sdp_session_description_set_bandwidths(belle_sdp_session_description_t* session_description, belle_sip_list_t* bandwidths) {
1399 belle_sdp_base_description_set_bandwidths(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),bandwidths);
1400 }
belle_sdp_session_description_add_bandwidth(belle_sdp_session_description_t * session_description,const belle_sdp_bandwidth_t * bandwidth)1401 void belle_sdp_session_description_add_bandwidth(belle_sdp_session_description_t* session_description, const belle_sdp_bandwidth_t* bandwidth) {
1402 belle_sdp_base_description_add_bandwidth(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),bandwidth);
1403 }
belle_sdp_session_description_set_connection(belle_sdp_session_description_t * session_description,belle_sdp_connection_t * connection)1404 void belle_sdp_session_description_set_connection(belle_sdp_session_description_t* session_description, belle_sdp_connection_t* connection) {
1405 SET_OBJECT(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),connection,belle_sdp_connection_t)
1406 }
belle_sdp_session_description_set_emails(belle_sdp_session_description_t * session_description,belle_sip_list_t * emails)1407 void belle_sdp_session_description_set_emails(belle_sdp_session_description_t* session_description, belle_sip_list_t* emails) {
1408 SET_LIST(session_description->emails,emails)
1409 }
belle_sdp_session_description_set_info(belle_sdp_session_description_t * session_description,belle_sdp_info_t * info)1410 void belle_sdp_session_description_set_info(belle_sdp_session_description_t* session_description, belle_sdp_info_t* info) {
1411 SET_OBJECT(BELLE_SIP_CAST(session_description,belle_sdp_base_description_t),info,belle_sdp_info_t)
1412 }
1413 /*void belle_sdp_session_description_set_key(belle_sdp_session_description_t* session_description, belle_sdp_key_t* key);*/
belle_sdp_session_description_set_media_descriptions(belle_sdp_session_description_t * session_description,belle_sip_list_t * media_descriptions)1414 void belle_sdp_session_description_set_media_descriptions(belle_sdp_session_description_t* session_description, belle_sip_list_t* media_descriptions) {
1415 SET_LIST(session_description->media_descriptions,media_descriptions)
1416 }
belle_sdp_session_description_add_media_description(belle_sdp_session_description_t * session_description,belle_sdp_media_description_t * media_description)1417 void belle_sdp_session_description_add_media_description(belle_sdp_session_description_t* session_description, belle_sdp_media_description_t* media_description) {
1418 session_description->media_descriptions = belle_sip_list_append(session_description->media_descriptions,belle_sip_object_ref(media_description));
1419 }
1420
belle_sdp_session_description_set_origin(belle_sdp_session_description_t * session_description,belle_sdp_origin_t * origin)1421 void belle_sdp_session_description_set_origin(belle_sdp_session_description_t* session_description, belle_sdp_origin_t* origin) {
1422 SET_OBJECT(session_description,origin,belle_sdp_origin_t)
1423 }
belle_sdp_session_description_set_phones(belle_sdp_session_description_t * session_description,belle_sip_list_t * phones)1424 void belle_sdp_session_description_set_phones(belle_sdp_session_description_t* session_description, belle_sip_list_t* phones) {
1425 SET_LIST(session_description->phones,phones)
1426 }
belle_sdp_session_description_set_session_name(belle_sdp_session_description_t * session_description,belle_sdp_session_name_t * session_name)1427 void belle_sdp_session_description_set_session_name(belle_sdp_session_description_t* session_description, belle_sdp_session_name_t* session_name) {
1428 SET_OBJECT(session_description,session_name,belle_sdp_session_name_t)
1429 }
belle_sdp_session_description_set_time_descriptions(belle_sdp_session_description_t * session_description,belle_sip_list_t * times)1430 void belle_sdp_session_description_set_time_descriptions(belle_sdp_session_description_t* session_description, belle_sip_list_t* times) {
1431 SET_LIST(session_description->times,times)
1432 }
belle_sdp_session_description_set_time_description(belle_sdp_session_description_t * session_description,belle_sdp_time_description_t * time_desc)1433 void belle_sdp_session_description_set_time_description(belle_sdp_session_description_t* session_description, belle_sdp_time_description_t* time_desc) {
1434 belle_sdp_session_description_set_time_descriptions(session_description,belle_sip_list_new(time_desc));
1435 }
belle_sdp_session_description_set_uri(belle_sdp_session_description_t * session_description,belle_sdp_uri_t * uri)1436 void belle_sdp_session_description_set_uri(belle_sdp_session_description_t* session_description, belle_sdp_uri_t* uri) {
1437 SET_OBJECT(session_description,uri,belle_sdp_uri_t)
1438 }
belle_sdp_session_description_set_version(belle_sdp_session_description_t * session_description,belle_sdp_version_t * version)1439 void belle_sdp_session_description_set_version(belle_sdp_session_description_t* session_description, belle_sdp_version_t* version) {
1440 SET_OBJECT(session_description,version,belle_sdp_version_t)
1441 }
belle_sdp_session_description_set_zone_adjustments(belle_sdp_session_description_t * session_description,belle_sdp_uri_t * zone_adjustments)1442 void belle_sdp_session_description_set_zone_adjustments(belle_sdp_session_description_t* session_description, belle_sdp_uri_t* zone_adjustments) {
1443 SET_OBJECT(session_description,zone_adjustments,belle_sdp_uri_t)
1444 }
1445 /************************
1446 * time
1447 ***********************/
1448 struct _belle_sdp_time {
1449 belle_sip_object_t base;
1450 int start;
1451 int stop;
1452 };
1453
belle_sdp_time_destroy(belle_sdp_time_t * time)1454 void belle_sdp_time_destroy(belle_sdp_time_t* time) {
1455
1456 }
1457
belle_sdp_time_clone(belle_sdp_time_t * time,const belle_sdp_time_t * orig)1458 void belle_sdp_time_clone(belle_sdp_time_t *time, const belle_sdp_time_t *orig){
1459 time->start=orig->start;
1460 time->stop=orig->stop;
1461 }
1462
belle_sdp_time_marshal(belle_sdp_time_t * time,char * buff,size_t buff_size,size_t * offset)1463 belle_sip_error_code belle_sdp_time_marshal(belle_sdp_time_t* time, char* buff, size_t buff_size, size_t *offset) {
1464 return belle_sip_snprintf(buff,buff_size,offset,"%i %i",time->start,time->stop);
1465 }
1466
1467 BELLE_SDP_NEW(time,belle_sip_object)
1468 //BELLE_SDP_PARSE(version)
1469 GET_SET_INT(belle_sdp_time,start,int);
1470 GET_SET_INT(belle_sdp_time,stop,int);
1471
1472 /************************
1473 * time description
1474 ***********************/
1475 struct _belle_sdp_time_description {
1476 belle_sip_object_t base;
1477 belle_sdp_time_t* time;
1478
1479 };
1480
belle_sdp_time_description_destroy(belle_sdp_time_description_t * time_description)1481 void belle_sdp_time_description_destroy(belle_sdp_time_description_t* time_description) {
1482 if (time_description->time) belle_sip_object_unref(BELLE_SIP_OBJECT(time_description->time));
1483 }
1484
belle_sdp_time_description_clone(belle_sdp_time_description_t * time_description,const belle_sdp_time_description_t * orig)1485 void belle_sdp_time_description_clone(belle_sdp_time_description_t *time_description, const belle_sdp_time_description_t *orig){
1486 if (orig->time) time_description->time = BELLE_SDP_TIME(belle_sip_object_clone_and_ref(BELLE_SIP_OBJECT(orig->time)));
1487 }
1488
belle_sdp_time_description_marshal(belle_sdp_time_description_t * time_description,char * buff,size_t buff_size,size_t * offset)1489 belle_sip_error_code belle_sdp_time_description_marshal(belle_sdp_time_description_t* time_description, char* buff, size_t buff_size, size_t *offset) {
1490 return belle_sip_object_marshal(BELLE_SIP_OBJECT(time_description->time),buff,buff_size,offset);
1491 }
1492
BELLE_SDP_NEW(time_description,belle_sip_object)1493 BELLE_SDP_NEW(time_description,belle_sip_object)
1494
1495 belle_sdp_time_description_t* belle_sdp_time_description_create (int start,int stop) {
1496 belle_sdp_time_description_t* time_desc= belle_sdp_time_description_new();
1497 belle_sdp_time_t* time = belle_sdp_time_new();
1498 belle_sdp_time_set_start(time,start);
1499 belle_sdp_time_set_stop(time,stop);
1500 belle_sdp_time_description_set_time(time_desc,time);
1501 return time_desc;
1502 }
belle_sdp_time_description_get_repeate_times(const belle_sdp_time_description_t * time_description)1503 belle_sip_list_t* belle_sdp_time_description_get_repeate_times(const belle_sdp_time_description_t* time_description) {
1504 return NULL;
1505 }
belle_sdp_time_description_get_time(const belle_sdp_time_description_t * time_description)1506 belle_sdp_time_t* belle_sdp_time_description_get_time(const belle_sdp_time_description_t* time_description) {
1507 return time_description->time;
1508 }
belle_sdp_time_description_set_repeate_times(belle_sdp_time_description_t * time_description,belle_sip_list_t * times)1509 void belle_sdp_time_description_set_repeate_times(belle_sdp_time_description_t* time_description, belle_sip_list_t* times) {
1510 belle_sip_error("time description repeat time not implemented");
1511 }
belle_sdp_time_description_set_time(belle_sdp_time_description_t * time_description,belle_sdp_time_t * time)1512 void belle_sdp_time_description_set_time(belle_sdp_time_description_t* time_description, belle_sdp_time_t* time) {
1513 SET_OBJECT(time_description,time,belle_sdp_time_t)
1514 }
1515
1516 /************************
1517 * version
1518 ***********************/
1519 struct _belle_sdp_version {
1520 belle_sip_object_t base;
1521 int version;
1522 };
1523
belle_sdp_version_destroy(belle_sdp_version_t * version)1524 void belle_sdp_version_destroy(belle_sdp_version_t* version) {
1525
1526 }
1527
belle_sdp_version_clone(belle_sdp_version_t * version,const belle_sdp_version_t * orig)1528 void belle_sdp_version_clone(belle_sdp_version_t *version, const belle_sdp_version_t *orig){
1529 version->version = orig->version;
1530 }
1531
belle_sdp_version_marshal(belle_sdp_version_t * version,char * buff,size_t buff_size,size_t * offset)1532 belle_sip_error_code belle_sdp_version_marshal(belle_sdp_version_t* version, char* buff, size_t buff_size, size_t *offset) {
1533 return belle_sip_snprintf(buff,buff_size,offset,"v=%i",version->version);
1534 }
1535
BELLE_SDP_NEW(version,belle_sip_object)1536 BELLE_SDP_NEW(version,belle_sip_object)
1537 belle_sdp_version_t* belle_sdp_version_create(int version) {
1538 belle_sdp_version_t* v = belle_sdp_version_new();
1539 belle_sdp_version_set_version(v,version);
1540 return v;
1541 }
1542 //BELLE_SDP_PARSE(version)
1543 GET_SET_INT(belle_sdp_version,version,int);
1544
1545 /***************************************************************************************
1546 * mime_parameter
1547 *
1548 **************************************************************************************/
1549
belle_sdp_mime_parameter_destroy(belle_sdp_mime_parameter_t * mime_parameter)1550 static void belle_sdp_mime_parameter_destroy(belle_sdp_mime_parameter_t *mime_parameter) {
1551 if (mime_parameter->type) belle_sip_free((void*)mime_parameter->type);
1552 if (mime_parameter->parameters) belle_sip_free((void*)mime_parameter->parameters);
1553 }
belle_sdp_mime_parameter_clone(belle_sdp_mime_parameter_t * mime_parameter,belle_sdp_mime_parameter_t * orig)1554 static void belle_sdp_mime_parameter_clone(belle_sdp_mime_parameter_t *mime_parameter,belle_sdp_mime_parameter_t *orig) {
1555 mime_parameter->rate = orig->rate;
1556 mime_parameter->channel_count = orig->channel_count;
1557 mime_parameter->ptime = orig->ptime;
1558 mime_parameter->max_ptime = orig->max_ptime;
1559 mime_parameter->media_format = orig->media_format;
1560 CLONE_STRING(belle_sdp_mime_parameter,type,mime_parameter,orig);
1561 CLONE_STRING(belle_sdp_mime_parameter,parameters,mime_parameter,orig);
1562 }
1563 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sdp_mime_parameter_t);
1564 BELLE_SIP_INSTANCIATE_VPTR(belle_sdp_mime_parameter_t
1565 ,belle_sip_object_t
1566 ,belle_sdp_mime_parameter_destroy
1567 ,belle_sdp_mime_parameter_clone
1568 ,NULL
1569 ,TRUE);
1570
belle_sdp_mime_parameter_new()1571 belle_sdp_mime_parameter_t* belle_sdp_mime_parameter_new() {
1572 belle_sdp_mime_parameter_t* l_param = belle_sip_object_new(belle_sdp_mime_parameter_t);
1573 l_param->ptime = -1;
1574 l_param->max_ptime = -1;
1575 return l_param;
1576 }
belle_sdp_mime_parameter_create(const char * type,int media_format,int rate,int channel_count)1577 belle_sdp_mime_parameter_t* belle_sdp_mime_parameter_create(const char* type, int media_format, int rate,int channel_count) {
1578 belle_sdp_mime_parameter_t* mime_param= belle_sdp_mime_parameter_new();
1579 belle_sdp_mime_parameter_set_type(mime_param,type);
1580 belle_sdp_mime_parameter_set_media_format(mime_param,media_format);
1581 belle_sdp_mime_parameter_set_rate(mime_param,rate);
1582 belle_sdp_mime_parameter_set_channel_count(mime_param,channel_count);
1583 return mime_param;
1584 }
1585 GET_SET_INT(belle_sdp_mime_parameter,rate,int);
1586 GET_SET_INT(belle_sdp_mime_parameter,channel_count,int);
1587 GET_SET_INT(belle_sdp_mime_parameter,ptime,int);
1588 GET_SET_INT(belle_sdp_mime_parameter,max_ptime,int);
1589 GET_SET_INT(belle_sdp_mime_parameter,media_format,int);
1590 GET_SET_STRING(belle_sdp_mime_parameter,type);
1591 GET_SET_STRING(belle_sdp_mime_parameter,parameters);
1592
1593