/** * Copyright (c) 2019 Paul-Louis Ageneau, Murat Dogan * * 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.hpp" #include #include #include #ifdef _WIN32 #include #endif using namespace rtc; using namespace std; template weak_ptr make_weak_ptr(shared_ptr ptr) { return ptr; } int main(int argc, char **argv) { InitLogger(LogLevel::Warning); Configuration config; // config.iceServers.emplace_back("stun.l.google.com:19302"); // config.enableIceTcp = true; // TURN Server example // IceServer turnServer("TURN_SERVER_URL", "PORT_NO", "USERNAME", "PASSWORD", // IceServer::RelayType::TurnUdp); // config.iceServers.push_back(turnServer); auto pc = std::make_shared(config); #ifdef _WIN32 WSADATA wsaData; int iResult; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { std::string err("WSAStartup failed. Error:"); err.append(WSAGetLastError() + ""); std::cout << err; return -1; } #endif pc->onLocalDescription([](const Description &sdp) { std::string s(sdp); std::replace(s.begin(), s.end(), '\n', static_cast(94)); std::replace(s.begin(), s.end(), '\r', static_cast(95)); cout << "Local Description (Paste this to other peer):" << endl << s << endl << endl; }); pc->onLocalCandidate([](const Candidate &candidate) { cout << "Local Candidate (Paste this to other peer):" << endl << candidate << endl << endl; }); pc->onStateChange( [](PeerConnection::State state) { cout << "[ State: " << state << " ]" << endl; }); pc->onGatheringStateChange([](PeerConnection::GatheringState state) { cout << "[ Gathering State: " << state << " ]" << endl; }); shared_ptr dc = nullptr; pc->onDataChannel([&](shared_ptr _dc) { cout << "[ Got a DataChannel with label: " << _dc->label() << " ]" << endl; dc = _dc; dc->onClosed([&]() { cout << "[ DataChannel closed: " << dc->label() << " ]" << endl; }); dc->onMessage([](const variant &message) { if (holds_alternative(message)) { cout << "[ Received: " << get(message) << " ]" << endl; } }); }); bool exit = false; while (!exit) { cout << endl << endl << "*************************************************************************" << endl << "* 0: Exit /" << " 1: Enter Description /" << " 2: Enter Candidate /" << " 3: Send Message *" << endl << " [Command]: "; int command; std::string sdp, candidate, message; const char *a; std::unique_ptr candidatePtr; std::unique_ptr descPtr; cin >> command; switch (command) { case 0: exit = true; break; case 1: // Parse Description cout << "[SDP]: "; sdp = ""; while (sdp.length() == 0) getline(cin, sdp); std::replace(sdp.begin(), sdp.end(), static_cast(94), '\n'); std::replace(sdp.begin(), sdp.end(), static_cast(95), '\r'); descPtr = std::make_unique(sdp, Description::Type::Offer, Description::Role::Passive); pc->setRemoteDescription(*descPtr); break; case 2: // Parse Candidate cout << "[Candidate]: "; candidate = ""; while (candidate.length() == 0) getline(cin, candidate); candidatePtr = std::make_unique(candidate); pc->addRemoteCandidate(*candidatePtr); break; case 3: // Send Message if (!dc || !dc->isOpen()) { cout << "** Channel is not Open ** "; break; } cout << "[Message]: "; message = ""; while (message.length() == 0) getline(cin, message); dc->send(message); break; default: cout << "** Invalid Command ** "; break; } } if (dc) dc->close(); if (pc) pc->close(); #ifdef _WIN32 WSACleanup(); #endif }