Browse Source

Merge pull request #47 from murat-dogan/master

Get Selected Candidate Pair Info
Paul-Louis Ageneau 5 years ago
parent
commit
7c667cafee

+ 15 - 0
include/rtc/candidate.hpp

@@ -25,6 +25,17 @@
 
 
 namespace rtc {
 namespace rtc {
 
 
+#if not USE_JUICE
+enum class CandidateType { Host = 0, ServerReflexive, PeerReflexive, Relayed };
+enum class CandidateTransportType { Udp = 0, TcpActive, TcpPassive, TcpSo };
+struct CandidateInfo {
+	string address;
+	int port;
+	CandidateType type;
+	CandidateTransportType transportType;
+};
+#endif
+
 class Candidate {
 class Candidate {
 public:
 public:
 	Candidate(string candidate, string mid = "");
 	Candidate(string candidate, string mid = "");
@@ -46,6 +57,10 @@ private:
 } // namespace rtc
 } // namespace rtc
 
 
 std::ostream &operator<<(std::ostream &out, const rtc::Candidate &candidate);
 std::ostream &operator<<(std::ostream &out, const rtc::Candidate &candidate);
+#if not USE_JUICE
+std::ostream &operator<<(std::ostream &out, const rtc::CandidateType &type);
+std::ostream &operator<<(std::ostream &out, const rtc::CandidateTransportType &transportType);
+#endif
 
 
 #endif
 #endif
 
 

+ 4 - 0
include/rtc/peerconnection.hpp

@@ -87,6 +87,10 @@ public:
 	void onStateChange(std::function<void(State state)> callback);
 	void onStateChange(std::function<void(State state)> callback);
 	void onGatheringStateChange(std::function<void(GatheringState state)> callback);
 	void onGatheringStateChange(std::function<void(GatheringState state)> callback);
 
 
+#if not USE_JUICE
+	bool getSelectedCandidatePair(CandidateInfo *local, CandidateInfo *remote);
+#endif
+
 private:
 private:
 	init_token mInitToken = Init::Token();
 	init_token mInitToken = Init::Token();
 
 

+ 32 - 0
src/candidate.cpp

@@ -131,3 +131,35 @@ Candidate::operator string() const {
 std::ostream &operator<<(std::ostream &out, const rtc::Candidate &candidate) {
 std::ostream &operator<<(std::ostream &out, const rtc::Candidate &candidate) {
 	return out << std::string(candidate);
 	return out << std::string(candidate);
 }
 }
+
+#if not USE_JUICE
+std::ostream &operator<<(std::ostream &out, const rtc::CandidateType &type) {
+	switch (type) {
+	case rtc::CandidateType::Host:
+		return out << "Host";
+	case rtc::CandidateType::PeerReflexive:
+		return out << "PeerReflexive";
+	case rtc::CandidateType::Relayed:
+		return out << "Relayed";
+	case rtc::CandidateType::ServerReflexive:
+		return out << "ServerReflexive";
+	default:
+		return out << "Unknown";
+	}
+}
+
+std::ostream &operator<<(std::ostream &out, const rtc::CandidateTransportType &transportType) {
+	switch (transportType) {
+	case rtc::CandidateTransportType::TcpActive:
+		return out << "TcpActive";
+	case rtc::CandidateTransportType::TcpPassive:
+		return out << "TcpPassive";
+	case rtc::CandidateTransportType::TcpSo:
+		return out << "TcpSo";
+	case rtc::CandidateTransportType::Udp:
+		return out << "Udp";
+	default:
+		return out << "Unknown";
+	}
+}
+#endif

+ 51 - 0
src/icetransport.cpp

@@ -661,6 +661,57 @@ void IceTransport::LogCallback(const gchar *logDomain, GLogLevelFlags logLevel,
 	PLOG(severity) << "nice: " << message;
 	PLOG(severity) << "nice: " << message;
 }
 }
 
 
+bool IceTransport::getSelectedCandidatePair(CandidateInfo *localInfo, CandidateInfo *remoteInfo) {
+	NiceCandidate *local, *remote;
+	gboolean result = nice_agent_get_selected_pair(mNiceAgent.get(), mStreamId, 1, &local, &remote);
+
+	if (!result)
+		return false;
+
+	char ipaddr[INET6_ADDRSTRLEN];
+	nice_address_to_string(&local->addr, ipaddr);
+	localInfo->address = std::string(ipaddr);
+	localInfo->port = nice_address_get_port(&local->addr);
+	localInfo->type = IceTransport::NiceTypeToCandidateType(local->type);
+	localInfo->transportType = IceTransport::NiceTransportTypeToCandidateTransportType(local->transport);
+
+	nice_address_to_string(&remote->addr, ipaddr);
+	remoteInfo->address = std::string(ipaddr);
+	remoteInfo->port = nice_address_get_port(&remote->addr);
+	remoteInfo->type = IceTransport::NiceTypeToCandidateType(remote->type);
+	remoteInfo->transportType = IceTransport::NiceTransportTypeToCandidateTransportType(remote->transport);
+
+	nice_candidate_free(local);
+	nice_candidate_free(remote);
+	return true;
+}
+
+const CandidateType IceTransport::NiceTypeToCandidateType(NiceCandidateType type) {
+	switch (type) {
+	case NiceCandidateType::NICE_CANDIDATE_TYPE_HOST:
+		return CandidateType::Host;
+	case NiceCandidateType::NICE_CANDIDATE_TYPE_PEER_REFLEXIVE:
+		return CandidateType::PeerReflexive;
+	case NiceCandidateType::NICE_CANDIDATE_TYPE_RELAYED:
+		return CandidateType::Relayed;
+	case NiceCandidateType::NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE:
+		return CandidateType::ServerReflexive;
+	}
+}
+
+const CandidateTransportType IceTransport::NiceTransportTypeToCandidateTransportType(NiceCandidateTransport type) {
+	switch (type) {
+	case NiceCandidateTransport::NICE_CANDIDATE_TRANSPORT_TCP_ACTIVE:
+		return CandidateTransportType::TcpActive;
+	case NiceCandidateTransport::NICE_CANDIDATE_TRANSPORT_TCP_PASSIVE:
+		return CandidateTransportType::TcpPassive;
+	case NiceCandidateTransport::NICE_CANDIDATE_TRANSPORT_TCP_SO:
+		return CandidateTransportType::TcpSo;
+	case NiceCandidateTransport::NICE_CANDIDATE_TRANSPORT_UDP:
+		return CandidateTransportType::Udp;
+	}
+}
+
 } // namespace rtc
 } // namespace rtc
 
 
 #endif
 #endif

+ 5 - 1
src/icetransport.hpp

@@ -37,7 +37,7 @@
 #include <thread>
 #include <thread>
 
 
 namespace rtc {
 namespace rtc {
-
+	
 class IceTransport : public Transport {
 class IceTransport : public Transport {
 public:
 public:
 #if USE_JUICE
 #if USE_JUICE
@@ -56,6 +56,8 @@ public:
 		Completed = NICE_COMPONENT_STATE_READY,
 		Completed = NICE_COMPONENT_STATE_READY,
 		Failed = NICE_COMPONENT_STATE_FAILED,
 		Failed = NICE_COMPONENT_STATE_FAILED,
 	};
 	};
+
+	bool getSelectedCandidatePair(CandidateInfo *local, CandidateInfo *remote);
 #endif
 #endif
 	enum class GatheringState { New = 0, InProgress = 1, Complete = 2 };
 	enum class GatheringState { New = 0, InProgress = 1, Complete = 2 };
 
 
@@ -133,6 +135,8 @@ private:
 	static gboolean TimeoutCallback(gpointer userData);
 	static gboolean TimeoutCallback(gpointer userData);
 	static void LogCallback(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message,
 	static void LogCallback(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message,
 	                        gpointer user_data);
 	                        gpointer user_data);
+	static const CandidateType NiceTypeToCandidateType(NiceCandidateType type);
+	static const CandidateTransportType NiceTransportTypeToCandidateTransportType(NiceCandidateTransport type);
 #endif
 #endif
 };
 };
 
 

+ 7 - 0
src/peerconnection.cpp

@@ -569,6 +569,13 @@ void PeerConnection::resetCallbacks() {
 	mGatheringStateChangeCallback = nullptr;
 	mGatheringStateChangeCallback = nullptr;
 }
 }
 
 
+#if not USE_JUICE
+bool PeerConnection::getSelectedCandidatePair(CandidateInfo *local, CandidateInfo *remote) {
+	auto iceTransport = std::atomic_load(&mIceTransport);
+	return iceTransport->getSelectedCandidatePair(local, remote);
+}
+#endif
+
 } // namespace rtc
 } // namespace rtc
 
 
 std::ostream &operator<<(std::ostream &out, const rtc::PeerConnection::State &state) {
 std::ostream &operator<<(std::ostream &out, const rtc::PeerConnection::State &state) {

+ 18 - 1
test/p2p/answerer.cpp

@@ -76,7 +76,8 @@ int main(int argc, char **argv) {
 		     << "* 0: Exit /"
 		     << "* 0: Exit /"
 		     << " 1: Enter remote description /"
 		     << " 1: Enter remote description /"
 		     << " 2: Enter remote candidate /"
 		     << " 2: Enter remote candidate /"
-		     << " 3: Send message *" << endl
+		     << " 3: Send message /"
+		     << " 4: Print Connection Info *" << endl
 		     << "[Command]: ";
 		     << "[Command]: ";
 
 
 		int command = -1;
 		int command = -1;
@@ -120,6 +121,22 @@ int main(int argc, char **argv) {
 			dc->send(message);
 			dc->send(message);
 			break;
 			break;
 		}
 		}
+		case 4: {
+			// Connection Info
+			if (!dc || !dc->isOpen()) {
+				cout << "** Channel is not Open ** ";
+				break;
+			}
+			CandidateInfo local, remote;
+			if (pc->getSelectedCandidatePair(&local, &remote)) {
+				cout << "Local: " << local.address << ":" << local.port << " " << local.type << " "
+				     << local.transportType << endl;
+				cout << "Remote: " << remote.address << ":" << remote.port << " " << remote.type
+				     << " " << remote.transportType << endl;
+			} else
+				cout << "Could not get Candidate Pair Info" << endl;
+			break;
+		}
 		default: {
 		default: {
 			cout << "** Invalid Command ** ";
 			cout << "** Invalid Command ** ";
 			break;
 			break;

+ 18 - 1
test/p2p/offerer.cpp

@@ -77,7 +77,8 @@ int main(int argc, char **argv) {
 		     << "* 0: Exit /"
 		     << "* 0: Exit /"
 		     << " 1: Enter remote description /"
 		     << " 1: Enter remote description /"
 		     << " 2: Enter remote candidate /"
 		     << " 2: Enter remote candidate /"
-		     << " 3: Send message *" << endl
+		     << " 3: Send message /"
+		     << " 4: Print Connection Info *" << endl
 		     << "[Command]: ";
 		     << "[Command]: ";
 
 
 		int command = -1;
 		int command = -1;
@@ -120,6 +121,22 @@ int main(int argc, char **argv) {
 			dc->send(message);
 			dc->send(message);
 			break;
 			break;
 		}
 		}
+		case 4: {
+			// Connection Info
+			if (!dc || !dc->isOpen()) {
+				cout << "** Channel is not Open ** ";
+				break;
+			}
+			CandidateInfo local, remote;
+			if (pc->getSelectedCandidatePair(&local, &remote)) {
+				cout << "Local: " << local.address << ":" << local.port << " " << local.type << " "
+				     << local.transportType << endl;
+				cout << "Remote: " << remote.address << ":" << remote.port << " " << remote.type
+				     << " " << remote.transportType << endl;
+			} else
+				cout << "Could not get Candidate Pair Info" << endl;
+			break;
+		}
 		default: {
 		default: {
 			cout << "** Invalid Command ** ";
 			cout << "** Invalid Command ** ";
 			break;
 			break;