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