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