summaryrefslogtreecommitdiffstats
path: root/stream/freesdp
diff options
context:
space:
mode:
authorben <ben@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-07-31 17:39:17 +0000
committerben <ben@b3059339-0415-0410-9bf9-f77b7e298cf2>2006-07-31 17:39:17 +0000
commit49867bd432352d19172ab26cf873bd5651e69e25 (patch)
treec2d419bb4f81564036baa12832a44b8aac27c6d1 /stream/freesdp
parentd3b998da64927403879ad588287c178f86b7c849 (diff)
downloadmpv-49867bd432352d19172ab26cf873bd5651e69e25.tar.bz2
mpv-49867bd432352d19172ab26cf873bd5651e69e25.tar.xz
introduce new 'stream' directory for all stream layer related components and split them from libmpdemux
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@19277 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'stream/freesdp')
-rw-r--r--stream/freesdp/common.c226
-rw-r--r--stream/freesdp/common.h352
-rw-r--r--stream/freesdp/errorlist.c72
-rw-r--r--stream/freesdp/parser.c1958
-rw-r--r--stream/freesdp/parser.h728
-rw-r--r--stream/freesdp/parserpriv.h118
-rw-r--r--stream/freesdp/priv.h274
7 files changed, 3728 insertions, 0 deletions
diff --git a/stream/freesdp/common.c b/stream/freesdp/common.c
new file mode 100644
index 0000000000..6ea625d2ed
--- /dev/null
+++ b/stream/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/stream/freesdp/common.h b/stream/freesdp/common.h
new file mode 100644
index 0000000000..ae59406049
--- /dev/null
+++ b/stream/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/stream/freesdp/errorlist.c b/stream/freesdp/errorlist.c
new file mode 100644
index 0000000000..e934cd6da5
--- /dev/null
+++ b/stream/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/stream/freesdp/parser.c b/stream/freesdp/parser.c
new file mode 100644
index 0000000000..0d6f97238f
--- /dev/null
+++ b/stream/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);
+ while (!strncmp (p2, "r=", 2))
+ NEXT_LINE (p2);
+ }
+ dsc->time_periods_count = j;
+ if (dsc->time_periods_count == 0)
+ return FSDPE_MISSING_TIME;
+ dsc->time_periods = calloc (dsc->time_periods_count,
+ sizeof (fsdp_time_period_t *));
+ index = 0;
+ for (j = 0; j < dsc->time_periods_count; j++)
+ {
+ unsigned int h = 0;
+ if (sscanf (p, "t=%10lu %10lu", &wuint[0], &wuint[1]) != 2)
+ {
+ /* not all periods have been successfully parsed */
+ dsc->time_periods_count = j;
+ return FSDPE_INVALID_TIME;
+ }
+ dsc->time_periods[j] = calloc (1, sizeof (fsdp_time_period_t));
+
+ /* convert from NTP to time_t time */
+ if (wuint[0] != 0)
+ wuint[0] -= NTP_EPOCH_OFFSET;
+ if (wuint[1] != 0)
+ wuint[1] -= NTP_EPOCH_OFFSET;
+ dsc->time_periods[j]->start = wuint[0];
+ dsc->time_periods[j]->stop = wuint[1];
+ NEXT_LINE (p);
+
+ /* `r' lines [zero or more repeat times for each t=] */
+ /*r=<repeat interval> <active duration