+const char *lttng_viewer_command_string(enum lttng_viewer_command cmd)
+{
+ switch (cmd){
+ case LTTNG_VIEWER_CONNECT:
+ return "CONNECT";
+ case LTTNG_VIEWER_LIST_SESSIONS:
+ return "LIST_SESSIONS";
+ case LTTNG_VIEWER_ATTACH_SESSION:
+ return "ATTACH_SESSION";
+ case LTTNG_VIEWER_GET_NEXT_INDEX:
+ return "GET_NEXT_INDEX";
+ case LTTNG_VIEWER_GET_PACKET:
+ return "GET_PACKET";
+ case LTTNG_VIEWER_GET_METADATA:
+ return "GET_METADATA";
+ case LTTNG_VIEWER_GET_NEW_STREAMS:
+ return "GET_NEW_STREAMS";
+ case LTTNG_VIEWER_CREATE_SESSION:
+ return "CREATE_SESSION";
+ case LTTNG_VIEWER_DETACH_SESSION:
+ return "DETACH_SESSION";
+ }
+
+ bt_common_abort();
+}
+
+static
+const char *lttng_viewer_next_index_return_code_string(
+ enum lttng_viewer_next_index_return_code code)
+{
+ switch (code) {
+ case LTTNG_VIEWER_INDEX_OK:
+ return "INDEX_OK";
+ case LTTNG_VIEWER_INDEX_RETRY:
+ return "INDEX_RETRY";
+ case LTTNG_VIEWER_INDEX_HUP:
+ return "INDEX_HUP";
+ case LTTNG_VIEWER_INDEX_ERR:
+ return "INDEX_ERR";
+ case LTTNG_VIEWER_INDEX_INACTIVE:
+ return "INDEX_INACTIVE";
+ case LTTNG_VIEWER_INDEX_EOF:
+ return "INDEX_EOF";
+ }
+
+ bt_common_abort();
+}
+
+static
+const char *lttng_viewer_get_packet_return_code_string(
+ enum lttng_viewer_get_packet_return_code code)
+{
+ switch (code) {
+ case LTTNG_VIEWER_GET_PACKET_OK:
+ return "GET_PACKET_OK";
+ case LTTNG_VIEWER_GET_PACKET_RETRY:
+ return "GET_PACKET_RETRY";
+ case LTTNG_VIEWER_GET_PACKET_ERR:
+ return "GET_PACKET_ERR";
+ case LTTNG_VIEWER_GET_PACKET_EOF:
+ return "GET_PACKET_EOF";
+ }
+
+ bt_common_abort();
+};
+
+static
+const char *lttng_viewer_seek_string(enum lttng_viewer_seek seek)
+{
+ switch (seek) {
+ case LTTNG_VIEWER_SEEK_BEGINNING:
+ return "SEEK_BEGINNING";
+ case LTTNG_VIEWER_SEEK_LAST:
+ return "SEEK_LAST";
+ }
+
+ bt_common_abort();
+}
+
+static inline
+enum lttng_live_iterator_status viewer_status_to_live_iterator_status(
+ enum lttng_live_viewer_status viewer_status)
+{
+ switch (viewer_status) {
+ case LTTNG_LIVE_VIEWER_STATUS_OK:
+ return LTTNG_LIVE_ITERATOR_STATUS_OK;
+ case LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED:
+ return LTTNG_LIVE_ITERATOR_STATUS_AGAIN;
+ case LTTNG_LIVE_VIEWER_STATUS_ERROR:
+ return LTTNG_LIVE_ITERATOR_STATUS_ERROR;
+ }
+
+ bt_common_abort();
+}
+
+static inline
+enum ctf_msg_iter_medium_status viewer_status_to_ctf_msg_iter_medium_status(
+ enum lttng_live_viewer_status viewer_status)
+{
+ switch (viewer_status) {
+ case LTTNG_LIVE_VIEWER_STATUS_OK:
+ return CTF_MSG_ITER_MEDIUM_STATUS_OK;
+ case LTTNG_LIVE_VIEWER_STATUS_INTERRUPTED:
+ return CTF_MSG_ITER_MEDIUM_STATUS_AGAIN;
+ case LTTNG_LIVE_VIEWER_STATUS_ERROR:
+ return CTF_MSG_ITER_MEDIUM_STATUS_ERROR;
+ }
+
+ bt_common_abort();
+}
+
+static inline
+void viewer_connection_close_socket(
+ struct live_viewer_connection *viewer_connection)
+{
+ bt_self_component_class *self_comp_class =
+ viewer_connection->self_comp_class;
+ bt_self_component *self_comp =
+ viewer_connection->self_comp;
+ int ret = bt_socket_close(viewer_connection->control_sock);
+ if (ret == -1) {
+ BT_COMP_OR_COMP_CLASS_LOGW_ERRNO(
+ self_comp, self_comp_class,
+ "Error closing viewer connection socket: ", ".");
+ }
+
+ viewer_connection->control_sock = BT_INVALID_SOCKET;
+}
+
+/*
+ * This function receives a message from the Relay daemon.
+ * If it received the entire message, it returns _OK,
+ * If it's interrupted, it returns _INTERRUPTED,
+ * otherwise, it returns _ERROR.
+ */
+static
+enum lttng_live_viewer_status lttng_live_recv(
+ struct live_viewer_connection *viewer_connection,