2 * This file is part of the Nice GLib ICE library.
4 * Unit test for ICE full-mode related features.
6 * (C) 2007 Nokia Corporation. All rights reserved.
7 * Contact: Kai Vehmanen
9 * The contents of this file are subject to the Mozilla Public License Version
10 * 1.1 (the "License"); you may not use this file except in compliance with
11 * the License. You may obtain a copy of the License at
12 * http://www.mozilla.org/MPL/
14 * Software distributed under the License is distributed on an "AS IS" basis,
15 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16 * for the specific language governing rights and limitations under the
19 * The Original Code is the Nice GLib ICE library.
21 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
22 * Corporation. All Rights Reserved.
27 * Alternatively, the contents of this file may be used under the terms of the
28 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
29 * case the provisions of LGPL are applicable instead of those above. If you
30 * wish to allow use of your version of this file only under the terms of the
31 * LGPL and not to allow others to use your version of this file under the
32 * MPL, indicate your decision by deleting the provisions above and replace
33 * them with the notice and other provisions required by the LGPL. If you do
34 * not delete the provisions above, a recipient may use your version of this
35 * file under either the MPL or the LGPL.
48 #define USE_LOOPBACK 1
51 #define USE_RELIABLE 1
54 #define PROXY_IP "127.0.0.1"
55 #define PROXY_PORT 1080
56 #define PROXY_USERNAME NULL
57 #define PROXY_PASSWORD NULL
60 #define PROXY_TYPE NICE_PROXY_TYPE_SOCKS5
62 #define PROXY_TYPE NICE_PROXY_TYPE_NONE
66 #define NICE_COMPATIBILITY NICE_COMPATIBILITY_GOOGLE
70 #define USE_LOOPBACK 0
72 #define TURN_IP "209.85.163.126"
74 #define TURN_USER "ih9ppiM0P6vN34DB"
76 #define TURN_USER2 TURN_USER
77 #define TURN_PASS2 TURN_PASS
78 #define TURN_TYPE NICE_RELAY_TYPE_TURN_TLS
83 #define NICE_COMPATIBILITY NICE_COMPATIBILITY_RFC5245
85 #define USE_TURN_SERVER_ORG 1
87 #define USE_TURN_SERVER_ORG 0
90 #define NUMB_IP "64.251.22.149"
91 #define NUMB_PORT 3478
92 #define NUMB_USER "youness.alaoui@collabora.co.uk"
93 #define NUMB_PASS "badger"
95 #define TSORG_IP "127.0.0.1"
96 #define TSORG_PORT 3478
97 #define TSORG_USER "toto"
98 #define TSORG_PASS "password"
101 #if USE_TURN_SERVER_ORG
102 #define TURN_IP TSORG_IP
103 #define TURN_PORT TSORG_PORT
104 #define TURN_USER TSORG_USER
105 #define TURN_PASS TSORG_PASS
106 #define TURN_USER2 TSORG_USER
107 #define TURN_PASS2 TSORG_PASS
108 #define TURN_TYPE NICE_RELAY_TYPE_TURN_TCP
110 #define TURN_IP NUMB_IP
111 #define TURN_PORT NUMB_PORT
112 #define TURN_USER NUMB_USER
113 #define TURN_PASS NUMB_PASS
114 #define TURN_USER2 NUMB_USER
115 #define TURN_PASS2 NUMB_PASS
116 #define TURN_TYPE NICE_RELAY_TYPE_TURN_UDP
122 static NiceComponentState global_lagent_state
[2] = { NICE_COMPONENT_STATE_LAST
, NICE_COMPONENT_STATE_LAST
};
123 static NiceComponentState global_ragent_state
[2] = { NICE_COMPONENT_STATE_LAST
, NICE_COMPONENT_STATE_LAST
};
124 static guint global_components_ready
= 0;
125 static guint global_components_ready_exit
= 0;
126 static guint global_components_failed
= 0;
127 static guint global_components_failed_exit
= 0;
128 static GMainLoop
*global_mainloop
= NULL
;
129 static gboolean global_lagent_gathering_done
= FALSE
;
130 static gboolean global_ragent_gathering_done
= FALSE
;
131 static gboolean global_lagent_ibr_received
= FALSE
;
132 static gboolean global_ragent_ibr_received
= FALSE
;
133 static int global_lagent_cands
= 0;
134 static int global_ragent_cands
= 0;
135 static gint global_ragent_read
= 0;
136 static guint global_exit_when_ibr_received
= 0;
138 static void priv_print_global_status (void)
140 g_debug ("\tgathering_done=%d", global_lagent_gathering_done
&& global_ragent_gathering_done
);
141 g_debug ("\tlstate[rtp]=%d [rtcp]=%d", global_lagent_state
[0], global_lagent_state
[1]);
142 g_debug ("\trstate[rtp]=%d [rtcp]=%d", global_ragent_state
[0], global_ragent_state
[1]);
143 g_debug ("\tL cands=%d R cands=%d", global_lagent_cands
, global_ragent_cands
);
146 static gboolean
timer_cb (gpointer pointer
)
148 g_debug ("test-fullmode:%s: %p", G_STRFUNC
, pointer
);
150 /* signal status via a global variable */
152 /* note: should not be reached, abort */
153 g_error ("ERROR: test has got stuck, aborting...");
158 static void cb_writable (NiceAgent
*agent
, guint stream_id
, guint component_id
)
160 g_debug ("Transport is now writable, stopping mainloop");
161 g_main_loop_quit (global_mainloop
);
164 static void cb_nice_recv (NiceAgent
*agent
, guint stream_id
, guint component_id
, guint len
, gchar
*buf
, gpointer user_data
)
166 g_debug ("test-fullmode:%s: %p", G_STRFUNC
, user_data
);
168 /* XXX: dear compiler, these are for you: */
169 (void)agent
; (void)stream_id
; (void)component_id
; (void)buf
;
172 * Lets ignore stun packets that got through
176 if (strncmp ("12345678", buf
, 8))
179 if (GPOINTER_TO_UINT (user_data
) == 2) {
180 g_debug ("right agent received %d bytes, stopping mainloop", len
);
181 global_ragent_read
= len
;
182 g_main_loop_quit (global_mainloop
);
186 static void cb_candidate_gathering_done(NiceAgent
*agent
, guint stream_id
, gpointer data
)
188 g_debug ("test-fullmode:%s: %p", G_STRFUNC
, data
);
190 if (GPOINTER_TO_UINT (data
) == 1)
191 global_lagent_gathering_done
= TRUE
;
192 else if (GPOINTER_TO_UINT (data
) == 2)
193 global_ragent_gathering_done
= TRUE
;
195 if (global_lagent_gathering_done
&&
196 global_ragent_gathering_done
)
197 g_main_loop_quit (global_mainloop
);
199 /* XXX: dear compiler, these are for you: */
203 static void cb_component_state_changed (NiceAgent
*agent
, guint stream_id
, guint component_id
, guint state
, gpointer data
)
205 g_debug ("test-fullmode:%s: %p", G_STRFUNC
, data
);
207 if (GPOINTER_TO_UINT (data
) == 1)
208 global_lagent_state
[component_id
- 1] = state
;
209 else if (GPOINTER_TO_UINT (data
) == 2)
210 global_ragent_state
[component_id
- 1] = state
;
212 if (state
== NICE_COMPONENT_STATE_READY
)
213 global_components_ready
++;
214 if (state
== NICE_COMPONENT_STATE_FAILED
)
215 global_components_failed
++;
217 g_debug ("test-fullmode: checks READY/EXIT-AT %u/%u.", global_components_ready
, global_components_ready_exit
);
218 g_debug ("test-fullmode: checks FAILED/EXIT-AT %u/%u.", global_components_failed
, global_components_failed_exit
);
220 /* signal status via a global variable */
221 if (global_components_ready
== global_components_ready_exit
&&
222 global_components_failed
== global_components_failed_exit
) {
223 g_debug ("Components ready/failed achieved. Stopping mailoop");
224 g_main_loop_quit (global_mainloop
);
229 /* signal status via a global variable */
230 if (global_components_failed
== global_components_failed_exit
) {
231 g_main_loop_quit (global_mainloop
);
236 /* XXX: dear compiler, these are for you: */
237 (void)agent
; (void)stream_id
; (void)data
; (void)component_id
;
240 static void cb_new_selected_pair(NiceAgent
*agent
, guint stream_id
, guint component_id
,
241 gchar
*lfoundation
, gchar
* rfoundation
, gpointer data
)
243 g_debug ("test-fullmode:%s: %p", G_STRFUNC
, data
);
245 if (GPOINTER_TO_UINT (data
) == 1)
246 ++global_lagent_cands
;
247 else if (GPOINTER_TO_UINT (data
) == 2)
248 ++global_ragent_cands
;
250 /* XXX: dear compiler, these are for you: */
251 (void)agent
; (void)stream_id
; (void)component_id
; (void)lfoundation
; (void)rfoundation
;
254 static void cb_new_candidate(NiceAgent
*agent
, guint stream_id
, guint component_id
,
255 gchar
*foundation
, gpointer data
)
257 g_debug ("test-fullmode:%s: %p", G_STRFUNC
, data
);
259 /* XXX: dear compiler, these are for you: */
260 (void)agent
; (void)stream_id
; (void)data
; (void)component_id
; (void)foundation
;
263 static void cb_initial_binding_request_received(NiceAgent
*agent
, guint stream_id
, gpointer data
)
265 g_debug ("test-fullmode:%s: %p", G_STRFUNC
, data
);
267 if (GPOINTER_TO_UINT (data
) == 1)
268 global_lagent_ibr_received
= TRUE
;
269 else if (GPOINTER_TO_UINT (data
) == 2)
270 global_ragent_ibr_received
= TRUE
;
272 if (global_exit_when_ibr_received
) {
273 g_debug ("Received initial binding request. Stopping mailoop");
274 g_main_loop_quit (global_mainloop
);
277 /* XXX: dear compiler, these are for you: */
278 (void)agent
; (void)stream_id
; (void)data
;
281 static void set_candidates (NiceAgent
*from
, guint from_stream
,
282 NiceAgent
*to
, guint to_stream
, guint component
, gboolean remove_non_relay
)
284 GSList
*cands
= NULL
, *i
;
286 cands
= nice_agent_get_local_candidates (from
, from_stream
, component
);
287 if (remove_non_relay
) {
289 for (i
= cands
; i
; i
= i
->next
) {
290 NiceCandidate
*cand
= i
->data
;
291 if (cand
->type
!= NICE_CANDIDATE_TYPE_RELAYED
) {
292 cands
= g_slist_remove (cands
, cand
);
293 nice_candidate_free (cand
);
298 nice_agent_set_remote_candidates (to
, to_stream
, component
, cands
);
300 for (i
= cands
; i
; i
= i
->next
)
301 nice_candidate_free ((NiceCandidate
*) i
->data
);
302 g_slist_free (cands
);
305 static void set_credentials (NiceAgent
*lagent
, guint lstream
,
306 NiceAgent
*ragent
, guint rstream
)
308 gchar
*ufrag
= NULL
, *password
= NULL
;
310 nice_agent_get_local_credentials(lagent
, lstream
, &ufrag
, &password
);
311 nice_agent_set_remote_credentials (ragent
, rstream
, ufrag
, password
);
314 nice_agent_get_local_credentials(ragent
, rstream
, &ufrag
, &password
);
315 nice_agent_set_remote_credentials (lagent
, lstream
, ufrag
, password
);
320 static int run_full_test (NiceAgent
*lagent
, NiceAgent
*ragent
, NiceAddress
*baseaddr
, guint ready
, guint failed
)
325 /* XXX: dear compiler, this is for you */
328 /* step: initialize variables modified by the callbacks */
329 global_components_ready
= 0;
330 global_components_ready_exit
= ready
;
331 global_components_failed
= 0;
332 global_components_failed_exit
= failed
;
333 global_lagent_gathering_done
= FALSE
;
334 global_ragent_gathering_done
= FALSE
;
335 global_lagent_ibr_received
=
336 global_ragent_ibr_received
= FALSE
;
337 global_lagent_cands
=
338 global_ragent_cands
= 0;
340 g_object_set (G_OBJECT (lagent
), "controlling-mode", TRUE
, NULL
);
341 g_object_set (G_OBJECT (ragent
), "controlling-mode", FALSE
, NULL
);
343 /* step: add one stream, with RTP+RTCP components, to each agent */
344 ls_id
= nice_agent_add_stream (lagent
, 2);
346 rs_id
= nice_agent_add_stream (ragent
, 2);
347 g_assert (ls_id
> 0);
348 g_assert (rs_id
> 0);
350 nice_agent_set_relay_info(lagent
, ls_id
, 1,
351 TURN_IP
, TURN_PORT
, TURN_USER
, TURN_PASS
, TURN_TYPE
);
352 nice_agent_set_relay_info(lagent
, ls_id
, 2,
353 TURN_IP
, TURN_PORT
, TURN_USER
, TURN_PASS
, TURN_TYPE
);
354 nice_agent_set_relay_info(ragent
, rs_id
, 1,
355 TURN_IP
, TURN_PORT
, TURN_USER2
, TURN_PASS2
, TURN_TYPE
);
356 nice_agent_set_relay_info(ragent
, rs_id
, 2,
357 TURN_IP
, TURN_PORT
, TURN_USER2
, TURN_PASS2
, TURN_TYPE
);
361 /* Gather candidates and test nice_agent_set_port_range */
362 nice_agent_set_port_range (lagent
, ls_id
, 1, 10000, 10000);
363 nice_agent_set_port_range (lagent
, ls_id
, 2, 10001, 10001);
364 nice_agent_set_port_range (ragent
, rs_id
, 1, 12345, 12345);
365 nice_agent_set_port_range (ragent
, rs_id
, 2, 10000, 10001);
366 g_assert (nice_agent_gather_candidates (lagent
, ls_id
) == TRUE
);
367 g_assert (nice_agent_gather_candidates (ragent
, rs_id
) == FALSE
);
368 g_assert (nice_agent_get_local_candidates (ragent
, rs_id
, 1) == NULL
);
369 g_assert (nice_agent_get_local_candidates (ragent
, rs_id
, 2) == NULL
);
370 nice_agent_set_port_range (ragent
, rs_id
, 2, 10000, 10002);
371 g_assert (nice_agent_gather_candidates (ragent
, rs_id
) == TRUE
);
375 GSList
*cands
= NULL
, *i
;
376 NiceCandidate
*cand
= NULL
;
378 cands
= nice_agent_get_local_candidates (lagent
, ls_id
, 1);
379 g_assert (g_slist_length (cands
) == 1);
381 g_assert (cand
->type
== NICE_CANDIDATE_TYPE_HOST
);
382 g_assert (nice_address_get_port (&cand
->addr
) == 10000);
383 for (i
= cands
; i
; i
= i
->next
)
384 nice_candidate_free ((NiceCandidate
*) i
->data
);
385 g_slist_free (cands
);
387 cands
= nice_agent_get_local_candidates (lagent
, ls_id
, 2);
388 g_assert (g_slist_length (cands
) == 1);
390 g_assert (cand
->type
== NICE_CANDIDATE_TYPE_HOST
);
391 g_assert (nice_address_get_port (&cand
->addr
) == 10001);
392 for (i
= cands
; i
; i
= i
->next
)
393 nice_candidate_free ((NiceCandidate
*) i
->data
);
394 g_slist_free (cands
);
396 cands
= nice_agent_get_local_candidates (ragent
, rs_id
, 1);
397 g_assert (g_slist_length (cands
) == 1);
399 g_assert (cand
->type
== NICE_CANDIDATE_TYPE_HOST
);
400 g_assert (nice_address_get_port (&cand
->addr
) == 12345);
401 for (i
= cands
; i
; i
= i
->next
)
402 nice_candidate_free ((NiceCandidate
*) i
->data
);
403 g_slist_free (cands
);
405 cands
= nice_agent_get_local_candidates (ragent
, rs_id
, 2);
406 g_assert (g_slist_length (cands
) == 1);
408 g_assert (cand
->type
== NICE_CANDIDATE_TYPE_HOST
);
409 g_assert (nice_address_get_port (&cand
->addr
) == 10002);
410 for (i
= cands
; i
; i
= i
->next
)
411 nice_candidate_free ((NiceCandidate
*) i
->data
);
412 g_slist_free (cands
);
417 /* step: attach to mainloop (needed to register the fds) */
418 nice_agent_attach_recv (lagent
, ls_id
, NICE_COMPONENT_TYPE_RTP
,
419 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
420 GUINT_TO_POINTER (1));
421 nice_agent_attach_recv (lagent
, ls_id
, NICE_COMPONENT_TYPE_RTCP
,
422 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
423 GUINT_TO_POINTER (1));
424 nice_agent_attach_recv (ragent
, rs_id
, NICE_COMPONENT_TYPE_RTP
,
425 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
426 GUINT_TO_POINTER (2));
427 nice_agent_attach_recv (ragent
, rs_id
, NICE_COMPONENT_TYPE_RTCP
,
428 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
429 GUINT_TO_POINTER (2));
431 /* step: run mainloop until local candidates are ready
432 * (see timer_cb() above) */
433 if (global_lagent_gathering_done
!= TRUE
||
434 global_ragent_gathering_done
!= TRUE
) {
435 g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'...");
436 g_main_loop_run (global_mainloop
);
437 g_assert (global_lagent_gathering_done
== TRUE
);
438 g_assert (global_ragent_gathering_done
== TRUE
);
441 set_credentials (lagent
, ls_id
, ragent
, rs_id
);
443 /* step: pass the remote candidates to agents */
444 set_candidates (ragent
, rs_id
, lagent
, ls_id
, NICE_COMPONENT_TYPE_RTP
, USE_TURN
);
445 set_candidates (ragent
, rs_id
, lagent
, ls_id
, NICE_COMPONENT_TYPE_RTCP
, USE_TURN
);
446 set_candidates (lagent
, ls_id
, ragent
, rs_id
, NICE_COMPONENT_TYPE_RTP
, USE_TURN
);
447 set_candidates (lagent
, ls_id
, ragent
, rs_id
, NICE_COMPONENT_TYPE_RTCP
, USE_TURN
);
449 g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed...");
451 /* step: run the mainloop until connectivity checks succeed
452 * (see timer_cb() above) */
453 g_main_loop_run (global_mainloop
);
455 /* note: verify that STUN binding requests were sent */
456 g_assert (global_lagent_ibr_received
== TRUE
);
457 g_assert (global_ragent_ibr_received
== TRUE
);
459 /* note: test payload send and receive */
460 global_ragent_read
= 0;
461 ret
= nice_agent_send (lagent
, ls_id
, 1, 16, "1234567812345678");
464 gboolean reliable
= FALSE
;
465 g_object_get (G_OBJECT (lagent
), "reliable", &reliable
, NULL
);
466 g_debug ("Sending data returned -1 in %s mode", reliable
?"Reliable":"Non-reliable");
468 gulong signal_handler
;
469 signal_handler
= g_signal_connect (G_OBJECT (lagent
),
470 "reliable-transport-writable", G_CALLBACK (cb_writable
), NULL
);
471 g_debug ("Running mainloop until transport is writable");
472 g_main_loop_run (global_mainloop
);
473 g_signal_handler_disconnect(G_OBJECT (lagent
), signal_handler
);
475 ret
= nice_agent_send (lagent
, ls_id
, 1, 16, "1234567812345678");
478 g_debug ("Sent %d bytes", ret
);
479 g_assert (ret
== 16);
480 g_main_loop_run (global_mainloop
);
481 g_assert (global_ragent_read
== 16);
483 g_debug ("test-fullmode: Ran mainloop, removing streams...");
485 /* step: clean up resources and exit */
487 nice_agent_remove_stream (lagent
, ls_id
);
488 nice_agent_remove_stream (ragent
, rs_id
);
494 * Simulate the case where answer to the offer is delayed and
495 * some STUN connectivity checks reach the offering party
496 * before it gets the remote SDP information.
498 static int run_full_test_delayed_answer (NiceAgent
*lagent
, NiceAgent
*ragent
, NiceAddress
*baseaddr
, guint ready
, guint failed
)
503 /* XXX: dear compiler, this is for you */
506 /* step: initialize variables modified by the callbacks */
507 global_components_ready
= 0;
508 global_components_ready_exit
= ready
;
509 global_components_failed
= 0;
510 global_components_failed_exit
= failed
;
511 global_lagent_gathering_done
= FALSE
;
512 global_ragent_gathering_done
= FALSE
;
513 global_lagent_ibr_received
=
514 global_ragent_ibr_received
= FALSE
;
515 global_exit_when_ibr_received
= 1;
516 global_lagent_cands
=
517 global_ragent_cands
= 0;
519 g_object_set (G_OBJECT (lagent
), "controlling-mode", TRUE
, NULL
);
520 g_object_set (G_OBJECT (ragent
), "controlling-mode", FALSE
, NULL
);
522 /* step: add one stream, with RTP+RTCP components, to each agent */
523 ls_id
= nice_agent_add_stream (lagent
, 2);
525 rs_id
= nice_agent_add_stream (ragent
, 2);
526 g_assert (ls_id
> 0);
527 g_assert (rs_id
> 0);
529 /* We don't try this with TURN because as long as both agents don't
530 have the remote candidates, they won't be able to create the
531 permission on the TURN server, so the connchecks will never go through */
533 nice_agent_gather_candidates (lagent
, ls_id
);
534 nice_agent_gather_candidates (ragent
, rs_id
);
536 /* step: attach to mainloop (needed to register the fds) */
537 nice_agent_attach_recv (lagent
, ls_id
, NICE_COMPONENT_TYPE_RTP
,
538 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
539 GUINT_TO_POINTER (1));
540 nice_agent_attach_recv (lagent
, ls_id
, NICE_COMPONENT_TYPE_RTCP
,
541 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
542 GUINT_TO_POINTER (1));
543 nice_agent_attach_recv (ragent
, rs_id
, NICE_COMPONENT_TYPE_RTP
,
544 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
545 GUINT_TO_POINTER (2));
546 nice_agent_attach_recv (ragent
, rs_id
, NICE_COMPONENT_TYPE_RTCP
,
547 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
548 GUINT_TO_POINTER (2));
550 /* step: run mainloop until local candidates are ready
551 * (see timer_cb() above) */
552 if (global_lagent_gathering_done
!= TRUE
||
553 global_ragent_gathering_done
!= TRUE
) {
554 g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'...");
555 g_main_loop_run (global_mainloop
);
556 g_assert (global_lagent_gathering_done
== TRUE
);
557 g_assert (global_ragent_gathering_done
== TRUE
);
560 set_credentials (lagent
, ls_id
, ragent
, rs_id
);
562 /* step: set remote candidates for agent R (answering party) */
563 /* We have to disable TURN for this test because with the delayed answer,
564 we can't create turn permissions, so we won't receive any connchecks */
565 set_candidates (lagent
, ls_id
, ragent
, rs_id
, NICE_COMPONENT_TYPE_RTP
, FALSE
);
566 set_candidates (lagent
, ls_id
, ragent
, rs_id
, NICE_COMPONENT_TYPE_RTCP
, FALSE
);
568 g_debug ("test-fullmode: Set properties, next running mainloop until first check is received...");
570 /* step: run the mainloop until first connectivity check receveid */
571 g_main_loop_run (global_mainloop
);
572 global_exit_when_ibr_received
= 0;
574 /* note: verify that STUN binding requests were sent */
575 g_assert (global_lagent_ibr_received
== TRUE
);
577 g_debug ("test-fullmode: Delayed answer received, continuing processing..");
579 /* step: pass remove candidates to agent L (offering party) */
580 set_candidates (ragent
, rs_id
, lagent
, ls_id
, NICE_COMPONENT_TYPE_RTP
, FALSE
);
581 set_candidates (ragent
, rs_id
, lagent
, ls_id
, NICE_COMPONENT_TYPE_RTCP
, FALSE
);
583 g_debug ("test-fullmode: Running mainloop until connectivity checks succeeed.");
585 g_main_loop_run (global_mainloop
);
586 g_assert (global_ragent_ibr_received
== TRUE
);
587 g_assert (global_components_failed
== 0);
589 /* note: test payload send and receive */
590 global_ragent_read
= 0;
591 ret
= nice_agent_send (lagent
, ls_id
, 1, 16, "1234567812345678");
593 gboolean reliable
= FALSE
;
594 g_object_get (G_OBJECT (lagent
), "reliable", &reliable
, NULL
);
596 gulong signal_handler
;
597 signal_handler
= g_signal_connect (G_OBJECT (lagent
),
598 "reliable-transport-writable", G_CALLBACK (cb_writable
), NULL
);
599 g_main_loop_run (global_mainloop
);
600 g_signal_handler_disconnect(G_OBJECT (lagent
), signal_handler
);
602 ret
= nice_agent_send (lagent
, ls_id
, 1, 16, "1234567812345678");
605 global_ragent_read
= 0;
606 g_assert (ret
== 16);
607 g_main_loop_run (global_mainloop
);
608 g_assert (global_ragent_read
== 16);
610 g_debug ("test-fullmode: Ran mainloop, removing streams...");
612 /* step: clean up resources and exit */
614 nice_agent_remove_stream (lagent
, ls_id
);
615 nice_agent_remove_stream (ragent
, rs_id
);
620 static int run_full_test_wrong_password (NiceAgent
*lagent
, NiceAgent
*ragent
, NiceAddress
*baseaddr
)
624 /* XXX: dear compiler, this is for you */
627 global_components_ready
= 0;
628 global_components_ready_exit
= 0;
629 global_components_failed
= 0;
630 global_components_failed_exit
= 2;
631 global_lagent_state
[0] = global_lagent_state
[1] =
632 global_ragent_state
[0] = global_ragent_state
[1]
633 = NICE_COMPONENT_STATE_LAST
;
634 global_lagent_gathering_done
=
635 global_ragent_gathering_done
= FALSE
;
636 global_lagent_cands
=
637 global_ragent_cands
= 0;
639 g_object_set (G_OBJECT (lagent
), "controlling-mode", TRUE
, NULL
);
640 g_object_set (G_OBJECT (ragent
), "controlling-mode", FALSE
, NULL
);
642 /* step: add one stream, with one component, to each agent */
643 ls_id
= nice_agent_add_stream (lagent
, 1);
645 rs_id
= nice_agent_add_stream (ragent
, 1);
646 g_assert (ls_id
> 0);
647 g_assert (rs_id
> 0);
650 nice_agent_set_relay_info(lagent
, ls_id
, 1,
651 TURN_IP
, TURN_PORT
, TURN_USER
, TURN_PASS
, TURN_TYPE
);
652 nice_agent_set_relay_info(ragent
, rs_id
, 1,
653 TURN_IP
, TURN_PORT
, TURN_USER
, TURN_PASS
, TURN_TYPE
);
656 nice_agent_gather_candidates (lagent
, ls_id
);
657 nice_agent_gather_candidates (ragent
, rs_id
);
659 /* step: attach to mainloop (needed to register the fds) */
660 nice_agent_attach_recv (lagent
, ls_id
, NICE_COMPONENT_TYPE_RTP
,
661 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
662 GUINT_TO_POINTER (1));
663 nice_agent_attach_recv (ragent
, rs_id
, NICE_COMPONENT_TYPE_RTP
,
664 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
665 GUINT_TO_POINTER (2));
667 /* step: run mainloop until local candidates are ready
668 * (see timer_cb() above) */
669 if (global_lagent_gathering_done
!= TRUE
||
670 global_ragent_gathering_done
!= TRUE
) {
671 g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'...");
672 g_main_loop_run (global_mainloop
);
673 g_assert (global_lagent_gathering_done
== TRUE
);
674 g_assert (global_ragent_gathering_done
== TRUE
);
677 g_debug ("test-fullmode: Got local candidates...");
679 set_credentials (lagent
, ls_id
, ragent
, rs_id
);
680 nice_agent_set_remote_credentials (ragent
, rs_id
, "wrong", "password");
681 nice_agent_set_remote_credentials (lagent
, ls_id
, "wrong2", "password2");
684 /* step: pass the remote candidates to agents */
685 set_candidates (ragent
, rs_id
, lagent
, ls_id
, NICE_COMPONENT_TYPE_RTP
, USE_TURN
);
686 set_candidates (lagent
, ls_id
, ragent
, rs_id
, NICE_COMPONENT_TYPE_RTP
, USE_TURN
);
688 g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed...");
690 /* step: run the mainloop until connectivity checks succeed
691 * (see timer_cb() above) */
692 g_main_loop_run (global_mainloop
);
694 /* note: verify that correct number of local candidates were reported */
695 g_assert (global_lagent_cands
== 0);
696 g_assert (global_ragent_cands
== 0);
698 g_debug ("test-fullmode: Ran mainloop, removing streams...");
700 /* step: clean up resources and exit */
702 nice_agent_remove_stream (lagent
, ls_id
);
703 nice_agent_remove_stream (ragent
, rs_id
);
708 static int run_full_test_control_conflict (NiceAgent
*lagent
, NiceAgent
*ragent
, NiceAddress
*baseaddr
, gboolean role
)
712 /* XXX: dear compiler, this is for you */
715 global_components_ready
= 0;
716 global_components_ready_exit
= 2;
717 global_components_failed
= 0;
718 global_components_failed_exit
= 0;
719 global_lagent_gathering_done
=
720 global_ragent_gathering_done
= FALSE
;
721 global_lagent_cands
=
722 global_ragent_cands
= 0;
723 global_lagent_ibr_received
=
724 global_ragent_ibr_received
= FALSE
;
726 g_object_set (G_OBJECT (lagent
), "controlling-mode", role
, NULL
);
727 g_object_set (G_OBJECT (ragent
), "controlling-mode", role
, NULL
);
729 /* step: add one stream, with one component, to each agent */
730 ls_id
= nice_agent_add_stream (lagent
, 1);
732 rs_id
= nice_agent_add_stream (ragent
, 1);
733 g_assert (ls_id
> 0);
734 g_assert (rs_id
> 0);
737 nice_agent_set_relay_info(lagent
, ls_id
, 1,
738 TURN_IP
, TURN_PORT
, TURN_USER
, TURN_PASS
, TURN_TYPE
);
739 nice_agent_set_relay_info(ragent
, rs_id
, 1,
740 TURN_IP
, TURN_PORT
, TURN_USER
, TURN_PASS
, TURN_TYPE
);
743 nice_agent_gather_candidates (lagent
, ls_id
);
744 nice_agent_gather_candidates (ragent
, rs_id
);
746 /* step: attach to mainloop (needed to register the fds) */
747 nice_agent_attach_recv (lagent
, ls_id
, NICE_COMPONENT_TYPE_RTP
,
748 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
749 GUINT_TO_POINTER (1));
750 nice_agent_attach_recv (ragent
, rs_id
, NICE_COMPONENT_TYPE_RTP
,
751 g_main_loop_get_context (global_mainloop
), cb_nice_recv
,
752 GUINT_TO_POINTER (2));
754 /* step: run mainloop until local candidates are ready
755 * (see timer_cb() above) */
756 if (global_lagent_gathering_done
!= TRUE
||
757 global_ragent_gathering_done
!= TRUE
) {
758 g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'...");
759 g_main_loop_run (global_mainloop
);
760 g_assert (global_lagent_gathering_done
== TRUE
);
761 g_assert (global_ragent_gathering_done
== TRUE
);
764 g_debug ("test-fullmode: Got local candidates...");
766 set_credentials (lagent
, ls_id
, ragent
, rs_id
);
768 /* step: pass the remote candidates to agents */
769 set_candidates (ragent
, rs_id
, lagent
, ls_id
, NICE_COMPONENT_TYPE_RTP
, USE_TURN
);
770 set_candidates (lagent
, ls_id
, ragent
, rs_id
, NICE_COMPONENT_TYPE_RTP
, USE_TURN
);
772 g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed...");
774 /* step: run the mainloop until connectivity checks succeed
775 * (see timer_cb() above) */
776 g_main_loop_run (global_mainloop
);
778 /* When using TURN, we get peer reflexive candidates for the host cands
779 that we removed so we can get another new_selected_pair signal later
780 depending on timing/racing, we could double (or not) the amount we expected
783 /* note: verify that correct number of local candidates were reported */
784 g_assert (global_lagent_cands
== 1);
785 g_assert (global_ragent_cands
== 1);
788 g_debug ("test-fullmode: Ran mainloop, removing streams...");
790 /* step: clean up resources and exit */
792 nice_agent_remove_stream (lagent
, ls_id
);
793 nice_agent_remove_stream (ragent
, rs_id
);
800 NiceAgent
*lagent
, *ragent
; /* agent's L and R */
801 NiceAddress baseaddr
;
804 const char *stun_server
= NULL
, *stun_server_port
= NULL
;
809 WSAStartup(0x0202, &w
);
812 #if !GLIB_CHECK_VERSION(2,31,8)
816 global_mainloop
= g_main_loop_new (NULL
, FALSE
);
818 /* Note: impl limits ...
819 * - no multi-stream support
823 /* step: create the agents L and R */
825 lagent
= nice_agent_new_reliable (g_main_loop_get_context (global_mainloop
),
827 ragent
= nice_agent_new_reliable (g_main_loop_get_context (global_mainloop
),
830 lagent
= nice_agent_new (g_main_loop_get_context (global_mainloop
),
832 ragent
= nice_agent_new (g_main_loop_get_context (global_mainloop
),
836 nice_agent_set_software (lagent
, "Test-fullmode, Left Agent");
837 nice_agent_set_software (ragent
, "Test-fullmode, Right Agent");
839 /* step: add a timer to catch state changes triggered by signals */
841 timer_id
= g_timeout_add (300000, timer_cb
, NULL
);
843 timer_id
= g_timeout_add (30000, timer_cb
, NULL
);
846 /* step: specify which local interface to use */
848 if (!nice_address_set_from_string (&baseaddr
, "127.0.0.1"))
849 g_assert_not_reached ();
850 nice_agent_add_local_address (lagent
, &baseaddr
);
851 nice_agent_add_local_address (ragent
, &baseaddr
);
854 g_signal_connect (G_OBJECT (lagent
), "candidate-gathering-done",
855 G_CALLBACK (cb_candidate_gathering_done
), GUINT_TO_POINTER(1));
856 g_signal_connect (G_OBJECT (ragent
), "candidate-gathering-done",
857 G_CALLBACK (cb_candidate_gathering_done
), GUINT_TO_POINTER (2));
858 g_signal_connect (G_OBJECT (lagent
), "component-state-changed",
859 G_CALLBACK (cb_component_state_changed
), GUINT_TO_POINTER (1));
860 g_signal_connect (G_OBJECT (ragent
), "component-state-changed",
861 G_CALLBACK (cb_component_state_changed
), GUINT_TO_POINTER (2));
862 g_signal_connect (G_OBJECT (lagent
), "new-selected-pair",
863 G_CALLBACK (cb_new_selected_pair
), GUINT_TO_POINTER(1));
864 g_signal_connect (G_OBJECT (ragent
), "new-selected-pair",
865 G_CALLBACK (cb_new_selected_pair
), GUINT_TO_POINTER (2));
866 g_signal_connect (G_OBJECT (lagent
), "new-candidate",
867 G_CALLBACK (cb_new_candidate
), GUINT_TO_POINTER (1));
868 g_signal_connect (G_OBJECT (ragent
), "new-candidate",
869 G_CALLBACK (cb_new_candidate
), GUINT_TO_POINTER (2));
870 g_signal_connect (G_OBJECT (lagent
), "initial-binding-request-received",
871 G_CALLBACK (cb_initial_binding_request_received
),
872 GUINT_TO_POINTER (1));
873 g_signal_connect (G_OBJECT (ragent
), "initial-binding-request-received",
874 G_CALLBACK (cb_initial_binding_request_received
),
875 GUINT_TO_POINTER (2));
877 stun_server
= getenv ("NICE_STUN_SERVER");
878 stun_server_port
= getenv ("NICE_STUN_SERVER_PORT");
880 g_object_set (G_OBJECT (lagent
), "stun-server", stun_server
, NULL
);
881 g_object_set (G_OBJECT (lagent
), "stun-server-port", atoi (stun_server_port
), NULL
);
882 g_object_set (G_OBJECT (ragent
), "stun-server", stun_server
, NULL
);
883 g_object_set (G_OBJECT (ragent
), "stun-server-port", atoi (stun_server_port
), NULL
);
886 g_object_set (G_OBJECT (lagent
), "upnp", USE_UPNP
, NULL
);
887 g_object_set (G_OBJECT (lagent
), "proxy-ip", PROXY_IP
, NULL
);
888 g_object_set (G_OBJECT (lagent
), "proxy-port", PROXY_PORT
, NULL
);
889 g_object_set (G_OBJECT (lagent
), "proxy-type", PROXY_TYPE
, NULL
);
890 g_object_set (G_OBJECT (lagent
), "proxy-username", PROXY_USERNAME
, NULL
);
891 g_object_set (G_OBJECT (lagent
), "proxy-password", PROXY_PASSWORD
, NULL
);
892 g_object_set (G_OBJECT (ragent
), "upnp", USE_UPNP
, NULL
);
893 g_object_set (G_OBJECT (ragent
), "proxy-ip", PROXY_IP
, NULL
);
894 g_object_set (G_OBJECT (ragent
), "proxy-port", PROXY_PORT
, NULL
);
895 g_object_set (G_OBJECT (ragent
), "proxy-type", PROXY_TYPE
, NULL
);
896 g_object_set (G_OBJECT (ragent
), "proxy-username", PROXY_USERNAME
, NULL
);
897 g_object_set (G_OBJECT (ragent
), "proxy-password", PROXY_PASSWORD
, NULL
);
899 /* step: test setter/getter functions for properties */
901 guint max_checks
= 0;
902 gchar
*string
= NULL
;
904 gboolean mode
= FALSE
;
905 g_object_get (G_OBJECT (lagent
), "stun-server", &string
, NULL
);
906 g_assert (stun_server
== NULL
|| strcmp (string
, stun_server
) == 0);
908 g_object_get (G_OBJECT (lagent
), "stun-server-port", &port
, NULL
);
909 g_assert (stun_server_port
== NULL
|| port
== (guint
)atoi (stun_server_port
));
910 g_object_get (G_OBJECT (lagent
), "proxy-ip", &string
, NULL
);
911 g_assert (strcmp (string
, PROXY_IP
) == 0);
913 g_object_get (G_OBJECT (lagent
), "proxy-port", &port
, NULL
);
914 g_assert (port
== PROXY_PORT
);
915 g_object_get (G_OBJECT (lagent
), "controlling-mode", &mode
, NULL
);
916 g_assert (mode
== TRUE
);
917 g_object_set (G_OBJECT (lagent
), "max-connectivity-checks", 300, NULL
);
918 g_object_get (G_OBJECT (lagent
), "max-connectivity-checks", &max_checks
, NULL
);
919 g_assert (max_checks
== 300);
922 /* step: run test the first time */
923 g_debug ("test-fullmode: TEST STARTS / running test for the 1st time");
924 result
= run_full_test (lagent
, ragent
, &baseaddr
, 4 ,0);
925 priv_print_global_status ();
926 g_assert (result
== 0);
927 g_assert (global_lagent_state
[0] == NICE_COMPONENT_STATE_READY
);
928 g_assert (global_lagent_state
[1] == NICE_COMPONENT_STATE_READY
);
929 g_assert (global_ragent_state
[0] == NICE_COMPONENT_STATE_READY
);
930 g_assert (global_ragent_state
[1] == NICE_COMPONENT_STATE_READY
);
931 /* When using TURN, we get peer reflexive candidates for the host cands
932 that we removed so we can get another new_selected_pair signal later
933 depending on timing/racing, we could double (or not) the amount we expected
936 /* note: verify that correct number of local candidates were reported */
937 g_assert (global_lagent_cands
== 2);
938 g_assert (global_ragent_cands
== 2);
942 /* step: run test again without unref'ing agents */
943 g_debug ("test-fullmode: TEST STARTS / running test for the 2nd time");
944 result
= run_full_test (lagent
, ragent
, &baseaddr
, 4, 0);
945 priv_print_global_status ();
946 g_assert (result
== 0);
947 g_assert (global_lagent_state
[0] == NICE_COMPONENT_STATE_READY
);
948 g_assert (global_lagent_state
[1] == NICE_COMPONENT_STATE_READY
);
949 g_assert (global_ragent_state
[0] == NICE_COMPONENT_STATE_READY
);
950 g_assert (global_ragent_state
[1] == NICE_COMPONENT_STATE_READY
);
951 /* When using TURN, we get peer reflexive candidates for the host cands
952 that we removed so we can get another new_selected_pair signal later
953 depending on timing/racing, we could double (or not) the amount we expected
956 /* note: verify that correct number of local candidates were reported */
957 g_assert (global_lagent_cands
== 2);
958 g_assert (global_ragent_cands
== 2);
962 /* step: run test simulating delayed SDP answer */
963 g_debug ("test-fullmode: TEST STARTS / delayed SDP answer");
964 result
= run_full_test_delayed_answer (lagent
, ragent
, &baseaddr
, 4, 0);
965 priv_print_global_status ();
966 g_assert (result
== 0);
967 g_assert (global_lagent_state
[0] == NICE_COMPONENT_STATE_READY
);
968 g_assert (global_lagent_state
[1] == NICE_COMPONENT_STATE_READY
);
969 g_assert (global_ragent_state
[0] == NICE_COMPONENT_STATE_READY
);
970 g_assert (global_ragent_state
[1] == NICE_COMPONENT_STATE_READY
);
971 /* note: verify that correct number of local candidates were reported */
972 /* When using TURN, we get peer reflexive candidates for the host cands
973 that we removed so we can get another new_selected_pair signal later
974 depending on timing/racing, we could double (or not) the amount we expected
977 g_assert (global_lagent_cands
== 2);
978 g_assert (global_ragent_cands
== 2);
985 /* run test with incorrect credentials (make sure process fails) */
986 g_debug ("test-fullmode: TEST STARTS / incorrect credentials");
987 result
= run_full_test_wrong_password (lagent
, ragent
, &baseaddr
);
988 priv_print_global_status ();
989 g_assert (result
== 0);
990 g_assert (global_lagent_state
[0] == NICE_COMPONENT_STATE_FAILED
);
991 g_assert (global_lagent_state
[1] == NICE_COMPONENT_STATE_LAST
);
992 g_assert (global_ragent_state
[0] == NICE_COMPONENT_STATE_FAILED
);
993 g_assert (global_ragent_state
[1] == NICE_COMPONENT_STATE_LAST
);
995 /* The max connectivity checks test can't be run with TURN because
996 we'll have 3 local candidates instead of 1 and the checks will
997 be random, so we can't predict how many will fail/succeed */
1000 /* step: run test with a hard limit for connecitivity checks */
1001 g_debug ("test-fullmode: TEST STARTS / max connectivity checks");
1002 g_object_set (G_OBJECT (lagent
), "max-connectivity-checks", 1, NULL
);
1003 g_object_set (G_OBJECT (ragent
), "max-connectivity-checks", 1, NULL
);
1004 result
= run_full_test (lagent
, ragent
, &baseaddr
, 2, 2);
1005 priv_print_global_status ();
1006 g_assert (result
== 0);
1007 /* should FAIL as agent L can't send any checks: */
1008 g_assert (global_lagent_state
[0] == NICE_COMPONENT_STATE_FAILED
||
1009 global_lagent_state
[1] == NICE_COMPONENT_STATE_FAILED
);
1010 g_assert (global_lagent_state
[0] == NICE_COMPONENT_STATE_FAILED
||
1011 global_lagent_state
[1] == NICE_COMPONENT_STATE_FAILED
);
1014 g_object_set (G_OBJECT (lagent
), "max-connectivity-checks", 100, NULL
);
1015 g_object_set (G_OBJECT (ragent
), "max-connectivity-checks", 100, NULL
);
1016 result
= run_full_test (lagent
, ragent
, &baseaddr
, 4, 0);
1017 priv_print_global_status ();
1018 /* should SUCCEED as agent L can send the checks: */
1019 g_assert (result
== 0);
1020 g_assert (global_lagent_state
[0] == NICE_COMPONENT_STATE_READY
);
1021 g_assert (global_lagent_state
[1] == NICE_COMPONENT_STATE_READY
);
1022 g_assert (global_ragent_state
[0] == NICE_COMPONENT_STATE_READY
);
1023 g_assert (global_ragent_state
[1] == NICE_COMPONENT_STATE_READY
);
1024 g_object_set (G_OBJECT (lagent
), "max-connectivity-checks", 100, NULL
);
1026 /* run test with a conflict in controlling mode: controlling-controlling */
1027 g_debug ("test-fullmode: TEST STARTS / controlling mode conflict case-1");
1028 result
= run_full_test_control_conflict (lagent
, ragent
, &baseaddr
, TRUE
);
1029 priv_print_global_status ();
1030 g_assert (result
== 0);
1032 g_assert (global_lagent_state
[0] == NICE_COMPONENT_STATE_READY
);
1033 g_assert (global_lagent_state
[1] == NICE_COMPONENT_STATE_READY
);
1034 g_assert (global_ragent_state
[0] == NICE_COMPONENT_STATE_READY
);
1035 g_assert (global_ragent_state
[1] == NICE_COMPONENT_STATE_READY
);
1037 /* run test with a conflict in controlling mode: controlled-controlled */
1038 g_debug ("test-fullmode: TEST STARTS / controlling mode conflict case-2");
1039 result
= run_full_test_control_conflict (lagent
, ragent
, &baseaddr
, FALSE
);
1040 priv_print_global_status ();
1041 g_assert (result
== 0);
1042 g_assert (global_lagent_state
[0] == NICE_COMPONENT_STATE_READY
);
1043 g_assert (global_lagent_state
[1] == NICE_COMPONENT_STATE_READY
);
1044 g_assert (global_ragent_state
[0] == NICE_COMPONENT_STATE_READY
);
1045 g_assert (global_ragent_state
[1] == NICE_COMPONENT_STATE_READY
);
1047 g_object_unref (lagent
);
1048 g_object_unref (ragent
);
1050 g_main_loop_unref (global_mainloop
);
1051 global_mainloop
= NULL
;
1053 g_source_remove (timer_id
);