summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlam3rboy <34555296+Flam3rboy@users.noreply.github.com>2021-08-12 20:32:55 +0200
committerFlam3rboy <34555296+Flam3rboy@users.noreply.github.com>2021-08-12 20:32:55 +0200
commitca432fda543c3d124bd507de7156400058fda802 (patch)
tree5d20deb8d4d89e26887668a59d45ad70789267eb
parentMerge branch 'master' into util (diff)
parentMerge pull request #21 from ItsNewe/master (diff)
downloadserver-ca432fda543c3d124bd507de7156400058fda802.tar.xz
Merge branch 'rtc'
-rw-r--r--.gitignore40
-rw-r--r--CMakeLists.txt16
-rw-r--r--README.md31
-rw-r--r--config.json1
-rw-r--r--src/main.cpp47
-rw-r--r--src/mongoStub.cpp84
-rw-r--r--src/mongoStub.hpp41
-rw-r--r--src/rtcPeerHandler.cpp83
-rw-r--r--src/rtcPeerHandler.hpp32
-rw-r--r--src/rtcServer.hpp0
10 files changed, 353 insertions, 22 deletions
diff --git a/.gitignore b/.gitignore
index d7fc3f74..f14b4548 100644
--- a/.gitignore
+++ b/.gitignore
@@ -104,4 +104,42 @@ typings/
 .DS_Store
 
 # Compiled TypeScript code
-dist/
\ No newline at end of file
+dist/
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.o
+
+# Protobuffer builds
+*.pb.cc
+*.pb.h
+
+# Directories
+build/
+.vscode/
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 00000000..2cf5c0a6
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 3.2)
+project(fosscord-media)
+
+set(CMAKE_CXX_STANDARD 17)
+
+find_package(Threads REQUIRED)
+
+find_package(mongocxx REQUIRED)
+find_package(Boost REQUIRED)
+
+
+file(GLOB SourceFiles ${PROJECT_SOURCE_DIR}/src/*.cpp)
+#include_directories("bsoncxx/v_noabi/bsoncxx/")
+add_executable(${CMAKE_PROJECT_NAME} ${SourceFiles})
+
+target_link_libraries(${CMAKE_PROJECT_NAME} datachannel mongo::mongocxx_shared Boost::boost)
\ No newline at end of file
diff --git a/README.md b/README.md
index 9c983acd..ee452adf 100644
--- a/README.md
+++ b/README.md
@@ -1,29 +1,18 @@
-<p align="center">
-  <img width="100" src="https://raw.githubusercontent.com/fosscord/fosscord/master/assets/logo_big_transparent.png" />
-</p>
-<h1 align="center">Fosscord server util</h1>
+# Fosscord-media
 
-<p>
-  <a href="https://discord.gg/ZrnGQP6p3d">
-    <img src="https://img.shields.io/discord/806142446094385153?color=7489d5&logo=discord&logoColor=ffffff" />
-  </a>
-  <img src="https://img.shields.io/static/v1?label=Status&message=Development&color=blue">
-  <a title="Crowdin" target="_blank" href="https://translate.fosscord.com/"><img src="https://badges.crowdin.net/fosscord/localized.svg"></a>
-   <a href="https://opencollective.com/fosscord">
-    <img src="https://opencollective.com/fosscord/tiers/badge.svg">
-  </a>
-</p>
+A Fosscord media (voice and video) server
 
-## [About](https://fosscord.com)
-
-Fosscord is a free open source selfhostable chat, voice and video discord-compatible platform.
+## Installation
 
-Fosscord server util contains all necessary logic that is shared between the [api](https://github.com/fosscord/fosscord-api), [gateway](https://github.com/fosscord/fosscord-gateway) and [cdn](https://github.com/fosscord/fosscord-cdn).
+### Prerequisites
 
-It contains all mongoose database models and utility functions.
+-   Install the [libdatachannel](https://github.com/paullouisageneau/libdatachannel) library
+-   Install the [libmongocxx](http://mongocxx.org/mongocxx-v3/installation/) driver and its requirements
 
-## Installation
+### Building
 
 ```bash
-npm install @fosscord/server-util
+$ cmake
+$ cd build
+$ make
 ```
diff --git a/config.json b/config.json
new file mode 100644
index 00000000..9e26dfee
--- /dev/null
+++ b/config.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 00000000..372eaa00
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,47 @@
+//   $$$$$$\                                                                   $$\                           
+//  $$  __$$\                                                                  $$ |
+//  $$ /  \__|$$$$$$\   $$$$$$$\  $$$$$$$\  $$$$$$$\  $$$$$$\   $$$$$$\   $$$$$$$ |
+//  $$$$\    $$  __$$\ $$  _____|$$  _____|$$  _____|$$  __$$\ $$  __$$\ $$  __$$ |
+//  $$  _|   $$ /  $$ |\$$$$$$\  \$$$$$$\  $$ /      $$ /  $$ |$$ |  \__|$$ /  $$ |
+//  $$ |     $$ |  $$ | \____$$\  \____$$\ $$ |      $$ |  $$ |$$ |      $$ |  $$ |
+//  $$ |     \$$$$$$  |$$$$$$$  |$$$$$$$  |\$$$$$$$\ \$$$$$$  |$$ |      \$$$$$$$ |
+//  \__|      \______/ \_______/ \_______/  \_______| \______/ \__|       \_______|
+//
+//
+//
+//                       $$\                      $$$$$$\                                                    
+//                       \__|                    $$  __$$\                                                   
+//  $$\    $$\  $$$$$$\  $$\  $$$$$$$\  $$$$$$\  $$ /  \__| $$$$$$\   $$$$$$\ $$\    $$\  $$$$$$\   $$$$$$\  
+//  \$$\  $$  |$$  __$$\ $$ |$$  _____|$$  __$$\ \$$$$$$\  $$  __$$\ $$  __$$\\$$\  $$  |$$  __$$\ $$  __$$\ 
+//   \$$\$$  / $$ /  $$ |$$ |$$ /      $$$$$$$$ | \____$$\ $$$$$$$$ |$$ |  \__|\$$\$$  / $$$$$$$$ |$$ |  \__|
+//    \$$$  /  $$ |  $$ |$$ |$$ |      $$   ____|$$\   $$ |$$   ____|$$ |       \$$$  /  $$   ____|$$ |
+//     \$  /   \$$$$$$  |$$ |\$$$$$$$\ \$$$$$$$\ \$$$$$$  |\$$$$$$$\ $$ |        \$  /   \$$$$$$$\ $$ |
+//      \_/     \______/ \__| \_______| \_______| \______/  \_______|\__|         \_/     \_______|\__|
+//
+//
+//
+
+#include "rtcPeerHandler.hpp" //Handle peer connection requests
+#include "mongoStub.hpp"	//Handle communication with the MongoDB server
+
+int main(int argc, char **argv){
+
+	auto commsHandler = std::make_shared<rtcPeerHandler>();
+	auto mongoHandler = std::make_unique<mongoStub>();
+
+	mongocxx::options::change_stream options;
+	//voiceEvents collection watcher
+    mongocxx::change_stream colCs = mongoHandler->getCol().watch(options);
+
+	std::cout << "Server created and listening for events" << std::endl;
+
+	//Check for new messages in the collection
+	for (;;){
+		std::vector<mongoStub::mongoMessage> t = mongoHandler->getNewMessages(&colCs);
+		for(auto &i : t){
+			std::cout << "[" << i.eventName << "] " << std::endl;
+		}
+	}
+
+	return 0;
+}
\ No newline at end of file
diff --git a/src/mongoStub.cpp b/src/mongoStub.cpp
new file mode 100644
index 00000000..ccd2abda
--- /dev/null
+++ b/src/mongoStub.cpp
@@ -0,0 +1,84 @@
+#include "mongoStub.hpp"
+
+mongoStub::mongoStub() {
+    if (this->client) {
+        this->db = client["fosscord"];
+
+        if (this->db) {
+            this->col = db["events"];
+
+        } else {
+            std::cout << "db not found";
+            exit(-1);
+        }
+    } else {
+        std::cout << "Client couldn't be initialized";
+        exit(-1);
+    }
+}
+
+// Too slow for my liking
+std::vector<mongoStub::mongoMessage> mongoStub::getNewMessages(
+    mongocxx::change_stream* colCs) {
+    std::vector<mongoStub::mongoMessage> retVec;
+
+    for (auto&& event : *colCs) {
+        mongoStub::mongoMessage returnValue;
+
+        std::cout << bsoncxx::to_json(event) << std::endl;
+
+        // Only listen to insert events (to avoid "precondition failed: data"
+        // exception)
+        if (event["operationType"].get_utf8().value.to_string() != "insert") {
+            continue;
+        }
+
+        std::string evName = event["fullDocument"]["event"].get_utf8().value.to_string();
+
+		if(evName.substr(0, 7)=="VSERVER"){ continue; } //Ignore the event if it's been emited by a voice server
+
+        if (evName == "UDP_CONNECTION") {
+            handleUdpRequest(
+				event["fullDocument"]["data"]["d"]["address"].get_utf8().value.to_string(),
+				event["fullDocument"]["data"]["d"]["port"].get_int32().value,
+				event["fullDocument"]["data"]["d"]["mode"].get_utf8().value.to_string()
+				);
+
+        } else if (evName == "VOICE_REQUEST") {
+			//TODO
+            continue;
+        }
+
+        returnValue.eventName = evName;
+        retVec.push_back(returnValue);
+    }
+
+    return retVec;
+}
+
+
+void mongoStub::handleUdpRequest(std::string address, int port, std::string mode) {
+    using bsoncxx::builder::basic::kvp;
+    using bsoncxx::builder::basic::sub_array;
+    using bsoncxx::builder::basic::sub_document;
+
+    auto builder = bsoncxx::builder::basic::document{};
+
+	//Handle UDP socket stuff (later tho)
+	
+    builder.append(kvp("event", "VSERVER_UDP_RESPONSE"));
+    builder.append(kvp("op", "4"));
+    builder.append(kvp("d", [](sub_document subdoc) {
+		subdoc.append(kvp("mode", "CRYPT_MODE")),
+		subdoc.append(kvp("secret_key", [](sub_array subarr) {
+            subarr.append(1, 2, 3, 5);  // HOW DO I GEN A SKEY?
+        }));
+	}));
+	
+	
+	bsoncxx::stdx::optional<mongocxx::result::insert_one> r= col.insert_one(builder.view());
+}
+
+void mongoStub::handleVoiceRequest() {
+	//Is this really needed? idk
+}
\ No newline at end of file
diff --git a/src/mongoStub.hpp b/src/mongoStub.hpp
new file mode 100644
index 00000000..2809142f
--- /dev/null
+++ b/src/mongoStub.hpp
@@ -0,0 +1,41 @@
+#ifndef MONGOSTUB_HPP
+#define MONGOSTUB_HPP
+
+#include <boost/utility.hpp>
+#include <cstdint>
+#include <iostream>
+#include <vector>
+#include <mongocxx/client.hpp>
+#include <mongocxx/instance.hpp>
+#include <mongocxx/change_stream.hpp>
+#include <bsoncxx/json.hpp>
+#include <bsoncxx/document/element.hpp>
+
+
+class mongoStub{
+	public:
+		mongoStub();
+
+		struct mongoMessage{
+			std::string eventName;
+			std::vector<std::string> data;
+		};
+
+		std::vector<mongoMessage> getNewMessages(mongocxx::change_stream* colCs);
+
+		mongocxx::collection getCol() const { return col; }
+
+		
+		
+	private:
+		mongocxx::instance instance;
+		mongocxx::client client{mongocxx::uri{}};
+		mongocxx::database db;
+		mongocxx::collection col;
+		mongocxx::change_stream* colCs = nullptr;
+
+		void handleUdpRequest(std::string address, int port, std::string mode);
+		void handleVoiceRequest();
+};
+
+#endif
diff --git a/src/rtcPeerHandler.cpp b/src/rtcPeerHandler.cpp
new file mode 100644
index 00000000..9bfc6466
--- /dev/null
+++ b/src/rtcPeerHandler.cpp
@@ -0,0 +1,83 @@
+#include "rtcPeerHandler.hpp"
+
+rtcPeerHandler::rtcPeerHandler() {
+    rtc::InitLogger(rtc::LogLevel::Verbose, NULL);
+}
+
+void rtcPeerHandler::initiateConnection(std::string peerIP, int peerPort) {
+    // Socket connection between client and server
+    SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
+    sockaddr_in addr;
+    addr.sin_addr.s_addr = inet_addr(peerIP.c_str());
+    addr.sin_port = htons(peerPort);
+    addr.sin_family = AF_INET;
+
+    rtc::Configuration conf;
+    conf.enableIceTcp = false;
+    conf.disableAutoNegotiation = false;
+
+    auto pc = std::make_shared<rtc::PeerConnection>(conf);
+
+    rtc::Description::Audio media("audio",
+                                  rtc::Description::Direction::SendRecv);
+    media.addOpusCodec(96);
+    media.setBitrate(64);
+
+    auto track = pc->addTrack(media);
+
+    // auto session = std::make_shared<rtc::MediaHandler>();
+
+    // track->setMediaHandler(session);
+
+    rtc::Reliability rtcRel;
+    rtcRel.unordered = true;
+    rtcRel.type = rtc::Reliability::Type::Timed;
+    rtcRel.rexmit = 500;
+
+    rtc::DataChannelInit rtcConf;
+    rtcConf.reliability = rtcRel;
+    rtcConf.negotiated = false;
+
+    pc->onStateChange([](rtc::PeerConnection::State state) {
+        std::cout << "State: " << state << std::endl;
+        if (state == rtc::PeerConnection::State::Disconnected ||
+            state == rtc::PeerConnection::State::Failed ||
+            state == rtc::PeerConnection::State::Closed) {
+            // remove disconnected client
+        }
+    });
+
+    pc->onGatheringStateChange([](rtc::PeerConnection::GatheringState state) {
+        std::cout << "Gathering State: " << state << std::endl;
+    });
+
+    /*std::tuple<rtc::Track*, rtc::RtcpSrReporter*> addAudio(
+		
+        const std::shared_ptr<rtc::PeerConnection> pc,
+        const uint8_t payloadType, const uint32_t ssrc, const std::string cname,
+        const std::string msid, const std::function<void(void)> onOpen) {
+        auto audio = Description::Audio(cname);
+        audio.addOpusCodec(payloadType);
+        audio.addSSRC(ssrc, cname, msid, cname);
+        auto track = pc->addTrack(audio);
+        // create RTP configuration
+        auto rtpConfig = make_shared<RtpPacketizationConfig>(
+            ssrc, cname, payloadType, OpusRtpPacketizer::defaultClockRate);
+        // create packetizer
+        auto packetizer = make_shared<OpusRtpPacketizer>(rtpConfig);
+        // create opus handler
+        auto opusHandler = make_shared<OpusPacketizationHandler>(packetizer);
+
+        // add RTCP SR handler
+        auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
+        opusHandler->addToChain(srReporter);
+
+        // set handler
+        track->setMediaHandler(opusHandler);
+        track->onOpen(onOpen);
+        auto trackData = make_shared<ClientTrackData>(track, srReporter);
+        return trackData;
+    }*/
+
+    pc->createDataChannel("Fosscord voice connection", rtcConf);
+}
diff --git a/src/rtcPeerHandler.hpp b/src/rtcPeerHandler.hpp
new file mode 100644
index 00000000..3ba32a83
--- /dev/null
+++ b/src/rtcPeerHandler.hpp
@@ -0,0 +1,32 @@
+#include "libdatachannel/rtc.hpp"
+#include <iostream>
+#include <memory>
+#include "nlohmann/json.hpp"
+#include <array>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#else
+#include <arpa/inet.h>
+typedef int SOCKET;
+#endif
+
+using json = nlohmann::json;
+
+#ifndef RTCPEERHANDLER
+#define RTCPEERHANDLER
+class rtcPeerHandler{
+public:
+	rtcPeerHandler();
+	void initiateConnection(std::string peerIP, int peerPort);
+
+	struct client
+	{
+		std::shared_ptr<rtc::PeerConnection> pc;
+		std::shared_ptr<rtc::DataChannel> dc;
+	};
+
+private:
+	std::map<SOCKET, client> clients;
+};
+#endif
\ No newline at end of file
diff --git a/src/rtcServer.hpp b/src/rtcServer.hpp
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/rtcServer.hpp