📄 sdp_rfc2327.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 <osip/const.h>#include <osip/sdp.h>#include <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 */intsdp_bandwidth_init (sdp_bandwidth_t ** b){ *b = (sdp_bandwidth_t *) smalloc (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; sfree (b->b_bwtype); sfree (b->b_bandwidth);}intsdp_time_descr_init (sdp_time_descr_t ** td){ *td = (sdp_time_descr_t *) smalloc (sizeof (sdp_time_descr_t)); if (*td == NULL) return -1; (*td)->t_start_time = NULL; (*td)->t_stop_time = NULL; (*td)->r_repeats = (list_t *) smalloc (sizeof (list_t)); list_init ((*td)->r_repeats); return 0;}voidsdp_time_descr_free (sdp_time_descr_t * td){ if (td == NULL) return; sfree (td->t_start_time); sfree (td->t_stop_time); listofchar_free (td->r_repeats); sfree (td->r_repeats);}intsdp_key_init (sdp_key_t ** key){ *key = (sdp_key_t *) smalloc (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; sfree (key->k_keytype); sfree (key->k_keydata);}intsdp_attribute_init (sdp_attribute_t ** attribute){ *attribute = (sdp_attribute_t *) smalloc (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; sfree (attribute->a_att_field); sfree (attribute->a_att_value);}intsdp_connection_init (sdp_connection_t ** connection){ *connection = (sdp_connection_t *) smalloc (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; sfree (connection->c_nettype); sfree (connection->c_addrtype); sfree (connection->c_addr); sfree (connection->c_addr_multicast_ttl); sfree (connection->c_addr_multicast_int);}intsdp_media_init (sdp_media_t ** media){ *media = (sdp_media_t *) smalloc (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 = (list_t *) smalloc (sizeof (list_t)); list_init ((*media)->m_payloads); (*media)->i_info = NULL; (*media)->c_connections = (list_t *) smalloc (sizeof (list_t)); list_init ((*media)->c_connections); (*media)->b_bandwidths = (list_t *) smalloc (sizeof (list_t)); list_init ((*media)->b_bandwidths); (*media)->a_attributes = (list_t *) smalloc (sizeof (list_t)); list_init ((*media)->a_attributes); (*media)->k_key = NULL; return 0;}voidsdp_media_free (sdp_media_t * media){ if (media == NULL) return; sfree (media->m_media); sfree (media->m_port); sfree (media->m_number_of_port); sfree (media->m_proto); listofchar_free (media->m_payloads); sfree (media->m_payloads); sfree (media->i_info); list_special_free (media->c_connections, (void *(*)(void *)) &sdp_connection_free); sfree (media->c_connections); list_special_free (media->b_bandwidths, (void *(*)(void *)) &sdp_bandwidth_free); sfree (media->b_bandwidths); list_special_free (media->a_attributes, (void *(*)(void *)) &sdp_attribute_free); sfree (media->a_attributes); sdp_key_free (media->k_key); sfree (media->k_key);}/* to be changed to sdp_init(sdp_t **dest) */intsdp_init (sdp_t ** sdp){ (*sdp) = (sdp_t *) smalloc (sizeof (sdp_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 = (list_t *) smalloc (sizeof (list_t)); if ((*sdp)->e_emails == NULL) return -1; list_init ((*sdp)->e_emails); (*sdp)->p_phones = (list_t *) smalloc (sizeof (list_t)); if ((*sdp)->p_phones == NULL) return -1; list_init ((*sdp)->p_phones); (*sdp)->c_connection = NULL; (*sdp)->b_bandwidths = (list_t *) smalloc (sizeof (list_t)); if ((*sdp)->b_bandwidths == NULL) return -1; list_init ((*sdp)->b_bandwidths); (*sdp)->t_descrs = (list_t *) smalloc (sizeof (list_t)); if ((*sdp)->t_descrs == NULL) return -1; list_init ((*sdp)->t_descrs); (*sdp)->z_adjustments = NULL; (*sdp)->k_key = NULL; (*sdp)->a_attributes = (list_t *) smalloc (sizeof (list_t)); if ((*sdp)->a_attributes == NULL) return -1; list_init ((*sdp)->a_attributes); (*sdp)->m_medias = (list_t *) smalloc (sizeof (list_t)); if ((*sdp)->m_medias == NULL) return -1; list_init ((*sdp)->m_medias); return 0;}intsdp_parse_v (sdp_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 "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 = smalloc (crlf - (equal + 1) + 1); sstrncpy (sdp->v_version, equal + 1, crlf - (equal + 1)); if (crlf[1] == '\n') *next = crlf + 2; else *next = crlf + 1; return WF;}intsdp_parse_o (sdp_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 = set_next_token (&(sdp->o_username), tmp, ' ', &tmp_next); if (i != 0) return -1; tmp = tmp_next; /* sess_id contains only numeric characters */ i = 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 = 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 = 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 = 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 = 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 = 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;}intsdp_parse_s (sdp_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 = smalloc (crlf - (equal + 1) + 1); sstrncpy (sdp->s_name, equal + 1, crlf - (equal + 1)); if (crlf[1] == '\n') *next = crlf + 2; else *next = crlf + 1; return WF;}intsdp_parse_i (sdp_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 = smalloc (crlf - (equal + 1) + 1); sstrncpy (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 = list_size (sdp->m_medias); if (i == 0) sdp->i_info = i_info; else { sdp_media_t *last_sdp_media = (sdp_media_t *) 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;}intsdp_parse_u (sdp_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 = smalloc (crlf - (equal + 1) + 1); sstrncpy (sdp->u_uri, equal + 1, crlf - (equal + 1)); if (crlf[1] == '\n') *next = crlf + 2; else *next = crlf + 1; return WF;}intsdp_parse_e (sdp_t * sdp, char *buf, char **next){ char *equal; char *crlf; char *e_email; *next = buf; equal = buf; while ((*equal != '=') && (*equal != '\0')) equal++; if (*equal == '\0') return ERR_ERROR; /* check if header is "e" */ if (equal[-1] != 'e') return ERR_DISCARD;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -