[feat] Support trickle ice

This commit is contained in:
dijunkun
2024-07-29 16:47:51 +08:00
parent 15419cc313
commit af49ebe63d
6 changed files with 130 additions and 222 deletions

View File

@@ -5,10 +5,11 @@
#include "log.h" #include "log.h"
IceAgent::IceAgent(bool offer_peer, std::string &stun_ip, uint16_t stun_port, IceAgent::IceAgent(bool trickle_ice, bool offer_peer, std::string &stun_ip,
std::string &turn_ip, uint16_t turn_port, uint16_t stun_port, std::string &turn_ip, uint16_t turn_port,
std::string &turn_username, std::string &turn_password) std::string &turn_username, std::string &turn_password)
: stun_ip_(stun_ip), : trickle_ice_(trickle_ice),
stun_ip_(stun_ip),
stun_port_(stun_port), stun_port_(stun_port),
turn_ip_(turn_ip), turn_ip_(turn_ip),
turn_port_(turn_port), turn_port_(turn_port),
@@ -21,6 +22,9 @@ IceAgent::~IceAgent() {
DestroyIceAgent(); DestroyIceAgent();
} }
g_object_unref(agent_); g_object_unref(agent_);
g_free(ice_ufrag_);
g_free(ice_password_);
g_free(stream_sdp_);
} }
int IceAgent::CreateIceAgent(nice_cb_state_changed_t on_state_changed, int IceAgent::CreateIceAgent(nice_cb_state_changed_t on_state_changed,
@@ -46,7 +50,9 @@ int IceAgent::CreateIceAgent(nice_cb_state_changed_t on_state_changed,
agent_ = nice_agent_new_full( agent_ = nice_agent_new_full(
g_main_loop_get_context(gloop_), NICE_COMPATIBILITY_RFC5245, g_main_loop_get_context(gloop_), NICE_COMPATIBILITY_RFC5245,
(NiceAgentOption)(NICE_AGENT_OPTION_ICE_TRICKLE)); (NiceAgentOption)(trickle_ice_ ? NICE_AGENT_OPTION_ICE_TRICKLE |
NICE_AGENT_OPTION_RELIABLE
: NICE_AGENT_OPTION_RELIABLE));
if (agent_ == nullptr) { if (agent_ == nullptr) {
LOG_ERROR("Failed to create agent_"); LOG_ERROR("Failed to create agent_");
@@ -55,7 +61,6 @@ int IceAgent::CreateIceAgent(nice_cb_state_changed_t on_state_changed,
g_object_set(agent_, "stun-server", stun_ip_.c_str(), nullptr); g_object_set(agent_, "stun-server", stun_ip_.c_str(), nullptr);
g_object_set(agent_, "stun-server-port", stun_port_, nullptr); g_object_set(agent_, "stun-server-port", stun_port_, nullptr);
g_object_set(agent_, "controlling-mode", controlling_, nullptr); g_object_set(agent_, "controlling-mode", controlling_, nullptr);
// g_object_set(agent_, "ice-trickle", true, nullptr);
g_signal_connect(agent_, "candidate-gathering-done", g_signal_connect(agent_, "candidate-gathering-done",
G_CALLBACK(on_gathering_done_), user_ptr_); G_CALLBACK(on_gathering_done_), user_ptr_);
@@ -82,8 +87,6 @@ int IceAgent::CreateIceAgent(nice_cb_state_changed_t on_state_changed,
// true, // true,
// NULL); // NULL);
// nice_agent_set_remote_credentials(agent_, stream_id_, ufrag, password);
nice_agent_attach_recv(agent_, stream_id_, NICE_COMPONENT_TYPE_RTP, nice_agent_attach_recv(agent_, stream_id_, NICE_COMPONENT_TYPE_RTP,
g_main_loop_get_context(gloop_), on_recv_, g_main_loop_get_context(gloop_), on_recv_,
user_ptr_); user_ptr_);
@@ -130,32 +133,11 @@ int IceAgent::DestroyIceAgent() {
return 0; return 0;
} }
int IceAgent::GetLocalCredentials() { char *IceAgent::GetLocalStreamSdp() {
if (!nice_inited_) { stream_sdp_ = nice_agent_generate_local_stream_sdp(agent_, stream_id_, true);
LOG_ERROR("Nice agent has not been initialized"); return stream_sdp_;
return -1;
} }
if (nullptr == agent_) {
LOG_ERROR("Nice agent is nullptr");
return -1;
}
if (destroyed_) {
LOG_ERROR("Nice agent is destroyed");
return -1;
}
nice_agent_get_local_credentials(agent_, stream_id_, &ice_ufrag_,
&ice_password_);
return 0;
}
char *IceAgent::GetLocalUfrag() { return ufrag_; }
char *IceAgent::GetLocalPassword() { return password_; }
char *IceAgent::GenerateLocalSdp() { char *IceAgent::GenerateLocalSdp() {
if (!nice_inited_) { if (!nice_inited_) {
LOG_ERROR("Nice agent has not been initialized"); LOG_ERROR("Nice agent has not been initialized");
@@ -195,41 +177,14 @@ int IceAgent::SetRemoteSdp(const char *remote_sdp) {
} }
int ret = nice_agent_parse_remote_sdp(agent_, remote_sdp); int ret = nice_agent_parse_remote_sdp(agent_, remote_sdp);
if (ret > 0) { if (ret >= 0) {
return 0; return 0;
} else { } else {
LOG_ERROR("Failed to parse remote data: [{}]", remote_sdp); LOG_ERROR("Failed to parse remote sdp: [{}]", remote_sdp);
return -1; return -1;
} }
} }
int IceAgent::AddCandidate(const char *candidate) {
if (!nice_inited_) {
LOG_ERROR("Nice agent has not been initialized");
return -1;
}
if (nullptr == agent_) {
LOG_ERROR("Nice agent is nullptr");
return -1;
}
if (destroyed_) {
LOG_ERROR("Nice agent is destroyed");
return -1;
}
int ret = nice_agent_parse_remote_sdp(agent_, candidate);
if (ret > 0) {
return 0;
} else {
LOG_ERROR("Failed to parse remote candidate: [{}]", candidate);
return -1;
}
return 0;
}
int IceAgent::GatherCandidates() { int IceAgent::GatherCandidates() {
if (!nice_inited_) { if (!nice_inited_) {
LOG_ERROR("Nice agent has not been initialized"); LOG_ERROR("Nice agent has not been initialized");

View File

@@ -29,9 +29,9 @@ typedef void (*nice_cb_recv_t)(NiceAgent* agent, guint stream_id,
class IceAgent { class IceAgent {
public: public:
IceAgent(bool offer_peer, std::string& stun_ip, uint16_t stun_port, IceAgent(bool trickle_ice, bool offer_peer, std::string& stun_ip,
std::string& turn_ip, uint16_t turn_port, std::string& turn_username, uint16_t stun_port, std::string& turn_ip, uint16_t turn_port,
std::string& turn_password); std::string& turn_username, std::string& turn_password);
~IceAgent(); ~IceAgent();
int CreateIceAgent(nice_cb_state_changed_t on_state_changed, int CreateIceAgent(nice_cb_state_changed_t on_state_changed,
@@ -42,18 +42,12 @@ class IceAgent {
int DestroyIceAgent(); int DestroyIceAgent();
int GetLocalCredentials(); char* GetLocalStreamSdp();
char* GetLocalIceUfrag();
char* GetLocalIcePassword();
char* GenerateLocalSdp(); char* GenerateLocalSdp();
int SetRemoteSdp(const char* remote_sdp); int SetRemoteSdp(const char* remote_sdp);
int AddCandidate(const char* candidate);
int GatherCandidates(); int GatherCandidates();
NiceComponentState GetIceState(); NiceComponentState GetIceState();
@@ -76,9 +70,11 @@ class IceAgent {
std::atomic<bool> nice_inited_{false}; std::atomic<bool> nice_inited_{false};
gboolean exit_nice_thread_ = false; gboolean exit_nice_thread_ = false;
bool trickle_ice_ = true;
bool controlling_ = false; bool controlling_ = false;
gchar* ice_ufrag_ = nullptr; gchar* ice_ufrag_ = nullptr;
gchar* ice_password_ = nullptr; gchar* ice_password_ = nullptr;
gchar* stream_sdp_ = nullptr;
uint32_t stream_id_ = 0; uint32_t stream_id_ = 0;
uint32_t n_components_ = 1; uint32_t n_components_ = 1;
char* local_sdp_ = nullptr; char* local_sdp_ = nullptr;

View File

@@ -361,7 +361,7 @@ int PeerConnection::Leave() {
void PeerConnection::ProcessSignal(const std::string &signal) { void PeerConnection::ProcessSignal(const std::string &signal) {
auto j = json::parse(signal); auto j = json::parse(signal);
std::string type = j["type"]; std::string type = j["type"];
LOG_INFO("signal type: {}", type); // LOG_INFO("signal type: {}", type);
switch (HASH_STRING_PIECE(type.c_str())) { switch (HASH_STRING_PIECE(type.c_str())) {
case "ws_connection_id"_H: { case "ws_connection_id"_H: {
ws_connection_id_ = j["ws_connection_id"].get<unsigned int>(); ws_connection_id_ = j["ws_connection_id"].get<unsigned int>();
@@ -425,9 +425,9 @@ void PeerConnection::ProcessSignal(const std::string &signal) {
// continue; // continue;
// } // }
ice_transmission_list_[remote_user_id] = ice_transmission_list_[remote_user_id] =
std::make_unique<IceTransmission>(true, transmission_id, user_id_, std::make_unique<IceTransmission>(
remote_user_id, ws_transport_, trickle_ice_, true, transmission_id, user_id_, remote_user_id,
on_ice_status_change_); ws_transport_, on_ice_status_change_);
ice_transmission_list_[remote_user_id]->SetOnReceiveVideoFunc( ice_transmission_list_[remote_user_id]->SetOnReceiveVideoFunc(
on_receive_video_); on_receive_video_);
@@ -463,13 +463,7 @@ void PeerConnection::ProcessSignal(const std::string &signal) {
break; break;
} }
case "offer"_H: { case "offer"_H: {
std::string remote_sdp = j["sdp"].get<std::string>();
if (remote_sdp.empty()) {
LOG_INFO("Invalid remote sdp");
} else {
std::string transmission_id = j["transmission_id"].get<std::string>(); std::string transmission_id = j["transmission_id"].get<std::string>();
std::string sdp = j["sdp"].get<std::string>();
std::string remote_user_id = j["remote_user_id"].get<std::string>(); std::string remote_user_id = j["remote_user_id"].get<std::string>();
LOG_INFO("[{}] receive offer from [{}]", user_id_, remote_user_id); LOG_INFO("[{}] receive offer from [{}]", user_id_, remote_user_id);
@@ -482,9 +476,9 @@ void PeerConnection::ProcessSignal(const std::string &signal) {
} }
ice_transmission_list_[remote_user_id] = ice_transmission_list_[remote_user_id] =
std::make_unique<IceTransmission>(false, transmission_id, user_id_, std::make_unique<IceTransmission>(
remote_user_id, ws_transport_, trickle_ice_, false, transmission_id, user_id_, remote_user_id,
on_ice_status_change_); ws_transport_, on_ice_status_change_);
ice_transmission_list_[remote_user_id]->SetOnReceiveVideoFunc( ice_transmission_list_[remote_user_id]->SetOnReceiveVideoFunc(
on_receive_video_); on_receive_video_);
@@ -499,51 +493,57 @@ void PeerConnection::ProcessSignal(const std::string &signal) {
av1_encoding_ ? RtpPacket::AV1 : RtpPacket::H264); av1_encoding_ ? RtpPacket::AV1 : RtpPacket::H264);
ice_transmission_list_[remote_user_id]->SetTransmissionId( ice_transmission_list_[remote_user_id]->SetTransmissionId(
transmission_id_); transmission_id_);
ice_transmission_list_[remote_user_id]->SetRemoteSdp(remote_sdp);
ice_transmission_list_[remote_user_id]->GatherCandidates(); if (j.contains("sdp")) {
on_connection_status_(ConnectionStatus::Connecting, user_data_); on_connection_status_(ConnectionStatus::Connecting, user_data_);
std::string remote_sdp = j["sdp"].get<std::string>();
ice_transmission_list_[remote_user_id]->SetRemoteSdp(remote_sdp);
if (trickle_ice_) {
sdp_without_cands_ = remote_sdp;
ice_transmission_list_[remote_user_id]->SendAnswer();
} }
ice_transmission_list_[remote_user_id]->GatherCandidates();
} else {
LOG_ERROR("Invalid offer msg");
}
break; break;
} }
case "answer"_H: { case "answer"_H: {
std::string remote_sdp = j["sdp"].get<std::string>(); on_connection_status_(ConnectionStatus::Connecting, user_data_);
if (remote_sdp.empty()) {
LOG_INFO("remote_sdp is empty");
} else {
std::string transmission_id = j["transmission_id"].get<std::string>(); std::string transmission_id = j["transmission_id"].get<std::string>();
std::string sdp = j["sdp"].get<std::string>();
std::string remote_user_id = j["remote_user_id"].get<std::string>(); std::string remote_user_id = j["remote_user_id"].get<std::string>();
if (j.contains("sdp")) {
LOG_INFO("[{}] receive answer from [{}]", user_id_, remote_user_id); std::string remote_sdp = j["sdp"].get<std::string>();
if (ice_transmission_list_.find(remote_user_id) != if (ice_transmission_list_.find(remote_user_id) !=
ice_transmission_list_.end()) { ice_transmission_list_.end()) {
ice_transmission_list_[remote_user_id]->SetRemoteSdp(remote_sdp); ice_transmission_list_[remote_user_id]->SetRemoteSdp(remote_sdp);
if (trickle_ice_) {
sdp_without_cands_ = remote_sdp;
ice_transmission_list_[remote_user_id]->GatherCandidates();
}
}
} else {
LOG_ERROR("Invalid answer msg");
} }
on_connection_status_(ConnectionStatus::Connecting, user_data_);
}
break; break;
} }
case "offer_candidate"_H: { case "new_candidate"_H: {
std::string transmission_id = j["transmission_id"].get<std::string>(); std::string transmission_id = j["transmission_id"].get<std::string>();
std::string new_candidate = j["sdp"].get<std::string>(); std::string new_candidate = j["sdp"].get<std::string>();
std::string remote_user_id = j["remote_user_id"].get<std::string>(); std::string remote_user_id = j["remote_user_id"].get<std::string>();
LOG_INFO("[{}] receive new candidate from [{}]", user_id_, // LOG_INFO("[{}] receive new candidate from [{}]:[{}]", user_id_,
remote_user_id); // remote_user_id, new_candidate);
if (ice_transmission_list_.find(remote_user_id) != if (ice_transmission_list_.find(remote_user_id) !=
ice_transmission_list_.end()) { ice_transmission_list_.end()) {
ice_transmission_list_[remote_user_id]->AddCandidate(new_candidate); ice_transmission_list_[remote_user_id]->SetRemoteSdp(
sdp_without_cands_ + new_candidate);
} }
break; break;
} }
case "answer_candidate"_H: {
std::string transmission_id = j["transmission_id"].get<std::string>();
std::string new_candidate = j["sdp"].get<std::string>();
break;
}
default: { default: {
break; break;
} }

View File

@@ -97,6 +97,7 @@ class PeerConnection {
int turn_server_port_ = 0; int turn_server_port_ = 0;
bool hardware_acceleration_ = false; bool hardware_acceleration_ = false;
bool av1_encoding_ = false; bool av1_encoding_ = false;
bool trickle_ice_ = true;
private: private:
std::shared_ptr<WsTransmission> ws_transport_ = nullptr; std::shared_ptr<WsTransmission> ws_transport_ = nullptr;
@@ -109,6 +110,7 @@ class PeerConnection {
SignalStatus signal_status_ = SignalStatus::SignalClosed; SignalStatus signal_status_ = SignalStatus::SignalClosed;
std::mutex signal_status_mutex_; std::mutex signal_status_mutex_;
std::atomic<bool> leave_{false}; std::atomic<bool> leave_{false};
std::string sdp_without_cands_ = "";
private: private:
std::map<std::string, std::unique_ptr<IceTransmission>> std::map<std::string, std::unique_ptr<IceTransmission>>

View File

@@ -12,11 +12,12 @@
using nlohmann::json; using nlohmann::json;
IceTransmission::IceTransmission( IceTransmission::IceTransmission(
bool offer_peer, std::string &transmission_id, std::string &user_id, bool trickle_ice, bool offer_peer, std::string &transmission_id,
std::string &remote_user_id, std::string &user_id, std::string &remote_user_id,
std::shared_ptr<WsTransmission> ice_ws_transmission, std::shared_ptr<WsTransmission> ice_ws_transmission,
std::function<void(std::string)> on_ice_status_change) std::function<void(std::string)> on_ice_status_change)
: offer_peer_(offer_peer), : trickle_ice_(trickle_ice),
offer_peer_(offer_peer),
transmission_id_(transmission_id), transmission_id_(transmission_id),
user_id_(user_id), user_id_(user_id),
remote_user_id_(remote_user_id), remote_user_id_(remote_user_id),
@@ -147,9 +148,9 @@ int IceTransmission::InitIceTransmission(
remote_user_id_.size()); remote_user_id_.size());
}); });
ice_agent_ = ice_agent_ = std::make_unique<IceAgent>(trickle_ice_, offer_peer_, stun_ip,
std::make_unique<IceAgent>(offer_peer_, stun_ip, stun_port, turn_ip, stun_port, turn_ip, turn_port,
turn_port, turn_username, turn_password); turn_username, turn_password);
ice_agent_->CreateIceAgent( ice_agent_->CreateIceAgent(
[](NiceAgent *agent, guint stream_id, guint component_id, [](NiceAgent *agent, guint stream_id, guint component_id,
@@ -180,16 +181,18 @@ int IceTransmission::InitIceTransmission(
cand = (NiceCandidate *)i->data; cand = (NiceCandidate *)i->data;
if (g_strcmp0(cand->foundation, foundation) == 0) { if (g_strcmp0(cand->foundation, foundation) == 0) {
ice_transmission_obj->new_local_candidate_ = ice_transmission_obj->new_local_candidate_ =
nice_agent_generate_local_sdp(agent); nice_agent_generate_local_candidate_sdp(agent, cand);
json message = { json message = {
{"type", "offer_candidate"}, {"type", "new_candidate"},
{"transmission_id", ice_transmission_obj->transmission_id_}, {"transmission_id", ice_transmission_obj->transmission_id_},
{"user_id", ice_transmission_obj->user_id_}, {"user_id", ice_transmission_obj->user_id_},
{"remote_user_id", ice_transmission_obj->remote_user_id_}, {"remote_user_id", ice_transmission_obj->remote_user_id_},
{"sdp", ice_transmission_obj->new_local_candidate_}}; {"sdp", ice_transmission_obj->new_local_candidate_}};
LOG_INFO("Send new local candidate sdp:[{}]", // LOG_INFO("[{}] Send new candidate to [{}]]:[{}]",
ice_transmission_obj->new_local_candidate_); // ice_transmission_obj->user_id_,
// ice_transmission_obj->remote_user_id_,
// ice_transmission_obj->new_local_candidate_);
if (ice_transmission_obj->ice_ws_transport_) { if (ice_transmission_obj->ice_ws_transport_) {
ice_transmission_obj->ice_ws_transport_->Send(message.dump()); ice_transmission_obj->ice_ws_transport_->Send(message.dump());
@@ -202,20 +205,19 @@ int IceTransmission::InitIceTransmission(
}, },
[](NiceAgent *agent, guint stream_id, gpointer user_ptr) { [](NiceAgent *agent, guint stream_id, gpointer user_ptr) {
// non-trickle // non-trickle
// if (user_ptr) { if (user_ptr) {
// IceTransmission *ice_transmission_obj = IceTransmission *ice_transmission_obj =
// static_cast<IceTransmission *>(user_ptr); static_cast<IceTransmission *>(user_ptr);
// LOG_INFO("[{}] gather_done", ice_transmission_obj->user_id_); LOG_INFO("[{}] gather_done", ice_transmission_obj->user_id_);
// if (ice_transmission_obj->offer_peer_) { if (!ice_transmission_obj->trickle_ice_) {
// ice_transmission_obj->GetLocalSdp(); if (ice_transmission_obj->offer_peer_) {
// ice_transmission_obj->SendOffer(); ice_transmission_obj->SendOffer();
} else {
// } else { ice_transmission_obj->SendAnswer();
// ice_transmission_obj->CreateAnswer(); }
// ice_transmission_obj->SendAnswer(); }
// } }
// }
}, },
[](NiceAgent *agent, guint stream_id, guint component_id, [](NiceAgent *agent, guint stream_id, guint component_id,
const char *lfoundation, const char *rfoundation, gpointer user_ptr) { const char *lfoundation, const char *rfoundation, gpointer user_ptr) {
@@ -265,23 +267,19 @@ int IceTransmission::SetTransmissionId(const std::string &transmission_id) {
int IceTransmission::JoinTransmission() { int IceTransmission::JoinTransmission() {
LOG_INFO("[{}] Join transmission", user_id_); LOG_INFO("[{}] Join transmission", user_id_);
CreateOffer(); if (trickle_ice_) {
SendOffer();
} else {
GatherCandidates();
}
return 0; return 0;
} }
int IceTransmission::GatherCandidates() { int IceTransmission::GatherCandidates() {
int ret = ice_agent_->GatherCandidates(); int ret = ice_agent_->GatherCandidates();
while (ret) { if (ret < 0) {
LOG_ERROR("Gather candidates failed, retry"); LOG_ERROR("Gather candidates failed");
ret = ice_agent_->GatherCandidates();
} }
LOG_INFO("[{}] Gather candidates", user_id_);
return 0;
}
int IceTransmission::GetLocalSdp() {
local_sdp_ = ice_agent_->GenerateLocalSdp();
LOG_INFO("[{}] generate local sdp", user_id_);
return 0; return 0;
} }
@@ -292,47 +290,14 @@ int IceTransmission::SetRemoteSdp(const std::string &remote_sdp) {
return 0; return 0;
} }
int IceTransmission::AddCandidate(const std::string &candidate) {
ice_agent_->AddCandidate(candidate.c_str());
LOG_INFO("[{}] add candidate", user_id_);
return 0;
}
int IceTransmission::CreateOffer() {
LOG_INFO("[{}] create offer", user_id_);
GatherCandidates();
if (trickle_ice_) {
SendLocalCredentials();
}
return 0;
}
int IceTransmission::SendLocalCredentials() {
ice_agent_->GetLocalIceUfrag();
ice_agent_->GetLocalIcePassword();
json message = {{"type", "credentials"},
{"transmission_id", transmission_id_},
{"user_id", user_id_},
{"remote_user_id", remote_user_id_},
{"ufrag", ice_agent_->GetLocalIceUfrag()},
{"password", ice_agent_->GetLocalIcePassword()}};
LOG_INFO("Send credentials:\n{}", message.dump());
if (ice_ws_transport_) {
ice_ws_transport_->Send(message.dump());
}
return 0;
}
int IceTransmission::SendOffer() { int IceTransmission::SendOffer() {
json message = {{"type", "offer"}, json message = {{"type", "offer"},
{"transmission_id", transmission_id_}, {"transmission_id", transmission_id_},
{"user_id", user_id_}, {"user_id", user_id_},
{"remote_user_id", remote_user_id_}, {"remote_user_id", remote_user_id_},
{"sdp", local_sdp_}}; {"sdp", trickle_ice_ ? ice_agent_->GetLocalStreamSdp()
// LOG_INFO("Send offer:\n{}", message.dump()); : ice_agent_->GenerateLocalSdp()}};
// LOG_INFO("Send offer with sdp:[{}]", message.dump());
if (ice_ws_transport_) { if (ice_ws_transport_) {
ice_ws_transport_->Send(message.dump()); ice_ws_transport_->Send(message.dump());
@@ -341,22 +306,19 @@ int IceTransmission::SendOffer() {
return 0; return 0;
} }
int IceTransmission::CreateAnswer() {
GetLocalSdp();
return 0;
}
int IceTransmission::SendAnswer() { int IceTransmission::SendAnswer() {
json message = {{"type", "answer"}, json message = {{"type", "answer"},
{"transmission_id", transmission_id_}, {"transmission_id", transmission_id_},
{"sdp", local_sdp_},
{"user_id", user_id_}, {"user_id", user_id_},
{"remote_user_id", remote_user_id_}}; {"remote_user_id", remote_user_id_},
{"sdp", trickle_ice_ ? ice_agent_->GetLocalStreamSdp()
: ice_agent_->GenerateLocalSdp()}};
// LOG_INFO("Send answer with sdp:[{}]", message.dump());
if (ice_ws_transport_) { if (ice_ws_transport_) {
ice_ws_transport_->Send(message.dump()); ice_ws_transport_->Send(message.dump());
LOG_INFO("[{}->{}] send answer", user_id_, remote_user_id_); LOG_INFO("[{}->{}] send answer", user_id_, remote_user_id_);
} }
return 0; return 0;
} }

View File

@@ -32,8 +32,9 @@ class IceTransmission {
}; };
public: public:
IceTransmission(bool offer_peer, std::string &transmission_id, IceTransmission(bool trickle_ice, bool offer_peer,
std::string &user_id, std::string &remote_user_id, std::string &transmission_id, std::string &user_id,
std::string &remote_user_id,
std::shared_ptr<WsTransmission> ice_ws_transmission, std::shared_ptr<WsTransmission> ice_ws_transmission,
std::function<void(std::string)> on_ice_status_change); std::function<void(std::string)> on_ice_status_change);
~IceTransmission(); ~IceTransmission();
@@ -80,20 +81,12 @@ class IceTransmission {
public: public:
int GatherCandidates(); int GatherCandidates();
int SendLocalCredentials(); int SendLocalStreamSdp();
int GetLocalSdp();
int SetRemoteSdp(const std::string &remote_sdp); int SetRemoteSdp(const std::string &remote_sdp);
int AddCandidate(const std::string &candidate);
int CreateOffer();
int SendOffer(); int SendOffer();
int CreateAnswer();
int SendAnswer(); int SendAnswer();
private: private: