James Kuszmaul | 4a42b18 | 2021-01-17 11:32:46 -0800 | [diff] [blame^] | 1 | #include "handler.h" |
| 2 | #include "common.h" |
| 3 | #include "utils.h" |
| 4 | #include <rawrtc.h> |
| 5 | #include <rawrtcc.h> |
| 6 | #include <rawrtcdc.h> |
| 7 | #include <re.h> |
| 8 | #include <string.h> // strlen |
| 9 | |
| 10 | #define DEBUG_MODULE "helper-handler" |
| 11 | #define DEBUG_LEVEL 7 |
| 12 | #include <re_dbg.h> |
| 13 | |
| 14 | /* |
| 15 | * Print the ICE gatherer's state. |
| 16 | */ |
| 17 | void default_ice_gatherer_state_change_handler( |
| 18 | enum rawrtc_ice_gatherer_state const state, // read-only |
| 19 | void* const arg // will be casted to `struct client*` |
| 20 | ) { |
| 21 | struct client* const client = arg; |
| 22 | char const* const state_name = rawrtc_ice_gatherer_state_to_name(state); |
| 23 | (void) arg; |
| 24 | DEBUG_PRINTF("(%s) ICE gatherer state: %s\n", client->name, state_name); |
| 25 | } |
| 26 | |
| 27 | /* |
| 28 | * Print the ICE gatherer's error event. |
| 29 | */ |
| 30 | void default_ice_gatherer_error_handler( |
| 31 | struct rawrtc_ice_candidate* const candidate, // read-only, nullable |
| 32 | char const* const url, // read-only |
| 33 | uint16_t const error_code, // read-only |
| 34 | char const* const error_text, // read-only |
| 35 | void* const arg // will be casted to `struct client*` |
| 36 | ) { |
| 37 | struct client* const client = arg; |
| 38 | (void) candidate; |
| 39 | (void) error_code; |
| 40 | (void) arg; |
| 41 | DEBUG_NOTICE("(%s) ICE gatherer error, URL: %s, reason: %s\n", client->name, url, error_text); |
| 42 | } |
| 43 | |
| 44 | /* |
| 45 | * Print the newly gathered local candidate. |
| 46 | */ |
| 47 | void default_ice_gatherer_local_candidate_handler( |
| 48 | struct rawrtc_ice_candidate* const candidate, |
| 49 | char const* const url, // read-only |
| 50 | void* const arg // will be casted to `struct client*` |
| 51 | ) { |
| 52 | struct client* const client = arg; |
| 53 | (void) arg; |
| 54 | print_ice_candidate(candidate, url, NULL, client); |
| 55 | } |
| 56 | |
| 57 | /* |
| 58 | * Print the ICE transport's state. |
| 59 | */ |
| 60 | void default_ice_transport_state_change_handler( |
| 61 | enum rawrtc_ice_transport_state const state, |
| 62 | void* const arg // will be casted to `struct client*` |
| 63 | ) { |
| 64 | struct client* const client = arg; |
| 65 | char const* const state_name = rawrtc_ice_transport_state_to_name(state); |
| 66 | (void) arg; |
| 67 | DEBUG_PRINTF("(%s) ICE transport state: %s\n", client->name, state_name); |
| 68 | } |
| 69 | |
| 70 | /* |
| 71 | * Print the ICE candidate pair change event. |
| 72 | */ |
| 73 | void default_ice_transport_candidate_pair_change_handler( |
| 74 | struct rawrtc_ice_candidate* const local, // read-only |
| 75 | struct rawrtc_ice_candidate* const remote, // read-only |
| 76 | void* const arg // will be casted to `struct client*` |
| 77 | ) { |
| 78 | struct client* const client = arg; |
| 79 | (void) local; |
| 80 | (void) remote; |
| 81 | DEBUG_PRINTF("(%s) ICE transport candidate pair change\n", client->name); |
| 82 | } |
| 83 | |
| 84 | /* |
| 85 | * Print the DTLS transport's state. |
| 86 | */ |
| 87 | void default_dtls_transport_state_change_handler( |
| 88 | enum rawrtc_dtls_transport_state const state, // read-only |
| 89 | void* const arg // will be casted to `struct client*` |
| 90 | ) { |
| 91 | struct client* const client = arg; |
| 92 | char const* const state_name = rawrtc_dtls_transport_state_to_name(state); |
| 93 | DEBUG_PRINTF("(%s) DTLS transport state change: %s\n", client->name, state_name); |
| 94 | } |
| 95 | |
| 96 | /* |
| 97 | * Print the DTLS transport's error event. |
| 98 | */ |
| 99 | void default_dtls_transport_error_handler( |
| 100 | // TODO: error.message (probably from OpenSSL) |
| 101 | void* const arg // will be casted to `struct client*` |
| 102 | ) { |
| 103 | struct client* const client = arg; |
| 104 | // TODO: Print error message |
| 105 | DEBUG_WARNING("(%s) DTLS transport error: %s\n", client->name, "???"); |
| 106 | } |
| 107 | |
| 108 | #if RAWRTC_HAVE_SCTP_REDIRECT_TRANSPORT |
| 109 | /* |
| 110 | * Print the SCTP redirect transport's state. |
| 111 | */ |
| 112 | void default_sctp_redirect_transport_state_change_handler( |
| 113 | enum rawrtc_sctp_redirect_transport_state const state, |
| 114 | void* const arg // will be casted to `struct client*` |
| 115 | ) { |
| 116 | struct client* const client = arg; |
| 117 | char const* const state_name = rawrtc_sctp_redirect_transport_state_to_name(state); |
| 118 | DEBUG_PRINTF("(%s) SCTP redirect transport state change: %s\n", client->name, state_name); |
| 119 | } |
| 120 | #endif |
| 121 | |
| 122 | /* |
| 123 | * Print the SCTP transport's state. |
| 124 | */ |
| 125 | void default_sctp_transport_state_change_handler( |
| 126 | enum rawrtc_sctp_transport_state const state, |
| 127 | void* const arg // will be casted to `struct client*` |
| 128 | ) { |
| 129 | struct client* const client = arg; |
| 130 | char const* const state_name = rawrtc_sctp_transport_state_to_name(state); |
| 131 | DEBUG_PRINTF("(%s) SCTP transport state change: %s\n", client->name, state_name); |
| 132 | } |
| 133 | |
| 134 | /* |
| 135 | * Print the newly created data channel's parameter. |
| 136 | */ |
| 137 | void default_data_channel_handler( |
| 138 | struct rawrtc_data_channel* const channel, // read-only, MUST be referenced when used |
| 139 | void* const arg // will be casted to `struct client*` |
| 140 | ) { |
| 141 | struct client* const client = arg; |
| 142 | struct rawrtc_data_channel_parameters* parameters; |
| 143 | enum rawrtc_code const ignore[] = {RAWRTC_CODE_NO_VALUE}; |
| 144 | char* label = NULL; |
| 145 | |
| 146 | // Get data channel label and protocol |
| 147 | EOE(rawrtc_data_channel_get_parameters(¶meters, channel)); |
| 148 | EOEIGN(rawrtc_data_channel_parameters_get_label(&label, parameters), ignore); |
| 149 | DEBUG_INFO("(%s) New data channel instance: %s\n", client->name, label ? label : "n/a"); |
| 150 | mem_deref(label); |
| 151 | mem_deref(parameters); |
| 152 | } |
| 153 | |
| 154 | /* |
| 155 | * Print the data channel open event. |
| 156 | */ |
| 157 | void default_data_channel_open_handler( |
| 158 | void* const arg // will be casted to `struct data_channel_helper*` |
| 159 | ) { |
| 160 | struct data_channel_helper* const channel = arg; |
| 161 | struct client* const client = channel->client; |
| 162 | DEBUG_PRINTF("(%s) Data channel open: %s\n", client->name, channel->label); |
| 163 | } |
| 164 | |
| 165 | /* |
| 166 | * Print the data channel buffered amount low event. |
| 167 | */ |
| 168 | void default_data_channel_buffered_amount_low_handler( |
| 169 | void* const arg // will be casted to `struct data_channel_helper*` |
| 170 | ) { |
| 171 | struct data_channel_helper* const channel = arg; |
| 172 | struct client* const client = channel->client; |
| 173 | DEBUG_PRINTF("(%s) Data channel buffered amount low: %s\n", client->name, channel->label); |
| 174 | } |
| 175 | |
| 176 | /* |
| 177 | * Print the data channel error event. |
| 178 | */ |
| 179 | void default_data_channel_error_handler( |
| 180 | void* const arg // will be casted to `struct data_channel_helper*` |
| 181 | ) { |
| 182 | struct data_channel_helper* const channel = arg; |
| 183 | struct client* const client = channel->client; |
| 184 | DEBUG_WARNING("(%s) Data channel error: %s\n", client->name, channel->label); |
| 185 | } |
| 186 | |
| 187 | /* |
| 188 | * Print the data channel close event. |
| 189 | */ |
| 190 | void default_data_channel_close_handler( |
| 191 | void* const arg // will be casted to `struct data_channel_helper*` |
| 192 | ) { |
| 193 | struct data_channel_helper* const channel = arg; |
| 194 | struct client* const client = channel->client; |
| 195 | DEBUG_PRINTF("(%s) Data channel closed: %s\n", client->name, channel->label); |
| 196 | } |
| 197 | |
| 198 | char const* const separator = ", "; |
| 199 | |
| 200 | static int debug_data_channel_message_flags( |
| 201 | struct re_printf* const pf, enum rawrtc_data_channel_message_flag const flags) { |
| 202 | int err = 0; |
| 203 | char const* prefix = ""; |
| 204 | |
| 205 | if (flags & RAWRTC_DATA_CHANNEL_MESSAGE_FLAG_IS_ABORTED) { |
| 206 | err |= re_hprintf(pf, "%saborted", prefix); |
| 207 | prefix = separator; |
| 208 | } |
| 209 | if (flags & RAWRTC_DATA_CHANNEL_MESSAGE_FLAG_IS_COMPLETE) { |
| 210 | err |= re_hprintf(pf, "%scomplete", prefix); |
| 211 | prefix = separator; |
| 212 | } |
| 213 | if (flags & RAWRTC_DATA_CHANNEL_MESSAGE_FLAG_IS_STRING) { |
| 214 | err |= re_hprintf(pf, "%sstring", prefix); |
| 215 | prefix = separator; |
| 216 | } |
| 217 | if (flags & RAWRTC_DATA_CHANNEL_MESSAGE_FLAG_IS_BINARY) { |
| 218 | err |= re_hprintf(pf, "%sbinary", prefix); |
| 219 | } |
| 220 | |
| 221 | return err; |
| 222 | } |
| 223 | |
| 224 | /* |
| 225 | * Print the data channel's received message's size. |
| 226 | */ |
| 227 | void default_data_channel_message_handler( |
| 228 | struct mbuf* const buffer, |
| 229 | enum rawrtc_data_channel_message_flag const flags, |
| 230 | void* const arg // will be casted to `struct data_channel_helper*` |
| 231 | ) { |
| 232 | struct data_channel_helper* const channel = arg; |
| 233 | struct client* const client = channel->client; |
| 234 | DEBUG_PRINTF( |
| 235 | "(%s) Incoming message for data channel %s: %zu bytes; flags=(%H)\n", client->name, |
| 236 | channel->label, mbuf_get_left(buffer), debug_data_channel_message_flags, flags); |
| 237 | } |
| 238 | |
| 239 | /* |
| 240 | * Print negotiation needed (duh!) |
| 241 | */ |
| 242 | void default_negotiation_needed_handler(void* const arg) { |
| 243 | struct client* const client = arg; |
| 244 | DEBUG_PRINTF("(%s) Negotiation needed\n", client->name); |
| 245 | } |
| 246 | |
| 247 | /* |
| 248 | * Print the peer connection's state. |
| 249 | */ |
| 250 | void default_peer_connection_state_change_handler( |
| 251 | enum rawrtc_peer_connection_state const state, // read-only |
| 252 | void* const arg // will be casted to `struct client*` |
| 253 | ) { |
| 254 | struct client* const client = arg; |
| 255 | char const* const state_name = rawrtc_peer_connection_state_to_name(state); |
| 256 | DEBUG_PRINTF("(%s) Peer connection state change: %s\n", client->name, state_name); |
| 257 | } |
| 258 | |
| 259 | /* |
| 260 | * Print the newly gathered local candidate (peer connection variant). |
| 261 | */ |
| 262 | void default_peer_connection_local_candidate_handler( |
| 263 | struct rawrtc_peer_connection_ice_candidate* const candidate, |
| 264 | char const* const url, // read-only |
| 265 | void* const arg) { |
| 266 | struct client* const client = arg; |
| 267 | struct rawrtc_ice_candidate* ortc_candidate = NULL; |
| 268 | |
| 269 | // Get underlying ORTC ICE candidate (if any) |
| 270 | if (candidate) { |
| 271 | EOE(rawrtc_peer_connection_ice_candidate_get_ortc_candidate(&ortc_candidate, candidate)); |
| 272 | } |
| 273 | |
| 274 | // Print local candidate |
| 275 | print_ice_candidate(ortc_candidate, url, candidate, client); |
| 276 | mem_deref(ortc_candidate); |
| 277 | } |
| 278 | |
| 279 | /* |
| 280 | * Print the peer connections local candidate error event. |
| 281 | */ |
| 282 | void default_peer_connection_local_candidate_error_handler( |
| 283 | struct rawrtc_peer_connection_ice_candidate* const candidate, // read-only, nullable |
| 284 | char const* const url, // read-only |
| 285 | uint16_t const error_code, // read-only |
| 286 | char const* const error_text, // read-only |
| 287 | void* const arg // will be casted to `struct client*` |
| 288 | ) { |
| 289 | struct client* const client = arg; |
| 290 | (void) candidate; |
| 291 | (void) error_code; |
| 292 | (void) arg; |
| 293 | DEBUG_NOTICE("(%s) ICE candidate error, URL: %s, reason: %s\n", client->name, url, error_text); |
| 294 | } |
| 295 | |
| 296 | /* |
| 297 | * Print the signaling state. |
| 298 | */ |
| 299 | void default_signaling_state_change_handler( |
| 300 | enum rawrtc_signaling_state const state, // read-only |
| 301 | void* const arg) { |
| 302 | struct client* const client = arg; |
| 303 | char const* const state_name = rawrtc_signaling_state_to_name(state); |
| 304 | DEBUG_PRINTF("(%s) Signaling state change: %s\n", client->name, state_name); |
| 305 | } |
| 306 | |
| 307 | /* |
| 308 | * Stop the main loop. |
| 309 | */ |
| 310 | void default_signal_handler(int sig) { |
| 311 | DEBUG_INFO("Got signal: %d, terminating...\n", sig); |
| 312 | re_cancel(); |
| 313 | } |
| 314 | |
| 315 | /* |
| 316 | * FD-listener that stops the main loop in case the input buffer |
| 317 | * contains a line feed or a carriage return. |
| 318 | */ |
| 319 | void stop_on_return_handler(int flags, void* arg) { |
| 320 | char buffer[128]; |
| 321 | size_t length; |
| 322 | (void) flags; |
| 323 | (void) arg; |
| 324 | |
| 325 | // Get message from stdin |
| 326 | if (!fgets((char*) buffer, 128, stdin)) { |
| 327 | EOR(errno); |
| 328 | } |
| 329 | length = strlen(buffer); |
| 330 | |
| 331 | // Exit? |
| 332 | if (length > 0 && length < 3 && (buffer[0] == '\n' || buffer[0] == '\r')) { |
| 333 | // Stop main loop |
| 334 | DEBUG_INFO("Exiting\n"); |
| 335 | re_cancel(); |
| 336 | } |
| 337 | } |