static void test_io_stream_properties (NiceAddress *addr) { NiceAgent *agent; guint stream_id; GIOStream *io_stream; GInputStream *input_stream; GOutputStream *output_stream; agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); stream_id = nice_agent_add_stream (agent, 1); /* Try building an I/O stream around it. */ io_stream = nice_agent_get_io_stream (agent, stream_id, 1); g_assert (G_IS_IO_STREAM (io_stream)); g_assert (NICE_IS_IO_STREAM (io_stream)); /* Check various initial properties. */ g_assert (!g_io_stream_is_closed (G_IO_STREAM (io_stream))); g_assert (!g_io_stream_has_pending (G_IO_STREAM (io_stream))); /* Check the input stream’s properties. */ input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_INPUT_STREAM (input_stream)); g_assert (NICE_IS_INPUT_STREAM (input_stream)); g_assert (!g_input_stream_is_closed (input_stream)); g_assert (!g_input_stream_has_pending (input_stream)); /* Check the output stream’s properties. */ output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_OUTPUT_STREAM (output_stream)); g_assert (NICE_IS_OUTPUT_STREAM (output_stream)); g_assert (!g_output_stream_is_closing (output_stream)); g_assert (!g_output_stream_is_closed (output_stream)); g_assert (!g_output_stream_has_pending (output_stream)); /* Remove the component and check that the I/O streams close. */ nice_agent_remove_stream (agent, stream_id); g_assert (g_io_stream_is_closed (G_IO_STREAM (io_stream))); g_assert (g_input_stream_is_closed (input_stream)); g_assert (g_output_stream_is_closed (output_stream)); g_object_unref (io_stream); g_object_unref (agent); }
static void test_invalid_stream (NiceAddress *addr) { NiceAgent *agent; GIOStream *io_stream; agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); /* Try building an I/O stream for an invalid stream. All its operations should * return G_IO_ERROR_BROKEN_PIPE. */ io_stream = nice_agent_get_io_stream (agent, 5, 5); g_assert (io_stream == NULL); g_object_unref (agent); }
JNIEXPORT jlong JNICALL CAST_JNI(createAgentNative,jlong gloopLong,jint useReliable) { GMainLoop* tmp_gloop = (GMainLoop*)gloopLong; NiceAgent* tmp_agent = NULL; // initialize the Ctx AgentCtx* agentCtx = (AgentCtx*) calloc(1,sizeof(AgentCtx)); agentCtx->hasStateObserver = 0; agentCtx->stateObserverObj = 0; agentCtx->cbCandidateGatheringDoneId=0; agentCtx->cbComponentStateChangedId=0; for(int i=0;i<MAX_COMPONENT;i++) { agentCtx->recvCallbackCtx[i] = NULL; } agentCtx->gloop = tmp_gloop; // Create the nice agent if(useReliable==1) { tmp_agent = nice_agent_new_reliable(g_main_loop_get_context (tmp_gloop), NICE_COMPATIBILITY_RFC5245); } else { tmp_agent = nice_agent_new(g_main_loop_get_context (tmp_gloop), NICE_COMPATIBILITY_RFC5245); } if (tmp_agent == NULL) { LOGD("Failed to create agent"); return 0; } agentCtx->agent = tmp_agent; // Connect to the signals g_signal_connect(tmp_agent, "candidate-gathering-done", G_CALLBACK(cb_candidate_gathering_done), agentCtx); g_signal_connect(tmp_agent, "component-state-changed", G_CALLBACK(cb_component_state_changed), agentCtx); g_signal_connect(tmp_agent, "new-selected-pair", G_CALLBACK(cb_new_selected_pair), agentCtx); return (long)agentCtx; }
static void test_zero_length_reads_writes (NiceAddress *addr) { NiceAgent *agent; guint stream_id; GIOStream *io_stream; GInputStream *input_stream; GOutputStream *output_stream; GPollableInputStream *pollable_input_stream; GPollableOutputStream *pollable_output_stream; GError *error = NULL; guint8 buf[1]; /* should never be accessed */ agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); /* Add a stream. */ stream_id = nice_agent_add_stream (agent, 1); /* Try building an I/O stream around it. */ io_stream = nice_agent_get_io_stream (agent, stream_id, 1); g_assert (G_IS_IO_STREAM (io_stream)); g_assert (NICE_IS_IO_STREAM (io_stream)); input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream)); output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream)); pollable_input_stream = G_POLLABLE_INPUT_STREAM (input_stream); pollable_output_stream = G_POLLABLE_OUTPUT_STREAM (output_stream); /* Check zero-length reads and writes complete immediately without error. */ g_assert (g_input_stream_read (input_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert (g_output_stream_write (output_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); /* Remove the component and check that zero-length reads and writes still * result in a 0 response, rather than any error. */ nice_agent_remove_stream (agent, stream_id); g_assert (g_io_stream_is_closed (G_IO_STREAM (io_stream))); g_assert (g_input_stream_read (input_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert (g_output_stream_write (output_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, 0, NULL, &error) == 0); g_assert_no_error (error); g_object_unref (io_stream); g_object_unref (agent); }
static void test_pollable_cancellation (NiceAddress *addr) { NiceAgent *agent; guint stream_id; GIOStream *io_stream; GInputStream *input_stream; GOutputStream *output_stream; GPollableInputStream *pollable_input_stream; GPollableOutputStream *pollable_output_stream; guint8 buf[65536]; GError *error = NULL; GSource *stream_source; GCancellable *cancellable; agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); /* Add a stream. */ stream_id = nice_agent_add_stream (agent, 1); /* Try building an I/O stream around it. */ io_stream = nice_agent_get_io_stream (agent, stream_id, 1); g_assert (G_IS_IO_STREAM (io_stream)); g_assert (NICE_IS_IO_STREAM (io_stream)); /* Grab the input and output streams. */ input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_INPUT_STREAM (input_stream)); pollable_input_stream = G_POLLABLE_INPUT_STREAM (input_stream); output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_OUTPUT_STREAM (output_stream)); pollable_output_stream = G_POLLABLE_OUTPUT_STREAM (output_stream); /* Check the non-blocking read() and write() return immediately if called with * a cancelled cancellable. */ cancellable = g_cancellable_new (); g_cancellable_cancel (cancellable); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, sizeof (buf), cancellable, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); g_clear_error (&error); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, sizeof (buf), cancellable, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); g_clear_error (&error); g_object_unref (cancellable); /* Check the GSources invoke a callback when run with the cancellable * cancelled. */ cancellable = g_cancellable_new (); stream_source = g_pollable_input_stream_create_source (pollable_input_stream, cancellable); check_pollable_source_cancellation (stream_source, cancellable); g_source_unref (stream_source); g_object_unref (cancellable); /* And for the output stream. */ cancellable = g_cancellable_new (); stream_source = g_pollable_output_stream_create_source (pollable_output_stream, cancellable); check_pollable_source_cancellation (stream_source, cancellable); g_object_unref (io_stream); g_source_unref (stream_source); g_object_unref (cancellable); g_object_unref (agent); }
static void test_pollable_properties (NiceAddress *addr) { NiceAgent *agent; guint stream_id; GIOStream *io_stream; GInputStream *input_stream; GOutputStream *output_stream; GPollableInputStream *pollable_input_stream; GPollableOutputStream *pollable_output_stream; guint8 buf[65536]; GError *error = NULL; GSource *stream_source; agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); /* Add a stream. */ stream_id = nice_agent_add_stream (agent, 1); /* Try building an I/O stream around it. */ io_stream = nice_agent_get_io_stream (agent, stream_id, 1); g_assert (G_IS_IO_STREAM (io_stream)); g_assert (NICE_IS_IO_STREAM (io_stream)); /* Check the input stream’s properties. */ input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_INPUT_STREAM (input_stream)); pollable_input_stream = G_POLLABLE_INPUT_STREAM (input_stream); g_assert (g_pollable_input_stream_can_poll (pollable_input_stream)); g_assert (!g_pollable_input_stream_is_readable (pollable_input_stream)); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, sizeof (buf), NULL, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); g_clear_error (&error); stream_source = g_pollable_input_stream_create_source (pollable_input_stream, NULL); g_assert (stream_source != NULL); g_source_unref (stream_source); /* Check the output stream’s properties. */ output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_OUTPUT_STREAM (output_stream)); pollable_output_stream = G_POLLABLE_OUTPUT_STREAM (output_stream); g_assert (g_pollable_output_stream_can_poll (pollable_output_stream)); g_assert (!g_pollable_output_stream_is_writable (pollable_output_stream)); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, sizeof (buf), NULL, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); g_clear_error (&error); stream_source = g_pollable_output_stream_create_source (pollable_output_stream, NULL); g_assert (stream_source != NULL); g_source_unref (stream_source); /* Remove the component and check that the I/O streams close. */ nice_agent_remove_stream (agent, stream_id); g_assert (!g_pollable_input_stream_is_readable (pollable_input_stream)); g_assert (!g_pollable_output_stream_is_writable (pollable_output_stream)); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, sizeof (buf), NULL, &error) == 0); g_assert_no_error (error); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, sizeof (buf), NULL, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED); g_clear_error (&error); g_object_unref (io_stream); g_object_unref (agent); }
int main (void) { NiceAgent *lagent, *ragent; /* agent's L and R */ NiceAddress baseaddr; int result; guint timer_id; const char *stun_server = NULL, *stun_server_port = NULL; #ifdef G_OS_WIN32 WSADATA w; WSAStartup(0x0202, &w); #endif g_type_init (); #if !GLIB_CHECK_VERSION(2,31,8) g_thread_init(NULL); #endif global_mainloop = g_main_loop_new (NULL, FALSE); /* Note: impl limits ... * - no multi-stream support * - no IPv6 support */ /* step: create the agents L and R */ #if USE_RELIABLE lagent = nice_agent_new_reliable (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY); ragent = nice_agent_new_reliable (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY); #else lagent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY); ragent = nice_agent_new (g_main_loop_get_context (global_mainloop), NICE_COMPATIBILITY); #endif nice_agent_set_software (lagent, "Test-fullmode, Left Agent"); nice_agent_set_software (ragent, "Test-fullmode, Right Agent"); /* step: add a timer to catch state changes triggered by signals */ #if USE_TURN timer_id = g_timeout_add (300000, timer_cb, NULL); #else timer_id = g_timeout_add (30000, timer_cb, NULL); #endif /* step: specify which local interface to use */ #if USE_LOOPBACK if (!nice_address_set_from_string (&baseaddr, "127.0.0.1")) g_assert_not_reached (); nice_agent_add_local_address (lagent, &baseaddr); nice_agent_add_local_address (ragent, &baseaddr); #endif g_signal_connect (G_OBJECT (lagent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "candidate-gathering-done", G_CALLBACK (cb_candidate_gathering_done), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "component-state-changed", G_CALLBACK (cb_component_state_changed), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER(1)); g_signal_connect (G_OBJECT (ragent), "new-selected-pair", G_CALLBACK (cb_new_selected_pair), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "new-candidate", G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "new-candidate", G_CALLBACK (cb_new_candidate), GUINT_TO_POINTER (2)); g_signal_connect (G_OBJECT (lagent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), GUINT_TO_POINTER (1)); g_signal_connect (G_OBJECT (ragent), "initial-binding-request-received", G_CALLBACK (cb_initial_binding_request_received), GUINT_TO_POINTER (2)); stun_server = getenv ("NICE_STUN_SERVER"); stun_server_port = getenv ("NICE_STUN_SERVER_PORT"); if (stun_server) { g_object_set (G_OBJECT (lagent), "stun-server", stun_server, NULL); g_object_set (G_OBJECT (lagent), "stun-server-port", atoi (stun_server_port), NULL); g_object_set (G_OBJECT (ragent), "stun-server", stun_server, NULL); g_object_set (G_OBJECT (ragent), "stun-server-port", atoi (stun_server_port), NULL); } g_object_set (G_OBJECT (lagent), "upnp", USE_UPNP, NULL); g_object_set (G_OBJECT (lagent), "proxy-ip", PROXY_IP, NULL); g_object_set (G_OBJECT (lagent), "proxy-port", PROXY_PORT, NULL); g_object_set (G_OBJECT (lagent), "proxy-type", PROXY_TYPE, NULL); g_object_set (G_OBJECT (lagent), "proxy-username", PROXY_USERNAME, NULL); g_object_set (G_OBJECT (lagent), "proxy-password", PROXY_PASSWORD, NULL); g_object_set (G_OBJECT (ragent), "upnp", USE_UPNP, NULL); g_object_set (G_OBJECT (ragent), "proxy-ip", PROXY_IP, NULL); g_object_set (G_OBJECT (ragent), "proxy-port", PROXY_PORT, NULL); g_object_set (G_OBJECT (ragent), "proxy-type", PROXY_TYPE, NULL); g_object_set (G_OBJECT (ragent), "proxy-username", PROXY_USERNAME, NULL); g_object_set (G_OBJECT (ragent), "proxy-password", PROXY_PASSWORD, NULL); /* step: test setter/getter functions for properties */ { guint max_checks = 0; gchar *string = NULL; guint port = 0; gboolean mode = FALSE; g_object_get (G_OBJECT (lagent), "stun-server", &string, NULL); g_assert (stun_server == NULL || strcmp (string, stun_server) == 0); g_free (string); g_object_get (G_OBJECT (lagent), "stun-server-port", &port, NULL); g_assert (stun_server_port == NULL || port == (guint)atoi (stun_server_port)); g_object_get (G_OBJECT (lagent), "proxy-ip", &string, NULL); g_assert (strcmp (string, PROXY_IP) == 0); g_free (string); g_object_get (G_OBJECT (lagent), "proxy-port", &port, NULL); g_assert (port == PROXY_PORT); g_object_get (G_OBJECT (lagent), "controlling-mode", &mode, NULL); g_assert (mode == TRUE); g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 300, NULL); g_object_get (G_OBJECT (lagent), "max-connectivity-checks", &max_checks, NULL); g_assert (max_checks == 300); } /* step: run test the first time */ g_debug ("test-fullmode: TEST STARTS / running test for the 1st time"); result = run_full_test (lagent, ragent, &baseaddr, 4 ,0); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); /* When using TURN, we get peer reflexive candidates for the host cands that we removed so we can get another new_selected_pair signal later depending on timing/racing, we could double (or not) the amount we expected */ #if !(USE_TURN) /* note: verify that correct number of local candidates were reported */ g_assert (global_lagent_cands == 2); g_assert (global_ragent_cands == 2); #endif /* step: run test again without unref'ing agents */ g_debug ("test-fullmode: TEST STARTS / running test for the 2nd time"); result = run_full_test (lagent, ragent, &baseaddr, 4, 0); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); /* When using TURN, we get peer reflexive candidates for the host cands that we removed so we can get another new_selected_pair signal later depending on timing/racing, we could double (or not) the amount we expected */ #if !(USE_TURN) /* note: verify that correct number of local candidates were reported */ g_assert (global_lagent_cands == 2); g_assert (global_ragent_cands == 2); #endif /* step: run test simulating delayed SDP answer */ g_debug ("test-fullmode: TEST STARTS / delayed SDP answer"); result = run_full_test_delayed_answer (lagent, ragent, &baseaddr, 4, 0); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); /* note: verify that correct number of local candidates were reported */ /* When using TURN, we get peer reflexive candidates for the host cands that we removed so we can get another new_selected_pair signal later depending on timing/racing, we could double (or not) the amount we expected */ #if !(USE_TURN) g_assert (global_lagent_cands == 2); g_assert (global_ragent_cands == 2); #endif #if TEST_GOOGLE return result; #endif /* run test with incorrect credentials (make sure process fails) */ g_debug ("test-fullmode: TEST STARTS / incorrect credentials"); result = run_full_test_wrong_password (lagent, ragent, &baseaddr); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_FAILED); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_LAST); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_FAILED); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_LAST); /* The max connectivity checks test can't be run with TURN because we'll have 3 local candidates instead of 1 and the checks will be random, so we can't predict how many will fail/succeed */ #if USE_TURN == 0 /* step: run test with a hard limit for connecitivity checks */ g_debug ("test-fullmode: TEST STARTS / max connectivity checks"); g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 1, NULL); g_object_set (G_OBJECT (ragent), "max-connectivity-checks", 1, NULL); result = run_full_test (lagent, ragent, &baseaddr, 2, 2); priv_print_global_status (); g_assert (result == 0); /* should FAIL as agent L can't send any checks: */ g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_FAILED || global_lagent_state[1] == NICE_COMPONENT_STATE_FAILED); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_FAILED || global_lagent_state[1] == NICE_COMPONENT_STATE_FAILED); #endif g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 100, NULL); g_object_set (G_OBJECT (ragent), "max-connectivity-checks", 100, NULL); result = run_full_test (lagent, ragent, &baseaddr, 4, 0); priv_print_global_status (); /* should SUCCEED as agent L can send the checks: */ g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); g_object_set (G_OBJECT (lagent), "max-connectivity-checks", 100, NULL); /* run test with a conflict in controlling mode: controlling-controlling */ g_debug ("test-fullmode: TEST STARTS / controlling mode conflict case-1"); result = run_full_test_control_conflict (lagent, ragent, &baseaddr, TRUE); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); /* run test with a conflict in controlling mode: controlled-controlled */ g_debug ("test-fullmode: TEST STARTS / controlling mode conflict case-2"); result = run_full_test_control_conflict (lagent, ragent, &baseaddr, FALSE); priv_print_global_status (); g_assert (result == 0); g_assert (global_lagent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_lagent_state[1] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[0] == NICE_COMPONENT_STATE_READY); g_assert (global_ragent_state[1] == NICE_COMPONENT_STATE_READY); g_object_unref (lagent); g_object_unref (ragent); g_main_loop_unref (global_mainloop); global_mainloop = NULL; g_source_remove (timer_id); #ifdef G_OS_WIN32 WSACleanup(); #endif return result; }