diff options
Diffstat (limited to 'src')
31 files changed, 922 insertions, 425 deletions
diff --git a/src/77-mm-usb-device-blacklist.rules b/src/77-mm-usb-device-blacklist.rules index 78a6770d..58b0cee6 100644 --- a/src/77-mm-usb-device-blacklist.rules +++ b/src/77-mm-usb-device-blacklist.rules @@ -62,5 +62,11 @@ ATTRS{idVendor}=="0592", ATTRS{idProduct}=="0002", ENV{ID_MM_DEVICE_IGNORE}="1" # that isn't blacklisted. ATTRS{idVendor}=="0830", ATTRS{idProduct}=="0061", ENV{ID_MM_DEVICE_IGNORE}="1" +# Belkin F5U183 Serial Adapter (unlikely to have a modem behind it) +ATTRS{idVendor}=="050d", ATTRS{idProduct}=="0103", ENV{ID_MM_DEVICE_IGNORE}="1" + +# ATEN Intl UC-232A (Prolific) +ATTRS{idVendor}=="0557", ATTRS{idProduct}=="2008", ENV{ID_MM_DEVICE_IGNORE}="1" + LABEL="mm_usb_device_blacklist_end" diff --git a/src/Makefile.am b/src/Makefile.am index 3e656d81..e813e7e8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -81,6 +81,8 @@ endif modem_manager_SOURCES = \ main.c \ + mm-log.c \ + mm-log.h \ mm-callback-info.c \ mm-callback-info.h \ $(auth_sources) \ @@ -109,8 +111,6 @@ modem_manager_SOURCES = \ mm-modem-gsm-ussd.h \ mm-modem-simple.c \ mm-modem-simple.h \ - mm-options.c \ - mm-options.h \ mm-plugin.c \ mm-plugin.h \ mm-plugin-base.c \ @@ -11,7 +11,7 @@ * GNU General Public License for more details: * * Copyright (C) 2008 - 2009 Novell, Inc. - * Copyright (C) 2009 - 2010 Red Hat, Inc. + * Copyright (C) 2009 - 2011 Red Hat, Inc. */ #include <config.h> @@ -21,8 +21,10 @@ #include <unistd.h> #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> +#include <stdlib.h> + #include "mm-manager.h" -#include "mm-options.h" +#include "mm-log.h" #if !defined(MM_DIST_VERSION) # define MM_DIST_VERSION VERSION @@ -34,9 +36,9 @@ static void mm_signal_handler (int signo) { if (signo == SIGUSR1) - mm_options_set_debug (!mm_options_debug ()); + mm_log_usr1 (); else if (signo == SIGINT || signo == SIGTERM) { - g_message ("Caught signal %d, shutting down...", signo); + mm_info ("Caught signal %d, shutting down...", signo); if (loop) g_main_loop_quit (loop); else @@ -60,64 +62,9 @@ setup_signals (void) } static void -log_handler (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer ignored) -{ - int syslog_priority; - - switch (log_level) { - case G_LOG_LEVEL_ERROR: - syslog_priority = LOG_CRIT; - break; - - case G_LOG_LEVEL_CRITICAL: - syslog_priority = LOG_ERR; - break; - - case G_LOG_LEVEL_WARNING: - syslog_priority = LOG_WARNING; - break; - - case G_LOG_LEVEL_MESSAGE: - syslog_priority = LOG_NOTICE; - break; - - case G_LOG_LEVEL_DEBUG: - syslog_priority = LOG_DEBUG; - break; - - case G_LOG_LEVEL_INFO: - default: - syslog_priority = LOG_INFO; - break; - } - - syslog (syslog_priority, "%s", message); -} - - -static void -logging_setup (void) -{ - openlog (G_LOG_DOMAIN, LOG_CONS, LOG_DAEMON); - g_log_set_handler (G_LOG_DOMAIN, - G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, - log_handler, - NULL); -} - -static void -logging_shutdown (void) -{ - closelog (); -} - -static void destroy_cb (DBusGProxy *proxy, gpointer user_data) { - g_message ("disconnected from the system bus, exiting."); + mm_warn ("disconnected from the system bus, exiting."); g_main_loop_quit (loop); } @@ -139,16 +86,16 @@ create_dbus_proxy (DBusGConnection *bus) G_TYPE_INVALID, G_TYPE_UINT, &request_name_result, G_TYPE_INVALID)) { - g_warning ("Could not acquire the %s service.\n" - " Message: '%s'", MM_DBUS_SERVICE, err->message); + mm_warn ("Could not acquire the %s service.\n" + " Message: '%s'", MM_DBUS_SERVICE, err->message); g_error_free (err); g_object_unref (proxy); proxy = NULL; } else if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - g_warning ("Could not acquire the " MM_DBUS_SERVICE - " service as it is already taken. Return: %d", - request_name_result); + mm_warn ("Could not acquire the " MM_DBUS_SERVICE + " service as it is already taken. Return: %d", + request_name_result); g_object_unref (proxy); proxy = NULL; @@ -175,17 +122,49 @@ main (int argc, char *argv[]) DBusGProxy *proxy; MMManager *manager; GError *err = NULL; + GOptionContext *opt_ctx; guint id; + const char *log_level = NULL, *log_file = NULL; + gboolean debug = FALSE, show_ts = FALSE, rel_ts = FALSE; + + GOptionEntry entries[] = { + { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, "Output to console rather than syslog", NULL }, + { "log-level", 0, 0, G_OPTION_ARG_STRING, &log_level, "Log level: one of [ERR, WARN, INFO, DEBUG]", "INFO" }, + { "log-file", 0, 0, G_OPTION_ARG_STRING, &log_file, "Path to log file", NULL }, + { "timestamps", 0, 0, G_OPTION_ARG_NONE, &show_ts, "Show timestamps in log output", NULL }, + { "relative-timestamps", 0, 0, G_OPTION_ARG_NONE, &rel_ts, "Use relative timestamps (from MM start)", NULL }, + { NULL } + }; - mm_options_parse (argc, argv); g_type_init (); - setup_signals (); + opt_ctx = g_option_context_new (NULL); + g_option_context_set_summary (opt_ctx, "DBus system service to communicate with modems."); + g_option_context_add_main_entries (opt_ctx, entries, NULL); + + if (!g_option_context_parse (opt_ctx, &argc, &argv, &err)) { + g_warning ("%s\n", err->message); + g_error_free (err); + exit (1); + } - if (!mm_options_debug ()) - logging_setup (); + g_option_context_free (opt_ctx); + + if (debug) { + log_level = "DEBUG"; + if (!show_ts && !rel_ts) + show_ts = TRUE; + } + + if (!mm_log_setup (log_level, log_file, show_ts, rel_ts, &err)) { + g_warning ("Failed to set up logging: %s", err->message); + g_error_free (err); + exit (1); + } + + setup_signals (); - g_message ("ModemManager (version " MM_DIST_VERSION ") starting..."); + mm_info ("ModemManager (version " MM_DIST_VERSION ") starting..."); bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err); if (!bus) { @@ -235,7 +214,7 @@ main (int argc, char *argv[]) g_object_unref (proxy); dbus_g_connection_unref (bus); - logging_shutdown (); + mm_log_shutdown (); return 0; } diff --git a/src/mm-at-serial-port.c b/src/mm-at-serial-port.c index 3df8681b..30da3a3b 100644 --- a/src/mm-at-serial-port.c +++ b/src/mm-at-serial-port.c @@ -23,7 +23,7 @@ #include "mm-at-serial-port.h" #include "mm-errors.h" -#include "mm-options.h" +#include "mm-log.h" G_DEFINE_TYPE (MMAtSerialPort, mm_at_serial_port, MM_TYPE_SERIAL_PORT) @@ -273,7 +273,6 @@ debug_log (MMSerialPort *port, const char *prefix, const char *buf, gsize len) { static GString *debug = NULL; const char *s; - GTimeVal tv; if (!debug) debug = g_string_sized_new (256); @@ -296,12 +295,7 @@ debug_log (MMSerialPort *port, const char *prefix, const char *buf, gsize len) } g_string_append_c (debug, '\''); - g_get_current_time (&tv); - g_debug ("<%ld.%ld> (%s): %s", - tv.tv_sec, - tv.tv_usec, - mm_port_get_device (MM_PORT (port)), - debug->str); + mm_dbg ("(%s): %s", mm_port_get_device (MM_PORT (port)), debug->str); g_string_truncate (debug, 0); } diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c index f3e99d1a..0a95e7b1 100644 --- a/src/mm-generic-cdma.c +++ b/src/mm-generic-cdma.c @@ -30,6 +30,7 @@ #include "mm-serial-parsers.h" #include "mm-modem-helpers.h" #include "libqcdm/src/commands.h" +#include "mm-log.h" #define MM_GENERIC_CDMA_PREV_STATE_TAG "prev-state" @@ -68,6 +69,8 @@ typedef struct { guint poll_id; + char *meid; + MMModemCdmaRegistrationState cdma_1x_reg_state; MMModemCdmaRegistrationState evdo_reg_state; @@ -1045,7 +1048,7 @@ get_signal_quality (MMModemCdma *modem, at_port = mm_generic_cdma_get_best_at_port (MM_GENERIC_CDMA (modem), &info->error); if (!at_port && !priv->qcdm) { - g_message ("Returning saved signal quality %d", priv->cdma1x_quality); + mm_dbg ("Returning saved signal quality %d", priv->cdma1x_quality); mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->cdma1x_quality), NULL); mm_callback_info_schedule (info); return; @@ -1524,15 +1527,22 @@ reg_query_speri_done (MMAtSerialPort *port, if (!p || !mm_cdma_parse_eri (p, &roam, NULL, NULL)) goto done; - /* Change the 1x and EVDO registration states to roaming if they were - * anything other than UNKNOWN. - */ if (roam) { + /* Change the 1x and EVDO registration states to roaming if they were + * anything other than UNKNOWN. + */ if (mm_generic_cdma_query_reg_state_get_callback_1x_state (info)) mm_generic_cdma_query_reg_state_set_callback_1x_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING); if (mm_generic_cdma_query_reg_state_get_callback_evdo_state (info)) mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING); + } else { + /* Change 1x and/or EVDO registration state to home if home/roaming wasn't previously known */ + if (mm_generic_cdma_query_reg_state_get_callback_1x_state (info) == MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED) + mm_generic_cdma_query_reg_state_set_callback_1x_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_HOME); + + if (mm_generic_cdma_query_reg_state_get_callback_evdo_state (info) == MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED) + mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_HOME); } done: @@ -1584,6 +1594,12 @@ real_query_registration_state (MMGenericCdma *self, port = mm_generic_cdma_get_best_at_port (self, &info->error); if (!port) { + /* If we can't get an AT port, but less specific registration checks + * were successful, just use that and don't return an error. + */ + if ( cur_cdma_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN + || cur_evdo_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) + g_clear_error (&info->error); mm_callback_info_schedule (info); return; } @@ -1722,7 +1738,7 @@ reg_hdrstate_cb (MMQcdmSerialPort *port, /* Get HDR subsystem state to determine EVDO registration when in 1X mode */ result = qcdm_cmd_hdr_subsys_state_info_result ((const char *) response->data, response->len, - &info->error); + NULL); if (result) { guint8 session_state = QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_CLOSED; guint8 almp_state = QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_INACTIVE; @@ -1801,19 +1817,24 @@ reg_cmstate_cb (MMQcdmSerialPort *port, MMAtSerialPort *at_port = NULL; QCDMResult *result = NULL; guint32 opmode = 0, sysmode = 0; + GError *qcdm_error = NULL; /* Parse the response */ if (!error) - result = qcdm_cmd_cm_subsys_state_info_result ((const char *) response->data, response->len, &info->error); + result = qcdm_cmd_cm_subsys_state_info_result ((const char *) response->data, response->len, &qcdm_error); if (!result) { /* If there was some error, fall back to use +CAD like we did before QCDM */ if (info->modem) at_port = mm_generic_cdma_get_best_at_port (MM_GENERIC_CDMA (info->modem), &info->error); + else + info->error = g_error_copy (qcdm_error); + if (at_port) mm_at_serial_port_queue_command (at_port, "+CAD?", 3, get_analog_digital_done, info); else mm_callback_info_schedule (info); + g_clear_error (&qcdm_error); return; } @@ -1856,8 +1877,8 @@ get_registration_state (MMModemCdma *modem, port = mm_generic_cdma_get_best_at_port (MM_GENERIC_CDMA (modem), &info->error); if (!port && !priv->qcdm) { - g_message ("Returning saved registration states: 1x: %d EVDO: %d", - priv->cdma_1x_reg_state, priv->evdo_reg_state); + mm_dbg ("Returning saved registration states: 1x: %d EVDO: %d", + priv->cdma_1x_reg_state, priv->evdo_reg_state); mm_generic_cdma_query_reg_state_set_callback_1x_state (info, priv->cdma_1x_reg_state); mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, priv->evdo_reg_state); mm_callback_info_schedule (info); @@ -2268,6 +2289,9 @@ get_property (GObject *object, guint prop_id, case MM_MODEM_PROP_TYPE: g_value_set_uint (value, MM_MODEM_TYPE_CDMA); break; + case MM_MODEM_CDMA_PROP_MEID: + g_value_set_string (value, priv->meid); + break; case PROP_EVDO_REV0: g_value_set_boolean (value, priv->evdo_rev0); break; @@ -2320,6 +2344,10 @@ mm_generic_cdma_class_init (MMGenericCdmaClass *klass) MM_MODEM_PROP_TYPE, MM_MODEM_TYPE); + g_object_class_override_property (object_class, + MM_MODEM_CDMA_PROP_MEID, + MM_MODEM_CDMA_MEID); + g_object_class_install_property (object_class, PROP_EVDO_REV0, g_param_spec_boolean (MM_GENERIC_CDMA_EVDO_REV0, "EVDO rev0", diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index 7f28dd5c..98713b0d 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -33,7 +33,7 @@ #include "mm-qcdm-serial-port.h" #include "mm-serial-parsers.h" #include "mm-modem-helpers.h" -#include "mm-options.h" +#include "mm-log.h" #include "mm-properties-changed-signal.h" #include "mm-utils.h" #include "mm-modem-location.h" @@ -471,10 +471,8 @@ get_iccid_done (MMModem *modem, g_free (priv->simid); priv->simid = g_strdup (g_checksum_get_string (sum)); - if (mm_options_debug ()) { - g_debug ("SIM ID source '%s'", response); - g_debug ("SIM ID '%s'", priv->simid); - } + mm_dbg ("SIM ID source '%s'", response); + mm_dbg ("SIM ID '%s'", priv->simid); g_object_notify (G_OBJECT (modem), MM_MODEM_GSM_CARD_SIM_IDENTIFIER); @@ -990,6 +988,57 @@ periodic_poll_cb (gpointer user_data) return TRUE; /* continue running */ } +#define CREG_NUM_TAG "creg-num" +#define CGREG_NUM_TAG "cgreg-num" + +static void +initial_unsolicited_reg_check_done (MMCallbackInfo *info) +{ + MMGenericGsmPrivate *priv; + guint creg_num, cgreg_num; + + if (!info->modem || info->error) + goto done; + + priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); + if (!priv->secondary) + goto done; + + /* Enable unsolicited registration responses on secondary ports too, + * to ensure that we get the response even if the modem is connected + * on the primary port. We enable responses on both ports because we + * cannot trust modems to reliably send the responses on the port we + * enable them on. + */ + + creg_num = GPOINTER_TO_UINT (mm_callback_info_get_data (info, CREG_NUM_TAG)); + switch (creg_num) { + case 1: + mm_at_serial_port_queue_command (priv->secondary, "+CREG=1", 3, NULL, NULL); + break; + case 2: + mm_at_serial_port_queue_command (priv->secondary, "+CREG=2", 3, NULL, NULL); + break; + default: + break; + } + + cgreg_num = GPOINTER_TO_UINT (mm_callback_info_get_data (info, CGREG_NUM_TAG)); + switch (cgreg_num) { + case 1: + mm_at_serial_port_queue_command (priv->secondary, "+CGREG=1", 3, NULL, NULL); + break; + case 2: + mm_at_serial_port_queue_command (priv->secondary, "+CGREG=2", 3, NULL, NULL); + break; + default: + break; + } + +done: + mm_callback_info_schedule (info); +} + static void cgreg1_done (MMAtSerialPort *port, GString *response, @@ -1007,11 +1056,14 @@ cgreg1_done (MMAtSerialPort *port, /* The modem doesn't like unsolicited CGREG, so we'll need to poll */ priv->cgreg_poll = TRUE; - } + } else + mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (1), NULL); + /* Success; get initial state */ mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem); } - mm_callback_info_schedule (info); + + initial_unsolicited_reg_check_done (info); } static void @@ -1032,11 +1084,13 @@ cgreg2_done (MMAtSerialPort *port, } else { add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI); + mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (2), NULL); + /* Success; get initial state */ mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem); /* All done */ - mm_callback_info_schedule (info); + initial_unsolicited_reg_check_done (info); } } else { /* Modem got removed */ @@ -1061,7 +1115,9 @@ creg1_done (MMAtSerialPort *port, /* The modem doesn't like unsolicited CREG, so we'll need to poll */ priv->creg_poll = TRUE; - } + } else + mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (1), NULL); + /* Success; get initial state */ mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem); @@ -1090,6 +1146,8 @@ creg2_done (MMAtSerialPort *port, } else { add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI); + mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (2), NULL); + /* Success; get initial state */ mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem); @@ -1240,8 +1298,15 @@ cmer_cb (MMAtSerialPort *port, GError *error, gpointer user_data) { - if (!error) - MM_GENERIC_GSM_GET_PRIVATE (user_data)->cmer_enabled = TRUE; + if (!error) { + MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (user_data); + + priv->cmer_enabled = TRUE; + + /* Enable CMER on the secondary port if we can too */ + if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary))) + mm_at_serial_port_queue_command (priv->secondary, "+CMER=3,0,0,1", 3, NULL, NULL); + } } static void @@ -1306,12 +1371,9 @@ mm_generic_gsm_enable_complete (MMGenericGsm *self, */ if (priv->secondary) { if (!mm_serial_port_open (MM_SERIAL_PORT (priv->secondary), &error)) { - if (mm_options_debug ()) { - g_warning ("%s: error opening secondary port: (%d) %s", - __func__, - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - } + mm_dbg ("error opening secondary port: (%d) %s", + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); } } @@ -1524,11 +1586,16 @@ disable_flash_done (MMSerialPort *port, priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem); /* Disable unsolicited messages */ - mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "AT+CREG=0", 3, NULL, NULL); - mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "AT+CGREG=0", 3, NULL, NULL); + mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "+CREG=0", 3, NULL, NULL); + mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "+CGREG=0", 3, NULL, NULL); if (priv->cmer_enabled) { mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "+CMER=0", 3, NULL, NULL); + + /* And on the secondary port */ + if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary))) + mm_at_serial_port_queue_command (priv->secondary, "+CMER=0", 3, NULL, NULL); + priv->cmer_enabled = FALSE; } @@ -1541,6 +1608,15 @@ disable_flash_done (MMSerialPort *port, } static void +secondary_unsolicited_done (MMAtSerialPort *port, + GString *response, + GError *error, + gpointer user_data) +{ + mm_serial_port_close_force (MM_SERIAL_PORT (port)); +} + +static void disable (MMModem *modem, MMModemFn callback, gpointer user_data) @@ -1575,9 +1651,12 @@ disable (MMModem *modem, update_lac_ci (self, 0, 0, 1); _internal_update_access_technology (self, MM_MODEM_GSM_ACCESS_TECH_UNKNOWN); - /* Close the secondary port if its open */ - if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary))) - mm_serial_port_close_force (MM_SERIAL_PORT (priv->secondary)); + /* Clean up the secondary port if it's open */ + if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary))) { + mm_at_serial_port_queue_command (priv->secondary, "+CREG=0", 3, NULL, NULL); + mm_at_serial_port_queue_command (priv->secondary, "+CGREG=0", 3, NULL, NULL); + mm_at_serial_port_queue_command (priv->secondary, "+CMER=0", 3, secondary_unsolicited_done, NULL); + } info = mm_callback_info_new (modem, callback, user_data); @@ -2237,7 +2316,7 @@ roam_disconnect_done (MMModem *modem, GError *error, gpointer user_data) { - g_message ("Disconnected because roaming is not allowed"); + mm_info ("Disconnected because roaming is not allowed"); } static void @@ -2268,9 +2347,9 @@ mm_generic_gsm_set_reg_status (MMGenericGsm *self, if (priv->reg_status[rs_type - 1] == status) return; - g_debug ("%s registration state changed: %d", - (rs_type == MM_GENERIC_GSM_REG_TYPE_CS) ? "CS" : "PS", - status); + mm_dbg ("%s registration state changed: %d", + (rs_type == MM_GENERIC_GSM_REG_TYPE_CS) ? "CS" : "PS", + status); priv->reg_status[rs_type - 1] = status; port = mm_generic_gsm_get_best_at_port (self, NULL); @@ -2389,11 +2468,8 @@ reg_state_changed (MMAtSerialPort *port, GError *error = NULL; if (!mm_gsm_parse_creg_response (match_info, &state, &lac, &cell_id, &act, &cgreg, &error)) { - if (mm_options_debug ()) { - g_warning ("%s: error parsing unsolicited registration: %s", - __func__, - error && error->message ? error->message : "(unknown)"); - } + mm_warn ("error parsing unsolicited registration: %s", + error && error->message ? error->message : "(unknown)"); return; } @@ -3830,10 +3906,10 @@ ussd_update_state (MMGenericGsm *self, MMModemGsmUssdState new_state) } static void -ussd_initiate_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) +ussd_send_done (MMAtSerialPort *port, + GString *response, + GError *error, + gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMGenericGsmPrivate *priv; @@ -3860,10 +3936,7 @@ ussd_initiate_done (MMAtSerialPort *port, case 0: /* no further action required */ ussd_state = MM_MODEM_GSM_USSD_STATE_IDLE; break; - case 1: /* Not an error but not yet implemented */ - info->error = g_error_new (MM_MODEM_ERROR, - MM_MODEM_ERROR_GENERAL, - "Further action required."); + case 1: /* further action required */ ussd_state = MM_MODEM_GSM_USSD_STATE_USER_RESPONSE; break; case 2: @@ -3894,10 +3967,8 @@ ussd_initiate_done (MMAtSerialPort *port, if (reply) { /* look for the reply data coding scheme */ - if (mm_options_debug ()) { - if ((start = strrchr (end, ',')) != NULL) - g_debug ("USSD data coding scheme %d", atoi (start + 1)); - } + if ((start = strrchr (end, ',')) != NULL) + mm_dbg ("USSD data coding scheme %d", atoi (start + 1)); converted = mm_modem_charset_hex_to_utf8 (reply, priv->cur_charset); mm_callback_info_set_result (info, converted, g_free); @@ -3919,10 +3990,10 @@ done: } static void -ussd_initiate (MMModemGsmUssd *modem, - const char *command, - MMModemStringFn callback, - gpointer user_data) +ussd_send (MMModemGsmUssd *modem, + const char *command, + MMModemStringFn callback, + gpointer user_data) { MMCallbackInfo *info; char *atc_command; @@ -3947,13 +4018,57 @@ ussd_initiate (MMModemGsmUssd *modem, atc_command = g_strdup_printf ("+CUSD=1,\"%s\",15", hex); g_free (hex); - mm_at_serial_port_queue_command (port, atc_command, 10, ussd_initiate_done, info); + mm_at_serial_port_queue_command (port, atc_command, 10, ussd_send_done, info); g_free (atc_command); ussd_update_state (MM_GENERIC_GSM (modem), MM_MODEM_GSM_USSD_STATE_ACTIVE); } static void +ussd_initiate (MMModemGsmUssd *modem, + const char *command, + MMModemStringFn callback, + gpointer user_data) +{ + MMCallbackInfo *info; + MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem); + info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data); + + if (priv->ussd_state != MM_MODEM_GSM_USSD_STATE_IDLE) { + info->error = g_error_new (MM_MODEM_ERROR, + MM_MODEM_ERROR_GENERAL, + "USSD session already active."); + mm_callback_info_schedule (info); + return; + } + + ussd_send (modem, command, callback, user_data); + return; +} + +static void +ussd_respond (MMModemGsmUssd *modem, + const char *command, + MMModemStringFn callback, + gpointer user_data) +{ + MMCallbackInfo *info; + MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem); + info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data); + + if (priv->ussd_state != MM_MODEM_GSM_USSD_STATE_USER_RESPONSE) { + info->error = g_error_new (MM_MODEM_ERROR, + MM_MODEM_ERROR_GENERAL, + "No active USSD session, cannot respond."); + mm_callback_info_schedule (info); + return; + } + + ussd_send (modem, command, callback, user_data); + return; +} + +static void ussd_cancel_done (MMAtSerialPort *port, GString *response, GError *error, @@ -4123,6 +4238,7 @@ simple_state_machine (MMModem *modem, GError *error, gpointer user_data) gboolean done = FALSE; MMModemGsmAllowedMode allowed_mode; gboolean home_only = FALSE; + char *data_device; info->error = mm_modem_check_removed (modem, error); if (info->error) @@ -4130,16 +4246,9 @@ simple_state_machine (MMModem *modem, GError *error, gpointer user_data) priv = MM_GENERIC_GSM_GET_PRIVATE (modem); - if (mm_options_debug ()) { - GTimeVal tv; - char *data_device; - - g_object_get (G_OBJECT (modem), MM_MODEM_DATA_DEVICE, &data_device, NULL); - g_get_current_time (&tv); - g_debug ("<%ld.%ld> (%s): simple connect state %d", - tv.tv_sec, tv.tv_usec, data_device, state); - g_free (data_device); - } + g_object_get (G_OBJECT (modem), MM_MODEM_DATA_DEVICE, &data_device, NULL); + mm_dbg ("(%s): simple connect state %d", data_device, state); + g_free (data_device); switch (state) { case SIMPLE_STATE_CHECK_PIN: @@ -4238,29 +4347,21 @@ simple_connect (MMModemSimple *simple, gpointer user_data) { MMCallbackInfo *info; + GHashTableIter iter; + gpointer key, value; + char *data_device; - /* If debugging, list all the simple connect properties */ - if (mm_options_debug ()) { - GHashTableIter iter; - gpointer key, value; - GTimeVal tv; - char *data_device; - - g_object_get (G_OBJECT (simple), MM_MODEM_DATA_DEVICE, &data_device, NULL); - g_get_current_time (&tv); - - g_hash_table_iter_init (&iter, properties); - while (g_hash_table_iter_next (&iter, &key, &value)) { - char *val_str; - - val_str = g_strdup_value_contents ((GValue *) value); - g_debug ("<%ld.%ld> (%s): %s => %s", - tv.tv_sec, tv.tv_usec, - data_device, (const char *) key, val_str); - g_free (val_str); - } - g_free (data_device); + /* List simple connect properties when debugging */ + g_object_get (G_OBJECT (simple), MM_MODEM_DATA_DEVICE, &data_device, NULL); + g_hash_table_iter_init (&iter, properties); + while (g_hash_table_iter_next (&iter, &key, &value)) { + char *val_str; + + val_str = g_strdup_value_contents ((GValue *) value); + mm_dbg ("(%s): %s => %s", data_device, (const char *) key, val_str); + g_free (val_str); } + g_free (data_device); info = mm_callback_info_new (MM_MODEM (simple), callback, user_data); mm_callback_info_set_data (info, "simple-connect-properties", @@ -4633,6 +4734,7 @@ static void modem_gsm_ussd_init (MMModemGsmUssd *class) { class->initiate = ussd_initiate; + class->respond = ussd_respond; class->cancel = ussd_cancel; } diff --git a/src/mm-log.c b/src/mm-log.c new file mode 100644 index 00000000..82d40bc8 --- /dev/null +++ b/src/mm-log.c @@ -0,0 +1,227 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 2 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: + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#define _GNU_SOURCE +#include <config.h> +#include <stdio.h> +#include <syslog.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <unistd.h> + +#include "mm-log.h" + +enum { + TS_FLAG_NONE = 0, + TS_FLAG_WALL, + TS_FLAG_REL +}; + +static gboolean ts_flags = TS_FLAG_NONE; +static guint32 log_level = LOGL_INFO | LOGL_WARN | LOGL_ERR; +static GTimeVal rel_start = { 0, 0 }; +static int logfd = -1; + +typedef struct { + guint32 num; + const char *name; +} LogDesc; + +static const LogDesc level_descs[] = { + { LOGL_ERR, "ERR" }, + { LOGL_WARN | LOGL_ERR, "WARN" }, + { LOGL_INFO | LOGL_WARN | LOGL_ERR, "INFO" }, + { LOGL_DEBUG | LOGL_INFO | LOGL_WARN | LOGL_ERR, "DEBUG" }, + { 0, NULL } +}; + +void +_mm_log (const char *loc, + const char *func, + guint32 level, + const char *fmt, + ...) +{ + va_list args; + char *msg; + GTimeVal tv; + char tsbuf[100] = { 0 }; + char msgbuf[512] = { 0 }; + int syslog_priority = LOG_INFO; + const char *prefix = NULL; + + if (!(log_level & level)) + return; + + va_start (args, fmt); + msg = g_strdup_vprintf (fmt, args); + va_end (args); + + if (ts_flags == TS_FLAG_WALL) { + g_get_current_time (&tv); + snprintf (&tsbuf[0], sizeof (tsbuf), " [%09ld.%06ld]", tv.tv_sec, tv.tv_usec); + } else if (ts_flags == TS_FLAG_REL) { + time_t secs; + suseconds_t usecs; + + g_get_current_time (&tv); + secs = tv.tv_sec - rel_start.tv_sec; + usecs = tv.tv_usec - rel_start.tv_usec; + if (usecs < 0) { + secs--; + usecs += 1000000; + } + + snprintf (&tsbuf[0], sizeof (tsbuf), " [%06ld.%06ld]", secs, usecs); + } + + if ((log_level & LOGL_DEBUG) && (level == LOGL_DEBUG)) + prefix = "debug"; + else if ((log_level & LOGL_INFO) && (level == LOGL_INFO)) + prefix = "info"; + else if ((log_level & LOGL_WARN) && (level == LOGL_WARN)) { + prefix = "warn"; + syslog_priority = LOG_WARNING; + } else if ((log_level & LOGL_ERR) && (level == LOGL_ERR)) { + prefix = "err"; + syslog_priority = LOG_ERR; + } else + g_warn_if_reached (); + + if (prefix) { + if (log_level & LOGL_DEBUG) + snprintf (msgbuf, sizeof (msgbuf), "<%s>%s [%s] %s(): %s\n", prefix, tsbuf, loc, func, msg); + else + snprintf (msgbuf, sizeof (msgbuf), "<%s>%s %s\n", prefix, tsbuf, msg); + + if (logfd < 0) + syslog (syslog_priority, "%s", msgbuf); + else { + write (logfd, msgbuf, strlen (msgbuf)); + fsync (logfd); /* Make sure output is dumped to disk immediately */ + } + } + + g_free (msg); +} + +static void +log_handler (const gchar *log_domain, + GLogLevelFlags level, + const gchar *message, + gpointer ignored) +{ + int syslog_priority; + + switch (level) { + case G_LOG_LEVEL_ERROR: + syslog_priority = LOG_CRIT; + break; + case G_LOG_LEVEL_CRITICAL: + syslog_priority = LOG_ERR; + break; + case G_LOG_LEVEL_WARNING: + syslog_priority = LOG_WARNING; + break; + case G_LOG_LEVEL_MESSAGE: + syslog_priority = LOG_NOTICE; + break; + case G_LOG_LEVEL_DEBUG: + syslog_priority = LOG_DEBUG; + break; + case G_LOG_LEVEL_INFO: + default: + syslog_priority = LOG_INFO; + break; + } + + if (logfd < 0) + syslog (syslog_priority, "%s", message); + else + write (logfd, message, strlen (message)); +} + +gboolean +mm_log_setup (const char *level, + const char *log_file, + gboolean show_timestamps, + gboolean rel_timestamps, + GError **error) +{ + /* levels */ + if (level && strlen (level)) { + gboolean found = FALSE; + const LogDesc *diter; + + for (diter = &level_descs[0]; diter->name; diter++) { + if (!strcasecmp (diter->name, level)) { + log_level = diter->num; + found = TRUE; + break; + } + } + + if (!found) { + g_set_error (error, 0, 0, "Unknown log level '%s'", level); + return FALSE; + } + } + + if (show_timestamps) + ts_flags = TS_FLAG_WALL; + else if (rel_timestamps) + ts_flags = TS_FLAG_REL; + + /* Grab start time for relative timestamps */ + g_get_current_time (&rel_start); + + if (log_file == NULL) + openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PID | LOG_PERROR, LOG_DAEMON); + else { + logfd = open (log_file, + O_CREAT | O_APPEND | O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if (logfd < 0) { + g_set_error (error, 0, 0, "Failed to open log file: (%d) %s", + errno, strerror (errno)); + return FALSE; + } + } + + g_log_set_handler (G_LOG_DOMAIN, + G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + log_handler, + NULL); + + return TRUE; +} + +void +mm_log_usr1 (void) +{ +} + +void +mm_log_shutdown (void) +{ + if (logfd < 0) + closelog (); + else + close (logfd); +} + diff --git a/src/mm-log.h b/src/mm-log.h new file mode 100644 index 00000000..9b0d875f --- /dev/null +++ b/src/mm-log.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 2 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: + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#ifndef MM_LOG_H +#define MM_LOG_H + +#include <glib.h> + +/* Log levels */ +enum { + LOGL_ERR = 0x00000001, + LOGL_WARN = 0x00000002, + LOGL_INFO = 0x00000004, + LOGL_DEBUG = 0x00000008 +}; + +#define mm_err(...) \ + _mm_log (G_STRLOC, G_STRFUNC, LOGL_ERR, ## __VA_ARGS__ ) + +#define mm_warn(...) \ + _mm_log (G_STRLOC, G_STRFUNC, LOGL_WARN, ## __VA_ARGS__ ) + +#define mm_info(...) \ + _mm_log (G_STRLOC, G_STRFUNC, LOGL_INFO, ## __VA_ARGS__ ) + +#define mm_dbg(...) \ + _mm_log (G_STRLOC, G_STRFUNC, LOGL_DEBUG, ## __VA_ARGS__ ) + +#define mm_log(level, ...) \ + _mm_log (G_STRLOC, G_STRFUNC, level, ## __VA_ARGS__ ) + +void _mm_log (const char *loc, + const char *func, + guint32 level, + const char *fmt, + ...) __attribute__((__format__ (__printf__, 4, 5))); + +gboolean mm_log_setup (const char *level, + const char *log_file, + gboolean show_ts, + gboolean rel_ts, + GError **error); + +void mm_log_usr1 (void); + +void mm_log_shutdown (void); + +#endif /* MM_LOG_H */ + diff --git a/src/mm-manager.c b/src/mm-manager.c index 605ec5a1..561d427c 100644 --- a/src/mm-manager.c +++ b/src/mm-manager.c @@ -24,6 +24,7 @@ #include "mm-manager.h" #include "mm-errors.h" #include "mm-plugin.h" +#include "mm-log.h" static gboolean impl_manager_enumerate_devices (MMManager *manager, GPtrArray **devices, @@ -112,9 +113,9 @@ load_plugin (const char *path) plugin = (*plugin_create_func) (); if (plugin) { g_object_weak_ref (G_OBJECT (plugin), (GWeakNotify) g_module_close, module); - g_message ("Loaded plugin %s", mm_plugin_get_name (plugin)); + mm_info ("Loaded plugin %s", mm_plugin_get_name (plugin)); } else - g_warning ("Could not load plugin %s: initialization failed", path); + mm_warn ("Could not load plugin %s: initialization failed", path); out: if (!plugin) @@ -196,7 +197,7 @@ remove_modem (MMManager *manager, MMModem *modem) device = mm_modem_get_device (modem); g_assert (device); - g_debug ("Removed modem %s", device); + mm_dbg ("Removed modem %s", device); g_signal_emit (manager, signals[DEVICE_REMOVED], 0, modem); g_hash_table_remove (priv->modems, device); @@ -234,8 +235,8 @@ check_export_modem (MMManager *self, MMModem *modem) SupportsInfo *info = value; if (!strcmp (info->physdev_path, modem_physdev)) { - g_debug ("(%s/%s): outstanding support task prevents export of %s", - info->subsys, info->name, modem_physdev); + mm_dbg ("(%s/%s): outstanding support task prevents export of %s", + info->subsys, info->name, modem_physdev); goto out; } } @@ -257,7 +258,7 @@ check_export_modem (MMManager *self, MMModem *modem) dbus_g_connection_register_g_object (priv->connection, path, G_OBJECT (modem)); g_object_set_data_full (G_OBJECT (modem), DBUS_PATH_TAG, path, (GDestroyNotify) g_free); - g_debug ("Exported modem %s as %s", modem_physdev, path); + mm_dbg ("Exported modem %s as %s", modem_physdev, path); physdev = g_udev_client_query_by_sysfs_path (priv->udev, modem_physdev); if (physdev) @@ -268,10 +269,10 @@ check_export_modem (MMManager *self, MMModem *modem) MM_MODEM_HW_VID, &vid, MM_MODEM_HW_PID, &pid, NULL); - g_debug ("(%s): VID 0x%04X PID 0x%04X (%s)", + mm_dbg ("(%s): VID 0x%04X PID 0x%04X (%s)", path, (vid & 0xFFFF), (pid & 0xFFFF), subsys ? subsys : "unknown"); - g_debug ("(%s): data port is %s", path, data_device); + mm_dbg ("(%s): data port is %s", path, data_device); g_free (data_device); if (physdev) @@ -309,7 +310,7 @@ add_modem (MMManager *manager, MMModem *modem, MMPlugin *plugin) g_hash_table_insert (priv->modems, g_strdup (device), modem); g_object_set_data (G_OBJECT (modem), MANAGER_PLUGIN_TAG, plugin); - g_debug ("Added modem %s", device); + mm_dbg ("Added modem %s", device); g_signal_connect (modem, "notify::" MM_MODEM_VALID, G_CALLBACK (modem_valid), manager); check_export_modem (manager, modem); } @@ -446,7 +447,7 @@ supports_defer_timeout (gpointer user_data) existing = find_modem_for_device (info->manager, info->physdev_path); - g_debug ("(%s): re-checking support...", info->name); + mm_dbg ("(%s): re-checking support...", info->name); try_supports_port (info->manager, MM_PLUGIN (info->cur_plugin->data), existing, @@ -478,9 +479,9 @@ try_supports_port (MMManager *manager, supports_callback (plugin, info->subsys, info->name, 0, info); break; case MM_PLUGIN_SUPPORTS_PORT_DEFER: - g_debug ("(%s): (%s) deferring support check", - mm_plugin_get_name (plugin), - info->name); + mm_dbg ("(%s): (%s) deferring support check", + mm_plugin_get_name (plugin), + info->name); if (info->defer_id) g_source_remove (info->defer_id); @@ -549,22 +550,21 @@ do_grab_port (gpointer user_data) type_name = "CDMA"; device = mm_modem_get_device (modem); - g_message ("(%s): %s modem %s claimed port %s", - mm_plugin_get_name (info->best_plugin), - type_name, - device, - info->name); + mm_info ("(%s): %s modem %s claimed port %s", + mm_plugin_get_name (info->best_plugin), + type_name, + device, + info->name); g_free (device); add_modem (info->manager, modem, info->best_plugin); } else { - g_warning ("%s: plugin '%s' claimed to support %s/%s but couldn't: (%d) %s", - __func__, - mm_plugin_get_name (info->best_plugin), - info->subsys, - info->name, - error ? error->code : -1, - (error && error->message) ? error->message : "(unknown)"); + mm_warn ("plugin '%s' claimed to support %s/%s but couldn't: (%d) %s", + mm_plugin_get_name (info->best_plugin), + info->subsys, + info->name, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); modem = existing; } } @@ -613,8 +613,8 @@ supports_callback (MMPlugin *plugin, * support this port, but this plugin is clearly the right plugin * since it claimed this port's physical modem, just drop the port. */ - g_debug ("(%s/%s): ignoring port unsupported by physical modem's plugin", - info->subsys, info->name); + mm_dbg ("(%s/%s): ignoring port unsupported by physical modem's plugin", + info->subsys, info->name); supports_cleanup (info->manager, info->subsys, info->name, existing); return; } @@ -631,14 +631,14 @@ supports_callback (MMPlugin *plugin, */ next_plugin = existing_plugin; } else { - g_debug ("(%s/%s): plugin %p (%s) existing %p (%s) info->best %p (%s)", - info->subsys, info->name, - plugin, - plugin ? mm_plugin_get_name (plugin) : "none", - existing_plugin, - existing_plugin ? mm_plugin_get_name (existing_plugin) : "none", - info->best_plugin, - info->best_plugin ? mm_plugin_get_name (info->best_plugin) : "none"); + mm_dbg ("(%s/%s): plugin %p (%s) existing %p (%s) info->best %p (%s)", + info->subsys, info->name, + plugin, + plugin ? mm_plugin_get_name (plugin) : "none", + existing_plugin, + existing_plugin ? mm_plugin_get_name (existing_plugin) : "none", + info->best_plugin, + info->best_plugin ? mm_plugin_get_name (info->best_plugin) : "none"); g_assert_not_reached (); } } else { @@ -783,14 +783,14 @@ device_added (MMManager *manager, GUdevDevice *device) && strcmp (name, "lo") && strcmp (name, "tty") && !strstr (name, "virbr")) - g_debug ("(%s/%s): could not get port's parent device", subsys, name); + mm_dbg ("(%s/%s): could not get port's parent device", subsys, name); goto out; } /* Is the device blacklisted? */ if (g_udev_device_get_property_as_boolean (physdev, "ID_MM_DEVICE_IGNORE")) { - g_debug ("(%s/%s): port's parent device is blacklisted", subsys, name); + mm_dbg ("(%s/%s): port's parent device is blacklisted", subsys, name); goto out; } @@ -799,13 +799,13 @@ device_added (MMManager *manager, GUdevDevice *device) if ( physdev_subsys && !strcmp (physdev_subsys, "platform") && !g_udev_device_get_property_as_boolean (physdev, "ID_MM_PLATFORM_DRIVER_PROBE")) { - g_debug ("(%s/%s): port's parent platform driver is not whitelisted", subsys, name); + mm_dbg ("(%s/%s): port's parent platform driver is not whitelisted", subsys, name); goto out; } physdev_path = g_udev_device_get_sysfs_path (physdev); if (!physdev_path) { - g_debug ("(%s/%s): could not get port's parent device sysfs path", subsys, name); + mm_dbg ("(%s/%s): could not get port's parent device sysfs path", subsys, name); goto out; } @@ -836,7 +836,7 @@ device_removed (MMManager *manager, GUdevDevice *device) MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager); MMModem *modem; const char *subsys, *name; - char *key; + char *key, *modem_device; SupportsInfo *info; g_return_if_fail (device != NULL); @@ -851,6 +851,9 @@ device_removed (MMManager *manager, GUdevDevice *device) /* find_modem_for_port handles tty and net removal */ modem = find_modem_for_port (manager, subsys, name); if (modem) { + modem_device = mm_modem_get_device (modem); + mm_info ("(%s/%s): released by modem %s", subsys, name, modem_device); + g_free (modem_device); mm_modem_release_port (modem, subsys, name); return; } @@ -865,10 +868,9 @@ device_removed (MMManager *manager, GUdevDevice *device) */ const char *sysfs_path = g_udev_device_get_sysfs_path (device); - // g_debug ("Looking for a modem for removed device %s", sysfs_path); modem = find_modem_for_device (manager, sysfs_path); if (modem) { - g_debug ("Removing modem claimed by removed device %s", sysfs_path); + mm_dbg ("Removing modem claimed by removed device %s", sysfs_path); remove_modem (manager, modem); return; } diff --git a/src/mm-modem-base.c b/src/mm-modem-base.c index 50088fb5..ee5e1c86 100644 --- a/src/mm-modem-base.c +++ b/src/mm-modem-base.c @@ -25,7 +25,7 @@ #include "mm-at-serial-port.h" #include "mm-qcdm-serial-port.h" #include "mm-errors.h" -#include "mm-options.h" +#include "mm-log.h" #include "mm-properties-changed-signal.h" #include "mm-callback-info.h" #include "mm-modem-helpers.h" @@ -148,15 +148,13 @@ mm_modem_base_add_port (MMModemBase *self, if (!port) return NULL; - if (mm_options_debug ()) { - device = mm_modem_get_device (MM_MODEM (self)); + device = mm_modem_get_device (MM_MODEM (self)); + mm_dbg ("(%s) type %s claimed by %s", + name, + mm_port_type_to_name (ptype), + device); + g_free (device); - g_message ("(%s) type %s claimed by %s", - name, - mm_port_type_to_name (ptype), - device); - g_free (device); - } key = get_hash_key (subsys, name); g_hash_table_insert (priv->ports, key, port); return port; @@ -165,10 +163,32 @@ mm_modem_base_add_port (MMModemBase *self, gboolean mm_modem_base_remove_port (MMModemBase *self, MMPort *port) { + MMModemBasePrivate *priv; + char *device, *key, *name; + const char *type_name, *subsys; + gboolean removed; + g_return_val_if_fail (MM_IS_MODEM_BASE (self), FALSE); g_return_val_if_fail (port != NULL, FALSE); - return g_hash_table_remove (MM_MODEM_BASE_GET_PRIVATE (self)->ports, port); + priv = MM_MODEM_BASE_GET_PRIVATE (self); + + name = g_strdup (mm_port_get_device (port)); + subsys = mm_port_subsys_to_name (mm_port_get_subsys (port)); + type_name = mm_port_type_to_name (mm_port_get_port_type (port)); + + key = get_hash_key (subsys, name); + removed = g_hash_table_remove (priv->ports, key); + if (removed) { + /* Port may have already been destroyed by removal from the hash */ + device = mm_modem_get_device (MM_MODEM (self)); + mm_dbg ("(%s) type %s removed from %s", name, type_name, device); + g_free (device); + } + g_free (key); + g_free (name); + + return removed; } void @@ -233,9 +253,9 @@ mm_modem_base_set_equipment_identifier (MMModemBase *self, const char *ident) dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG); if (dbus_path) { if (priv->equipment_ident) - g_message ("Modem %s: Equipment identifier set (%s)", dbus_path, priv->equipment_ident); + mm_info ("Modem %s: Equipment identifier set (%s)", dbus_path, priv->equipment_ident); else - g_message ("Modem %s: Equipment identifier not set", dbus_path); + mm_warn ("Modem %s: Equipment identifier not set", dbus_path); } g_object_notify (G_OBJECT (self), MM_MODEM_EQUIPMENT_IDENTIFIER); @@ -274,9 +294,9 @@ mm_modem_base_set_unlock_required (MMModemBase *self, const char *unlock_require dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG); if (dbus_path) { if (priv->unlock_required) - g_message ("Modem %s: unlock required (%s)", dbus_path, priv->unlock_required); + mm_info ("Modem %s: unlock required (%s)", dbus_path, priv->unlock_required); else - g_message ("Modem %s: unlock no longer required", dbus_path); + mm_info ("Modem %s: unlock no longer required", dbus_path); } g_object_notify (G_OBJECT (self), MM_MODEM_UNLOCK_REQUIRED); @@ -311,11 +331,11 @@ mm_modem_base_set_unlock_retries (MMModemBase *self, guint unlock_retries) dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG); if (dbus_path) { if (priv->unlock_required) { - g_message ("Modem %s: # unlock retries for %s is %d", - dbus_path, priv->unlock_required, priv->unlock_retries); + mm_info ("Modem %s: # unlock retries for %s is %d", + dbus_path, priv->unlock_required, priv->unlock_retries); } else { - g_message ("Modem %s: # unlock retries is %d", - dbus_path, priv->unlock_retries); + mm_info ("Modem %s: # unlock retries is %d", + dbus_path, priv->unlock_retries); } } @@ -446,8 +466,7 @@ card_info_cache_invoke (MMCallbackInfo *info) priv->gsn, priv->revision, priv->model, - priv->manf, - mm_options_debug ()); + priv->manf); g_object_notify (G_OBJECT (self), MM_MODEM_DEVICE_IDENTIFIER); callback (info->modem, priv->manf, priv->model, priv->revision, info->error, info->user_data); @@ -626,6 +645,10 @@ mm_modem_base_init (MMModemBase *self) MM_MODEM_UNLOCK_RETRIES, NULL, MM_MODEM_DBUS_INTERFACE); + mm_properties_changed_signal_register_property (G_OBJECT (self), + MM_MODEM_IP_METHOD, + NULL, + MM_MODEM_DBUS_INTERFACE); } static void diff --git a/src/mm-modem-cdma.c b/src/mm-modem-cdma.c index 3f4ffe54..722918e0 100644 --- a/src/mm-modem-cdma.c +++ b/src/mm-modem-cdma.c @@ -357,6 +357,15 @@ mm_modem_cdma_init (gpointer g_iface) if (initialized) return; + /* Properties */ + g_object_interface_install_property + (g_iface, + g_param_spec_string (MM_MODEM_CDMA_MEID, + "MEID", + "MEID", + NULL, + G_PARAM_READABLE)); + /* Signals */ signals[SIGNAL_QUALITY] = g_signal_new ("signal-quality", diff --git a/src/mm-modem-cdma.h b/src/mm-modem-cdma.h index 89751518..4d30386a 100644 --- a/src/mm-modem-cdma.h +++ b/src/mm-modem-cdma.h @@ -35,6 +35,14 @@ typedef enum { #define MM_MODEM_CDMA_REGISTRATION_STATE_CHANGED "registration-state-changed" +#define MM_MODEM_CDMA_MEID "meid" + +typedef enum { + MM_MODEM_CDMA_PROP_FIRST = 0x1200, + + MM_MODEM_CDMA_PROP_MEID = MM_MODEM_CDMA_PROP_FIRST, +} MMModemCdmaProp; + typedef struct _MMModemCdma MMModemCdma; typedef void (*MMModemCdmaServingSystemFn) (MMModemCdma *modem, diff --git a/src/mm-modem-gsm-network.c b/src/mm-modem-gsm-network.c index 4cd69218..75ca7de9 100644 --- a/src/mm-modem-gsm-network.c +++ b/src/mm-modem-gsm-network.c @@ -108,6 +108,8 @@ mm_modem_gsm_network_act_to_old_mode (MMModemGsmAccessTech act) return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSUPA; else if (act & MM_MODEM_GSM_ACCESS_TECH_HSPA) return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA; + else if (act & MM_MODEM_GSM_ACCESS_TECH_HSPA_PLUS) + return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA; return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY; } diff --git a/src/mm-modem-gsm-ussd.c b/src/mm-modem-gsm-ussd.c index def22134..f90a8458 100644 --- a/src/mm-modem-gsm-ussd.c +++ b/src/mm-modem-gsm-ussd.c @@ -106,6 +106,23 @@ mm_modem_gsm_ussd_initiate (MMModemGsmUssd *self, } void +mm_modem_gsm_ussd_respond (MMModemGsmUssd *self, + const char *command, + MMModemStringFn callback, + gpointer user_data) +{ + g_return_if_fail (MM_IS_MODEM_GSM_USSD (self)); + g_return_if_fail (command != NULL); + g_return_if_fail (callback != NULL); + + if (MM_MODEM_GSM_USSD_GET_INTERFACE (self)->respond) + MM_MODEM_GSM_USSD_GET_INTERFACE (self)->respond(self, command, callback, user_data); + else + str_call_not_supported (self, callback, user_data); + +} + +void mm_modem_gsm_ussd_cancel (MMModemGsmUssd *self, MMModemFn callback, gpointer user_data) @@ -149,16 +166,6 @@ ussd_auth_info_new (const char* command) /*****************************************************************************/ static void -impl_modem_gsm_ussd_respond (MMModemGsmUssd *modem, - const char *responste, - DBusGMethodInvocation *context) -{ - async_call_not_supported (modem, async_call_done, context); -} - -/*****************************************************************************/ - -static void ussd_initiate_auth_cb (MMAuthRequest *req, GObject *owner, DBusGMethodInvocation *context, @@ -209,6 +216,56 @@ impl_modem_gsm_ussd_initiate (MMModemGsmUssd *modem, } static void +ussd_respond_auth_cb (MMAuthRequest *req, + GObject *owner, + DBusGMethodInvocation *context, + gpointer user_data) +{ + MMModemGsmUssd *self = MM_MODEM_GSM_USSD (owner); + UssdAuthInfo *info = user_data; + GError *error = NULL; + + /* Return any authorization error, otherwise respond to the USSD */ + if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) + goto done; + + if (!info->command) { + error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, + "Missing USSD command"); + } + +done: + if (error) { + str_call_done (MM_MODEM (self), NULL, error, context); + g_error_free (error); + } else + mm_modem_gsm_ussd_respond (self, info->command, str_call_done, context); +} + +static void +impl_modem_gsm_ussd_respond (MMModemGsmUssd *modem, + const char *command, + DBusGMethodInvocation *context) +{ + GError *error = NULL; + UssdAuthInfo *info; + + info = ussd_auth_info_new (command); + + /* Make sure the caller is authorized to respond to the USSD */ + if (!mm_modem_auth_request (MM_MODEM (modem), + MM_AUTHORIZATION_USSD, + context, + ussd_respond_auth_cb, + info, + ussd_auth_info_destroy, + &error)) { + dbus_g_method_return_error (context, error); + g_error_free (error); + } +} + +static void ussd_cancel_auth_cb (MMAuthRequest *req, GObject *owner, DBusGMethodInvocation *context, diff --git a/src/mm-modem-gsm-ussd.h b/src/mm-modem-gsm-ussd.h index d0da59be..c8f652b9 100644 --- a/src/mm-modem-gsm-ussd.h +++ b/src/mm-modem-gsm-ussd.h @@ -46,6 +46,11 @@ struct _MMModemGsmUssd { MMModemStringFn callback, gpointer user_data); + void (*respond) (MMModemGsmUssd *modem, + const char *command, + MMModemStringFn callback, + gpointer user_data); + void (*cancel) (MMModemGsmUssd *modem, MMModemFn callback, gpointer user_data); @@ -58,6 +63,11 @@ void mm_modem_gsm_ussd_initiate (MMModemGsmUssd *self, MMModemStringFn callback, gpointer user_data); +void mm_modem_gsm_ussd_respond (MMModemGsmUssd *self, + const char *command, + MMModemStringFn callback, + gpointer user_data); + void mm_modem_gsm_ussd_cancel (MMModemGsmUssd *self, MMModemFn callback, gpointer user_data); diff --git a/src/mm-modem-gsm.h b/src/mm-modem-gsm.h index 6d9135a4..a427d354 100644 --- a/src/mm-modem-gsm.h +++ b/src/mm-modem-gsm.h @@ -54,8 +54,9 @@ typedef enum { MM_MODEM_GSM_ACCESS_TECH_HSDPA = 6, /* UTRAN w/HSDPA */ MM_MODEM_GSM_ACCESS_TECH_HSUPA = 7, /* UTRAN w/HSUPA */ MM_MODEM_GSM_ACCESS_TECH_HSPA = 8, /* UTRAN w/HSDPA and HSUPA */ + MM_MODEM_GSM_ACCESS_TECH_HSPA_PLUS = 9, /* UTRAN w/HSPA+ */ - MM_MODEM_GSM_ACCESS_TECH_LAST = MM_MODEM_GSM_ACCESS_TECH_HSPA + MM_MODEM_GSM_ACCESS_TECH_LAST = MM_MODEM_GSM_ACCESS_TECH_HSPA_PLUS } MMModemGsmAccessTech; typedef enum { diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index 25998b1f..f13b4f27 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -25,6 +25,7 @@ #include "mm-errors.h" #include "mm-modem-helpers.h" +#include "mm-log.h" const char * mm_strip_tag (const char *str, const char *cmd) @@ -242,10 +243,14 @@ mm_gsm_destroy_scan_data (gpointer data) /* +CREG: <n>,<stat>,<lac>,<ci>,<AcT> (ETSI 27.007 solicited and some CREG=2 unsolicited) */ #define CREG6 "\\+(CREG|CGREG):\\s*(\\d{1}),\\s*(\\d{1})\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*(\\d{1,2})" +/* +CREG: <n>,<stat>,<lac>,<ci>,<AcT?>,<something> (Samsung Wave S8500) */ +/* '<CR><LF>+CREG: 2,1,000B,2816, B, C2816<CR><LF><CR><LF>OK<CR><LF>' */ +#define CREG7 "\\+(CREG|CGREG):\\s*(\\d{1}),\\s*(\\d{1})\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*[^,\\s]*" + GPtrArray * mm_gsm_creg_regex_get (gboolean solicited) { - GPtrArray *array = g_ptr_array_sized_new (6); + GPtrArray *array = g_ptr_array_sized_new (7); GRegex *regex; /* #1 */ @@ -296,6 +301,14 @@ mm_gsm_creg_regex_get (gboolean solicited) g_assert (regex); g_ptr_array_add (array, regex); + /* #7 */ + if (solicited) + regex = g_regex_new (CREG7 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + else + regex = g_regex_new ("\\r\\n" CREG7 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + g_assert (regex); + g_ptr_array_add (array, regex); + return array; } @@ -785,7 +798,9 @@ mm_gsm_string_to_access_tech (const char *string) /* Better technologies are listed first since modems sometimes say * stuff like "GPRS/EDGE" and that should be handled as EDGE. */ - if (strcasestr (string, "HSPA")) + if (strcasestr (string, "HSPA+")) + return MM_MODEM_GSM_ACCESS_TECH_HSPA_PLUS; + else if (strcasestr (string, "HSPA")) return MM_MODEM_GSM_ACCESS_TECH_HSPA; else if (strcasestr (string, "HSDPA/HSUPA")) return MM_MODEM_GSM_ACCESS_TECH_HSPA; @@ -815,10 +830,9 @@ mm_create_device_identifier (guint vid, const char *gsn, const char *revision, const char *model, - const char *manf, - gboolean debug) + const char *manf) { - GString *devid, *dbg = NULL; + GString *devid, *msg = NULL; GChecksum *sum; char *p, *ret = NULL; char str_vid[10], str_pid[10]; @@ -845,41 +859,35 @@ mm_create_device_identifier (guint vid, return NULL; p = devid->str; - if (debug) - dbg = g_string_sized_new (strlen (devid->str) + 17); + msg = g_string_sized_new (strlen (devid->str) + 17); sum = g_checksum_new (G_CHECKSUM_SHA1); if (vid) { snprintf (str_vid, sizeof (str_vid) - 1, "%08x", vid); g_checksum_update (sum, (const guchar *) &str_vid[0], strlen (str_vid)); - if (dbg) - g_string_append_printf (dbg, "%08x", vid); + g_string_append_printf (msg, "%08x", vid); } if (vid) { snprintf (str_pid, sizeof (str_pid) - 1, "%08x", pid); g_checksum_update (sum, (const guchar *) &str_pid[0], strlen (str_pid)); - if (dbg) - g_string_append_printf (dbg, "%08x", pid); + g_string_append_printf (msg, "%08x", pid); } while (*p) { /* Strip spaces and linebreaks */ if (!isblank (*p) && !isspace (*p) && isascii (*p)) { g_checksum_update (sum, (const guchar *) p, 1); - if (dbg) - g_string_append_c (dbg, *p); + g_string_append_c (msg, *p); } p++; } ret = g_strdup (g_checksum_get_string (sum)); g_checksum_free (sum); - if (dbg) { - g_debug ("Device ID source '%s'", dbg->str); - g_debug ("Device ID '%s'", ret); - g_string_free (dbg, TRUE); - } + mm_dbg ("Device ID source '%s'", msg->str); + mm_dbg ("Device ID '%s'", ret); + g_string_free (msg, TRUE); return ret; } diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index eda6e5d7..71ccaa5d 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -66,8 +66,7 @@ char *mm_create_device_identifier (guint vid, const char *gsn, const char *revision, const char *model, - const char *manf, - gboolean debug); + const char *manf); typedef struct CindResponse CindResponse; GHashTable *mm_parse_cind_test_response (const char *reply, GError **error); diff --git a/src/mm-modem.c b/src/mm-modem.c index c65bee54..f8234723 100644 --- a/src/mm-modem.c +++ b/src/mm-modem.c @@ -18,7 +18,7 @@ #include <string.h> #include <dbus/dbus-glib.h> #include "mm-modem.h" -#include "mm-options.h" +#include "mm-log.h" #include "mm-errors.h" #include "mm-callback-info.h" #include "mm-marshal.h" @@ -28,6 +28,7 @@ static void impl_modem_connect (MMModem *modem, const char *number, DBusGMethodI static void impl_modem_disconnect (MMModem *modem, DBusGMethodInvocation *context); static void impl_modem_get_ip4_config (MMModem *modem, DBusGMethodInvocation *context); static void impl_modem_get_info (MMModem *modem, DBusGMethodInvocation *context); +static void impl_modem_reset (MMModem *modem, DBusGMethodInvocation *context); static void impl_modem_factory_reset (MMModem *modem, const char *code, DBusGMethodInvocation *context); #include "mm-modem-glue.h" @@ -478,6 +479,56 @@ impl_modem_get_info (MMModem *modem, /*****************************************************************************/ static void +reset_auth_cb (MMAuthRequest *req, + GObject *owner, + DBusGMethodInvocation *context, + gpointer user_data) +{ + MMModem *self = MM_MODEM (owner); + GError *error = NULL; + + /* Return any authorization error, otherwise try to reset the modem */ + if (!mm_modem_auth_finish (self, req, &error)) { + dbus_g_method_return_error (context, error); + g_error_free (error); + } else + mm_modem_reset (self, async_call_done, context); +} + +static void +impl_modem_reset (MMModem *modem, DBusGMethodInvocation *context) +{ + GError *error = NULL; + + /* Make sure the caller is authorized to reset the device */ + if (!mm_modem_auth_request (MM_MODEM (modem), + MM_AUTHORIZATION_DEVICE_CONTROL, + context, + reset_auth_cb, + NULL, NULL, + &error)) { + dbus_g_method_return_error (context, error); + g_error_free (error); + } +} + +void +mm_modem_reset (MMModem *self, + MMModemFn callback, + gpointer user_data) +{ + g_return_if_fail (MM_IS_MODEM (self)); + g_return_if_fail (callback != NULL); + + if (MM_MODEM_GET_INTERFACE (self)->reset) + MM_MODEM_GET_INTERFACE (self)->reset (self, callback, user_data); + else + async_op_not_supported (self, callback, user_data); +} + +/*****************************************************************************/ + +static void factory_reset_auth_cb (MMAuthRequest *req, GObject *owner, DBusGMethodInvocation *context, @@ -704,22 +755,10 @@ mm_modem_set_state (MMModem *self, dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG); if (dbus_path) { - if (mm_options_debug ()) { - GTimeVal tv; - - g_get_current_time (&tv); - g_debug ("<%ld.%ld> Modem %s: state changed (%s -> %s)", - tv.tv_sec, - tv.tv_usec, - dbus_path, - state_to_string (old_state), - state_to_string (new_state)); - } else { - g_message ("Modem %s: state changed (%s -> %s)", - dbus_path, - state_to_string (old_state), - state_to_string (new_state)); - } + mm_info ("Modem %s: state changed (%s -> %s)", + dbus_path, + state_to_string (old_state), + state_to_string (new_state)); } } } diff --git a/src/mm-modem.h b/src/mm-modem.h index 1faf3838..8a755d88 100644 --- a/src/mm-modem.h +++ b/src/mm-modem.h @@ -194,6 +194,10 @@ struct _MMModem { MMAuthRequest *req, GError **error); + void (*reset) (MMModem *self, + MMModemFn callback, + gpointer user_data); + void (*factory_reset) (MMModem *self, const char *code, MMModemFn callback, @@ -257,6 +261,10 @@ void mm_modem_set_charset (MMModem *self, MMModemFn callback, gpointer user_data); +void mm_modem_reset (MMModem *self, + MMModemFn callback, + gpointer user_data); + void mm_modem_factory_reset (MMModem *self, const char *code, MMModemFn callback, diff --git a/src/mm-options.c b/src/mm-options.c deleted file mode 100644 index 7bbeefd6..00000000 --- a/src/mm-options.c +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * 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 2 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: - * - * Copyright (C) 2008 Novell, Inc. - */ - -#include <stdlib.h> -#include <glib.h> -#include "mm-options.h" - -static gboolean debug = FALSE; - -void -mm_options_parse (int argc, char *argv[]) -{ - GOptionContext *opt_ctx; - GError *error = NULL; - GOptionEntry entries[] = { - { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, "Output to console rather than syslog", NULL }, - { NULL } - }; - - opt_ctx = g_option_context_new (NULL); - g_option_context_set_summary (opt_ctx, "DBus system service to communicate with modems."); - g_option_context_add_main_entries (opt_ctx, entries, NULL); - - if (!g_option_context_parse (opt_ctx, &argc, &argv, &error)) { - g_warning ("%s\n", error->message); - g_error_free (error); - exit (1); - } - - g_option_context_free (opt_ctx); -} - -void -mm_options_set_debug (gboolean enabled) -{ - debug = enabled; -} - -gboolean -mm_options_debug (void) -{ - return debug; -} diff --git a/src/mm-options.h b/src/mm-options.h deleted file mode 100644 index ce33e274..00000000 --- a/src/mm-options.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * 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 2 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: - * - * Copyright (C) 2008 Novell, Inc. - */ - -#ifndef MM_OPTIONS_H -#define MM_OPTIONS_H - -void mm_options_parse (int argc, char *argv[]); -void mm_options_set_debug (gboolean enabled); -gboolean mm_options_debug (void); - -#endif /* MM_OPTIONS_H */ diff --git a/src/mm-plugin-base.c b/src/mm-plugin-base.c index 5a86b977..8d32e2a5 100644 --- a/src/mm-plugin-base.c +++ b/src/mm-plugin-base.c @@ -36,6 +36,7 @@ #include "mm-utils.h" #include "libqcdm/src/commands.h" #include "libqcdm/src/utils.h" +#include "mm-log.h" static void plugin_init (MMPlugin *plugin_class); @@ -807,9 +808,9 @@ try_open (gpointer user_data) task_priv->full_id = g_signal_connect (task_priv->probe_port, "buffer-full", G_CALLBACK (port_buffer_full), task); - g_debug ("(%s): probe requested by plugin '%s'", - g_udev_device_get_name (port), - mm_plugin_get_name (MM_PLUGIN (task_priv->plugin))); + mm_dbg ("(%s): probe requested by plugin '%s'", + g_udev_device_get_name (port), + mm_plugin_get_name (MM_PLUGIN (task_priv->plugin))); mm_serial_port_flash (MM_SERIAL_PORT (task_priv->probe_port), 100, TRUE, flash_done, task); } diff --git a/src/mm-port.c b/src/mm-port.c index b2018fe2..a1291d0b 100644 --- a/src/mm-port.c +++ b/src/mm-port.c @@ -19,7 +19,7 @@ #include <string.h> #include "mm-port.h" -#include "mm-options.h" +#include "mm-log.h" G_DEFINE_TYPE (MMPort, mm_port, G_TYPE_OBJECT) @@ -47,6 +47,20 @@ typedef struct { /*****************************************************************************/ const char * +mm_port_subsys_to_name (MMPortSubsys psubsys) +{ + switch (psubsys) { + case MM_PORT_SUBSYS_TTY: + return "tty"; + case MM_PORT_SUBSYS_NET: + return "net"; + default: + break; + } + return "(unknown)"; +} + +const char * mm_port_type_to_name (MMPortType ptype) { switch (ptype) { @@ -161,16 +175,10 @@ mm_port_set_connected (MMPort *self, gboolean connected) if (priv->connected != connected) { priv->connected = connected; g_object_notify (G_OBJECT (self), MM_PORT_CONNECTED); - if (mm_options_debug()) { - GTimeVal tv; - - g_get_current_time (&tv); - g_debug ("<%ld.%ld> (%s): port now %s", - tv.tv_sec, - tv.tv_usec, - priv->device, - connected ? "connected" : "disconnected"); - } + + mm_dbg ("(%s): port now %s", + priv->device, + connected ? "connected" : "disconnected"); } } diff --git a/src/mm-port.h b/src/mm-port.h index 43f78f46..4bcffd49 100644 --- a/src/mm-port.h +++ b/src/mm-port.h @@ -78,5 +78,7 @@ void mm_port_set_connected (MMPort *self, gboolean connected); const char * mm_port_type_to_name (MMPortType ptype); +const char * mm_port_subsys_to_name (MMPortSubsys psubsys); + #endif /* MM_PORT_H */ diff --git a/src/mm-properties-changed-signal.c b/src/mm-properties-changed-signal.c index 633ff771..4408e80a 100644 --- a/src/mm-properties-changed-signal.c +++ b/src/mm-properties-changed-signal.c @@ -21,6 +21,7 @@ #include "mm-marshal.h" #include "mm-properties-changed-signal.h" #include "mm-properties-changed-glue.h" +#include "mm-log.h" #define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) #define DBUS_TYPE_G_ARRAY_OF_STRING (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING)) @@ -150,10 +151,10 @@ properties_changed (gpointer data) { char buf[2048] = { 0, }; g_hash_table_foreach (props, add_to_string, &buf); - g_message ("%s: %s -> (%s) %s", __func__, - G_OBJECT_TYPE_NAME (object), - interface, - buf); + mm_dbg ("%s: %s -> (%s) %s", __func__, + G_OBJECT_TYPE_NAME (object), + interface, + buf); } #endif diff --git a/src/mm-qcdm-serial-port.c b/src/mm-qcdm-serial-port.c index 7f4302c5..e467f2a2 100644 --- a/src/mm-qcdm-serial-port.c +++ b/src/mm-qcdm-serial-port.c @@ -21,9 +21,9 @@ #include "mm-qcdm-serial-port.h" #include "mm-errors.h" -#include "mm-options.h" #include "libqcdm/src/com.h" #include "libqcdm/src/utils.h" +#include "mm-log.h" G_DEFINE_TYPE (MMQcdmSerialPort, mm_qcdm_serial_port, MM_TYPE_SERIAL_PORT) @@ -182,7 +182,6 @@ debug_log (MMSerialPort *port, const char *prefix, const char *buf, gsize len) { static GString *debug = NULL; const char *s = buf; - GTimeVal tv; if (!debug) debug = g_string_sized_new (512); @@ -192,12 +191,7 @@ debug_log (MMSerialPort *port, const char *prefix, const char *buf, gsize len) while (len--) g_string_append_printf (debug, " %02x", (guint8) (*s++ & 0xFF)); - g_get_current_time (&tv); - g_debug ("<%ld.%ld> (%s): %s", - tv.tv_sec, - tv.tv_usec, - mm_port_get_device (MM_PORT (port)), - debug->str); + mm_dbg ("(%s): %s", mm_port_get_device (MM_PORT (port)), debug->str); g_string_truncate (debug, 0); } diff --git a/src/mm-serial-parsers.c b/src/mm-serial-parsers.c index 735ebd97..75bcce4d 100644 --- a/src/mm-serial-parsers.c +++ b/src/mm-serial-parsers.c @@ -19,6 +19,7 @@ #include "mm-serial-parsers.h" #include "mm-errors.h" +#include "mm-log.h" /* Clean up the response by removing control characters like <CR><LF> etc */ static void @@ -174,7 +175,7 @@ mm_serial_parser_v0_parse (gpointer data, response_clean (response); if (local_error) { - g_debug ("Got failure code %d: %s", local_error->code, local_error->message); + mm_dbg ("Got failure code %d: %s", local_error->code, local_error->message); g_propagate_error (error, local_error); } @@ -336,7 +337,7 @@ done: response_clean (response); if (local_error) { - g_debug ("Got failure code %d: %s", local_error->code, local_error->message); + mm_dbg ("Got failure code %d: %s", local_error->code, local_error->message); g_propagate_error (error, local_error); } diff --git a/src/mm-serial-port.c b/src/mm-serial-port.c index 0f4d888e..bf2a98ab 100644 --- a/src/mm-serial-port.c +++ b/src/mm-serial-port.c @@ -30,7 +30,7 @@ #include "mm-serial-port.h" #include "mm-errors.h" -#include "mm-options.h" +#include "mm-log.h" static gboolean mm_serial_port_queue_process (gpointer data); @@ -152,10 +152,10 @@ mm_serial_port_print_config (MMSerialPort *port, const char *detail) return; } - g_message ("*** %s (%s): (%s) baud rate: %d (%s)", - __func__, detail, mm_port_get_device (MM_PORT (port)), - stbuf.c_cflag & CBAUD, - baud_to_string (stbuf.c_cflag & CBAUD)); + mm_info ("(%s): (%s) baud rate: %d (%s)", + detail, mm_port_get_device (MM_PORT (port)), + stbuf.c_cflag & CBAUD, + baud_to_string (stbuf.c_cflag & CBAUD)); } #endif @@ -350,7 +350,7 @@ serial_debug (MMSerialPort *self, const char *prefix, const char *buf, gsize len { g_return_if_fail (len > 0); - if (mm_options_debug () && MM_SERIAL_PORT_GET_CLASS (self)->debug_log) + if (MM_SERIAL_PORT_GET_CLASS (self)->debug_log) MM_SERIAL_PORT_GET_CLASS (self)->debug_log (self, prefix, buf, len); } @@ -686,7 +686,6 @@ mm_serial_port_open (MMSerialPort *self, GError **error) MMSerialPortPrivate *priv; char *devfile; const char *device; - GTimeVal tv; struct serial_struct sinfo; g_return_val_if_fail (MM_IS_SERIAL_PORT (self), FALSE); @@ -700,12 +699,7 @@ mm_serial_port_open (MMSerialPort *self, GError **error) goto success; } - if (mm_options_debug ()) { - g_get_current_time (&tv); - g_debug ("<%ld.%ld> (%s) opening serial port...", - tv.tv_sec, tv.tv_usec, device); - } else - g_message ("(%s) opening serial port...", device); + mm_info ("(%s) opening serial port...", device); /* Only open a new file descriptor if we weren't given one already */ if (priv->fd < 0) { @@ -767,11 +761,7 @@ mm_serial_port_open (MMSerialPort *self, GError **error) success: priv->open_count++; - if (mm_options_debug ()) { - g_get_current_time (&tv); - g_debug ("<%ld.%ld> (%s) device open count is %d (open)", - tv.tv_sec, tv.tv_usec, device, priv->open_count); - } + mm_dbg ("(%s) device open count is %d (open)", device, priv->open_count); return TRUE; error: @@ -794,7 +784,6 @@ mm_serial_port_close (MMSerialPort *self) { MMSerialPortPrivate *priv; const char *device; - GTimeVal tv; int i; g_return_if_fail (MM_IS_SERIAL_PORT (self)); @@ -806,11 +795,7 @@ mm_serial_port_close (MMSerialPort *self) priv->open_count--; - if (mm_options_debug ()) { - g_get_current_time (&tv); - g_debug ("<%ld.%ld> (%s) device open count is %d (close)", - tv.tv_sec, tv.tv_usec, device, priv->open_count); - } + mm_dbg ("(%s) device open count is %d (close)", device, priv->open_count); if (priv->open_count > 0) return; @@ -823,12 +808,7 @@ mm_serial_port_close (MMSerialPort *self) if (priv->fd >= 0) { GTimeVal tv_start, tv_end; - g_get_current_time (&tv_start); - if (mm_options_debug ()) { - g_debug ("<%ld.%ld> (%s) closing serial port...", - tv_start.tv_sec, tv_start.tv_usec, device); - } else - g_message ("(%s) closing serial port...", device); + mm_info ("(%s) closing serial port...", device); mm_port_set_connected (MM_PORT (self), FALSE); @@ -842,16 +822,16 @@ mm_serial_port_close (MMSerialPort *self) mm_serial_port_flash_cancel (self); + g_get_current_time (&tv_start); + tcsetattr (priv->fd, TCSANOW, &priv->old_t); tcflush (priv->fd, TCIOFLUSH); close (priv->fd); priv->fd = -1; g_get_current_time (&tv_end); - if (mm_options_debug ()) { - g_debug ("<%ld.%ld> (%s) serial port closed", - tv_end.tv_sec, tv_end.tv_usec, device); - } + + mm_info ("(%s) serial port closed", device); /* Some ports don't respond to data and when close is called * the serial layer waits up to 30 second (closing_wait) for @@ -859,7 +839,7 @@ mm_serial_port_close (MMSerialPort *self) * Log that. See GNOME bug #630670 for more details. */ if (tv_end.tv_sec - tv_start.tv_sec > 20) - g_warning ("(%s): close blocked by driver for more than 20 seconds!", device); + mm_warn ("(%s): close blocked by driver for more than 20 seconds!", device); } /* Clear the command queue */ diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c index f0cbe61c..946916ff 100644 --- a/src/tests/test-modem-helpers.c +++ b/src/tests/test-modem-helpers.c @@ -17,6 +17,7 @@ #include <string.h> #include "mm-modem-helpers.h" +#include "mm-log.h" typedef struct { GPtrArray *solicited_creg; @@ -722,6 +723,16 @@ test_cgreg2_x220_unsolicited (void *f, gpointer d) } static void +test_creg2_s8500_wave_unsolicited (void *f, gpointer d) +{ + TestData *data = (TestData *) d; + const char *reply = "\r\n+CREG: 2,1,000B,2816, B, C2816\r\n"; + const CregResult result = { 1, 0x000B, 0x2816, 0, 7, FALSE}; + + test_creg_match ("Samsung Wave S8500 CREG=2", FALSE, reply, data, &result); +} + +static void test_cscs_icon225_support_response (void *f, gpointer d) { const char *reply = "\r\n+CSCS: (\"IRA\",\"GSM\",\"UCS2\")\r\n"; @@ -1069,8 +1080,7 @@ test_devid_item (void *f, gpointer d) item->gsn, item->revision, item->model, - item->manf, - FALSE); + item->manf); g_assert (devid); if (strcmp (devid, item->devid)) g_message ("%s", devid); @@ -1107,7 +1117,7 @@ test_cind_results (const char *desc, compare = g_hash_table_lookup (results, expected->desc); g_assert (compare); - g_assert_cmpint (i, ==, cind_response_get_index (compare)); + g_assert_cmpint (i + 1, ==, cind_response_get_index (compare)); g_assert_cmpint (expected->min, ==, cind_response_get_min (compare)); g_assert_cmpint (expected->max, ==, cind_response_get_max (compare)); } @@ -1168,6 +1178,15 @@ test_data_free (TestData *data) g_free (data); } +void +_mm_log (const char *loc, + const char *func, + guint32 level, + const char *fmt, + ...) +{ + /* Dummy log function */ +} #if GLIB_CHECK_VERSION(2,25,12) typedef GTestFixtureFunc TCFunc; @@ -1231,6 +1250,7 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_creg2_tm506_solicited, data)); g_test_suite_add (suite, TESTCASE (test_creg2_xu870_unsolicited_unregistered, data)); g_test_suite_add (suite, TESTCASE (test_creg2_md400_unsolicited, data)); + g_test_suite_add (suite, TESTCASE (test_creg2_s8500_wave_unsolicited, data)); g_test_suite_add (suite, TESTCASE (test_cgreg1_solicited, data)); g_test_suite_add (suite, TESTCASE (test_cgreg1_unsolicited, data)); diff --git a/src/tests/test-qcdm-serial-port.c b/src/tests/test-qcdm-serial-port.c index ab737c5e..3aeed6ab 100644 --- a/src/tests/test-qcdm-serial-port.c +++ b/src/tests/test-qcdm-serial-port.c @@ -31,6 +31,7 @@ #include "libqcdm/src/commands.h" #include "libqcdm/src/utils.h" #include "libqcdm/src/com.h" +#include "mm-log.h" typedef struct { int master; @@ -449,10 +450,14 @@ typedef void (*TCFunc)(void); #define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL) #define TESTCASE_PTY(t, d) g_test_create_case (#t, sizeof (*d), d, (TCFunc) test_pty_create, (TCFunc) t, (TCFunc) test_pty_cleanup) -gboolean mm_options_debug (void); -gboolean mm_options_debug (void) +void +_mm_log (const char *loc, + const char *func, + guint32 level, + const char *fmt, + ...) { - return g_test_verbose (); + /* Dummy log function */ } int main (int argc, char **argv) |