mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
Init project
This commit is contained in:
124
src/ice/ice_agent.cpp
Normal file
124
src/ice/ice_agent.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "ice_agent.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
IceAgent::IceAgent() {}
|
||||
|
||||
IceAgent::~IceAgent() {}
|
||||
|
||||
int IceAgent::CreateIceAgent(juice_cb_state_changed_t on_state_changed,
|
||||
juice_cb_candidate_t on_candidate,
|
||||
juice_cb_gathering_done_t on_gathering_done,
|
||||
juice_cb_recv_t on_recv, void *user_ptr) {
|
||||
// juice_set_log_level(JUICE_LOG_LEVEL_DEBUG);
|
||||
|
||||
juice_config_t config;
|
||||
memset(&config, 0, sizeof(config));
|
||||
|
||||
// STUN server example
|
||||
config.stun_server_host = "120.77.216.215";
|
||||
config.stun_server_port = 3478;
|
||||
|
||||
config.cb_state_changed = on_state_changed;
|
||||
config.cb_candidate = on_candidate;
|
||||
config.cb_gathering_done = on_gathering_done;
|
||||
config.cb_recv = on_recv;
|
||||
config.user_ptr = user_ptr;
|
||||
|
||||
agent_ = juice_create(&config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceAgent::DestoryIceAgent() {
|
||||
juice_destroy(agent_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *IceAgent::GenerateLocalSdp() {
|
||||
if (nullptr == agent_) {
|
||||
LOG_INFO("agent_ is nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
juice_get_local_description(agent_, local_sdp_, JUICE_MAX_SDP_STRING_LEN);
|
||||
LOG_INFO("Generate local sdp:[\n{}]", local_sdp_);
|
||||
|
||||
return local_sdp_;
|
||||
}
|
||||
|
||||
int IceAgent::SetRemoteSdp(const char *remote_sdp) {
|
||||
LOG_INFO("Set remote sdp");
|
||||
juice_set_remote_description(agent_, remote_sdp);
|
||||
LOG_INFO("Remote description:[\n{}]", remote_sdp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceAgent::GatherCandidates() {
|
||||
LOG_INFO("Gather candidates");
|
||||
juice_gather_candidates(agent_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
juice_state_t IceAgent::GetIceState() {
|
||||
state_ = juice_get_state(agent_);
|
||||
|
||||
return state_;
|
||||
}
|
||||
|
||||
bool IceAgent::GetSelectedCandidates() {
|
||||
char local[JUICE_MAX_CANDIDATE_SDP_STRING_LEN];
|
||||
char remote[JUICE_MAX_CANDIDATE_SDP_STRING_LEN];
|
||||
|
||||
bool success = state_ == JUICE_STATE_COMPLETED;
|
||||
if (success &= (juice_get_selected_candidates(
|
||||
agent_, local, JUICE_MAX_CANDIDATE_SDP_STRING_LEN, remote,
|
||||
JUICE_MAX_CANDIDATE_SDP_STRING_LEN) == 0)) {
|
||||
LOG_INFO("Local candidate 1: {}", local);
|
||||
LOG_INFO("Remote candidate 1: {}", remote);
|
||||
if ((!strstr(local, "typ host") && !strstr(local, "typ prflx")) ||
|
||||
(!strstr(remote, "typ host") && !strstr(remote, "typ prflx")))
|
||||
success = false; // local connection should be possible
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool IceAgent::GetSelectedAddresses() {
|
||||
char localAddr[JUICE_MAX_ADDRESS_STRING_LEN];
|
||||
char remoteAddr[JUICE_MAX_ADDRESS_STRING_LEN];
|
||||
|
||||
bool success = state_ == JUICE_STATE_COMPLETED;
|
||||
if (success &= (juice_get_selected_addresses(
|
||||
agent_, localAddr, JUICE_MAX_ADDRESS_STRING_LEN,
|
||||
remoteAddr, JUICE_MAX_ADDRESS_STRING_LEN) == 0)) {
|
||||
LOG_INFO("Local address 1: {}", localAddr);
|
||||
LOG_INFO("Remote address 1: {}", remoteAddr);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
int IceAgent::AddRemoteCandidates(const char *remote_candidates) {
|
||||
juice_add_remote_candidate(agent_, remote_candidates);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceAgent::SetRemoteGatheringDone() {
|
||||
juice_set_remote_gathering_done(agent_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceAgent::Send(const char *data, size_t size) {
|
||||
juice_send(agent_, data, size);
|
||||
return 0;
|
||||
}
|
||||
42
src/ice/ice_agent.h
Normal file
42
src/ice/ice_agent.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef _ICE_AGENT_H_
|
||||
#define _ICE_AGENT_H_
|
||||
|
||||
#include "juice/juice.h"
|
||||
|
||||
class IceAgent {
|
||||
public:
|
||||
IceAgent();
|
||||
~IceAgent();
|
||||
|
||||
int CreateIceAgent(juice_cb_state_changed_t on_state_changed,
|
||||
juice_cb_candidate_t on_candidate,
|
||||
juice_cb_gathering_done_t on_gathering_done,
|
||||
juice_cb_recv_t on_recv, void* user_ptr);
|
||||
|
||||
int DestoryIceAgent();
|
||||
|
||||
char* GenerateLocalSdp();
|
||||
|
||||
int SetRemoteSdp(const char* remote_sdp);
|
||||
|
||||
int GatherCandidates();
|
||||
|
||||
juice_state_t GetIceState();
|
||||
|
||||
bool GetSelectedCandidates();
|
||||
|
||||
bool GetSelectedAddresses();
|
||||
|
||||
int AddRemoteCandidates(const char* remote_candidates);
|
||||
|
||||
int SetRemoteGatheringDone();
|
||||
|
||||
int Send(const char* data, size_t size);
|
||||
|
||||
private:
|
||||
juice_agent_t* agent_ = nullptr;
|
||||
char local_sdp_[JUICE_MAX_SDP_STRING_LEN];
|
||||
juice_state_t state_;
|
||||
};
|
||||
|
||||
#endif
|
||||
267
src/ice/ice_transport.cpp
Normal file
267
src/ice/ice_transport.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
#include "ice_transport.h"
|
||||
|
||||
#include <map>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
static const std::map<std::string, unsigned int> siganl_types{
|
||||
{"connection_id", 1},
|
||||
{"offer", 2},
|
||||
{"transport_id", 3},
|
||||
{"remote_sdp", 4},
|
||||
{"candidate", 5}};
|
||||
|
||||
const std::vector<std::string> ice_status = {
|
||||
"JUICE_STATE_DISCONNECTED", "JUICE_STATE_GATHERING",
|
||||
"JUICE_STATE_CONNECTING", "JUICE_STATE_CONNECTED",
|
||||
"JUICE_STATE_COMPLETED", "JUICE_STATE_FAILED"};
|
||||
|
||||
IceTransport::IceTransport(
|
||||
WsTransport *ice_ws_transport,
|
||||
std::function<void(const char *, size_t)> on_receive_ice_msg)
|
||||
: ice_ws_transport_(ice_ws_transport),
|
||||
on_receive_ice_msg_cb_(on_receive_ice_msg) {}
|
||||
|
||||
IceTransport::~IceTransport() {}
|
||||
|
||||
int IceTransport::InitIceTransport() {
|
||||
ice_agent_ = new IceAgent();
|
||||
|
||||
ice_agent_->CreateIceAgent(
|
||||
[](juice_agent_t *agent, juice_state_t state, void *user_ptr) {
|
||||
LOG_INFO("state_change: {}", ice_status[state]);
|
||||
},
|
||||
[](juice_agent_t *agent, const char *sdp, void *user_ptr) {
|
||||
LOG_INFO("candadite: {}", sdp);
|
||||
// trickle
|
||||
// static_cast<IceTransport
|
||||
// *>(user_ptr)->SendOfferLocalCandidate(sdp);
|
||||
},
|
||||
[](juice_agent_t *agent, void *user_ptr) {
|
||||
LOG_INFO("gather_done");
|
||||
// non-trickle
|
||||
if (user_ptr) {
|
||||
static_cast<IceTransport *>(user_ptr)->GetLocalSdp();
|
||||
static_cast<IceTransport *>(user_ptr)->SendOffer();
|
||||
}
|
||||
},
|
||||
[](juice_agent_t *agent, const char *data, size_t size, void *user_ptr) {
|
||||
LOG_INFO("on_recv");
|
||||
if (user_ptr &&
|
||||
static_cast<IceTransport *>(user_ptr)->on_receive_ice_msg_cb_) {
|
||||
static_cast<IceTransport *>(user_ptr)->on_receive_ice_msg_cb_(data,
|
||||
size);
|
||||
}
|
||||
},
|
||||
this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::InitIceTransport(std::string const &id) {
|
||||
transport_id_ = id;
|
||||
|
||||
ice_agent_->CreateIceAgent(
|
||||
[](juice_agent_t *agent, juice_state_t state, void *user_ptr) {
|
||||
LOG_INFO("state_change: {}", ice_status[state]);
|
||||
},
|
||||
[](juice_agent_t *agent, const char *sdp, void *user_ptr) {
|
||||
LOG_INFO("candadite: {}", sdp);
|
||||
// trickle
|
||||
// static_cast<PeerConnection
|
||||
// *>(user_ptr)->SendAnswerLocalCandidate(sdp);
|
||||
},
|
||||
[](juice_agent_t *agent, void *user_ptr) {
|
||||
LOG_INFO("gather_done");
|
||||
// non-trickle
|
||||
if (user_ptr) {
|
||||
static_cast<IceTransport *>(user_ptr)->CreateAnswer();
|
||||
static_cast<IceTransport *>(user_ptr)->SendAnswer();
|
||||
}
|
||||
},
|
||||
[](juice_agent_t *agent, const char *data, size_t size, void *user_ptr) {
|
||||
LOG_INFO("on_recv");
|
||||
if (user_ptr &&
|
||||
static_cast<IceTransport *>(user_ptr)->on_receive_ice_msg_cb_) {
|
||||
static_cast<IceTransport *>(user_ptr)->on_receive_ice_msg_cb_(data,
|
||||
size);
|
||||
}
|
||||
},
|
||||
this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::DestroyIceTransport() {
|
||||
if (ice_agent_) {
|
||||
delete ice_agent_;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::CreateTransport() {
|
||||
LOG_INFO("Create transport");
|
||||
offer_peer_ = true;
|
||||
|
||||
// if (SignalStatus::Connected != signal_status_) {
|
||||
// LOG_ERROR("Not connect to signalserver");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
json message = {{"type", "create_transport"}};
|
||||
if (ice_ws_transport_) {
|
||||
ice_ws_transport_->Send(message.dump());
|
||||
LOG_INFO("Send msg: {}", message.dump().c_str());
|
||||
}
|
||||
|
||||
CreateOffer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::CreateTransport(std::string transport_id) {
|
||||
LOG_INFO("Join transport");
|
||||
offer_peer_ = false;
|
||||
|
||||
// if (SignalStatus::Connected != signal_status_) {
|
||||
// LOG_ERROR("Not connect to signalserver");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
QueryRemoteSdp(transport_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::GatherCandidates() {
|
||||
ice_agent_->GatherCandidates();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::GetLocalSdp() {
|
||||
local_sdp_ = ice_agent_->GenerateLocalSdp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::SetRemoteSdp(const std::string &remote_sdp) {
|
||||
ice_agent_->SetRemoteSdp(remote_sdp.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::AddRemoteCandidate(const std::string &remote_candidate) {
|
||||
ice_agent_->AddRemoteCandidates(remote_candidate.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::CreateOffer() {
|
||||
LOG_INFO("Create offer");
|
||||
GatherCandidates();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::SendOffer() {
|
||||
json message = {
|
||||
{"type", "offer"}, {"transport_id", transport_id_}, {"sdp", local_sdp_}};
|
||||
LOG_INFO("Send offer:\n{}", message.dump().c_str());
|
||||
|
||||
if (ice_ws_transport_) {
|
||||
ice_ws_transport_->Send(message.dump());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::QueryRemoteSdp(std::string transport_id) {
|
||||
json message = {{"type", "query_remote_sdp"},
|
||||
{"transport_id", transport_id_}};
|
||||
LOG_INFO("Query remote sdp");
|
||||
|
||||
if (ice_ws_transport_) {
|
||||
ice_ws_transport_->Send(message.dump());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::CreateAnswer() {
|
||||
GetLocalSdp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::SendAnswer() {
|
||||
json message = {
|
||||
{"type", "answer"}, {"transport_id", transport_id_}, {"sdp", local_sdp_}};
|
||||
LOG_INFO("Send answer:\n{}", message.dump().c_str());
|
||||
|
||||
if (ice_ws_transport_) {
|
||||
ice_ws_transport_->Send(message.dump());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::SendOfferLocalCandidate(const std::string &remote_candidate) {
|
||||
json message = {{"type", "offer_candidate"},
|
||||
{"transport_id", transport_id_},
|
||||
{"sdp", remote_candidate}};
|
||||
LOG_INFO("Send candidate:\n{}", message.dump().c_str());
|
||||
|
||||
if (ice_ws_transport_) {
|
||||
ice_ws_transport_->Send(message.dump());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::SendAnswerLocalCandidate(
|
||||
const std::string &remote_candidate) {
|
||||
json message = {{"type", "answer_candidate"},
|
||||
{"transport_id", transport_id_},
|
||||
{"sdp", remote_candidate}};
|
||||
LOG_INFO("Send candidate:\n{}", message.dump().c_str());
|
||||
|
||||
if (ice_ws_transport_) {
|
||||
ice_ws_transport_->Send(message.dump());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransport::SendData(const char *data, size_t size) {
|
||||
ice_agent_->Send(data, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void IceTransport::OnReceiveMessage(const std::string &msg) {
|
||||
auto j = json::parse(msg);
|
||||
LOG_INFO("msg: {}", msg.c_str());
|
||||
|
||||
std::string type = j["type"];
|
||||
auto itr = siganl_types.find(type);
|
||||
if (itr != siganl_types.end()) {
|
||||
LOG_INFO("msg type :{}", itr->first);
|
||||
switch (itr->second) {
|
||||
case 2: {
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
transport_id_ = j["transport_id"].get<std::string>();
|
||||
LOG_INFO("Receive local peer transport_id [{}]", transport_id_);
|
||||
// SendOffer();
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
remote_sdp_ = j["sdp"].get<std::string>();
|
||||
LOG_INFO("Receive remote sdp [{}]", remote_sdp_);
|
||||
SetRemoteSdp(remote_sdp_);
|
||||
|
||||
if (!offer_peer_) {
|
||||
GatherCandidates();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
std::string candidate = j["sdp"].get<std::string>();
|
||||
LOG_INFO("Receive candidate [{}]", candidate);
|
||||
AddRemoteCandidate(candidate);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/ice/ice_transport.h
Normal file
66
src/ice/ice_transport.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef _ICE_TRANSPORT_H_
|
||||
#define _ICE_TRANSPORT_H_
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "ice_agent.h"
|
||||
#include "ws_transport.h"
|
||||
|
||||
class IceTransport {
|
||||
public:
|
||||
IceTransport(WsTransport *ice_ws_transport,
|
||||
std::function<void(const char *, size_t)> on_receive_ice_msg);
|
||||
|
||||
~IceTransport();
|
||||
|
||||
int InitIceTransport();
|
||||
int InitIceTransport(std::string const &id);
|
||||
|
||||
int DestroyIceTransport();
|
||||
|
||||
int CreateTransport();
|
||||
int CreateTransport(std::string transport_id);
|
||||
|
||||
int SendData(const char *data, size_t size);
|
||||
|
||||
void OnReceiveUserData(const char *data, size_t size);
|
||||
|
||||
void OnReceiveMessage(const std::string &msg);
|
||||
|
||||
private:
|
||||
int GatherCandidates();
|
||||
|
||||
int GetLocalSdp();
|
||||
|
||||
int QueryRemoteSdp(std::string transport_id);
|
||||
|
||||
int SetRemoteSdp(const std::string &remote_sdp);
|
||||
|
||||
int AddRemoteCandidate(const std::string &remote_candidate);
|
||||
|
||||
int CreateOffer();
|
||||
|
||||
int SendOffer();
|
||||
|
||||
int CreateAnswer();
|
||||
|
||||
int SendAnswer();
|
||||
|
||||
int SendOfferLocalCandidate(const std::string &remote_candidate);
|
||||
|
||||
int SendAnswerLocalCandidate(const std::string &remote_candidate);
|
||||
|
||||
private:
|
||||
IceAgent *ice_agent_ = nullptr;
|
||||
WsTransport *ice_ws_transport_ = nullptr;
|
||||
std::function<void(const char *, size_t)> on_receive_ice_msg_cb_ = nullptr;
|
||||
std::string local_sdp_;
|
||||
std::string remote_sdp_;
|
||||
std::string local_candidates_;
|
||||
std::string remote_candidates_;
|
||||
unsigned int connection_id_ = 0;
|
||||
std::string transport_id_ = "";
|
||||
bool offer_peer_ = true;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user