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