Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
libnice
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
libnice
Commits
d70b1973
Commit
d70b1973
authored
Feb 05, 2013
by
Youness Alaoui
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new parsing API, for stream and candidates
parent
4ef4f8f7
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
539 additions
and
184 deletions
+539
-184
agent/agent.c
agent/agent.c
+378
-182
agent/agent.h
agent/agent.h
+151
-2
docs/reference/libnice/libnice-sections.txt
docs/reference/libnice/libnice-sections.txt
+5
-0
nice/libnice.sym
nice/libnice.sym
+5
-0
No files found.
agent/agent.c
View file @
d70b1973
...
@@ -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
;
}
}
agent/agent.h
View file @
d70b1973
...
@@ -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 */
...
...
docs/reference/libnice/libnice-sections.txt
View file @
d70b1973
...
@@ -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
...
...
nice/libnice.sym
View file @
d70b1973
...
@@ -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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment