JNIEXPORT jint JNICALL CAST_JNI(addStreamNative,jlong agentCtxLong,jstring jstreamName,jint numberOfComponent) { AgentCtx* agentCtx = (AgentCtx*) agentCtxLong; NiceAgent* tmp_agent = agentCtx->agent; jboolean isCopy; const gchar *name = (gchar*) (*env)->GetStringUTFChars(env, jstreamName, &isCopy); // Create a new stream with one component int stream_id = nice_agent_add_stream(tmp_agent, numberOfComponent); if (stream_id == 0) { LOGD("Failed to add stream"); return 0; } nice_agent_set_stream_name (tmp_agent, stream_id, name); if(name) { (*env)->ReleaseStringUTFChars(env,jstreamName,name); } agentCtx->totalComponentNumber = numberOfComponent; for(int i=0;i<numberOfComponent;i++) { nice_agent_attach_recv(tmp_agent, stream_id, i+1, g_main_loop_get_context (agentCtx->gloop), recv_callback, agentCtx); } return stream_id; }
static void * example_thread(void *data) { NiceAgent *agent; GIOChannel* io_stdin; guint stream_id; gchar *line = NULL; gchar *sdp, *sdp64; #ifdef G_OS_WIN32 io_stdin = g_io_channel_win32_new_fd(_fileno(stdin)); #else io_stdin = g_io_channel_unix_new(fileno(stdin)); #endif g_io_channel_set_flags(io_stdin, G_IO_FLAG_NONBLOCK, NULL); // Create the nice agent agent = nice_agent_new(g_main_loop_get_context (gloop), NICE_COMPATIBILITY_RFC5245); if (agent == NULL) g_error("Failed to create agent"); // Set the STUN settings and controlling mode if (stun_addr) { g_object_set(agent, "stun-server", stun_addr, NULL); g_object_set(agent, "stun-server-port", stun_port, NULL); } g_object_set(agent, "controlling-mode", controlling, NULL); // Connect to the signals g_signal_connect(agent, "candidate-gathering-done", G_CALLBACK(cb_candidate_gathering_done), NULL); g_signal_connect(agent, "component-state-changed", G_CALLBACK(cb_component_state_changed), NULL); // Create a new stream with one component stream_id = nice_agent_add_stream(agent, 1); if (stream_id == 0) g_error("Failed to add stream"); nice_agent_set_stream_name (agent, stream_id, "text"); // Attach to the component to receive the data // Without this call, candidates cannot be gathered nice_agent_attach_recv(agent, stream_id, 1, g_main_loop_get_context (gloop), cb_nice_recv, NULL); // Start gathering local candidates if (!nice_agent_gather_candidates(agent, stream_id)) g_error("Failed to start candidate gathering"); g_debug("waiting for candidate-gathering-done signal..."); g_mutex_lock(&gather_mutex); while (!exit_thread && !candidate_gathering_done) g_cond_wait(&gather_cond, &gather_mutex); g_mutex_unlock(&gather_mutex); if (exit_thread) goto end; // Candidate gathering is done. Send our local candidates on stdout sdp = nice_agent_generate_local_sdp (agent); printf("Generated SDP from agent :\n%s\n\n", sdp); printf("Copy the following line to remote client:\n"); sdp64 = g_base64_encode ((const guchar *)sdp, strlen (sdp)); printf("\n %s\n", sdp64); g_free (sdp); g_free (sdp64); // Listen on stdin for the remote candidate list printf("Enter remote data (single line, no wrapping):\n"); printf("> "); fflush (stdout); while (!exit_thread) { GIOStatus s = g_io_channel_read_line (io_stdin, &line, NULL, NULL, NULL); if (s == G_IO_STATUS_NORMAL) { gsize sdp_len; sdp = (gchar *) g_base64_decode (line, &sdp_len); // Parse remote candidate list and set it on the agent if (sdp && nice_agent_parse_remote_sdp (agent, sdp) > 0) { g_free (sdp); g_free (line); break; } else { fprintf(stderr, "ERROR: failed to parse remote data\n"); printf("Enter remote data (single line, no wrapping):\n"); printf("> "); fflush (stdout); } g_free (sdp); g_free (line); } else if (s == G_IO_STATUS_AGAIN) { g_usleep (100000); } } g_debug("waiting for state READY or FAILED signal..."); g_mutex_lock(&negotiate_mutex); while (!exit_thread && !negotiation_done) g_cond_wait(&negotiate_cond, &negotiate_mutex); g_mutex_unlock(&negotiate_mutex); if (exit_thread) goto end; // Listen to stdin and send data written to it printf("\nSend lines to remote (Ctrl-D to quit):\n"); printf("> "); fflush (stdout); while (!exit_thread) { GIOStatus s = g_io_channel_read_line (io_stdin, &line, NULL, NULL, NULL); if (s == G_IO_STATUS_NORMAL) { nice_agent_send(agent, stream_id, 1, strlen(line), line); g_free (line); printf("> "); fflush (stdout); } else if (s == G_IO_STATUS_AGAIN) { g_usleep (100000); } else { // Ctrl-D was pressed. nice_agent_send(agent, stream_id, 1, 1, "\0"); break; } } end: g_object_unref(agent); g_io_channel_unref (io_stdin); g_main_loop_quit (gloop); return NULL; }