static char * kms_ice_nice_agent_add_stream (KmsIceBaseAgent * self, const char *stream_id, guint16 min_port, guint16 max_port) { KmsIceNiceAgent *nice_agent = KMS_ICE_NICE_AGENT (self); guint id = nice_agent_add_stream (nice_agent->priv->agent, KMS_NICE_N_COMPONENTS); char buff[33]; int i; if (min_port != 0 && max_port != 0 && min_port != 1 && max_port != G_MAXUINT16) { for (i = 1; i <= KMS_NICE_N_COMPONENTS; i++) { nice_agent_set_port_range (nice_agent->priv->agent, id, i, min_port, max_port); } } if (id == 0) { GST_ERROR_OBJECT (self, "Cannot add nice stream for %s.", stream_id); return NULL; } //convert id to char* g_snprintf (buff, 32, "%d", id); return g_strdup (buff); }
void NiceConnection::init() { streamsGathered = 0; this->updateIceState(NICE_INITIAL); g_type_init(); ELOG_DEBUG("Creating Main Context"); context_ = g_main_context_new(); ELOG_DEBUG("Creating Main Loop"); loop_ = g_main_loop_new(context_, FALSE); ELOG_DEBUG("Creating Agent"); //loop_ = g_main_loop_new(NULL, FALSE); // nice_debug_enable( TRUE ); // Create a nice agent //agent_ = nice_agent_new(g_main_loop_get_context(loop_), NICE_COMPATIBILITY_RFC5245); agent_ = nice_agent_new(context_, NICE_COMPATIBILITY_RFC5245); GValue controllingMode = { 0 }; g_value_init(&controllingMode, G_TYPE_BOOLEAN); g_value_set_boolean(&controllingMode, false); g_object_set_property(G_OBJECT( agent_ ), "controlling-mode", &controllingMode); // NiceAddress* naddr = nice_address_new(); // nice_agent_add_local_address(agent_, naddr); if (stunServer_.compare("") != 0 && stunPort_!=0) { GValue val = { 0 }, val2 = { 0 }; g_value_init(&val, G_TYPE_STRING); g_value_set_string(&val, stunServer_.c_str()); g_object_set_property(G_OBJECT( agent_ ), "stun-server", &val); g_value_init(&val2, G_TYPE_UINT); g_value_set_uint(&val2, stunPort_); g_object_set_property(G_OBJECT( agent_ ), "stun-server-port", &val2); ELOG_WARN("Stun Server %s:%d", stunServer_.c_str(), stunPort_); } // Connect the signals g_signal_connect( G_OBJECT( agent_ ), "candidate-gathering-done", G_CALLBACK( cb_candidate_gathering_done ), this); g_signal_connect( G_OBJECT( agent_ ), "component-state-changed", G_CALLBACK( cb_component_state_changed ), this); g_signal_connect( G_OBJECT( agent_ ), "new-selected-pair", G_CALLBACK( cb_new_selected_pair ), this); // Create a new stream and start gathering candidates ELOG_DEBUG("Adding Stream... Number of components %d", iceComponents_); nice_agent_add_stream(agent_, iceComponents_); // Set Port Range ----> If this doesn't work when linking the file libnice.sym has to be modified to include this call if (minPort_!=0 && maxPort_!=0) { nice_agent_set_port_range(agent_, (guint)1, (guint)1, (guint)minPort_, (guint)maxPort_); } nice_agent_gather_candidates(agent_, 1); nice_agent_attach_recv(agent_, 1, 1, context_, cb_nice_recv, this); if (iceComponents_ > 1) { nice_agent_attach_recv(agent_, 1, 2, context_, cb_nice_recv, this); } // Attach to the component to receive the data g_main_loop_run(loop_); }
void NiceConnection::init() { if(this->checkIceState() != NICE_INITIAL){ ELOG_DEBUG("Initing NiceConnection not in INITIAL state, exiting... %p", this); return; }; { boost::unique_lock<boost::mutex> lock(agentMutex_); if(!running_) return; this->updateIceState(NICE_INITIAL); g_type_init(); context_ = g_main_context_new(); g_main_context_set_poll_func(context_,timed_poll); /* loop_ = g_main_loop_new(context_, FALSE); */ ELOG_DEBUG("Creating Agent"); //loop_ = g_main_loop_new(NULL, FALSE); // nice_debug_enable( TRUE ); // Create a nice agent //agent_ = nice_agent_new(g_main_loop_get_context(loop_), NICE_COMPATIBILITY_RFC5245); agent_ = nice_agent_new(context_, NICE_COMPATIBILITY_RFC5245); GValue controllingMode = { 0 }; g_value_init(&controllingMode, G_TYPE_BOOLEAN); g_value_set_boolean(&controllingMode, false); g_object_set_property(G_OBJECT( agent_ ), "controlling-mode", &controllingMode); // NiceAddress* naddr = nice_address_new(); // nice_agent_add_local_address(agent_, naddr); if (stunServer_.compare("") != 0 && stunPort_!=0){ GValue val = { 0 }, val2 = { 0 }; g_value_init(&val, G_TYPE_STRING); g_value_set_string(&val, stunServer_.c_str()); g_object_set_property(G_OBJECT( agent_ ), "stun-server", &val); g_value_init(&val2, G_TYPE_UINT); g_value_set_uint(&val2, stunPort_); g_object_set_property(G_OBJECT( agent_ ), "stun-server-port", &val2); ELOG_DEBUG("Setting STUN server %s:%d", stunServer_.c_str(), stunPort_); } // Connect the signals g_signal_connect( G_OBJECT( agent_ ), "candidate-gathering-done", G_CALLBACK( cb_candidate_gathering_done ), this); g_signal_connect( G_OBJECT( agent_ ), "component-state-changed", G_CALLBACK( cb_component_state_changed ), this); g_signal_connect( G_OBJECT( agent_ ), "new-selected-pair", G_CALLBACK( cb_new_selected_pair ), this); // Create a new stream and start gathering candidates ELOG_DEBUG("Adding Stream... Number of components %d", iceComponents_); nice_agent_add_stream(agent_, iceComponents_); // Set Port Range ----> If this doesn't work when linking the file libnice.sym has to be modified to include this call if (minPort_!=0 && maxPort_!=0){ ELOG_DEBUG("Setting port range: %d to %d\n", minPort_, maxPort_); nice_agent_set_port_range(agent_, (guint)1, (guint)1, (guint)minPort_, (guint)maxPort_); } if (SERVER_SIDE_TURN){ for (int i = 1; i < (iceComponents_ +1); i++){ ELOG_DEBUG("Setting TURN Comp %d\n", i); nice_agent_set_relay_info (agent_, 1, i, "", // TURN Server IP 3479, // TURN Server PORT "", // Username "", // Pass NICE_RELAY_TYPE_TURN_UDP); } } ELOG_DEBUG("Gathering candidates %p", this); nice_agent_gather_candidates(agent_, 1); if(agent_){ nice_agent_attach_recv(agent_, 1, 1, context_, cb_nice_recv, this); if (iceComponents_ > 1) { nice_agent_attach_recv(agent_, 1, 2, context_,cb_nice_recv, this); } }else{ running_=false; } } // Attach to the component to receive the data while(running_){ boost::unique_lock<boost::mutex> lockContext(agentMutex_); if(this->checkIceState()>=NICE_FINISHED) break; g_main_context_iteration(context_, true); } ELOG_DEBUG("LibNice thread finished %p", this); }
void LibNiceInterfaceImpl::NiceAgentSetPortRange(NiceAgent* agent, unsigned int stream_id, unsigned int component_id, unsigned int min_port, unsigned int max_port) { return nice_agent_set_port_range(agent, stream_id, component_id, min_port, max_port); }
static int run_full_test (NiceAgent *lagent, NiceAgent *ragent, NiceAddress *baseaddr, guint ready, guint failed) { guint ls_id, rs_id; gint ret; /* XXX: dear compiler, this is for you */ (void)baseaddr; /* step: initialize variables modified by the callbacks */ global_components_ready = 0; global_components_ready_exit = ready; global_components_failed = 0; global_components_failed_exit = failed; global_lagent_gathering_done = FALSE; global_ragent_gathering_done = FALSE; global_lagent_ibr_received = global_ragent_ibr_received = FALSE; global_lagent_cands = global_ragent_cands = 0; g_object_set (G_OBJECT (lagent), "controlling-mode", TRUE, NULL); g_object_set (G_OBJECT (ragent), "controlling-mode", FALSE, NULL); /* step: add one stream, with RTP+RTCP components, to each agent */ ls_id = nice_agent_add_stream (lagent, 2); rs_id = nice_agent_add_stream (ragent, 2); g_assert (ls_id > 0); g_assert (rs_id > 0); #if USE_TURN nice_agent_set_relay_info(lagent, ls_id, 1, TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE); nice_agent_set_relay_info(lagent, ls_id, 2, TURN_IP, TURN_PORT, TURN_USER, TURN_PASS, TURN_TYPE); nice_agent_set_relay_info(ragent, rs_id, 1, TURN_IP, TURN_PORT, TURN_USER2, TURN_PASS2, TURN_TYPE); nice_agent_set_relay_info(ragent, rs_id, 2, TURN_IP, TURN_PORT, TURN_USER2, TURN_PASS2, TURN_TYPE); #endif /* Gather candidates and test nice_agent_set_port_range */ nice_agent_set_port_range (lagent, ls_id, 1, 10000, 10000); nice_agent_set_port_range (lagent, ls_id, 2, 10001, 10001); nice_agent_set_port_range (ragent, rs_id, 1, 12345, 12345); nice_agent_set_port_range (ragent, rs_id, 2, 10000, 10001); g_assert (nice_agent_gather_candidates (lagent, ls_id) == TRUE); g_assert (nice_agent_gather_candidates (ragent, rs_id) == FALSE); g_assert (nice_agent_get_local_candidates (ragent, rs_id, 1) == NULL); g_assert (nice_agent_get_local_candidates (ragent, rs_id, 2) == NULL); nice_agent_set_port_range (ragent, rs_id, 2, 10000, 10002); g_assert (nice_agent_gather_candidates (ragent, rs_id) == TRUE); #ifdef USE_LOOPBACK { GSList *cands = NULL, *i; NiceCandidate *cand = NULL; cands = nice_agent_get_local_candidates (lagent, ls_id, 1); g_assert (g_slist_length (cands) == 1); cand = cands->data; g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST); g_assert (nice_address_get_port (&cand->addr) == 10000); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); cands = nice_agent_get_local_candidates (lagent, ls_id, 2); g_assert (g_slist_length (cands) == 1); cand = cands->data; g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST); g_assert (nice_address_get_port (&cand->addr) == 10001); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); cands = nice_agent_get_local_candidates (ragent, rs_id, 1); g_assert (g_slist_length (cands) == 1); cand = cands->data; g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST); g_assert (nice_address_get_port (&cand->addr) == 12345); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); cands = nice_agent_get_local_candidates (ragent, rs_id, 2); g_assert (g_slist_length (cands) == 1); cand = cands->data; g_assert (cand->type == NICE_CANDIDATE_TYPE_HOST); g_assert (nice_address_get_port (&cand->addr) == 10002); for (i = cands; i; i = i->next) nice_candidate_free ((NiceCandidate *) i->data); g_slist_free (cands); } #endif /* step: attach to mainloop (needed to register the fds) */ nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (1)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (2)); nice_agent_attach_recv (ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, g_main_loop_get_context (global_mainloop), cb_nice_recv, GUINT_TO_POINTER (2)); /* step: run mainloop until local candidates are ready * (see timer_cb() above) */ if (global_lagent_gathering_done != TRUE || global_ragent_gathering_done != TRUE) { g_debug ("test-fullmode: Added streams, running mainloop until 'candidate-gathering-done'..."); g_main_loop_run (global_mainloop); g_assert (global_lagent_gathering_done == TRUE); g_assert (global_ragent_gathering_done == TRUE); } set_credentials (lagent, ls_id, ragent, rs_id); /* step: pass the remote candidates to agents */ set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTP, USE_TURN); set_candidates (ragent, rs_id, lagent, ls_id, NICE_COMPONENT_TYPE_RTCP, USE_TURN); set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTP, USE_TURN); set_candidates (lagent, ls_id, ragent, rs_id, NICE_COMPONENT_TYPE_RTCP, USE_TURN); g_debug ("test-fullmode: Set properties, next running mainloop until connectivity checks succeed..."); /* step: run the mainloop until connectivity checks succeed * (see timer_cb() above) */ g_main_loop_run (global_mainloop); /* note: verify that STUN binding requests were sent */ g_assert (global_lagent_ibr_received == TRUE); g_assert (global_ragent_ibr_received == TRUE); /* note: test payload send and receive */ global_ragent_read = 0; ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678"); if (ret == -1) { gboolean reliable = FALSE; g_object_get (G_OBJECT (lagent), "reliable", &reliable, NULL); g_debug ("Sending data returned -1 in %s mode", reliable?"Reliable":"Non-reliable"); if (reliable) { gulong signal_handler; signal_handler = g_signal_connect (G_OBJECT (lagent), "reliable-transport-writable", G_CALLBACK (cb_writable), NULL); g_debug ("Running mainloop until transport is writable"); g_main_loop_run (global_mainloop); g_signal_handler_disconnect(G_OBJECT (lagent), signal_handler); ret = nice_agent_send (lagent, ls_id, 1, 16, "1234567812345678"); } } g_debug ("Sent %d bytes", ret); g_assert (ret == 16); g_main_loop_run (global_mainloop); g_assert (global_ragent_read == 16); g_debug ("test-fullmode: Ran mainloop, removing streams..."); /* step: clean up resources and exit */ nice_agent_remove_stream (lagent, ls_id); nice_agent_remove_stream (ragent, rs_id); return 0; }
NiceConnection::NiceConnection(MediaType med, const std::string &transport_name,NiceConnectionListener* listener, unsigned int iceComponents, const IceConfig& iceConfig, std::string username, std::string password) : mediaType(med), agent_(NULL), listener_(listener), candsDelivered_(0), context_(NULL), iceState_(NICE_INITIAL), iceComponents_(iceComponents) { localCandidates.reset(new std::vector<CandidateInfo>()); transportName.reset(new std::string(transport_name)); for (unsigned int i = 1; i<=iceComponents_; i++) { comp_state_list_[i] = NICE_INITIAL; } g_type_init(); context_ = g_main_context_new(); g_main_context_set_poll_func(context_,timed_poll); ELOG_DEBUG("Creating Agent"); nice_debug_enable( FALSE ); // Create a nice agent agent_ = nice_agent_new(context_, NICE_COMPATIBILITY_RFC5245); GValue controllingMode = { 0 }; g_value_init(&controllingMode, G_TYPE_BOOLEAN); g_value_set_boolean(&controllingMode, false); g_object_set_property(G_OBJECT( agent_ ), "controlling-mode", &controllingMode); GValue checks = { 0 }; g_value_init(&checks, G_TYPE_UINT); g_value_set_uint(&checks, 100); g_object_set_property(G_OBJECT( agent_ ), "max-connectivity-checks", &checks); if (iceConfig.stunServer.compare("") != 0 && iceConfig.stunPort!=0){ GValue val = { 0 }, val2 = { 0 }; g_value_init(&val, G_TYPE_STRING); g_value_set_string(&val, iceConfig.stunServer.c_str()); g_object_set_property(G_OBJECT( agent_ ), "stun-server", &val); g_value_init(&val2, G_TYPE_UINT); g_value_set_uint(&val2, iceConfig.stunPort); g_object_set_property(G_OBJECT( agent_ ), "stun-server-port", &val2); ELOG_DEBUG("Setting STUN server %s:%d", iceConfig.stunServer.c_str(), iceConfig.stunPort); } // Connect the signals g_signal_connect( G_OBJECT( agent_ ), "candidate-gathering-done", G_CALLBACK( cb_candidate_gathering_done ), this); g_signal_connect( G_OBJECT( agent_ ), "component-state-changed", G_CALLBACK( cb_component_state_changed ), this); g_signal_connect( G_OBJECT( agent_ ), "new-selected-pair", G_CALLBACK( cb_new_selected_pair ), this); g_signal_connect( G_OBJECT( agent_ ), "new-candidate", G_CALLBACK( cb_new_candidate ), this); // Create a new stream and start gathering candidates ELOG_DEBUG("Adding Stream... Number of components %d", iceComponents_); nice_agent_add_stream(agent_, iceComponents_); gchar *ufrag = NULL, *upass = NULL; nice_agent_get_local_credentials(agent_, 1, &ufrag, &upass); ufrag_ = std::string(ufrag); g_free(ufrag); upass_ = std::string(upass); g_free(upass); // Set our remote credentials. This must be done *after* we add a stream. if (username.compare("")!=0 && password.compare("")!=0){ ELOG_DEBUG("Setting remote credentials in constructor"); this->setRemoteCredentials(username, password); } // Set Port Range ----> If this doesn't work when linking the file libnice.sym has to be modified to include this call if (iceConfig.minPort!=0 && iceConfig.maxPort!=0){ ELOG_DEBUG("Setting port range: %d to %d\n", iceConfig.minPort, iceConfig.maxPort); nice_agent_set_port_range(agent_, (guint)1, (guint)1, (guint)iceConfig.minPort, (guint)iceConfig.maxPort); } if (iceConfig.turnServer.compare("") != 0 && iceConfig.turnPort!=0){ ELOG_DEBUG("Setting TURN server %s:%d", iceConfig.turnServer.c_str(), iceConfig.turnPort); ELOG_DEBUG("Setting TURN credentials %s:%s", iceConfig.turnUsername.c_str(), iceConfig.turnPass.c_str()); for (unsigned int i = 1; i <= iceComponents_ ; i++){ nice_agent_set_relay_info (agent_, 1, i, iceConfig.turnServer.c_str(), // TURN Server IP iceConfig.turnPort, // TURN Server PORT iceConfig.turnUsername.c_str(), // Username iceConfig.turnPass.c_str(), // Pass NICE_RELAY_TYPE_TURN_UDP); } } if(agent_){ for (unsigned int i = 1; i<=iceComponents_; i++){ nice_agent_attach_recv(agent_, 1, i, context_, cb_nice_recv, this); } running_ = true; } else{ running_=false; } m_Thread_ = boost::thread(&NiceConnection::init, this); }