/* GStreamer
 * Copyright (C) <2005,2006,2007> Wim Taymans <wim@fluendo.com>
 *               <2007> Peter Kjellerstedt  <pkj at axis 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, 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:gstrtsptransport
 * @title: GstRTSPRange
 * @short_description: dealing with RTSP transports
 *
 * Provides helper functions to deal with RTSP transport strings.
 */

#include <string.h>
#include <stdlib.h>

#include "gstrtsptransport.h"
#include "gstrtsp-enumtypes.h"

#define MAX_MANAGERS	2

typedef enum
{
  RTSP_TRANSPORT_DELIVERY = 1 << 0,     /* multicast | unicast */
  RTSP_TRANSPORT_DESTINATION = 1 << 1,
  RTSP_TRANSPORT_SOURCE = 1 << 2,
  RTSP_TRANSPORT_INTERLEAVED = 1 << 3,
  RTSP_TRANSPORT_APPEND = 1 << 4,
  RTSP_TRANSPORT_TTL = 1 << 5,
  RTSP_TRANSPORT_LAYERS = 1 << 6,
  RTSP_TRANSPORT_PORT = 1 << 7,
  RTSP_TRANSPORT_CLIENT_PORT = 1 << 8,
  RTSP_TRANSPORT_SERVER_PORT = 1 << 9,
  RTSP_TRANSPORT_SSRC = 1 << 10,
  RTSP_TRANSPORT_MODE = 1 << 11,
} RTSPTransportParameter;

typedef struct
{
  const gchar *name;
  const GstRTSPTransMode mode;
  const GstRTSPProfile profile;
  const GstRTSPLowerTrans ltrans;
  const gchar *media_type;
  const gchar *manager[MAX_MANAGERS];
} GstRTSPTransMap;

static const GstRTSPTransMap transports[] = {
  {"rtp", GST_RTSP_TRANS_RTP, GST_RTSP_PROFILE_AVP,
        GST_RTSP_LOWER_TRANS_UDP_MCAST, "application/x-rtp",
      {"rtpbin", "rtpdec"}},
  {"srtp", GST_RTSP_TRANS_RTP, GST_RTSP_PROFILE_SAVP,
        GST_RTSP_LOWER_TRANS_UDP_MCAST, "application/x-srtp",
      {"rtpbin", "rtpdec"}},
  {"rtpf", GST_RTSP_TRANS_RTP, GST_RTSP_PROFILE_AVPF,
        GST_RTSP_LOWER_TRANS_UDP_MCAST, "application/x-rtp",
      {"rtpbin", "rtpdec"}},
  {"srtpf", GST_RTSP_TRANS_RTP, GST_RTSP_PROFILE_SAVPF,
        GST_RTSP_LOWER_TRANS_UDP_MCAST, "application/x-srtp",
      {"rtpbin", "rtpdec"}},
  {"x-real-rdt", GST_RTSP_TRANS_RDT, GST_RTSP_PROFILE_AVP,
        GST_RTSP_LOWER_TRANS_UNKNOWN, "application/x-rdt",
      {"rdtmanager", NULL}},
  {"x-pn-tng", GST_RTSP_TRANS_RDT, GST_RTSP_PROFILE_AVP,
        GST_RTSP_LOWER_TRANS_UNKNOWN, "application/x-rdt",
      {"rdtmanager", NULL}},
  {NULL, GST_RTSP_TRANS_UNKNOWN, GST_RTSP_PROFILE_UNKNOWN,
      GST_RTSP_LOWER_TRANS_UNKNOWN, NULL, {NULL, NULL}}
};

typedef struct
{
  const gchar *name;
  const GstRTSPProfile profile;
} RTSPProfileMap;

static const RTSPProfileMap profiles[] = {
  {"avp", GST_RTSP_PROFILE_AVP},
  {"savp", GST_RTSP_PROFILE_SAVP},
  {"avpf", GST_RTSP_PROFILE_AVPF},
  {"savpf", GST_RTSP_PROFILE_SAVPF},
  {NULL, GST_RTSP_PROFILE_UNKNOWN}
};

typedef struct
{
  const gchar *name;
  const GstRTSPLowerTrans ltrans;
} RTSPLTransMap;

static const RTSPLTransMap ltrans[] = {
  {"udp", GST_RTSP_LOWER_TRANS_UDP},
  {"mcast", GST_RTSP_LOWER_TRANS_UDP_MCAST},
  {"tcp", GST_RTSP_LOWER_TRANS_TCP},
  {NULL, GST_RTSP_LOWER_TRANS_UNKNOWN}
};

#define RTSP_TRANSPORT_PARAMETER_IS_UNIQUE(param) \
G_STMT_START {                                    \
  if ((transport_params & (param)) != 0)          \
    goto invalid_transport;                       \
  transport_params |= (param);                    \
} G_STMT_END

/**
 * gst_rtsp_transport_new:
 * @transport: location to hold the new #GstRTSPTransport
 *
 * Allocate a new initialized #GstRTSPTransport. Use gst_rtsp_transport_free()
 * after usage.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_transport_new (GstRTSPTransport ** transport)
{
  GstRTSPTransport *trans;

  g_return_val_if_fail (transport != NULL, GST_RTSP_EINVAL);

  trans = g_new0 (GstRTSPTransport, 1);

  *transport = trans;

  return gst_rtsp_transport_init (trans);
}

/**
 * gst_rtsp_transport_init:
 * @transport: a #GstRTSPTransport
 *
 * Initialize @transport so that it can be used.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_transport_init (GstRTSPTransport * transport)
{
  g_return_val_if_fail (transport != NULL, GST_RTSP_EINVAL);

  g_free (transport->destination);
  g_free (transport->source);

  memset (transport, 0, sizeof (GstRTSPTransport));

  transport->trans = GST_RTSP_TRANS_RTP;
  transport->profile = GST_RTSP_PROFILE_AVP;
  transport->lower_transport = GST_RTSP_LOWER_TRANS_UDP_MCAST;
  transport->mode_play = TRUE;
  transport->mode_record = FALSE;
  transport->interleaved.min = -1;
  transport->interleaved.max = -1;
  transport->port.min = -1;
  transport->port.max = -1;
  transport->client_port.min = -1;
  transport->client_port.max = -1;
  transport->server_port.min = -1;
  transport->server_port.max = -1;

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_transport_get_mime:
 * @trans: a #GstRTSPTransMode
 * @mime: location to hold the result
 *
 * Get the mime type of the transport mode @trans. This mime type is typically
 * used to generate #GstCaps events.
 *
 * Deprecated: This functions only deals with the GstRTSPTransMode and only
 *    returns the mime type for #GST_RTSP_PROFILE_AVP. Use
 *    gst_rtsp_transport_get_media_type() instead.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_transport_get_mime (GstRTSPTransMode trans, const gchar ** mime)
{
  gint i;

  g_return_val_if_fail (mime != NULL, GST_RTSP_EINVAL);

  for (i = 0; transports[i].name; i++)
    if (transports[i].mode == trans
        && transports[i].profile == GST_RTSP_PROFILE_AVP)
      break;
  *mime = transports[i].media_type;

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_transport_get_media_type:
 * @transport: a #GstRTSPTransport
 * @media_type: (out) (transfer none): media type of @transport
 *
 * Get the media type of @transport. This media type is typically
 * used to generate #GstCaps events.
 *
 * Since: 1.4
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_transport_get_media_type (GstRTSPTransport * transport,
    const gchar ** media_type)
{
  gint i;

  g_return_val_if_fail (transport != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (media_type != NULL, GST_RTSP_EINVAL);

  for (i = 0; transports[i].name; i++)
    if (transports[i].mode == transport->trans
        && transports[i].profile == transport->profile)
      break;
  *media_type = transports[i].media_type;

  return GST_RTSP_OK;
}

static GstRTSPLowerTrans
get_default_lower_trans (GstRTSPTransport * transport)
{
  gint i;

  for (i = 0; transports[i].name; i++)
    if (transports[i].mode == transport->trans
        && transports[i].profile == transport->profile)
      break;

  return transports[i].ltrans;
}

/**
 * gst_rtsp_transport_get_manager:
 * @trans: a #GstRTSPTransMode
 * @manager: location to hold the result
 * @option: option index.
 *
 * Get the #GstElement that can handle the buffers transported over @trans.
 *
 * It is possible that there are several managers available, use @option to
 * selected one.
 *
 * @manager will contain an element name or #NULL when no manager is
 * needed/available for @trans.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_transport_get_manager (GstRTSPTransMode trans, const gchar ** manager,
    guint option)
{
  gint i;

  g_return_val_if_fail (manager != NULL, GST_RTSP_EINVAL);

  for (i = 0; transports[i].name; i++)
    if (transports[i].mode == trans)
      break;

  if (option < MAX_MANAGERS)
    *manager = transports[i].manager[option];
  else
    *manager = NULL;

  return GST_RTSP_OK;
}

static void
parse_mode (GstRTSPTransport * transport, const gchar * str)
{
  transport->mode_play = (strstr (str, "play") != NULL);
  transport->mode_record = (strstr (str, "record") != NULL);
}

static gboolean
check_range (const gchar * str, gchar ** tmp, gint * range)
{
  glong range_val;

  range_val = strtol (str, tmp, 10);
  if (range_val >= G_MININT && range_val <= G_MAXINT) {
    *range = range_val;
    return TRUE;
  } else {
    return FALSE;
  }
}

static gboolean
parse_range (const gchar * str, GstRTSPRange * range)
{
  gchar *minus;
  gchar *tmp;

  /* even though strtol() allows white space, plus and minus in front of
   * the number, we do not allow it
   */
  if (g_ascii_isspace (*str) || *str == '+' || *str == '-')
    goto invalid_range;

  minus = strstr (str, "-");
  if (minus) {
    if (g_ascii_isspace (minus[1]) || minus[1] == '+' || minus[1] == '-')
      goto invalid_range;

    if (!check_range (str, &tmp, &range->min) || str == tmp || tmp != minus)
      goto invalid_range;

    if (!check_range (minus + 1, &tmp, &range->max) || (*tmp && *tmp != ';'))
      goto invalid_range;
  } else {
    if (!check_range (str, &tmp, &range->min) || str == tmp ||
        (*tmp && *tmp != ';'))
      goto invalid_range;

    range->max = -1;
  }

  return TRUE;

invalid_range:
  {
    range->min = -1;
    range->max = -1;
    return FALSE;
  }
}

static gchar *
range_as_text (const GstRTSPRange * range)
{
  if (range->min < 0)
    return NULL;
  else if (range->max < 0)
    return g_strdup_printf ("%d", range->min);
  else
    return g_strdup_printf ("%d-%d", range->min, range->max);
}

static const gchar *
rtsp_transport_mode_as_text (const GstRTSPTransport * transport)
{
  gint i;

  for (i = 0; transports[i].name; i++)
    if (transports[i].mode == transport->trans)
      return transports[i].name;

  return NULL;
}

static const gchar *
rtsp_transport_profile_as_text (const GstRTSPTransport * transport)
{
  gint i;

  for (i = 0; profiles[i].name; i++)
    if (profiles[i].profile == transport->profile)
      return profiles[i].name;

  return NULL;
}

static const gchar *
rtsp_transport_ltrans_as_text (const GstRTSPTransport * transport)
{
  gint i;

  /* need to special case GST_RTSP_LOWER_TRANS_UDP_MCAST */
  if (transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST)
    return "udp";

  for (i = 0; ltrans[i].name; i++)
    if (ltrans[i].ltrans == transport->lower_transport)
      return ltrans[i].name;

  return NULL;
}

#define IS_VALID_PORT_RANGE(range) \
    (range.min >= 0 && range.min < 65536 && range.max < 65536)

#define IS_VALID_INTERLEAVE_RANGE(range) \
    (range.min >= 0 && range.min < 256 && range.max < 256)

/**
 * gst_rtsp_transport_parse:
 * @str: a transport string
 * @transport: a #GstRTSPTransport
 *
 * Parse the RTSP transport string @str into @transport.
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_transport_parse (const gchar * str, GstRTSPTransport * transport)
{
  gchar **split, *down, **transp = NULL;
  guint transport_params = 0;
  gint i, count;

  g_return_val_if_fail (transport != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (str != NULL, GST_RTSP_EINVAL);

  gst_rtsp_transport_init (transport);

  /* case insensitive */
  down = g_ascii_strdown (str, -1);

  split = g_strsplit (down, ";", 0);
  g_free (down);

  /* First field contains the transport/profile/lower_transport */
  if (split[0] == NULL)
    goto invalid_transport;

  transp = g_strsplit (split[0], "/", 0);

  if (transp[0] == NULL || transp[1] == NULL)
    goto invalid_transport;

  for (i = 0; transports[i].name; i++)
    if (strcmp (transp[0], transports[i].name) == 0)
      break;
  transport->trans = transports[i].mode;

  if (transport->trans != GST_RTSP_TRANS_RDT) {
    for (i = 0; profiles[i].name; i++)
      if (strcmp (transp[1], profiles[i].name) == 0)
        break;
    transport->profile = profiles[i].profile;
    count = 2;
  } else {
    /* RDT has transport/lower_transport */
    transport->profile = GST_RTSP_PROFILE_AVP;
    count = 1;
  }

  if (transp[count] != NULL) {
    for (i = 0; ltrans[i].name; i++)
      if (strcmp (transp[count], ltrans[i].name) == 0)
        break;
    transport->lower_transport = ltrans[i].ltrans;
  } else {
    /* specifying the lower transport is optional */
    transport->lower_transport = get_default_lower_trans (transport);
  }

  g_strfreev (transp);
  transp = NULL;

  if (transport->trans == GST_RTSP_TRANS_UNKNOWN ||
      transport->profile == GST_RTSP_PROFILE_UNKNOWN ||
      transport->lower_transport == GST_RTSP_LOWER_TRANS_UNKNOWN)
    goto unsupported_transport;

  i = 1;
  while (split[i]) {
    if (strcmp (split[i], "multicast") == 0) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DELIVERY);
      if (transport->lower_transport == GST_RTSP_LOWER_TRANS_TCP)
        goto invalid_transport;
      transport->lower_transport = GST_RTSP_LOWER_TRANS_UDP_MCAST;
    } else if (strcmp (split[i], "unicast") == 0) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DELIVERY);
      if (transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST)
        transport->lower_transport = GST_RTSP_LOWER_TRANS_UDP;
    } else if (g_str_has_prefix (split[i], "destination=")) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DESTINATION);
      transport->destination = g_strdup (split[i] + 12);
    } else if (g_str_has_prefix (split[i], "source=")) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SOURCE);
      transport->source = g_strdup (split[i] + 7);
    } else if (g_str_has_prefix (split[i], "layers=")) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_LAYERS);
      transport->layers = strtoul (split[i] + 7, NULL, 10);
    } else if (g_str_has_prefix (split[i], "mode=")) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_MODE);
      parse_mode (transport, split[i] + 5);
      if (!transport->mode_play && !transport->mode_record)
        goto invalid_transport;
    } else if (strcmp (split[i], "append") == 0) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_APPEND);
      transport->append = TRUE;
    } else if (g_str_has_prefix (split[i], "interleaved=")) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_INTERLEAVED);
      parse_range (split[i] + 12, &transport->interleaved);
      if (!IS_VALID_INTERLEAVE_RANGE (transport->interleaved))
        goto invalid_transport;
    } else if (g_str_has_prefix (split[i], "ttl=")) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_TTL);
      transport->ttl = strtoul (split[i] + 4, NULL, 10);
      if (transport->ttl >= 256)
        goto invalid_transport;
    } else if (g_str_has_prefix (split[i], "port=")) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_PORT);
      if (parse_range (split[i] + 5, &transport->port)) {
        if (!IS_VALID_PORT_RANGE (transport->port))
          goto invalid_transport;
      }
    } else if (g_str_has_prefix (split[i], "client_port=")) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_CLIENT_PORT);
      if (parse_range (split[i] + 12, &transport->client_port)) {
        if (!IS_VALID_PORT_RANGE (transport->client_port))
          goto invalid_transport;
      }
    } else if (g_str_has_prefix (split[i], "server_port=")) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SERVER_PORT);
      if (parse_range (split[i] + 12, &transport->server_port)) {
        if (!IS_VALID_PORT_RANGE (transport->server_port))
          goto invalid_transport;
      }
    } else if (g_str_has_prefix (split[i], "ssrc=")) {
      RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SSRC);
      transport->ssrc = strtoul (split[i] + 5, NULL, 16);
    } else {
      /* unknown field... */
      if (strlen (split[i]) > 0) {
        g_warning ("unknown transport field \"%s\"", split[i]);
      }
    }
    i++;
  }
  g_strfreev (split);

  return GST_RTSP_OK;

unsupported_transport:
  {
    g_strfreev (split);
    return GST_RTSP_ERROR;
  }
invalid_transport:
  {
    g_strfreev (transp);
    g_strfreev (split);
    return GST_RTSP_EINVAL;
  }
}

/**
 * gst_rtsp_transport_as_text:
 * @transport: a #GstRTSPTransport
 *
 * Convert @transport into a string that can be used to signal the transport in
 * an RTSP SETUP response.
 *
 * Returns: a string describing the RTSP transport or #NULL when the transport
 * is invalid.
 */
gchar *
gst_rtsp_transport_as_text (GstRTSPTransport * transport)
{
  GPtrArray *strs;
  gchar *res;
  const gchar *tmp;

  g_return_val_if_fail (transport != NULL, NULL);

  strs = g_ptr_array_new ();

  /* add the transport specifier */
  if ((tmp = rtsp_transport_mode_as_text (transport)) == NULL)
    goto invalid_transport;
  g_ptr_array_add (strs, g_ascii_strup (tmp, -1));

  g_ptr_array_add (strs, g_strdup ("/"));

  if ((tmp = rtsp_transport_profile_as_text (transport)) == NULL)
    goto invalid_transport;
  g_ptr_array_add (strs, g_ascii_strup (tmp, -1));

  if (transport->trans != GST_RTSP_TRANS_RTP ||
      (transport->profile != GST_RTSP_PROFILE_AVP &&
          transport->profile != GST_RTSP_PROFILE_SAVP &&
          transport->profile != GST_RTSP_PROFILE_AVPF &&
          transport->profile != GST_RTSP_PROFILE_SAVPF) ||
      transport->lower_transport == GST_RTSP_LOWER_TRANS_TCP) {
    g_ptr_array_add (strs, g_strdup ("/"));

    if ((tmp = rtsp_transport_ltrans_as_text (transport)) == NULL)
      goto invalid_transport;

    g_ptr_array_add (strs, g_ascii_strup (tmp, -1));
  }

  /*
   * the order of the following parameters is the same as the one specified in
   * RFC 2326 to please some weird RTSP clients that require it
   */

  /* add the unicast/multicast parameter */
  if (transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST)
    g_ptr_array_add (strs, g_strdup (";multicast"));
  else
    g_ptr_array_add (strs, g_strdup (";unicast"));

  /* add the destination parameter */
  if (transport->destination != NULL) {
    g_ptr_array_add (strs, g_strdup (";destination="));
    g_ptr_array_add (strs, g_strdup (transport->destination));
  }

  /* add the source parameter */
  if (transport->source != NULL) {
    g_ptr_array_add (strs, g_strdup (";source="));
    g_ptr_array_add (strs, g_strdup (transport->source));
  }

  /* add the interleaved parameter */
  if (transport->lower_transport == GST_RTSP_LOWER_TRANS_TCP &&
      transport->interleaved.min >= 0) {
    if (transport->interleaved.min < 256 && transport->interleaved.max < 256) {
      g_ptr_array_add (strs, g_strdup (";interleaved="));
      g_ptr_array_add (strs, range_as_text (&transport->interleaved));
    } else
      goto invalid_transport;
  }

  /* add the append parameter */
  if (transport->mode_record && transport->append)
    g_ptr_array_add (strs, g_strdup (";append"));

  /* add the ttl parameter */
  if (transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST &&
      transport->ttl != 0) {
    if (transport->ttl < 256) {
      g_ptr_array_add (strs, g_strdup (";ttl="));
      g_ptr_array_add (strs, g_strdup_printf ("%u", transport->ttl));
    } else
      goto invalid_transport;
  }

  /* add the layers parameter */
  if (transport->layers != 0) {
    g_ptr_array_add (strs, g_strdup (";layers="));
    g_ptr_array_add (strs, g_strdup_printf ("%u", transport->layers));
  }

  /* add the port parameter */
  if (transport->lower_transport != GST_RTSP_LOWER_TRANS_TCP) {
    if (transport->trans == GST_RTSP_TRANS_RTP && transport->port.min >= 0) {
      if (transport->port.min < 65536 && transport->port.max < 65536) {
        g_ptr_array_add (strs, g_strdup (";port="));
        g_ptr_array_add (strs, range_as_text (&transport->port));
      } else
        goto invalid_transport;
    }

    /* add the client_port parameter */
    if (transport->trans == GST_RTSP_TRANS_RTP
        && transport->client_port.min >= 0) {
      if (transport->client_port.min < 65536
          && transport->client_port.max < 65536) {
        g_ptr_array_add (strs, g_strdup (";client_port="));
        g_ptr_array_add (strs, range_as_text (&transport->client_port));
      } else
        goto invalid_transport;
    }

    /* add the server_port parameter */
    if (transport->trans == GST_RTSP_TRANS_RTP
        && transport->server_port.min >= 0) {
      if (transport->server_port.min < 65536
          && transport->server_port.max < 65536) {
        g_ptr_array_add (strs, g_strdup (";server_port="));
        g_ptr_array_add (strs, range_as_text (&transport->server_port));
      } else
        goto invalid_transport;
    }
  }

  /* add the ssrc parameter */
  if (transport->lower_transport != GST_RTSP_LOWER_TRANS_UDP_MCAST &&
      transport->ssrc != 0) {
    g_ptr_array_add (strs, g_strdup (";ssrc="));
    g_ptr_array_add (strs, g_strdup_printf ("%08X", transport->ssrc));
  }

  /* add the mode parameter */
  if (transport->mode_play && transport->mode_record)
    g_ptr_array_add (strs, g_strdup (";mode=\"PLAY,RECORD\""));
  else if (transport->mode_record)
    g_ptr_array_add (strs, g_strdup (";mode=\"RECORD\""));
  else if (transport->mode_play)
    g_ptr_array_add (strs, g_strdup (";mode=\"PLAY\""));

  /* add a terminating NULL */
  g_ptr_array_add (strs, NULL);

  res = g_strjoinv (NULL, (gchar **) strs->pdata);
  g_strfreev ((gchar **) g_ptr_array_free (strs, FALSE));

  return res;

invalid_transport:
  {
    g_ptr_array_add (strs, NULL);
    g_strfreev ((gchar **) g_ptr_array_free (strs, FALSE));
    return NULL;
  }
}

/**
 * gst_rtsp_transport_free:
 * @transport: a #GstRTSPTransport
 *
 * Free the memory used by @transport.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_transport_free (GstRTSPTransport * transport)
{
  g_return_val_if_fail (transport != NULL, GST_RTSP_EINVAL);

  gst_rtsp_transport_init (transport);
  g_free (transport);

  return GST_RTSP_OK;
}
