summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlam3rboy <34555296+Flam3rboy@users.noreply.github.com>2021-05-21 19:21:32 +0200
committerGitHub <noreply@github.com>2021-05-21 19:21:32 +0200
commit9c9c948ae9eb1959aabd70eff968dd49272a05fb (patch)
tree096bacda4fc8b765a7712330850b2b50657112bb
parentMerge branch 'master' of https://github.com/discord-open-source/discord-voice (diff)
parent[del] Removed protobuf build files (diff)
downloadserver-9c9c948ae9eb1959aabd70eff968dd49272a05fb.tar.xz
Merge pull request #19 from ItsNewe/master
Set up the initial project structure
-rw-r--r--.gitignore143
-rw-r--r--CMakeLists.txt32
-rw-r--r--README.md14
-rw-r--r--config.json1
-rw-r--r--src/main.cpp36
-rw-r--r--src/protodefs/protos.proto24
-rw-r--r--src/rpcStub.cpp32
-rw-r--r--src/rpcStub.hpp15
-rw-r--r--src/rtcPeerHandler.cpp83
-rw-r--r--src/rtcPeerHandler.hpp32
-rw-r--r--src/rtcServer.hpp0
11 files changed, 307 insertions, 105 deletions
diff --git a/.gitignore b/.gitignore

index 5c7cd31d..539bb001 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,105 +1,38 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port -.DS_Store \ No newline at end of file +# 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..cebd3adf --- /dev/null +++ b/CMakeLists.txt
@@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.15) +project(fosscord-media) + +set(CMAKE_CXX_STANDARD 17) + +find_package(Threads REQUIRED) +find_package(Protobuf REQUIRED) +find_package(gRPC CONFIG REQUIRED) +find_package(absl REQUIRED) +find_package(nlohmann_json REQUIRED) + +file(GLOB SourceFiles ${PROJECT_SOURCE_DIR}/src/*.cpp) + +file(GLOB ProtoFiles ${PROJECT_SOURCE_DIR}/src/protodefs/*.proto) +set(PROTOBUF_INPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src/protodefs) +set(PROTOBUF_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src/protodefs/include) + +foreach(file ${ProtoFiles}) + execute_process(COMMAND "LD_LIBRARY_PATH=/usr/local/lib protoc --proto_path=\"${PROTOBUF_INPUT_DIRECTORY}\" + --cpp_out=\"${PROJECT_SOURCE_DIR}/src/protodefs/include\" --grpc_out=\"${PROJECT_SOURCE_DIR}/src/protodefs/include\" + --plugin=protoc-gen-grpc=/usr/local/bin/grpc_cpp_plugin protos.proto" + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) +endforeach() + + +include_directories(${Protobuf_INCLUDE_DIRS}) + +#protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ProtoFiles) + +add_executable(${CMAKE_PROJECT_NAME} ${SourceFiles}) + +target_link_libraries(${CMAKE_PROJECT_NAME} datachannel gRPC::grpc++ absl::base absl::synchronization absl::strings ${Protobuf_LIBRARIES} nlohmann_json::nlohmann_json) \ No newline at end of file diff --git a/README.md b/README.md
index ecd3c7ca..4ddd4708 100644 --- a/README.md +++ b/README.md
@@ -1,2 +1,16 @@ # Fosscord-media A Fosscord media (voice and video) server + + +## Installation +### Prerequisites +- Install the [libdatachannel](https://github.com/paullouisageneau/libdatachannel) library +- Install the [gRPC](https://github.com/grpc/grpc) library + +### Building + +```bash +$ 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..2fdeceee --- /dev/null +++ b/src/main.cpp
@@ -0,0 +1,36 @@ +// $$$$$$\ $$\ +// $$ __$$\ $$ | +// $$ / \__|$$$$$$\ $$$$$$$\ $$$$$$$\ $$$$$$$\ $$$$$$\ $$$$$$\ $$$$$$$ | +// $$$$\ $$ __$$\ $$ _____|$$ _____|$$ _____|$$ __$$\ $$ __$$\ $$ __$$ | +// $$ _| $$ / $$ |\$$$$$$\ \$$$$$$\ $$ / $$ / $$ |$$ | \__|$$ / $$ | +// $$ | $$ | $$ | \____$$\ \____$$\ $$ | $$ | $$ |$$ | $$ | $$ | +// $$ | \$$$$$$ |$$$$$$$ |$$$$$$$ |\$$$$$$$\ \$$$$$$ |$$ | \$$$$$$$ | +// \__| \______/ \_______/ \_______/ \_______| \______/ \__| \_______| +// +// +// +// $$\ $$$$$$\ +// \__| $$ __$$\ +// $$\ $$\ $$$$$$\ $$\ $$$$$$$\ $$$$$$\ $$ / \__| $$$$$$\ $$$$$$\ $$\ $$\ $$$$$$\ $$$$$$\ +// \$$\ $$ |$$ __$$\ $$ |$$ _____|$$ __$$\ \$$$$$$\ $$ __$$\ $$ __$$\\$$\ $$ |$$ __$$\ $$ __$$\ +// \$$\$$ / $$ / $$ |$$ |$$ / $$$$$$$$ | \____$$\ $$$$$$$$ |$$ | \__|\$$\$$ / $$$$$$$$ |$$ | \__| +// \$$$ / $$ | $$ |$$ |$$ | $$ ____|$$\ $$ |$$ ____|$$ | \$$$ / $$ ____|$$ | +// \$ / \$$$$$$ |$$ |\$$$$$$$\ \$$$$$$$\ \$$$$$$ |\$$$$$$$\ $$ | \$ / \$$$$$$$\ $$ | +// \_/ \______/ \__| \_______| \_______| \______/ \_______|\__| \_/ \_______|\__| +// +// +// + +#include "rtcPeerHandler.hpp" //Handle peer connection requests +#include "rpcStub.hpp" //Handle gRPC communications between the different fosscord elements + +int main(int argc, char **argv){ + + auto commsHandler = std::make_shared<rtcPeerHandler>(); + auto rpcHandler = std::unique_ptr<rpcStub>(new rpcStub(commsHandler, 8057)); + + std::cout << "Server created" << std::endl; + + //rpcHandler->server->Wait(); //blocking, this will need to be threaded + return 0; +} \ No newline at end of file diff --git a/src/protodefs/protos.proto b/src/protodefs/protos.proto new file mode 100644
index 00000000..11face5f --- /dev/null +++ b/src/protodefs/protos.proto
@@ -0,0 +1,24 @@ +syntax = "proto3"; + +package fosscordMedia; + +service fosscordInternals{ + rpc vRequest(voiceRequest) returns (voiceAnswer) {} +} + +message voiceRequest{ //OP1 from gw + uint64 userid = 1; + uint64 guildid = 2; + string ip=3; + uint32 port=4; + string protocol=5; + string rtcConnectionId=6; +} + +message voiceAnswer{//OP2 and OP4 to gw + string ip=1; + uint32 port=3; + repeated string modes=2; + int32 ssrc=4; + string audioCodec=5; +} \ No newline at end of file diff --git a/src/rpcStub.cpp b/src/rpcStub.cpp new file mode 100644
index 00000000..1633aab8 --- /dev/null +++ b/src/rpcStub.cpp
@@ -0,0 +1,32 @@ +#include "rpcStub.hpp" + +class fossCordInternalsImpl final : public fosscordMedia::fosscordInternals::Service { + std::shared_ptr<rtcPeerHandler> ph; + fossCordInternalsImpl(std::shared_ptr<rtcPeerHandler> handler){ + this->ph= handler; + } + grpc::Status vRequest(grpc::ServerContext* ctx, + const fosscordMedia::voiceRequest* req, + fosscordMedia::voiceAnswer* resp) override { + + this->ph->initiateConnection(req->ip(), req->port()); + return grpc::Status::OK; + } +}; + +rpcStub::rpcStub(std::shared_ptr<rtcPeerHandler> handler, int port) { + if (not port) { + port = 8057; + } + this->ph = handler; + + fossCordInternalsImpl* service; + grpc::ServerBuilder builder; + builder.AddListeningPort("0.0.0.0:" + std::to_string(port), + grpc::InsecureServerCredentials()); + builder.RegisterService(service); + + this->server = builder.BuildAndStart(); + + std::cout << "RPC stub listening on port " << port << std::endl; +} \ No newline at end of file diff --git a/src/rpcStub.hpp b/src/rpcStub.hpp new file mode 100644
index 00000000..d183cf3c --- /dev/null +++ b/src/rpcStub.hpp
@@ -0,0 +1,15 @@ +#include <grpc++/grpc++.h> +#include "protodefs/include/protos.grpc.pb.h" +#include "rtcPeerHandler.hpp" + +#ifndef RPCSTUB +#define RPCSTUB +class rpcStub{ + public: + rpcStub(std::shared_ptr<rtcPeerHandler> peerHandler, int port); + std::unique_ptr<grpc::Server> server; + + private: + std::shared_ptr<rtcPeerHandler> ph; +}; +#endif \ No newline at end of file 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