blob: 4c61313d0571686727e0b695e2a1925798c9ef1f [file] [log] [blame]
Austin Schuh52e5e3a2021-04-24 22:30:02 -07001#ifndef AOS_NETWORK_RAWRTC_H_
2#define AOS_NETWORK_RAWRTC_H_
3
4#include <functional>
5#include <string>
6
7extern "C" {
8#include <rawrtc.h>
9
10#include "external/com_github_rawrtc_rawrtc_common/include/rawrtcc/utils.h"
11}
12
13#include "flatbuffers/flatbuffers.h"
14#include "glog/logging.h"
15
16namespace aos {
17namespace web_proxy {
18
19// TODO(austin): This doesn't allow streaming data in.
20#define CHECK_RAWRTC(x) \
21 [&]() { \
22 enum rawrtc_code r = x; \
23 return CHECK(r == RAWRTC_CODE_SUCCESS) \
24 << " actual " << rawrtc_code_to_str(r); \
25 }()
26
27#define CHECK_RAWRTC_IGNORE(x, i) \
28 [&]() { \
29 enum rawrtc_code r = x; \
30 for (auto w : i) { \
31 if (w == r) return; \
32 } \
33 return CHECK(r == RAWRTC_CODE_SUCCESS); \
34 }()
35
36// Wrapper around a RawRTC data channel to manage it's lifetime and provide C++
37// callbacks for all the callbacks.
38//
39// There are 3 phases of the object's lifetime.
40// 1) Initialization. Callbacks can be set here.
41// 2) Open. Calling Open transitions the channel to be open and triggers the
42// on_open callback to be called.
43// 3) Close. This must be called before destroying the channel and calls the
44// on_close callback and shuts down the channel.
45class ScopedDataChannel {
46 public:
James Kuszmaula5822682021-12-23 18:39:28 -080047 static std::shared_ptr<ScopedDataChannel> MakeDataChannel();
Austin Schuh52e5e3a2021-04-24 22:30:02 -070048 ScopedDataChannel(const ScopedDataChannel &) = delete;
49 ScopedDataChannel &operator=(const ScopedDataChannel &) = delete;
50
51 ~ScopedDataChannel();
52
53 // Setters for all the callbacks. These may be called whenever.
54
55 // Registers a callback to be called when the channel is opened. This only
56 // gets called once during or after Open is called.
57 void set_on_open(std::function<void()> &&fn) { on_open_ = std::move(fn); }
58
59 // Registers a callback to be called when the channel is closed. This only
60 // gets called once during or after Close is called.
61 void set_on_close(std::function<void()> &&fn) { on_close_ = std::move(fn); }
62
63 void set_on_buffered_amount_low(std::function<void()> &&fn) {
64 on_buffered_amount_low_ = std::move(fn);
65 }
66 void set_on_error(std::function<void()> &&fn) { on_error_ = std::move(fn); }
67 void set_on_message(
68 std::function<void(struct mbuf *const,
69 enum rawrtc_data_channel_message_flag const)> &&fn) {
70 on_message_ = std::move(fn);
71 }
72
73 // Opens the channel on the provided connection with the provided label. This
74 // is separate so we can optionally register callbacks before opening.
75 void Open(struct rawrtc_peer_connection *connection,
76 const std::string &label);
77 // Takes over an already open channel.
78 void Open(struct rawrtc_data_channel *channel);
79
80 // Closes the channel. It must be open first.
81 void Close();
82
83 // Sends a buffer.
84 void Send(const ::flatbuffers::DetachedBuffer &buffer);
85 void Send(struct mbuf *buffer);
86
87 std::string_view label() const { return label_; }
88
89 // Returns the amount of data buffered.
90 uint64_t buffered_amount();
91
92 private:
James Kuszmaula5822682021-12-23 18:39:28 -080093 ScopedDataChannel();
Austin Schuh52e5e3a2021-04-24 22:30:02 -070094 // Trampolines from C -> C++.
95 static void StaticDataChannelOpenHandler(void *const arg);
96 static void StaticBufferedAmountLowHandler(void *const arg);
97 static void StaticDataChannelErrorHandler(void *const arg);
98 static void StaticDataChannelCloseHandler(void *const arg);
99 static void StaticDataChannelMessageHandler(
100 struct mbuf *const
101 buffer, // nullable (in case partial delivery has been requested)
102 enum rawrtc_data_channel_message_flag const flags, void *const arg);
103
104 // Our channel and the label for it.
105 std::string label_;
106 struct rawrtc_data_channel *data_channel_ = nullptr;
107
108 bool opened_ = false;
109 bool closed_ = false;
110
111 std::function<void()> on_open_;
112 std::function<void()> on_buffered_amount_low_;
113 std::function<void()> on_error_;
114 std::function<void()> on_close_;
115 std::function<void(struct mbuf *const,
116 enum rawrtc_data_channel_message_flag const)>
117 on_message_;
118
119 // Self referential pointer to keep ourselves in scope until close() gets
120 // called.
121 std::shared_ptr<ScopedDataChannel> self_;
122};
123
124// Wraper around a RawRTC connection to both manage it's lifetime and provide
125// std::function interfaces for the callbacks.
126class RawRTCConnection {
127 public:
128 RawRTCConnection();
129
130 virtual ~RawRTCConnection();
131
132 void set_on_negotiation_needed(std::function<void()> &&fn) {
133 on_negotiation_needed_ = std::move(fn);
134 }
135 void set_on_local_candidate(
136 std::function<void(struct rawrtc_peer_connection_ice_candidate *,
137 char const *)> &&fn) {
138 on_local_candidate_ = std::move(fn);
139 }
140 // Sets the handler for a peer connection local candidate error. Arguments
141 // are the candidate, URL, error_code and error_text.
142 void set_on_peer_connection_local_candidate_error(
143 std::function<void(struct rawrtc_peer_connection_ice_candidate *,
144 char const *, uint16_t, char const *)> &&fn) {
145 on_peer_connection_local_candidate_error_ = std::move(fn);
146 }
147 void set_on_signaling_state_change(
148 std::function<void(enum rawrtc_signaling_state const)> &&fn) {
149 on_signaling_state_change_ = std::move(fn);
150 }
151 void set_on_ice_transport_state_change(
152 std::function<void(const enum rawrtc_ice_transport_state)> &&fn) {
153 on_ice_transport_state_change_ = std::move(fn);
154 }
155 void set_on_ice_gatherer_state_change(
156 std::function<void(const enum rawrtc_ice_gatherer_state)> &&fn) {
157 on_ice_gatherer_state_change_ = std::move(fn);
158 }
159 void set_on_connection_state_change(
160 std::function<void(const enum rawrtc_peer_connection_state)> &&fn) {
161 on_connection_state_change_ = std::move(fn);
162 }
163
164 // TODO(austin): Really, this should be a ScopedDataChannel object.
165 void set_on_data_channel(
166 std::function<void(std::shared_ptr<ScopedDataChannel>)> &&fn) {
167 on_data_channel_ = std::move(fn);
168 }
169
170 // Opens the connection. This lets us register callbacks before starting it.
171 void Open();
172
173 // Returns the connection if Open has been called.
174 struct rawrtc_peer_connection *connection() {
175 return connection_;
176 }
177
178 private:
179 // Trampolines from C -> C++.
180 static void StaticNegotiationNeededHandler(void *const arg);
181 static void StaticLocalCandidateHandler(
182 struct rawrtc_peer_connection_ice_candidate *const candidate,
183 char const *const url, void *const arg);
184 static void StaticPeerConnectionLocalCandidateErrorHandler(
185 struct rawrtc_peer_connection_ice_candidate *const candidate,
186 char const *const url, uint16_t const error_code,
187 char const *const error_text, void *const arg);
188 static void StaticSignalingStateChangeHandler(
189 const enum rawrtc_signaling_state state, void *const arg);
190 static void StaticIceTransportStateChangeHandler(
191 const enum rawrtc_ice_transport_state state, void *const arg);
192 static void StaticIceGathererStateChangeHandler(
193 const enum rawrtc_ice_gatherer_state state, void *const arg);
194 static void StaticConnectionStateChangeHandler(
195 const enum rawrtc_peer_connection_state state, void *const arg);
196 static void StaticDataChannelHandler(
197 struct rawrtc_data_channel *const channel, void *const arg);
198
199 // The connection.
200 struct rawrtc_peer_connection *connection_ = nullptr;
201
202 // Callbacks
203 std::function<void()> on_negotiation_needed_;
204 std::function<void(struct rawrtc_peer_connection_ice_candidate *,
205 char const *)>
206 on_local_candidate_;
207 std::function<void(struct rawrtc_peer_connection_ice_candidate *,
208 char const *, uint16_t, char const *)>
209 on_peer_connection_local_candidate_error_;
210 std::function<void(enum rawrtc_signaling_state const)>
211 on_signaling_state_change_;
212 std::function<void(const enum rawrtc_ice_transport_state)>
213 on_ice_transport_state_change_;
214 std::function<void(const enum rawrtc_ice_gatherer_state)>
215 on_ice_gatherer_state_change_;
216 std::function<void(const enum rawrtc_peer_connection_state)>
217 on_connection_state_change_;
218 std::function<void(std::shared_ptr<ScopedDataChannel>)> on_data_channel_;
219};
220
221} // namespace web_proxy
222} // namespace aos
223
224#endif // AOS_NETWORK_RAWRTC_H_