1 /*
2 The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
3 Copyright (C) 2001-2020 Aymeric MOIZARD amoizard@antisip.com
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include <osipparser2/internal.h>
21
22 #include <osipparser2/osip_const.h>
23 #include <osipparser2/sdp_message.h>
24 #include <osipparser2/osip_message.h>
25 #include <osipparser2/osip_port.h>
26
27 #define ERR_ERROR -1 /* bad header */
28 #define ERR_DISCARD 0 /* wrong header */
29 #define OSIP_WF 1 /* well formed header */
30
31 static int sdp_message_parse_v(sdp_message_t *sdp, char *buf, char **next);
32 static int sdp_message_parse_o(sdp_message_t *sdp, char *buf, char **next);
33 static int sdp_message_parse_s(sdp_message_t *sdp, char *buf, char **next);
34 static int sdp_message_parse_i(sdp_message_t *sdp, char *buf, char **next);
35 static int sdp_message_parse_u(sdp_message_t *sdp, char *buf, char **next);
36 static int sdp_message_parse_e(sdp_message_t *sdp, char *buf, char **next);
37 static int sdp_message_parse_p(sdp_message_t *sdp, char *buf, char **next);
38 static int sdp_message_parse_c(sdp_message_t *sdp, char *buf, char **next);
39 static int sdp_message_parse_b(sdp_message_t *sdp, char *buf, char **next);
40 static int sdp_message_parse_t(sdp_message_t *sdp, char *buf, char **next);
41 static int sdp_message_parse_r(sdp_message_t *sdp, char *buf, char **next);
42 static int sdp_message_parse_z(sdp_message_t *sdp, char *buf, char **next);
43 static int sdp_message_parse_k(sdp_message_t *sdp, char *buf, char **next);
44 static int sdp_message_parse_a(sdp_message_t *sdp, char *buf, char **next);
45 static int sdp_message_parse_m(sdp_message_t *sdp, char *buf, char **next);
46
47 static int sdp_append_media(char **string, int *size, char *tmp, sdp_media_t *media, char **next_tmp);
48 static int sdp_append_attribute(char **string, int *size, char *tmp, sdp_attribute_t *attribute, char **next_tmp);
49 static int sdp_append_key(char **string, int *size, char *tmp, sdp_key_t *key, char **next_tmp);
50 static int sdp_append_time_descr(char **string, int *size, char *tmp, sdp_time_descr_t *time_descr, char **next_tmp);
51 static int sdp_append_bandwidth(char **string, int *size, char *tmp, sdp_bandwidth_t *bandwidth, char **next_tmp);
52 static int sdp_append_connection(char **string, int *size, char *tmp, sdp_connection_t *conn, char **next_tmp);
53
54 static char *__osip_sdp_append_string(char **string, int *size, char *cur, char *string_osip_to_append);
55
sdp_bandwidth_init(sdp_bandwidth_t ** b)56 int sdp_bandwidth_init(sdp_bandwidth_t **b) {
57 *b = (sdp_bandwidth_t *) osip_malloc(sizeof(sdp_bandwidth_t));
58
59 if (*b == NULL)
60 return OSIP_NOMEM;
61
62 (*b)->b_bwtype = NULL;
63 (*b)->b_bandwidth = NULL;
64 return OSIP_SUCCESS;
65 }
66
sdp_bandwidth_free(sdp_bandwidth_t * b)67 void sdp_bandwidth_free(sdp_bandwidth_t *b) {
68 if (b == NULL)
69 return;
70
71 osip_free(b->b_bwtype);
72 osip_free(b->b_bandwidth);
73 osip_free(b);
74 }
75
sdp_time_descr_init(sdp_time_descr_t ** td)76 int sdp_time_descr_init(sdp_time_descr_t **td) {
77 *td = (sdp_time_descr_t *) osip_malloc(sizeof(sdp_time_descr_t));
78
79 if (*td == NULL)
80 return OSIP_NOMEM;
81
82 (*td)->t_start_time = NULL;
83 (*td)->t_stop_time = NULL;
84 osip_list_init(&(*td)->r_repeats);
85 return OSIP_SUCCESS;
86 }
87
sdp_time_descr_free(sdp_time_descr_t * td)88 void sdp_time_descr_free(sdp_time_descr_t *td) {
89 if (td == NULL)
90 return;
91
92 osip_free(td->t_start_time);
93 osip_free(td->t_stop_time);
94 osip_list_ofchar_free(&td->r_repeats);
95 osip_free(td);
96 }
97
sdp_key_init(sdp_key_t ** key)98 int sdp_key_init(sdp_key_t **key) {
99 *key = (sdp_key_t *) osip_malloc(sizeof(sdp_key_t));
100
101 if (*key == NULL)
102 return OSIP_NOMEM;
103
104 (*key)->k_keytype = NULL;
105 (*key)->k_keydata = NULL;
106 return OSIP_SUCCESS;
107 }
108
sdp_key_free(sdp_key_t * key)109 void sdp_key_free(sdp_key_t *key) {
110 if (key == NULL)
111 return;
112
113 osip_free(key->k_keytype);
114 osip_free(key->k_keydata);
115 osip_free(key);
116 }
117
sdp_attribute_init(sdp_attribute_t ** attribute)118 int sdp_attribute_init(sdp_attribute_t **attribute) {
119 *attribute = (sdp_attribute_t *) osip_malloc(sizeof(sdp_attribute_t));
120
121 if (*attribute == NULL)
122 return OSIP_NOMEM;
123
124 (*attribute)->a_att_field = NULL;
125 (*attribute)->a_att_value = NULL;
126 return OSIP_SUCCESS;
127 }
128
sdp_attribute_free(sdp_attribute_t * attribute)129 void sdp_attribute_free(sdp_attribute_t *attribute) {
130 if (attribute == NULL)
131 return;
132
133 osip_free(attribute->a_att_field);
134 osip_free(attribute->a_att_value);
135 osip_free(attribute);
136 }
137
sdp_connection_init(sdp_connection_t ** connection)138 int sdp_connection_init(sdp_connection_t **connection) {
139 *connection = (sdp_connection_t *) osip_malloc(sizeof(sdp_connection_t));
140
141 if (*connection == NULL)
142 return OSIP_NOMEM;
143
144 (*connection)->c_nettype = NULL;
145 (*connection)->c_addrtype = NULL;
146 (*connection)->c_addr = NULL;
147 (*connection)->c_addr_multicast_ttl = NULL;
148 (*connection)->c_addr_multicast_int = NULL;
149 return OSIP_SUCCESS;
150 }
151
sdp_connection_free(sdp_connection_t * connection)152 void sdp_connection_free(sdp_connection_t *connection) {
153 if (connection == NULL)
154 return;
155
156 osip_free(connection->c_nettype);
157 osip_free(connection->c_addrtype);
158 osip_free(connection->c_addr);
159 osip_free(connection->c_addr_multicast_ttl);
160 osip_free(connection->c_addr_multicast_int);
161 osip_free(connection);
162 }
163
sdp_media_init(sdp_media_t ** media)164 int sdp_media_init(sdp_media_t **media) {
165 int i;
166
167 *media = (sdp_media_t *) osip_malloc(sizeof(sdp_media_t));
168
169 if (*media == NULL)
170 return OSIP_NOMEM;
171
172 (*media)->m_media = NULL;
173 (*media)->m_port = NULL;
174 (*media)->m_number_of_port = NULL;
175 (*media)->m_proto = NULL;
176 i = osip_list_init(&(*media)->m_payloads);
177
178 if (i != 0) {
179 osip_free(*media);
180 *media = NULL;
181 return OSIP_NOMEM;
182 }
183
184 (*media)->i_info = NULL;
185 i = osip_list_init(&(*media)->c_connections);
186
187 if (i != 0) {
188 osip_list_ofchar_free(&(*media)->m_payloads);
189 osip_free(*media);
190 *media = NULL;
191 return OSIP_NOMEM;
192 }
193
194 i = osip_list_init(&(*media)->b_bandwidths);
195
196 if (i != 0) {
197 osip_list_ofchar_free(&(*media)->m_payloads);
198 osip_list_special_free(&(*media)->c_connections, (void (*)(void *)) & sdp_connection_free);
199 osip_free(*media);
200 *media = NULL;
201 return OSIP_NOMEM;
202 }
203
204 i = osip_list_init(&(*media)->a_attributes);
205
206 if (i != 0) {
207 osip_list_ofchar_free(&(*media)->m_payloads);
208 osip_list_special_free(&(*media)->c_connections, (void (*)(void *)) & sdp_connection_free);
209 osip_list_special_free(&(*media)->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
210 osip_free(*media);
211 *media = NULL;
212 return OSIP_NOMEM;
213 }
214
215 (*media)->k_key = NULL;
216 return OSIP_SUCCESS;
217 }
218
sdp_media_free(sdp_media_t * media)219 void sdp_media_free(sdp_media_t *media) {
220 if (media == NULL)
221 return;
222
223 osip_free(media->m_media);
224 osip_free(media->m_port);
225 osip_free(media->m_number_of_port);
226 osip_free(media->m_proto);
227 osip_list_ofchar_free(&media->m_payloads);
228 osip_free(media->i_info);
229 osip_list_special_free(&media->c_connections, (void (*)(void *)) & sdp_connection_free);
230 osip_list_special_free(&media->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
231 osip_list_special_free(&media->a_attributes, (void (*)(void *)) & sdp_attribute_free);
232 sdp_key_free(media->k_key);
233 osip_free(media);
234 }
235
236 /* to be changed to sdp_message_init(sdp_message_t **dest) */
sdp_message_init(sdp_message_t ** sdp)237 int sdp_message_init(sdp_message_t **sdp) {
238 int i;
239
240 (*sdp) = (sdp_message_t *) osip_malloc(sizeof(sdp_message_t));
241
242 if (*sdp == NULL)
243 return OSIP_NOMEM;
244
245 (*sdp)->v_version = NULL;
246 (*sdp)->o_username = NULL;
247 (*sdp)->o_sess_id = NULL;
248 (*sdp)->o_sess_version = NULL;
249 (*sdp)->o_nettype = NULL;
250 (*sdp)->o_addrtype = NULL;
251 (*sdp)->o_addr = NULL;
252 (*sdp)->s_name = NULL;
253 (*sdp)->i_info = NULL;
254 (*sdp)->u_uri = NULL;
255
256 i = osip_list_init(&(*sdp)->e_emails);
257
258 if (i != 0) {
259 osip_list_ofchar_free(&(*sdp)->e_emails);
260 osip_free(*sdp);
261 *sdp = NULL;
262 return OSIP_NOMEM;
263 }
264
265 i = osip_list_init(&(*sdp)->p_phones);
266
267 if (i != 0) {
268 osip_list_ofchar_free(&(*sdp)->e_emails);
269 osip_free(*sdp);
270 *sdp = NULL;
271 return OSIP_NOMEM;
272 }
273
274 (*sdp)->c_connection = NULL;
275
276 i = osip_list_init(&(*sdp)->b_bandwidths);
277
278 if (i != 0) {
279 osip_list_ofchar_free(&(*sdp)->e_emails);
280 osip_list_ofchar_free(&(*sdp)->p_phones);
281 osip_free(*sdp);
282 *sdp = NULL;
283 return OSIP_NOMEM;
284 }
285
286 i = osip_list_init(&(*sdp)->t_descrs);
287
288 if (i != 0) {
289 osip_list_ofchar_free(&(*sdp)->e_emails);
290 osip_list_ofchar_free(&(*sdp)->p_phones);
291 osip_list_special_free(&(*sdp)->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
292 osip_free(*sdp);
293 *sdp = NULL;
294 return OSIP_NOMEM;
295 }
296
297 (*sdp)->z_adjustments = NULL;
298 (*sdp)->k_key = NULL;
299
300 i = osip_list_init(&(*sdp)->a_attributes);
301
302 if (i != 0) {
303 osip_list_ofchar_free(&(*sdp)->e_emails);
304 osip_list_ofchar_free(&(*sdp)->p_phones);
305 osip_list_special_free(&(*sdp)->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
306 osip_list_special_free(&(*sdp)->t_descrs, (void (*)(void *)) & sdp_time_descr_free);
307 osip_free(*sdp);
308 *sdp = NULL;
309 return OSIP_NOMEM;
310 }
311
312 i = osip_list_init(&(*sdp)->m_medias);
313
314 if (i != 0) {
315 osip_list_ofchar_free(&(*sdp)->e_emails);
316 osip_list_ofchar_free(&(*sdp)->p_phones);
317 osip_list_special_free(&(*sdp)->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
318 osip_list_special_free(&(*sdp)->t_descrs, (void (*)(void *)) & sdp_time_descr_free);
319 osip_list_special_free(&(*sdp)->a_attributes, (void (*)(void *)) & sdp_attribute_free);
320 osip_free(*sdp);
321 *sdp = NULL;
322 return OSIP_NOMEM;
323 }
324
325 return OSIP_SUCCESS;
326 }
327
328 /* append string_osip_to_append to string at position cur
329 size is the current allocated size of the element
330 */
__osip_sdp_append_string(char ** string,int * size,char * cur,char * string_osip_to_append)331 static char *__osip_sdp_append_string(char **string, int *size, char *cur, char *string_osip_to_append) {
332 int length = (int) strlen(string_osip_to_append);
333
334 if (cur - (*string) + length + 1 > *size) {
335 int length2;
336
337 length2 = (int) (cur - *string);
338 (*string) = osip_realloc((*string), *size + length + 500);
339 *size = *size + length + 500; /* optimize: avoid too much realloc */
340 cur = (*string) + length2; /* the initial allocation may have changed! */
341 }
342
343 osip_strncpy(cur, string_osip_to_append, length);
344 return cur + strlen(cur);
345 }
346
sdp_message_parse_v(sdp_message_t * sdp,char * buf,char ** next)347 static int sdp_message_parse_v(sdp_message_t *sdp, char *buf, char **next) {
348 char *equal;
349 char *crlf;
350
351 *next = buf;
352
353 equal = buf;
354
355 while ((*equal != '=') && (*equal != '\0'))
356 equal++;
357
358 if (*equal == '\0')
359 return ERR_ERROR;
360
361 if (equal == buf)
362 return ERR_DISCARD;
363
364 /* check if header is "v" */
365 if (equal[-1] != 'v')
366 return ERR_DISCARD;
367
368 crlf = equal + 1;
369
370 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
371 crlf++;
372
373 if (*crlf == '\0')
374 return ERR_ERROR;
375
376 if (crlf == equal + 1)
377 return ERR_ERROR; /*v=\r ?? bad header */
378
379 sdp->v_version = osip_malloc(crlf - (equal + 1) + 1);
380
381 if (sdp->v_version == NULL)
382 return OSIP_NOMEM;
383
384 osip_strncpy(sdp->v_version, equal + 1, crlf - (equal + 1));
385
386 if (crlf[1] == '\n')
387 *next = crlf + 2;
388
389 else
390 *next = crlf + 1;
391
392 return OSIP_WF;
393 }
394
sdp_message_parse_o(sdp_message_t * sdp,char * buf,char ** next)395 static int sdp_message_parse_o(sdp_message_t *sdp, char *buf, char **next) {
396 char *equal;
397 char *crlf;
398 char *tmp;
399 char *tmp_next;
400 int i;
401
402 *next = buf;
403
404 equal = buf;
405
406 while ((*equal != '=') && (*equal != '\0'))
407 equal++;
408
409 if (*equal == '\0')
410 return ERR_ERROR;
411
412 /* check if header is "o" */
413 if (equal[-1] != 'o')
414 return ERR_DISCARD;
415
416 crlf = equal + 1;
417
418 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
419 crlf++;
420
421 if (*crlf == '\0')
422 return ERR_ERROR;
423
424 if (crlf == equal + 1)
425 return ERR_ERROR; /* o=\r ?? bad header */
426
427 tmp = equal + 1;
428 /* o=username sess-id sess-version nettype addrtype addr */
429
430 /* useranme can contain any char (ascii) except "space" and CRLF */
431 #ifdef FIREFLY_BUG_SUPPORT
432
433 if (tmp[0] == ' ') {
434 sdp->o_username = osip_strdup("firefly");
435 tmp++;
436
437 } else {
438 i = __osip_set_next_token(&(sdp->o_username), tmp, ' ', &tmp_next);
439
440 if (i != 0)
441 return -1;
442
443 tmp = tmp_next;
444 }
445
446 #else
447 i = __osip_set_next_token(&(sdp->o_username), tmp, ' ', &tmp_next);
448
449 if (i != 0)
450 return -1;
451
452 tmp = tmp_next;
453 #endif
454
455 /* sess_id contains only numeric characters */
456 i = __osip_set_next_token(&(sdp->o_sess_id), tmp, ' ', &tmp_next);
457
458 if (i != 0)
459 return -1;
460
461 tmp = tmp_next;
462
463 /* sess_id contains only numeric characters */
464 i = __osip_set_next_token(&(sdp->o_sess_version), tmp, ' ', &tmp_next);
465
466 if (i != 0)
467 return -1;
468
469 tmp = tmp_next;
470
471 /* nettype is "IN" but will surely be extented!!! assume it's some alpha-char */
472 i = __osip_set_next_token(&(sdp->o_nettype), tmp, ' ', &tmp_next);
473
474 if (i != 0)
475 return -1;
476
477 tmp = tmp_next;
478
479 /* addrtype is "IP4" or "IP6" but will surely be extented!!! */
480 i = __osip_set_next_token(&(sdp->o_addrtype), tmp, ' ', &tmp_next);
481
482 if (i != 0)
483 return -1;
484
485 tmp = tmp_next;
486
487 /* addr is "IP4" or "IP6" but will surely be extented!!! */
488 i = __osip_set_next_token(&(sdp->o_addr), tmp, '\r', &tmp_next);
489
490 if (i != 0) { /* could it be "\n" only??? rfc says to accept CR or LF instead of CRLF */
491 i = __osip_set_next_token(&(sdp->o_addr), tmp, '\n', &tmp_next);
492
493 if (i != 0)
494 return -1;
495 }
496
497 if (crlf[1] == '\n')
498 *next = crlf + 2;
499
500 else
501 *next = crlf + 1;
502
503 return OSIP_WF;
504 }
505
sdp_message_parse_s(sdp_message_t * sdp,char * buf,char ** next)506 static int sdp_message_parse_s(sdp_message_t *sdp, char *buf, char **next) {
507 char *equal;
508 char *crlf;
509
510 *next = buf;
511
512 equal = buf;
513
514 while ((*equal != '=') && (*equal != '\0'))
515 equal++;
516
517 if (*equal == '\0')
518 return ERR_ERROR;
519
520 /* check if header is "s" */
521 if (equal[-1] != 's')
522 return ERR_DISCARD;
523
524 crlf = equal + 1;
525
526 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
527 crlf++;
528
529 if (*crlf == '\0')
530 return ERR_ERROR;
531
532 #ifdef FIREFLY_BUG_SUPPORT
533
534 if (crlf == equal + 1) {
535 sdp->s_name = osip_strdup(" ");
536
537 if (crlf[1] == '\n')
538 *next = crlf + 2;
539
540 else
541 *next = crlf + 1;
542
543 return OSIP_WF; /* o=\r ?? bad header */
544 }
545
546 #else
547
548 if (crlf == equal + 1)
549 return ERR_ERROR; /* o=\r ?? bad header */
550
551 #endif
552
553 /* s=text */
554
555 /* text is interpreted as ISO-10646 UTF8! */
556 /* using ISO 8859-1 requires "a=charset:ISO-8859-1 */
557 sdp->s_name = osip_malloc(crlf - (equal + 1) + 1);
558
559 if (sdp->s_name == NULL)
560 return OSIP_NOMEM;
561
562 osip_strncpy(sdp->s_name, equal + 1, crlf - (equal + 1));
563
564 if (crlf[1] == '\n')
565 *next = crlf + 2;
566
567 else
568 *next = crlf + 1;
569
570 return OSIP_WF;
571 }
572
sdp_message_parse_i(sdp_message_t * sdp,char * buf,char ** next)573 static int sdp_message_parse_i(sdp_message_t *sdp, char *buf, char **next) {
574 char *equal;
575 char *crlf;
576 int i;
577 char *i_info;
578
579 *next = buf;
580
581 equal = buf;
582
583 while ((*equal != '=') && (*equal != '\0'))
584 equal++;
585
586 if (*equal == '\0')
587 return ERR_ERROR;
588
589 /* check if header is "i" */
590 if (equal[-1] != 'i')
591 return ERR_DISCARD;
592
593 crlf = equal + 1;
594
595 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
596 crlf++;
597
598 if (*crlf == '\0')
599 return ERR_ERROR;
600
601 if (crlf == equal + 1)
602 return ERR_ERROR; /* o=\r ?? bad header */
603
604 /* s=text */
605
606 /* text is interpreted as ISO-10646 UTF8! */
607 /* using ISO 8859-1 requires "a=charset:ISO-8859-1 */
608 i_info = osip_malloc(crlf - (equal + 1) + 1);
609
610 if (i_info == NULL)
611 return OSIP_NOMEM;
612
613 osip_strncpy(i_info, equal + 1, crlf - (equal + 1));
614
615 /* add the bandwidth at the correct place:
616 if there is no media line yet, then the "b=" is the
617 global one.
618 */
619 i = osip_list_size(&sdp->m_medias);
620
621 if (i == 0)
622 sdp->i_info = i_info;
623
624 else {
625 sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get(&sdp->m_medias, i - 1);
626
627 last_sdp_media->i_info = i_info;
628 }
629
630 if (crlf[1] == '\n')
631 *next = crlf + 2;
632
633 else
634 *next = crlf + 1;
635
636 return OSIP_WF;
637 }
638
sdp_message_parse_u(sdp_message_t * sdp,char * buf,char ** next)639 static int sdp_message_parse_u(sdp_message_t *sdp, char *buf, char **next) {
640 char *equal;
641 char *crlf;
642
643 *next = buf;
644
645 equal = buf;
646
647 while ((*equal != '=') && (*equal != '\0'))
648 equal++;
649
650 if (*equal == '\0')
651 return ERR_ERROR;
652
653 /* check if header is "u" */
654 if (equal[-1] != 'u')
655 return ERR_DISCARD;
656
657 crlf = equal + 1;
658
659 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
660 crlf++;
661
662 if (*crlf == '\0')
663 return ERR_ERROR;
664
665 if (crlf == equal + 1)
666 return ERR_ERROR; /* u=\r ?? bad header */
667
668 /* u=uri */
669 /* we assume this is a URI */
670 sdp->u_uri = osip_malloc(crlf - (equal + 1) + 1);
671
672 if (sdp->u_uri == NULL)
673 return OSIP_NOMEM;
674
675 osip_strncpy(sdp->u_uri, equal + 1, crlf - (equal + 1));
676
677 if (crlf[1] == '\n')
678 *next = crlf + 2;
679
680 else
681 *next = crlf + 1;
682
683 return OSIP_WF;
684 }
685
sdp_message_parse_e(sdp_message_t * sdp,char * buf,char ** next)686 static int sdp_message_parse_e(sdp_message_t *sdp, char *buf, char **next) {
687 char *equal;
688 char *crlf;
689 char *e_email;
690
691 *next = buf;
692
693 equal = buf;
694
695 while ((*equal != '=') && (*equal != '\0'))
696 equal++;
697
698 if (*equal == '\0')
699 return ERR_ERROR;
700
701 /* check if header is "e" */
702 if (equal[-1] != 'e')
703 return ERR_DISCARD;
704
705 crlf = equal + 1;
706
707 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
708 crlf++;
709
710 if (*crlf == '\0')
711 return ERR_ERROR;
712
713 if (crlf == equal + 1)
714 return ERR_ERROR; /* e=\r ?? bad header */
715
716 /* e=email */
717 /* we assume this is an EMAIL-ADDRESS */
718 e_email = osip_malloc(crlf - (equal + 1) + 1);
719
720 if (e_email == NULL)
721 return OSIP_NOMEM;
722
723 osip_strncpy(e_email, equal + 1, crlf - (equal + 1));
724
725 osip_list_add(&sdp->e_emails, e_email, -1);
726
727 if (crlf[1] == '\n')
728 *next = crlf + 2;
729
730 else
731 *next = crlf + 1;
732
733 return OSIP_WF;
734 }
735
sdp_message_parse_p(sdp_message_t * sdp,char * buf,char ** next)736 static int sdp_message_parse_p(sdp_message_t *sdp, char *buf, char **next) {
737 char *equal;
738 char *crlf;
739 char *p_phone;
740
741 *next = buf;
742
743 equal = buf;
744
745 while ((*equal != '=') && (*equal != '\0'))
746 equal++;
747
748 if (*equal == '\0')
749 return ERR_ERROR;
750
751 /* check if header is "p" */
752 if (equal[-1] != 'p')
753 return ERR_DISCARD;
754
755 crlf = equal + 1;
756
757 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
758 crlf++;
759
760 if (*crlf == '\0')
761 return ERR_ERROR;
762
763 if (crlf == equal + 1)
764 return ERR_ERROR; /* p=\r ?? bad header */
765
766 /* e=email */
767 /* we assume this is an EMAIL-ADDRESS */
768 p_phone = osip_malloc(crlf - (equal + 1) + 1);
769
770 if (p_phone == NULL)
771 return OSIP_NOMEM;
772
773 osip_strncpy(p_phone, equal + 1, crlf - (equal + 1));
774
775 osip_list_add(&sdp->p_phones, p_phone, -1);
776
777 if (crlf[1] == '\n')
778 *next = crlf + 2;
779
780 else
781 *next = crlf + 1;
782
783 return OSIP_WF;
784 }
785
sdp_message_parse_c(sdp_message_t * sdp,char * buf,char ** next)786 static int sdp_message_parse_c(sdp_message_t *sdp, char *buf, char **next) {
787 char *equal;
788 char *crlf;
789 char *tmp;
790 char *tmp_next;
791 sdp_connection_t *c_header;
792 int i;
793
794 *next = buf;
795
796 equal = buf;
797
798 while ((*equal != '=') && (*equal != '\0'))
799 equal++;
800
801 if (*equal == '\0')
802 return ERR_ERROR;
803
804 /* check if header is "c" */
805 if (equal[-1] != 'c')
806 return ERR_DISCARD;
807
808 crlf = equal + 1;
809
810 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
811 crlf++;
812
813 if (*crlf == '\0')
814 return ERR_ERROR;
815
816 if (crlf == equal + 1)
817 return ERR_ERROR; /* c=\r ?? bad header */
818
819 tmp = equal + 1;
820 i = sdp_connection_init(&c_header);
821
822 if (i != 0)
823 return ERR_ERROR;
824
825 /* c=nettype addrtype (multicastaddr | addr) */
826
827 /* nettype is "IN" and will be extended */
828 i = __osip_set_next_token(&(c_header->c_nettype), tmp, ' ', &tmp_next);
829
830 if (i != 0) {
831 sdp_connection_free(c_header);
832 return -1;
833 }
834
835 tmp = tmp_next;
836
837 /* nettype is "IP4" or "IP6" and will be extended */
838 i = __osip_set_next_token(&(c_header->c_addrtype), tmp, ' ', &tmp_next);
839
840 if (i != 0) {
841 sdp_connection_free(c_header);
842 return -1;
843 }
844
845 tmp = tmp_next;
846
847 /* there we have a multicast or unicast address */
848 /* multicast can be ip/ttl [/integer] */
849 /* unicast is FQDN or ip (no ttl, no integer) */
850
851 /* is MULTICAST? */
852 {
853 char *slash = strchr(tmp, '/');
854
855 if (slash != NULL && slash < crlf) { /* it's a multicast address! */
856 i = __osip_set_next_token(&(c_header->c_addr), tmp, '/', &tmp_next);
857
858 if (i != 0) {
859 sdp_connection_free(c_header);
860 return -1;
861 }
862
863 tmp = tmp_next;
864 slash = strchr(slash + 1, '/');
865
866 if (slash != NULL && slash < crlf) { /* optionnal integer is there! */
867 i = __osip_set_next_token(&(c_header->c_addr_multicast_ttl), tmp, '/', &tmp_next);
868
869 if (i != 0) {
870 sdp_connection_free(c_header);
871 return -1;
872 }
873
874 tmp = tmp_next;
875 i = __osip_set_next_token(&(c_header->c_addr_multicast_int), tmp, '\r', &tmp_next);
876
877 if (i != 0) {
878 i = __osip_set_next_token(&(c_header->c_addr_multicast_int), tmp, '\n', &tmp_next);
879
880 if (i != 0) {
881 sdp_connection_free(c_header);
882 return -1;
883 }
884 }
885
886 } else {
887 i = __osip_set_next_token(&(c_header->c_addr_multicast_ttl), tmp, '\r', &tmp_next);
888
889 if (i != 0) {
890 i = __osip_set_next_token(&(c_header->c_addr_multicast_ttl), tmp, '\n', &tmp_next);
891
892 if (i != 0) {
893 sdp_connection_free(c_header);
894 return -1;
895 }
896 }
897 }
898
899 } else {
900 /* in this case, we have a unicast address */
901 i = __osip_set_next_token(&(c_header->c_addr), tmp, '\r', &tmp_next);
902
903 if (i != 0) {
904 i = __osip_set_next_token(&(c_header->c_addr), tmp, '\n', &tmp_next);
905
906 if (i != 0) {
907 sdp_connection_free(c_header);
908 return -1;
909 }
910 }
911 }
912 }
913
914 /* add the connection at the correct place:
915 if there is no media line yet, then the "c=" is the
916 global one.
917 */
918 i = osip_list_size(&sdp->m_medias);
919
920 if (i == 0)
921 sdp->c_connection = c_header;
922
923 else {
924 sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get(&sdp->m_medias, i - 1);
925
926 osip_list_add(&last_sdp_media->c_connections, c_header, -1);
927 }
928
929 if (crlf[1] == '\n')
930 *next = crlf + 2;
931
932 else
933 *next = crlf + 1;
934
935 return OSIP_WF;
936 }
937
sdp_message_parse_b(sdp_message_t * sdp,char * buf,char ** next)938 static int sdp_message_parse_b(sdp_message_t *sdp, char *buf, char **next) {
939 char *equal;
940 char *crlf;
941 char *tmp;
942 char *tmp_next;
943 int i;
944 sdp_bandwidth_t *b_header;
945
946 *next = buf;
947
948 equal = buf;
949
950 while ((*equal != '=') && (*equal != '\0'))
951 equal++;
952
953 if (*equal == '\0')
954 return ERR_ERROR;
955
956 /* check if header is "b" */
957 if (equal[-1] != 'b')
958 return ERR_DISCARD;
959
960 crlf = equal + 1;
961
962 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
963 crlf++;
964
965 if (*crlf == '\0')
966 return ERR_ERROR;
967
968 if (crlf == equal + 1)
969 return ERR_ERROR; /* b=\r ?? bad header */
970
971 tmp = equal + 1;
972 /* b = bwtype: bandwidth */
973 i = sdp_bandwidth_init(&b_header);
974
975 if (i != 0)
976 return ERR_ERROR;
977
978 /* bwtype is alpha-numeric */
979 i = __osip_set_next_token(&(b_header->b_bwtype), tmp, ':', &tmp_next);
980
981 if (i != 0) {
982 sdp_bandwidth_free(b_header);
983 return -1;
984 }
985
986 tmp = tmp_next;
987
988 i = __osip_set_next_token(&(b_header->b_bandwidth), tmp, '\r', &tmp_next);
989
990 if (i != 0) {
991 i = __osip_set_next_token(&(b_header->b_bandwidth), tmp, '\n', &tmp_next);
992
993 if (i != 0) {
994 sdp_bandwidth_free(b_header);
995 return -1;
996 }
997 }
998
999 /* add the bandwidth at the correct place:
1000 if there is no media line yet, then the "b=" is the
1001 global one.
1002 */
1003 i = osip_list_size(&sdp->m_medias);
1004
1005 if (i == 0)
1006 osip_list_add(&sdp->b_bandwidths, b_header, -1);
1007
1008 else {
1009 sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get(&sdp->m_medias, i - 1);
1010
1011 osip_list_add(&last_sdp_media->b_bandwidths, b_header, -1);
1012 }
1013
1014 if (crlf[1] == '\n')
1015 *next = crlf + 2;
1016
1017 else
1018 *next = crlf + 1;
1019
1020 return OSIP_WF;
1021 }
1022
sdp_message_parse_t(sdp_message_t * sdp,char * buf,char ** next)1023 static int sdp_message_parse_t(sdp_message_t *sdp, char *buf, char **next) {
1024 char *equal;
1025 char *crlf;
1026 char *tmp;
1027 char *tmp_next;
1028 int i;
1029 sdp_time_descr_t *t_header;
1030
1031 *next = buf;
1032
1033 equal = buf;
1034
1035 while ((*equal != '=') && (*equal != '\0'))
1036 equal++;
1037
1038 if (*equal == '\0')
1039 return ERR_ERROR;
1040
1041 /* check if header is "t" */
1042 if (equal[-1] != 't')
1043 return ERR_DISCARD;
1044
1045 crlf = equal + 1;
1046
1047 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1048 crlf++;
1049
1050 if (*crlf == '\0')
1051 return ERR_ERROR;
1052
1053 if (crlf == equal + 1)
1054 return ERR_ERROR; /* t=\r ?? bad header */
1055
1056 tmp = equal + 1;
1057 /* t = start_time stop_time */
1058 i = sdp_time_descr_init(&t_header);
1059
1060 if (i != 0)
1061 return ERR_ERROR;
1062
1063 i = __osip_set_next_token(&(t_header->t_start_time), tmp, ' ', &tmp_next);
1064
1065 if (i != 0) {
1066 sdp_time_descr_free(t_header);
1067 return -1;
1068 }
1069
1070 tmp = tmp_next;
1071
1072 i = __osip_set_next_token(&(t_header->t_stop_time), tmp, '\r', &tmp_next);
1073
1074 if (i != 0) {
1075 i = __osip_set_next_token(&(t_header->t_stop_time), tmp, '\n', &tmp_next);
1076
1077 if (i != 0) {
1078 sdp_time_descr_free(t_header);
1079 return -1;
1080 }
1081 }
1082
1083 /* add the new time_description header */
1084 osip_list_add(&sdp->t_descrs, t_header, -1);
1085
1086 if (crlf[1] == '\n')
1087 *next = crlf + 2;
1088
1089 else
1090 *next = crlf + 1;
1091
1092 return OSIP_WF;
1093 }
1094
sdp_message_parse_r(sdp_message_t * sdp,char * buf,char ** next)1095 static int sdp_message_parse_r(sdp_message_t *sdp, char *buf, char **next) {
1096 char *equal;
1097 char *crlf;
1098 int index;
1099 char *r_header;
1100 sdp_time_descr_t *t_descr;
1101
1102 *next = buf;
1103
1104 equal = buf;
1105
1106 while ((*equal != '=') && (*equal != '\0'))
1107 equal++;
1108
1109 if (*equal == '\0')
1110 return ERR_ERROR;
1111
1112 /* check if header is "r" */
1113 if (equal[-1] != 'r')
1114 return ERR_DISCARD;
1115
1116 index = osip_list_size(&sdp->t_descrs);
1117
1118 if (index == 0)
1119 return ERR_ERROR; /* r field can't come alone! */
1120
1121 crlf = equal + 1;
1122
1123 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1124 crlf++;
1125
1126 if (*crlf == '\0')
1127 return ERR_ERROR;
1128
1129 if (crlf == equal + 1)
1130 return ERR_ERROR; /* r=\r ?? bad header */
1131
1132 /* r=far too complexe and somewhat useless... I don't parse it! */
1133 r_header = osip_malloc(crlf - (equal + 1) + 1);
1134
1135 if (r_header == NULL)
1136 return OSIP_NOMEM;
1137
1138 osip_strncpy(r_header, equal + 1, crlf - (equal + 1));
1139
1140 /* r field carry information for the last "t" field */
1141 t_descr = (sdp_time_descr_t *) osip_list_get(&sdp->t_descrs, index - 1);
1142 osip_list_add(&t_descr->r_repeats, r_header, -1);
1143
1144 if (crlf[1] == '\n')
1145 *next = crlf + 2;
1146
1147 else
1148 *next = crlf + 1;
1149
1150 return OSIP_WF;
1151 }
1152
sdp_message_parse_z(sdp_message_t * sdp,char * buf,char ** next)1153 static int sdp_message_parse_z(sdp_message_t *sdp, char *buf, char **next) {
1154 char *equal;
1155 char *crlf;
1156 char *z_header;
1157
1158 *next = buf;
1159
1160 equal = buf;
1161
1162 while ((*equal != '=') && (*equal != '\0'))
1163 equal++;
1164
1165 if (*equal == '\0')
1166 return ERR_ERROR;
1167
1168 /* check if header is "z" */
1169 if (equal[-1] != 'z')
1170 return ERR_DISCARD;
1171
1172 crlf = equal + 1;
1173
1174 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1175 crlf++;
1176
1177 if (*crlf == '\0')
1178 return ERR_ERROR;
1179
1180 if (crlf == equal + 1)
1181 return ERR_ERROR; /* z=\r ?? bad header */
1182
1183 /* z=somewhat useless... I don't parse it! */
1184 z_header = osip_malloc(crlf - (equal + 1) + 1);
1185
1186 if (z_header == NULL)
1187 return OSIP_NOMEM;
1188
1189 osip_strncpy(z_header, equal + 1, crlf - (equal + 1));
1190
1191 sdp->z_adjustments = z_header;
1192
1193 if (crlf[1] == '\n')
1194 *next = crlf + 2;
1195
1196 else
1197 *next = crlf + 1;
1198
1199 return OSIP_WF;
1200 }
1201
sdp_message_parse_k(sdp_message_t * sdp,char * buf,char ** next)1202 static int sdp_message_parse_k(sdp_message_t *sdp, char *buf, char **next) {
1203 char *equal;
1204 char *crlf;
1205 int i;
1206 char *colon;
1207 sdp_key_t *k_header;
1208 char *tmp;
1209 char *tmp_next;
1210
1211 *next = buf;
1212
1213 equal = buf;
1214
1215 while ((*equal != '=') && (*equal != '\0'))
1216 equal++;
1217
1218 if (*equal == '\0')
1219 return ERR_ERROR;
1220
1221 /* check if header is "k" */
1222 if (equal[-1] != 'k')
1223 return ERR_DISCARD;
1224
1225 crlf = equal + 1;
1226
1227 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1228 crlf++;
1229
1230 if (*crlf == '\0')
1231 return ERR_ERROR;
1232
1233 if (crlf == equal + 1)
1234 return ERR_ERROR; /* k=\r ?? bad header */
1235
1236 tmp = equal + 1;
1237
1238 i = sdp_key_init(&k_header);
1239
1240 if (i != 0)
1241 return ERR_ERROR;
1242
1243 /* k=key-type[:key-data] */
1244
1245 /* is there any key-data? */
1246 colon = strchr(equal + 1, ':');
1247
1248 if ((colon != NULL) && (colon < crlf)) {
1249 /* att-field is alpha-numeric */
1250 i = __osip_set_next_token(&(k_header->k_keytype), tmp, ':', &tmp_next);
1251
1252 if (i != 0) {
1253 sdp_key_free(k_header);
1254 return -1;
1255 }
1256
1257 tmp = tmp_next;
1258
1259 i = __osip_set_next_token(&(k_header->k_keydata), tmp, '\r', &tmp_next);
1260
1261 if (i != 0) {
1262 i = __osip_set_next_token(&(k_header->k_keydata), tmp, '\n', &tmp_next);
1263
1264 if (i != 0) {
1265 sdp_key_free(k_header);
1266 return -1;
1267 }
1268 }
1269
1270 } else {
1271 i = __osip_set_next_token(&(k_header->k_keytype), tmp, '\r', &tmp_next);
1272
1273 if (i != 0) {
1274 i = __osip_set_next_token(&(k_header->k_keytype), tmp, '\n', &tmp_next);
1275
1276 if (i != 0) {
1277 sdp_key_free(k_header);
1278 return -1;
1279 }
1280 }
1281 }
1282
1283 /* add the key at the correct place:
1284 if there is no media line yet, then the "k=" is the
1285 global one.
1286 */
1287 i = osip_list_size(&sdp->m_medias);
1288
1289 if (i == 0)
1290 sdp->k_key = k_header;
1291
1292 else {
1293 sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get(&sdp->m_medias, i - 1);
1294
1295 /* fixed Jan 10,2020: avoid a possible memory leak with k appearing several times after media line */
1296 /* fixed Nov 04,2020: wrong test was applied. Any media k= line was being rejected */
1297 if (last_sdp_media->k_key != NULL) {
1298 /* I believe such condition cannot happen any more: the method can't be called twice on a media */
1299 sdp_key_free(k_header);
1300 return -1;
1301 }
1302
1303 last_sdp_media->k_key = k_header;
1304 }
1305
1306 if (crlf[1] == '\n')
1307 *next = crlf + 2;
1308
1309 else
1310 *next = crlf + 1;
1311
1312 return OSIP_WF;
1313 }
1314
sdp_message_parse_a(sdp_message_t * sdp,char * buf,char ** next)1315 static int sdp_message_parse_a(sdp_message_t *sdp, char *buf, char **next) {
1316 char *equal;
1317 char *crlf;
1318 char *tmp;
1319 char *tmp_next;
1320 int i;
1321 sdp_attribute_t *a_attribute;
1322 char *colon;
1323
1324 *next = buf;
1325
1326 equal = buf;
1327
1328 while ((*equal != '=') && (*equal != '\0'))
1329 equal++;
1330
1331 if (*equal == '\0')
1332 return ERR_ERROR;
1333
1334 /* check if header is "a" */
1335 if (equal[-1] != 'a')
1336 return ERR_DISCARD;
1337
1338 crlf = equal + 1;
1339
1340 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1341 crlf++;
1342
1343 if (*crlf == '\0')
1344 return ERR_ERROR;
1345
1346 if (crlf == equal + 1)
1347 return ERR_ERROR; /* a=\r ?? bad header */
1348
1349 tmp = equal + 1;
1350
1351 i = sdp_attribute_init(&a_attribute);
1352
1353 if (i != 0)
1354 return ERR_ERROR;
1355
1356 /* a=att-field[:att-value] */
1357
1358 /* is there any att-value? */
1359 colon = strchr(equal + 1, ':');
1360
1361 if ((colon != NULL) && (colon < crlf)) {
1362 /* att-field is alpha-numeric */
1363 i = __osip_set_next_token(&(a_attribute->a_att_field), tmp, ':', &tmp_next);
1364
1365 if (i != 0) {
1366 sdp_attribute_free(a_attribute);
1367 return -1;
1368 }
1369
1370 tmp = tmp_next;
1371
1372 i = __osip_set_next_token(&(a_attribute->a_att_value), tmp, '\r', &tmp_next);
1373
1374 if (i != 0) {
1375 i = __osip_set_next_token(&(a_attribute->a_att_value), tmp, '\n', &tmp_next);
1376
1377 if (i != 0) {
1378 sdp_attribute_free(a_attribute);
1379 return -1;
1380 }
1381 }
1382
1383 } else {
1384 i = __osip_set_next_token(&(a_attribute->a_att_field), tmp, '\r', &tmp_next);
1385
1386 if (i != 0) {
1387 i = __osip_set_next_token(&(a_attribute->a_att_field), tmp, '\n', &tmp_next);
1388
1389 if (i != 0) {
1390 sdp_attribute_free(a_attribute);
1391 return -1;
1392 }
1393 }
1394 }
1395
1396 /* add the attribute at the correct place:
1397 if there is no media line yet, then the "a=" is the
1398 global one.
1399 */
1400 i = osip_list_size(&sdp->m_medias);
1401
1402 if (i == 0)
1403 osip_list_add(&sdp->a_attributes, a_attribute, -1);
1404
1405 else {
1406 sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get(&sdp->m_medias, i - 1);
1407
1408 osip_list_add(&last_sdp_media->a_attributes, a_attribute, -1);
1409 }
1410
1411 if (crlf[1] == '\n')
1412 *next = crlf + 2;
1413
1414 else
1415 *next = crlf + 1;
1416
1417 return OSIP_WF;
1418 }
1419
sdp_message_parse_m(sdp_message_t * sdp,char * buf,char ** next)1420 static int sdp_message_parse_m(sdp_message_t *sdp, char *buf, char **next) {
1421 char *equal;
1422 char *crlf;
1423 char *tmp;
1424 char *tmp_next;
1425 int i;
1426 sdp_media_t *m_header;
1427 char *slash;
1428 char *space;
1429
1430 *next = buf;
1431
1432 equal = buf;
1433
1434 while ((*equal != '=') && (*equal != '\0'))
1435 equal++;
1436
1437 if (*equal == '\0')
1438 return ERR_ERROR;
1439
1440 /* check if header is "m" */
1441 if (equal[-1] != 'm')
1442 return ERR_ERROR; /* fixed Jan 10,2020: avoid a possible memory leak with m being not detected */
1443
1444 crlf = equal + 1;
1445
1446 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1447 crlf++;
1448
1449 if (*crlf == '\0')
1450 return ERR_ERROR;
1451
1452 if (crlf == equal + 1)
1453 return ERR_ERROR; /* a=\r ?? bad header */
1454
1455 tmp = equal + 1;
1456
1457 i = sdp_media_init(&m_header);
1458
1459 if (i != 0)
1460 return ERR_ERROR;
1461
1462 /* m=media port ["/"integer] proto *(payload_number) */
1463
1464 /* media is "audio" "video" "application" "data" or other... */
1465 i = __osip_set_next_token(&(m_header->m_media), tmp, ' ', &tmp_next);
1466
1467 if (i != 0) {
1468 sdp_media_free(m_header);
1469 return -1;
1470 }
1471
1472 tmp = tmp_next;
1473
1474 slash = strchr(tmp, '/');
1475 space = strchr(tmp, ' ');
1476
1477 if (space == NULL) { /* not possible! */
1478 sdp_media_free(m_header);
1479 return ERR_ERROR;
1480 }
1481
1482 if ((slash != NULL) && (slash < space)) { /* a number of port is specified! */
1483 i = __osip_set_next_token(&(m_header->m_port), tmp, '/', &tmp_next);
1484
1485 if (i != 0) {
1486 sdp_media_free(m_header);
1487 return -1;
1488 }
1489
1490 tmp = tmp_next;
1491
1492 i = __osip_set_next_token(&(m_header->m_number_of_port), tmp, ' ', &tmp_next);
1493
1494 if (i != 0) {
1495 sdp_media_free(m_header);
1496 return -1;
1497 }
1498
1499 tmp = tmp_next;
1500
1501 } else {
1502 i = __osip_set_next_token(&(m_header->m_port), tmp, ' ', &tmp_next);
1503
1504 if (i != 0) {
1505 sdp_media_free(m_header);
1506 return -1;
1507 }
1508
1509 tmp = tmp_next;
1510 }
1511
1512 i = __osip_set_next_token(&(m_header->m_proto), tmp, ' ', &tmp_next);
1513
1514 if (i != 0) {
1515 /* a few stack don't add SPACE after m_proto when rejecting all payloads */
1516 i = __osip_set_next_token(&(m_header->m_proto), tmp, '\r', &tmp_next);
1517
1518 if (i != 0) {
1519 i = __osip_set_next_token(&(m_header->m_proto), tmp, '\n', &tmp_next);
1520
1521 if (i != 0) {
1522 sdp_media_free(m_header);
1523 return -1;
1524 }
1525 }
1526 }
1527
1528 tmp = tmp_next;
1529
1530 {
1531 char *str;
1532 int more_space_before_crlf;
1533
1534 space = strchr(tmp + 1, ' ');
1535
1536 if (space == NULL)
1537 more_space_before_crlf = 1;
1538
1539 else if ((space != NULL) && (space > crlf))
1540 more_space_before_crlf = 1;
1541
1542 else
1543 more_space_before_crlf = 0;
1544
1545 while (more_space_before_crlf == 0) {
1546 i = __osip_set_next_token(&str, tmp, ' ', &tmp_next);
1547
1548 if (i != 0) {
1549 sdp_media_free(m_header);
1550 return -1;
1551 }
1552
1553 tmp = tmp_next;
1554 osip_list_add(&m_header->m_payloads, str, -1);
1555
1556 space = strchr(tmp + 1, ' ');
1557
1558 if (space == NULL)
1559 more_space_before_crlf = 1;
1560
1561 else if ((space != NULL) && (space > crlf))
1562 more_space_before_crlf = 1;
1563
1564 else
1565 more_space_before_crlf = 0;
1566 }
1567
1568 if (tmp_next < crlf) { /* tmp_next is still less than clrf: no space */
1569 i = __osip_set_next_token(&str, tmp, '\r', &tmp_next);
1570
1571 if (i != 0) {
1572 i = __osip_set_next_token(&str, tmp, '\n', &tmp_next);
1573
1574 if (i != 0) {
1575 sdp_media_free(m_header);
1576 return -1;
1577 }
1578 }
1579
1580 osip_list_add(&m_header->m_payloads, str, -1);
1581 }
1582 }
1583
1584 osip_list_add(&sdp->m_medias, m_header, -1);
1585
1586 if (crlf[1] == '\n')
1587 *next = crlf + 2;
1588
1589 else
1590 *next = crlf + 1;
1591
1592 return OSIP_WF;
1593 }
1594
sdp_message_parse(sdp_message_t * sdp,const char * buf)1595 int sdp_message_parse(sdp_message_t *sdp, const char *buf) {
1596 /* In SDP, headers must be in the right order */
1597 /* This is a simple example
1598 v=0
1599 o=user1 53655765 2353687637 IN IP4 128.3.4.5
1600 s=Mbone Audio
1601 i=Discussion of Mbone Engineering Issues
1602 e=mbone@somewhere.com
1603 c=IN IP4 224.2.0.1/127
1604 t=0 0
1605 m=audio 3456 RTP/AVP 0
1606 a=rtpmap:0 PCMU/8000
1607 */
1608
1609 char *next_buf;
1610 char *ptr;
1611 int i;
1612
1613 ptr = (char *) buf;
1614 /* mandatory */
1615 i = sdp_message_parse_v(sdp, ptr, &next_buf);
1616
1617 if (i == -1) /* header is bad */
1618 return -1;
1619
1620 else if (0 == i) /* header is not "v" */
1621 return -1;
1622
1623 ptr = next_buf;
1624
1625 /* adtech phone use the wrong ordering and place "s" before "o" */
1626 i = sdp_message_parse_s(sdp, ptr, &next_buf);
1627
1628 if (i == -1) /* header is bad */
1629 return -1;
1630
1631 /* else if (0==i) header is not "s" */
1632 /* else ADTECH PHONE DETECTED */
1633
1634 ptr = next_buf;
1635
1636 i = sdp_message_parse_o(sdp, ptr, &next_buf);
1637
1638 if (i == -1) /* header is bad */
1639 return -1;
1640
1641 else if (0 == i) /* header is not "o" */
1642 return -1;
1643
1644 ptr = next_buf;
1645
1646 if (sdp->s_name == NULL) { /* fixed Jan 10,2020: avoid a possible memory leak with s appearing both before o and after o */
1647 i = sdp_message_parse_s(sdp, ptr, &next_buf);
1648
1649 if (i == -1) /* header is bad */
1650 return -1;
1651
1652 else if (0 == i) { /* header is not "s" */
1653 /* return -1; */
1654 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "The \"s\" parameter is mandatory, but this packet does not contain any! - anyway, we don't mind about it.\n"));
1655 }
1656
1657 ptr = next_buf;
1658 }
1659
1660 i = sdp_message_parse_i(sdp, ptr, &next_buf);
1661
1662 if (i == -1) /* header is bad */
1663 return -1;
1664
1665 ptr = next_buf;
1666
1667 i = sdp_message_parse_u(sdp, ptr, &next_buf);
1668
1669 if (i == -1) /* header is bad */
1670 return -1;
1671
1672 ptr = next_buf;
1673
1674 i = 1;
1675
1676 while (i == 1) {
1677 i = sdp_message_parse_e(sdp, ptr, &next_buf);
1678
1679 if (i == -1) /* header is bad */
1680 return -1;
1681
1682 ptr = next_buf;
1683 }
1684
1685 i = 1;
1686
1687 while (i == 1) {
1688 i = sdp_message_parse_p(sdp, ptr, &next_buf);
1689
1690 if (i == -1) /* header is bad */
1691 return -1;
1692
1693 ptr = next_buf;
1694 }
1695
1696 /* rfc2327: there should be at least of email or phone number! */
1697 if (osip_list_size(&sdp->e_emails) == 0 && osip_list_size(&sdp->p_phones) == 0) {
1698 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "The rfc2327 says there should be at least an email or a phone header!- anyway, we don't mind about it.\n"));
1699 }
1700
1701 i = sdp_message_parse_c(sdp, ptr, &next_buf);
1702
1703 if (i == -1) /* header is bad */
1704 return -1;
1705
1706 ptr = next_buf;
1707
1708 i = 1;
1709
1710 while (i == 1) {
1711 i = sdp_message_parse_b(sdp, ptr, &next_buf);
1712
1713 if (i == -1) /* header is bad */
1714 return -1;
1715
1716 ptr = next_buf;
1717 }
1718
1719 /* 1 or more "t" header + 0 or more "r" header for each "t" header */
1720 i = sdp_message_parse_t(sdp, ptr, &next_buf);
1721
1722 if (i == -1) /* header is bad */
1723 return -1;
1724
1725 else if (i == ERR_DISCARD)
1726 return -1; /* t is mandatory */
1727
1728 ptr = next_buf;
1729
1730 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1731 return OSIP_SUCCESS;
1732
1733 i = 1;
1734
1735 while (i == 1) { /* is a "r" header */
1736 i = sdp_message_parse_r(sdp, ptr, &next_buf);
1737
1738 if (i == -1) /* header is bad */
1739 return -1;
1740
1741 ptr = next_buf;
1742
1743 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1744 return OSIP_SUCCESS;
1745 }
1746
1747 {
1748 int more_t_header = 1;
1749
1750 i = sdp_message_parse_t(sdp, ptr, &next_buf);
1751
1752 if (i == -1) /* header is bad */
1753 return -1;
1754
1755 ptr = next_buf;
1756
1757 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1758 return OSIP_SUCCESS;
1759
1760 while (more_t_header == 1) {
1761 i = 1;
1762
1763 while (i == 1) { /* is a "r" header */
1764 i = sdp_message_parse_r(sdp, ptr, &next_buf);
1765
1766 if (i == -1) /* header is bad */
1767 return -1;
1768
1769 ptr = next_buf;
1770
1771 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1772 return OSIP_SUCCESS;
1773 }
1774
1775 i = sdp_message_parse_t(sdp, ptr, &next_buf);
1776
1777 if (i == -1) /* header is bad */
1778 return -1;
1779
1780 else if (i == ERR_DISCARD)
1781 more_t_header = 0;
1782
1783 else
1784 more_t_header = 1; /* no more "t" headers */
1785
1786 ptr = next_buf;
1787
1788 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1789 return OSIP_SUCCESS;
1790 }
1791 }
1792
1793 i = sdp_message_parse_z(sdp, ptr, &next_buf);
1794
1795 if (i == -1) /* header is bad */
1796 return -1;
1797
1798 ptr = next_buf;
1799
1800 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1801 return OSIP_SUCCESS;
1802
1803 i = sdp_message_parse_k(sdp, ptr, &next_buf);
1804
1805 if (i == -1) /* header is bad */
1806 return -1;
1807
1808 ptr = next_buf;
1809
1810 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1811 return OSIP_SUCCESS;
1812
1813 /* 0 or more "a" header */
1814 i = 1;
1815
1816 while (i == 1) { /* no more "a" header */
1817 i = sdp_message_parse_a(sdp, ptr, &next_buf);
1818
1819 if (i == -1) /* header is bad */
1820 return -1;
1821
1822 ptr = next_buf;
1823
1824 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1825 return OSIP_SUCCESS;
1826 }
1827
1828 /* 0 or more media headers */
1829 {
1830 int more_m_header = 1;
1831
1832 while (more_m_header == 1) {
1833 more_m_header = sdp_message_parse_m(sdp, ptr, &next_buf);
1834
1835 if (more_m_header == -1) /* header is bad */
1836 return -1;
1837
1838 ptr = next_buf;
1839
1840 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1841 return OSIP_SUCCESS;
1842
1843 i = sdp_message_parse_i(sdp, ptr, &next_buf);
1844
1845 if (i == -1) /* header is bad */
1846 return -1;
1847
1848 ptr = next_buf;
1849
1850 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1851 return OSIP_SUCCESS;
1852
1853 i = 1;
1854
1855 while (i == 1) {
1856 i = sdp_message_parse_c(sdp, ptr, &next_buf);
1857
1858 if (i == -1) /* header is bad */
1859 return -1;
1860
1861 ptr = next_buf;
1862
1863 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1864 return OSIP_SUCCESS;
1865 }
1866
1867 i = 1;
1868
1869 while (i == 1) {
1870 i = sdp_message_parse_b(sdp, ptr, &next_buf);
1871
1872 if (i == -1) /* header is bad */
1873 return -1;
1874
1875 ptr = next_buf;
1876
1877 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1878 return OSIP_SUCCESS;
1879 }
1880
1881 i = sdp_message_parse_k(sdp, ptr, &next_buf);
1882
1883 if (i == -1) /* header is bad */
1884 return -1;
1885
1886 ptr = next_buf;
1887
1888 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1889 return OSIP_SUCCESS;
1890
1891 /* 0 or more a headers */
1892 i = 1;
1893
1894 while (i == 1) {
1895 i = sdp_message_parse_a(sdp, ptr, &next_buf);
1896
1897 if (i == -1) /* header is bad */
1898 return -1;
1899
1900 ptr = next_buf;
1901
1902 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1903 return OSIP_SUCCESS;
1904 }
1905 }
1906 }
1907
1908 return OSIP_SUCCESS;
1909 }
1910
sdp_append_connection(char ** string,int * size,char * tmp,sdp_connection_t * conn,char ** next_tmp)1911 static int sdp_append_connection(char **string, int *size, char *tmp, sdp_connection_t *conn, char **next_tmp) {
1912 if (conn->c_nettype == NULL)
1913 return -1;
1914
1915 if (conn->c_addrtype == NULL)
1916 return -1;
1917
1918 if (conn->c_addr == NULL)
1919 return -1;
1920
1921 tmp = __osip_sdp_append_string(string, size, tmp, "c=");
1922 tmp = __osip_sdp_append_string(string, size, tmp, conn->c_nettype);
1923 tmp = __osip_sdp_append_string(string, size, tmp, " ");
1924 tmp = __osip_sdp_append_string(string, size, tmp, conn->c_addrtype);
1925 tmp = __osip_sdp_append_string(string, size, tmp, " ");
1926 tmp = __osip_sdp_append_string(string, size, tmp, conn->c_addr);
1927
1928 if (conn->c_addr_multicast_ttl != NULL) {
1929 tmp = __osip_sdp_append_string(string, size, tmp, "/");
1930 tmp = __osip_sdp_append_string(string, size, tmp, conn->c_addr_multicast_ttl);
1931 }
1932
1933 if (conn->c_addr_multicast_int != NULL) {
1934 tmp = __osip_sdp_append_string(string, size, tmp, "/");
1935 tmp = __osip_sdp_append_string(string, size, tmp, conn->c_addr_multicast_int);
1936 }
1937
1938 tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
1939 *next_tmp = tmp;
1940 return OSIP_SUCCESS;
1941 }
1942
sdp_append_bandwidth(char ** string,int * size,char * tmp,sdp_bandwidth_t * bandwidth,char ** next_tmp)1943 static int sdp_append_bandwidth(char **string, int *size, char *tmp, sdp_bandwidth_t *bandwidth, char **next_tmp) {
1944 if (bandwidth->b_bwtype == NULL)
1945 return -1;
1946
1947 if (bandwidth->b_bandwidth == NULL)
1948 return -1;
1949
1950 tmp = __osip_sdp_append_string(string, size, tmp, "b=");
1951 tmp = __osip_sdp_append_string(string, size, tmp, bandwidth->b_bwtype);
1952 tmp = __osip_sdp_append_string(string, size, tmp, ":");
1953 tmp = __osip_sdp_append_string(string, size, tmp, bandwidth->b_bandwidth);
1954 tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
1955
1956 *next_tmp = tmp;
1957 return OSIP_SUCCESS;
1958 }
1959
sdp_append_time_descr(char ** string,int * size,char * tmp,sdp_time_descr_t * time_descr,char ** next_tmp)1960 static int sdp_append_time_descr(char **string, int *size, char *tmp, sdp_time_descr_t *time_descr, char **next_tmp) {
1961 int pos;
1962
1963 if (time_descr->t_start_time == NULL)
1964 return -1;
1965
1966 if (time_descr->t_stop_time == NULL)
1967 return -1;
1968
1969 tmp = __osip_sdp_append_string(string, size, tmp, "t=");
1970 tmp = __osip_sdp_append_string(string, size, tmp, time_descr->t_start_time);
1971 tmp = __osip_sdp_append_string(string, size, tmp, " ");
1972 tmp = __osip_sdp_append_string(string, size, tmp, time_descr->t_stop_time);
1973
1974 tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
1975
1976 pos = 0;
1977
1978 while (!osip_list_eol(&time_descr->r_repeats, pos)) {
1979 char *str = (char *) osip_list_get(&time_descr->r_repeats, pos);
1980
1981 tmp = __osip_sdp_append_string(string, size, tmp, "r=");
1982 tmp = __osip_sdp_append_string(string, size, tmp, str);
1983 tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
1984 pos++;
1985 }
1986
1987 *next_tmp = tmp;
1988 return OSIP_SUCCESS;
1989 }
1990
sdp_append_key(char ** string,int * size,char * tmp,sdp_key_t * key,char ** next_tmp)1991 static int sdp_append_key(char **string, int *size, char *tmp, sdp_key_t *key, char **next_tmp) {
1992 if (key->k_keytype == NULL)
1993 return -1;
1994
1995 tmp = __osip_sdp_append_string(string, size, tmp, "k=");
1996 tmp = __osip_sdp_append_string(string, size, tmp, key->k_keytype);
1997
1998 if (key->k_keydata != NULL) {
1999 tmp = __osip_sdp_append_string(string, size, tmp, ":");
2000 tmp = __osip_sdp_append_string(string, size, tmp, key->k_keydata);
2001 }
2002
2003 tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
2004 *next_tmp = tmp;
2005 return OSIP_SUCCESS;
2006 }
2007
sdp_append_attribute(char ** string,int * size,char * tmp,sdp_attribute_t * attribute,char ** next_tmp)2008 static int sdp_append_attribute(char **string, int *size, char *tmp, sdp_attribute_t *attribute, char **next_tmp) {
2009 if (attribute->a_att_field == NULL)
2010 return -1;
2011
2012 tmp = __osip_sdp_append_string(string, size, tmp, "a=");
2013 tmp = __osip_sdp_append_string(string, size, tmp, attribute->a_att_field);
2014
2015 if (attribute->a_att_value != NULL) {
2016 tmp = __osip_sdp_append_string(string, size, tmp, ":");
2017 tmp = __osip_sdp_append_string(string, size, tmp, attribute->a_att_value);
2018 }
2019
2020 tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
2021
2022 *next_tmp = tmp;
2023 return OSIP_SUCCESS;
2024 }
2025
2026 /* internal facility */
sdp_append_media(char ** string,int * size,char * tmp,sdp_media_t * media,char ** next_tmp)2027 static int sdp_append_media(char **string, int *size, char *tmp, sdp_media_t *media, char **next_tmp) {
2028 int pos;
2029
2030 if (media->m_media == NULL)
2031 return -1;
2032
2033 if (media->m_port == NULL)
2034 return -1;
2035
2036 if (media->m_proto == NULL)
2037 return -1;
2038
2039 tmp = __osip_sdp_append_string(string, size, tmp, "m=");
2040 tmp = __osip_sdp_append_string(string, size, tmp, media->m_media);
2041 tmp = __osip_sdp_append_string(string, size, tmp, " ");
2042 if (media->m_port[0] == '0')
2043 tmp = __osip_sdp_append_string(string, size, tmp, "0");
2044 else
2045 tmp = __osip_sdp_append_string(string, size, tmp, media->m_port);
2046
2047 if (media->m_number_of_port != NULL) {
2048 tmp = __osip_sdp_append_string(string, size, tmp, "/");
2049 tmp = __osip_sdp_append_string(string, size, tmp, media->m_number_of_port);
2050 }
2051
2052 tmp = __osip_sdp_append_string(string, size, tmp, " ");
2053 tmp = __osip_sdp_append_string(string, size, tmp, media->m_proto);
2054 pos = 0;
2055
2056 while (!osip_list_eol(&media->m_payloads, pos)) {
2057 char *str = (char *) osip_list_get(&media->m_payloads, pos);
2058
2059 tmp = __osip_sdp_append_string(string, size, tmp, " ");
2060 tmp = __osip_sdp_append_string(string, size, tmp, str);
2061 pos++;
2062 }
2063
2064 tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
2065
2066 if (media->i_info != NULL) {
2067 tmp = __osip_sdp_append_string(string, size, tmp, "i=");
2068 tmp = __osip_sdp_append_string(string, size, tmp, media->i_info);
2069 tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
2070 }
2071
2072 pos = 0;
2073
2074 while (!osip_list_eol(&media->c_connections, pos)) {
2075 sdp_connection_t *conn = (sdp_connection_t *) osip_list_get(&media->c_connections, pos);
2076 char *next_tmp2;
2077 int i;
2078
2079 i = sdp_append_connection(string, size, tmp, conn, &next_tmp2);
2080
2081 if (i != 0)
2082 return -1;
2083
2084 tmp = next_tmp2;
2085 pos++;
2086 }
2087
2088 pos = 0;
2089
2090 while (!osip_list_eol(&media->b_bandwidths, pos)) {
2091 sdp_bandwidth_t *band = (sdp_bandwidth_t *) osip_list_get(&media->b_bandwidths, pos);
2092 char *next_tmp2;
2093 int i;
2094
2095 i = sdp_append_bandwidth(string, size, tmp, band, &next_tmp2);
2096
2097 if (i != 0)
2098 return -1;
2099
2100 tmp = next_tmp2;
2101 pos++;
2102 }
2103
2104 if (media->k_key != NULL) {
2105 char *next_tmp2;
2106 int i;
2107
2108 i = sdp_append_key(string, size, tmp, media->k_key, &next_tmp2);
2109
2110 if (i != 0)
2111 return -1;
2112
2113 tmp = next_tmp2;
2114 }
2115
2116 pos = 0;
2117
2118 while (!osip_list_eol(&media->a_attributes, pos)) {
2119 sdp_attribute_t *attr = (sdp_attribute_t *) osip_list_get(&media->a_attributes, pos);
2120 char *next_tmp2;
2121 int i;
2122
2123 i = sdp_append_attribute(string, size, tmp, attr, &next_tmp2);
2124
2125 if (i != 0)
2126 return -1;
2127
2128 tmp = next_tmp2;
2129 pos++;
2130 }
2131
2132 *next_tmp = tmp;
2133 return OSIP_SUCCESS;
2134 }
2135
sdp_message_to_str(sdp_message_t * sdp,char ** dest)2136 int sdp_message_to_str(sdp_message_t *sdp, char **dest) {
2137 int size;
2138 int pos;
2139 char *tmp;
2140 char *string;
2141
2142 *dest = NULL;
2143
2144 if (!sdp || sdp->v_version == NULL)
2145 return -1;
2146
2147 if (sdp->o_username == NULL || sdp->o_sess_id == NULL || sdp->o_sess_version == NULL || sdp->o_nettype == NULL || sdp->o_addrtype == NULL || sdp->o_addr == NULL)
2148 return -1;
2149
2150 /* RFC says "s=" is mandatory... rfc2543 (SIP) recommends to
2151 accept SDP datas without s_name... as some buggy implementations
2152 often forget it...
2153 */
2154 /* if (sdp->s_name == NULL)
2155 return -1; */
2156
2157 size = BODY_MESSAGE_MAX_SIZE;
2158 tmp = (char *) osip_malloc(size);
2159
2160 if (tmp == NULL)
2161 return OSIP_NOMEM;
2162
2163 string = tmp;
2164
2165 tmp = __osip_sdp_append_string(&string, &size, tmp, "v=");
2166 tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->v_version);
2167 tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2168 tmp = __osip_sdp_append_string(&string, &size, tmp, "o=");
2169 tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_username);
2170 tmp = __osip_sdp_append_string(&string, &size, tmp, " ");
2171 tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_sess_id);
2172 tmp = __osip_sdp_append_string(&string, &size, tmp, " ");
2173 tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_sess_version);
2174 tmp = __osip_sdp_append_string(&string, &size, tmp, " ");
2175 tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_nettype);
2176 tmp = __osip_sdp_append_string(&string, &size, tmp, " ");
2177 tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_addrtype);
2178 tmp = __osip_sdp_append_string(&string, &size, tmp, " ");
2179 tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_addr);
2180 tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2181
2182 if (sdp->s_name != NULL) {
2183 tmp = __osip_sdp_append_string(&string, &size, tmp, "s=");
2184 tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->s_name);
2185 tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2186 }
2187
2188 if (sdp->i_info != NULL) {
2189 tmp = __osip_sdp_append_string(&string, &size, tmp, "i=");
2190 tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->i_info);
2191 tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2192 }
2193
2194 if (sdp->u_uri != NULL) {
2195 tmp = __osip_sdp_append_string(&string, &size, tmp, "u=");
2196 tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->u_uri);
2197 tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2198 }
2199
2200 pos = 0;
2201
2202 while (!osip_list_eol(&sdp->e_emails, pos)) {
2203 char *email = (char *) osip_list_get(&sdp->e_emails, pos);
2204
2205 tmp = __osip_sdp_append_string(&string, &size, tmp, "e=");
2206 tmp = __osip_sdp_append_string(&string, &size, tmp, email);
2207 tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2208 pos++;
2209 }
2210
2211 pos = 0;
2212
2213 while (!osip_list_eol(&sdp->p_phones, pos)) {
2214 char *phone = (char *) osip_list_get(&sdp->p_phones, pos);
2215
2216 tmp = __osip_sdp_append_string(&string, &size, tmp, "p=");
2217 tmp = __osip_sdp_append_string(&string, &size, tmp, phone);
2218 tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2219 pos++;
2220 }
2221
2222 if (sdp->c_connection != NULL) {
2223 char *next_tmp;
2224 int i;
2225
2226 i = sdp_append_connection(&string, &size, tmp, sdp->c_connection, &next_tmp);
2227
2228 if (i != 0) {
2229 osip_free(string);
2230 return -1;
2231 }
2232
2233 tmp = next_tmp;
2234 }
2235
2236 pos = 0;
2237
2238 while (!osip_list_eol(&sdp->b_bandwidths, pos)) {
2239 sdp_bandwidth_t *header = (sdp_bandwidth_t *) osip_list_get(&sdp->b_bandwidths, pos);
2240 char *next_tmp;
2241 int i;
2242
2243 i = sdp_append_bandwidth(&string, &size, tmp, header, &next_tmp);
2244
2245 if (i != 0) {
2246 osip_free(string);
2247 return -1;
2248 }
2249
2250 tmp = next_tmp;
2251 pos++;
2252 }
2253
2254 pos = 0;
2255
2256 while (!osip_list_eol(&sdp->t_descrs, pos)) {
2257 sdp_time_descr_t *header = (sdp_time_descr_t *) osip_list_get(&sdp->t_descrs, pos);
2258 char *next_tmp;
2259 int i;
2260
2261 i = sdp_append_time_descr(&string, &size, tmp, header, &next_tmp);
2262
2263 if (i != 0) {
2264 osip_free(string);
2265 return -1;
2266 }
2267
2268 tmp = next_tmp;
2269 pos++;
2270 }
2271
2272 if (sdp->z_adjustments != NULL) {
2273 tmp = __osip_sdp_append_string(&string, &size, tmp, "z=");
2274 tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->z_adjustments);
2275 tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2276 }
2277
2278 if (sdp->k_key != NULL) {
2279 char *next_tmp;
2280 int i;
2281
2282 i = sdp_append_key(&string, &size, tmp, sdp->k_key, &next_tmp);
2283
2284 if (i != 0) {
2285 osip_free(string);
2286 return -1;
2287 }
2288
2289 tmp = next_tmp;
2290 }
2291
2292 pos = 0;
2293
2294 while (!osip_list_eol(&sdp->a_attributes, pos)) {
2295 sdp_attribute_t *header = (sdp_attribute_t *) osip_list_get(&sdp->a_attributes, pos);
2296 char *next_tmp;
2297 int i;
2298
2299 i = sdp_append_attribute(&string, &size, tmp, header, &next_tmp);
2300
2301 if (i != 0) {
2302 osip_free(string);
2303 return -1;
2304 }
2305
2306 tmp = next_tmp;
2307 pos++;
2308 }
2309
2310 pos = 0;
2311
2312 while (!osip_list_eol(&sdp->m_medias, pos)) {
2313 sdp_media_t *header = (sdp_media_t *) osip_list_get(&sdp->m_medias, pos);
2314 char *next_tmp;
2315 int i;
2316
2317 i = sdp_append_media(&string, &size, tmp, header, &next_tmp);
2318
2319 if (i != 0) {
2320 osip_free(string);
2321 return -1;
2322 }
2323
2324 tmp = next_tmp;
2325 pos++;
2326 }
2327
2328 *dest = string;
2329 return OSIP_SUCCESS;
2330 }
2331
sdp_message_free(sdp_message_t * sdp)2332 void sdp_message_free(sdp_message_t *sdp) {
2333 if (sdp == NULL)
2334 return;
2335
2336 osip_free(sdp->v_version);
2337 osip_free(sdp->o_username);
2338 osip_free(sdp->o_sess_id);
2339 osip_free(sdp->o_sess_version);
2340 osip_free(sdp->o_nettype);
2341 osip_free(sdp->o_addrtype);
2342 osip_free(sdp->o_addr);
2343 osip_free(sdp->s_name);
2344 osip_free(sdp->i_info);
2345 osip_free(sdp->u_uri);
2346
2347 osip_list_ofchar_free(&sdp->e_emails);
2348
2349 osip_list_ofchar_free(&sdp->p_phones);
2350
2351 sdp_connection_free(sdp->c_connection);
2352
2353 osip_list_special_free(&sdp->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
2354
2355 osip_list_special_free(&sdp->t_descrs, (void (*)(void *)) & sdp_time_descr_free);
2356
2357 osip_free(sdp->z_adjustments);
2358 sdp_key_free(sdp->k_key);
2359
2360 osip_list_special_free(&sdp->a_attributes, (void (*)(void *)) & sdp_attribute_free);
2361
2362 osip_list_special_free(&sdp->m_medias, (void (*)(void *)) & sdp_media_free);
2363
2364 osip_free(sdp);
2365 }
2366
sdp_message_clone(sdp_message_t * sdp,sdp_message_t ** dest)2367 int sdp_message_clone(sdp_message_t *sdp, sdp_message_t **dest) {
2368 int i;
2369 char *body;
2370
2371 i = sdp_message_init(dest);
2372
2373 if (i != 0)
2374 return -1;
2375
2376 i = sdp_message_to_str(sdp, &body);
2377
2378 if (i != 0)
2379 goto error_sc1;
2380
2381 i = sdp_message_parse(*dest, body);
2382 osip_free(body);
2383
2384 if (i != 0)
2385 goto error_sc1;
2386
2387 return OSIP_SUCCESS;
2388
2389 error_sc1:
2390 sdp_message_free(*dest);
2391 return -1;
2392 }
2393