2 The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
3 Copyright (C) 2001,2002,2003 Aymeric MOIZARD jack@atosc.org
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.
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.
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
20 #include <osipparser2/osip_const.h>
21 #include <osipparser2/sdp_message.h>
22 #include <osipparser2/osip_port.h>
27 #define ERR_ERROR -1 /* bad header */
28 #define ERR_DISCARD 0 /* wrong header */
29 #define WF 1 /* well formed header */
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);
47 static int sdp_append_media (char *string, int size, char *tmp,
48 sdp_media_t * media, char **next_tmp);
49 static int sdp_append_attribute (char *string, int size, char *tmp,
50 sdp_attribute_t * attribute,
52 static int sdp_append_key (char *string, int size, char *tmp, sdp_key_t * key,
54 static int sdp_append_time_descr (char *string, int size, char *tmp,
55 sdp_time_descr_t * time_descr,
57 static int sdp_append_bandwidth (char *string, int size, char *tmp,
58 sdp_bandwidth_t * bandwidth,
60 static int sdp_append_connection (char *string, int size, char *tmp,
61 sdp_connection_t * conn, char **next_tmp);
64 sdp_bandwidth_init (sdp_bandwidth_t ** b)
66 *b = (sdp_bandwidth_t *) osip_malloc (sizeof (sdp_bandwidth_t));
69 (*b)->b_bwtype = NULL;
70 (*b)->b_bandwidth = NULL;
75 sdp_bandwidth_free (sdp_bandwidth_t * b)
79 osip_free (b->b_bwtype);
80 osip_free (b->b_bandwidth);
85 sdp_time_descr_init (sdp_time_descr_t ** td)
87 *td = (sdp_time_descr_t *) osip_malloc (sizeof (sdp_time_descr_t));
90 (*td)->t_start_time = NULL;
91 (*td)->t_stop_time = NULL;
92 (*td)->r_repeats = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
93 osip_list_init ((*td)->r_repeats);
98 sdp_time_descr_free (sdp_time_descr_t * td)
102 osip_free (td->t_start_time);
103 osip_free (td->t_stop_time);
104 osip_list_ofchar_free (td->r_repeats);
109 sdp_key_init (sdp_key_t ** key)
111 *key = (sdp_key_t *) osip_malloc (sizeof (sdp_key_t));
114 (*key)->k_keytype = NULL;
115 (*key)->k_keydata = NULL;
120 sdp_key_free (sdp_key_t * key)
124 osip_free (key->k_keytype);
125 osip_free (key->k_keydata);
130 sdp_attribute_init (sdp_attribute_t ** attribute)
132 *attribute = (sdp_attribute_t *) osip_malloc (sizeof (sdp_attribute_t));
133 if (*attribute == NULL)
135 (*attribute)->a_att_field = NULL;
136 (*attribute)->a_att_value = NULL;
141 sdp_attribute_free (sdp_attribute_t * attribute)
143 if (attribute == NULL)
145 osip_free (attribute->a_att_field);
146 osip_free (attribute->a_att_value);
147 osip_free (attribute);
151 sdp_connection_init (sdp_connection_t ** connection)
153 *connection = (sdp_connection_t *) osip_malloc (sizeof (sdp_connection_t));
154 if (*connection == NULL)
156 (*connection)->c_nettype = NULL;
157 (*connection)->c_addrtype = NULL;
158 (*connection)->c_addr = NULL;
159 (*connection)->c_addr_multicast_ttl = NULL;
160 (*connection)->c_addr_multicast_int = NULL;
165 sdp_connection_free (sdp_connection_t * connection)
167 if (connection == NULL)
169 osip_free (connection->c_nettype);
170 osip_free (connection->c_addrtype);
171 osip_free (connection->c_addr);
172 osip_free (connection->c_addr_multicast_ttl);
173 osip_free (connection->c_addr_multicast_int);
174 osip_free (connection);
178 sdp_media_init (sdp_media_t ** media)
180 *media = (sdp_media_t *) osip_malloc (sizeof (sdp_media_t));
183 (*media)->m_media = NULL;
184 (*media)->m_port = NULL;
185 (*media)->m_number_of_port = NULL;
186 (*media)->m_proto = NULL;
187 (*media)->m_payloads = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
188 osip_list_init ((*media)->m_payloads);
189 (*media)->i_info = NULL;
190 (*media)->c_connections =
191 (osip_list_t *) osip_malloc (sizeof (osip_list_t));
192 osip_list_init ((*media)->c_connections);
193 (*media)->b_bandwidths = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
194 osip_list_init ((*media)->b_bandwidths);
195 (*media)->a_attributes = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
196 osip_list_init ((*media)->a_attributes);
197 (*media)->k_key = NULL;
202 sdp_media_free (sdp_media_t * media)
206 osip_free (media->m_media);
207 osip_free (media->m_port);
208 osip_free (media->m_number_of_port);
209 osip_free (media->m_proto);
210 osip_list_ofchar_free (media->m_payloads);
211 osip_free (media->i_info);
212 osip_list_special_free (media->c_connections,
213 (void *(*)(void *)) &sdp_connection_free);
214 osip_list_special_free (media->b_bandwidths,
215 (void *(*)(void *)) &sdp_bandwidth_free);
216 osip_list_special_free (media->a_attributes,
217 (void *(*)(void *)) &sdp_attribute_free);
218 sdp_key_free (media->k_key);
222 /* to be changed to sdp_message_init(sdp_message_t **dest) */
224 sdp_message_init (sdp_message_t ** sdp)
226 (*sdp) = (sdp_message_t *) osip_malloc (sizeof (sdp_message_t));
230 (*sdp)->v_version = NULL;
231 (*sdp)->o_username = NULL;
232 (*sdp)->o_sess_id = NULL;
233 (*sdp)->o_sess_version = NULL;
234 (*sdp)->o_nettype = NULL;
235 (*sdp)->o_addrtype = NULL;
236 (*sdp)->o_addr = NULL;
237 (*sdp)->s_name = NULL;
238 (*sdp)->i_info = NULL;
239 (*sdp)->u_uri = NULL;
241 (*sdp)->e_emails = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
242 if ((*sdp)->e_emails == NULL)
244 osip_list_init ((*sdp)->e_emails);
246 (*sdp)->p_phones = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
247 if ((*sdp)->p_phones == NULL)
249 osip_list_init ((*sdp)->p_phones);
251 (*sdp)->c_connection = NULL;
253 (*sdp)->b_bandwidths = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
254 if ((*sdp)->b_bandwidths == NULL)
256 osip_list_init ((*sdp)->b_bandwidths);
258 (*sdp)->t_descrs = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
259 if ((*sdp)->t_descrs == NULL)
261 osip_list_init ((*sdp)->t_descrs);
263 (*sdp)->z_adjustments = NULL;
264 (*sdp)->k_key = NULL;
266 (*sdp)->a_attributes = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
267 if ((*sdp)->a_attributes == NULL)
269 osip_list_init ((*sdp)->a_attributes);
271 (*sdp)->m_medias = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
272 if ((*sdp)->m_medias == NULL)
274 osip_list_init ((*sdp)->m_medias);
279 sdp_message_parse_v (sdp_message_t * sdp, char *buf, char **next)
287 while ((*equal != '=') && (*equal != '\0'))
295 /* check if header is "v" */
296 if (equal[-1] != 'v')
301 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
305 if (crlf == equal + 1)
306 return ERR_ERROR; /*v=\r ?? bad header */
307 sdp->v_version = osip_malloc (crlf - (equal + 1) + 1);
308 osip_strncpy (sdp->v_version, equal + 1, crlf - (equal + 1));
318 sdp_message_parse_o (sdp_message_t * sdp, char *buf, char **next)
329 while ((*equal != '=') && (*equal != '\0'))
334 /* check if header is "o" */
335 if (equal[-1] != 'o')
340 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
344 if (crlf == equal + 1)
345 return ERR_ERROR; /* o=\r ?? bad header */
348 /* o=username sess-id sess-version nettype addrtype addr */
350 /* useranme can contain any char (ascii) except "space" and CRLF */
351 i = __osip_set_next_token (&(sdp->o_username), tmp, ' ', &tmp_next);
356 /* sess_id contains only numeric characters */
357 i = __osip_set_next_token (&(sdp->o_sess_id), tmp, ' ', &tmp_next);
362 /* sess_id contains only numeric characters */
363 i = __osip_set_next_token (&(sdp->o_sess_version), tmp, ' ', &tmp_next);
368 /* nettype is "IN" but will surely be extented!!! assume it's some alpha-char */
369 i = __osip_set_next_token (&(sdp->o_nettype), tmp, ' ', &tmp_next);
374 /* addrtype is "IP4" or "IP6" but will surely be extented!!! */
375 i = __osip_set_next_token (&(sdp->o_addrtype), tmp, ' ', &tmp_next);
380 /* addr is "IP4" or "IP6" but will surely be extented!!! */
381 i = __osip_set_next_token (&(sdp->o_addr), tmp, '\r', &tmp_next);
383 { /* could it be "\n" only??? rfc says to accept CR or LF instead of CRLF */
384 i = __osip_set_next_token (&(sdp->o_addr), tmp, '\n', &tmp_next);
397 sdp_message_parse_s (sdp_message_t * sdp, char *buf, char **next)
405 while ((*equal != '=') && (*equal != '\0'))
410 /* check if header is "s" */
411 if (equal[-1] != 's')
416 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
420 if (crlf == equal + 1)
421 return ERR_ERROR; /* o=\r ?? bad header */
425 /* text is interpreted as ISO-10646 UTF8! */
426 /* using ISO 8859-1 requires "a=charset:ISO-8859-1 */
427 sdp->s_name = osip_malloc (crlf - (equal + 1) + 1);
428 osip_strncpy (sdp->s_name, equal + 1, crlf - (equal + 1));
438 sdp_message_parse_i (sdp_message_t * sdp, char *buf, char **next)
448 while ((*equal != '=') && (*equal != '\0'))
453 /* check if header is "i" */
454 if (equal[-1] != 'i')
459 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
463 if (crlf == equal + 1)
464 return ERR_ERROR; /* o=\r ?? bad header */
468 /* text is interpreted as ISO-10646 UTF8! */
469 /* using ISO 8859-1 requires "a=charset:ISO-8859-1 */
470 i_info = osip_malloc (crlf - (equal + 1) + 1);
471 osip_strncpy (i_info, equal + 1, crlf - (equal + 1));
473 /* add the bandwidth at the correct place:
474 if there is no media line yet, then the "b=" is the
477 i = osip_list_size (sdp->m_medias);
479 sdp->i_info = i_info;
482 sdp_media_t *last_sdp_media =
483 (sdp_media_t *) osip_list_get (sdp->m_medias, i - 1);
484 last_sdp_media->i_info = i_info;
495 sdp_message_parse_u (sdp_message_t * sdp, char *buf, char **next)
503 while ((*equal != '=') && (*equal != '\0'))
508 /* check if header is "u" */
509 if (equal[-1] != 'u')
514 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
518 if (crlf == equal + 1)
519 return ERR_ERROR; /* u=\r ?? bad header */
522 /* we assume this is a URI */
523 sdp->u_uri = osip_malloc (crlf - (equal + 1) + 1);
524 osip_strncpy (sdp->u_uri, equal + 1, crlf - (equal + 1));
534 sdp_message_parse_e (sdp_message_t * sdp, char *buf, char **next)
543 while ((*equal != '=') && (*equal != '\0'))
548 /* check if header is "e" */
549 if (equal[-1] != 'e')
554 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
558 if (crlf == equal + 1)
559 return ERR_ERROR; /* e=\r ?? bad header */
562 /* we assume this is an EMAIL-ADDRESS */
563 e_email = osip_malloc (crlf - (equal + 1) + 1);
564 osip_strncpy (e_email, equal + 1, crlf - (equal + 1));
566 osip_list_add (sdp->e_emails, e_email, -1);
576 sdp_message_parse_p (sdp_message_t * sdp, char *buf, char **next)
585 while ((*equal != '=') && (*equal != '\0'))
590 /* check if header is "p" */
591 if (equal[-1] != 'p')
596 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
600 if (crlf == equal + 1)
601 return ERR_ERROR; /* p=\r ?? bad header */
604 /* we assume this is an EMAIL-ADDRESS */
605 p_phone = osip_malloc (crlf - (equal + 1) + 1);
606 osip_strncpy (p_phone, equal + 1, crlf - (equal + 1));
608 osip_list_add (sdp->p_phones, p_phone, -1);
618 sdp_message_parse_c (sdp_message_t * sdp, char *buf, char **next)
624 sdp_connection_t *c_header;
630 while ((*equal != '=') && (*equal != '\0'))
635 /* check if header is "c" */
636 if (equal[-1] != 'c')
641 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
645 if (crlf == equal + 1)
646 return ERR_ERROR; /* c=\r ?? bad header */
649 i = sdp_connection_init (&c_header);
652 /* c=nettype addrtype (multicastaddr | addr) */
654 /* nettype is "IN" and will be extended */
655 i = __osip_set_next_token (&(c_header->c_nettype), tmp, ' ', &tmp_next);
660 /* nettype is "IP4" or "IP6" and will be extended */
661 i = __osip_set_next_token (&(c_header->c_addrtype), tmp, ' ', &tmp_next);
666 /* there we have a multicast or unicast address */
667 /* multicast can be ip/ttl [/integer] */
668 /* unicast is FQDN or ip (no ttl, no integer) */
672 char *slash = strchr (tmp, '/');
674 if (slash != NULL && slash < crlf) /* it's a multicast address! */
676 i = __osip_set_next_token (&(c_header->c_addr), tmp, '/', &tmp_next);
680 slash = strchr (slash + 1, '/');
681 if (slash != NULL && slash < crlf) /* optionnal integer is there! */
684 __osip_set_next_token (&(c_header->c_addr_multicast_ttl), tmp,
690 __osip_set_next_token (&(c_header->c_addr_multicast_int), tmp,
695 __osip_set_next_token (&(c_header->c_addr_multicast_int),
696 tmp, '\n', &tmp_next);
699 sdp_connection_free (c_header);
707 __osip_set_next_token (&(c_header->c_addr_multicast_ttl), tmp,
712 __osip_set_next_token (&(c_header->c_addr_multicast_ttl),
713 tmp, '\n', &tmp_next);
716 sdp_connection_free (c_header);
724 /* in this case, we have a unicast address */
725 i = __osip_set_next_token (&(c_header->c_addr), tmp, '\r', &tmp_next);
729 __osip_set_next_token (&(c_header->c_addr), tmp, '\n',
733 sdp_connection_free (c_header);
740 /* add the connection at the correct place:
741 if there is no media line yet, then the "c=" is the
744 i = osip_list_size (sdp->m_medias);
746 sdp->c_connection = c_header;
749 sdp_media_t *last_sdp_media =
750 (sdp_media_t *) osip_list_get (sdp->m_medias, i - 1);
751 osip_list_add (last_sdp_media->c_connections, c_header, -1);
761 sdp_message_parse_b (sdp_message_t * sdp, char *buf, char **next)
768 sdp_bandwidth_t *b_header;
773 while ((*equal != '=') && (*equal != '\0'))
778 /* check if header is "b" */
779 if (equal[-1] != 'b')
784 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
788 if (crlf == equal + 1)
789 return ERR_ERROR; /* b=\r ?? bad header */
792 /* b = bwtype: bandwidth */
793 i = sdp_bandwidth_init (&b_header);
797 /* bwtype is alpha-numeric */
798 i = __osip_set_next_token (&(b_header->b_bwtype), tmp, ':', &tmp_next);
803 i = __osip_set_next_token (&(b_header->b_bandwidth), tmp, '\r', &tmp_next);
807 __osip_set_next_token (&(b_header->b_bandwidth), tmp, '\n',
811 sdp_bandwidth_free (b_header);
816 /* add the bandwidth at the correct place:
817 if there is no media line yet, then the "b=" is the
820 i = osip_list_size (sdp->m_medias);
822 osip_list_add (sdp->b_bandwidths, b_header, -1);
825 sdp_media_t *last_sdp_media =
826 (sdp_media_t *) osip_list_get (sdp->m_medias, i - 1);
827 osip_list_add (last_sdp_media->b_bandwidths, b_header, -1);
838 sdp_message_parse_t (sdp_message_t * sdp, char *buf, char **next)
845 sdp_time_descr_t *t_header;
850 while ((*equal != '=') && (*equal != '\0'))
855 /* check if header is "t" */
856 if (equal[-1] != 't')
861 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
865 if (crlf == equal + 1)
866 return ERR_ERROR; /* t=\r ?? bad header */
869 /* t = start_time stop_time */
870 i = sdp_time_descr_init (&t_header);
874 i = __osip_set_next_token (&(t_header->t_start_time), tmp, ' ', &tmp_next);
877 sdp_time_descr_free (t_header);
882 i = __osip_set_next_token (&(t_header->t_stop_time), tmp, '\r', &tmp_next);
886 __osip_set_next_token (&(t_header->t_stop_time), tmp, '\n',
890 sdp_time_descr_free (t_header);
895 /* add the new time_description header */
896 osip_list_add (sdp->t_descrs, t_header, -1);
906 sdp_message_parse_r (sdp_message_t * sdp, char *buf, char **next)
912 sdp_time_descr_t *t_descr;
917 while ((*equal != '=') && (*equal != '\0'))
922 /* check if header is "r" */
923 if (equal[-1] != 'r')
926 index = osip_list_size (sdp->t_descrs);
928 return ERR_ERROR; /* r field can't come alone! */
932 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
936 if (crlf == equal + 1)
937 return ERR_ERROR; /* r=\r ?? bad header */
939 /* r=far too complexe and somewhat useless... I don't parse it! */
940 r_header = osip_malloc (crlf - (equal + 1) + 1);
941 osip_strncpy (r_header, equal + 1, crlf - (equal + 1));
943 /* r field carry information for the last "t" field */
944 t_descr = (sdp_time_descr_t *) osip_list_get (sdp->t_descrs, index - 1);
945 osip_list_add (t_descr->r_repeats, r_header, -1);
955 sdp_message_parse_z (sdp_message_t * sdp, char *buf, char **next)
964 while ((*equal != '=') && (*equal != '\0'))
969 /* check if header is "z" */
970 if (equal[-1] != 'z')
975 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
979 if (crlf == equal + 1)
980 return ERR_ERROR; /* z=\r ?? bad header */
982 /* z=somewhat useless... I don't parse it! */
983 z_header = osip_malloc (crlf - (equal + 1) + 1);
984 osip_strncpy (z_header, equal + 1, crlf - (equal + 1));
986 sdp->z_adjustments = z_header;
996 sdp_message_parse_k (sdp_message_t * sdp, char *buf, char **next)
1002 sdp_key_t *k_header;
1009 while ((*equal != '=') && (*equal != '\0'))
1014 /* check if header is "k" */
1015 if (equal[-1] != 'k')
1020 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1024 if (crlf == equal + 1)
1025 return ERR_ERROR; /* k=\r ?? bad header */
1029 i = sdp_key_init (&k_header);
1032 /* k=key-type[:key-data] */
1034 /* is there any key-data? */
1035 colon = strchr (equal + 1, ':');
1036 if ((colon != NULL) && (colon < crlf))
1038 /* att-field is alpha-numeric */
1039 i = __osip_set_next_token (&(k_header->k_keytype), tmp, ':', &tmp_next);
1042 sdp_key_free (k_header);
1048 __osip_set_next_token (&(k_header->k_keydata), tmp, '\r', &tmp_next);
1052 __osip_set_next_token (&(k_header->k_keydata), tmp, '\n',
1056 sdp_key_free (k_header);
1064 __osip_set_next_token (&(k_header->k_keytype), tmp, '\r', &tmp_next);
1068 __osip_set_next_token (&(k_header->k_keytype), tmp, '\n',
1072 sdp_key_free (k_header);
1078 /* add the key at the correct place:
1079 if there is no media line yet, then the "k=" is the
1082 i = osip_list_size (sdp->m_medias);
1084 sdp->k_key = k_header;
1087 sdp_media_t *last_sdp_media =
1088 (sdp_media_t *) osip_list_get (sdp->m_medias, i - 1);
1089 last_sdp_media->k_key = k_header;
1092 if (crlf[1] == '\n')
1100 sdp_message_parse_a (sdp_message_t * sdp, char *buf, char **next)
1107 sdp_attribute_t *a_attribute;
1113 while ((*equal != '=') && (*equal != '\0'))
1118 /* check if header is "a" */
1119 if (equal[-1] != 'a')
1124 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1128 if (crlf == equal + 1)
1129 return ERR_ERROR; /* a=\r ?? bad header */
1133 i = sdp_attribute_init (&a_attribute);
1137 /* a=att-field[:att-value] */
1139 /* is there any att-value? */
1140 colon = strchr (equal + 1, ':');
1141 if ((colon != NULL) && (colon < crlf))
1143 /* att-field is alpha-numeric */
1145 __osip_set_next_token (&(a_attribute->a_att_field), tmp, ':',
1149 sdp_attribute_free (a_attribute);
1155 __osip_set_next_token (&(a_attribute->a_att_value), tmp, '\r',
1160 __osip_set_next_token (&(a_attribute->a_att_value), tmp, '\n',
1164 sdp_attribute_free (a_attribute);
1172 __osip_set_next_token (&(a_attribute->a_att_field), tmp, '\r',
1177 __osip_set_next_token (&(a_attribute->a_att_field), tmp, '\n',
1181 sdp_attribute_free (a_attribute);
1187 /* add the attribute at the correct place:
1188 if there is no media line yet, then the "a=" is the
1191 i = osip_list_size (sdp->m_medias);
1193 osip_list_add (sdp->a_attributes, a_attribute, -1);
1196 sdp_media_t *last_sdp_media =
1197 (sdp_media_t *) osip_list_get (sdp->m_medias, i - 1);
1198 osip_list_add (last_sdp_media->a_attributes, a_attribute, -1);
1201 if (crlf[1] == '\n')
1209 sdp_message_parse_m (sdp_message_t * sdp, char *buf, char **next)
1216 sdp_media_t *m_header;
1223 while ((*equal != '=') && (*equal != '\0'))
1228 /* check if header is "m" */
1229 if (equal[-1] != 'm')
1234 while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1238 if (crlf == equal + 1)
1239 return ERR_ERROR; /* a=\r ?? bad header */
1243 i = sdp_media_init (&m_header);
1247 /* m=media port ["/"integer] proto *(payload_number) */
1249 /* media is "audio" "video" "application" "data" or other... */
1250 i = __osip_set_next_token (&(m_header->m_media), tmp, ' ', &tmp_next);
1253 sdp_media_free (m_header);
1258 slash = strchr (tmp, '/');
1259 space = strchr (tmp, ' ');
1260 if (space == NULL) /* not possible! */
1262 sdp_media_free (m_header);
1265 if ((slash != NULL) && (slash < space))
1266 { /* a number of port is specified! */
1267 i = __osip_set_next_token (&(m_header->m_port), tmp, '/', &tmp_next);
1270 sdp_media_free (m_header);
1276 __osip_set_next_token (&(m_header->m_number_of_port), tmp, ' ',
1280 sdp_media_free (m_header);
1287 i = __osip_set_next_token (&(m_header->m_port), tmp, ' ', &tmp_next);
1290 sdp_media_free (m_header);
1296 i = __osip_set_next_token (&(m_header->m_proto), tmp, ' ', &tmp_next);
1299 sdp_media_free (m_header);
1306 int more_space_before_crlf;
1308 space = strchr (tmp + 1, ' ');
1310 more_space_before_crlf = 1;
1311 else if ((space != NULL) && (space > crlf))
1312 more_space_before_crlf = 1;
1314 more_space_before_crlf = 0;
1315 while (more_space_before_crlf == 0)
1317 i = __osip_set_next_token (&str, tmp, ' ', &tmp_next);
1320 sdp_media_free (m_header);
1324 osip_list_add (m_header->m_payloads, str, -1);
1326 space = strchr (tmp + 1, ' ');
1328 more_space_before_crlf = 1;
1329 else if ((space != NULL) && (space > crlf))
1330 more_space_before_crlf = 1;
1332 more_space_before_crlf = 0;
1334 if (tmp_next < crlf)
1335 { /* tmp_next is still less than clrf: no space */
1336 i = __osip_set_next_token (&str, tmp, '\r', &tmp_next);
1339 i = __osip_set_next_token (&str, tmp, '\n', &tmp_next);
1342 sdp_media_free (m_header);
1346 osip_list_add (m_header->m_payloads, str, -1);
1350 osip_list_add (sdp->m_medias, m_header, -1);
1352 if (crlf[1] == '\n')
1361 sdp_message_parse (sdp_message_t * sdp, const char *buf)
1364 /* In SDP, headers must be in the right order */
1365 /* This is a simple example
1367 o=user1 53655765 2353687637 IN IP4 128.3.4.5
1369 i=Discussion of Mbone Engineering Issues
1370 e=mbone@somewhere.com
1371 c=IN IP4 224.2.0.1/127
1373 m=audio 3456 RTP/AVP 0
1374 a=rtpmap:0 PCMU/8000
1383 i = sdp_message_parse_v (sdp, ptr, &next_buf);
1384 if (i == -1) /* header is bad */
1386 else if (0 == i) /* header is not "v" */
1390 /* adtech phone use the wrong ordering and place "s" before "o" */
1391 i = sdp_message_parse_s (sdp, ptr, &next_buf);
1392 if (i == -1) /* header is bad */
1394 /* else if (0==i) header is not "s" */
1395 /* else ADTECH PHONE DETECTED */
1401 i = sdp_message_parse_o (sdp, ptr, &next_buf);
1402 if (i == -1) /* header is bad */
1404 else if (0 == i) /* header is not "o" */
1408 i = sdp_message_parse_s (sdp, ptr, &next_buf);
1409 if (i == -1) /* header is bad */
1411 else if (0 == i) /* header is not "s" */
1414 OSIP_TRACE (osip_trace
1415 (__FILE__, __LINE__, OSIP_INFO4, NULL,
1416 "The \"s\" parameter is mandatory, but this packet does not contain any! - anyway, we don't mind about it.\n"));
1420 i = sdp_message_parse_i (sdp, ptr, &next_buf);
1421 if (i == -1) /* header is bad */
1425 i = sdp_message_parse_u (sdp, ptr, &next_buf);
1426 if (i == -1) /* header is bad */
1433 i = sdp_message_parse_e (sdp, ptr, &next_buf);
1434 if (i == -1) /* header is bad */
1441 i = sdp_message_parse_p (sdp, ptr, &next_buf);
1442 if (i == -1) /* header is bad */
1447 /* rfc2327: there should be at least of email or phone number! */
1448 if (osip_list_size (sdp->e_emails) == 0
1449 && osip_list_size (sdp->p_phones) == 0)
1451 OSIP_TRACE (osip_trace
1452 (__FILE__, __LINE__, OSIP_INFO4, NULL,
1453 "The rfc2327 says there should be at least an email or a phone header!- anyway, we don't mind about it.\n"));
1456 i = sdp_message_parse_c (sdp, ptr, &next_buf);
1457 if (i == -1) /* header is bad */
1464 i = sdp_message_parse_b (sdp, ptr, &next_buf);
1465 if (i == -1) /* header is bad */
1470 /* 1 or more "t" header + 0 or more "r" header for each "t" header */
1471 i = sdp_message_parse_t (sdp, ptr, &next_buf);
1472 if (i == -1) /* header is bad */
1474 else if (i == ERR_DISCARD)
1475 return -1; /* t is mandatory */
1478 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1482 while (i == 1) /* is a "r" header */
1484 i = sdp_message_parse_r (sdp, ptr, &next_buf);
1485 if (i == -1) /* header is bad */
1488 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1495 int more_t_header = 1;
1497 i = sdp_message_parse_t (sdp, ptr, &next_buf);
1498 if (i == -1) /* header is bad */
1502 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1505 while (more_t_header == 1)
1508 while (i == 1) /* is a "r" header */
1510 i = sdp_message_parse_r (sdp, ptr, &next_buf);
1511 if (i == -1) /* header is bad */
1514 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1518 i = sdp_message_parse_t (sdp, ptr, &next_buf);
1519 if (i == -1) /* header is bad */
1521 else if (i == ERR_DISCARD)
1524 more_t_header = 1; /* no more "t" headers */
1526 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1531 i = sdp_message_parse_z (sdp, ptr, &next_buf);
1532 if (i == -1) /* header is bad */
1535 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1538 i = sdp_message_parse_k (sdp, ptr, &next_buf);
1539 if (i == -1) /* header is bad */
1542 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1545 /* 0 or more "a" header */
1547 while (i == 1) /* no more "a" header */
1549 i = sdp_message_parse_a (sdp, ptr, &next_buf);
1550 if (i == -1) /* header is bad */
1553 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1556 /* 0 or more media headers */
1558 int more_m_header = 1;
1560 while (more_m_header == 1)
1562 more_m_header = sdp_message_parse_m (sdp, ptr, &next_buf);
1563 if (more_m_header == -1) /* header is bad */
1566 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1569 i = sdp_message_parse_i (sdp, ptr, &next_buf);
1570 if (i == -1) /* header is bad */
1573 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1579 i = sdp_message_parse_c (sdp, ptr, &next_buf);
1580 if (i == -1) /* header is bad */
1583 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1590 i = sdp_message_parse_b (sdp, ptr, &next_buf);
1591 if (i == -1) /* header is bad */
1594 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1597 i = sdp_message_parse_k (sdp, ptr, &next_buf);
1598 if (i == -1) /* header is bad */
1601 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1603 /* 0 or more a headers */
1607 i = sdp_message_parse_a (sdp, ptr, &next_buf);
1608 if (i == -1) /* header is bad */
1611 if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1621 sdp_append_connection (char *string, int size, char *tmp,
1622 sdp_connection_t * conn, char **next_tmp)
1624 if (conn->c_nettype == NULL)
1626 if (conn->c_addrtype == NULL)
1628 if (conn->c_addr == NULL)
1631 tmp = __osip_sdp_append_string (string, size, tmp, "c=");
1632 tmp = __osip_sdp_append_string (string, size, tmp, conn->c_nettype);
1633 tmp = __osip_sdp_append_string (string, size, tmp, " ");
1634 tmp = __osip_sdp_append_string (string, size, tmp, conn->c_addrtype);
1635 tmp = __osip_sdp_append_string (string, size, tmp, " ");
1636 tmp = __osip_sdp_append_string (string, size, tmp, conn->c_addr);
1637 if (conn->c_addr_multicast_ttl != NULL)
1639 tmp = __osip_sdp_append_string (string, size, tmp, "/");
1641 __osip_sdp_append_string (string, size, tmp,
1642 conn->c_addr_multicast_ttl);
1644 if (conn->c_addr_multicast_int != NULL)
1646 tmp = __osip_sdp_append_string (string, size, tmp, "/");
1648 __osip_sdp_append_string (string, size, tmp,
1649 conn->c_addr_multicast_int);
1651 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1657 sdp_append_bandwidth (char *string, int size, char *tmp,
1658 sdp_bandwidth_t * bandwidth, char **next_tmp)
1660 if (bandwidth->b_bwtype == NULL)
1662 if (bandwidth->b_bandwidth == NULL)
1665 tmp = __osip_sdp_append_string (string, size, tmp, "b=");
1666 tmp = __osip_sdp_append_string (string, size, tmp, bandwidth->b_bwtype);
1667 tmp = __osip_sdp_append_string (string, size, tmp, ":");
1668 tmp = __osip_sdp_append_string (string, size, tmp, bandwidth->b_bandwidth);
1669 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1676 sdp_append_time_descr (char *string, int size, char *tmp,
1677 sdp_time_descr_t * time_descr, char **next_tmp)
1681 if (time_descr->t_start_time == NULL)
1683 if (time_descr->t_stop_time == NULL)
1687 tmp = __osip_sdp_append_string (string, size, tmp, "t=");
1689 __osip_sdp_append_string (string, size, tmp, time_descr->t_start_time);
1690 tmp = __osip_sdp_append_string (string, size, tmp, " ");
1691 tmp = __osip_sdp_append_string (string, size, tmp, time_descr->t_stop_time);
1693 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1696 while (!osip_list_eol (time_descr->r_repeats, pos))
1698 char *str = (char *) osip_list_get (time_descr->r_repeats, pos);
1700 tmp = __osip_sdp_append_string (string, size, tmp, "r=");
1701 tmp = __osip_sdp_append_string (string, size, tmp, str);
1702 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1711 sdp_append_key (char *string, int size, char *tmp, sdp_key_t * key,
1714 if (key->k_keytype == NULL)
1717 tmp = __osip_sdp_append_string (string, size, tmp, "k=");
1718 tmp = __osip_sdp_append_string (string, size, tmp, key->k_keytype);
1719 if (key->k_keydata != NULL)
1721 tmp = __osip_sdp_append_string (string, size, tmp, ":");
1722 tmp = __osip_sdp_append_string (string, size, tmp, key->k_keydata);
1724 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1730 sdp_append_attribute (char *string, int size, char *tmp,
1731 sdp_attribute_t * attribute, char **next_tmp)
1733 if (attribute->a_att_field == NULL)
1736 tmp = __osip_sdp_append_string (string, size, tmp, "a=");
1737 tmp = __osip_sdp_append_string (string, size, tmp, attribute->a_att_field);
1738 if (attribute->a_att_value != NULL)
1740 tmp = __osip_sdp_append_string (string, size, tmp, ":");
1742 __osip_sdp_append_string (string, size, tmp, attribute->a_att_value);
1744 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1750 /* internal facility */
1752 sdp_append_media (char *string, int size, char *tmp, sdp_media_t * media,
1757 if (media->m_media == NULL)
1759 if (media->m_port == NULL)
1761 if (media->m_proto == NULL)
1764 tmp = __osip_sdp_append_string (string, size, tmp, "m=");
1765 tmp = __osip_sdp_append_string (string, size, tmp, media->m_media);
1766 tmp = __osip_sdp_append_string (string, size, tmp, " ");
1767 tmp = __osip_sdp_append_string (string, size, tmp, media->m_port);
1768 if (media->m_number_of_port != NULL)
1770 tmp = __osip_sdp_append_string (string, size, tmp, "/");
1772 __osip_sdp_append_string (string, size, tmp, media->m_number_of_port);
1774 tmp = __osip_sdp_append_string (string, size, tmp, " ");
1775 tmp = __osip_sdp_append_string (string, size, tmp, media->m_proto);
1777 while (!osip_list_eol (media->m_payloads, pos))
1779 char *str = (char *) osip_list_get (media->m_payloads, pos);
1781 tmp = __osip_sdp_append_string (string, size, tmp, " ");
1782 tmp = __osip_sdp_append_string (string, size, tmp, str);
1785 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1787 if (media->i_info != NULL)
1789 tmp = __osip_sdp_append_string (string, size, tmp, "i=");
1790 tmp = __osip_sdp_append_string (string, size, tmp, media->i_info);
1791 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1795 while (!osip_list_eol (media->c_connections, pos))
1797 sdp_connection_t *conn =
1798 (sdp_connection_t *) osip_list_get (media->c_connections, pos);
1802 i = sdp_append_connection (string, size, tmp, conn, &next_tmp2);
1810 while (!osip_list_eol (media->b_bandwidths, pos))
1812 sdp_bandwidth_t *band =
1813 (sdp_bandwidth_t *) osip_list_get (media->b_bandwidths, pos);
1817 i = sdp_append_bandwidth (string, size, tmp, band, &next_tmp2);
1824 if (media->k_key != NULL)
1829 i = sdp_append_key (string, size, tmp, media->k_key, &next_tmp2);
1836 while (!osip_list_eol (media->a_attributes, pos))
1838 sdp_attribute_t *attr =
1839 (sdp_attribute_t *) osip_list_get (media->a_attributes, pos);
1843 i = sdp_append_attribute (string, size, tmp, attr, &next_tmp2);
1855 sdp_message_to_str (sdp_message_t * sdp, char **dest)
1863 if (sdp->v_version == NULL)
1865 if (sdp->o_username == NULL ||
1866 sdp->o_sess_id == NULL ||
1867 sdp->o_sess_version == NULL ||
1868 sdp->o_nettype == NULL || sdp->o_addrtype == NULL
1869 || sdp->o_addr == NULL)
1872 /* RFC says "s=" is mandatory... rfc2543 (SIP) recommends to
1873 accept SDP datas without s_name... as some buggy implementations
1876 /* if (sdp->s_name == NULL)
1880 tmp = (char *) osip_malloc (size);
1883 tmp = __osip_sdp_append_string (string, size, tmp, "v=");
1884 tmp = __osip_sdp_append_string (string, size, tmp, sdp->v_version);
1885 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1886 tmp = __osip_sdp_append_string (string, size, tmp, "o=");
1887 tmp = __osip_sdp_append_string (string, size, tmp, sdp->o_username);
1888 tmp = __osip_sdp_append_string (string, size, tmp, " ");
1889 tmp = __osip_sdp_append_string (string, size, tmp, sdp->o_sess_id);
1890 tmp = __osip_sdp_append_string (string, size, tmp, " ");
1891 tmp = __osip_sdp_append_string (string, size, tmp, sdp->o_sess_version);
1892 tmp = __osip_sdp_append_string (string, size, tmp, " ");
1893 tmp = __osip_sdp_append_string (string, size, tmp, sdp->o_nettype);
1894 tmp = __osip_sdp_append_string (string, size, tmp, " ");
1895 tmp = __osip_sdp_append_string (string, size, tmp, sdp->o_addrtype);
1896 tmp = __osip_sdp_append_string (string, size, tmp, " ");
1897 tmp = __osip_sdp_append_string (string, size, tmp, sdp->o_addr);
1898 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1899 if (sdp->s_name != NULL)
1901 tmp = __osip_sdp_append_string (string, size, tmp, "s=");
1902 tmp = __osip_sdp_append_string (string, size, tmp, sdp->s_name);
1903 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1905 if (sdp->i_info != NULL)
1907 tmp = __osip_sdp_append_string (string, size, tmp, "i=");
1908 tmp = __osip_sdp_append_string (string, size, tmp, sdp->i_info);
1909 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1911 if (sdp->u_uri != NULL)
1913 tmp = __osip_sdp_append_string (string, size, tmp, "u=");
1914 tmp = __osip_sdp_append_string (string, size, tmp, sdp->u_uri);
1915 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1918 while (!osip_list_eol (sdp->e_emails, pos))
1920 char *email = (char *) osip_list_get (sdp->e_emails, pos);
1922 tmp = __osip_sdp_append_string (string, size, tmp, "e=");
1923 tmp = __osip_sdp_append_string (string, size, tmp, email);
1924 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1928 while (!osip_list_eol (sdp->p_phones, pos))
1930 char *phone = (char *) osip_list_get (sdp->p_phones, pos);
1932 tmp = __osip_sdp_append_string (string, size, tmp, "p=");
1933 tmp = __osip_sdp_append_string (string, size, tmp, phone);
1934 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1937 if (sdp->c_connection != NULL)
1943 sdp_append_connection (string, size, tmp, sdp->c_connection,
1950 while (!osip_list_eol (sdp->b_bandwidths, pos))
1952 sdp_bandwidth_t *header =
1953 (sdp_bandwidth_t *) osip_list_get (sdp->b_bandwidths, pos);
1957 i = sdp_append_bandwidth (string, size, tmp, header, &next_tmp);
1965 while (!osip_list_eol (sdp->t_descrs, pos))
1967 sdp_time_descr_t *header =
1968 (sdp_time_descr_t *) osip_list_get (sdp->t_descrs, pos);
1972 i = sdp_append_time_descr (string, size, tmp, header, &next_tmp);
1979 if (sdp->z_adjustments != NULL)
1981 tmp = __osip_sdp_append_string (string, size, tmp, "z=");
1982 tmp = __osip_sdp_append_string (string, size, tmp, sdp->z_adjustments);
1983 tmp = __osip_sdp_append_string (string, size, tmp, CRLF);
1986 if (sdp->k_key != NULL)
1991 i = sdp_append_key (string, size, tmp, sdp->k_key, &next_tmp);
1998 while (!osip_list_eol (sdp->a_attributes, pos))
2000 sdp_attribute_t *header =
2001 (sdp_attribute_t *) osip_list_get (sdp->a_attributes, pos);
2005 i = sdp_append_attribute (string, size, tmp, header, &next_tmp);
2013 while (!osip_list_eol (sdp->m_medias, pos))
2015 sdp_media_t *header =
2016 (sdp_media_t *) osip_list_get (sdp->m_medias, pos);
2020 i = sdp_append_media (string, size, tmp, header, &next_tmp);
2031 sdp_message_free (sdp_message_t * sdp)
2035 osip_free (sdp->v_version);
2036 osip_free (sdp->o_username);
2037 osip_free (sdp->o_sess_id);
2038 osip_free (sdp->o_sess_version);
2039 osip_free (sdp->o_nettype);
2040 osip_free (sdp->o_addrtype);
2041 osip_free (sdp->o_addr);
2042 osip_free (sdp->s_name);
2043 osip_free (sdp->i_info);
2044 osip_free (sdp->u_uri);
2046 osip_list_ofchar_free (sdp->e_emails);
2048 osip_list_ofchar_free (sdp->p_phones);
2050 sdp_connection_free (sdp->c_connection);
2052 osip_list_special_free (sdp->b_bandwidths,
2053 (void *(*)(void *)) &sdp_bandwidth_free);
2055 osip_list_special_free (sdp->t_descrs,
2056 (void *(*)(void *)) &sdp_time_descr_free);
2058 osip_free (sdp->z_adjustments);
2059 sdp_key_free (sdp->k_key);
2061 osip_list_special_free (sdp->a_attributes,
2062 (void *(*)(void *)) &sdp_attribute_free);
2064 osip_list_special_free (sdp->m_medias, (void *(*)(void *)) &sdp_media_free);
2070 sdp_message_clone (sdp_message_t * sdp, sdp_message_t ** dest)
2075 i = sdp_message_init (dest);
2079 i = sdp_message_to_str (sdp, &body);
2083 i = sdp_message_parse (*dest, body);
2091 sdp_message_free (*dest);