2
0
Paul-Louis Ageneau 4 жил өмнө
parent
commit
d9de5080e5

+ 2 - 1
CMakeLists.txt

@@ -91,8 +91,9 @@ set(LIBDATACHANNEL_HEADERS
 set(TESTS_SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/test/main.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/test/connectivity.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/test/capi.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/test/track.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/test/capi_connectivity.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/test/capi_track.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/test/websocket.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/test/benchmark.cpp
 )

+ 6 - 6
test/capi.cpp → test/capi_connectivity.cpp

@@ -37,8 +37,8 @@ typedef struct {
 	bool connected;
 } Peer;
 
-Peer *peer1 = NULL;
-Peer *peer2 = NULL;
+static Peer *peer1 = NULL;
+static Peer *peer2 = NULL;
 
 static void descriptionCallback(const char *sdp, const char *type, void *ptr) {
 	Peer *peer = (Peer *)ptr;
@@ -132,7 +132,7 @@ static void deletePeer(Peer *peer) {
 	}
 }
 
-int test_capi_main() {
+int test_capi_connectivity_main() {
 	int attempts;
 
 	rtcInitLogger(RTC_LOG_DEBUG, nullptr);
@@ -170,7 +170,7 @@ int test_capi_main() {
 	rtcSetMessageCallback(peer1->dc, messageCallback);
 
 	attempts = 10;
-	while (!peer2->connected && !peer1->connected && attempts--)
+	while ((!peer2->connected || !peer1->connected) && attempts--)
 		sleep(1);
 
 	if (peer1->state != RTC_CONNECTED || peer2->state != RTC_CONNECTED) {
@@ -213,7 +213,7 @@ error:
 
 #include <stdexcept>
 
-void test_capi() {
-	if (test_capi_main())
+void test_capi_connectivity() {
+	if (test_capi_connectivity_main())
 		throw std::runtime_error("Connection failed");
 }

+ 198 - 0
test/capi_track.cpp

@@ -0,0 +1,198 @@
+/**
+ * Copyright (c) 2020 Paul-Louis Ageneau
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <rtc/rtc.h>
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#ifdef _WIN32
+#include <windows.h>
+static void sleep(unsigned int secs) { Sleep(secs * 1000); }
+#else
+#include <unistd.h> // for sleep
+#endif
+
+typedef struct {
+	rtcState state;
+	rtcGatheringState gatheringState;
+	int pc;
+	int tr;
+	bool connected;
+} Peer;
+
+static Peer *peer1 = NULL;
+static Peer *peer2 = NULL;
+
+static const char *mediaDescription = "video 9 UDP/TLS/RTP/SAVPF\r\n"
+                                      "a=mid:video\r\n";
+
+static void descriptionCallback(const char *sdp, const char *type, void *ptr) {
+	Peer *peer = (Peer *)ptr;
+	printf("Description %d:\n%s\n", peer == peer1 ? 1 : 2, sdp);
+	Peer *other = peer == peer1 ? peer2 : peer1;
+	rtcSetRemoteDescription(other->pc, sdp, type);
+}
+
+static void candidateCallback(const char *cand, const char *mid, void *ptr) {
+	Peer *peer = (Peer *)ptr;
+	printf("Candidate %d: %s\n", peer == peer1 ? 1 : 2, cand);
+	Peer *other = peer == peer1 ? peer2 : peer1;
+	rtcAddRemoteCandidate(other->pc, cand, mid);
+}
+
+static void stateChangeCallback(rtcState state, void *ptr) {
+	Peer *peer = (Peer *)ptr;
+	peer->state = state;
+	printf("State %d: %d\n", peer == peer1 ? 1 : 2, (int)state);
+}
+
+static void gatheringStateCallback(rtcGatheringState state, void *ptr) {
+	Peer *peer = (Peer *)ptr;
+	peer->gatheringState = state;
+	printf("Gathering state %d: %d\n", peer == peer1 ? 1 : 2, (int)state);
+}
+
+static void openCallback(void *ptr) {
+	Peer *peer = (Peer *)ptr;
+	peer->connected = true;
+	printf("Track %d: Open\n", peer == peer1 ? 1 : 2);
+}
+
+static void closedCallback(void *ptr) {
+	Peer *peer = (Peer *)ptr;
+	peer->connected = false;
+}
+
+static void trackCallback(int tr, void *ptr) {
+	Peer *peer = (Peer *)ptr;
+	peer->tr = tr;
+	peer->connected = true;
+	rtcSetClosedCallback(tr, closedCallback);
+
+	char buffer[1024];
+	if (rtcGetTrackDescription(tr, buffer, 1024) >= 0)
+		printf("Track %d: Received with media description: \n%s\n", peer == peer1 ? 1 : 2, buffer);
+}
+
+static Peer *createPeer(const rtcConfiguration *config) {
+	Peer *peer = (Peer *)malloc(sizeof(Peer));
+	if (!peer)
+		return nullptr;
+	memset(peer, 0, sizeof(Peer));
+
+	// Create peer connection
+	peer->pc = rtcCreatePeerConnection(config);
+	rtcSetUserPointer(peer->pc, peer);
+	rtcSetTrackCallback(peer->pc, trackCallback);
+	rtcSetLocalDescriptionCallback(peer->pc, descriptionCallback);
+	rtcSetLocalCandidateCallback(peer->pc, candidateCallback);
+	rtcSetStateChangeCallback(peer->pc, stateChangeCallback);
+	rtcSetGatheringStateChangeCallback(peer->pc, gatheringStateCallback);
+
+	return peer;
+}
+
+static void deletePeer(Peer *peer) {
+	if (peer) {
+		if (peer->tr)
+			rtcDeleteTrack(peer->tr);
+		if (peer->pc)
+			rtcDeletePeerConnection(peer->pc);
+		free(peer);
+	}
+}
+
+int test_capi_track_main() {
+	int attempts;
+
+	rtcInitLogger(RTC_LOG_DEBUG, nullptr);
+
+	// Create peer 1
+	rtcConfiguration config1;
+	memset(&config1, 0, sizeof(config1));
+	// STUN server example
+	// const char *iceServers[1] = {"stun:stun.l.google.com:19302"};
+	// config1.iceServers = iceServers;
+	// config1.iceServersCount = 1;
+
+	peer1 = createPeer(&config1);
+	if (!peer1)
+		goto error;
+
+	// Create peer 2
+	rtcConfiguration config2;
+	memset(&config2, 0, sizeof(config2));
+	// STUN server example
+	// config2.iceServers = iceServers;
+	// config2.iceServersCount = 1;
+	// Port range example
+	config2.portRangeBegin = 5000;
+	config2.portRangeEnd = 6000;
+
+	peer2 = createPeer(&config2);
+	if (!peer2)
+		goto error;
+
+	// Peer 1: Create track
+	peer1->tr = rtcCreateTrack(peer1->pc, mediaDescription);
+	rtcSetOpenCallback(peer1->tr, openCallback);
+	rtcSetClosedCallback(peer1->tr, closedCallback);
+
+	// Initiate the handshake
+	rtcSetLocalDescription(peer1->pc);
+
+	attempts = 10;
+	while ((!peer2->connected || !peer1->connected) && attempts--)
+		sleep(1);
+
+	if (peer1->state != RTC_CONNECTED || peer2->state != RTC_CONNECTED) {
+		fprintf(stderr, "PeerConnection is not connected\n");
+		goto error;
+	}
+
+	if (!peer1->connected || !peer2->connected) {
+		fprintf(stderr, "Track is not connected\n");
+		goto error;
+	}
+
+	deletePeer(peer1);
+	sleep(1);
+	deletePeer(peer2);
+	sleep(1);
+
+	// You may call rtcCleanup() when finished to free static resources
+	rtcCleanup();
+	sleep(2);
+
+	printf("Success\n");
+	return 0;
+
+error:
+	deletePeer(peer1);
+	deletePeer(peer2);
+	return -1;
+}
+
+#include <stdexcept>
+
+void test_capi_track() {
+	if (test_capi_track_main())
+		throw std::runtime_error("Connection failed");
+}

+ 14 - 5
test/main.cpp

@@ -24,8 +24,9 @@ using namespace std;
 using namespace chrono_literals;
 
 void test_connectivity();
-void test_capi();
 void test_track();
+void test_capi_connectivity();
+void test_capi_track();
 void test_websocket();
 size_t benchmark(chrono::milliseconds duration);
 
@@ -50,11 +51,11 @@ int main(int argc, char **argv) {
 		return -1;
 	}
 	try {
-		cout << endl << "*** Running WebRTC C API test..." << endl;
-		test_capi();
-		cout << "*** Finished WebRTC C API test" << endl;
+		cout << endl << "*** Running WebRTC C API connectivity test..." << endl;
+		test_capi_connectivity();
+		cout << "*** Finished WebRTC C API connectivity test" << endl;
 	} catch (const exception &e) {
-		cerr << "WebRTC C API test failed: " << e.what() << endl;
+		cerr << "WebRTC C API connectivity test failed: " << e.what() << endl;
 		return -1;
 	}
 #if RTC_ENABLE_MEDIA
@@ -66,6 +67,14 @@ int main(int argc, char **argv) {
 		cerr << "WebRTC Track test failed: " << e.what() << endl;
 		return -1;
 	}
+	try {
+		cout << endl << "*** Running WebRTC C API track test..." << endl;
+		test_capi_track();
+		cout << "*** Finished WebRTC C API track test" << endl;
+	} catch (const exception &e) {
+		cerr << "WebRTC C API track test failed: " << e.what() << endl;
+		return -1;
+	}
 #endif
 #if RTC_ENABLE_WEBSOCKET
 	try {