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 ( ...@@ -2225,26 +2225,12 @@ nice_agent_get_local_credentials (
return ret; return ret;
} }
NICEAPI_EXPORT int static int
nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint component_id, const GSList *candidates) _set_remote_candidates_locked (NiceAgent *agent, Stream *stream,
Component *component, const GSList *candidates)
{ {
const GSList *i; const GSList *i;
int added = 0; 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) { if (agent->reliable && component->tcp == NULL) {
nice_debug ("Agent %p: not setting remote candidate for s%d:%d because " 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 ...@@ -2259,8 +2245,8 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo
if (nice_address_is_valid (&d->addr) == TRUE) { if (nice_address_is_valid (&d->addr) == TRUE) {
gboolean res = gboolean res =
priv_add_remote_candidate (agent, priv_add_remote_candidate (agent,
stream_id, stream->id,
component_id, component->id,
d->type, d->type,
&d->addr, &d->addr,
&d->base_addr, &d->base_addr,
...@@ -2282,8 +2268,35 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo ...@@ -2282,8 +2268,35 @@ nice_agent_set_remote_candidates (NiceAgent *agent, guint stream_id, guint compo
nice_debug ("Agent %p : Warning: unable to schedule any conn checks!", agent); nice_debug ("Agent %p : Warning: unable to schedule any conn checks!", agent);
} }
done:
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: done:
agent_unlock(); agent_unlock();
return added; return added;
} }
...@@ -3052,6 +3065,77 @@ nice_agent_get_stream_name (NiceAgent *agent, guint stream_id) ...@@ -3052,6 +3065,77 @@ nice_agent_get_stream_name (NiceAgent *agent, guint stream_id)
return name; 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 * static const gchar *
_cand_type_to_sdp (NiceCandidateType type) { _cand_type_to_sdp (NiceCandidateType type) {
switch(type) { switch(type) {
...@@ -3067,17 +3151,34 @@ _cand_type_to_sdp (NiceCandidateType 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_address_to_string (&candidate->addr, ip4);
nice_agent_generate_local_sdp (NiceAgent *agent) 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;
GSList *i, *j, *k;
agent_lock(); if (include_non_ice) {
for (i = agent->streams; i; i = i->next) {
Stream *stream = i->data;
NiceCandidate *default_candidate = NULL;
NiceAddress rtp, rtcp; NiceAddress rtp, rtcp;
gchar ip4[INET6_ADDRSTRLEN]; gchar ip4[INET6_ADDRSTRLEN];
...@@ -3087,31 +3188,20 @@ nice_agent_generate_local_sdp (NiceAgent *agent) ...@@ -3087,31 +3188,20 @@ nice_agent_generate_local_sdp (NiceAgent *agent)
nice_address_set_ipv4 (&rtcp, 0); nice_address_set_ipv4 (&rtcp, 0);
/* Find default candidates */ /* Find default candidates */
for (j = stream->components; j; j = j->next) { for (i = stream->components; i; i = i->next) {
Component *component = j->data; Component *component = i->data;
NiceCandidate *default_candidate;
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 (component->id == NICE_COMPONENT_TYPE_RTP) {
if (default_candidate == NULL || default_candidate = _get_default_local_candidate_locked (agent, stream,
local_candidate->priority < default_candidate->priority) { component);
default_candidate = local_candidate; if (default_candidate)
rtp = local_candidate->addr; rtp = default_candidate->addr;
} } else if (component->id == NICE_COMPONENT_TYPE_RTCP) {
} else if (component->id == NICE_COMPONENT_TYPE_RTCP && default_candidate = _get_default_local_candidate_locked (agent, stream,
default_candidate != NULL && component);
strncmp (local_candidate->foundation, default_candidate->foundation, if (default_candidate)
NICE_CANDIDATE_MAX_FOUNDATION) == 0) { rtcp = default_candidate->addr;
rtcp = local_candidate->addr;
break;
}
} }
} }
...@@ -3122,30 +3212,35 @@ nice_agent_generate_local_sdp (NiceAgent *agent) ...@@ -3122,30 +3212,35 @@ nice_agent_generate_local_sdp (NiceAgent *agent)
if (nice_address_get_port (&rtcp) != 0) if (nice_address_get_port (&rtcp) != 0)
g_string_append_printf (sdp, "a=rtcp:%d\n", g_string_append_printf (sdp, "a=rtcp:%d\n",
nice_address_get_port (&rtcp)); 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-ufrag:%s\n", stream->local_ufrag);
g_string_append_printf (sdp, "a=ice-pwd:%s\n", stream->local_password); g_string_append_printf (sdp, "a=ice-pwd:%s\n", stream->local_password);
for (j = stream->components; j; j = j->next) { for (i = stream->components; i; i = i->next) {
Component *component = j->data; Component *component = i->data;
for (k = component->local_candidates; k; k = k->next) { for (j = component->local_candidates; j; j = j->next) {
NiceCandidate *cand = k->data; NiceCandidate *candidate = j->data;
nice_address_to_string (&cand->addr, ip4); _generate_candidate_sdp (agent, candidate, sdp);
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"); 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(); agent_unlock();
...@@ -3153,6 +3248,48 @@ nice_agent_generate_local_sdp (NiceAgent *agent) ...@@ -3153,6 +3248,48 @@ nice_agent_generate_local_sdp (NiceAgent *agent)
return g_string_free (sdp, FALSE); 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();
return g_string_free (sdp, FALSE);
}
NICEAPI_EXPORT gint NICEAPI_EXPORT gint
nice_agent_parse_remote_sdp (NiceAgent *agent, const gchar *sdp) nice_agent_parse_remote_sdp (NiceAgent *agent, const gchar *sdp)
{ {
...@@ -3193,23 +3330,110 @@ nice_agent_parse_remote_sdp (NiceAgent *agent, const gchar *sdp) ...@@ -3193,23 +3330,110 @@ nice_agent_parse_remote_sdp (NiceAgent *agent, const gchar *sdp)
} }
g_free (name); g_free (name);
} else if (g_str_has_prefix (sdp_lines[i], "a=ice-ufrag:")) { } else if (g_str_has_prefix (sdp_lines[i], "a=ice-ufrag:")) {
const gchar *ufrag = sdp_lines[i] + 12;
if (current_stream == NULL) { if (current_stream == NULL) {
ret = -1; ret = -1;
goto done; 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:")) { } 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, sdp_lines[i] + 10,
NICE_STREAM_MAX_PWD);
} else if (g_str_has_prefix (sdp_lines[i], "a=candidate:")) {
NiceCandidate *candidate = NULL;
Component *component = NULL;
GSList *cands = NULL;
gint added;
if (current_stream == NULL) { if (current_stream == NULL) {
ret = -1; ret = -1;
goto done; goto done;
} }
g_strlcpy (current_stream->remote_password, pwd, NICE_STREAM_MAX_PWD); candidate = nice_agent_parse_remote_candidate_sdp (agent,
current_stream->id, sdp_lines[i]);
if (candidate == NULL) {
ret = -1;
goto done;
}
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++;
}
}
done:
if (sdp_lines)
g_strfreev(sdp_lines);
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:")) { } else if (g_str_has_prefix (sdp_lines[i], "a=candidate:")) {
const gchar *candidate = sdp_lines[i] + 12; 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;
}
candidates = g_slist_prepend (candidates, candidate);
}
}
done:
if (sdp_lines)
g_strfreev(sdp_lines);
agent_unlock();
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; int ntype = -1;
gchar **tokens = NULL; gchar **tokens = NULL;
const gchar *foundation = NULL; const gchar *foundation = NULL;
...@@ -3222,116 +3446,88 @@ nice_agent_parse_remote_sdp (NiceAgent *agent, const gchar *sdp) ...@@ -3222,116 +3446,88 @@ nice_agent_parse_remote_sdp (NiceAgent *agent, const gchar *sdp)
const gchar *raddr = NULL; const gchar *raddr = NULL;
guint16 rport; guint16 rport;
static const gchar *type_names[] = {"host", "srflx", "prflx", "relay"}; static const gchar *type_names[] = {"host", "srflx", "prflx", "relay"};
guint j; guint i;
if (current_stream == NULL) { if (!g_str_has_prefix (sdp, "a=candidate:"))
ret = -1;
goto done; goto done;
}
tokens = g_strsplit (candidate, " ", 0); tokens = g_strsplit (sdp + 12, " ", 0);
for (j = 0; tokens && tokens[j]; j++) { for (i = 0; tokens && tokens[i]; i++) {
switch (j) { switch (i) {
case 0: case 0:
foundation = tokens[j]; foundation = tokens[i];
break; break;
case 1: case 1:
component_id = (guint) g_ascii_strtoull (tokens[j], NULL, 10); component_id = (guint) g_ascii_strtoull (tokens[i], NULL, 10);
break; break;
case 2: case 2:
transport = tokens[j]; transport = tokens[i];
break; break;
case 3: case 3:
priority = (guint32) g_ascii_strtoull (tokens[j], NULL, 10); priority = (guint32) g_ascii_strtoull (tokens[i], NULL, 10);
break; break;
case 4: case 4:
addr = tokens[j]; addr = tokens[i];
break; break;
case 5: case 5:
port = (guint16) g_ascii_strtoull (tokens[j], NULL, 10); port = (guint16) g_ascii_strtoull (tokens[i], NULL, 10);
break; break;
default: default:
if (tokens[j + 1] == NULL) { if (tokens[i + 1] == NULL)
g_strfreev(tokens);
ret = -1;
goto done; 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);
} }
if (g_strcmp0 (tokens[j], "typ") == 0) { i++;
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; break;
} }
} }
if (type == NULL) { if (type == NULL)
g_strfreev(tokens);
ret = -1;
goto done; goto done;
}
ntype = -1; ntype = -1;
for (j = 0; j < G_N_ELEMENTS (type_names); j++) { for (i = 0; i < G_N_ELEMENTS (type_names); i++) {
if (g_strcmp0 (type, type_names[j]) == 0) { if (g_strcmp0 (type, type_names[i]) == 0) {
ntype = j; ntype = i;
break; break;
} }
} }
if (ntype == -1) { if (ntype == -1)
g_strfreev(tokens);
ret = -1;
goto done; goto done;
}
if (g_strcmp0 (transport, "UDP") == 0) { if (g_strcmp0 (transport, "UDP") == 0) {
NiceCandidate *cand = NULL; candidate = nice_candidate_new(ntype);
GSList *cands = NULL; candidate->component_id = component_id;
gint added; candidate->stream_id = stream_id;
candidate->transport = NICE_CANDIDATE_TRANSPORT_UDP;
cand = nice_candidate_new(ntype); g_strlcpy(candidate->foundation, foundation, NICE_CANDIDATE_MAX_FOUNDATION);
cand->component_id = component_id; candidate->priority = priority;
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)) { if (!nice_address_set_from_string (&candidate->addr, addr)) {
nice_candidate_free (cand); nice_candidate_free (candidate);
g_strfreev(tokens); candidate = NULL;
ret = -1;
goto done; goto done;
} }
nice_address_set_port (&cand->addr, port); nice_address_set_port (&candidate->addr, port);
if (raddr && rport) { if (raddr && rport) {
if (!nice_address_set_from_string (&cand->base_addr, raddr)) { if (!nice_address_set_from_string (&candidate->base_addr, raddr)) {
nice_candidate_free (cand); nice_candidate_free (candidate);
g_strfreev(tokens); candidate = NULL;
ret = -1;
goto done; goto done;
} }
nice_address_set_port (&cand->base_addr, rport); nice_address_set_port (&candidate->base_addr, rport);
}
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++;
}
g_strfreev(tokens);
} }
} }
done: done:
if (sdp_lines) if (tokens)
g_strfreev(sdp_lines); g_strfreev(tokens);
agent_unlock();
return ret; return candidate;
} }
...@@ -823,11 +823,39 @@ const gchar *nice_agent_get_stream_name ( ...@@ -823,11 +823,39 @@ const gchar *nice_agent_get_stream_name (
NiceAgent *agent, NiceAgent *agent,
guint stream_id); 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: * nice_agent_generate_local_sdp:
* @agent: The #NiceAgent Object * @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> <note>
<para> <para>
...@@ -842,12 +870,15 @@ const gchar *nice_agent_get_stream_name ( ...@@ -842,12 +870,15 @@ const gchar *nice_agent_get_stream_name (
</para> </para>
<para> <para>
The default candidate in the SDP will be selected based on the lowest The default candidate in the SDP will be selected based on the lowest
priority candidate. priority candidate for the first component.
</para> </para>
</note> </note>
* *
* <para>See also: nice_agent_set_stream_name() </para> * <para>See also: nice_agent_set_stream_name() </para>
* <para>See also: nice_agent_parse_remote_sdp() </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() * Returns: A string representing the local SDP. Must be freed with g_free()
* once done. * once done.
...@@ -858,6 +889,69 @@ gchar * ...@@ -858,6 +889,69 @@ gchar *
nice_agent_generate_local_sdp ( nice_agent_generate_local_sdp (
NiceAgent *agent); 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: * nice_agent_parse_remote_sdp:
* @agent: The #NiceAgent Object * @agent: The #NiceAgent Object
...@@ -877,6 +971,8 @@ nice_agent_generate_local_sdp ( ...@@ -877,6 +971,8 @@ nice_agent_generate_local_sdp (
* *
* <para>See also: nice_agent_set_stream_name() </para> * <para>See also: nice_agent_set_stream_name() </para>
* <para>See also: nice_agent_generate_local_sdp() </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 * Returns: The number of candidates added, negative on errors
* *
...@@ -888,6 +984,59 @@ nice_agent_parse_remote_sdp ( ...@@ -888,6 +984,59 @@ nice_agent_parse_remote_sdp (
const gchar *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 G_END_DECLS
#endif /* _AGENT_H */ #endif /* _AGENT_H */
......
...@@ -30,8 +30,13 @@ nice_agent_set_software ...@@ -30,8 +30,13 @@ nice_agent_set_software
nice_agent_restart nice_agent_restart
nice_agent_set_stream_name nice_agent_set_stream_name
nice_agent_get_stream_name nice_agent_get_stream_name
nice_agent_get_default_local_candidate
nice_agent_generate_local_sdp 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_sdp
nice_agent_parse_remote_stream_sdp
nice_agent_parse_remote_candidate_sdp
<SUBSECTION Standard> <SUBSECTION Standard>
NICE_AGENT NICE_AGENT
NICE_IS_AGENT NICE_IS_AGENT
......
...@@ -18,7 +18,10 @@ nice_agent_add_local_address ...@@ -18,7 +18,10 @@ nice_agent_add_local_address
nice_agent_add_stream nice_agent_add_stream
nice_agent_attach_recv nice_agent_attach_recv
nice_agent_gather_candidates nice_agent_gather_candidates
nice_agent_generate_local_candidate_sdp
nice_agent_generate_local_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_candidates
nice_agent_get_local_credentials nice_agent_get_local_credentials
nice_agent_get_remote_candidates nice_agent_get_remote_candidates
...@@ -27,7 +30,9 @@ nice_agent_get_stream_name ...@@ -27,7 +30,9 @@ nice_agent_get_stream_name
nice_agent_get_type nice_agent_get_type
nice_agent_new nice_agent_new
nice_agent_new_reliable nice_agent_new_reliable
nice_agent_parse_remote_candidate_sdp
nice_agent_parse_remote_sdp nice_agent_parse_remote_sdp
nice_agent_parse_remote_stream_sdp
nice_agent_remove_stream nice_agent_remove_stream
nice_agent_restart nice_agent_restart
nice_agent_send 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