mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
gst/rtsp/rtsptransport.*: Add validation to rtsp_transport_parse().
Original commit message from CVS: Patch by: Peter Kjellerstedt <pkj at axis com> * gst/rtsp/rtsptransport.c: (rtsp_transport_init), (parse_mode), (parse_range), (range_as_text), (rtsp_transport_mode_as_text), (rtsp_transport_profile_as_text), (rtsp_transport_ltrans_as_text), (rtsp_transport_parse), (rtsp_transport_as_text): * gst/rtsp/rtsptransport.h: Add validation to rtsp_transport_parse(). Add rtsp_transport_as_text() to generate an RTSP header from an RTSPTransport. Change ssrc to guint (was a string) since that is what it is, even though it is sent as a hex string. Correctly identify PLAY|RECORD mode parameters (the syntax in the RFC is incorrect, which can be seen when looking at the examples in the RFC). Fixes #437670.
This commit is contained in:
parent
28713ecdf1
commit
5f9984e866
3 changed files with 384 additions and 40 deletions
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
||||||
|
2007-05-12 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
Patch by: Peter Kjellerstedt <pkj at axis com>
|
||||||
|
|
||||||
|
* gst/rtsp/rtsptransport.c: (rtsp_transport_init), (parse_mode),
|
||||||
|
(parse_range), (range_as_text), (rtsp_transport_mode_as_text),
|
||||||
|
(rtsp_transport_profile_as_text), (rtsp_transport_ltrans_as_text),
|
||||||
|
(rtsp_transport_parse), (rtsp_transport_as_text):
|
||||||
|
* gst/rtsp/rtsptransport.h:
|
||||||
|
Add validation to rtsp_transport_parse().
|
||||||
|
Add rtsp_transport_as_text() to generate an RTSP header from an
|
||||||
|
RTSPTransport.
|
||||||
|
Change ssrc to guint (was a string) since that is what it is, even
|
||||||
|
though it is sent as a hex string.
|
||||||
|
Correctly identify PLAY|RECORD mode parameters (the syntax in the RFC is
|
||||||
|
incorrect, which can be seen when looking at the examples in the RFC).
|
||||||
|
Fixes #437670.
|
||||||
|
|
||||||
2007-05-11 Zaheer Abbas Merali <<zaheerabbas at merali dot org>>
|
2007-05-11 Zaheer Abbas Merali <<zaheerabbas at merali dot org>>
|
||||||
|
|
||||||
Patch by: Eric Anholt
|
Patch by: Eric Anholt
|
||||||
|
|
|
@ -47,6 +47,22 @@
|
||||||
|
|
||||||
#define MAX_MANAGERS 2
|
#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
|
typedef struct
|
||||||
{
|
{
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
|
@ -84,9 +100,16 @@ static const RTSPLTransMap ltrans[] = {
|
||||||
{"udp", RTSP_LOWER_TRANS_UDP},
|
{"udp", RTSP_LOWER_TRANS_UDP},
|
||||||
{"mcast", RTSP_LOWER_TRANS_UDP_MCAST},
|
{"mcast", RTSP_LOWER_TRANS_UDP_MCAST},
|
||||||
{"tcp", RTSP_LOWER_TRANS_TCP},
|
{"tcp", RTSP_LOWER_TRANS_TCP},
|
||||||
{NULL, RTSP_LOWER_TRANS_UDP_MCAST} /* UDP is default */
|
{NULL, 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
|
||||||
|
|
||||||
RTSPResult
|
RTSPResult
|
||||||
rtsp_transport_new (RTSPTransport ** transport)
|
rtsp_transport_new (RTSPTransport ** transport)
|
||||||
{
|
{
|
||||||
|
@ -108,15 +131,22 @@ rtsp_transport_init (RTSPTransport * transport)
|
||||||
|
|
||||||
g_free (transport->destination);
|
g_free (transport->destination);
|
||||||
g_free (transport->source);
|
g_free (transport->source);
|
||||||
g_free (transport->ssrc);
|
|
||||||
|
|
||||||
memset (transport, 0, sizeof (RTSPTransport));
|
memset (transport, 0, sizeof (RTSPTransport));
|
||||||
|
|
||||||
transport->trans = RTSP_TRANS_RTP;
|
transport->trans = RTSP_TRANS_RTP;
|
||||||
transport->profile = RTSP_PROFILE_AVP;
|
transport->profile = RTSP_PROFILE_AVP;
|
||||||
transport->lower_transport = RTSP_LOWER_TRANS_UDP;
|
transport->lower_transport = RTSP_LOWER_TRANS_UDP_MCAST;
|
||||||
transport->mode_play = TRUE;
|
transport->mode_play = TRUE;
|
||||||
transport->mode_record = FALSE;
|
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 RTSP_OK;
|
return RTSP_OK;
|
||||||
}
|
}
|
||||||
|
@ -157,31 +187,110 @@ rtsp_transport_get_manager (RTSPTransMode trans, const gchar ** manager,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_mode (RTSPTransport * transport, gchar * str)
|
parse_mode (RTSPTransport * transport, const gchar * str)
|
||||||
{
|
{
|
||||||
transport->mode_play = (strstr (str, "\"play\"") != NULL);
|
transport->mode_play = (strstr (str, "play") != NULL);
|
||||||
transport->mode_record = (strstr (str, "\"record\"") != NULL);
|
transport->mode_record = (strstr (str, "record") != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_range (RTSPTransport * transport, gchar * str, RTSPRange * range)
|
parse_range (const gchar * str, RTSPRange * range)
|
||||||
{
|
{
|
||||||
gchar *minus;
|
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, "-");
|
minus = strstr (str, "-");
|
||||||
if (minus) {
|
if (minus) {
|
||||||
range->min = atoi (str);
|
if (g_ascii_isspace (minus[1]) || minus[1] == '+' || minus[1] == '-')
|
||||||
range->max = atoi (minus + 1);
|
goto invalid_range;
|
||||||
|
|
||||||
|
range->min = strtol (str, &tmp, 10);
|
||||||
|
if (str == tmp || tmp != minus)
|
||||||
|
goto invalid_range;
|
||||||
|
|
||||||
|
range->max = strtol (minus + 1, &tmp, 10);
|
||||||
|
if (*tmp && *tmp != ';')
|
||||||
|
goto invalid_range;
|
||||||
} else {
|
} else {
|
||||||
range->min = atoi (str);
|
range->min = strtol (str, &tmp, 10);
|
||||||
|
if (str == tmp || (*tmp && *tmp != ';'))
|
||||||
|
goto invalid_range;
|
||||||
|
|
||||||
range->max = -1;
|
range->max = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
invalid_range:
|
||||||
|
{
|
||||||
|
range->min = -1;
|
||||||
|
range->max = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
range_as_text (const RTSPRange * 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 RTSPTransport * 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 RTSPTransport * 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 RTSPTransport * transport)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
/* need to special case RTSP_LOWER_TRANS_UDP_MCAST */
|
||||||
|
if (transport->lower_transport == 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTSPResult
|
RTSPResult
|
||||||
rtsp_transport_parse (const gchar * str, RTSPTransport * transport)
|
rtsp_transport_parse (const gchar * str, RTSPTransport * transport)
|
||||||
{
|
{
|
||||||
gchar **split, *down;
|
gchar **split, *down, **transp = NULL;
|
||||||
|
guint transport_params = 0;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
|
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
|
||||||
|
@ -193,52 +302,112 @@ rtsp_transport_parse (const gchar * str, RTSPTransport * transport)
|
||||||
down = g_ascii_strdown (str, -1);
|
down = g_ascii_strdown (str, -1);
|
||||||
|
|
||||||
split = g_strsplit (down, ";", 0);
|
split = g_strsplit (down, ";", 0);
|
||||||
|
g_free (down);
|
||||||
|
|
||||||
/* First field contains the transport/profile/lower_transport */
|
/* First field contains the transport/profile/lower_transport */
|
||||||
i = 0;
|
if (split[0] == NULL)
|
||||||
if (split[0]) {
|
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++)
|
for (i = 0; transports[i].name; i++)
|
||||||
if (strstr (split[0], transports[i].name))
|
if (strcmp (transp[0], transports[i].name) == 0)
|
||||||
break;
|
break;
|
||||||
transport->trans = transports[i].mode;
|
transport->trans = transports[i].mode;
|
||||||
|
|
||||||
for (i = 0; profiles[i].name; i++)
|
for (i = 0; profiles[i].name; i++)
|
||||||
if (strstr (split[0], profiles[i].name))
|
if (strcmp (transp[1], profiles[i].name) == 0)
|
||||||
break;
|
break;
|
||||||
transport->profile = profiles[i].profile;
|
transport->profile = profiles[i].profile;
|
||||||
|
|
||||||
|
if (transp[2] != NULL) {
|
||||||
for (i = 0; ltrans[i].name; i++)
|
for (i = 0; ltrans[i].name; i++)
|
||||||
if (strstr (split[0], ltrans[i].name))
|
if (strcmp (transp[2], ltrans[i].name) == 0)
|
||||||
break;
|
break;
|
||||||
transport->lower_transport = ltrans[i].ltrans;
|
transport->lower_transport = ltrans[i].ltrans;
|
||||||
i = 1;
|
} else {
|
||||||
}
|
/* specifying the lower transport is optional */
|
||||||
while (split[i]) {
|
if (transport->trans == RTSP_TRANS_RTP &&
|
||||||
if (g_str_has_prefix (split[i], "multicast")) {
|
transport->profile == RTSP_PROFILE_AVP)
|
||||||
transport->lower_transport = RTSP_LOWER_TRANS_UDP_MCAST;
|
transport->lower_transport = RTSP_LOWER_TRANS_UDP_MCAST;
|
||||||
} else if (g_str_has_prefix (split[i], "unicast")) {
|
else
|
||||||
|
transport->lower_transport = RTSP_LOWER_TRANS_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev (transp);
|
||||||
|
transp = NULL;
|
||||||
|
|
||||||
|
if (transport->trans == RTSP_TRANS_UNKNOWN ||
|
||||||
|
transport->profile == RTSP_PROFILE_UNKNOWN ||
|
||||||
|
transport->lower_transport == 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 == RTSP_LOWER_TRANS_TCP)
|
||||||
|
goto invalid_transport;
|
||||||
|
transport->lower_transport = RTSP_LOWER_TRANS_UDP_MCAST;
|
||||||
|
} else if (strcmp (split[i], "unicast") == 0) {
|
||||||
|
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DELIVERY);
|
||||||
if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST)
|
if (transport->lower_transport == RTSP_LOWER_TRANS_UDP_MCAST)
|
||||||
transport->lower_transport = RTSP_LOWER_TRANS_UDP;
|
transport->lower_transport = RTSP_LOWER_TRANS_UDP;
|
||||||
} else if (g_str_has_prefix (split[i], "destination=")) {
|
} else if (g_str_has_prefix (split[i], "destination=")) {
|
||||||
|
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_DESTINATION);
|
||||||
transport->destination = g_strdup (split[i] + 12);
|
transport->destination = g_strdup (split[i] + 12);
|
||||||
} else if (g_str_has_prefix (split[i], "source=")) {
|
} else if (g_str_has_prefix (split[i], "source=")) {
|
||||||
|
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SOURCE);
|
||||||
transport->source = g_strdup (split[i] + 7);
|
transport->source = g_strdup (split[i] + 7);
|
||||||
} else if (g_str_has_prefix (split[i], "layers=")) {
|
} else if (g_str_has_prefix (split[i], "layers=")) {
|
||||||
transport->layers = atoi (split[i] + 7);
|
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=")) {
|
} else if (g_str_has_prefix (split[i], "mode=")) {
|
||||||
|
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_MODE);
|
||||||
parse_mode (transport, split[i] + 5);
|
parse_mode (transport, split[i] + 5);
|
||||||
} else if (g_str_has_prefix (split[i], "append")) {
|
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;
|
transport->append = TRUE;
|
||||||
} else if (g_str_has_prefix (split[i], "interleaved=")) {
|
} else if (g_str_has_prefix (split[i], "interleaved=")) {
|
||||||
parse_range (transport, split[i] + 12, &transport->interleaved);
|
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_INTERLEAVED);
|
||||||
|
parse_range (split[i] + 12, &transport->interleaved);
|
||||||
|
if (transport->interleaved.min < 0 ||
|
||||||
|
transport->interleaved.min >= 256 ||
|
||||||
|
transport->interleaved.max >= 256)
|
||||||
|
goto invalid_transport;
|
||||||
} else if (g_str_has_prefix (split[i], "ttl=")) {
|
} else if (g_str_has_prefix (split[i], "ttl=")) {
|
||||||
transport->ttl = atoi (split[i] + 4);
|
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=")) {
|
} else if (g_str_has_prefix (split[i], "port=")) {
|
||||||
parse_range (transport, split[i] + 5, &transport->port);
|
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_PORT);
|
||||||
|
parse_range (split[i] + 5, &transport->port);
|
||||||
|
if (transport->port.min < 0 ||
|
||||||
|
transport->port.min >= 65536 || transport->port.max >= 65536)
|
||||||
|
goto invalid_transport;
|
||||||
} else if (g_str_has_prefix (split[i], "client_port=")) {
|
} else if (g_str_has_prefix (split[i], "client_port=")) {
|
||||||
parse_range (transport, split[i] + 12, &transport->client_port);
|
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_CLIENT_PORT);
|
||||||
|
parse_range (split[i] + 12, &transport->client_port);
|
||||||
|
if (transport->client_port.min < 0 ||
|
||||||
|
transport->client_port.min >= 65536 ||
|
||||||
|
transport->client_port.max >= 65536)
|
||||||
|
goto invalid_transport;
|
||||||
} else if (g_str_has_prefix (split[i], "server_port=")) {
|
} else if (g_str_has_prefix (split[i], "server_port=")) {
|
||||||
parse_range (transport, split[i] + 12, &transport->server_port);
|
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SERVER_PORT);
|
||||||
|
parse_range (split[i] + 12, &transport->server_port);
|
||||||
|
if (transport->server_port.min < 0 ||
|
||||||
|
transport->server_port.min >= 65536 ||
|
||||||
|
transport->server_port.max >= 65536)
|
||||||
|
goto invalid_transport;
|
||||||
} else if (g_str_has_prefix (split[i], "ssrc=")) {
|
} else if (g_str_has_prefix (split[i], "ssrc=")) {
|
||||||
transport->ssrc = g_strdup (split[i] + 5);
|
RTSP_TRANSPORT_PARAMETER_IS_UNIQUE (RTSP_TRANSPORT_SSRC);
|
||||||
|
transport->ssrc = strtoul (split[i] + 5, NULL, 16);
|
||||||
} else {
|
} else {
|
||||||
/* unknown field... */
|
/* unknown field... */
|
||||||
g_warning ("unknown transport field \"%s\"", split[i]);
|
g_warning ("unknown transport field \"%s\"", split[i]);
|
||||||
|
@ -246,9 +415,165 @@ rtsp_transport_parse (const gchar * str, RTSPTransport * transport)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
g_strfreev (split);
|
g_strfreev (split);
|
||||||
g_free (down);
|
|
||||||
|
|
||||||
return RTSP_OK;
|
return RTSP_OK;
|
||||||
|
|
||||||
|
unsupported_transport:
|
||||||
|
{
|
||||||
|
g_strfreev (split);
|
||||||
|
return RTSP_ERROR;
|
||||||
|
}
|
||||||
|
invalid_transport:
|
||||||
|
{
|
||||||
|
g_strfreev (transp);
|
||||||
|
g_strfreev (split);
|
||||||
|
return RTSP_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
rtsp_transport_as_text (RTSPTransport * 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 != RTSP_TRANS_RTP ||
|
||||||
|
transport->profile != RTSP_PROFILE_AVP ||
|
||||||
|
transport->lower_transport == 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 == 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 == 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 == 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->trans == 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 == 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 == 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 != 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RTSPResult
|
RTSPResult
|
||||||
|
|
|
@ -117,21 +117,21 @@ typedef struct _RTSPTransport {
|
||||||
|
|
||||||
gchar *destination;
|
gchar *destination;
|
||||||
gchar *source;
|
gchar *source;
|
||||||
gint layers;
|
guint layers;
|
||||||
gboolean mode_play;
|
gboolean mode_play;
|
||||||
gboolean mode_record;
|
gboolean mode_record;
|
||||||
gboolean append;
|
gboolean append;
|
||||||
RTSPRange interleaved;
|
RTSPRange interleaved;
|
||||||
|
|
||||||
/* multicast specific */
|
/* multicast specific */
|
||||||
gint ttl;
|
guint ttl;
|
||||||
|
|
||||||
/* UDP specific */
|
/* UDP specific */
|
||||||
RTSPRange port;
|
RTSPRange port;
|
||||||
RTSPRange client_port;
|
RTSPRange client_port;
|
||||||
RTSPRange server_port;
|
RTSPRange server_port;
|
||||||
/* RTP specific */
|
/* RTP specific */
|
||||||
gchar *ssrc;
|
guint ssrc;
|
||||||
|
|
||||||
} RTSPTransport;
|
} RTSPTransport;
|
||||||
|
|
||||||
|
@ -139,6 +139,7 @@ RTSPResult rtsp_transport_new (RTSPTransport **transport);
|
||||||
RTSPResult rtsp_transport_init (RTSPTransport *transport);
|
RTSPResult rtsp_transport_init (RTSPTransport *transport);
|
||||||
|
|
||||||
RTSPResult rtsp_transport_parse (const gchar *str, RTSPTransport *transport);
|
RTSPResult rtsp_transport_parse (const gchar *str, RTSPTransport *transport);
|
||||||
|
gchar *rtsp_transport_as_text (RTSPTransport *transport);
|
||||||
|
|
||||||
RTSPResult rtsp_transport_get_mime (RTSPTransMode trans, const gchar **mime);
|
RTSPResult rtsp_transport_get_mime (RTSPTransMode trans, const gchar **mime);
|
||||||
RTSPResult rtsp_transport_get_manager (RTSPTransMode trans, const gchar **manager, guint option);
|
RTSPResult rtsp_transport_get_manager (RTSPTransMode trans, const gchar **manager, guint option);
|
||||||
|
|
Loading…
Reference in a new issue