/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * mmcli -- Control modem status & access information from the command line * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Copyright (C) 2011 Aleksander Morgado * Copyright (C) 2011 Google, Inc. */ #include "config.h" #include #include #include #include #include #include #define _LIBMM_INSIDE_MMCLI #include #include "mmcli.h" #include "mmcli-common.h" #define PROGRAM_NAME "mmcli" #define PROGRAM_VERSION PACKAGE_VERSION /* Globals */ static GMainLoop *loop; static GCancellable *cancellable; /* Context */ static gboolean verbose_flag; static gboolean version_flag; static gboolean async_flag; static gint timeout = 30; /* by default, use 30s for all operations */ static GOptionEntry main_entries[] = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose_flag, "Run action with verbose logs", NULL }, { "version", 'V', 0, G_OPTION_ARG_NONE, &version_flag, "Print version", NULL }, { "async", 'a', 0, G_OPTION_ARG_NONE, &async_flag, "Use asynchronous methods", NULL }, { "timeout", 0, 0, G_OPTION_ARG_INT, &timeout, "Timeout for the operation", "[SECONDS]" }, { NULL } }; static void signals_handler (int signum) { if (cancellable) { /* Ignore consecutive requests of cancellation */ if (!g_cancellable_is_cancelled (cancellable)) { g_printerr ("%s\n", "cancelling the operation...\n"); g_cancellable_cancel (cancellable); } return; } if (loop && g_main_loop_is_running (loop)) { g_printerr ("%s\n", "cancelling the main loop...\n"); g_main_loop_quit (loop); } } static void log_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { const gchar *log_level_str; time_t now; gchar time_str[64]; struct tm *local_time; now = time ((time_t *) NULL); local_time = localtime (&now); strftime (time_str, 64, "%d %b %Y, %H:%M:%S", local_time); switch (log_level) { case G_LOG_LEVEL_WARNING: log_level_str = "-Warning **"; break; case G_LOG_LEVEL_CRITICAL: case G_LOG_FLAG_FATAL: case G_LOG_LEVEL_ERROR: log_level_str = "-Error **"; break; case G_LOG_LEVEL_DEBUG: log_level_str = "[Debug]"; break; default: log_level_str = ""; break; } g_print ("[%s] %s %s\n", time_str, log_level_str, message); } static void print_version_and_exit (void) { g_print ("\n" PROGRAM_NAME " " PROGRAM_VERSION "\n" "Copyright (2011) Aleksander Morgado\n" "License GPLv2+: GNU GPL version 2 or later \n" "This is free software: you are free to change and redistribute it.\n" "There is NO WARRANTY, to the extent permitted by law.\n" "\n"); exit (EXIT_SUCCESS); } void mmcli_async_operation_done (void) { if (cancellable) { g_object_unref (cancellable); cancellable = NULL; } g_main_loop_quit (loop); } void mmcli_force_async_operation (void) { if (!async_flag) { g_debug ("Forcing request to be run asynchronously"); async_flag = TRUE; } } void mmcli_force_sync_operation (void) { if (async_flag) { g_debug ("Ignoring request to run asynchronously"); async_flag = FALSE; } } void mmcli_force_operation_timeout (GDBusProxy *proxy) { g_dbus_proxy_set_default_timeout (proxy, timeout * 1000); } gint main (gint argc, gchar **argv) { GDBusConnection *connection; GOptionContext *context; GError *error = NULL; setlocale (LC_ALL, ""); g_type_init (); /* Setup option context, process it and destroy it */ context = g_option_context_new ("- Control and monitor the ModemManager"); g_option_context_add_group (context, mmcli_manager_get_option_group ()); g_option_context_add_group (context, mmcli_get_common_option_group ()); g_option_context_add_group (context, mmcli_modem_get_option_group ()); g_option_context_add_group (context, mmcli_modem_3gpp_get_option_group ()); g_option_context_add_group (context, mmcli_modem_cdma_get_option_group ()); g_option_context_add_group (context, mmcli_modem_simple_get_option_group ()); g_option_context_add_group (context, mmcli_modem_location_get_option_group ()); g_option_context_add_group (context, mmcli_modem_messaging_get_option_group ()); g_option_context_add_group (context, mmcli_modem_time_get_option_group ()); g_option_context_add_group (context, mmcli_modem_firmware_get_option_group ()); g_option_context_add_group (context, mmcli_modem_signal_get_option_group ()); g_option_context_add_group (context, mmcli_modem_oma_get_option_group ()); g_option_context_add_group (context, mmcli_sim_get_option_group ()); g_option_context_add_group (context, mmcli_bearer_get_option_group ()); g_option_context_add_group (context, mmcli_sms_get_option_group ()); g_option_context_add_main_entries (context, main_entries, NULL); g_option_context_parse (context, &argc, &argv, NULL); g_option_context_free (context); if (version_flag) print_version_and_exit (); if (verbose_flag) g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, log_handler, NULL); /* Setup signals */ signal (SIGINT, signals_handler); signal (SIGHUP, signals_handler); signal (SIGTERM, signals_handler); /* Setup dbus connection to use */ connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (!connection) { g_printerr ("error: couldn't get bus: %s\n", error ? error->message : "unknown error"); exit (EXIT_FAILURE); } /* Create requirements for async options */ cancellable = g_cancellable_new (); loop = g_main_loop_new (NULL, FALSE); /* Manager options? */ if (mmcli_manager_options_enabled ()) { /* Ensure options from different groups are not enabled */ if (mmcli_modem_options_enabled ()) { g_printerr ("error: cannot use manager and modem options " "at the same time\n"); exit (EXIT_FAILURE); } if (async_flag) mmcli_manager_run_asynchronous (connection, cancellable); else mmcli_manager_run_synchronous (connection); } /* Sim options? */ else if (mmcli_sim_options_enabled ()) { if (async_flag) mmcli_sim_run_asynchronous (connection, cancellable); else mmcli_sim_run_synchronous (connection); } /* Bearer options? */ else if (mmcli_bearer_options_enabled ()) { if (async_flag) mmcli_bearer_run_asynchronous (connection, cancellable); else mmcli_bearer_run_synchronous (connection); } /* Sms options? */ else if (mmcli_sms_options_enabled ()) { if (async_flag) mmcli_sms_run_asynchronous (connection, cancellable); else mmcli_sms_run_synchronous (connection); } /* Modem 3GPP options? */ else if (mmcli_modem_3gpp_options_enabled ()) { if (async_flag) mmcli_modem_3gpp_run_asynchronous (connection, cancellable); else mmcli_modem_3gpp_run_synchronous (connection); } /* Modem CDMA options? */ else if (mmcli_modem_cdma_options_enabled ()) { if (async_flag) mmcli_modem_cdma_run_asynchronous (connection, cancellable); else mmcli_modem_cdma_run_synchronous (connection); } /* Modem Simple options? */ else if (mmcli_modem_simple_options_enabled ()) { if (async_flag) mmcli_modem_simple_run_asynchronous (connection, cancellable); else mmcli_modem_simple_run_synchronous (connection); } /* Modem Location options? */ else if (mmcli_modem_location_options_enabled ()) { if (async_flag) mmcli_modem_location_run_asynchronous (connection, cancellable); else mmcli_modem_location_run_synchronous (connection); } /* Modem Messaging options? */ else if (mmcli_modem_messaging_options_enabled ()) { if (async_flag) mmcli_modem_messaging_run_asynchronous (connection, cancellable); else mmcli_modem_messaging_run_synchronous (connection); } /* Modem Time options? */ else if (mmcli_modem_time_options_enabled ()) { if (async_flag) mmcli_modem_time_run_asynchronous (connection, cancellable); else mmcli_modem_time_run_synchronous (connection); } /* Modem Firmware options? */ else if (mmcli_modem_firmware_options_enabled ()) { if (async_flag) mmcli_modem_firmware_run_asynchronous (connection, cancellable); else mmcli_modem_firmware_run_synchronous (connection); } /* Modem Signal options? */ else if (mmcli_modem_signal_options_enabled ()) { if (async_flag) mmcli_modem_signal_run_asynchronous (connection, cancellable); else mmcli_modem_signal_run_synchronous (connection); } /* Modem Oma options? */ else if (mmcli_modem_oma_options_enabled ()) { if (async_flag) mmcli_modem_oma_run_asynchronous (connection, cancellable); else mmcli_modem_oma_run_synchronous (connection); } /* Modem options? * NOTE: let this check be always the last one, as other groups also need * having a modem specified, and therefore if -m is set, modem options * are always enabled. */ else if (mmcli_modem_options_enabled ()) { if (async_flag) mmcli_modem_run_asynchronous (connection, cancellable); else mmcli_modem_run_synchronous (connection); } /* No options? */ else { g_printerr ("error: no actions specified\n"); exit (EXIT_FAILURE); } /* Run loop only in async operations */ if (async_flag) g_main_loop_run (loop); if (mmcli_manager_options_enabled ()) { mmcli_manager_shutdown (); } else if (mmcli_modem_3gpp_options_enabled ()) { mmcli_modem_3gpp_shutdown (); } else if (mmcli_modem_cdma_options_enabled ()) { mmcli_modem_cdma_shutdown (); } else if (mmcli_modem_simple_options_enabled ()) { mmcli_modem_simple_shutdown (); } else if (mmcli_modem_location_options_enabled ()) { mmcli_modem_location_shutdown (); } else if (mmcli_modem_messaging_options_enabled ()) { mmcli_modem_messaging_shutdown (); } else if (mmcli_modem_time_options_enabled ()) { mmcli_modem_time_shutdown (); } else if (mmcli_modem_firmware_options_enabled ()) { mmcli_modem_firmware_shutdown (); } else if (mmcli_modem_signal_options_enabled ()) { mmcli_modem_signal_shutdown (); } else if (mmcli_modem_oma_options_enabled ()) { mmcli_modem_oma_shutdown (); } else if (mmcli_sim_options_enabled ()) { mmcli_sim_shutdown (); } else if (mmcli_bearer_options_enabled ()) { mmcli_bearer_shutdown (); } else if (mmcli_sms_options_enabled ()) { mmcli_sms_shutdown (); } else if (mmcli_modem_options_enabled ()) { mmcli_modem_shutdown (); } if (cancellable) g_object_unref (cancellable); g_main_loop_unref (loop); g_object_unref (connection); return EXIT_SUCCESS; }