mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 20:25:34 +08:00
[feat] Support trickle ice
This commit is contained in:
@@ -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");
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,87 +463,87 @@ void PeerConnection::ProcessSignal(const std::string &signal) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "offer"_H: {
|
case "offer"_H: {
|
||||||
std::string remote_sdp = j["sdp"].get<std::string>();
|
std::string transmission_id = j["transmission_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);
|
||||||
|
|
||||||
if (remote_sdp.empty()) {
|
if (0 != CreateVideoCodec(hardware_acceleration_)) {
|
||||||
LOG_INFO("Invalid remote sdp");
|
LOG_ERROR("Create video codec failed");
|
||||||
} else {
|
|
||||||
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>();
|
|
||||||
LOG_INFO("[{}] receive offer from [{}]", user_id_, remote_user_id);
|
|
||||||
|
|
||||||
if (0 != CreateVideoCodec(hardware_acceleration_)) {
|
|
||||||
LOG_ERROR("Create video codec failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != CreateAudioCodec()) {
|
|
||||||
LOG_ERROR("Create audio codec failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
ice_transmission_list_[remote_user_id] =
|
|
||||||
std::make_unique<IceTransmission>(false, transmission_id, user_id_,
|
|
||||||
remote_user_id, ws_transport_,
|
|
||||||
on_ice_status_change_);
|
|
||||||
|
|
||||||
ice_transmission_list_[remote_user_id]->SetOnReceiveVideoFunc(
|
|
||||||
on_receive_video_);
|
|
||||||
ice_transmission_list_[remote_user_id]->SetOnReceiveAudioFunc(
|
|
||||||
on_receive_audio_);
|
|
||||||
ice_transmission_list_[remote_user_id]->SetOnReceiveDataFunc(
|
|
||||||
on_receive_data_);
|
|
||||||
ice_transmission_list_[remote_user_id]->InitIceTransmission(
|
|
||||||
cfg_stun_server_ip_, stun_server_port_, cfg_turn_server_ip_,
|
|
||||||
turn_server_port_, cfg_turn_server_username_,
|
|
||||||
cfg_turn_server_password_,
|
|
||||||
av1_encoding_ ? RtpPacket::AV1 : RtpPacket::H264);
|
|
||||||
ice_transmission_list_[remote_user_id]->SetTransmissionId(
|
|
||||||
transmission_id_);
|
|
||||||
ice_transmission_list_[remote_user_id]->SetRemoteSdp(remote_sdp);
|
|
||||||
ice_transmission_list_[remote_user_id]->GatherCandidates();
|
|
||||||
on_connection_status_(ConnectionStatus::Connecting, user_data_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (0 != CreateAudioCodec()) {
|
||||||
|
LOG_ERROR("Create audio codec failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
ice_transmission_list_[remote_user_id] =
|
||||||
|
std::make_unique<IceTransmission>(
|
||||||
|
trickle_ice_, false, transmission_id, user_id_, remote_user_id,
|
||||||
|
ws_transport_, on_ice_status_change_);
|
||||||
|
|
||||||
|
ice_transmission_list_[remote_user_id]->SetOnReceiveVideoFunc(
|
||||||
|
on_receive_video_);
|
||||||
|
ice_transmission_list_[remote_user_id]->SetOnReceiveAudioFunc(
|
||||||
|
on_receive_audio_);
|
||||||
|
ice_transmission_list_[remote_user_id]->SetOnReceiveDataFunc(
|
||||||
|
on_receive_data_);
|
||||||
|
ice_transmission_list_[remote_user_id]->InitIceTransmission(
|
||||||
|
cfg_stun_server_ip_, stun_server_port_, cfg_turn_server_ip_,
|
||||||
|
turn_server_port_, cfg_turn_server_username_,
|
||||||
|
cfg_turn_server_password_,
|
||||||
|
av1_encoding_ ? RtpPacket::AV1 : RtpPacket::H264);
|
||||||
|
ice_transmission_list_[remote_user_id]->SetTransmissionId(
|
||||||
|
transmission_id_);
|
||||||
|
|
||||||
|
if (j.contains("sdp")) {
|
||||||
|
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()) {
|
std::string transmission_id = j["transmission_id"].get<std::string>();
|
||||||
LOG_INFO("remote_sdp is empty");
|
std::string remote_user_id = j["remote_user_id"].get<std::string>();
|
||||||
} else {
|
if (j.contains("sdp")) {
|
||||||
std::string transmission_id = j["transmission_id"].get<std::string>();
|
std::string remote_sdp = j["sdp"].get<std::string>();
|
||||||
std::string sdp = j["sdp"].get<std::string>();
|
|
||||||
std::string remote_user_id = j["remote_user_id"].get<std::string>();
|
|
||||||
|
|
||||||
LOG_INFO("[{}] receive answer from [{}]", user_id_, remote_user_id);
|
|
||||||
|
|
||||||
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 {
|
||||||
on_connection_status_(ConnectionStatus::Connecting, user_data_);
|
LOG_ERROR("Invalid answer msg");
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>>
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user