Imported Upstream version 0.1.17
[platform/upstream/libnice.git] / tests / test-fullmode.c
1 /*
2  * This file is part of the Nice GLib ICE library.
3  *
4  * Unit test for ICE full-mode related features.
5  *
6  * (C) 2007 Nokia Corporation. All rights reserved.
7  *  Contact: Kai Vehmanen
8  *
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/
13  *
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
17  * License.
18  *
19  * The Original Code is the Nice GLib ICE library.
20  *
21  * The Initial Developers of the Original Code are Collabora Ltd and Nokia
22  * Corporation. All Rights Reserved.
23  *
24  * Contributors:
25  *   Kai Vehmanen, Nokia
26  *
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.
36  */
37 #ifdef HAVE_CONFIG_H
38 # include <config.h>
39 #endif
40
41 #include "agent.h"
42
43 #include <stdlib.h>
44 #include <string.h>
45
46
47 #define USE_TURN 0
48 #define USE_LOOPBACK 1
49 #define USE_PROXY 0
50 #define USE_UPNP 0
51 #define USE_RELIABLE 0
52 #define TEST_GOOGLE 0
53
54 #define PROXY_IP "127.0.0.1"
55 #define PROXY_PORT 1080
56 #define PROXY_USERNAME NULL
57 #define PROXY_PASSWORD NULL
58
59 #if USE_PROXY
60 #define PROXY_TYPE NICE_PROXY_TYPE_SOCKS5
61 #else
62 #define PROXY_TYPE NICE_PROXY_TYPE_NONE
63 #endif
64
65 #if TEST_GOOGLE
66 #define NICE_COMPATIBILITY NICE_COMPATIBILITY_GOOGLE
67
68 #if USE_TURN
69 #undef USE_LOOPBACK
70 #define USE_LOOPBACK 0
71
72 #define TURN_IP "209.85.163.126"
73 #define TURN_PORT 443
74 #define TURN_USER "ih9ppiM0P6vN34DB"
75 #define TURN_PASS ""
76 #define TURN_USER2 TURN_USER
77 #define TURN_PASS2 TURN_PASS
78 #define TURN_TYPE NICE_RELAY_TYPE_TURN_TLS
79
80 #endif
81
82 #else
83 #define NICE_COMPATIBILITY NICE_COMPATIBILITY_RFC5245
84 #if USE_LOOPBACK
85 #define USE_TURN_SERVER_ORG 1
86 #else
87 #define USE_TURN_SERVER_ORG 0
88 #endif
89
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"
94
95 #define TSORG_IP "127.0.0.1"
96 #define TSORG_PORT 3478
97 #define TSORG_USER "toto"
98 #define TSORG_PASS "password"
99
100
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
109 #else
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
117 #endif
118
119 #endif
120
121
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;
137
138 static void priv_print_global_status (void)
139 {
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);
144 }
145
146 static gboolean timer_cb (gpointer pointer)
147 {
148   g_debug ("test-fullmode:%s: %p", G_STRFUNC, pointer);
149
150   /* signal status via a global variable */
151
152   /* note: should not be reached, abort */
153   g_error ("ERROR: test has got stuck, aborting...");
154
155   return FALSE;
156 }
157
158 static void cb_writable (NiceAgent*agent, guint stream_id, guint component_id,
159     gpointer user_data)
160 {
161   guint *ls_id = user_data;
162
163   if (stream_id == *ls_id && component_id == 1) {
164     g_debug ("Transport is now writable, stopping mainloop");
165     *ls_id = 0;
166   }
167 }
168
169 static void cb_nice_recv (NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data)
170 {
171   g_debug ("test-fullmode:%s: %p", G_STRFUNC, user_data);
172
173   /* XXX: dear compiler, these are for you: */
174   (void)agent; (void)stream_id; (void)component_id; (void)buf;
175
176   /*
177    * Lets ignore stun packets that got through
178    */
179   if (len < 8)
180     return;
181   if (strncmp ("12345678", buf, 8))
182     return;
183
184   if (component_id == 2)
185     return;
186
187   if (GPOINTER_TO_UINT (user_data) == 2) {
188     g_debug ("right agent received %d bytes, stopping mainloop", len);
189     global_ragent_read = len;
190     g_main_loop_quit (global_mainloop);
191   }
192 }
193
194 static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data)
195 {
196   g_debug ("test-fullmode:%s: %p", G_STRFUNC, data);
197
198   if (GPOINTER_TO_UINT (data) == 1)
199     global_lagent_gathering_done = TRUE;
200   else if (GPOINTER_TO_UINT (data) == 2)
201     global_ragent_gathering_done = TRUE;
202
203   if (global_lagent_gathering_done &&
204       global_ragent_gathering_done)
205     g_main_loop_quit (global_mainloop);
206
207   /* XXX: dear compiler, these are for you: */
208   (void)agent;
209 }
210
211 static void cb_component_state_changed (NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data)
212 {
213   gboolean ready_to_connected = FALSE;
214   g_debug ("test-fullmode:%s: %p", G_STRFUNC, data);
215
216   if (GPOINTER_TO_UINT (data) == 1) {
217     if (global_lagent_state[component_id - 1] == NICE_COMPONENT_STATE_READY &&
218         state == NICE_COMPONENT_STATE_CONNECTED)
219       ready_to_connected = TRUE;
220     global_lagent_state[component_id - 1] = state;
221   } else if (GPOINTER_TO_UINT (data) == 2) {
222     if (global_ragent_state[component_id - 1] == NICE_COMPONENT_STATE_READY &&
223         state == NICE_COMPONENT_STATE_CONNECTED)
224       ready_to_connected = TRUE;
225     global_ragent_state[component_id - 1] = state;
226   }
227
228   if (state == NICE_COMPONENT_STATE_READY)
229     global_components_ready++;
230   else if (state == NICE_COMPONENT_STATE_CONNECTED && ready_to_connected)
231     global_components_ready--;
232   if (state == NICE_COMPONENT_STATE_FAILED)
233     global_components_failed++;
234
235   g_debug ("test-fullmode: checks READY/EXIT-AT %u/%u.", global_components_ready, global_components_ready_exit);
236   g_debug ("test-fullmode: checks FAILED/EXIT-AT %u/%u.", global_components_failed, global_components_failed_exit);
237
238   /* signal status via a global variable */
239   if (global_components_ready == global_components_ready_exit &&
240       global_components_failed == global_components_failed_exit) {
241     g_debug ("Components ready/failed achieved. Stopping mailoop");
242     g_main_loop_quit (global_mainloop); 
243     return;
244   }
245
246 #if 0
247   /* signal status via a global variable */
248   if (global_components_failed == global_components_failed_exit) {
249     g_main_loop_quit (global_mainloop); 
250     return;
251   }
252 #endif
253
254   /* XXX: dear compiler, these are for you: */
255   (void)agent; (void)stream_id; (void)data; (void)component_id;
256 }
257
258 static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, 
259                                  gchar *lfoundation, gchar* rfoundation, gpointer data)
260 {
261   g_debug ("test-fullmode:%s: %p", G_STRFUNC, data);
262
263   if (GPOINTER_TO_UINT (data) == 1)
264     ++global_lagent_cands;
265   else if (GPOINTER_TO_UINT (data) == 2)
266     ++global_ragent_cands;
267
268   /* XXX: dear compiler, these are for you: */
269   (void)agent; (void)stream_id; (void)component_id; (void)lfoundation; (void)rfoundation;
270 }
271
272 static void cb_new_candidate(NiceAgent *agent, guint stream_id, guint component_id, 
273                              gchar *foundation, gpointer data)
274 {
275   g_debug ("test-fullmode:%s: %p", G_STRFUNC, data);
276
277   /* XXX: dear compiler, these are for you: */
278   (void)agent; (void)stream_id; (void)data; (void)component_id; (void)foundation;
279 }
280
281 static void cb_initial_binding_request_received(NiceAgent *agent, guint stream_id, gpointer data)
282 {
283   g_debug ("test-fullmode:%s: %p", G_STRFUNC, data);
284
285   if (GPOINTER_TO_UINT (data) == 1)
286     global_lagent_ibr_received = TRUE;
287   else if (GPOINTER_TO_UINT (data) == 2)
288     global_ragent_ibr_received = TRUE;
289
290   if (global_exit_when_ibr_received) {
291     g_debug ("Received initial binding request. Stopping mailoop");
292     g_main_loop_quit (global_mainloop);
293   }
294
295   /* XXX: dear compiler, these are for you: */
296   (void)agent; (void)stream_id; (void)data;
297 }
298
299 static void cb_closed (GObject *src, GAsyncResult *result, gpointer data)
300 {
301   NiceAgent *agent = NICE_AGENT (src);
302
303   g_debug ("test-fullmode:%s: %p", G_STRFUNC, agent);
304
305   *((gboolean *)data) = TRUE;
306 }
307
308 static void set_candidates (NiceAgent *from, guint from_stream,
309     NiceAgent *to, guint to_stream, guint component, gboolean remove_non_relay)
310 {
311   GSList *cands = NULL, *i;
312
313   cands = nice_agent_get_local_candidates (from, from_stream, component);
314   if (remove_non_relay) {
315   restart:
316     for (i = cands; i; i = i->next) {
317       NiceCandidate *cand = i->data;
318       if (cand->type != NICE_CANDIDATE_TYPE_RELAYED) {
319         cands = g_slist_remove (cands, cand);
320         nice_candidate_free (cand);
321         goto restart;
322       }
323     }
324   }
325   nice_agent_set_remote_candidates (to, to_stream, component, cands);
326
327   for (i = cands; i; i = i->next)
328     nice_candidate_free ((NiceCandidate *) i->data);
329   g_slist_free (cands);
330 }
331
332 static void set_credentials (NiceAgent *lagent, guint lstream,
333     NiceAgent *ragent, guint rstream)
334 {
335   gchar *ufrag = NULL, *password = NULL;
336
337   nice_agent_get_local_credentials(lagent, lstream, &ufrag, &password);
338   nice_agent_set_remote_credentials (ragent, rstream, ufrag, password);
339   g_free (ufrag);
340   g_free (password);
341   nice_agent_get_local_credentials(ragent, rstream, &ufrag, &password);
342   nice_agent_set_remote_credentials (lagent, lstream, ufrag, password);
343   g_free (ufrag);
344   g_free (password);
345 }
346
347 static guint16
348 get_port (NiceAgent *agent, guint stream_id, guint component_id)
349 {
350   GSList *cands = nice_agent_get_local_candidates (agent, stream_id,
351       component_id);
352   GSList *item;
353   guint16 port = 0;
354
355   g_assert (cands != NULL);
356
357   for (item = cands; item; item = item->next) {
358     NiceCandidate *cand = item->data;
359     port = nice_address_get_port (&cand->addr);
360     break;
361   }
362   g_assert (port != 0);
363
364   g_slist_free_full (cands, (GDestroyNotify) nice_candidate_free);
365
366   return port;
367 }
368
369 static int run_full_test (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr, guint ready, guint failed)
370 {
371   guint ls_id, rs_id;
372   gint ret;
373   guint16 port;
374
375   /* XXX: dear compiler, this is for you */
376   (void)baseaddr;
377
378   /* step: initialize variables modified by the callbacks */
379   global_components_ready = 0;
380   global_components_ready_exit = ready;
381   global_components_failed = 0;
382   global_components_failed_exit = failed;
383   global_lagent_gathering_done = FALSE;
384   global_ragent_gathering_done = FALSE;
385   global_lagent_ibr_received =
386     global_ragent_ibr_received = FALSE;
387   global_lagent_cands =
388     global_ragent_cands = 0;
389
390   g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL);
391   g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL);
392
393   /* step: add one stream, with RTP+RTCP components, to each agent */
394   ls_id = nice_agent_add_stream (lagent, 2);
395
396   rs_id = nice_agent_add_stream (ragent, 2);
397   g_assert_cmpuint (ls_id, >, 0);
398   g_assert_cmpuint (rs_id, >, 0);
399 #if USE_TURN
400   nice_agent_set_relay_info(lagent, ls_id, 1,
401       TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE);
402   nice_agent_set_relay_info(lagent, ls_id, 2,
403       TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE);
404   nice_agent_set_relay_info(ragent, rs_id, 1,
405       TURN_IP, TURN_PORT, TURN_USER2, TURN_PASS2, TURN_TYPE);
406   nice_agent_set_relay_info(ragent, rs_id, 2,
407       TURN_IP, TURN_PORT, TURN_USER2, TURN_PASS2, TURN_TYPE);
408 #endif
409
410
411   /* Gather candidates and test nice_agent_set_port_range */
412   for (port = 10000; port < 60000; port++) {
413     nice_agent_set_port_range (lagent, ls_id, 1, port, port);
414     if (nice_agent_gather_candidates (lagent, ls_id))
415       break;
416   }
417
418   g_assert_cmpuint (port, ==, get_port (lagent, ls_id, 1));
419
420   nice_agent_set_port_range (ragent, rs_id, 2, port, port);
421
422   g_assert (nice_agent_gather_candidates (ragent, rs_id) == FALSE);
423   g_assert (nice_agent_get_local_candidates (ragent, rs_id, 1) == NULL);
424   g_assert (nice_agent_get_local_candidates (ragent, rs_id, 2) == NULL);
425   nice_agent_set_port_range (ragent, rs_id, 2, 0, 0);
426   g_assert (nice_agent_gather_candidates (lagent, ls_id) == TRUE);
427   g_assert (nice_agent_gather_candidates (ragent, rs_id) == TRUE);
428
429 #if USE_LOOPBACK
430   {
431     GSList *cands = NULL, *i;
432     NiceCandidate *cand = NULL;
433
434     cands = nice_agent_get_local_candidates (lagent, ls_id, 1);
435     g_assert_cmpuint (g_slist_length (cands), ==, 1);
436     cand = cands->data;
437     g_assert_cmpint (cand->type, ==, NICE_CANDIDATE_TYPE_HOST);
438     for (i = cands; i; i = i->next)
439       nice_candidate_free ((NiceCandidate *) i->data);
440     g_slist_free (cands);
441
442     cands = nice_agent_get_local_candidates (lagent, ls_id, 2);
443     g_assert_cmpuint (g_slist_length (cands), ==, 1);
444     cand = cands->data;
445     g_assert_cmpint (cand->type, ==, NICE_CANDIDATE_TYPE_HOST);
446     for (i = cands; i; i = i->next)
447       nice_candidate_free ((NiceCandidate *) i->data);
448     g_slist_free (cands);
449
450     cands = nice_agent_get_local_candidates (ragent, rs_id, 1);
451     g_assert_cmpuint (g_slist_length (cands), ==, 1);
452     cand = cands->data;
453     g_assert_cmpint (cand->type, ==, NICE_CANDIDATE_TYPE_HOST);
454     for (i = cands; i; i = i->next)
455       nice_candidate_free ((NiceCandidate *) i->data);
456     g_slist_free (cands);
457
458     cands = nice_agent_get_local_candidates (ragent, rs_id, 2);
459     g_assert_cmpuint (g_slist_length (cands), ==, 1);
460     cand = cands->data;
461     g_assert_cmpint (cand->type, ==, NICE_CANDIDATE_TYPE_HOST);
462     for (i = cands; i; i = i->next)
463       nice_candidate_free ((NiceCandidate *) i->data);
464     g_slist_free (cands);
465
466   }
467 #endif
468
469   /* step: attach to mainloop (needed to register the fds) */
470   nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
471       g_main_loop_get_context (global_mainloop), cb_nice_recv,
472       GUINT_TO_POINTER (1));
473   nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP,
474       g_main_loop_get_context (global_mainloop), cb_nice_recv,
475       GUINT_TO_POINTER (1));
476   nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
477       g_main_loop_get_context (global_mainloop), cb_nice_recv,
478       GUINT_TO_POINTER (2));
479   nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP,
480       g_main_loop_get_context (global_mainloop), cb_nice_recv,
481       GUINT_TO_POINTER (2));
482
483   /* step: run mainloop until local candidates are ready
484    *       (see timer_cb() above) */
485   if (global_lagent_gathering_done != TRUE ||
486       global_ragent_gathering_done != TRUE) {
487     g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'...");
488     g_main_loop_run (global_mainloop);
489     g_assert (global_lagent_gathering_done == TRUE);
490     g_assert (global_ragent_gathering_done == TRUE);
491   }
492
493   set_credentials (lagent, ls_id, ragent, rs_id);
494
495   /* step: pass the remote candidates to agents  */
496   set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP, USE_TURN);
497   set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, USE_TURN);
498   set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP, USE_TURN);
499   set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, USE_TURN);
500
501   g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed...");
502
503   /* step: run the mainloop until connectivity checks succeed
504    *       (see timer_cb() above) */
505   g_main_loop_run (global_mainloop);
506
507   /* note: verify that STUN binding requests were sent */
508   g_assert (global_lagent_ibr_received == TRUE);
509   g_assert (global_ragent_ibr_received == TRUE);
510
511   /* note: test payload send and receive */
512   global_ragent_read = 0;
513   ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678");
514   if (ret == -1)
515   {
516     gboolean reliable = FALSE;
517     g_object_get (G_OBJECT (lagent), "reliable", &reliable, NULL);
518     g_debug ("Sending data returned -1 in %s mode", reliable?"Reliable":"Non-reliable");
519     if (reliable) {
520       gulong signal_handler;
521       guint ls_id_copy = ls_id;
522
523       signal_handler = g_signal_connect (G_OBJECT (lagent),
524           "reliable-transport-writable", G_CALLBACK (cb_writable), &ls_id_copy);
525       g_debug ("Running mainloop until transport is writable");
526       while (ls_id_copy == ls_id)
527         g_main_context_iteration (NULL, TRUE);
528       g_signal_handler_disconnect(G_OBJECT (lagent), signal_handler);
529
530       ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678");
531     }
532   }
533   g_debug ("Sent %d bytes", ret);
534   g_assert_cmpint (ret, ==, 16);
535   while (global_ragent_read != 16)
536     g_main_context_iteration (NULL, TRUE);
537   g_assert_cmpint (global_ragent_read, ==, 16);
538
539   g_debug ("test-fullmode: Ran mainloop, removing streams...");
540
541   /* step: clean up resources and exit */
542
543   nice_agent_remove_stream (lagent, ls_id);
544   nice_agent_remove_stream (ragent, rs_id);
545
546   return 0;
547 }
548
549 /*
550  * Simulate the case where answer to the offer is delayed and
551  * some STUN connectivity checks reach the offering party
552  * before it gets the remote SDP information.
553  */
554 static int run_full_test_delayed_answer (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr, guint ready, guint failed)
555 {
556   guint ls_id, rs_id;
557   gint ret;
558
559   /* XXX: dear compiler, this is for you */
560   (void)baseaddr;
561
562   /* step: initialize variables modified by the callbacks */
563   global_components_ready = 0;
564   global_components_ready_exit = ready;
565   global_components_failed = 0;
566   global_components_failed_exit = failed;
567   global_lagent_gathering_done = FALSE;
568   global_ragent_gathering_done = FALSE;
569   global_lagent_ibr_received =
570     global_ragent_ibr_received = FALSE;
571   global_exit_when_ibr_received = 1;
572   global_lagent_cands =
573     global_ragent_cands = 0;
574
575   g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL);
576   g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL);
577
578   /* step: add one stream, with RTP+RTCP components, to each agent */
579   ls_id = nice_agent_add_stream (lagent, 2);
580
581   rs_id = nice_agent_add_stream (ragent, 2);
582   g_assert_cmpuint (ls_id, >, 0);
583   g_assert_cmpuint (rs_id, >, 0);
584
585   /* We don't try this with TURN because as long as both agents don't
586      have the remote candidates, they won't be able to create the
587      permission on the TURN server, so the connchecks will never go through */
588
589   nice_agent_gather_candidates (lagent, ls_id);
590   nice_agent_gather_candidates (ragent, rs_id);
591
592   /* step: attach to mainloop (needed to register the fds) */
593   nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
594       g_main_loop_get_context (global_mainloop), cb_nice_recv,
595       GUINT_TO_POINTER (1));
596   nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP,
597       g_main_loop_get_context (global_mainloop), cb_nice_recv,
598       GUINT_TO_POINTER (1));
599   nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
600       g_main_loop_get_context (global_mainloop), cb_nice_recv,
601       GUINT_TO_POINTER (2));
602   nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP,
603       g_main_loop_get_context (global_mainloop), cb_nice_recv,
604       GUINT_TO_POINTER (2));
605
606   /* step: run mainloop until local candidates are ready
607    *       (see timer_cb() above) */
608   if (global_lagent_gathering_done != TRUE ||
609       global_ragent_gathering_done != TRUE) {
610     g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'...");
611     g_main_loop_run (global_mainloop);
612     g_assert (global_lagent_gathering_done == TRUE);
613     g_assert (global_ragent_gathering_done == TRUE);
614   }
615
616   set_credentials (lagent, ls_id, ragent, rs_id);
617
618   /* step: set remote candidates for agent R (answering party) */
619   /* We have to disable TURN for this test because with the delayed answer,
620      we can't create turn permissions, so we won't receive any connchecks */
621   set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP, FALSE);
622   set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, FALSE);
623
624   g_debug ("test-fullmode: Set properties, next running mainloop until first check is received...");
625
626   /* step: run the mainloop until first connectivity check receveid */
627   g_main_loop_run (global_mainloop);
628   global_exit_when_ibr_received = 0;
629
630   /* note: verify that STUN binding requests were sent */
631   g_assert (global_lagent_ibr_received == TRUE);
632
633   g_debug ("test-fullmode: Delayed answer received, continuing processing..");
634
635   /* step: pass remove candidates to agent L (offering party) */
636   set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP, FALSE);
637   set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, FALSE);
638
639   g_debug ("test-fullmode: Running mainloop until connectivity checks succeeed.");
640
641   g_main_loop_run (global_mainloop);
642   g_assert (global_ragent_ibr_received == TRUE);
643   g_assert_cmpuint (global_components_failed, ==, 0);
644
645   /* note: test payload send and receive */
646   global_ragent_read = 0;
647   ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678");
648   if (ret == -1) {
649     gboolean reliable = FALSE;
650     g_object_get (G_OBJECT (lagent), "reliable", &reliable, NULL);
651     if (reliable) {
652       gulong signal_handler;
653       guint ls_id_copy = ls_id;
654
655       signal_handler = g_signal_connect (G_OBJECT (lagent),
656           "reliable-transport-writable", G_CALLBACK (cb_writable), &ls_id_copy);
657       g_debug ("Running mainloop until transport is writable");
658       while (ls_id_copy == ls_id)
659         g_main_context_iteration (NULL, TRUE);
660       g_signal_handler_disconnect(G_OBJECT (lagent), signal_handler);
661
662       ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678");
663     }
664   }
665   global_ragent_read = 0;
666   g_assert_cmpint (ret, ==, 16);
667   g_main_loop_run (global_mainloop);
668   g_assert_cmpint (global_ragent_read, ==, 16);
669
670   g_debug ("test-fullmode: Ran mainloop, removing streams...");
671
672   /* step: clean up resources and exit */
673
674   nice_agent_remove_stream (lagent, ls_id);
675   nice_agent_remove_stream (ragent, rs_id);
676
677   return 0;
678 }
679
680 static int run_full_test_wrong_password (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr)
681 {
682   guint ls_id, rs_id;
683
684   /* XXX: dear compiler, this is for you */
685   (void)baseaddr;
686
687   global_components_ready = 0;
688   global_components_ready_exit = 0;
689   global_components_failed = 0;
690   global_components_failed_exit = 2;
691   global_lagent_state[0] =   global_lagent_state[1] = 
692     global_ragent_state[0] = global_ragent_state[1] 
693     = NICE_COMPONENT_STATE_LAST;
694   global_lagent_gathering_done = 
695     global_ragent_gathering_done = FALSE;
696   global_lagent_cands = 
697     global_ragent_cands = 0;
698
699   g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL);
700   g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL);
701
702   /* step: add one stream, with one component, to each agent */
703   ls_id = nice_agent_add_stream (lagent, 1);
704
705   rs_id = nice_agent_add_stream (ragent, 1);
706   g_assert_cmpuint (ls_id, >, 0);
707   g_assert_cmpuint (rs_id, >, 0);
708
709 #if USE_TURN
710   nice_agent_set_relay_info(lagent, ls_id, 1,
711       TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE);
712   nice_agent_set_relay_info(ragent, rs_id, 1,
713       TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE);
714 #endif
715
716   nice_agent_gather_candidates (lagent, ls_id);
717   nice_agent_gather_candidates (ragent, rs_id);
718
719   /* step: attach to mainloop (needed to register the fds) */
720   nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
721       g_main_loop_get_context (global_mainloop), cb_nice_recv,
722       GUINT_TO_POINTER (1));
723   nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
724       g_main_loop_get_context (global_mainloop), cb_nice_recv,
725       GUINT_TO_POINTER (2));
726
727   /* step: run mainloop until local candidates are ready
728    *       (see timer_cb() above) */
729   if (global_lagent_gathering_done != TRUE ||
730       global_ragent_gathering_done != TRUE) {
731     g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'...");
732     g_main_loop_run (global_mainloop);
733     g_assert (global_lagent_gathering_done == TRUE);
734     g_assert (global_ragent_gathering_done == TRUE);
735   }
736
737   g_debug ("test-fullmode: Got local candidates...");
738
739   set_credentials (lagent, ls_id, ragent, rs_id);
740   nice_agent_set_remote_credentials (ragent, rs_id, "wrong", "password");
741   nice_agent_set_remote_credentials (lagent, ls_id, "wrong2", "password2");
742
743
744   /* step: pass the remote candidates to agents  */
745   set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP, USE_TURN);
746   set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP, USE_TURN);
747
748   g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed...");
749
750   /* step: run the mainloop until connectivity checks succeed
751    *       (see timer_cb() above) */
752   g_main_loop_run (global_mainloop);
753
754   /* note: verify that correct number of local candidates were reported */
755   g_assert_cmpint (global_lagent_cands, ==, 0);
756   g_assert_cmpint (global_ragent_cands, ==, 0);
757
758   g_debug ("test-fullmode: Ran mainloop, removing streams...");
759
760   /* step: clean up resources and exit */
761
762   nice_agent_remove_stream (lagent, ls_id);
763   nice_agent_remove_stream (ragent, rs_id);
764
765   return 0;
766 }
767
768 static int run_full_test_control_conflict (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr, gboolean role)
769 {
770   guint ls_id, rs_id;
771
772   /* XXX: dear compiler, this is for you */
773   (void)baseaddr;
774
775   global_components_ready = 0;
776   global_components_ready_exit = 2;
777   global_components_failed = 0;
778   global_components_failed_exit = 0;
779   global_lagent_gathering_done =
780     global_ragent_gathering_done = FALSE;
781   global_lagent_cands = 
782     global_ragent_cands = 0;
783   global_lagent_ibr_received =
784     global_ragent_ibr_received = FALSE;
785
786   g_object_set (G_OBJECT (lagent), "controlling-mode", role, NULL);
787   g_object_set (G_OBJECT (ragent), "controlling-mode", role, NULL);
788
789   /* step: add one stream, with one component, to each agent */
790   ls_id = nice_agent_add_stream (lagent, 1);
791
792   rs_id = nice_agent_add_stream (ragent, 1);
793   g_assert_cmpuint (ls_id, >, 0);
794   g_assert_cmpuint (rs_id, >, 0);
795
796 #if USE_TURN
797   nice_agent_set_relay_info(lagent, ls_id, 1,
798       TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE);
799   nice_agent_set_relay_info(ragent, rs_id, 1,
800       TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE);
801 #endif
802
803   nice_agent_gather_candidates (lagent, ls_id);
804   nice_agent_gather_candidates (ragent, rs_id);
805
806   /* step: attach to mainloop (needed to register the fds) */
807   nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP,
808       g_main_loop_get_context (global_mainloop), cb_nice_recv,
809       GUINT_TO_POINTER (1));
810   nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP,
811       g_main_loop_get_context (global_mainloop), cb_nice_recv,
812       GUINT_TO_POINTER (2));
813
814   /* step: run mainloop until local candidates are ready 
815    *       (see timer_cb() above) */
816   if (global_lagent_gathering_done != TRUE ||
817       global_ragent_gathering_done != TRUE) {
818     g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'...");
819     g_main_loop_run (global_mainloop);
820     g_assert (global_lagent_gathering_done == TRUE);
821     g_assert (global_ragent_gathering_done == TRUE);
822   }
823
824   g_debug ("test-fullmode: Got local candidates...");
825
826   set_credentials (lagent, ls_id, ragent, rs_id);
827
828   /* step: pass the remote candidates to agents  */
829   set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP, USE_TURN);
830   set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP, USE_TURN);
831
832   g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed...");
833
834   /* step: run the mainloop until connectivity checks succeed
835    *       (see timer_cb() above) */
836   g_main_loop_run (global_mainloop);
837
838   /* When using TURN, we get peer reflexive candidates for the host cands
839      that we removed so we can get another new_selected_pair signal later
840      depending on timing/racing, we could double (or not) the amount we expected
841   */
842 #if !(USE_TURN)
843   /* note: verify that correct number of local candidates were reported */
844   g_assert_cmpint (global_lagent_cands, ==, 1);
845   g_assert_cmpint (global_ragent_cands, ==, 1);
846 #endif
847
848   g_debug ("test-fullmode: Ran mainloop, removing streams...");
849
850   /* step: clean up resources and exit */
851
852   nice_agent_remove_stream (lagent, ls_id);
853   nice_agent_remove_stream (ragent, rs_id);
854
855   return 0;
856 }
857
858 int main (void)
859 {
860   NiceAgent *lagent, *ragent;      /* agent's L and R */
861   NiceAddress baseaddr;
862   int result;
863   guint timer_id;
864   const char *stun_server = NULL, *stun_server_port = NULL;
865   gboolean lagent_closed = FALSE;
866   gboolean ragent_closed = FALSE;
867
868 #ifdef G_OS_WIN32
869   WSADATA w;
870
871   WSAStartup(0x0202, &w);
872 #endif
873
874   global_mainloop = g_main_loop_new (NULL, FALSE);
875
876   /* Note: impl limits ...
877    * - no multi-stream support
878    * - no IPv6 support
879    */
880
881   /* step: create the agents L and R */
882 #if USE_RELIABLE
883   lagent = nice_agent_new_reliable (g_main_loop_get_context (global_mainloop),
884       NICE_COMPATIBILITY);
885   ragent = nice_agent_new_reliable (g_main_loop_get_context (global_mainloop),
886       NICE_COMPATIBILITY);
887 #else
888   lagent = nice_agent_new (g_main_loop_get_context (global_mainloop),
889       NICE_COMPATIBILITY);
890   ragent = nice_agent_new (g_main_loop_get_context (global_mainloop),
891       NICE_COMPATIBILITY);
892 #endif
893
894   g_object_set (G_OBJECT (lagent), "ice-tcp", FALSE,  NULL);
895   g_object_set (G_OBJECT (ragent), "ice-tcp", FALSE,  NULL);
896
897
898   nice_agent_set_software (lagent, "Test-fullmode, Left Agent");
899   nice_agent_set_software (ragent, "Test-fullmode, Right Agent");
900
901   /* step: add a timer to catch state changes triggered by signals */
902 #if USE_TURN
903   timer_id = g_timeout_add (300000, timer_cb, NULL);
904 #else
905   timer_id = g_timeout_add (30000, timer_cb, NULL);
906 #endif
907
908   /* step: specify which local interface to use */
909 #if USE_LOOPBACK
910   if (!nice_address_set_from_string (&baseaddr, "127.0.0.1"))
911     g_assert_not_reached ();
912   nice_agent_add_local_address (lagent, &baseaddr);
913   nice_agent_add_local_address (ragent, &baseaddr);
914 #endif
915
916   g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done",
917       G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER(1));
918   g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done",
919       G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER (2));
920   g_signal_connect (G_OBJECT (lagent), "component-state-changed",
921       G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (1));
922   g_signal_connect (G_OBJECT (ragent), "component-state-changed",
923       G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (2));
924   g_signal_connect (G_OBJECT (lagent), "new-selected-pair",
925       G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER(1));
926   g_signal_connect (G_OBJECT (ragent), "new-selected-pair",
927       G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER (2));
928   g_signal_connect (G_OBJECT (lagent), "new-candidate",
929       G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (1));
930   g_signal_connect (G_OBJECT (ragent), "new-candidate",
931       G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (2));
932   g_signal_connect (G_OBJECT (lagent), "initial-binding-request-received",
933       G_CALLBACK (cb_initial_binding_request_received),
934       GUINT_TO_POINTER (1));
935   g_signal_connect (G_OBJECT (ragent), "initial-binding-request-received",
936       G_CALLBACK (cb_initial_binding_request_received),
937       GUINT_TO_POINTER (2));
938
939   stun_server = getenv ("NICE_STUN_SERVER");
940   stun_server_port = getenv ("NICE_STUN_SERVER_PORT");
941   if (stun_server) {
942     g_object_set (G_OBJECT (lagent), "stun-server", stun_server,  NULL);
943     g_object_set (G_OBJECT (lagent), "stun-server-port", atoi (stun_server_port),  NULL);
944     g_object_set (G_OBJECT (ragent), "stun-server", stun_server,  NULL);
945     g_object_set (G_OBJECT (ragent), "stun-server-port", atoi (stun_server_port),  NULL);
946   }
947
948   g_object_set (G_OBJECT (lagent), "upnp", USE_UPNP,  NULL);
949   g_object_set (G_OBJECT (lagent), "proxy-ip", PROXY_IP,  NULL);
950   g_object_set (G_OBJECT (lagent), "proxy-port", PROXY_PORT, NULL);
951   g_object_set (G_OBJECT (lagent), "proxy-type", PROXY_TYPE, NULL);
952   g_object_set (G_OBJECT (lagent), "proxy-username", PROXY_USERNAME, NULL);
953   g_object_set (G_OBJECT (lagent), "proxy-password", PROXY_PASSWORD, NULL);
954   g_object_set (G_OBJECT (ragent), "upnp", USE_UPNP,  NULL);
955   g_object_set (G_OBJECT (ragent), "proxy-ip", PROXY_IP,  NULL);
956   g_object_set (G_OBJECT (ragent), "proxy-port", PROXY_PORT, NULL);
957   g_object_set (G_OBJECT (ragent), "proxy-type", PROXY_TYPE, NULL);
958   g_object_set (G_OBJECT (ragent), "proxy-username", PROXY_USERNAME, NULL);
959   g_object_set (G_OBJECT (ragent), "proxy-password", PROXY_PASSWORD, NULL);
960
961   /* step: test setter/getter functions for properties */
962   {
963     guint max_checks = 0;
964     gchar *string = NULL;
965     guint port = 0;
966     gboolean mode = FALSE;
967     g_object_get (G_OBJECT (lagent), "stun-server", &string, NULL);
968     g_assert (stun_server == NULL || strcmp (string, stun_server) == 0);
969     g_free (string);
970     g_object_get (G_OBJECT (lagent), "stun-server-port", &port, NULL);
971     g_assert (stun_server_port == NULL || port == (guint)atoi (stun_server_port));
972     g_object_get (G_OBJECT (lagent), "proxy-ip", &string, NULL);
973     g_assert_cmpstr (string, ==, PROXY_IP);
974     g_free (string);
975     g_object_get (G_OBJECT (lagent), "proxy-port", &port, NULL);
976     g_assert_cmpuint (port, ==, PROXY_PORT);
977     g_object_get (G_OBJECT (lagent), "controlling-mode", &mode, NULL);
978     g_assert (mode == TRUE);
979     g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 300, NULL);
980     g_object_get (G_OBJECT (lagent), "max-connectivity-checks", &max_checks, NULL);
981     g_assert_cmpuint (max_checks, ==, 300);
982   }
983
984   /* step: run test the first time */
985   g_debug ("test-fullmode: TEST STARTS / running test for the 1st time");
986   result = run_full_test (lagent, ragent, &baseaddr, 4 ,0);
987   priv_print_global_status ();
988   g_assert_cmpint (result, ==, 0);
989   g_assert_cmpint (global_lagent_state[0], ==, NICE_COMPONENT_STATE_READY);
990   g_assert_cmpint (global_lagent_state[1], ==, NICE_COMPONENT_STATE_READY);
991   g_assert_cmpint (global_ragent_state[0], ==, NICE_COMPONENT_STATE_READY);
992   g_assert_cmpint (global_ragent_state[1], ==, NICE_COMPONENT_STATE_READY);
993   /* When using TURN, we get peer reflexive candidates for the host cands
994      that we removed so we can get another new_selected_pair signal later
995      depending on timing/racing, we could double (or not) the amount we expected
996   */
997 #if !(USE_TURN)
998   /* note: verify that correct number of local candidates were reported */
999     g_assert_cmpint (global_lagent_cands, ==, 2);
1000     g_assert_cmpint (global_ragent_cands, ==, 2);
1001 #endif
1002
1003
1004   /* step: run test again without unref'ing agents */
1005   g_debug ("test-fullmode: TEST STARTS / running test for the 2nd time");
1006   result = run_full_test (lagent, ragent, &baseaddr, 4, 0);
1007   priv_print_global_status ();
1008   g_assert_cmpint (result, ==, 0);
1009   g_assert_cmpint (global_lagent_state[0], ==, NICE_COMPONENT_STATE_READY);
1010   g_assert_cmpint (global_lagent_state[1], ==, NICE_COMPONENT_STATE_READY);
1011   g_assert_cmpint (global_ragent_state[0], ==, NICE_COMPONENT_STATE_READY);
1012   g_assert_cmpint (global_ragent_state[1], ==, NICE_COMPONENT_STATE_READY);
1013   /* When using TURN, we get peer reflexive candidates for the host cands
1014      that we removed so we can get another new_selected_pair signal later
1015      depending on timing/racing, we could double (or not) the amount we expected
1016   */
1017 #if !(USE_TURN)
1018   /* note: verify that correct number of local candidates were reported */
1019   g_assert_cmpint (global_lagent_cands, ==, 2);
1020   g_assert_cmpint (global_ragent_cands, ==, 2);
1021 #endif
1022
1023
1024   /* step: run test simulating delayed SDP answer */
1025   g_debug ("test-fullmode: TEST STARTS / delayed SDP answer");
1026   result = run_full_test_delayed_answer (lagent, ragent, &baseaddr, 4, 0);
1027   priv_print_global_status ();
1028   g_assert_cmpint (result, ==, 0);
1029   g_assert_cmpint (global_lagent_state[0], ==, NICE_COMPONENT_STATE_READY);
1030   g_assert_cmpint (global_lagent_state[1], ==, NICE_COMPONENT_STATE_READY);
1031   g_assert_cmpint (global_ragent_state[0], ==, NICE_COMPONENT_STATE_READY);
1032   g_assert_cmpint (global_ragent_state[1], ==, NICE_COMPONENT_STATE_READY);
1033   /* note: verify that correct number of local candidates were reported */
1034   /* When using TURN, we get peer reflexive candidates for the host cands
1035      that we removed so we can get another new_selected_pair signal later
1036      depending on timing/racing, we could double (or not) the amount we expected
1037   */
1038 #if !(USE_TURN)
1039   g_assert_cmpint (global_lagent_cands, ==, 2);
1040   g_assert_cmpint (global_ragent_cands, ==, 2);
1041 #endif
1042
1043 #if TEST_GOOGLE
1044   return result;
1045 #endif
1046
1047   /* run test with incorrect credentials (make sure process fails) */
1048   g_debug ("test-fullmode: TEST STARTS / incorrect credentials");
1049   result = run_full_test_wrong_password (lagent, ragent, &baseaddr);
1050   priv_print_global_status ();
1051   g_assert_cmpint (result, ==, 0);
1052   g_assert_cmpint (global_lagent_state[0], ==, NICE_COMPONENT_STATE_FAILED);
1053   g_assert_cmpint (global_lagent_state[1], ==, NICE_COMPONENT_STATE_LAST);
1054   g_assert_cmpint (global_ragent_state[0], ==, NICE_COMPONENT_STATE_FAILED);
1055   g_assert_cmpint (global_ragent_state[1], ==, NICE_COMPONENT_STATE_LAST);
1056
1057   /* The max connectivity checks test can't be run with TURN because
1058      we'll have 3 local candidates instead of 1 and the checks will
1059      be random, so we can't predict how many will fail/succeed */
1060 #if USE_TURN == 0
1061
1062   /* step: run test with a hard limit for connecitivity checks */
1063   g_debug ("test-fullmode: TEST STARTS / max connectivity checks");
1064   g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 1, NULL);
1065   g_object_set (G_OBJECT (ragent), "max-connectivity-checks", 1, NULL);
1066   result = run_full_test (lagent, ragent, &baseaddr, 2, 2);
1067   priv_print_global_status ();
1068   g_assert_cmpint (result, ==, 0);
1069   /* should FAIL as agent L can't send any checks: */
1070   g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_FAILED ||
1071             global_lagent_state[1] == NICE_COMPONENT_STATE_FAILED);
1072   g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_FAILED ||
1073             global_lagent_state[1] == NICE_COMPONENT_STATE_FAILED);
1074 #endif
1075
1076   g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 100, NULL);
1077   g_object_set (G_OBJECT (ragent), "max-connectivity-checks", 100, NULL);
1078   result = run_full_test (lagent, ragent, &baseaddr, 4, 0);
1079   priv_print_global_status ();
1080   /* should SUCCEED as agent L can send the checks: */
1081   g_assert_cmpint (result, ==, 0);
1082   g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_CONNECTED ||
1083       global_lagent_state[0] == NICE_COMPONENT_STATE_READY);
1084   g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_CONNECTED ||
1085       global_lagent_state[1] == NICE_COMPONENT_STATE_READY);
1086   g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_CONNECTED ||
1087       global_ragent_state[0] == NICE_COMPONENT_STATE_READY);
1088   g_assert(global_ragent_state[1] == NICE_COMPONENT_STATE_CONNECTED ||
1089       global_ragent_state[1] == NICE_COMPONENT_STATE_READY);
1090   g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 100, NULL);
1091
1092   /* run test with a conflict in controlling mode: controlling-controlling */
1093   g_debug ("test-fullmode: TEST STARTS / controlling mode conflict case-1");
1094   result = run_full_test_control_conflict (lagent, ragent, &baseaddr, TRUE);
1095   priv_print_global_status ();
1096   g_assert_cmpint (result, ==, 0);
1097
1098   g_assert_cmpint (global_lagent_state[0], ==, NICE_COMPONENT_STATE_READY);
1099   g_assert_cmpint (global_lagent_state[1], ==, NICE_COMPONENT_STATE_READY);
1100   g_assert_cmpint (global_ragent_state[0], ==, NICE_COMPONENT_STATE_READY);
1101   g_assert_cmpint (global_ragent_state[1], ==, NICE_COMPONENT_STATE_READY);
1102
1103   /* run test with a conflict in controlling mode: controlled-controlled */
1104   g_debug ("test-fullmode: TEST STARTS / controlling mode conflict case-2");
1105   result = run_full_test_control_conflict (lagent, ragent, &baseaddr, FALSE);
1106   priv_print_global_status ();
1107   g_assert_cmpint (result, ==, 0);
1108   g_assert_cmpint (global_lagent_state[0], ==, NICE_COMPONENT_STATE_READY);
1109   g_assert_cmpint (global_lagent_state[1], ==, NICE_COMPONENT_STATE_READY);
1110   g_assert_cmpint (global_ragent_state[0], ==, NICE_COMPONENT_STATE_READY);
1111   g_assert_cmpint (global_ragent_state[1], ==, NICE_COMPONENT_STATE_READY);
1112
1113   nice_agent_close_async (lagent, cb_closed, &lagent_closed);
1114   nice_agent_close_async (ragent, cb_closed, &ragent_closed);
1115   g_object_unref (lagent);
1116   g_object_unref (ragent);
1117
1118   while (!ragent_closed || !ragent_closed) {
1119     g_main_context_iteration (NULL, TRUE);
1120   }
1121
1122
1123   g_main_loop_unref (global_mainloop);
1124   global_mainloop = NULL;
1125
1126   g_source_remove (timer_id);
1127 #ifdef G_OS_WIN32
1128   WSACleanup();
1129 #endif
1130   return result;
1131 }