diff --git a/src/ice/libjuice/ice_agent.cpp b/src/ice/libjuice/ice_agent.cpp index 48bd921..8fc35e2 100644 --- a/src/ice/libjuice/ice_agent.cpp +++ b/src/ice/libjuice/ice_agent.cpp @@ -6,7 +6,7 @@ #include "log.h" -IceAgent::IceAgent(std::string &stun_ip, uint16_t stun_port, +IceAgent::IceAgent(bool offer_peer, std::string &stun_ip, uint16_t stun_port, std::string &turn_ip, uint16_t turn_port, std::string &turn_username, std::string &turn_password) : stun_ip_(stun_ip), diff --git a/src/ice/libjuice/ice_agent.h b/src/ice/libjuice/ice_agent.h index 96ea356..21252a7 100644 --- a/src/ice/libjuice/ice_agent.h +++ b/src/ice/libjuice/ice_agent.h @@ -8,8 +8,8 @@ class IceAgent { public: - IceAgent(std::string& stun_ip, uint16_t stun_port, std::string& turn_ip, - uint16_t turn_port, std::string& turn_username, + IceAgent(bool offer_peer, std::string& stun_ip, uint16_t stun_port, + std::string& turn_ip, uint16_t turn_port, std::string& turn_username, std::string& turn_password); ~IceAgent(); diff --git a/src/ice/libnice/ice_agent.cpp b/src/ice/libnice/ice_agent.cpp index a78cf47..e3b26c9 100644 --- a/src/ice/libnice/ice_agent.cpp +++ b/src/ice/libnice/ice_agent.cpp @@ -6,7 +6,7 @@ #include "log.h" -IceAgent::IceAgent(std::string &stun_ip, uint16_t stun_port, +IceAgent::IceAgent(bool offer_peer, std::string &stun_ip, uint16_t stun_port, std::string &turn_ip, uint16_t turn_port, std::string &turn_username, std::string &turn_password) : stun_ip_(stun_ip), @@ -14,49 +14,88 @@ IceAgent::IceAgent(std::string &stun_ip, uint16_t stun_port, turn_ip_(turn_ip), turn_port_(turn_port), turn_username_(turn_username), - turn_password_(turn_password) {} + turn_password_(turn_password), + controlling_(offer_peer) {} -IceAgent::~IceAgent() {} +IceAgent::~IceAgent() { + exit_thread_ = TRUE; + g_thread_join(gexamplethread_); +} + +void *IceAgent::CreateNcieAgent(void *data) { + if (!data) { + return nullptr; + } + + IceAgent *ice_agent_ptr = (IceAgent *)data; + + ice_agent_ptr->gloop_ = g_main_loop_new(NULL, FALSE); + + // Create the nice agent_ + ice_agent_ptr->agent_ = + nice_agent_new_reliable(g_main_loop_get_context(ice_agent_ptr->gloop_), + NICE_COMPATIBILITY_RFC5245); + if (ice_agent_ptr->agent_ == NULL) { + LOG_ERROR("Failed to create agent_"); + } + + g_object_set(ice_agent_ptr->agent_, "stun-server", + ice_agent_ptr->stun_ip_.c_str(), NULL); + g_object_set(ice_agent_ptr->agent_, "stun-server-port", + ice_agent_ptr->stun_port_, NULL); + + g_object_set(ice_agent_ptr->agent_, "controlling-mode", + ice_agent_ptr->controlling_, NULL); + + // Connect to the signals + g_signal_connect(ice_agent_ptr->agent_, "candidate-gathering-done", + G_CALLBACK(ice_agent_ptr->on_gathering_done_), + ice_agent_ptr->user_ptr_); + g_signal_connect(ice_agent_ptr->agent_, "new-selected-pair", + G_CALLBACK(ice_agent_ptr->on_candidate_), + ice_agent_ptr->user_ptr_); + g_signal_connect(ice_agent_ptr->agent_, "component-state-changed", + G_CALLBACK(ice_agent_ptr->on_state_changed_), + ice_agent_ptr->user_ptr_); + + // Create a new stream with one component + ice_agent_ptr->stream_id_ = nice_agent_add_stream(ice_agent_ptr->agent_, 1); + if (ice_agent_ptr->stream_id_ == 0) { + LOG_ERROR("Failed to add stream"); + } + + // nice_agent_set_stream_name(ice_agent_ptr->agent_, stream_id_, "video"); + + // Attach to the component to receive the data + // Without this call, candidates cannot be gathered + nice_agent_attach_recv(ice_agent_ptr->agent_, ice_agent_ptr->stream_id_, 1, + g_main_loop_get_context(ice_agent_ptr->gloop_), + ice_agent_ptr->on_recv_, ice_agent_ptr->user_ptr_); + + g_main_loop_run(ice_agent_ptr->gloop_); +} int IceAgent::CreateIceAgent(nice_cb_state_changed_t on_state_changed, nice_cb_candidate_t on_candidate, nice_cb_gathering_done_t on_gathering_done, nice_cb_recv_t on_recv, void *user_ptr) { + on_state_changed_ = on_state_changed; + on_candidate_ = on_candidate; + on_gathering_done_ = on_gathering_done; + on_recv_ = on_recv; + user_ptr_ = user_ptr; + g_networking_init(); - gloop_ = g_main_loop_new(NULL, FALSE); - // Create the nice agent_ - agent_ = nice_agent_new(g_main_loop_get_context(gloop_), - NICE_COMPATIBILITY_RFC5245); - if (agent_ == NULL) { - LOG_ERROR("Failed to create agent_"); - } + // gloop_ = g_main_loop_new(NULL, FALSE); + exit_thread_ = FALSE; + // gexamplethread_ = g_thread_new("example thread", &CreateNcieAgent, this); - g_object_set(agent_, "stun-server", stun_ip_.c_str(), 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(on_gathering_done), NULL); - g_signal_connect(agent_, "new-selected-pair", G_CALLBACK(on_candidate), NULL); - g_signal_connect(agent_, "component-state-changed", - G_CALLBACK(on_state_changed), NULL); - - // Create a new stream with one component - stream_id_ = nice_agent_add_stream(agent_, 1); - if (stream_id_ == 0) { - LOG_ERROR("Failed to add stream"); - } - nice_agent_set_stream_name(agent_, stream_id_, "video"); - - // 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_), - on_recv, NULL); + // g_main_loop_run(gloop_); + g_thread_.reset(new std::thread(std::bind(&IceAgent::CreateNcieAgent, this))); LOG_INFO("Nice agent init finish"); + g_usleep(100000); return 0; } diff --git a/src/ice/libnice/ice_agent.h b/src/ice/libnice/ice_agent.h index 561de22..9364441 100644 --- a/src/ice/libnice/ice_agent.h +++ b/src/ice/libnice/ice_agent.h @@ -2,6 +2,7 @@ #define _ICE_AGENT_H_ #include +#include #include "gio/gnetworking.h" #include "nice/agent.h" @@ -23,8 +24,8 @@ typedef void (*nice_cb_recv_t)(NiceAgent* agent, guint stream_id, class IceAgent { public: - IceAgent(std::string& stun_ip, uint16_t stun_port, std::string& turn_ip, - uint16_t turn_port, std::string& turn_username, + IceAgent(bool offer_peer, std::string& stun_ip, uint16_t stun_port, + std::string& turn_ip, uint16_t turn_port, std::string& turn_username, std::string& turn_password); ~IceAgent(); @@ -47,20 +48,32 @@ class IceAgent { int Send(const char* data, size_t size); - private: + static void* CreateNcieAgent(void* data); + + public: std::string stun_ip_ = ""; uint16_t stun_port_ = 0; std::string turn_ip_ = ""; uint16_t turn_port_ = 0; std::string turn_username_ = ""; std::string turn_password_ = ""; + + std::unique_ptr g_thread_; NiceAgent* agent_ = nullptr; GMainLoop* gloop_; + GThread* gexamplethread_; + gboolean exit_thread_; bool controlling_ = false; uint32_t stream_id_ = 0; // char local_sdp_[NICE_MAX_SDP_STRING_LEN]; char* local_sdp_ = nullptr; NiceComponentState state_; + + nice_cb_state_changed_t on_state_changed_; + nice_cb_candidate_t on_candidate_; + nice_cb_gathering_done_t on_gathering_done_; + nice_cb_recv_t on_recv_; + void* user_ptr_; }; #endif \ No newline at end of file diff --git a/src/pc/peer_connection.cpp b/src/pc/peer_connection.cpp index f23b77f..9af1f31 100644 --- a/src/pc/peer_connection.cpp +++ b/src/pc/peer_connection.cpp @@ -96,7 +96,7 @@ int PeerConnection::Init(PeerConnectionParams params, }; on_ice_status_change_ = [this](std::string ice_status) { - if ("completed" == ice_status) { + if ("completed" == ice_status || "ready" == ice_status) { ice_ready_ = true; on_connection_status_(ConnectionStatus::Connected); b_force_i_frame_ = true; diff --git a/src/transmission/ice_transmission.cpp b/src/transmission/ice_transmission.cpp index 5660ec3..c3e6585 100644 --- a/src/transmission/ice_transmission.cpp +++ b/src/transmission/ice_transmission.cpp @@ -111,8 +111,9 @@ int IceTransmission::InitIceTransmission(std::string &stun_ip, int stun_port, remote_user_id_.size()); }); - ice_agent_ = std::make_unique( - stun_ip, stun_port, turn_ip, turn_port, turn_username, turn_password); + ice_agent_ = + std::make_unique(offer_peer_, stun_ip, stun_port, turn_ip, + turn_port, turn_username, turn_password); #ifdef USE_NICE ice_agent_->CreateIceAgent( diff --git a/xmake.lua b/xmake.lua index a535005..d5604cc 100644 --- a/xmake.lua +++ b/xmake.lua @@ -205,7 +205,7 @@ target("guest") target("nicetest") set_kind("binary") add_packages("vcpkg::libnice") - add_files("tests/peerconnection/nicesdp.cpp") + add_files("tests/peerconnection/nice.cpp") add_includedirs("E:/SourceCode/vcpkg/installed/x64-windows-static/include/glib-2.0") add_includedirs("E:/SourceCode/vcpkg/installed/x64-windows-static/lib/glib-2.0/include") add_linkdirs("E:/SourceCode/vcpkg/installed/x64-windows-static/lib")