1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 // Original author: ekr@rtfm.com 8 9 #ifndef transportlayer_h__ 10 #define transportlayer_h__ 11 12 #include "sigslot.h" 13 14 #include "mozilla/DebugOnly.h" 15 #include "mozilla/RefPtr.h" 16 #include "nsCOMPtr.h" 17 #include "nsIEventTarget.h" 18 19 #include "m_cpp_utils.h" 20 #include "mediapacket.h" 21 22 namespace mozilla { 23 24 class TransportFlow; 25 26 typedef int TransportResult; 27 28 enum { TE_WOULDBLOCK = -1, TE_ERROR = -2, TE_INTERNAL = -3 }; 29 30 #define TRANSPORT_LAYER_ID(name) \ 31 const std::string id() const override { return name; } \ 32 static std::string ID() { return name; } 33 34 // Abstract base class for network transport layers. 35 class TransportLayer : public sigslot::has_slots<> { 36 public: 37 // The state of the transport flow 38 // We can't use "ERROR" because Windows has a macro named "ERROR" 39 enum State { TS_NONE, TS_INIT, TS_CONNECTING, TS_OPEN, TS_CLOSED, TS_ERROR }; 40 41 // Is this a stream or datagram flow TransportLayer()42 TransportLayer() : state_(TS_NONE), flow_id_(), downward_(nullptr) {} 43 44 virtual ~TransportLayer() = default; 45 46 // Called to initialize 47 nsresult Init(); // Called by Insert() to set up -- do not override InitInternal()48 virtual nsresult InitInternal() { return NS_OK; } // Called by Init 49 SetFlowId(const std::string & flow_id)50 void SetFlowId(const std::string& flow_id) { flow_id_ = flow_id; } 51 52 virtual void Chain(TransportLayer* downward); 53 54 // Downward interface downward()55 TransportLayer* downward() { return downward_; } 56 57 // Get the state state()58 State state() const { return state_; } 59 // Must be implemented by derived classes 60 virtual TransportResult SendPacket(MediaPacket& packet) = 0; 61 62 // Get the thread. GetThread()63 const nsCOMPtr<nsIEventTarget> GetThread() const { return target_; } 64 65 // Event definitions that one can register for 66 // State has changed 67 sigslot::signal2<TransportLayer*, State> SignalStateChange; 68 // Data received on the flow 69 sigslot::signal2<TransportLayer*, MediaPacket&> SignalPacketReceived; 70 71 // Return the layer id for this layer 72 virtual const std::string id() const = 0; 73 74 // The id of the flow flow_id()75 const std::string& flow_id() const { return flow_id_; } 76 77 protected: WasInserted()78 virtual void WasInserted() {} 79 virtual void SetState(State state, const char* file, unsigned line); 80 // Check if we are on the right thread CheckThread()81 void CheckThread() const { MOZ_ASSERT(CheckThreadInt(), "Wrong thread"); } 82 83 State state_; 84 std::string flow_id_; 85 TransportLayer* downward_; // The next layer in the stack 86 nsCOMPtr<nsIEventTarget> target_; 87 88 private: 89 DISALLOW_COPY_ASSIGN(TransportLayer); 90 CheckThreadInt()91 bool CheckThreadInt() const { 92 bool on; 93 94 if (!target_) // OK if no thread set. 95 return true; 96 97 NS_ENSURE_SUCCESS(target_->IsOnCurrentThread(&on), false); 98 NS_ENSURE_TRUE(on, false); 99 100 return true; 101 } 102 }; 103 104 #define LAYER_INFO \ 105 "Flow[" << flow_id() << "(none)" \ 106 << "]; Layer[" << id() << "]: " 107 #define TL_SET_STATE(x) SetState((x), __FILE__, __LINE__) 108 109 } // namespace mozilla 110 #endif 111