示例#1
0
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;
}
示例#2
0
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;
}