1 /** 2 * Copyright (c) 2017, Andrew Gault, Nick Chadwick and Guillaume Egles. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * * Neither the name of the <organization> nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #pragma once 29 30 /** 31 * Wrapper around libnice and NiceAgent. 32 */ 33 34 #include "ChunkQueue.hpp" 35 #include "PeerConnection.hpp" 36 #include "Logging.hpp" 37 38 #include <thread> 39 40 extern "C" { 41 #include <nice/agent.h> 42 } 43 44 namespace rtcdcpp { 45 46 /** 47 * Nice Wrapper broh. 48 */ 49 class NiceWrapper { 50 public: 51 // TODO: Remove reference to handler 52 // TODO: Add callback for candidates 53 NiceWrapper(PeerConnection *peer_connection); 54 virtual ~NiceWrapper(); 55 56 // Setup libnice 57 bool Initialize(); 58 59 // Start sending packets XXX: recv just happens once candidates are set 60 void StartSendLoop(); 61 62 // Shutdown nice and stop the send thread 63 void Stop(); 64 65 // Parse the remote SDP 66 void ParseRemoteSDP(std::string remote_sdp); 67 68 // void SetRemoteCredentials(std::string username, std::string password); 69 70 // Generate the local SDP 71 std::string GenerateLocalSDP(); 72 73 // Add a single remote ice candidate (supports trickling) 74 bool SetRemoteIceCandidate(std::string candidate_sdp); 75 76 // Set the remote ice candidates 77 bool SetRemoteIceCandidates(std::vector<std::string> candidate_sdps); 78 79 // Callback to call when we receive local ice candidates 80 // void SetLocalCandidatesCallback(std::vector<std::string> candidate_sdps); 81 82 // Callback to call when we receive remote data 83 void SetDataReceivedCallback(std::function<void(ChunkPtr)>); 84 85 // Send data over the nice channel 86 void SendData(ChunkPtr chunk); 87 88 private: 89 PeerConnection *peer_connection; 90 int packets_sent; 91 92 std::unique_ptr<NiceAgent, void (*)(gpointer)> agent; 93 std::unique_ptr<GMainLoop, void (*)(GMainLoop *)> loop; 94 uint32_t stream_id; 95 std::mutex send_lock; 96 97 bool gathering_done; 98 bool negotiation_done; 99 100 ChunkQueue send_queue; 101 102 std::function<void(ChunkPtr)> data_received_callback; 103 104 // Send data thread 105 void SendLoop(); 106 std::thread send_thread; 107 std::thread g_main_loop_thread; 108 std::atomic<bool> should_stop; 109 110 // Callback methods 111 void OnStateChange(uint32_t stream_id, uint32_t component_id, uint32_t state); 112 void OnGatheringDone(); 113 void OnCandidate(std::string candidate); 114 void OnSelectedPair(); 115 void OnDataReceived(const uint8_t *buf, int len); 116 void OnIceReady(); 117 void LogMessage(const gchar *message); 118 119 // Helper functions 120 friend void candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer user_data); 121 friend void component_state_changed(NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer user_data); 122 friend void new_local_candidate(NiceAgent *agent, NiceCandidate *candidate, gpointer user_data); 123 friend void new_selected_pair(NiceAgent *agent, guint stream_id, guint component_id, NiceCandidate *lcandidate, NiceCandidate *rcandidate, 124 gpointer user_data); 125 friend void data_received(NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer user_data); 126 friend void nice_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data); 127 128 std::shared_ptr<Logger> logger = GetLogger("rtcdcpp.Nice"); 129 }; 130 } 131