diff options
author | ben <ben@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2006-06-26 17:37:55 +0000 |
---|---|---|
committer | ben <ben@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2006-06-26 17:37:55 +0000 |
commit | 155f9d742ff4df39ba149f47baec8d518da36551 (patch) | |
tree | 4974dba2e908fee02be3aa5beb380ac99db4ab7b | |
parent | b31df04b82e45fb5e3146ec0d2f64813283cf05a (diff) | |
download | mpv-155f9d742ff4df39ba149f47baec8d518da36551.tar.bz2 mpv-155f9d742ff4df39ba149f47baec8d518da36551.tar.xz |
new imported library in libmpdemux: freesdp (will be used by native rtsp demuxer)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@18827 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r-- | libmpdemux/Makefile | 7 | ||||
-rw-r--r-- | libmpdemux/freesdp/common.c | 226 | ||||
-rw-r--r-- | libmpdemux/freesdp/common.h | 352 | ||||
-rw-r--r-- | libmpdemux/freesdp/errorlist.c | 72 | ||||
-rw-r--r-- | libmpdemux/freesdp/parser.c | 1958 | ||||
-rw-r--r-- | libmpdemux/freesdp/parser.h | 728 | ||||
-rw-r--r-- | libmpdemux/freesdp/parserpriv.h | 118 | ||||
-rw-r--r-- | libmpdemux/freesdp/priv.h | 274 |
8 files changed, 3734 insertions, 1 deletions
diff --git a/libmpdemux/Makefile b/libmpdemux/Makefile index ab32d53a61..2179ea3e36 100644 --- a/libmpdemux/Makefile +++ b/libmpdemux/Makefile @@ -141,6 +141,10 @@ SRCS += realrtsp/asmrp.c \ SRCS += librtsp/rtsp.c \ librtsp/rtsp_session.c \ +SRCS += freesdp/common.c \ + freesdp/errorlist.c \ + freesdp/parser.c \ + ifeq ($(STREAMING_LIVE555),yes) CPLUSPLUSSRCS = demux_rtp.cpp demux_rtp_codec.cpp CPLUSPLUSINCLUDE = $(LIVE_INCLUDES) @@ -188,7 +192,8 @@ test: $(LIBNAME) test.c clean: rm -f *.o *.a *~ \ realrtsp/*.o realrtsp/*.a realrtsp/*~ \ - librtsp/*.o librtsp/*.a librtsp/*~ + librtsp/*.o librtsp/*.a librtsp/*~ \ + freesdp/*.o freesdp/*.a freesdp/*~ distclean: clean rm -f .depend test diff --git a/libmpdemux/freesdp/common.c b/libmpdemux/freesdp/common.c new file mode 100644 index 0000000000..6ea625d2ed --- /dev/null +++ b/libmpdemux/freesdp/common.c @@ -0,0 +1,226 @@ +/* + This file is part of FreeSDP + Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp@suidzer0.org> + + FreeSDP is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/** + * @file common.c + * + * @short Implementation of routines common to parse and formatting + * modules . + * + * This file implements the routines that operate over data structures + * that are used in both the parse and formatting modules. + **/ + +#include "priv.h" +#include "common.h" + +static void +safe_free (void *ptr) +{ + if (ptr) + free (ptr); +} + +fsdp_description_t * +fsdp_description_new (void) +{ + fsdp_description_t *result = malloc (sizeof (fsdp_description_t)); + + result->version = 0; + result->o_username = result->o_session_id = + result->o_announcement_version = NULL; + result->o_network_type = FSDP_NETWORK_TYPE_UNDEFINED; + result->o_address_type = FSDP_ADDRESS_TYPE_UNDEFINED; + result->o_address = NULL; + result->s_name = NULL; + result->i_information = NULL; + result->u_uri = NULL; + result->emails = NULL; + result->emails_count = 0; + result->phones = NULL; + result->phones_count = 0; + /* At first, there is no session-level definition for these + parameters */ + result->c_network_type = FSDP_NETWORK_TYPE_UNDEFINED; + result->c_address_type = FSDP_ADDRESS_TYPE_UNDEFINED; + result->c_address.address = NULL; + /* there is no session-level definition for these parameters */ + result->bw_modifiers = NULL; + result->bw_modifiers_count = 0; + result->time_periods = NULL; + result->time_periods_count = 0; + result->timezone_adj = NULL; + result->k_encryption_method = FSDP_ENCRYPTION_METHOD_UNDEFINED; + result->k_encryption_content = NULL; + /* Default/undefined values for attributes */ + result->a_category = result->a_keywords = result->a_tool = NULL; + result->a_type = FSDP_SESSION_TYPE_UNDEFINED; + result->a_sendrecv_mode = FSDP_SENDRECV_UNDEFINED; + result->a_charset = NULL; + result->a_sdplangs = result->a_langs = NULL; + result->a_controls = NULL; + result->a_range = NULL; + result->a_rtpmaps = NULL; + result->a_rtpmaps_count = 0; + result->a_sdplangs_count = 0; + result->a_langs_count = 0; + result->a_controls_count = 0; + result->unidentified_attributes = NULL; + result->unidentified_attributes_count = 0; + result->media_announcements = NULL; + result->media_announcements_count = 0; + + return result; +} + +void +fsdp_description_delete (fsdp_description_t * dsc) +{ + fsdp_description_recycle (dsc); + safe_free (dsc); +} + +void +fsdp_description_recycle (fsdp_description_t * dsc) +{ + /* Recursively free all strings and arrays */ + unsigned int i, j; + + if (!dsc) + return; + + safe_free (dsc->o_username); + safe_free (dsc->o_session_id); + safe_free (dsc->o_announcement_version); + safe_free (dsc->o_address); + safe_free (dsc->s_name); + safe_free (dsc->i_information); + safe_free (dsc->u_uri); + + for (i = 0; i < dsc->emails_count; i++) + safe_free ((char *) dsc->emails[i]); + safe_free (dsc->emails); + + for (i = 0; i < dsc->phones_count; i++) + safe_free ((char *) dsc->phones[i]); + safe_free (dsc->phones); + + safe_free (dsc->c_address.address); + + for (i = 0; i < dsc->bw_modifiers_count; i++) + safe_free (dsc->bw_modifiers[i].b_unknown_bw_modt); + safe_free (dsc->bw_modifiers); + + for (i = 0; i < dsc->time_periods_count; i++) + { + for (j = 0; j < dsc->time_periods[i]->repeats_count; j++) + { + safe_free (dsc->time_periods[i]->repeats[j]->offsets); + safe_free (dsc->time_periods[i]->repeats[j]); + } + safe_free (dsc->time_periods[i]->repeats); + safe_free (dsc->time_periods[i]); + } + safe_free (dsc->time_periods); + + safe_free (dsc->timezone_adj); + safe_free (dsc->a_category); + safe_free (dsc->a_keywords); + safe_free (dsc->a_tool); + + for (i = 0; i < dsc->a_rtpmaps_count; i++) + safe_free (dsc->a_rtpmaps[i]); + safe_free (dsc->a_rtpmaps); + + safe_free (dsc->a_charset); + + for (i = 0; i < dsc->a_sdplangs_count; i++) + safe_free (dsc->a_sdplangs[i]); + safe_free (dsc->a_sdplangs); + + for (i = 0; i < dsc->a_langs_count; i++) + safe_free (dsc->a_langs[i]); + safe_free (dsc->a_langs); + + for (i = 0; i < dsc->a_controls_count; i++) + safe_free (dsc->a_controls[i]); + safe_free (dsc->a_controls); + + safe_free (dsc->a_range); + + for (i = 0; i < dsc->media_announcements_count; i++) + { + for (j = 0; j < dsc->media_announcements[i]->formats_count; j++) + safe_free (dsc->media_announcements[i]->formats[j]); + safe_free (dsc->media_announcements[i]->formats); + safe_free (dsc->media_announcements[i]->i_title); + + for (j = 0; j < dsc->media_announcements[i]->bw_modifiers_count; j++) + { + if (FSDP_BW_MOD_TYPE_UNKNOWN == + dsc->media_announcements[i]->bw_modifiers[j].b_mod_type) + safe_free (dsc->media_announcements[i]->bw_modifiers[j]. + b_unknown_bw_modt); + } + safe_free (dsc->media_announcements[i]->bw_modifiers); + + safe_free (dsc->media_announcements[i]->k_encryption_content); + + for (j = 0; j < dsc->media_announcements[i]->a_rtpmaps_count; j++) + { + safe_free (dsc->media_announcements[i]->a_rtpmaps[j]->pt); + safe_free (dsc->media_announcements[i]->a_rtpmaps[j]-> + encoding_name); + safe_free (dsc->media_announcements[i]->a_rtpmaps[j]->parameters); + safe_free (dsc->media_announcements[i]->a_rtpmaps[j]); + } + safe_free (dsc->media_announcements[i]->a_rtpmaps); + + for (j = 0; j < dsc->media_announcements[i]->a_sdplangs_count; j++) + safe_free (dsc->media_announcements[i]->a_sdplangs[j]); + safe_free (dsc->media_announcements[i]->a_sdplangs); + + for (j = 0; j < dsc->media_announcements[i]->a_langs_count; j++) + safe_free (dsc->media_announcements[i]->a_langs[j]); + safe_free (dsc->media_announcements[i]->a_langs); + + for (j = 0; j < dsc->media_announcements[i]->a_controls_count; j++) + safe_free (dsc->media_announcements[i]->a_controls[j]); + safe_free (dsc->media_announcements[i]->a_controls); + + for (j = 0; j < dsc->media_announcements[i]->a_fmtps_count; j++) + safe_free (dsc->media_announcements[i]->a_fmtps[j]); + safe_free (dsc->media_announcements[i]->a_fmtps); + + for (j = 0; + j < dsc->media_announcements[i]->unidentified_attributes_count; j++) + safe_free (dsc->media_announcements[i]->unidentified_attributes[j]); + safe_free (dsc->media_announcements[i]->unidentified_attributes); + safe_free (dsc->media_announcements[i]); + } + safe_free (dsc->media_announcements); + + /* This prevents the user to make the library crash when incorrectly + using recycled but not rebuilt descriptions */ + dsc->emails_count = 0; + dsc->phones_count = 0; + dsc->bw_modifiers_count = 0; + dsc->time_periods_count = 0; + dsc->media_announcements_count = 0; +} diff --git a/libmpdemux/freesdp/common.h b/libmpdemux/freesdp/common.h new file mode 100644 index 0000000000..ae59406049 --- /dev/null +++ b/libmpdemux/freesdp/common.h @@ -0,0 +1,352 @@ +/* + This file is part of FreeSDP. + Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp@altern.org> + + FreeSDP is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/** + * @file common.h + * @ingroup common + * @short Public header common for both parsing and formatting modules. + **/ + +#ifndef FSDP_COMMON_H +#define FSDP_COMMON_H + +/* Macros to avoid name mangling when compiling with a C++ compiler */ +#ifdef __cplusplus +# define BEGIN_C_DECLS extern "C" { +# define END_C_DECLS } +#else /* !__cplusplus */ +# define BEGIN_C_DECLS +# define END_C_DECLS +#endif /* __cplusplus */ + +#include <sys/time.h> +#include <time.h> + +BEGIN_C_DECLS +/** + * @defgroup common FreeSDP Common Facilities + * + * Data types and routines common for both parsing and formatting + * modules. + **/ +/** @addtogroup common */ +/*@{*/ +/** + * @enum fsdp_error_t freesdp/common.h + * @short Error codes in the FreeSDP library. + * + * There is a FSDPE_MISSING_XXXX for each mandatory line, as + * FSDPE_MISSING_OWNER. This kind of error is reported when a + * mandatory description line, such as the owner line, is not found + * where it should be in the SDP description. There are also several + * error codes like FSDPE_INVALID_XXXX. These are returned when there + * is a recognized line in the parsed description that violates the + * SDP syntax or gives wrong parameters, for instance "c=foo bar", + * which would cause a FSDPE_INVALID_CONNECTION error code to be + * returned. + **/ +typedef enum +{ + FSDPE_OK = 0, + FSDPE_ILLEGAL_CHARACTER, /**< Misplaced '\r', '\n' or '\0' */ + FSDPE_MISSING_VERSION, /**< The first line is not like + v=... */ + FSDPE_INVALID_VERSION, /**< Parse error in version line, + perhaps, the version specified in + v=... is not valid for FreeSDP */ + FSDPE_MISSING_OWNER, /**< No owner line found in its + place */ + FSDPE_INVALID_OWNER, /**< Parse error in owner line */ + FSDPE_MISSING_NAME, /**< No session name found in its + place */ + FSDPE_EMPTY_NAME, /**< Empty session name line */ + + FSDPE_INVALID_CONNECTION, /**< Syntax error in connection + line */ + + FSDPE_INVALID_CONNECTION_ADDRTYPE, /**< Unrecognized address type in + connection line */ + FSDPE_INVALID_CONNECTION_NETTYPE, /**< Unrecognized network type in + connection line */ + FSDPE_INVALID_BANDWIDTH, /**< Parse error in bandwidth + line */ + FSDPE_MISSING_TIME, /**< No time period has been given + for the session */ + FSDPE_INVALID_TIME, /**< Parse error in time line */ + FSDPE_INVALID_REPEAT, /**< Parse error in repeat time + line */ + FSDPE_INVALID_TIMEZONE, /**< Parse error in timezone line */ + FSDPE_INVALID_ENCRYPTION_METHOD, /**< Unknown encryption method */ + FSDPE_INVALID_ATTRIBUTE, /**< Syntax error in an attribute + line */ + + FSDPE_INVALID_ATTRIBUTE_RTPMAP,/**< Parse error in a=rtpmap:... line */ + FSDPE_INVALID_SESSION_TYPE, /**< An unknown session type has been + specified in a `type:' + session-level attribute */ + + FSDPE_INVALID_MEDIA, /**< Parse error in media line */ + FSDPE_UNKNOWN_MEDIA_TYPE, /**< Unknown media type in media + line */ + + FSDPE_UNKNOWN_MEDIA_TRANSPORT, /**< A media transport has been + specified that is unknown */ + + FSDPE_OVERFILLED, /**< extra unknown lines are at the + end of the description */ + FSDPE_INVALID_LINE, /**< a line unknown to FreeSDP has been + found */ + FSDPE_MISSING_CONNECTION_INFO, /**< No connection information has + been provided for the whole + session nor one or more media */ + FSDPE_INVALID_INDEX, + /* FSDPE_MAXSIZE, description does not fit requested maximun size */ + FSDPE_INTERNAL_ERROR, + + FSDPE_INVALID_PARAMETER, /**< Some parameter of the called + FreeSDP routine has been given an + invalid value. This includes + cases such as NULL pointers. */ + FSDPE_BUFFER_OVERFLOW +} fsdp_error_t; + +/** + * @short Type of network + * + * Initially, SDP defines "Internet". New network types may be + * registered with IANA. However, the number of types is expected to + * be small and rarely extended. In addition, every new network type + * requires at least one new address type. + **/ +typedef enum +{ + FSDP_NETWORK_TYPE_UNDEFINED, /**< Not provided */ + FSDP_NETWORK_TYPE_INET /**< Internet */ +} fsdp_network_type_t; + +/** + * @short Type of address + * + * Initially, IPv4 and IPv6 are defined for the network type + * Internet. New address types may be registered with IANA. + **/ +typedef enum +{ + FSDP_ADDRESS_TYPE_UNDEFINED, /**< Not provided */ + FSDP_ADDRESS_TYPE_IPV4, /**< IP version 4 */ + FSDP_ADDRESS_TYPE_IPV6 /**< IP version 6 */ +} fsdp_address_type_t; + +/** + * @short Type of bandwith modifiers + * + * Bandwidth modifiers specify the meaning of the bandwidth + * value. Initially "Conference Total" and "Application Specific" are + * defined. Both use kilobits as bandwidth unit. "Conference Total" + * specifies that the bandwidth value is a proposed upper limit to the + * session bandwidth. "Application Specific" specifies thath the + * bandwidth value is the application concept of maximum bandwidth. + **/ +typedef enum +{ + FSDP_BW_MOD_TYPE_UNDEFINED, /**< Not provided */ + FSDP_BW_MOD_TYPE_UNKNOWN, /**< Unknown bandwidth + modifier (FreeSDP + ignores it) */ + FSDP_BW_MOD_TYPE_CONFERENCE_TOTAL, /**< "CT - Conference Total" */ + FSDP_BW_MOD_TYPE_APPLICATION_SPECIFIC, /**< "AS - Application specific" */ + FSDP_BW_MOD_TYPE_RTCP_SENDERS, /**< "RS - RTCP bandwidth for + senders */ + FSDP_BW_MOD_TYPE_RTCP_RECEIVERS, /**< "RR - RTCP bandwidth for + receivers */ +} fsdp_bw_modifier_type_t; + +/** + * @short encryption method + * + * The encryption method specifies the way to get the encryption key. + **/ +typedef enum +{ + FSDP_ENCRYPTION_METHOD_UNDEFINED, /**< Not provided */ + FSDP_ENCRYPTION_METHOD_CLEAR, /**< The key field is the + untransformed key */ + FSDP_ENCRYPTION_METHOD_BASE64, /**< The key is base64 + encoded */ + FSDP_ENCRYPTION_METHOD_URI, /**< The key value provided is + a URI pointing to the actual + key */ + FSDP_ENCRYPTION_METHOD_PROMPT /**< The key is not provided + but should be got prompting + the user */ +} fsdp_encryption_method_t; + +/** + * @short Advised reception/transmission mode + * + * Depending on wheter sendrecv, recvonly, sendonly or inactive + * attribute is given, the tools used to participate in the session + * should be started in the corresponding transmission + * mode. FSDP_SENDRECV_SENDRECV is the default for sessions which are + * not of the conference type broadcast or H332. + **/ +typedef enum +{ + FSDP_SENDRECV_UNDEFINED, /**< Not specified */ + FSDP_SENDRECV_SENDRECV, /**< Send and receive */ + FSDP_SENDRECV_RECVONLY, /**< Receive only */ + FSDP_SENDRECV_SENDONLY, /**< Send only */ + FSDP_SENDRECV_INACTIVE /**< Do not send nor receive */ +} fsdp_sendrecv_mode_t; + +/** + * @short Values for `orient' media attribute. + * + * Normally used with whiteboard media, this attribute specifies the + * orientation of the whiteboard. + **/ +typedef enum +{ + FSDP_ORIENT_UNDEFINED, /**< Not specified */ + FSDP_ORIENT_PORTRAIT, /**< Portrait */ + FSDP_ORIENT_LANDSCAPE, /**< Landscape */ + FSDP_ORIENT_SEASCAPE /**< Upside down landscape */ +} fsdp_orient_t; + +/** + * @short Type of the conference + * + * The following types are initially defined: broadcast, meeting, + * moderated, test and H332. + **/ +typedef enum +{ + FSDP_SESSION_TYPE_UNDEFINED, /**< Not specified */ + FSDP_SESSION_TYPE_BROADCAST, /**< Broadcast session */ + FSDP_SESSION_TYPE_MEETING, /**< Meeting session */ + FSDP_SESSION_TYPE_MODERATED, /**< Moderated session */ + FSDP_SESSION_TYPE_TEST, /**< Test (do not display) */ + FSDP_SESSION_TYPE_H332 /**< H332 session */ +} fsdp_session_type_t; + +/** + * @short Media type + * + * The following types are defined initially: audio, video, + * application, data and control. + **/ +typedef enum +{ + FSDP_MEDIA_UNDEFINED, /**< Not specified */ + FSDP_MEDIA_VIDEO, /**< Video */ + FSDP_MEDIA_AUDIO, /**< Audio */ + FSDP_MEDIA_APPLICATION, /**< Application, such as whiteboard */ + FSDP_MEDIA_DATA, /**< bulk data */ + FSDP_MEDIA_CONTROL /**< Control channel */ +} fsdp_media_t; + +/** + * @short Transport protocol + * + * The transport protocol used depends on the address type. Initially, + * RTP over UDP Audio/Video Profile, and UDP are defined. + * + **/ +typedef enum +{ + FSDP_TP_UNDEFINED, /**< Not specified */ + FSDP_TP_RTP_AVP, /**< RTP Audio/Video Profile */ + FSDP_TP_UDP, /**< UDP */ + FSDP_TP_TCP, /**< TCP */ + FSDP_TP_UDPTL, /**< ITU-T T.38*/ + FSDP_TP_VAT, /**< old vat protocol (historic)*/ + FSDP_TP_OLD_RTP, /**< old rtp protocols (historic)*/ + FSDP_TP_H320 /**< TODO: add to the parser */ +} fsdp_transport_protocol_t; + +/** + * Session-level attributes whose value is specified as a character + * string in FreeSDP. These values are usually given to + * fsdp_get_strn_att() in order to get the corresponding value. + * + **/ +typedef enum +{ + FSDP_SESSION_STR_ATT_CATEGORY, + FSDP_SESSION_STR_ATT_KEYWORDS, + FSDP_SESSION_STR_ATT_TOOL, + FSDP_SESSION_STR_ATT_CHARSET, +} fsdp_session_str_att_t; + +/** + * @short FreeSDP SDP description media object. + * + * Object for media specific information in SDP descriptions. Each SDP + * description may include any number of media section. A + * fsdp_media_description_t object encapsulates the information in a + * media section, such as video, audio or whiteboard. + **/ +typedef struct fsdp_media_description_t_s fsdp_media_description_t; + +/** + * @short FreeSDP SDP session description object. + * + * Contains all the information extracted from a textual SDP + * description, including all the media announcements. + **/ +typedef struct fsdp_description_t_s fsdp_description_t; + +/** + * Allocates memory and initializes values for a new + * fsdp_description_t object. If you call this routine, do not forget + * about <code>fsdp_description_delete()</code> + * + * @return new fsdp_description_t object + **/ +fsdp_description_t *fsdp_description_new (void); + +/** + * Destroys a fsdp_description_t object. + * + * @param dsc pointer to the fsdp_description_t object to delete. + **/ +void fsdp_description_delete (fsdp_description_t * dsc); + +/** + * Calling this function over a description is equivalent to calling + * fsdp_description_delete and then fsdp_description_delete. This + * function is however more suitable and efficient for description + * processing loops. + * + * @param dsc pointer to the fsdp_description_t object to + * renew/recycle. + **/ +void fsdp_description_recycle (fsdp_description_t * dsc); + +/** + * * Returns a string correspondent to the error number. + * * + * * @param err_no error number. + * **/ +const char *fsdp_strerror (fsdp_error_t err_no); + + /*@}*//* closes addtogroup common */ + +END_C_DECLS +#endif /* FSDP_COMMON_H */ diff --git a/libmpdemux/freesdp/errorlist.c b/libmpdemux/freesdp/errorlist.c new file mode 100644 index 0000000000..e934cd6da5 --- /dev/null +++ b/libmpdemux/freesdp/errorlist.c @@ -0,0 +1,72 @@ +/* + This file is part of FreeSDP + Copyright (C) 2001, 2002 Federico Montesino Pouzols <fedemp@suidzer0.org> + + FreeSDP is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/** + * @file errorlist.c + * + * @short Translation table for error numbers + * + */ + +#ifndef FSDP_ERRORLIST_C +#define FSDP_ERRORLIST_C + +#include "common.h" + +const char *fsdp_error_t_s[] = { + "No error",/** FSDPE_OK **/ + "Illegal character detected",/** FSDPE_ILLEGAL_CHARACTER **/ + "Missing version item", /** FSDPE_MISSING_VERSION **/ + "Invalid version item", /** FSDPE_INVALID_VERSION **/ + "Owner item not present", /** FSDPE_MISSING_OWNER **/ + "Parse error in owner item", /** FSDPE_INVALID_OWNER **/ + "Session name not present", /** FSDPE_MISSING_NAME **/ + "Empty session name item", /** FSDPE_EMPTY_NAME **/ + "Syntax error in connection item", /** FSDPE_INVALID_CONNECTION **/ + "Unrecognized address type in connection item", /** FSDPE_INVALID_CONNECTION_ADDRTYPE **/ + "Unrecognized network type in connection item", /** FSDPE_INVALID_CONNECTION_NETTYPE **/ + "Parse error in bandwith item", /** FSDPE_INVALID_BANDWIDTH **/ + "No time period for the session", /** FSDPE_MISSING_TIME **/ + "Parse error in time item", /** FSDPE_INVALID_TIME **/ + "Parse error in repeat time item", /** FSDPE_INVALID_REPEAT **/ + "Parse error in timezone item", /** FSDPE_INVALID_TIMEZONE **/ + "Unknown encryption method", /** FSDPE_INVALID_ENCRYPTION_METHOD **/ + "Syntax error in an attribute item", /** FSDPE_INVALID_ATTRIBUTE **/ + "Syntax error in an rtpmap attribute item", /** FSDPE_INVALID_ATTRIBUTE_RTPMAP **/ + "Unknown session type in a session-level attribute", /** FSDPE_INVALID_SESSION_TYPE **/ + "Parse error in media item", /** FSDPE_INVALID_MEDIA **/ + "Unknown media type in media item", /** FSDPE_UNKNOWN_MEDIA_TYPE **/ + "Unknown media transport", /** FSDPE_UNKNOWN_MEDIA_TRANSPORT **/ + "Unknown extra lines in description item", /** FSDPE_OVERFILLED **/ + "Unknown line found", /** FSDPE_INVALID_LINE **/ + "No connection information provided", /** FSDPE_MISSING_CONNECTION_INFO **/ + "Description item does not fit in MAXSIZE", /** FSDPE_INVALID_INDEX **/ + "Internal error", /** FSDPE_INTERNAL_ERROR **/ + "Invalid function parameters", /** FSDPE_INVALID_PARAMETER **/ + "Buffer overflow" /** FSDPE_BUFFER_OVERFLOW **/ +}; + + +const char * +fsdp_strerror (fsdp_error_t err_no) +{ + return (fsdp_error_t_s[err_no]); +} + +#endif diff --git a/libmpdemux/freesdp/parser.c b/libmpdemux/freesdp/parser.c new file mode 100644 index 0000000000..b92ddd4862 --- /dev/null +++ b/libmpdemux/freesdp/parser.c @@ -0,0 +1,1958 @@ +/* + This file is part of FreeSDP + Copyright (C) 2001,2002,2003 Federico Montesino Pouzols <fedemp@altern.org> + + FreeSDP is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Benjamin Zores, (C) 2006 + added support in parser for the a=control: lines. + added support in parser for the a=range: lines. +*/ + +/** + * @file parser.c + * + * @short Parsing module implementation. + * + * This file implements the parsing routine <code>fsdp_parse</code> + * and the <code>fsdp_get_xxxx</code> routines that allow to get the + * session properties from a session description object build through + * the application of <code>fsdp_parse</code> to a textual SDP session + * description. + **/ + +#include "parserpriv.h" + +/** + * Moves the <code>c<code> pointer up to the beginning of the next + * line. + * + * @param c char pointer to pointer + * @retval FSDPE_ILLEGAL_CHARACTER, when an illegal '\r' character + * (not followed by a '\n') is found, returns + */ +#define NEXT_LINE(c) \ +({ \ + while ((*(c) != '\0') && (*(c) != '\r') && (*(c) != '\n')) { \ + (c)++; \ + } \ + if (*(c) == '\n') { \ + (c)++; \ + } else if (*(c) == '\r') { \ + (c)++; \ + if (*(c) == '\n') { \ + (c)++; \ + } else { \ + return FSDPE_ILLEGAL_CHARACTER; \ + } \ + } \ +}) + +fsdp_error_t +fsdp_parse (const char *text_description, fsdp_description_t * dsc) +{ + fsdp_error_t result; + const char *p = text_description, *p2; + unsigned int index, j; + /* temps for sscanf */ + const unsigned int TEMPCHARS = 6; + char fsdp_buf[TEMPCHARS][MAXSHORTFIELDLEN]; + char longfsdp_buf[MAXLONGFIELDLEN]; + const unsigned int TEMPINTS = 2; + unsigned long int wuint[TEMPINTS]; + + if ((NULL == text_description) || (NULL == dsc)) + return FSDPE_INVALID_PARAMETER; + + /***************************************************************************/ + /* A) parse session-level description */ + /***************************************************************************/ + + /* `v=' line (protocol version) */ + /* according to the RFC, only `v=0' is valid */ + if (sscanf (p, "v=%1lu", &wuint[0])) + { + if (wuint[0] != 0) + return FSDPE_INVALID_VERSION; + } + else + { + return FSDPE_MISSING_VERSION; + } + NEXT_LINE (p); + + /* `o=' line (owner/creator and session identifier) */ + /* o=<username> <session id> <version> <network type> <address type> + <address> */ + if (!strncmp (p, "o=", 2)) + { + p += 2; + /* note that the following max lengths may vary in the future and + are quite arbitary */ + if (sscanf + (p, + "%" MSFLENS "[\x21-\xFF] %" MSFLENS "[0-9] %" MSFLENS + "[0-9] %2s %3s %" MSFLENS "s", fsdp_buf[0], fsdp_buf[1], + fsdp_buf[2], fsdp_buf[3], fsdp_buf[4], fsdp_buf[5]) != 6) + return FSDPE_INVALID_OWNER; + dsc->o_username = strdup (fsdp_buf[0]); + dsc->o_session_id = strdup (fsdp_buf[1]); + dsc->o_announcement_version = strdup (fsdp_buf[2]); + if (!strncmp (fsdp_buf[3], "IN", 2)) + { + dsc->o_network_type = FSDP_NETWORK_TYPE_INET; + if (!strncmp (fsdp_buf[4], "IP4", 3)) + dsc->o_address_type = FSDP_ADDRESS_TYPE_IPV4; + else if (!strncmp (fsdp_buf[4], "IP6", 3)) + dsc->o_address_type = FSDP_ADDRESS_TYPE_IPV6; + else + return FSDPE_INVALID_OWNER; + } + else + { + return FSDPE_INVALID_OWNER; + } + /* TODO? check valid unicast address/FQDN */ + dsc->o_address = strdup (fsdp_buf[5]); + } + else + { + return FSDPE_MISSING_OWNER; + } + NEXT_LINE (p); + + /* `s=' line (session name) -note that the name string cannot be empty */ + /* s=<session name> */ + if (!strncmp (p, "s=", 2)) + { + if (sscanf (p, "s=%" MLFLENS "[^\r\n]", longfsdp_buf) < 1) + return FSDPE_EMPTY_NAME; + dsc->s_name = strdup (longfsdp_buf); + } + else + { + return FSDPE_MISSING_NAME; + } + NEXT_LINE (p); + + /* `i=' line (session information) [optional] */ + /* i=<session description> */ + if (!strncmp (p, "i=", 2) + && sscanf (p, "i=%" MLFLENS "[^\r\n]", longfsdp_buf)) + { + dsc->i_information = strdup (longfsdp_buf); + NEXT_LINE (p); + } + else + { + /* (optional) information absent */ + } + + /* `u=' line (URI of description) [optional] */ + /* u=<URI> */ + if (!strncmp (p, "u=", 2) + && sscanf (p, "u=%" MLFLENS "[^\r\n]", longfsdp_buf)) + { + /* TODO? check valid uri */ + dsc->u_uri = strdup (longfsdp_buf); + NEXT_LINE (p); + } + else + { + /* (optional) uri absent */ + } + + /* `e=' lines (email address) [zero or more] */ + /* e=<email address> */ + p2 = p; + j = 0; + while (!strncmp (p2, "e=", 2)) + { + /* First, count how many emails are there */ + j++; + NEXT_LINE (p2); + } + dsc->emails_count = j; + if (dsc->emails_count > 0) + { + /* Then, build the array of emails */ + dsc->emails = calloc (j, sizeof (const char *)); + for (j = 0; j < dsc->emails_count; j++) + { + sscanf (p, "e=%" MLFLENS "[^\r\n]", longfsdp_buf); + /* TODO? check valid email-address. */ + dsc->emails[j] = strdup (longfsdp_buf); + NEXT_LINE (p); + } + } + + /* `p=' lines (phone number) [zero or more] */ + /* p=<phone number> */ + j = 0; + /* assert ( p2 == p ); */ + while (!strncmp (p2, "p=", 2)) + { + j++; + NEXT_LINE (p2); + } + dsc->phones_count = j; + if (dsc->phones_count > 0) + { + dsc->phones = calloc (j, sizeof (const char *)); + for (j = 0; j < dsc->phones_count; j++) + { + sscanf (p, "p=%" MLFLENS "[^\r\n]", longfsdp_buf); + /* TODO? check valid phone-number. */ + dsc->phones[j] = strdup (longfsdp_buf); + NEXT_LINE (p); + } + } + + /* `c=' line (connection information - not required if included in all media) [optional] */ + /* c=<network type> <address type> <connection address> */ + result = fsdp_parse_c (&p, &(dsc->c_network_type), &(dsc->c_address_type), + &(dsc->c_address)); + if (FSDPE_OK != result) + return result; + + /* `b=' lines (bandwidth information) [optional] */ + /* b=<modifier>:<bandwidth-value> */ + result = + fsdp_parse_b (&p, &(dsc->bw_modifiers), &(dsc->bw_modifiers_count)); + if (FSDPE_OK != result) + return result; + + /* A.1) Time descriptions: */ + + /* `t=' lines (time the session is active) [1 or more] */ + /* t=<start time> <stop time> */ + j = 0; + p2 = p; + while (!strncmp (p2, "t=", 2)) + { + j++; + NEXT_LINE (p2); |