1 /* Copyright 2018 The WebRTC project authors. All Rights Reserved.
2  *
3  *  Use of this source code is governed by a BSD-style license
4  *  that can be found in the LICENSE file in the root of the source
5  *  tree. An additional intellectual property rights grant can be found
6  *  in the file PATENTS.  All contributing project authors may
7  *  be found in the AUTHORS file in the root of the source tree.
8  */
9 
10 // This is EXPERIMENTAL interface for media and datagram transports.
11 
12 #ifndef API_TRANSPORT_DATAGRAM_TRANSPORT_INTERFACE_H_
13 #define API_TRANSPORT_DATAGRAM_TRANSPORT_INTERFACE_H_
14 
15 #include <memory>
16 #include <string>
17 #include <utility>
18 
19 #include "absl/types/optional.h"
20 #include "api/array_view.h"
21 #include "api/rtc_error.h"
22 #include "api/transport/congestion_control_interface.h"
23 #include "api/transport/data_channel_transport_interface.h"
24 #include "api/units/data_rate.h"
25 #include "api/units/timestamp.h"
26 
27 namespace rtc {
28 class PacketTransportInternal;
29 }  // namespace rtc
30 
31 namespace webrtc {
32 
33 class MediaTransportStateCallback;
34 
35 typedef int64_t DatagramId;
36 
37 struct DatagramAck {
38   // |datagram_id| is same as passed in
39   // DatagramTransportInterface::SendDatagram.
40   DatagramId datagram_id;
41 
42   // The timestamp at which the remote peer received the identified datagram,
43   // according to that peer's clock.
44   Timestamp receive_timestamp = Timestamp::MinusInfinity();
45 };
46 
47 // All sink methods are called on network thread.
48 class DatagramSinkInterface {
49  public:
~DatagramSinkInterface()50   virtual ~DatagramSinkInterface() {}
51 
52   // Called when new packet is received.
53   virtual void OnDatagramReceived(rtc::ArrayView<const uint8_t> data) = 0;
54 
55   // Called when datagram is actually sent (datragram can be delayed due
56   // to congestion control or fusing). |datagram_id| is same as passed in
57   // DatagramTransportInterface::SendDatagram.
58   virtual void OnDatagramSent(DatagramId datagram_id) = 0;
59 
60   // Called when datagram is ACKed.
61   virtual void OnDatagramAcked(const DatagramAck& datagram_ack) = 0;
62 
63   // Called when a datagram is lost.
64   virtual void OnDatagramLost(DatagramId datagram_id) = 0;
65 };
66 
67 // Datagram transport allows to send and receive unreliable packets (datagrams)
68 // and receive feedback from congestion control (via
69 // CongestionControlInterface). The idea is to send RTP packets as datagrams and
70 // have underlying implementation of datagram transport to use QUIC datagram
71 // protocol.
72 class DatagramTransportInterface : public DataChannelTransportInterface {
73  public:
74   virtual ~DatagramTransportInterface() = default;
75 
76   // Connect the datagram transport to the ICE transport.
77   // The implementation must be able to ignore incoming packets that don't
78   // belong to it.
79   virtual void Connect(rtc::PacketTransportInternal* packet_transport) = 0;
80 
81   // Returns congestion control feedback interface or nullptr if datagram
82   // transport does not implement congestion control.
83   //
84   // Note that right now datagram transport is used without congestion control,
85   // but we plan to use it in the future.
86   virtual CongestionControlInterface* congestion_control() = 0;
87 
88   // Sets a state observer callback. Before datagram transport is destroyed, the
89   // callback must be unregistered by setting it to nullptr.
90   // A newly registered callback will be called with the current state.
91   // Datagram transport does not invoke this callback concurrently.
92   virtual void SetTransportStateCallback(
93       MediaTransportStateCallback* callback) = 0;
94 
95   // Start asynchronous send of datagram. The status returned by this method
96   // only pertains to the synchronous operations (e.g. serialization /
97   // packetization), not to the asynchronous operation.
98   //
99   // Datagrams larger than GetLargestDatagramSize() will fail and return error.
100   //
101   // Datagrams are sent in FIFO order.
102   //
103   // |datagram_id| is only used in ACK/LOST notifications in
104   // DatagramSinkInterface and does not need to be unique.
105   virtual RTCError SendDatagram(rtc::ArrayView<const uint8_t> data,
106                                 DatagramId datagram_id) = 0;
107 
108   // Returns maximum size of datagram message, does not change.
109   // TODO(sukhanov): Because value may be undefined before connection setup
110   // is complete, consider returning error when called before connection is
111   // established. Currently returns hardcoded const, because integration
112   // prototype may call before connection is established.
113   virtual size_t GetLargestDatagramSize() const = 0;
114 
115   // Sets packet sink. Sink must be unset by calling
116   // SetDataTransportSink(nullptr) before the data transport is destroyed or
117   // before new sink is set.
118   virtual void SetDatagramSink(DatagramSinkInterface* sink) = 0;
119 
120   // Retrieves transport parameters for this datagram transport.  May be called
121   // on either client- or server-perspective transports.
122   //
123   // For servers, the parameters represent what kind of connections and data the
124   // server is prepared to accept.  This is generally a superset of acceptable
125   // parameters.
126   //
127   // For clients, the parameters echo the server configuration used to create
128   // the client, possibly removing any fields or parameters which the client
129   // does not understand.
130   virtual std::string GetTransportParameters() const = 0;
131 
132   // Sets remote transport parameters.  |remote_params| is a serialized string
133   // of opaque parameters, understood by the datagram transport implementation.
134   // Returns an error if |remote_params| are not compatible with this transport.
135   //
136   // TODO(mellem): Make pure virtual.  The default implementation maintains
137   // original negotiation behavior (negotiation falls back to RTP if the
138   // remote datagram transport fails to echo exactly the local parameters).
SetRemoteTransportParameters(absl::string_view remote_params)139   virtual RTCError SetRemoteTransportParameters(
140       absl::string_view remote_params) {
141     if (remote_params == GetTransportParameters()) {
142       return RTCError::OK();
143     }
144     return RTCError(RTCErrorType::UNSUPPORTED_PARAMETER,
145                     "Local and remote transport parameters do not match");
146   }
147 };
148 
149 }  // namespace webrtc
150 
151 #endif  // API_TRANSPORT_DATAGRAM_TRANSPORT_INTERFACE_H_
152