Squashed 'third_party/rawrtc/rawrtc/' content from commit aa3ae4b24

Change-Id: I38a655a4259b62f591334e90a1315bd4e7e4d8ec
git-subtree-dir: third_party/rawrtc/rawrtc
git-subtree-split: aa3ae4b247275cc6e69c30613b3a4ba7fdc82d1b
diff --git a/tools/helper/handler.c b/tools/helper/handler.c
new file mode 100644
index 0000000..f6d8d1a
--- /dev/null
+++ b/tools/helper/handler.c
@@ -0,0 +1,337 @@
+#include "handler.h"
+#include "common.h"
+#include "utils.h"
+#include <rawrtc.h>
+#include <rawrtcc.h>
+#include <rawrtcdc.h>
+#include <re.h>
+#include <string.h>  // strlen
+
+#define DEBUG_MODULE "helper-handler"
+#define DEBUG_LEVEL 7
+#include <re_dbg.h>
+
+/*
+ * Print the ICE gatherer's state.
+ */
+void default_ice_gatherer_state_change_handler(
+    enum rawrtc_ice_gatherer_state const state,  // read-only
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    char const* const state_name = rawrtc_ice_gatherer_state_to_name(state);
+    (void) arg;
+    DEBUG_PRINTF("(%s) ICE gatherer state: %s\n", client->name, state_name);
+}
+
+/*
+ * Print the ICE gatherer's error event.
+ */
+void default_ice_gatherer_error_handler(
+    struct rawrtc_ice_candidate* const candidate,  // read-only, nullable
+    char const* const url,  // read-only
+    uint16_t const error_code,  // read-only
+    char const* const error_text,  // read-only
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    (void) candidate;
+    (void) error_code;
+    (void) arg;
+    DEBUG_NOTICE("(%s) ICE gatherer error, URL: %s, reason: %s\n", client->name, url, error_text);
+}
+
+/*
+ * Print the newly gathered local candidate.
+ */
+void default_ice_gatherer_local_candidate_handler(
+    struct rawrtc_ice_candidate* const candidate,
+    char const* const url,  // read-only
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    (void) arg;
+    print_ice_candidate(candidate, url, NULL, client);
+}
+
+/*
+ * Print the ICE transport's state.
+ */
+void default_ice_transport_state_change_handler(
+    enum rawrtc_ice_transport_state const state,
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    char const* const state_name = rawrtc_ice_transport_state_to_name(state);
+    (void) arg;
+    DEBUG_PRINTF("(%s) ICE transport state: %s\n", client->name, state_name);
+}
+
+/*
+ * Print the ICE candidate pair change event.
+ */
+void default_ice_transport_candidate_pair_change_handler(
+    struct rawrtc_ice_candidate* const local,  // read-only
+    struct rawrtc_ice_candidate* const remote,  // read-only
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    (void) local;
+    (void) remote;
+    DEBUG_PRINTF("(%s) ICE transport candidate pair change\n", client->name);
+}
+
+/*
+ * Print the DTLS transport's state.
+ */
+void default_dtls_transport_state_change_handler(
+    enum rawrtc_dtls_transport_state const state,  // read-only
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    char const* const state_name = rawrtc_dtls_transport_state_to_name(state);
+    DEBUG_PRINTF("(%s) DTLS transport state change: %s\n", client->name, state_name);
+}
+
+/*
+ * Print the DTLS transport's error event.
+ */
+void default_dtls_transport_error_handler(
+    // TODO: error.message (probably from OpenSSL)
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    // TODO: Print error message
+    DEBUG_WARNING("(%s) DTLS transport error: %s\n", client->name, "???");
+}
+
+#if RAWRTC_HAVE_SCTP_REDIRECT_TRANSPORT
+/*
+ * Print the SCTP redirect transport's state.
+ */
+void default_sctp_redirect_transport_state_change_handler(
+    enum rawrtc_sctp_redirect_transport_state const state,
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    char const* const state_name = rawrtc_sctp_redirect_transport_state_to_name(state);
+    DEBUG_PRINTF("(%s) SCTP redirect transport state change: %s\n", client->name, state_name);
+}
+#endif
+
+/*
+ * Print the SCTP transport's state.
+ */
+void default_sctp_transport_state_change_handler(
+    enum rawrtc_sctp_transport_state const state,
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    char const* const state_name = rawrtc_sctp_transport_state_to_name(state);
+    DEBUG_PRINTF("(%s) SCTP transport state change: %s\n", client->name, state_name);
+}
+
+/*
+ * Print the newly created data channel's parameter.
+ */
+void default_data_channel_handler(
+    struct rawrtc_data_channel* const channel,  // read-only, MUST be referenced when used
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    struct rawrtc_data_channel_parameters* parameters;
+    enum rawrtc_code const ignore[] = {RAWRTC_CODE_NO_VALUE};
+    char* label = NULL;
+
+    // Get data channel label and protocol
+    EOE(rawrtc_data_channel_get_parameters(&parameters, channel));
+    EOEIGN(rawrtc_data_channel_parameters_get_label(&label, parameters), ignore);
+    DEBUG_INFO("(%s) New data channel instance: %s\n", client->name, label ? label : "n/a");
+    mem_deref(label);
+    mem_deref(parameters);
+}
+
+/*
+ * Print the data channel open event.
+ */
+void default_data_channel_open_handler(
+    void* const arg  // will be casted to `struct data_channel_helper*`
+) {
+    struct data_channel_helper* const channel = arg;
+    struct client* const client = channel->client;
+    DEBUG_PRINTF("(%s) Data channel open: %s\n", client->name, channel->label);
+}
+
+/*
+ * Print the data channel buffered amount low event.
+ */
+void default_data_channel_buffered_amount_low_handler(
+    void* const arg  // will be casted to `struct data_channel_helper*`
+) {
+    struct data_channel_helper* const channel = arg;
+    struct client* const client = channel->client;
+    DEBUG_PRINTF("(%s) Data channel buffered amount low: %s\n", client->name, channel->label);
+}
+
+/*
+ * Print the data channel error event.
+ */
+void default_data_channel_error_handler(
+    void* const arg  // will be casted to `struct data_channel_helper*`
+) {
+    struct data_channel_helper* const channel = arg;
+    struct client* const client = channel->client;
+    DEBUG_WARNING("(%s) Data channel error: %s\n", client->name, channel->label);
+}
+
+/*
+ * Print the data channel close event.
+ */
+void default_data_channel_close_handler(
+    void* const arg  // will be casted to `struct data_channel_helper*`
+) {
+    struct data_channel_helper* const channel = arg;
+    struct client* const client = channel->client;
+    DEBUG_PRINTF("(%s) Data channel closed: %s\n", client->name, channel->label);
+}
+
+char const* const separator = ", ";
+
+static int debug_data_channel_message_flags(
+    struct re_printf* const pf, enum rawrtc_data_channel_message_flag const flags) {
+    int err = 0;
+    char const* prefix = "";
+
+    if (flags & RAWRTC_DATA_CHANNEL_MESSAGE_FLAG_IS_ABORTED) {
+        err |= re_hprintf(pf, "%saborted", prefix);
+        prefix = separator;
+    }
+    if (flags & RAWRTC_DATA_CHANNEL_MESSAGE_FLAG_IS_COMPLETE) {
+        err |= re_hprintf(pf, "%scomplete", prefix);
+        prefix = separator;
+    }
+    if (flags & RAWRTC_DATA_CHANNEL_MESSAGE_FLAG_IS_STRING) {
+        err |= re_hprintf(pf, "%sstring", prefix);
+        prefix = separator;
+    }
+    if (flags & RAWRTC_DATA_CHANNEL_MESSAGE_FLAG_IS_BINARY) {
+        err |= re_hprintf(pf, "%sbinary", prefix);
+    }
+
+    return err;
+}
+
+/*
+ * Print the data channel's received message's size.
+ */
+void default_data_channel_message_handler(
+    struct mbuf* const buffer,
+    enum rawrtc_data_channel_message_flag const flags,
+    void* const arg  // will be casted to `struct data_channel_helper*`
+) {
+    struct data_channel_helper* const channel = arg;
+    struct client* const client = channel->client;
+    DEBUG_PRINTF(
+        "(%s) Incoming message for data channel %s: %zu bytes; flags=(%H)\n", client->name,
+        channel->label, mbuf_get_left(buffer), debug_data_channel_message_flags, flags);
+}
+
+/*
+ * Print negotiation needed (duh!)
+ */
+void default_negotiation_needed_handler(void* const arg) {
+    struct client* const client = arg;
+    DEBUG_PRINTF("(%s) Negotiation needed\n", client->name);
+}
+
+/*
+ * Print the peer connection's state.
+ */
+void default_peer_connection_state_change_handler(
+    enum rawrtc_peer_connection_state const state,  // read-only
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    char const* const state_name = rawrtc_peer_connection_state_to_name(state);
+    DEBUG_PRINTF("(%s) Peer connection state change: %s\n", client->name, state_name);
+}
+
+/*
+ * Print the newly gathered local candidate (peer connection variant).
+ */
+void default_peer_connection_local_candidate_handler(
+    struct rawrtc_peer_connection_ice_candidate* const candidate,
+    char const* const url,  // read-only
+    void* const arg) {
+    struct client* const client = arg;
+    struct rawrtc_ice_candidate* ortc_candidate = NULL;
+
+    // Get underlying ORTC ICE candidate (if any)
+    if (candidate) {
+        EOE(rawrtc_peer_connection_ice_candidate_get_ortc_candidate(&ortc_candidate, candidate));
+    }
+
+    // Print local candidate
+    print_ice_candidate(ortc_candidate, url, candidate, client);
+    mem_deref(ortc_candidate);
+}
+
+/*
+ * Print the peer connections local candidate error event.
+ */
+void default_peer_connection_local_candidate_error_handler(
+    struct rawrtc_peer_connection_ice_candidate* const candidate,  // read-only, nullable
+    char const* const url,  // read-only
+    uint16_t const error_code,  // read-only
+    char const* const error_text,  // read-only
+    void* const arg  // will be casted to `struct client*`
+) {
+    struct client* const client = arg;
+    (void) candidate;
+    (void) error_code;
+    (void) arg;
+    DEBUG_NOTICE("(%s) ICE candidate error, URL: %s, reason: %s\n", client->name, url, error_text);
+}
+
+/*
+ * Print the signaling state.
+ */
+void default_signaling_state_change_handler(
+    enum rawrtc_signaling_state const state,  // read-only
+    void* const arg) {
+    struct client* const client = arg;
+    char const* const state_name = rawrtc_signaling_state_to_name(state);
+    DEBUG_PRINTF("(%s) Signaling state change: %s\n", client->name, state_name);
+}
+
+/*
+ * Stop the main loop.
+ */
+void default_signal_handler(int sig) {
+    DEBUG_INFO("Got signal: %d, terminating...\n", sig);
+    re_cancel();
+}
+
+/*
+ * FD-listener that stops the main loop in case the input buffer
+ * contains a line feed or a carriage return.
+ */
+void stop_on_return_handler(int flags, void* arg) {
+    char buffer[128];
+    size_t length;
+    (void) flags;
+    (void) arg;
+
+    // Get message from stdin
+    if (!fgets((char*) buffer, 128, stdin)) {
+        EOR(errno);
+    }
+    length = strlen(buffer);
+
+    // Exit?
+    if (length > 0 && length < 3 && (buffer[0] == '\n' || buffer[0] == '\r')) {
+        // Stop main loop
+        DEBUG_INFO("Exiting\n");
+        re_cancel();
+    }
+}