diff options
Diffstat (limited to 'gst-libs/gst/sdp/gstsdpmessage.c')
-rw-r--r-- | gst-libs/gst/sdp/gstsdpmessage.c | 2039 |
1 files changed, 0 insertions, 2039 deletions
diff --git a/gst-libs/gst/sdp/gstsdpmessage.c b/gst-libs/gst/sdp/gstsdpmessage.c deleted file mode 100644 index 5495abc3..00000000 --- a/gst-libs/gst/sdp/gstsdpmessage.c +++ /dev/null @@ -1,2039 +0,0 @@ -/* GStreamer - * Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library 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. - */ -/* - * Unless otherwise indicated, Source Code is licensed under MIT license. - * See further explanation attached in License Statement (distributed in the file - * LICENSE). - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * SECTION:gstsdpmessage - * @short_description: Helper methods for dealing with SDP messages - * - * <refsect2> - * <para> - * The GstSDPMessage helper functions makes it easy to parse and create SDP - * messages. - * </para> - * </refsect2> - * - * Last reviewed on 2007-07-24 (0.10.14) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#include <glib.h> /* for G_OS_WIN32 */ -#include <gst/gstinfo.h> /* For GST_STR_NULL */ - -#ifdef G_OS_WIN32 -/* ws2_32.dll has getaddrinfo and freeaddrinfo on Windows XP and later. - * minwg32 headers check WINVER before allowing the use of these */ -#ifndef WINVER -#define WINVER 0x0501 -#endif -#ifdef _MSC_VER -#include <Winsock2.h> -#endif -#include <ws2tcpip.h> -#else -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#endif - -#include "gstsdpmessage.h" - -/* FIXME, is currently allocated on the stack */ -#define MAX_LINE_LEN 1024 * 16 - -#define FREE_STRING(field) g_free (field); (field) = NULL -#define REPLACE_STRING(field, val) FREE_STRING(field); (field) = g_strdup (val) - -#define INIT_ARRAY(field, type, init_func) \ -G_STMT_START { \ - if (field) { \ - guint i; \ - for(i = 0; i < (field)->len; i++) \ - init_func (&g_array_index ((field), type, i)); \ - g_array_set_size ((field), 0); \ - } \ - else \ - (field) = g_array_new (FALSE, TRUE, sizeof (type)); \ -} G_STMT_END - -#define FREE_ARRAY(field) \ -G_STMT_START { \ - if (field) \ - g_array_free ((field), TRUE); \ - (field) = NULL; \ -} G_STMT_END - -#define INIT_PTR_ARRAY(field, type, init_func) \ -G_STMT_START { \ - if (field) { \ - guint i; \ - for(i = 0; i < (field)->len; i++) \ - init_func (g_array_index ((field), type, i)); \ - g_array_set_size ((field), 0); \ - } \ - else \ - (field) = g_array_new (FALSE, TRUE, sizeof (type)); \ -} G_STMT_END - -#define FREE_PTR_ARRAY(field) FREE_ARRAY(field) - -#define DEFINE_STRING_SETTER(field) \ -GstSDPResult gst_sdp_message_set_##field (GstSDPMessage *msg, const gchar *val) { \ - g_free (msg->field); \ - msg->field = g_strdup (val); \ - return GST_SDP_OK; \ -} -#define DEFINE_STRING_GETTER(field) \ -const gchar* gst_sdp_message_get_##field (const GstSDPMessage *msg) { \ - return msg->field; \ -} - -#define DEFINE_ARRAY_LEN(field) \ -guint gst_sdp_message_##field##_len (const GstSDPMessage *msg) { \ - return msg->field->len; \ -} -#define DEFINE_ARRAY_GETTER(method, field, type) \ -type * gst_sdp_message_get_##method (const GstSDPMessage *msg, guint idx) { \ - return &g_array_index (msg->field, type, idx); \ -} - -#define DEFINE_PTR_ARRAY_LEN(field) DEFINE_ARRAY_LEN(field) -#define DEFINE_PTR_ARRAY_GETTER(method, field, type) \ -type gst_sdp_message_get_##method (const GstSDPMessage *msg, guint idx) { \ - return g_array_index (msg->field, type, idx); \ -} -#define DEFINE_PTR_ARRAY_ADDER(method, field, type, dup_method) \ -GstSDPResult gst_sdp_message_add_##method (GstSDPMessage *msg, type val) { \ - type v = dup_method (val); \ - g_array_append_val (msg->field, v); \ - return GST_SDP_OK; \ -} - -static void -gst_sdp_origin_init (GstSDPOrigin * origin) -{ - FREE_STRING (origin->username); - FREE_STRING (origin->sess_id); - FREE_STRING (origin->sess_version); - FREE_STRING (origin->nettype); - FREE_STRING (origin->addrtype); - FREE_STRING (origin->addr); -} - -static void -gst_sdp_connection_init (GstSDPConnection * connection) -{ - FREE_STRING (connection->nettype); - FREE_STRING (connection->addrtype); - FREE_STRING (connection->address); - connection->ttl = 0; - connection->addr_number = 0; -} - -static void -gst_sdp_bandwidth_init (GstSDPBandwidth * bandwidth) -{ - FREE_STRING (bandwidth->bwtype); - bandwidth->bandwidth = 0; -} - -static void -gst_sdp_time_init (GstSDPTime * t) -{ - FREE_STRING (t->start); - FREE_STRING (t->stop); - INIT_PTR_ARRAY (t->repeat, gchar *, g_free); - FREE_PTR_ARRAY (t->repeat); -} - -static void -gst_sdp_zone_init (GstSDPZone * zone) -{ - FREE_STRING (zone->time); - FREE_STRING (zone->typed_time); -} - -static void -gst_sdp_key_init (GstSDPKey * key) -{ - FREE_STRING (key->type); - FREE_STRING (key->data); -} - -static void -gst_sdp_attribute_init (GstSDPAttribute * attr) -{ - FREE_STRING (attr->key); - FREE_STRING (attr->value); -} - -/** - * gst_sdp_message_new: - * @msg: pointer to new #GstSDPMessage - * - * Allocate a new GstSDPMessage and store the result in @msg. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_message_new (GstSDPMessage ** msg) -{ - GstSDPMessage *newmsg; - - g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL); - - newmsg = g_new0 (GstSDPMessage, 1); - - *msg = newmsg; - - return gst_sdp_message_init (newmsg); -} - -/** - * gst_sdp_message_init: - * @msg: a #GstSDPMessage - * - * Initialize @msg so that its contents are as if it was freshly allocated - * with gst_sdp_message_new(). This function is mostly used to initialize a message - * allocated on the stack. gst_sdp_message_uninit() undoes this operation. - * - * When this function is invoked on newly allocated data (with malloc or on the - * stack), its contents should be set to 0 before calling this function. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_message_init (GstSDPMessage * msg) -{ - g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL); - - FREE_STRING (msg->version); - gst_sdp_origin_init (&msg->origin); - FREE_STRING (msg->session_name); - FREE_STRING (msg->information); - FREE_STRING (msg->uri); - INIT_PTR_ARRAY (msg->emails, gchar *, g_free); - INIT_PTR_ARRAY (msg->phones, gchar *, g_free); - gst_sdp_connection_init (&msg->connection); - INIT_ARRAY (msg->bandwidths, GstSDPBandwidth, gst_sdp_bandwidth_init); - INIT_ARRAY (msg->times, GstSDPTime, gst_sdp_time_init); - INIT_ARRAY (msg->zones, GstSDPZone, gst_sdp_zone_init); - gst_sdp_key_init (&msg->key); - INIT_ARRAY (msg->attributes, GstSDPAttribute, gst_sdp_attribute_init); - INIT_ARRAY (msg->medias, GstSDPMedia, gst_sdp_media_uninit); - - return GST_SDP_OK; -} - -/** - * gst_sdp_message_uninit: - * @msg: a #GstSDPMessage - * - * Free all resources allocated in @msg. @msg should not be used anymore after - * this function. This function should be used when @msg was allocated on the - * stack and initialized with gst_sdp_message_init(). - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_message_uninit (GstSDPMessage * msg) -{ - g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL); - - gst_sdp_message_init (msg); - - FREE_PTR_ARRAY (msg->emails); - FREE_PTR_ARRAY (msg->phones); - FREE_ARRAY (msg->bandwidths); - FREE_ARRAY (msg->times); - FREE_ARRAY (msg->zones); - FREE_ARRAY (msg->attributes); - FREE_ARRAY (msg->medias); - - return GST_SDP_OK; -} - -/** - * gst_sdp_message_free: - * @msg: a #GstSDPMessage - * - * Free all resources allocated by @msg. @msg should not be used anymore after - * this function. This function should be used when @msg was dynamically - * allocated with gst_sdp_message_new(). - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_message_free (GstSDPMessage * msg) -{ - g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL); - - gst_sdp_message_uninit (msg); - g_free (msg); - - return GST_SDP_OK; -} - -static gboolean -is_multicast_address (const gchar * host_name, guint * family) -{ - struct addrinfo hints; - struct addrinfo *ai; - struct addrinfo *res; - gboolean ret = FALSE; - - memset (&hints, 0, sizeof (hints)); - hints.ai_socktype = SOCK_DGRAM; - - g_return_val_if_fail (host_name, FALSE); - - if (getaddrinfo (host_name, NULL, &hints, &res) < 0) - return FALSE; - - for (ai = res; !ret && ai; ai = ai->ai_next) { - if (ai->ai_family == AF_INET) - ret = - IN_MULTICAST (ntohl (((struct sockaddr_in *) ai->ai_addr)->sin_addr. - s_addr)); - else - ret = - IN6_IS_ADDR_MULTICAST (&((struct sockaddr_in6 *) ai->ai_addr)-> - sin6_addr); - if (ret && family) - *family = ai->ai_family; - } - - freeaddrinfo (res); - - return ret; -} - -/** - * gst_sdp_message_as_text: - * @msg: a #GstSDPMessage - * - * Convert the contents of @msg to a text string. - * - * Returns: A dynamically allocated string representing the SDP description. - */ -gchar * -gst_sdp_message_as_text (const GstSDPMessage * msg) -{ - /* change all vars so they match rfc? */ - GString *lines; - guint i; - - g_return_val_if_fail (msg != NULL, NULL); - - lines = g_string_new (""); - - if (msg->version) - g_string_append_printf (lines, "v=%s\r\n", msg->version); - - if (msg->origin.sess_id && msg->origin.sess_version && msg->origin.nettype && - msg->origin.addrtype && msg->origin.addr) - g_string_append_printf (lines, "o=%s %s %s %s %s %s\r\n", - msg->origin.username ? msg->origin.username : "-", msg->origin.sess_id, - msg->origin.sess_version, msg->origin.nettype, msg->origin.addrtype, - msg->origin.addr); - - if (msg->session_name) - g_string_append_printf (lines, "s=%s\r\n", msg->session_name); - - if (msg->information) - g_string_append_printf (lines, "i=%s\r\n", msg->information); - - if (msg->uri) - g_string_append_printf (lines, "u=%s\r\n", msg->uri); - - for (i = 0; i < gst_sdp_message_emails_len (msg); i++) - g_string_append_printf (lines, "e=%s\r\n", - gst_sdp_message_get_email (msg, i)); - - for (i = 0; i < gst_sdp_message_phones_len (msg); i++) - g_string_append_printf (lines, "p=%s\r\n", - gst_sdp_message_get_phone (msg, i)); - - if (gst_sdp_message_emails_len (msg) == 0 && - gst_sdp_message_phones_len (msg) == 0) - g_string_append_printf (lines, "e=NONE\r\n"); - - if (msg->connection.nettype && msg->connection.addrtype && - msg->connection.address) { - guint family; - - g_string_append_printf (lines, "c=%s %s %s", msg->connection.nettype, - msg->connection.addrtype, msg->connection.address); - if (is_multicast_address (msg->connection.address, &family)) { - if (family == AF_INET) - g_string_append_printf (lines, "/%u", msg->connection.ttl); - if (msg->connection.addr_number > 1) - g_string_append_printf (lines, "/%u", msg->connection.addr_number); - } - g_string_append_printf (lines, "\r\n"); - } - - for (i = 0; i < gst_sdp_message_bandwidths_len (msg); i++) { - const GstSDPBandwidth *bandwidth = gst_sdp_message_get_bandwidth (msg, i); - - g_string_append_printf (lines, "b=%s:%u\r\n", bandwidth->bwtype, - bandwidth->bandwidth); - } - - for (i = 0; i < gst_sdp_message_times_len (msg); i++) { - const GstSDPTime *times = gst_sdp_message_get_time (msg, i); - - g_string_append_printf (lines, "t=%s %s\r\n", times->start, times->stop); - - if (times->repeat != NULL) { - guint j; - - g_string_append_printf (lines, "r=%s", - g_array_index (times->repeat, gchar *, 0)); - for (j = 1; j < times->repeat->len; j++) - g_string_append_printf (lines, " %s", - g_array_index (times->repeat, gchar *, j)); - g_string_append_printf (lines, "\r\n"); - } - } - - if (gst_sdp_message_zones_len (msg) > 0) { - const GstSDPZone *zone = gst_sdp_message_get_zone (msg, 0); - - g_string_append_printf (lines, "z=%s %s", zone->time, zone->typed_time); - for (i = 1; i < gst_sdp_message_zones_len (msg); i++) { - zone = gst_sdp_message_get_zone (msg, i); - g_string_append_printf (lines, " %s %s", zone->time, zone->typed_time); - } - g_string_append_printf (lines, "\r\n"); - } - - if (msg->key.type) { - g_string_append_printf (lines, "k=%s", msg->key.type); - if (msg->key.data) - g_string_append_printf (lines, ":%s", msg->key.data); - g_string_append_printf (lines, "\r\n"); - } - - for (i = 0; i < gst_sdp_message_attributes_len (msg); i++) { - const GstSDPAttribute *attr = gst_sdp_message_get_attribute (msg, i); - - if (attr->key) { - g_string_append_printf (lines, "a=%s", attr->key); - if (attr->value) - g_string_append_printf (lines, ":%s", attr->value); - g_string_append_printf (lines, "\r\n"); - } - } - - for (i = 0; i < gst_sdp_message_medias_len (msg); i++) { - const GstSDPMedia *media = gst_sdp_message_get_media (msg, i); - gchar *sdp_media_str; - - sdp_media_str = gst_sdp_media_as_text (media); - g_string_append_printf (lines, "%s", sdp_media_str); - g_free (sdp_media_str); - } - - return g_string_free (lines, FALSE); -} - -/** - * gst_sdp_message_set_version: - * @msg: a #GstSDPMessage - * @version: the version - * - * Set the version in @msg. - * - * Returns: a #GstSDPResult. - */ -DEFINE_STRING_SETTER (version); -/** - * gst_sdp_message_get_version: - * @msg: a #GstSDPMessage - * - * Get the version in @msg. - * - * Returns: a #GstSDPResult. - */ -DEFINE_STRING_GETTER (version); - -/** - * gst_sdp_message_set_origin: - * @msg: a #GstSDPMessage - * @username: the user name - * @sess_id: a session id - * @sess_version: a session version - * @nettype: a network type - * @addrtype: an address type - * @addr: an address - * - * Configure the SDP origin in @msg with the given parameters. - * - * Returns: #GST_SDP_OK. - */ -GstSDPResult -gst_sdp_message_set_origin (GstSDPMessage * msg, const gchar * username, - const gchar * sess_id, const gchar * sess_version, const gchar * nettype, - const gchar * addrtype, const gchar * addr) -{ - REPLACE_STRING (msg->origin.username, username); - REPLACE_STRING (msg->origin.sess_id, sess_id); - REPLACE_STRING (msg->origin.sess_version, sess_version); - REPLACE_STRING (msg->origin.nettype, nettype); - REPLACE_STRING (msg->origin.addrtype, addrtype); - REPLACE_STRING (msg->origin.addr, addr); - - return GST_SDP_OK; -} - -/** - * gst_sdp_message_get_origin: - * @msg: a #GstSDPMessage - * - * Get the origin of @msg. - * - * Returns: a #GstSDPOrigin. The result remains valid as long as @msg is valid. - */ -const GstSDPOrigin * -gst_sdp_message_get_origin (const GstSDPMessage * msg) -{ - return &msg->origin; -} - -/** - * gst_sdp_message_set_session_name: - * @msg: a #GstSDPMessage - * @session_name: the session name - * - * Set the session name in @msg. - * - * Returns: a #GstSDPResult. - */ -DEFINE_STRING_SETTER (session_name); -/** - * gst_sdp_message_get_session_name: - * @msg: a #GstSDPMessage - * - * Get the session name in @msg. - * - * Returns: a #GstSDPResult. - */ -DEFINE_STRING_GETTER (session_name); -/** - * gst_sdp_message_set_information: - * @msg: a #GstSDPMessage - * @information: the information - * - * Set the information in @msg. - * - * Returns: a #GstSDPResult. - */ -DEFINE_STRING_SETTER (information); -/** - * gst_sdp_message_get_information: - * @msg: a #GstSDPMessage - * - * Get the information in @msg. - * - * Returns: a #GstSDPResult. - */ -DEFINE_STRING_GETTER (information); -/** - * gst_sdp_message_set_uri: - * @msg: a #GstSDPMessage - * @uri: the URI - * - * Set the URI in @msg. - * - * Returns: a #GstSDPResult. - */ -DEFINE_STRING_SETTER (uri); -/** - * gst_sdp_message_get_uri: - * @msg: a #GstSDPMessage - * - * Get the URI in @msg. - * - * Returns: a #GstSDPResult. - */ -DEFINE_STRING_GETTER (uri); - -/** - * gst_sdp_message_emails_len: - * @msg: a #GstSDPMessage - * - * Get the number of emails in @msg. - * - * Returns: the number of emails in @msg. - */ -DEFINE_ARRAY_LEN (emails); -/** - * gst_sdp_message_get_email: - * @msg: a #GstSDPMessage - * @idx: an email index - * - * Get the email with number @idx from @msg. - * - * Returns: the email at position @idx. - */ -DEFINE_PTR_ARRAY_GETTER (email, emails, const gchar *); - -/** - * gst_sdp_message_add_email: - * @msg: a #GstSDPMessage - * @email: an email - * - * Add @email to the list of emails in @msg. - * - * Returns: a #GstSDPResult. - */ -DEFINE_PTR_ARRAY_ADDER (email, emails, const gchar *, g_strdup); - -/** - * gst_sdp_message_phones_len: - * @msg: a #GstSDPMessage - * - * Get the number of phones in @msg. - * - * Returns: the number of phones in @msg. - */ -DEFINE_ARRAY_LEN (phones); -/** - * gst_sdp_message_get_phone: - * @msg: a #GstSDPMessage - * @idx: a phone index - * - * Get the phone with number @idx from @msg. - * - * Returns: the phone at position @idx. - */ -DEFINE_PTR_ARRAY_GETTER (phone, phones, const gchar *); - -/** - * gst_sdp_message_add_phone: - * @msg: a #GstSDPMessage - * @phone: a phone - * - * Add @phone to the list of phones in @msg. - * - * Returns: a #GstSDPResult. - */ -DEFINE_PTR_ARRAY_ADDER (phone, phones, const gchar *, g_strdup); - -/** - * gst_sdp_message_set_connection: - * @msg: a #GstSDPMessage - * @nettype: the type of network. "IN" is defined to have the meaning - * "Internet". - * @addrtype: the type of address. - * @address: the address - * @ttl: the time to live of the address - * @addr_number: the number of layers - * - * Configure the SDP connection in @msg with the given parameters. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_message_set_connection (GstSDPMessage * msg, const gchar * nettype, - const gchar * addrtype, const gchar * address, guint ttl, guint addr_number) -{ - REPLACE_STRING (msg->connection.nettype, nettype); - REPLACE_STRING (msg->connection.addrtype, addrtype); - REPLACE_STRING (msg->connection.address, address); - msg->connection.ttl = ttl; - msg->connection.addr_number = addr_number; - - return GST_SDP_OK; -} - -/** - * gst_sdp_message_get_connection: - * @msg: a #GstSDPMessage - * - * Get the connection of @msg. - * - * Returns: a #GstSDPConnection. The result remains valid as long as @msg is valid. - */ -const GstSDPConnection * -gst_sdp_message_get_connection (const GstSDPMessage * msg) -{ - return &msg->connection; -} - -/** - * gst_sdp_message_bandwidths_len: - * @msg: a #GstSDPMessage - * - * Get the number of bandwidth information in @msg. - * - * Returns: the number of bandwidth information in @msg. - */ -DEFINE_ARRAY_LEN (bandwidths); -/** - * gst_sdp_message_get_bandwidth: - * @msg: a #GstSDPMessage - * @idx: the bandwidth index - * - * Get the bandwidth at index @idx from @msg. - * - * Returns: a #GstSDPBandwidth. - */ -DEFINE_ARRAY_GETTER (bandwidth, bandwidths, const GstSDPBandwidth); - -/** - * gst_sdp_message_add_bandwidth: - * @msg: a #GstSDPMessage - * @bwtype: the bandwidth modifier type - * @bandwidth: the bandwidth in kilobits per second - * - * Add the specified bandwidth information to @msg. - * - * Returns: a #GstSDPResult. - */ - -GstSDPResult -gst_sdp_message_add_bandwidth (GstSDPMessage * msg, const gchar * bwtype, - guint bandwidth) -{ - GstSDPBandwidth bw; - - bw.bwtype = g_strdup (bwtype); - bw.bandwidth = bandwidth; - - g_array_append_val (msg->bandwidths, bw); - - return GST_SDP_OK; -} - -/** - * gst_sdp_message_times_len: - * @msg: a #GstSDPMessage - * - * Get the number of time information entries in @msg. - * - * Returns: the number of time information entries in @msg. - */ -DEFINE_ARRAY_LEN (times); - -/** - * gst_sdp_message_get_time: - * @msg: a #GstSDPMessage - * @idx: the time index - * - * Get time information with index @idx from @msg. - * - * Returns: a #GstSDPTime. - */ -DEFINE_ARRAY_GETTER (time, times, const GstSDPTime); - -/** - * gst_sdp_message_add_time: - * @msg: a #GstSDPMessage - * @start: the start time - * @stop: the stop time - * @repeat: the repeat times - * - * Add time information @start and @stop to @msg. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_message_add_time (GstSDPMessage * msg, const gchar * start, - const gchar * stop, const gchar ** repeat) -{ - GstSDPTime times; - - times.start = g_strdup (start); - times.stop = g_strdup (stop); - if (repeat) { - times.repeat = g_array_new (FALSE, TRUE, sizeof (gchar *)); - for (; *repeat; repeat++) { - gchar *r = g_strdup (*repeat); - - g_array_append_val (times.repeat, r); - } - } else - times.repeat = NULL; - g_array_append_val (msg->times, times); - - return GST_SDP_OK; -} - -/** - * gst_sdp_message_zones_len: - * @msg: a #GstSDPMessage - * - * Get the number of time zone information entries in @msg. - * - * Returns: the number of time zone information entries in @msg. - */ -DEFINE_ARRAY_LEN (zones); -/** - * gst_sdp_message_get_zone: - * @msg: a #GstSDPMessage - * @idx: the zone index - * - * Get time zone information with index @idx from @msg. - * - * Returns: a #GstSDPZone. - */ -DEFINE_ARRAY_GETTER (zone, zones, const GstSDPZone); - -/** - * gst_sdp_message_add_zone: - * @msg: a #GstSDPMessage - * @adj_time: the NTP time that a time zone adjustment happens - * @typed_time: the offset from the time when the session was first scheduled - * - * Add time zone information to @msg. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_message_add_zone (GstSDPMessage * msg, const gchar * adj_time, - const gchar * typed_time) -{ - GstSDPZone zone; - - zone.time = g_strdup (adj_time); - zone.typed_time = g_strdup (typed_time); - - g_array_append_val (msg->zones, zone); - - return GST_SDP_OK; -} - -/** - * gst_sdp_message_set_key: - * @msg: a #GstSDPMessage - * @type: the encryption type - * @data: the encryption data - * - * Adds the encryption information to @msg. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_message_set_key (GstSDPMessage * msg, const gchar * type, - const gchar * data) -{ - REPLACE_STRING (msg->key.type, type); - REPLACE_STRING (msg->key.data, data); - - return GST_SDP_OK; -} - -/** - * gst_sdp_message_get_key: - * @msg: a #GstSDPMessage - * - * Get the encryption information from @msg. - * - * Returns: a #GstSDPKey. - */ -const GstSDPKey * -gst_sdp_message_get_key (const GstSDPMessage * msg) -{ - return &msg->key; -} - -/** - * gst_sdp_message_attributes_len: - * @msg: a #GstSDPMessage - * - * Get the number of attributes in @msg. - * - * Returns: the number of attributes in @msg. - */ -DEFINE_ARRAY_LEN (attributes); - -/** - * gst_sdp_message_get_attribute: - * @msg: a #GstSDPMessage - * @idx: the index - * - * Get the attribute at position @idx in @msg. - * - * Returns: the #GstSDPAttribute at position @idx. - */ -DEFINE_ARRAY_GETTER (attribute, attributes, const GstSDPAttribute); - -/** - * gst_sdp_message_get_attribute_val_n: - * @msg: a #GstSDPMessage - * @key: the key - * @nth: the index - * - * Get the @nth attribute with key @key in @msg. - * - * Returns: the attribute value of the @nth attribute with @key. - */ -const gchar * -gst_sdp_message_get_attribute_val_n (const GstSDPMessage * msg, - const gchar * key, guint nth) -{ - guint i; - - for (i = 0; i < msg->attributes->len; i++) { - GstSDPAttribute *attr; - - attr = &g_array_index (msg->attributes, GstSDPAttribute, i); - if (!strcmp (attr->key, key)) { - if (nth == 0) - return attr->value; - else - nth--; - } - } - return NULL; -} - -/** - * gst_sdp_message_get_attribute_val: - * @msg: a #GstSDPMessage - * @key: the key - * - * Get the first attribute with key @key in @msg. - * - * Returns: the attribute value of the first attribute with @key. - */ -const gchar * -gst_sdp_message_get_attribute_val (const GstSDPMessage * msg, const gchar * key) -{ - return gst_sdp_message_get_attribute_val_n (msg, key, 0); -} - -/** - * gst_sdp_message_add_attribute: - * @msg: a #GstSDPMessage - * @key: the key - * @value: the value - * - * Add the attribute with @key and @value to @msg. - * - * Returns: @GST_SDP_OK. - */ -GstSDPResult -gst_sdp_message_add_attribute (GstSDPMessage * msg, const gchar * key, - const gchar * value) -{ - GstSDPAttribute attr; - - attr.key = g_strdup (key); - attr.value = g_strdup (value); - - g_array_append_val (msg->attributes, attr); - - return GST_SDP_OK; -} - -/** - * gst_sdp_message_medias_len: - * @msg: a #GstSDPMessage - * - * Get the number of media descriptions in @msg. - * - * Returns: the number of media descriptions in @msg. - */ -DEFINE_ARRAY_LEN (medias); -/** - * gst_sdp_message_get_media: - * @msg: a #GstSDPMessage - * @idx: the index - * - * Get the media description at index @idx in @msg. - * - * Returns: a #GstSDPMedia. - */ -DEFINE_ARRAY_GETTER (media, medias, const GstSDPMedia); - -/** - * gst_sdp_message_add_media: - * @msg: a #GstSDPMessage - * @media: a #GstSDPMedia to add - * - * Adds @media to the array of medias in @msg. This function takes ownership of - * the contents of @media so that @media will have to be reinitialized with - * gst_media_init() before it can be used again. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_message_add_media (GstSDPMessage * msg, GstSDPMedia * media) -{ - guint len; - GstSDPMedia *nmedia; - - len = msg->medias->len; - g_array_set_size (msg->medias, len + 1); - nmedia = &g_array_index (msg->medias, GstSDPMedia, len); - - memcpy (nmedia, media, sizeof (GstSDPMedia)); - memset (media, 0, sizeof (GstSDPMedia)); - - return GST_SDP_OK; -} - -/* media access */ - -/** - * gst_sdp_media_new: - * @media: pointer to new #GstSDPMedia - * - * Allocate a new GstSDPMedia and store the result in @media. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_media_new (GstSDPMedia ** media) -{ - GstSDPMedia *newmedia; - - g_return_val_if_fail (media != NULL, GST_SDP_EINVAL); - - newmedia = g_new0 (GstSDPMedia, 1); - - *media = newmedia; - - return gst_sdp_media_init (newmedia); -} - -/** - * gst_sdp_media_init: - * @media: a #GstSDPMedia - * - * Initialize @media so that its contents are as if it was freshly allocated - * with gst_sdp_media_new(). This function is mostly used to initialize a media - * allocated on the stack. gst_sdp_media_uninit() undoes this operation. - * - * When this function is invoked on newly allocated data (with malloc or on the - * stack), its contents should be set to 0 before calling this function. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_media_init (GstSDPMedia * media) -{ - g_return_val_if_fail (media != NULL, GST_SDP_EINVAL); - - FREE_STRING (media->media); - media->port = 0; - media->num_ports = 0; - FREE_STRING (media->proto); - INIT_PTR_ARRAY (media->fmts, gchar *, g_free); - FREE_STRING (media->information); - INIT_ARRAY (media->connections, GstSDPConnection, gst_sdp_connection_init); - INIT_ARRAY (media->bandwidths, GstSDPBandwidth, gst_sdp_bandwidth_init); - gst_sdp_key_init (&media->key); - INIT_ARRAY (media->attributes, GstSDPAttribute, gst_sdp_attribute_init); - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_uninit: - * @media: a #GstSDPMedia - * - * Free all resources allocated in @media. @media should not be used anymore after - * this function. This function should be used when @media was allocated on the - * stack and initialized with gst_sdp_media_init(). - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_media_uninit (GstSDPMedia * media) -{ - g_return_val_if_fail (media != NULL, GST_SDP_EINVAL); - - gst_sdp_media_init (media); - FREE_PTR_ARRAY (media->fmts); - FREE_ARRAY (media->connections); - FREE_ARRAY (media->bandwidths); - FREE_ARRAY (media->attributes); - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_free: - * @media: a #GstSDPMedia - * - * Free all resources allocated by @media. @media should not be used anymore after - * this function. This function should be used when @media was dynamically - * allocated with gst_sdp_media_new(). - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_media_free (GstSDPMedia * media) -{ - g_return_val_if_fail (media != NULL, GST_SDP_EINVAL); - - gst_sdp_media_uninit (media); - g_free (media); - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_as_text: - * @media: a #GstSDPMedia - * - * Convert the contents of @media to a text string. - * - * Returns: A dynamically allocated string representing the media. - */ -gchar * -gst_sdp_media_as_text (const GstSDPMedia * media) -{ - GString *lines; - guint i; - - g_return_val_if_fail (media != NULL, NULL); - - lines = g_string_new (""); - - if (media->media) - g_string_append_printf (lines, "m=%s", media->media); - - g_string_append_printf (lines, " %u", media->port); - - if (media->num_ports > 1) - g_string_append_printf (lines, "/%u", media->num_ports); - - g_string_append_printf (lines, " %s", media->proto); - - for (i = 0; i < gst_sdp_media_formats_len (media); i++) - g_string_append_printf (lines, " %s", gst_sdp_media_get_format (media, i)); - g_string_append_printf (lines, "\r\n"); - - if (media->information) - g_string_append_printf (lines, "i=%s", media->information); - - for (i = 0; i < gst_sdp_media_connections_len (media); i++) { - const GstSDPConnection *conn = gst_sdp_media_get_connection (media, i); - - if (conn->nettype && conn->addrtype && conn->address) { - guint family; - - g_string_append_printf (lines, "c=%s %s %s", conn->nettype, - conn->addrtype, conn->address); - if (is_multicast_address (conn->address, &family)) { - if (family == AF_INET) - g_string_append_printf (lines, "/%u", conn->ttl); - if (conn->addr_number > 1) - g_string_append_printf (lines, "/%u", conn->addr_number); - } - g_string_append_printf (lines, "\r\n"); - } - } - - for (i = 0; i < gst_sdp_media_bandwidths_len (media); i++) { - const GstSDPBandwidth *bandwidth = gst_sdp_media_get_bandwidth (media, i); - - g_string_append_printf (lines, "b=%s:%u\r\n", bandwidth->bwtype, - bandwidth->bandwidth); - } - - if (media->key.type) { - g_string_append_printf (lines, "k=%s", media->key.type); - if (media->key.data) - g_string_append_printf (lines, ":%s", media->key.data); - g_string_append_printf (lines, "\r\n"); - } - - for (i = 0; i < gst_sdp_media_attributes_len (media); i++) { - const GstSDPAttribute *attr = gst_sdp_media_get_attribute (media, i); - - if (attr->key) { - g_string_append_printf (lines, "a=%s", attr->key); - if (attr->value) - g_string_append_printf (lines, ":%s", attr->value); - g_string_append_printf (lines, "\r\n"); - } - } - - return g_string_free (lines, FALSE); -} - -/** - * gst_sdp_media_get_media: - * @media: a #GstSDPMedia - * - * Get the media description of @media. - * - * Returns: the media description. - */ -const gchar * -gst_sdp_media_get_media (const GstSDPMedia * media) -{ - return media->media; -} - -/** - * gst_sdp_media_set_media: - * @media: a #GstSDPMedia - * @med: the media description - * - * Set the media description of @media to @med. - * - * Returns: #GST_SDP_OK. - */ -GstSDPResult -gst_sdp_media_set_media (GstSDPMedia * media, const gchar * med) -{ - g_free (media->media); - media->media = g_strdup (med); - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_get_port: - * @media: a #GstSDPMedia - * - * Get the port number for @media. - * - * Returns: the port number of @media. - */ -guint -gst_sdp_media_get_port (const GstSDPMedia * media) -{ - return media->port; -} - -/** - * gst_sdp_media_get_num_ports: - * @media: a #GstSDPMedia - * - * Get the number of ports for @media. - * - * Returns: the number of ports for @media. - */ -guint -gst_sdp_media_get_num_ports (const GstSDPMedia * media) -{ - return media->num_ports; -} - -/** - * gst_sdp_media_set_port_info: - * @media: a #GstSDPMedia - * @port: the port number - * @num_ports: the number of ports - * - * Set the port information in @media. - * - * Returns: #GST_SDP_OK. - */ -GstSDPResult -gst_sdp_media_set_port_info (GstSDPMedia * media, guint port, guint num_ports) -{ - media->port = port; - media->num_ports = num_ports; - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_get_proto: - * @media: a #GstSDPMedia - * - * Get the transport protocol of @media - * - * Returns: the transport protocol of @media. - */ -const gchar * -gst_sdp_media_get_proto (const GstSDPMedia * media) -{ - return media->proto; -} - -/** - * gst_sdp_media_set_proto: - * @media: a #GstSDPMedia - * @proto: the media transport protocol - * - * Set the media transport protocol of @media to @proto. - * - * Returns: #GST_SDP_OK. - */ -GstSDPResult -gst_sdp_media_set_proto (GstSDPMedia * media, const gchar * proto) -{ - g_free (media->proto); - media->proto = g_strdup (proto); - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_formats_len: - * @media: a #GstSDPMedia - * - * Get the number of formats in @media. - * - * Returns: the number of formats in @media. - */ -guint -gst_sdp_media_formats_len (const GstSDPMedia * media) -{ - return media->fmts->len; -} - -/** - * gst_sdp_media_get_format: - * @media: a #GstSDPMedia - * @idx: an index - * - * Get the format information at position @idx in @media. - * - * Returns: the format at position @idx. - */ -const gchar * -gst_sdp_media_get_format (const GstSDPMedia * media, guint idx) -{ - if (idx >= media->fmts->len) - return NULL; - return g_array_index (media->fmts, gchar *, idx); -} - -/** - * gst_sdp_media_add_format: - * @media: a #GstSDPMedia - * @format: the format - * - * Add the format information to @media. - * - * Returns: #GST_SDP_OK. - */ -GstSDPResult -gst_sdp_media_add_format (GstSDPMedia * media, const gchar * format) -{ - gchar *fmt; - - fmt = g_strdup (format); - - g_array_append_val (media->fmts, fmt); - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_get_information: - * @media: a #GstSDPMedia - * - * Get the information of @media - * - * Returns: the information of @media. - */ -const gchar * -gst_sdp_media_get_information (const GstSDPMedia * media) -{ - return media->information; -} - -/** - * gst_sdp_media_set_information: - * @media: a #GstSDPMedia - * @information: the media information - * - * Set the media information of @media to @information. - * - * Returns: #GST_SDP_OK. - */ -GstSDPResult -gst_sdp_media_set_information (GstSDPMedia * media, const gchar * information) -{ - g_free (media->information); - media->information = g_strdup (information); - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_connections_len: - * @media: a #GstSDPMedia - * - * Get the number of connection fields in @media. - * - * Returns: the number of connections in @media. - */ -guint -gst_sdp_media_connections_len (const GstSDPMedia * media) -{ - return media->connections->len; -} - -/** - * gst_sdp_media_get_connection: - * @media: a #GstSDPMedia - * @idx: an index - * - * Get the connection at position @idx in @media. - * - * Returns: the #GstSDPConnection at position @idx. - */ -const GstSDPConnection * -gst_sdp_media_get_connection (const GstSDPMedia * media, guint idx) -{ - return &g_array_index (media->connections, GstSDPConnection, idx); -} - -/** - * gst_sdp_media_add_connection: - * @media: a #GstSDPMedia - * @nettype: the type of network. "IN" is defined to have the meaning - * "Internet". - * @addrtype: the type of address. - * @address: the address - * @ttl: the time to live of the address - * @addr_number: the number of layers - * - * Add the given connection parameters to @media. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_media_add_connection (GstSDPMedia * media, const gchar * nettype, - const gchar * addrtype, const gchar * address, guint ttl, guint addr_number) -{ - GstSDPConnection conn; - - conn.nettype = g_strdup (nettype); - conn.addrtype = g_strdup (addrtype); - conn.address = g_strdup (address); - conn.ttl = ttl; - conn.addr_number = addr_number; - - g_array_append_val (media->connections, conn); - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_bandwidths_len: - * @media: a #GstSDPMedia - * - * Get the number of bandwidth fields in @media. - * - * Returns: the number of bandwidths in @media. - */ -guint -gst_sdp_media_bandwidths_len (const GstSDPMedia * media) -{ - return media->bandwidths->len; -} - -/** - * gst_sdp_media_get_bandwidth: - * @media: a #GstSDPMedia - * @idx: an index - * - * Get the bandwidth at position @idx in @media. - * - * Returns: the #GstSDPBandwidth at position @idx. - */ -const GstSDPBandwidth * -gst_sdp_media_get_bandwidth (const GstSDPMedia * media, guint idx) -{ - return &g_array_index (media->bandwidths, GstSDPBandwidth, idx); -} - -/** - * gst_sdp_media_add_bandwidth: - * @media: a #GstSDPMedia - * @bwtype: the bandwidth modifier type - * @bandwidth: the bandwidth in kilobits per second - * - * Add the bandwidth information with @bwtype and @bandwidth to @media. - * - * Returns: #GST_SDP_OK. - */ -GstSDPResult -gst_sdp_media_add_bandwidth (GstSDPMedia * media, const gchar * bwtype, - guint bandwidth) -{ - GstSDPBandwidth bw; - - bw.bwtype = g_strdup (bwtype); - bw.bandwidth = bandwidth; - - g_array_append_val (media->bandwidths, bw); - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_set_key: - * @media: a #GstSDPMedia - * @type: the encryption type - * @data: the encryption data - * - * Adds the encryption information to @media. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_media_set_key (GstSDPMedia * media, const gchar * type, - const gchar * data) -{ - g_free (media->key.type); - media->key.type = g_strdup (type); - g_free (media->key.data); - media->key.data = g_strdup (data); - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_get_key: - * @media: a #GstSDPMedia - * - * Get the encryption information from @media. - * - * Returns: a #GstSDPKey. - */ -const GstSDPKey * -gst_sdp_media_get_key (const GstSDPMedia * media) -{ - return &media->key; -} - -/** - * gst_sdp_media_attributes_len: - * @media: a #GstSDPMedia - * - * Get the number of attribute fields in @media. - * - * Returns: the number of attributes in @media. - */ -guint -gst_sdp_media_attributes_len (const GstSDPMedia * media) -{ - return media->attributes->len; -} - -/** - * gst_sdp_media_add_attribute: - * @media: a #GstSDPMedia - * @key: a key - * @value: a value - * - * Add the attribute with @key and @value to @media. - * - * Returns: #GST_SDP_OK. - */ -GstSDPResult -gst_sdp_media_add_attribute (GstSDPMedia * media, const gchar * key, - const gchar * value) -{ - GstSDPAttribute attr; - - attr.key = g_strdup (key); - attr.value = g_strdup (value); - - g_array_append_val (media->attributes, attr); - - return GST_SDP_OK; -} - -/** - * gst_sdp_media_get_attribute: - * @media: a #GstSDPMedia - * @idx: an index - * - * Get the attribute at position @idx in @media. - * - * Returns: the #GstSDPAttribute at position @idx. - */ -const GstSDPAttribute * -gst_sdp_media_get_attribute (const GstSDPMedia * media, guint idx) -{ - return &g_array_index (media->attributes, GstSDPAttribute, idx); -} - -/** - * gst_sdp_media_get_attribute_val_n: - * @media: a #GstSDPMedia - * @key: a key - * @nth: an index - * - * Get the @nth attribute value for @key in @media. - * - * Returns: the @nth attribute value. - */ -const gchar * -gst_sdp_media_get_attribute_val_n (const GstSDPMedia * media, const gchar * key, - guint nth) -{ - guint i; - - for (i = 0; i < media->attributes->len; i++) { - GstSDPAttribute *attr; - - attr = &g_array_index (media->attributes, GstSDPAttribute, i); - if (!strcmp (attr->key, key)) { - if (nth == 0) - return attr->value; - else - nth--; - } - } - return NULL; -} - -/** - * gst_sdp_media_get_attribute_val: - * @media: a #GstSDPMedia - * @key: a key - * - * Get the first attribute value for @key in @media. - * - * Returns: the first attribute value for @key. - */ -const gchar * -gst_sdp_media_get_attribute_val (const GstSDPMedia * media, const gchar * key) -{ - return gst_sdp_media_get_attribute_val_n (media, key, 0); -} - -static void -read_string (gchar * dest, guint size, gchar ** src) -{ - guint idx; - - idx = 0; - /* skip spaces */ - while (g_ascii_isspace (**src)) - (*src)++; - - while (!g_ascii_isspace (**src) && **src != '\0') { - if (idx < size - 1) - dest[idx++] = **src; - (*src)++; - } - if (size > 0) - dest[idx] = '\0'; -} - -static void -read_string_del (gchar * dest, guint size, gchar del, gchar ** src) -{ - guint idx; - - idx = 0; - /* skip spaces */ - while (g_ascii_isspace (**src)) - (*src)++; - - while (**src != del && **src != '\0') { - if (idx < size - 1) - dest[idx++] = **src; - (*src)++; - } - if (size > 0) - dest[idx] = '\0'; -} - -enum -{ - SDP_SESSION, - SDP_MEDIA, -}; - -typedef struct -{ - guint state; - GstSDPMessage *msg; - GstSDPMedia *media; -} SDPContext; - -static gboolean -gst_sdp_parse_line (SDPContext * c, gchar type, gchar * buffer) -{ - gchar str[8192]; - gchar *p = buffer; - -#define READ_STRING(field) read_string (str, sizeof (str), &p); REPLACE_STRING (field, str) -#define READ_UINT(field) read_string (str, sizeof (str), &p); field = strtoul (str, NULL, 10) - - switch (type) { - case 'v': - if (buffer[0] != '0') - g_warning ("wrong SDP version"); - gst_sdp_message_set_version (c->msg, buffer); - break; - case 'o': - READ_STRING (c->msg->origin.username); - READ_STRING (c->msg->origin.sess_id); - READ_STRING (c->msg->origin.sess_version); - READ_STRING (c->msg->origin.nettype); - READ_STRING (c->msg->origin.addrtype); - READ_STRING (c->msg->origin.addr); - break; - case 's': - REPLACE_STRING (c->msg->session_name, buffer); - break; - case 'i': - if (c->state == SDP_SESSION) { - REPLACE_STRING (c->msg->information, buffer); - } else { - REPLACE_STRING (c->media->information, buffer); - } - break; - case 'u': - REPLACE_STRING (c->msg->uri, buffer); - break; - case 'e': - gst_sdp_message_add_email (c->msg, buffer); - break; - case 'p': - gst_sdp_message_add_phone (c->msg, buffer); - break; - case 'c': - { - GstSDPConnection conn; - gchar *str2; - - memset (&conn, 0, sizeof (conn)); - - str2 = p; - while ((str2 = strchr (str2, '/'))) - *str2++ = ' '; - READ_STRING (conn.nettype); - READ_STRING (conn.addrtype); - READ_STRING (conn.address); - READ_UINT (conn.ttl); - READ_UINT (conn.addr_number); - - if (c->state == SDP_SESSION) { - gst_sdp_message_set_connection (c->msg, conn.nettype, conn.addrtype, - conn.address, conn.ttl, conn.addr_number); - } else { - gst_sdp_media_add_connection (c->media, conn.nettype, conn.addrtype, - conn.address, conn.ttl, conn.addr_number); - } - gst_sdp_connection_init (&conn); - break; - } - case 'b': - { - gchar str2[MAX_LINE_LEN]; - - read_string_del (str, sizeof (str), ':', &p); - if (*p != '\0') - p++; - read_string (str2, sizeof (str2), &p); - if (c->state == SDP_SESSION) - gst_sdp_message_add_bandwidth (c->msg, str, atoi (str2)); - else - gst_sdp_media_add_bandwidth (c->media, str, atoi (str2)); - break; - } - case 't': - break; - case 'k': - break; - case 'a': - read_string_del (str, sizeof (str), ':', &p); - if (*p != '\0') - p++; - if (c->state == SDP_SESSION) - gst_sdp_message_add_attribute (c->msg, str, p); - else - gst_sdp_media_add_attribute (c->media, str, p); - break; - case 'm': - { - gchar *slash; - GstSDPMedia nmedia; - - c->state = SDP_MEDIA; - memset (&nmedia, 0, sizeof (nmedia)); - gst_sdp_media_init (&nmedia); - - /* m=<media> <port>/<number of ports> <proto> <fmt> ... */ - READ_STRING (nmedia.media); - read_string (str, sizeof (str), &p); - slash = g_strrstr (str, "/"); - if (slash) { - *slash = '\0'; - nmedia.port = atoi (str); - nmedia.num_ports = atoi (slash + 1); - } else { - nmedia.port = atoi (str); - nmedia.num_ports = -1; - } - READ_STRING (nmedia.proto); - do { - read_string (str, sizeof (str), &p); - gst_sdp_media_add_format (&nmedia, str); - } while (*p != '\0'); - - gst_sdp_message_add_media (c->msg, &nmedia); - c->media = - &g_array_index (c->msg->medias, GstSDPMedia, c->msg->medias->len - 1); - break; - } - default: - break; - } - return TRUE; -} - -/** - * gst_sdp_message_parse_buffer: - * @data: the start of the buffer - * @size: the size of the buffer - * @msg: the result #GstSDPMessage - * - * Parse the contents of @size bytes pointed to by @data and store the result in - * @msg. - * - * Returns: #GST_SDP_OK on success. - */ -GstSDPResult -gst_sdp_message_parse_buffer (const guint8 * data, guint size, - GstSDPMessage * msg) -{ - gchar *p; - SDPContext c; - gchar type; - gchar buffer[MAX_LINE_LEN]; - guint idx = 0; - - g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL); - g_return_val_if_fail (data != NULL, GST_SDP_EINVAL); - g_return_val_if_fail (size != 0, GST_SDP_EINVAL); - - c.state = SDP_SESSION; - c.msg = msg; - c.media = NULL; - - p = (gchar *) data; - while (TRUE) { - while (g_ascii_isspace (*p)) - p++; - - type = *p++; - if (type == '\0') - break; - - if (*p != '=') - goto line_done; - p++; - - idx = 0; - while (*p != '\n' && *p != '\r' && *p != '\0') { - if (idx < sizeof (buffer) - 1) - buffer[idx++] = *p; - p++; - } - buffer[idx] = '\0'; - gst_sdp_parse_line (&c, type, buffer); - - line_done: - while (*p != '\n' && *p != '\0') - p++; - if (*p == '\n') - p++; - } - - return GST_SDP_OK; -} - -static void -print_media (GstSDPMedia * media) -{ - g_print (" media: '%s'\n", GST_STR_NULL (media->media)); - g_print (" port: '%u'\n", media->port); - g_print (" num_ports: '%u'\n", media->num_ports); - g_print (" proto: '%s'\n", GST_STR_NULL (media->proto)); - if (media->fmts->len > 0) { - guint i; - - g_print (" formats:\n"); - for (i = 0; i < media->fmts->len; i++) { - g_print (" format '%s'\n", g_array_index (media->fmts, gchar *, i)); - } - } - g_print (" information: '%s'\n", GST_STR_NULL (media->information)); - if (media->connections->len > 0) { - guint i; - - g_print (" connections:\n"); - for (i = 0; i < media->connections->len; i++) { - GstSDPConnection *conn = - &g_array_index (media->connections, GstSDPConnection, i); - - g_print (" nettype: '%s'\n", GST_STR_NULL (conn->nettype)); - g_print (" addrtype: '%s'\n", GST_STR_NULL (conn->addrtype)); - g_print (" address: '%s'\n", GST_STR_NULL (conn->address)); - g_print (" ttl: '%u'\n", conn->ttl); - g_print (" addr_number: '%u'\n", conn->addr_number); - } - } - if (media->bandwidths->len > 0) { - guint i; - - g_print (" bandwidths:\n"); - for (i = 0; i < media->bandwidths->len; i++) { - GstSDPBandwidth *bw = - &g_array_index (media->bandwidths, GstSDPBandwidth, i); - - g_print (" type: '%s'\n", GST_STR_NULL (bw->bwtype)); - g_print (" bandwidth: '%u'\n", bw->bandwidth); - } - } - g_print (" key:\n"); - g_print (" type: '%s'\n", GST_STR_NULL (media->key.type)); - g_print (" data: '%s'\n", GST_STR_NULL (media->key.data)); - if (media->attributes->len > 0) { - guint i; - - g_print (" attributes:\n"); - for (i = 0; i < media->attributes->len; i++) { - GstSDPAttribute *attr = - &g_array_index (media->attributes, GstSDPAttribute, i); - - g_print (" attribute '%s' : '%s'\n", attr->key, attr->value); - } - } -} - -/** - * gst_sdp_message_dump: - * @msg: a #GstSDPMessage - * - * Dump the parsed contents of @msg to stdout. - * - * Returns: a #GstSDPResult. - */ -GstSDPResult -gst_sdp_message_dump (const GstSDPMessage * msg) -{ - g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL); - - g_print ("sdp packet %p:\n", msg); - g_print (" version: '%s'\n", GST_STR_NULL (msg->version)); - g_print (" origin:\n"); - g_print (" username: '%s'\n", GST_STR_NULL (msg->origin.username)); - g_print (" sess_id: '%s'\n", GST_STR_NULL (msg->origin.sess_id)); - g_print (" sess_version: '%s'\n", GST_STR_NULL (msg->origin.sess_version)); - g_print (" nettype: '%s'\n", GST_STR_NULL (msg->origin.nettype)); - g_print (" addrtype: '%s'\n", GST_STR_NULL (msg->origin.addrtype)); - g_print (" addr: '%s'\n", GST_STR_NULL (msg->origin.addr)); - g_print (" session_name: '%s'\n", GST_STR_NULL (msg->session_name)); - g_print (" information: '%s'\n", GST_STR_NULL (msg->information)); - g_print (" uri: '%s'\n", GST_STR_NULL (msg->uri)); - - if (msg->emails->len > 0) { - guint i; - - g_print (" emails:\n"); - for (i = 0; i < msg->emails->len; i++) { - g_print (" email '%s'\n", g_array_index (msg->emails, gchar *, i)); - } - } - if (msg->phones->len > 0) { - guint i; - - g_print (" phones:\n"); - for (i = 0; i < msg->phones->len; i++) { - g_print (" phone '%s'\n", g_array_index (msg->phones, gchar *, i)); - } - } - g_print (" connection:\n"); - g_print (" nettype: '%s'\n", GST_STR_NULL (msg->connection.nettype)); - g_print (" addrtype: '%s'\n", GST_STR_NULL (msg->connection.addrtype)); - g_print (" address: '%s'\n", GST_STR_NULL (msg->connection.address)); - g_print (" ttl: '%u'\n", msg->connection.ttl); - g_print (" addr_number: '%u'\n", msg->connection.addr_number); - if (msg->bandwidths->len > 0) { - guint i; - - g_print (" bandwidths:\n"); - for (i = 0; i < msg->bandwidths->len; i++) { - GstSDPBandwidth *bw = - &g_array_index (msg->bandwidths, GstSDPBandwidth, i); - - g_print (" type: '%s'\n", GST_STR_NULL (bw->bwtype)); - g_print (" bandwidth: '%u'\n", bw->bandwidth); - } - } - g_print (" key:\n"); - g_print (" type: '%s'\n", GST_STR_NULL (msg->key.type)); - g_print (" data: '%s'\n", GST_STR_NULL (msg->key.data)); - if (msg->attributes->len > 0) { - guint i; - - g_print (" attributes:\n"); - for (i = 0; i < msg->attributes->len; i++) { - GstSDPAttribute *attr = - &g_array_index (msg->attributes, GstSDPAttribute, i); - - g_print (" attribute '%s' : '%s'\n", attr->key, attr->value); - } - } - if (msg->medias->len > 0) { - guint i; - - g_print (" medias:\n"); - for (i = 0; i < msg->medias->len; i++) { - g_print (" media %u:\n", i); - print_media (&g_array_index (msg->medias, GstSDPMedia, i)); - } - } - return GST_SDP_OK; -} |