Commit d70b1973 authored by Youness Alaoui's avatar Youness Alaoui

Add new parsing API, for stream and candidates

parent 4ef4f8f7
......@@ -2225,26 +2225,12 @@ nice_agent_get_local_credentials (
return ret;
}
NICEAPI_EXPORT int
nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint component_id, const GSList *candidates)
static int
_set_remote_candidates_locked (NiceAgent *agent, Stream *stream,
Component *component, const GSList *candidates)
{
const GSList *i;
const GSList *i;
int added = 0;
Stream *stream;
Component *component;
nice_debug ("Agent %p: set_remote_candidates %d %d", agent, stream_id, component_id);
agent_lock();
if (!agent_find_component (agent, stream_id, component_id,
&stream, &component)) {
g_warning ("Could not find component %u in stream %u", component_id,
stream_id);
added = -1;
goto done;
}
if (agent->reliable && component->tcp == NULL) {
nice_debug ("Agent %p: not setting remote candidate for s%d:%d because "
......@@ -2259,8 +2245,8 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo
if (nice_address_is_valid (&d->addr) == TRUE) {
gboolean res =
priv_add_remote_candidate (agent,
stream_id,
component_id,
stream->id,
component->id,
d->type,
&d->addr,
&d->base_addr,
......@@ -2283,11 +2269,38 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo
}
done:
agent_unlock();
return added;
}
NICEAPI_EXPORT int
nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint component_id, const GSList *candidates)
{
int added = 0;
Stream *stream;
Component *component;
nice_debug ("Agent %p: set_remote_candidates %d %d", agent, stream_id, component_id);
agent_lock();
if (!agent_find_component (agent, stream_id, component_id,
&stream, &component)) {
g_warning ("Could not find component %u in stream %u", component_id,
stream_id);
added = -1;
goto done;
}
added = _set_remote_candidates_locked (agent, stream, component, candidates);
done:
agent_unlock();
return added;
}
static gint
_nice_agent_recv (
NiceAgent *agent,
......@@ -3052,6 +3065,77 @@ nice_agent_get_stream_name (NiceAgent *agent, guint stream_id)
return name;
}
static NiceCandidate *
_get_default_local_candidate_locked (NiceAgent *agent,
Stream *stream, Component *component)
{
GSList *i;
NiceCandidate *default_candidate = NULL;
NiceCandidate *default_rtp_candidate = NULL;
if (component->id != NICE_COMPONENT_TYPE_RTP) {
Component *rtp_component;
if (!agent_find_component (agent, stream->id, NICE_COMPONENT_TYPE_RTP,
NULL, &rtp_component))
goto done;
default_rtp_candidate = _get_default_local_candidate_locked (agent, stream,
rtp_component);
if (default_rtp_candidate == NULL)
goto done;
}
for (i = component->local_candidates; i; i = i->next) {
NiceCandidate *local_candidate = i->data;
/* Only check for ipv4 candidates */
if (nice_address_ip_version (&local_candidate->addr) != 4)
continue;
if (component->id == NICE_COMPONENT_TYPE_RTP) {
if (default_candidate == NULL ||
local_candidate->priority < default_candidate->priority) {
default_candidate = local_candidate;
}
} else if (strncmp (local_candidate->foundation,
default_rtp_candidate->foundation,
NICE_CANDIDATE_MAX_FOUNDATION) == 0) {
default_candidate = local_candidate;
break;
}
}
done:
return default_candidate;
}
NICEAPI_EXPORT NiceCandidate *
nice_agent_get_default_local_candidate (NiceAgent *agent,
guint stream_id, guint component_id)
{
Stream *stream = NULL;
Component *component = NULL;
NiceCandidate *default_candidate = NULL;
agent_lock ();
/* step: check if the component exists*/
if (!agent_find_component (agent, stream_id, component_id,
&stream, &component))
goto done;
default_candidate = _get_default_local_candidate_locked (agent, stream,
component);
if (default_candidate)
default_candidate = nice_candidate_copy (default_candidate);
done:
agent_unlock ();
return default_candidate;
}
static const gchar *
_cand_type_to_sdp (NiceCandidateType type) {
switch(type) {
......@@ -3067,17 +3151,34 @@ _cand_type_to_sdp (NiceCandidateType type) {
}
}
static void
_generate_candidate_sdp (NiceAgent *agent,
NiceCandidate *candidate, GString *sdp)
{
gchar ip4[INET6_ADDRSTRLEN];
NICEAPI_EXPORT gchar *
nice_agent_generate_local_sdp (NiceAgent *agent)
nice_address_to_string (&candidate->addr, ip4);
g_string_append_printf (sdp, "a=candidate:%.*s %d %s %d %s %d",
NICE_CANDIDATE_MAX_FOUNDATION, candidate->foundation,
candidate->component_id,
candidate->transport == NICE_CANDIDATE_TRANSPORT_UDP ? "UDP" : "???",
candidate->priority, ip4, nice_address_get_port (&candidate->addr));
g_string_append_printf (sdp, " typ %s", _cand_type_to_sdp (candidate->type));
if (nice_address_is_valid (&candidate->base_addr) &&
!nice_address_equal (&candidate->addr, &candidate->base_addr)) {
nice_address_to_string (&candidate->base_addr, ip4);
g_string_append_printf (sdp, " raddr %s rport %d", ip4,
nice_address_get_port (&candidate->base_addr));
}
}
static void
_generate_stream_sdp (NiceAgent *agent, Stream *stream,
GString *sdp, gboolean include_non_ice)
{
GString * sdp = g_string_new (NULL);
GSList *i, *j, *k;
GSList *i, *j;
agent_lock();
for (i = agent->streams; i; i = i->next) {
Stream *stream = i->data;
NiceCandidate *default_candidate = NULL;
if (include_non_ice) {
NiceAddress rtp, rtcp;
gchar ip4[INET6_ADDRSTRLEN];
......@@ -3087,31 +3188,20 @@ nice_agent_generate_local_sdp (NiceAgent *agent)
nice_address_set_ipv4 (&rtcp, 0);
/* Find default candidates */
for (j = stream->components; j; j = j->next) {
Component *component = j->data;
for (k = component->local_candidates; k; k = k->next) {
NiceCandidate *local_candidate = k->data;
if (local_candidate->component_id > 2)
continue;
/* Only check for ipv4 candidates */
if (nice_address_ip_version (&local_candidate->addr) != 4)
continue;
if (component->id == NICE_COMPONENT_TYPE_RTP) {
if (default_candidate == NULL ||
local_candidate->priority < default_candidate->priority) {
default_candidate = local_candidate;
rtp = local_candidate->addr;
}
} else if (component->id == NICE_COMPONENT_TYPE_RTCP &&
default_candidate != NULL &&
strncmp (local_candidate->foundation, default_candidate->foundation,
NICE_CANDIDATE_MAX_FOUNDATION) == 0) {
rtcp = local_candidate->addr;
break;
}
for (i = stream->components; i; i = i->next) {
Component *component = i->data;
NiceCandidate *default_candidate;
if (component->id == NICE_COMPONENT_TYPE_RTP) {
default_candidate = _get_default_local_candidate_locked (agent, stream,
component);
if (default_candidate)
rtp = default_candidate->addr;
} else if (component->id == NICE_COMPONENT_TYPE_RTCP) {
default_candidate = _get_default_local_candidate_locked (agent, stream,
component);
if (default_candidate)
rtcp = default_candidate->addr;
}
}
......@@ -3122,31 +3212,78 @@ nice_agent_generate_local_sdp (NiceAgent *agent)
if (nice_address_get_port (&rtcp) != 0)
g_string_append_printf (sdp, "a=rtcp:%d\n",
nice_address_get_port (&rtcp));
g_string_append_printf (sdp, "a=ice-ufrag:%s\n", stream->local_ufrag);
g_string_append_printf (sdp, "a=ice-pwd:%s\n", stream->local_password);
}
for (j = stream->components; j; j = j->next) {
Component *component = j->data;
g_string_append_printf (sdp, "a=ice-ufrag:%s\n", stream->local_ufrag);
g_string_append_printf (sdp, "a=ice-pwd:%s\n", stream->local_password);
for (k = component->local_candidates; k; k = k->next) {
NiceCandidate *cand = k->data;
nice_address_to_string (&cand->addr, ip4);
g_string_append_printf (sdp, "a=candidate:%.*s %d %s %d %s %d",
NICE_CANDIDATE_MAX_FOUNDATION, cand->foundation, cand->component_id,
cand->transport == NICE_CANDIDATE_TRANSPORT_UDP ? "UDP" : "???",
cand->priority, ip4, nice_address_get_port (&cand->addr));
g_string_append_printf (sdp, " typ %s", _cand_type_to_sdp (cand->type));
if (nice_address_is_valid (&cand->base_addr) &&
!nice_address_equal (&cand->addr, &cand->base_addr)) {
nice_address_to_string (&cand->base_addr, ip4);
g_string_append_printf (sdp, " raddr %s rport %d", ip4,
nice_address_get_port (&cand->base_addr));
}
g_string_append (sdp, "\n");
}
for (i = stream->components; i; i = i->next) {
Component *component = i->data;
for (j = component->local_candidates; j; j = j->next) {
NiceCandidate *candidate = j->data;
_generate_candidate_sdp (agent, candidate, sdp);
g_string_append (sdp, "\n");
}
}
}
NICEAPI_EXPORT gchar *
nice_agent_generate_local_sdp (NiceAgent *agent)
{
GString * sdp = g_string_new (NULL);
GSList *i;
agent_lock();
for (i = agent->streams; i; i = i->next) {
Stream *stream = i->data;
_generate_stream_sdp (agent, stream, sdp, TRUE);
}
agent_unlock();
return g_string_free (sdp, FALSE);
}
NICEAPI_EXPORT gchar *
nice_agent_generate_local_stream_sdp (NiceAgent *agent, guint stream_id,
gboolean include_non_ice)
{
GString *sdp = NULL;
gchar *ret = NULL;
Stream *stream;
agent_lock();
stream = agent_find_stream (agent, stream_id);
if (stream == NULL)
goto done;
sdp = g_string_new (NULL);
_generate_stream_sdp (agent, stream, sdp, include_non_ice);
ret = g_string_free (sdp, FALSE);
done:
agent_unlock();
return ret;
}
NICEAPI_EXPORT gchar *
nice_agent_generate_local_candidate_sdp (NiceAgent *agent,
NiceCandidate *candidate)
{
GString *sdp = NULL;
g_return_val_if_fail(candidate, NULL);
agent_lock();
sdp = g_string_new (NULL);
_generate_candidate_sdp (agent, candidate, sdp);
agent_unlock();
......@@ -3193,137 +3330,93 @@ nice_agent_parse_remote_sdp (NiceAgent *agent, const gchar *sdp)
}
g_free (name);
} else if (g_str_has_prefix (sdp_lines[i], "a=ice-ufrag:")) {
const gchar *ufrag = sdp_lines[i] + 12;
if (current_stream == NULL) {
ret = -1;
goto done;
}
g_strlcpy (current_stream->remote_ufrag, ufrag, NICE_STREAM_MAX_UFRAG);
g_strlcpy (current_stream->remote_ufrag, sdp_lines[i] + 12,
NICE_STREAM_MAX_UFRAG);
} else if (g_str_has_prefix (sdp_lines[i], "a=ice-pwd:")) {
const gchar *pwd = sdp_lines[i] + 10;
if (current_stream == NULL) {
ret = -1;
goto done;
}
g_strlcpy (current_stream->remote_password, pwd, NICE_STREAM_MAX_PWD);
g_strlcpy (current_stream->remote_password, sdp_lines[i] + 10,
NICE_STREAM_MAX_PWD);
} else if (g_str_has_prefix (sdp_lines[i], "a=candidate:")) {
const gchar *candidate = sdp_lines[i] + 12;
int ntype = -1;
gchar **tokens = NULL;
const gchar *foundation = NULL;
guint component_id;
const gchar *transport = NULL;
guint32 priority;
const gchar *addr = NULL;
guint16 port;
const gchar *type = NULL;
const gchar *raddr = NULL;
guint16 rport;
static const gchar *type_names[] = {"host", "srflx", "prflx", "relay"};
guint j;
NiceCandidate *candidate = NULL;
Component *component = NULL;
GSList *cands = NULL;
gint added;
if (current_stream == NULL) {
ret = -1;
goto done;
}
tokens = g_strsplit (candidate, " ", 0);
for (j = 0; tokens && tokens[j]; j++) {
switch (j) {
case 0:
foundation = tokens[j];
break;
case 1:
component_id = (guint) g_ascii_strtoull (tokens[j], NULL, 10);
break;
case 2:
transport = tokens[j];
break;
case 3:
priority = (guint32) g_ascii_strtoull (tokens[j], NULL, 10);
break;
case 4:
addr = tokens[j];
break;
case 5:
port = (guint16) g_ascii_strtoull (tokens[j], NULL, 10);
break;
default:
if (tokens[j + 1] == NULL) {
g_strfreev(tokens);
ret = -1;
goto done;
}
if (g_strcmp0 (tokens[j], "typ") == 0) {
type = tokens[j + 1];
} else if (g_strcmp0 (tokens[j], "raddr") == 0) {
raddr = tokens[j + 1];
} else if (g_strcmp0 (tokens[j], "rport") == 0) {
rport = (guint16) g_ascii_strtoull (tokens[j + 1], NULL, 10);
}
j++;
break;
}
}
if (type == NULL) {
g_strfreev(tokens);
candidate = nice_agent_parse_remote_candidate_sdp (agent,
current_stream->id, sdp_lines[i]);
if (candidate == NULL) {
ret = -1;
goto done;
}
ntype = -1;
for (j = 0; j < G_N_ELEMENTS (type_names); j++) {
if (g_strcmp0 (type, type_names[j]) == 0) {
ntype = j;
break;
}
}
if (ntype == -1) {
g_strfreev(tokens);
if (!agent_find_component (agent, candidate->stream_id,
candidate->component_id, NULL, &component)) {
nice_candidate_free (candidate);
ret = -1;
goto done;
}
cands = g_slist_prepend (cands, candidate);
added = _set_remote_candidates_locked (agent, current_stream,
component, cands);
g_slist_free_full(cands, (GDestroyNotify)&nice_candidate_free);
if (added > 0)
ret++;
}
}
if (g_strcmp0 (transport, "UDP") == 0) {
NiceCandidate *cand = NULL;
GSList *cands = NULL;
gint added;
cand = nice_candidate_new(ntype);
cand->component_id = component_id;
cand->stream_id = current_stream->id;
cand->transport = NICE_CANDIDATE_TRANSPORT_UDP;
g_strlcpy(cand->foundation, foundation, NICE_CANDIDATE_MAX_FOUNDATION);
cand->priority = priority;
if (!nice_address_set_from_string (&cand->addr, addr)) {
nice_candidate_free (cand);
g_strfreev(tokens);
ret = -1;
goto done;
}
nice_address_set_port (&cand->addr, port);
if (raddr && rport) {
if (!nice_address_set_from_string (&cand->base_addr, raddr)) {
nice_candidate_free (cand);
g_strfreev(tokens);
ret = -1;
goto done;
}
nice_address_set_port (&cand->base_addr, rport);
}
done:
if (sdp_lines)
g_strfreev(sdp_lines);
cands = g_slist_prepend (cands, cand);
added = nice_agent_set_remote_candidates (agent, current_stream->id,
component_id, cands);
g_slist_free_full(cands, (GDestroyNotify)&nice_candidate_free);
if (added > 0)
ret++;
agent_unlock();
return ret;
}
NICEAPI_EXPORT GSList *
nice_agent_parse_remote_stream_sdp (NiceAgent *agent, guint stream_id,
const gchar *sdp, gchar **ufrag, gchar **pwd)
{
Stream *stream = NULL;
gchar **sdp_lines = NULL;
GSList *candidates = NULL;
gint i;
agent_lock();
stream = agent_find_stream (agent, stream_id);
if (stream == NULL) {
goto done;
}
sdp_lines = g_strsplit (sdp, "\n", 0);
for (i = 0; sdp_lines && sdp_lines[i]; i++) {
if (ufrag && g_str_has_prefix (sdp_lines[i], "a=ice-ufrag:")) {
*ufrag = g_strdup (sdp_lines[i] + 12);
} else if (pwd && g_str_has_prefix (sdp_lines[i], "a=ice-pwd:")) {
*pwd = g_strdup (sdp_lines[i] + 10);
} else if (g_str_has_prefix (sdp_lines[i], "a=candidate:")) {
NiceCandidate *candidate = NULL;
candidate = nice_agent_parse_remote_candidate_sdp (agent, stream->id,
sdp_lines[i]);
if (candidate == NULL) {
g_slist_free_full(candidates, (GDestroyNotify)&nice_candidate_free);
candidates = NULL;
break;
}
g_strfreev(tokens);
candidates = g_slist_prepend (candidates, candidate);
}
}
......@@ -3333,5 +3426,108 @@ nice_agent_parse_remote_sdp (NiceAgent *agent, const gchar *sdp)
agent_unlock();
return ret;
return candidates;
}
NICEAPI_EXPORT NiceCandidate *
nice_agent_parse_remote_candidate_sdp (NiceAgent *agent, guint stream_id,
const gchar *sdp)
{
NiceCandidate *candidate = NULL;
int ntype = -1;
gchar **tokens = NULL;
const gchar *foundation = NULL;
guint component_id;
const gchar *transport = NULL;
guint32 priority;
const gchar *addr = NULL;
guint16 port;
const gchar *type = NULL;
const gchar *raddr = NULL;
guint16 rport;
static const gchar *type_names[] = {"host", "srflx", "prflx", "relay"};
guint i;
if (!g_str_has_prefix (sdp, "a=candidate:"))
goto done;
tokens = g_strsplit (sdp + 12, " ", 0);
for (i = 0; tokens && tokens[i]; i++) {
switch (i) {
case 0:
foundation = tokens[i];
break;
case 1:
component_id = (guint) g_ascii_strtoull (tokens[i], NULL, 10);
break;
case 2:
transport = tokens[i];
break;
case 3:
priority = (guint32) g_ascii_strtoull (tokens[i], NULL, 10);
break;
case 4:
addr = tokens[i];
break;
case 5:
port = (guint16) g_ascii_strtoull (tokens[i], NULL, 10);
break;
default:
if (tokens[i + 1] == NULL)
goto done;
if (g_strcmp0 (tokens[i], "typ") == 0) {
type = tokens[i + 1];
} else if (g_strcmp0 (tokens[i], "raddr") == 0) {
raddr = tokens[i + 1];
} else if (g_strcmp0 (tokens[i], "rport") == 0) {
rport = (guint16) g_ascii_strtoull (tokens[i + 1], NULL, 10);
}
i++;
break;
}
}
if (type == NULL)
goto done;
ntype = -1;
for (i = 0; i < G_N_ELEMENTS (type_names); i++) {
if (g_strcmp0 (type, type_names[i]) == 0) {
ntype = i;
break;
}
}
if (ntype == -1)
goto done;
if (g_strcmp0 (transport, "UDP") == 0) {
candidate = nice_candidate_new(ntype);
candidate->component_id = component_id;
candidate->stream_id = stream_id;
candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP;
g_strlcpy(candidate->foundation, foundation, NICE_CANDIDATE_MAX_FOUNDATION);
candidate->priority = priority;
if (!nice_address_set_from_string (&candidate->addr, addr)) {
nice_candidate_free (candidate);
candidate = NULL;
goto done;
}
nice_address_set_port (&candidate->addr, port);
if (raddr && rport) {
if (!nice_address_set_from_string (&candidate->base_addr, raddr)) {
nice_candidate_free (candidate);
candidate = NULL;
goto done;
}
nice_address_set_port (&candidate->base_addr, rport);
}
}
done:
if (tokens)
g_strfreev(tokens);
return candidate;
}
......@@ -823,11 +823,39 @@ const gchar *nice_agent_get_stream_name (
NiceAgent *agent,
guint stream_id);
/**
* nice_agent_get_default_local_candidate:
* @agent: The #NiceAgent Object
* @stream_id: The ID of the stream
* @component_id: The ID of the component
*
* This helper function will return the recommended default candidate to be
* used for non-ICE compatible clients. This will usually be the candidate
* with the lowest priority, since it will be the longest path but the one with
* the most chances of success.
* <note>
<para>
This function is only useful in order to manually generate the
local SDP
</para>
* </note>
*
* Returns: The candidate to be used as the default candidate, or %NULL in case
* of error. Must be freed with nice_candidate_free() once done.
*
*/
NiceCandidate *
nice_agent_get_default_local_candidate (
NiceAgent *agent,
guint stream_id,
guint component_id);
/**
* nice_agent_generate_local_sdp:
* @agent: The #NiceAgent Object
*
* Generate an SDP string containing the local candidates and credentials.
* Generate an SDP string containing the local candidates and credentials for
* all streams and components in the agent.
*
<note>
<para>
......@@ -842,12 +870,15 @@ const gchar *nice_agent_get_stream_name (
</para>
<para>
The default candidate in the SDP will be selected based on the lowest
priority candidate.
priority candidate for the first component.
</para>
</note>
*
* <para>See also: nice_agent_set_stream_name() </para>
* <para>See also: nice_agent_parse_remote_sdp() </para>
* <para>See also: nice_agent_generate_local_stream_sdp() </para>
* <para>See also: nice_agent_generate_local_candidate_sdp() </para>
* <para>See also: nice_agent_get_default_local_candidate() </para>
*
* Returns: A string representing the local SDP. Must be freed with g_free()
* once done.
......@@ -858,6 +889,69 @@ gchar *
nice_agent_generate_local_sdp (
NiceAgent *agent);
/**
* nice_agent_generate_local_stream_sdp:
* @agent: The #NiceAgent Object
* @stream_id: The ID of the stream
* @include_non_ice: Whether or not to include non ICE specific lines
* (m=, c= and a=rtcp: lines)
*
* Generate an SDP string containing the local candidates and credentials
* for a stream.
*
<note>
<para>
The SDP will not contain any codec lines and the 'm' line will not list
any payload types.
</para>
<para>
It is highly recommended to set the name of the stream prior to calling this
function. Unnamed streams will show up as '-' in the 'm' line.
</para>
<para>
The default candidate in the SDP will be selected based on the lowest
priority candidate.
</para>
</note>
*
* <para>See also: nice_agent_set_stream_name() </para>
* <para>See also: nice_agent_parse_remote_stream_sdp() </para>
* <para>See also: nice_agent_generate_local_sdp() </para>
* <para>See also: nice_agent_generate_local_candidate_sdp() </para>
* <para>See also: nice_agent_get_default_local_candidate() </para>
*
* Returns: A string representing the local SDP for the stream. Must be freed
* with g_free() once done.
*
* Since: 0.1.4
**/
gchar *
nice_agent_generate_local_stream_sdp (
NiceAgent *agent,
guint stream_id,
gboolean include_non_ice);
/**
* nice_agent_generate_local_candidate_sdp:
* @agent: The #NiceAgent Object
* @candidate: The candidate to generate
*
* Generate an SDP string representing a local candidate.
*
* <para>See also: nice_agent_parse_remote_candidate_sdp() </para>
* <para>See also: nice_agent_generate_local_sdp() </para>
* <para>See also: nice_agent_generate_local_stream_sdp() </para>
*
* Returns: A string representing the SDP for the candidate. Must be freed
* with g_free() once done.
*
* Since: 0.1.4
**/
gchar *
nice_agent_generate_local_candidate_sdp (
NiceAgent *agent,
NiceCandidate *candidate);
/**
* nice_agent_parse_remote_sdp:
* @agent: The #NiceAgent Object
......@@ -877,6 +971,8 @@ nice_agent_generate_local_sdp (
*
* <para>See also: nice_agent_set_stream_name() </para>
* <para>See also: nice_agent_generate_local_sdp() </para>
* <para>See also: nice_agent_parse_remote_stream_sdp() </para>
* <para>See also: nice_agent_parse_remote_candidate_sdp() </para>
*
* Returns: The number of candidates added, negative on errors
*
......@@ -888,6 +984,59 @@ nice_agent_parse_remote_sdp (
const gchar *sdp);
/**
* nice_agent_parse_remote_stream_sdp:
* @agent: The #NiceAgent Object
* @stream_id: The ID of the stream to parse
* @sdp: The remote SDP to parse
* @ufrag: Pointer to store the ice ufrag if non %NULL. Must be freed with
* g_free() after use
* @pwd: Pointer to store the ice password if non %NULL. Must be freed with
* g_free() after use
*
* Parse an SDP string representing a single stream and extracts candidates
* and credentials from it.
*
* <para>See also: nice_agent_generate_local_stream_sdp() </para>
* <para>See also: nice_agent_parse_remote_sdp() </para>
* <para>See also: nice_agent_parse_remote_candidate_sdp() </para>
*
* Returns: A #GSList of candidates parsed from the SDP, or %NULL in case of
* errors
*
* Since: 0.1.4
**/
GSList *
nice_agent_parse_remote_stream_sdp (
NiceAgent *agent,
guint stream_id,
const gchar *sdp,
gchar **ufrag,
gchar **pwd);
/**
* nice_agent_parse_remote_candidate_sdp:
* @agent: The #NiceAgent Object
* @stream_id: The ID of the stream the candidate belongs to
* @sdp: The remote SDP to parse
*
* Parse an SDP string and extracts the candidate from it.
*
* <para>See also: nice_agent_generate_local_candidate_sdp() </para>
* <para>See also: nice_agent_parse_remote_sdp() </para>
* <para>See also: nice_agent_parse_remote_stream_sdp() </para>
*
* Returns: The parsed candidate or %NULL if there was an error.
*
* Since: 0.1.4
**/
NiceCandidate *
nice_agent_parse_remote_candidate_sdp (
NiceAgent *agent,
guint stream_id,
const gchar *sdp);
G_END_DECLS
#endif /* _AGENT_H */
......
......@@ -30,8 +30,13 @@ nice_agent_set_software
nice_agent_restart
nice_agent_set_stream_name
nice_agent_get_stream_name
nice_agent_get_default_local_candidate
nice_agent_generate_local_sdp
nice_agent_generate_local_stream_sdp
nice_agent_generate_local_canidate_sdp
nice_agent_parse_remote_sdp
nice_agent_parse_remote_stream_sdp
nice_agent_parse_remote_candidate_sdp
<SUBSECTION Standard>
NICE_AGENT
NICE_IS_AGENT
......
......@@ -18,7 +18,10 @@ nice_agent_add_local_address
nice_agent_add_stream
nice_agent_attach_recv
nice_agent_gather_candidates
nice_agent_generate_local_candidate_sdp
nice_agent_generate_local_sdp
nice_agent_generate_local_stream_sdp
nice_agent_get_default_local_candidate
nice_agent_get_local_candidates
nice_agent_get_local_credentials
nice_agent_get_remote_candidates
......@@ -27,7 +30,9 @@ nice_agent_get_stream_name
nice_agent_get_type
nice_agent_new
nice_agent_new_reliable
nice_agent_parse_remote_candidate_sdp
nice_agent_parse_remote_sdp
nice_agent_parse_remote_stream_sdp
nice_agent_remove_stream
nice_agent_restart
nice_agent_send
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment