📄 sdp_message.c
字号:
/* The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) Copyright (C) 2001,2002,2003 Aymeric MOIZARD jack@atosc.org This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include <osipparser2/osip_const.h>#include <osipparser2/sdp_message.h>#include <osipparser2/osip_port.h>#include <stdio.h>#include <stdlib.h>#define ERR_ERROR -1 /* bad header */#define ERR_DISCARD 0 /* wrong header */#define WF 1 /* well formed header */static int sdp_message_parse_v (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_o (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_s (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_i (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_u (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_e (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_p (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_c (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_b (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_t (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_r (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_z (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_k (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_a (sdp_message_t * sdp, char *buf, char **next);static int sdp_message_parse_m (sdp_message_t * sdp, char *buf, char **next);static int sdp_append_media (char *string, int size, char *tmp, sdp_media_t * media, char **next_tmp);static int sdp_append_attribute (char *string, int size, char *tmp, sdp_attribute_t * attribute, char **next_tmp);static int sdp_append_key (char *string, int size, char *tmp, sdp_key_t * key, char **next_tmp);static int sdp_append_time_descr (char *string, int size, char *tmp, sdp_time_descr_t * time_descr, char **next_tmp);static int sdp_append_bandwidth (char *string, int size, char *tmp, sdp_bandwidth_t * bandwidth, char **next_tmp);static int sdp_append_connection (char *string, int size, char *tmp, sdp_connection_t * conn, char **next_tmp);intsdp_bandwidth_init (sdp_bandwidth_t ** b){ *b = (sdp_bandwidth_t *) osip_malloc (sizeof (sdp_bandwidth_t)); if (*b == NULL) return -1; (*b)->b_bwtype = NULL; (*b)->b_bandwidth = NULL; return 0;}voidsdp_bandwidth_free (sdp_bandwidth_t * b){ if (b == NULL) return; osip_free (b->b_bwtype); osip_free (b->b_bandwidth); osip_free (b);}intsdp_time_descr_init (sdp_time_descr_t ** td){ *td = (sdp_time_descr_t *) osip_malloc (sizeof (sdp_time_descr_t)); if (*td == NULL) return -1; (*td)->t_start_time = NULL; (*td)->t_stop_time = NULL; (*td)->r_repeats = (osip_list_t *) osip_malloc (sizeof (osip_list_t)); osip_list_init ((*td)->r_repeats); return 0;}voidsdp_time_descr_free (sdp_time_descr_t * td){ if (td == NULL) return; osip_free (td->t_start_time); osip_free (td->t_stop_time); osip_list_ofchar_free (td->r_repeats); osip_free (td);}intsdp_key_init (sdp_key_t ** key){ *key = (sdp_key_t *) osip_malloc (sizeof (sdp_key_t)); if (*key == NULL) return -1; (*key)->k_keytype = NULL; (*key)->k_keydata = NULL; return 0;}voidsdp_key_free (sdp_key_t * key){ if (key == NULL) return; osip_free (key->k_keytype); osip_free (key->k_keydata); osip_free (key);}intsdp_attribute_init (sdp_attribute_t ** attribute){ *attribute = (sdp_attribute_t *) osip_malloc (sizeof (sdp_attribute_t)); if (*attribute == NULL) return -1; (*attribute)->a_att_field = NULL; (*attribute)->a_att_value = NULL; return 0;}voidsdp_attribute_free (sdp_attribute_t * attribute){ if (attribute == NULL) return; osip_free (attribute->a_att_field); osip_free (attribute->a_att_value); osip_free (attribute);}intsdp_connection_init (sdp_connection_t ** connection){ *connection = (sdp_connection_t *) osip_malloc (sizeof (sdp_connection_t)); if (*connection == NULL) return -1; (*connection)->c_nettype = NULL; (*connection)->c_addrtype = NULL; (*connection)->c_addr = NULL; (*connection)->c_addr_multicast_ttl = NULL; (*connection)->c_addr_multicast_int = NULL; return 0;}voidsdp_connection_free (sdp_connection_t * connection){ if (connection == NULL) return; osip_free (connection->c_nettype); osip_free (connection->c_addrtype); osip_free (connection->c_addr); osip_free (connection->c_addr_multicast_ttl); osip_free (connection->c_addr_multicast_int); osip_free (connection);}intsdp_media_init (sdp_media_t ** media){ *media = (sdp_media_t *) osip_malloc (sizeof (sdp_media_t)); if (*media == NULL) return -1; (*media)->m_media = NULL; (*media)->m_port = NULL; (*media)->m_number_of_port = NULL; (*media)->m_proto = NULL; (*media)->m_payloads = (osip_list_t *) osip_malloc (sizeof (osip_list_t)); osip_list_init ((*media)->m_payloads); (*media)->i_info = NULL; (*media)->c_connections = (osip_list_t *) osip_malloc (sizeof (osip_list_t)); osip_list_init ((*media)->c_connections); (*media)->b_bandwidths = (osip_list_t *) osip_malloc (sizeof (osip_list_t)); osip_list_init ((*media)->b_bandwidths); (*media)->a_attributes = (osip_list_t *) osip_malloc (sizeof (osip_list_t)); osip_list_init ((*media)->a_attributes); (*media)->k_key = NULL; return 0;}voidsdp_media_free (sdp_media_t * media){ if (media == NULL) return; osip_free (media->m_media); osip_free (media->m_port); osip_free (media->m_number_of_port); osip_free (media->m_proto); osip_list_ofchar_free (media->m_payloads); osip_free (media->i_info); osip_list_special_free (media->c_connections, (void *(*)(void *)) &sdp_connection_free); osip_list_special_free (media->b_bandwidths, (void *(*)(void *)) &sdp_bandwidth_free); osip_list_special_free (media->a_attributes, (void *(*)(void *)) &sdp_attribute_free); sdp_key_free (media->k_key); osip_free (media);}/* to be changed to sdp_message_init(sdp_message_t **dest) */intsdp_message_init (sdp_message_t ** sdp){ (*sdp) = (sdp_message_t *) osip_malloc (sizeof (sdp_message_t)); if (*sdp == NULL) return -1; (*sdp)->v_version = NULL; (*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; (*sdp)->s_name = NULL; (*sdp)->i_info = NULL; (*sdp)->u_uri = NULL; (*sdp)->e_emails = (osip_list_t *) osip_malloc (sizeof (osip_list_t)); if ((*sdp)->e_emails == NULL) return -1; osip_list_init ((*sdp)->e_emails); (*sdp)->p_phones = (osip_list_t *) osip_malloc (sizeof (osip_list_t)); if ((*sdp)->p_phones == NULL) return -1; osip_list_init ((*sdp)->p_phones); (*sdp)->c_connection = NULL; (*sdp)->b_bandwidths = (osip_list_t *) osip_malloc (sizeof (osip_list_t)); if ((*sdp)->b_bandwidths == NULL) return -1; osip_list_init ((*sdp)->b_bandwidths); (*sdp)->t_descrs = (osip_list_t *) osip_malloc (sizeof (osip_list_t)); if ((*sdp)->t_descrs == NULL) return -1; osip_list_init ((*sdp)->t_descrs); (*sdp)->z_adjustments = NULL; (*sdp)->k_key = NULL; (*sdp)->a_attributes = (osip_list_t *) osip_malloc (sizeof (osip_list_t)); if ((*sdp)->a_attributes == NULL) return -1; osip_list_init ((*sdp)->a_attributes); (*sdp)->m_medias = (osip_list_t *) osip_malloc (sizeof (osip_list_t)); if ((*sdp)->m_medias == NULL) return -1; osip_list_init ((*sdp)->m_medias); return 0;}static intsdp_message_parse_v (sdp_message_t * sdp, char *buf, char **next){ char *equal; char *crlf; *next = buf; equal = buf; while ((*equal != '=') && (*equal != '\0')) equal++; if (*equal == '\0') return ERR_ERROR; if (equal == buf) return ERR_DISCARD; /* check if header is "v" */ if (equal[-1] != 'v') return ERR_DISCARD; crlf = equal + 1; while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) crlf++; if (*crlf == '\0') return ERR_ERROR; if (crlf == equal + 1) return ERR_ERROR; /*v=\r ?? bad header */ sdp->v_version = osip_malloc (crlf - (equal + 1) + 1); osip_strncpy (sdp->v_version, equal + 1, crlf - (equal + 1)); if (crlf[1] == '\n') *next = crlf + 2; else *next = crlf + 1; return WF;}static intsdp_message_parse_o (sdp_message_t * sdp, char *buf, char **next){ char *equal; char *crlf; char *tmp; char *tmp_next; int i; *next = buf; equal = buf; while ((*equal != '=') && (*equal != '\0')) equal++; if (*equal == '\0') return ERR_ERROR; /* check if header is "o" */ if (equal[-1] != 'o') return ERR_DISCARD; crlf = equal + 1; while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) crlf++; if (*crlf == '\0') return ERR_ERROR; if (crlf == equal + 1) return ERR_ERROR; /* o=\r ?? bad header */ tmp = equal + 1; /* o=username sess-id sess-version nettype addrtype addr */ /* useranme can contain any char (ascii) except "space" and CRLF */ i = __osip_set_next_token (&(sdp->o_username), tmp, ' ', &tmp_next); if (i != 0) return -1; tmp = tmp_next; /* sess_id contains only numeric characters */ i = __osip_set_next_token (&(sdp->o_sess_id), tmp, ' ', &tmp_next); if (i != 0) return -1; tmp = tmp_next; /* sess_id contains only numeric characters */ i = __osip_set_next_token (&(sdp->o_sess_version), tmp, ' ', &tmp_next); if (i != 0) return -1; tmp = tmp_next; /* nettype is "IN" but will surely be extented!!! assume it's some alpha-char */ i = __osip_set_next_token (&(sdp->o_nettype), tmp, ' ', &tmp_next); if (i != 0) return -1; tmp = tmp_next; /* addrtype is "IP4" or "IP6" but will surely be extented!!! */ i = __osip_set_next_token (&(sdp->o_addrtype), tmp, ' ', &tmp_next); if (i != 0) return -1; tmp = tmp_next; /* addr is "IP4" or "IP6" but will surely be extented!!! */ i = __osip_set_next_token (&(sdp->o_addr), tmp, '\r', &tmp_next); if (i != 0) { /* could it be "\n" only??? rfc says to accept CR or LF instead of CRLF */ i = __osip_set_next_token (&(sdp->o_addr), tmp, '\n', &tmp_next); if (i != 0) return -1; } if (crlf[1] == '\n') *next = crlf + 2; else *next = crlf + 1; return WF;}static intsdp_message_parse_s (sdp_message_t * sdp, char *buf, char **next){ char *equal; char *crlf; *next = buf; equal = buf; while ((*equal != '=') && (*equal != '\0')) equal++; if (*equal == '\0') return ERR_ERROR; /* check if header is "s" */ if (equal[-1] != 's') return ERR_DISCARD; crlf = equal + 1; while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) crlf++; if (*crlf == '\0') return ERR_ERROR; if (crlf == equal + 1) return ERR_ERROR; /* o=\r ?? bad header */ /* s=text */ /* text is interpreted as ISO-10646 UTF8! */ /* using ISO 8859-1 requires "a=charset:ISO-8859-1 */ sdp->s_name = osip_malloc (crlf - (equal + 1) + 1); osip_strncpy (sdp->s_name, equal + 1, crlf - (equal + 1)); if (crlf[1] == '\n') *next = crlf + 2; else *next = crlf + 1; return WF;}static intsdp_message_parse_i (sdp_message_t * sdp, char *buf, char **next){ char *equal; char *crlf; int i; char *i_info; *next = buf; equal = buf; while ((*equal != '=') && (*equal != '\0')) equal++; if (*equal == '\0') return ERR_ERROR; /* check if header is "i" */ if (equal[-1] != 'i') return ERR_DISCARD; crlf = equal + 1; while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) crlf++; if (*crlf == '\0') return ERR_ERROR; if (crlf == equal + 1) return ERR_ERROR; /* o=\r ?? bad header */ /* s=text */ /* text is interpreted as ISO-10646 UTF8! */ /* using ISO 8859-1 requires "a=charset:ISO-8859-1 */ i_info = osip_malloc (crlf - (equal + 1) + 1); osip_strncpy (i_info, equal + 1, crlf - (equal + 1)); /* add the bandwidth at the correct place: if there is no media line yet, then the "b=" is the global one. */ i = osip_list_size (sdp->m_medias); if (i == 0) sdp->i_info = i_info; else { sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get (sdp->m_medias, i - 1); last_sdp_media->i_info = i_info; } if (crlf[1] == '\n') *next = crlf + 2; else *next = crlf + 1; return WF;}static intsdp_message_parse_u (sdp_message_t * sdp, char *buf, char **next){ char *equal; char *crlf; *next = buf; equal = buf; while ((*equal != '=') && (*equal != '\0')) equal++; if (*equal == '\0') return ERR_ERROR; /* check if header is "u" */ if (equal[-1] != 'u') return ERR_DISCARD; crlf = equal + 1; while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0')) crlf++; if (*crlf == '\0') return ERR_ERROR; if (crlf == equal + 1) return ERR_ERROR; /* u=\r ?? bad header */ /* u=uri */ /* we assume this is a URI */ sdp->u_uri = osip_malloc (crlf - (equal + 1) + 1); osip_strncpy (sdp->u_uri, equal + 1, crlf - (equal + 1));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -