/* * dLeyna * * Copyright (C) 2012-2017 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU Lesser General Public License, * version 2.1, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * Regis Merlino * */ #include #include #include "connector-mgr.h" #include "control-point.h" #include "error.h" #include "log.h" #include "main-loop.h" #include "settings.h" #include "task-processor.h" typedef struct dleyna_daemon_context_t_ dleyna_daemon_context_t; struct dleyna_daemon_context_t_ { gboolean error; GMainLoop *main_loop; dleyna_connector_id_t connection; dleyna_task_processor_t *processor; dleyna_settings_t *settings; const dleyna_connector_t *connector; const dleyna_control_point_t *control_point; }; static dleyna_daemon_context_t g_context; static gboolean prv_context_mainloop_quit_cb(gpointer user_data) { DLEYNA_LOG_DEBUG("Main loop quit"); g_main_loop_quit(g_context.main_loop); return FALSE; } static gboolean prv_context_quit_cb(gpointer user_data) { DLEYNA_LOG_DEBUG("Quitting"); if (g_context.connection != NULL) { g_context.connector->disconnect(); g_context.control_point->stop_service(); } g_timeout_add_seconds(1, prv_context_mainloop_quit_cb, NULL); return FALSE; } static gboolean prv_context_init(const gchar *server, const dleyna_control_point_t *control_point) { gboolean retval = TRUE; const gchar *connector; memset(&g_context, 0, sizeof(g_context)); g_context.processor = dleyna_task_processor_new(prv_context_quit_cb); g_context.control_point = control_point; dleyna_settings_new(server, &g_context.settings); connector = dleyna_settings_connector_name(g_context.settings); g_context.connector = dleyna_connector_mgr_load(connector); if (!g_context.connector) retval = FALSE; return retval; } static void prv_connector_acquired(dleyna_connector_id_t connection) { g_context.connection = connection; if (!g_context.control_point->start_service(connection)) { g_context.error = TRUE; g_main_loop_quit(g_context.main_loop); } } static void prv_name_lost(dleyna_connector_id_t connection) { g_context.connection = NULL; dleyna_task_processor_set_quitting(g_context.processor); } static void prv_context_free(void) { dleyna_task_processor_free(g_context.processor); if (g_context.connector) { g_context.connector->shutdown(); dleyna_connector_mgr_release(g_context.connector); } if (g_context.main_loop) g_main_loop_unref(g_context.main_loop); if (g_context.settings) dleyna_settings_delete(g_context.settings); } int dleyna_main_loop_start(const char *server, const dleyna_control_point_t *control_point, gpointer user_data) { int retval = 1; dleyna_log_init(server, control_point->get_version()); if (!prv_context_init(server, control_point)) goto out; if (!g_context.connector->initialize( g_context.control_point->server_introspection(), g_context.control_point->root_introspection(), dleyna_error_quark(), user_data)) goto out; g_context.main_loop = g_main_loop_new(NULL, FALSE); g_context.connector->connect(g_context.control_point->server_name(), prv_connector_acquired, prv_name_lost); g_context.control_point->initialize(g_context.connector, g_context.processor, g_context.settings); g_main_loop_run(g_context.main_loop); if (g_context.error) goto on_error; retval = 0; on_error: g_context.control_point->free(); out: prv_context_free(); dleyna_log_finalize(); return retval; } static gboolean prv_set_quitting(gpointer user_data) { dleyna_task_processor_set_quitting(g_context.processor); return FALSE; } void dleyna_main_loop_quit(void) { g_idle_add_full(G_PRIORITY_HIGH_IDLE, prv_set_quitting, NULL, NULL); }