diff options
-rw-r--r-- | plugins/mm-modem-huawei-gsm.c | 101 | ||||
-rw-r--r-- | plugins/mm-modem-mbm.c | 65 | ||||
-rw-r--r-- | plugins/mm-modem-option.c | 46 | ||||
-rw-r--r-- | src/mm-generic-gsm.c | 106 | ||||
-rw-r--r-- | src/mm-generic-gsm.h | 21 | ||||
-rw-r--r-- | src/mm-modem-gsm-network.c | 92 | ||||
-rw-r--r-- | src/mm-modem-gsm-network.h | 22 | ||||
-rw-r--r-- | src/mm-modem-gsm.h | 2 |
8 files changed, 283 insertions, 172 deletions
diff --git a/plugins/mm-modem-huawei-gsm.c b/plugins/mm-modem-huawei-gsm.c index af6a4b7b..4594872b 100644 --- a/plugins/mm-modem-huawei-gsm.c +++ b/plugins/mm-modem-huawei-gsm.c @@ -41,7 +41,6 @@ G_DEFINE_TYPE_EXTENDED (MMModemHuaweiGsm, mm_modem_huawei_gsm, MM_TYPE_GENERIC_G typedef struct { /* Cached state */ guint signal_quality; - MMModemGsmMode mode; MMModemGsmBand band; } MMModemHuaweiGsmPrivate; @@ -68,23 +67,28 @@ parse_syscfg (MMModemHuaweiGsm *self, int *mode_b, guint32 *band, int *unknown1, - int *unknown2) + int *unknown2, + MMModemGsmMode *out_mode) { if (reply == NULL || strncmp (reply, "^SYSCFG:", 8)) return FALSE; if (sscanf (reply + 8, "%d,%d,%x,%d,%d", mode_a, mode_b, band, unknown1, unknown2)) { MMModemHuaweiGsmPrivate *priv = MM_MODEM_HUAWEI_GSM_GET_PRIVATE (self); - + MMModemGsmMode new_mode = MM_MODEM_GSM_MODE_ANY; + /* Network mode */ if (*mode_a == 2 && *mode_b == 1) - priv->mode = MM_MODEM_GSM_MODE_2G_PREFERRED; + new_mode = MM_MODEM_GSM_MODE_2G_PREFERRED; else if (*mode_a == 2 && *mode_b == 2) - priv->mode = MM_MODEM_GSM_MODE_3G_PREFERRED; + new_mode = MM_MODEM_GSM_MODE_3G_PREFERRED; else if (*mode_a == 13 && *mode_b == 1) - priv->mode = MM_MODEM_GSM_MODE_2G_ONLY; + new_mode = MM_MODEM_GSM_MODE_2G_ONLY; else if (*mode_a == 14 && *mode_b == 2) - priv->mode = MM_MODEM_GSM_MODE_3G_ONLY; + new_mode = MM_MODEM_GSM_MODE_3G_ONLY; + + if (out_mode) + *out_mode = new_mode; /* Band */ if (*band == 0x3FFFFFFF) @@ -101,26 +105,21 @@ parse_syscfg (MMModemHuaweiGsm *self, } static void -set_network_mode_done (MMSerialPort *port, +set_allowed_mode_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemHuaweiGsm *self = MM_MODEM_HUAWEI_GSM (info->modem); - MMModemHuaweiGsmPrivate *priv = MM_MODEM_HUAWEI_GSM_GET_PRIVATE (self); if (error) info->error = g_error_copy (error); - else - /* Success, cache the value */ - priv->mode = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "mode")); mm_callback_info_schedule (info); } static void -set_network_mode_get_done (MMSerialPort *port, +set_allowed_mode_get_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) @@ -134,7 +133,7 @@ set_network_mode_get_done (MMSerialPort *port, int a, b, u1, u2; guint32 band; - if (parse_syscfg (MM_MODEM_HUAWEI_GSM (info->modem), response->str, &a, &b, &band, &u1, &u2)) { + if (parse_syscfg (MM_MODEM_HUAWEI_GSM (info->modem), response->str, &a, &b, &band, &u1, &u2, NULL)) { char *command; switch (GPOINTER_TO_UINT (mm_callback_info_get_data (info, "mode"))) { @@ -142,16 +141,10 @@ set_network_mode_get_done (MMSerialPort *port, a = 2; b = 0; break; - case MM_MODEM_GSM_MODE_GPRS: - case MM_MODEM_GSM_MODE_EDGE: case MM_MODEM_GSM_MODE_2G_ONLY: a = 13; b = 1; break; - case MM_MODEM_GSM_MODE_UMTS: - case MM_MODEM_GSM_MODE_HSDPA: - case MM_MODEM_GSM_MODE_HSUPA: - case MM_MODEM_GSM_MODE_HSPA: case MM_MODEM_GSM_MODE_3G_ONLY: a = 14; b = 2; @@ -169,14 +162,14 @@ set_network_mode_get_done (MMSerialPort *port, } command = g_strdup_printf ("AT^SYSCFG=%d,%d,%X,%d,%d", a, b, band, u1, u2); - mm_serial_port_queue_command (port, command, 3, set_network_mode_done, info); + mm_serial_port_queue_command (port, command, 3, set_allowed_mode_done, info); g_free (command); } } } static void -set_network_mode (MMModemGsmNetwork *modem, +set_allowed_mode (MMGenericGsm *gsm, MMModemGsmMode mode, MMModemFn callback, gpointer user_data) @@ -184,28 +177,26 @@ set_network_mode (MMModemGsmNetwork *modem, MMCallbackInfo *info; MMSerialPort *primary; - info = mm_callback_info_new (MM_MODEM (modem), callback, user_data); + info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data); switch (mode) { case MM_MODEM_GSM_MODE_ANY: - case MM_MODEM_GSM_MODE_GPRS: - case MM_MODEM_GSM_MODE_EDGE: - case MM_MODEM_GSM_MODE_UMTS: - case MM_MODEM_GSM_MODE_HSDPA: - case MM_MODEM_GSM_MODE_HSUPA: - case MM_MODEM_GSM_MODE_HSPA: case MM_MODEM_GSM_MODE_2G_PREFERRED: case MM_MODEM_GSM_MODE_3G_PREFERRED: case MM_MODEM_GSM_MODE_2G_ONLY: case MM_MODEM_GSM_MODE_3G_ONLY: /* Allowed values */ mm_callback_info_set_data (info, "mode", GUINT_TO_POINTER (mode), NULL); - primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (gsm), MM_PORT_TYPE_PRIMARY); g_assert (primary); - mm_serial_port_queue_command (primary, "AT^SYSCFG?", 3, set_network_mode_get_done, info); + + /* Get current configuration first so we don't change band and other + * stuff when updating the mode. + */ + mm_serial_port_queue_command (primary, "AT^SYSCFG?", 3, set_allowed_mode_get_done, info); return; default: - info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Invalid mode."); + info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Unsupported allowed mode."); break; } @@ -213,49 +204,37 @@ set_network_mode (MMModemGsmNetwork *modem, } static void -get_network_mode_done (MMSerialPort *port, +get_allowed_mode_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMModemHuaweiGsm *self = MM_MODEM_HUAWEI_GSM (info->modem); - MMModemHuaweiGsmPrivate *priv = MM_MODEM_HUAWEI_GSM_GET_PRIVATE (self); int mode_a, mode_b, u1, u2; guint32 band; + MMModemGsmMode mode = MM_MODEM_GSM_MODE_ANY; if (error) info->error = g_error_copy (error); - else if (parse_syscfg (self, response->str, &mode_a, &mode_b, &band, &u1, &u2)) - mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->mode), NULL); + else if (parse_syscfg (self, response->str, &mode_a, &mode_b, &band, &u1, &u2, &mode)) + mm_callback_info_set_result (info, GUINT_TO_POINTER (mode), NULL); mm_callback_info_schedule (info); } static void -get_network_mode (MMModemGsmNetwork *modem, +get_allowed_mode (MMGenericGsm *gsm, MMModemUIntFn callback, gpointer user_data) { - MMModemHuaweiGsmPrivate *priv = MM_MODEM_HUAWEI_GSM_GET_PRIVATE (modem); - - if (priv->mode != MM_MODEM_GSM_MODE_ANY) { - /* have cached mode (from an unsolicited message). Use that */ - MMCallbackInfo *info; - - info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); - mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->mode), NULL); - mm_callback_info_schedule (info); - } else { - /* Get it from modem */ - MMCallbackInfo *info; - MMSerialPort *primary; + MMCallbackInfo *info; + MMSerialPort *primary; - info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); - primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); - g_assert (primary); - mm_serial_port_queue_command (primary, "AT^SYSCFG?", 3, get_network_mode_done, info); - } + info = mm_callback_info_uint_new (MM_MODEM (gsm), callback, user_data); + primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY); + g_assert (primary); + mm_serial_port_queue_command (primary, "AT^SYSCFG?", 3, get_allowed_mode_done, info); } static void @@ -293,7 +272,7 @@ set_band_get_done (MMSerialPort *port, int a, b, u1, u2; guint32 band; - if (parse_syscfg (self, response->str, &a, &b, &band, &u1, &u2)) { + if (parse_syscfg (self, response->str, &a, &b, &band, &u1, &u2, NULL)) { char *command; switch (GPOINTER_TO_UINT (mm_callback_info_get_data (info, "band"))) { @@ -370,7 +349,7 @@ get_band_done (MMSerialPort *port, if (error) info->error = g_error_copy (error); - else if (parse_syscfg (self, response->str, &mode_a, &mode_b, &band, &u1, &u2)) + else if (parse_syscfg (self, response->str, &mode_a, &mode_b, &band, &u1, &u2, NULL)) mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->band), NULL); mm_callback_info_schedule (info); @@ -596,8 +575,6 @@ modem_init (MMModem *modem_class) static void modem_gsm_network_init (MMModemGsmNetwork *class) { - class->set_network_mode = set_network_mode; - class->get_network_mode = get_network_mode; class->set_band = set_band; class->get_band = get_band; class->get_signal_quality = get_signal_quality; @@ -612,8 +589,12 @@ static void mm_modem_huawei_gsm_class_init (MMModemHuaweiGsmClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + MMGenericGsmClass *gsm_class = MM_GENERIC_GSM_CLASS (klass); mm_modem_huawei_gsm_parent_class = g_type_class_peek_parent (klass); g_type_class_add_private (object_class, sizeof (MMModemHuaweiGsmPrivate)); + + gsm_class->set_allowed_mode = set_allowed_mode; + gsm_class->get_allowed_mode = get_allowed_mode; } diff --git a/plugins/mm-modem-mbm.c b/plugins/mm-modem-mbm.c index 417457f7..72bd48a7 100644 --- a/plugins/mm-modem-mbm.c +++ b/plugins/mm-modem-mbm.c @@ -1,11 +1,13 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* - * Copyright (C) 2008 Ericsson AB + * Copyright (C) 2008 - 2010 Ericsson AB + * Copyright (C) 2009 - 2010 Red Hat, Inc. * * Author: Per Hallsmark <per.hallsmark@ericsson.com> * Bjorn Runaker <bjorn.runaker@ericsson.com> * Torgny Johansson <torgny.johansson@ericsson.com> * Jonas Sjöquist <jonas.sjoquist@ericsson.com> + * Dan Williams <dcbw@redhat.com> * * 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 @@ -170,14 +172,9 @@ mbm_parse_network_mode (MMModemGsmMode network_mode) case MM_MODEM_GSM_MODE_3G_PREFERRED: case MM_MODEM_GSM_MODE_2G_PREFERRED: return MBM_NETWORK_MODE_ANY; - case MM_MODEM_GSM_MODE_GPRS: - case MM_MODEM_GSM_MODE_EDGE: case MM_MODEM_GSM_MODE_2G_ONLY: return MBM_NETWORK_MODE_2G; case MM_MODEM_GSM_MODE_3G_ONLY: - case MM_MODEM_GSM_MODE_HSDPA: - case MM_MODEM_GSM_MODE_HSUPA: - case MM_MODEM_GSM_MODE_HSPA: return MBM_NETWORK_MODE_3G; default: return MBM_NETWORK_MODE_ANY; @@ -185,7 +182,7 @@ mbm_parse_network_mode (MMModemGsmMode network_mode) } static void -mbm_set_network_mode_done (MMSerialPort *port, +mbm_set_allowed_mode_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) @@ -199,7 +196,7 @@ mbm_set_network_mode_done (MMSerialPort *port, } static void -set_network_mode (MMModemGsmNetwork *modem, +set_allowed_mode (MMGenericGsm *gsm, MMModemGsmMode mode, MMModemFn callback, gpointer user_data) @@ -208,15 +205,16 @@ set_network_mode (MMModemGsmNetwork *modem, char *command; MMSerialPort *primary; - info = mm_callback_info_new (MM_MODEM (modem), callback, user_data); - primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data); + primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY); g_assert (primary); command = g_strdup_printf ("+CFUN=%d", mbm_parse_network_mode (mode)); - mm_serial_port_queue_command (primary, command, 3, mbm_set_network_mode_done, info); + mm_serial_port_queue_command (primary, command, 3, mbm_set_allowed_mode_done, info); g_free (command); } +#if 0 static void get_network_mode_done (MMSerialPort *port, GString *response, @@ -266,19 +264,52 @@ done: mm_callback_info_schedule (info); } +#endif + +static void +get_allowed_mode_done (MMSerialPort *port, + GString *response, + GError *error, + gpointer user_data) +{ + MMCallbackInfo *info = (MMCallbackInfo *) user_data; + gboolean parsed = FALSE; + + if (error) + info->error = g_error_copy (error); + else if (!g_str_has_prefix (response->str, "CFUN: ")) { + MMModemGsmMode mode = MM_MODEM_GSM_MODE_ANY; + int a; + + a = atoi (response->str + 6); + if (a == MBM_NETWORK_MODE_2G) + mode = MM_MODEM_GSM_MODE_2G_ONLY; + else if (a == MBM_NETWORK_MODE_3G) + mode = MM_MODEM_GSM_MODE_3G_ONLY; + + mm_callback_info_set_result (info, GUINT_TO_POINTER (mode), NULL); + parsed = TRUE; + } + + if (!error && !parsed) + info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, + "Could not parse allowed mode results"); + + mm_callback_info_schedule (info); +} static void -get_network_mode (MMModemGsmNetwork *modem, +get_allowed_mode (MMGenericGsm *gsm, MMModemUIntFn callback, gpointer user_data) { MMCallbackInfo *info; MMSerialPort *primary; - info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); - primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + info = mm_callback_info_uint_new (MM_MODEM (gsm), callback, user_data); + primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY); g_assert (primary); - mm_serial_port_queue_command (primary, "*ERINFO?", 3, get_network_mode_done, info); + mm_serial_port_queue_command (primary, "CFUN?", 3, get_allowed_mode_done, info); } /*****************************************************************************/ @@ -782,8 +813,6 @@ static void modem_gsm_network_init (MMModemGsmNetwork *class) { class->do_register = do_register; - class->get_network_mode = get_network_mode; - class->set_network_mode = set_network_mode; } static void @@ -832,5 +861,7 @@ mm_modem_mbm_class_init (MMModemMbmClass *klass) object_class->finalize = finalize; gsm_class->do_enable = do_enable; + gsm_class->get_allowed_mode = get_allowed_mode; + gsm_class->set_allowed_mode = set_allowed_mode; } diff --git a/plugins/mm-modem-option.c b/plugins/mm-modem-option.c index 273cb95a..ddd947da 100644 --- a/plugins/mm-modem-option.c +++ b/plugins/mm-modem-option.c @@ -22,10 +22,7 @@ #include "mm-errors.h" #include "mm-callback-info.h" -static void modem_gsm_network_init (MMModemGsmNetwork *gsm_network_class); - -G_DEFINE_TYPE_EXTENDED (MMModemOption, mm_modem_option, MM_TYPE_GENERIC_GSM, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_NETWORK, modem_gsm_network_init)) +G_DEFINE_TYPE (MMModemOption, mm_modem_option, MM_TYPE_GENERIC_GSM) #define MM_MODEM_OPTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MODEM_OPTION, MMModemOptionPrivate)) @@ -90,7 +87,7 @@ real_do_enable_power_up_done (MMGenericGsm *gsm, } static void -get_network_mode_done (MMSerialPort *port, +get_allowed_mode_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) @@ -130,27 +127,27 @@ get_network_mode_done (MMSerialPort *port, if (!error && !parsed) info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, - "Could not parse network mode results"); + "Could not parse allowed mode results"); mm_callback_info_schedule (info); } static void -get_network_mode (MMModemGsmNetwork *modem, +get_allowed_mode (MMGenericGsm *gsm, MMModemUIntFn callback, gpointer user_data) { MMCallbackInfo *info; MMSerialPort *primary; - info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); - primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + info = mm_callback_info_uint_new (MM_MODEM (gsm), callback, user_data); + primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY); g_assert (primary); - mm_serial_port_queue_command (primary, "AT_OPSYS?", 3, get_network_mode_done, info); + mm_serial_port_queue_command (primary, "AT_OPSYS?", 3, get_allowed_mode_done, info); } static void -set_network_mode_done (MMSerialPort *port, +set_allowed_mode_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) @@ -159,12 +156,12 @@ set_network_mode_done (MMSerialPort *port, if (error) info->error = g_error_copy (error); - + mm_callback_info_schedule (info); } static void -set_network_mode (MMModemGsmNetwork *modem, +set_allowed_mode (MMGenericGsm *gsm, MMModemGsmMode mode, MMModemFn callback, gpointer user_data) @@ -174,19 +171,12 @@ set_network_mode (MMModemGsmNetwork *modem, char *command; int i; - info = mm_callback_info_new (MM_MODEM (modem), callback, user_data); + info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data); switch (mode) { - case MM_MODEM_GSM_MODE_ANY: - case MM_MODEM_GSM_MODE_GPRS: - case MM_MODEM_GSM_MODE_EDGE: case MM_MODEM_GSM_MODE_2G_ONLY: i = 0; break; - case MM_MODEM_GSM_MODE_UMTS: - case MM_MODEM_GSM_MODE_HSDPA: - case MM_MODEM_GSM_MODE_HSUPA: - case MM_MODEM_GSM_MODE_HSPA: case MM_MODEM_GSM_MODE_3G_ONLY: i = 1; break; @@ -196,28 +186,22 @@ set_network_mode (MMModemGsmNetwork *modem, case MM_MODEM_GSM_MODE_3G_PREFERRED: i = 3; break; + case MM_MODEM_GSM_MODE_ANY: default: i = 5; break; } command = g_strdup_printf ("AT_OPSYS=%d,2", i); - primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY); g_assert (primary); - mm_serial_port_queue_command (primary, command, 3, set_network_mode_done, info); + mm_serial_port_queue_command (primary, command, 3, set_allowed_mode_done, info); g_free (command); } /*****************************************************************************/ static void -modem_gsm_network_init (MMModemGsmNetwork *class) -{ - class->set_network_mode = set_network_mode; - class->get_network_mode = get_network_mode; -} - -static void mm_modem_option_init (MMModemOption *self) { } @@ -242,5 +226,7 @@ mm_modem_option_class_init (MMModemOptionClass *klass) object_class->dispose = dispose; gsm_class->do_enable_power_up_done = real_do_enable_power_up_done; + gsm_class->set_allowed_mode = set_allowed_mode; + gsm_class->get_allowed_mode = get_allowed_mode; } diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index b28000c6..917a7621 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -56,6 +56,8 @@ typedef struct { guint32 pin_check_tries; guint pin_check_timeout; + guint32 allowed_mode; + char *oper_code; char *oper_name; guint32 ip_method; @@ -642,29 +644,43 @@ creg2_done (MMSerialPort *port, } } +static void +get_allowed_mode_done (MMModem *modem, + MMModemGsmMode mode, + GError *error, + gpointer user_data) +{ + if (modem) { + mm_generic_gsm_update_allowed_mode (MM_GENERIC_GSM (modem), + error ? MM_MODEM_GSM_MODE_UNKNOWN : mode); + } +} + void -mm_generic_gsm_enable_complete (MMGenericGsm *modem, +mm_generic_gsm_enable_complete (MMGenericGsm *self, GError *error, MMCallbackInfo *info) { MMGenericGsmPrivate *priv; - g_return_if_fail (modem != NULL); - g_return_if_fail (MM_IS_GENERIC_GSM (modem)); + g_return_if_fail (self != NULL); + g_return_if_fail (MM_IS_GENERIC_GSM (self)); g_return_if_fail (info != NULL); if (error) { - mm_modem_set_state (MM_MODEM (modem), + mm_modem_set_state (MM_MODEM (self), MM_MODEM_STATE_DISABLED, MM_MODEM_STATE_REASON_NONE); info->error = g_error_copy (error); + mm_callback_info_schedule (info); + return; } else { /* Modem is enabled; update the state */ - mm_generic_gsm_update_enabled_state (modem, FALSE, MM_MODEM_STATE_REASON_NONE); + mm_generic_gsm_update_enabled_state (self, FALSE, MM_MODEM_STATE_REASON_NONE); } - priv = MM_GENERIC_GSM_GET_PRIVATE (modem); + priv = MM_GENERIC_GSM_GET_PRIVATE (self); /* Open the second port here if the modem has one. We'll use it for * signal strength and registration updates when the device is connected, @@ -682,6 +698,11 @@ mm_generic_gsm_enable_complete (MMGenericGsm *modem, } } + /* Get allowed mode */ + if (MM_GENERIC_GSM_GET_CLASS (self)->get_allowed_mode) + MM_GENERIC_GSM_GET_CLASS (self)->get_allowed_mode (self, get_allowed_mode_done, NULL); + + /* Set up unsolicited registration notifications */ mm_serial_port_queue_command (priv->primary, "+CREG=2", 3, creg2_done, info); } @@ -2228,7 +2249,7 @@ mm_generic_gsm_update_access_technology (MMGenericGsm *modem, g_return_if_fail (modem != NULL); g_return_if_fail (MM_IS_GENERIC_GSM (modem)); - g_return_if_fail (check_for_single_value (mode) || (mode == MM_MODEM_GSM_MODE_HSPA)); + g_return_if_fail (check_for_single_value (mode)); g_return_if_fail ((mode & MM_MODEM_GSM_MODE_ANY) == 0); g_return_if_fail ((mode & MM_MODEM_GSM_MODE_2G_PREFERRED) == 0); g_return_if_fail ((mode & MM_MODEM_GSM_MODE_3G_PREFERRED) == 0); @@ -2242,7 +2263,63 @@ mm_generic_gsm_update_access_technology (MMGenericGsm *modem, g_object_notify (G_OBJECT (modem), MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY); /* Deprecated value */ - g_signal_emit_by_name (G_OBJECT (modem), "NetworkMode", mode); + g_signal_emit_by_name (G_OBJECT (modem), "network-mode", mode); + } +} + +void +mm_generic_gsm_update_allowed_mode (MMGenericGsm *self, + MMModemGsmMode mode) +{ + MMGenericGsmPrivate *priv; + + g_return_if_fail (self != NULL); + g_return_if_fail (MM_IS_GENERIC_GSM (self)); + + priv = MM_GENERIC_GSM_GET_PRIVATE (self); + + if (mode != priv->allowed_mode) { + priv->allowed_mode = mode; + g_object_notify (G_OBJECT (self), MM_MODEM_GSM_NETWORK_ALLOWED_MODE); + } +} + +static void +set_allowed_mode_done (MMModem *modem, GError *error, gpointer user_data) +{ + MMCallbackInfo *info = user_data; + + info->error = mm_modem_check_removed (info->modem, error); + if (!info->error) { + MMModemGsmMode mode = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "mode")); + + mm_generic_gsm_update_allowed_mode (MM_GENERIC_GSM (info->modem), mode); + } + + mm_callback_info_schedule (info); +} + +static void +set_allowed_mode (MMModemGsmNetwork *net, + MMModemGsmMode mode, + MMModemFn callback, + gpointer user_data) +{ + MMGenericGsm *self = MM_GENERIC_GSM (net); + MMCallbackInfo *info; + + info = mm_callback_info_new (MM_MODEM (self), callback, user_data); + + if (mode == MM_MODEM_GSM_MODE_UNKNOWN) { + info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Invalid mode."); + mm_callback_info_schedule (info); + } else if (!MM_GENERIC_GSM_GET_CLASS (self)->set_allowed_mode) { + info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED, + "Operation not supported"); + mm_callback_info_schedule (info); + } else { + mm_callback_info_set_data (info, "mode", GUINT_TO_POINTER (mode), NULL); + MM_GENERIC_GSM_GET_CLASS (self)->set_allowed_mode (self, mode, set_allowed_mode_done, info); } } @@ -2593,6 +2670,7 @@ modem_gsm_network_init (MMModemGsmNetwork *class) { class->do_register = do_register; class->get_registration_info = get_registration_info; + class->set_allowed_mode = set_allowed_mode; class->set_apn = set_apn; class->scan = scan; class->get_signal_quality = get_signal_quality; @@ -2620,6 +2698,10 @@ mm_generic_gsm_init (MMGenericGsm *self) priv->reg_regex = mm_gsm_creg_regex_get (TRUE); mm_properties_changed_signal_register_property (G_OBJECT (self), + MM_MODEM_GSM_NETWORK_ALLOWED_MODE, + MM_MODEM_GSM_NETWORK_DBUS_INTERFACE); + + mm_properties_changed_signal_register_property (G_OBJECT (self), MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY, MM_MODEM_GSM_NETWORK_DBUS_INTERFACE); } @@ -2636,6 +2718,7 @@ set_property (GObject *object, guint prop_id, case MM_GENERIC_GSM_PROP_INIT_CMD_OPTIONAL: case MM_GENERIC_GSM_PROP_SUPPORTED_BANDS: case MM_GENERIC_GSM_PROP_SUPPORTED_MODES: + case MM_GENERIC_GSM_PROP_ALLOWED_MODE: case MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY: break; default: @@ -2685,6 +2768,9 @@ get_property (GObject *object, guint prop_id, case MM_GENERIC_GSM_PROP_SUPPORTED_MODES: g_value_set_uint (value, 0); break; + case MM_GENERIC_GSM_PROP_ALLOWED_MODE: + g_value_set_uint (value, priv->allowed_mode); + break; case MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY: if (mm_modem_get_state (MM_MODEM (object)) >= MM_MODEM_STATE_ENABLED) g_value_set_uint (value, priv->access_tech); @@ -2754,6 +2840,10 @@ mm_generic_gsm_class_init (MMGenericGsmClass *klass) MM_MODEM_GSM_CARD_SUPPORTED_MODES); g_object_class_override_property (object_class, + MM_GENERIC_GSM_PROP_ALLOWED_MODE, + MM_MODEM_GSM_NETWORK_ALLOWED_MODE); + + g_object_class_override_property (object_class, MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY, MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY); diff --git a/src/mm-generic-gsm.h b/src/mm-generic-gsm.h index 477ec6b7..9b4c4848 100644 --- a/src/mm-generic-gsm.h +++ b/src/mm-generic-gsm.h @@ -44,6 +44,7 @@ typedef enum { MM_GENERIC_GSM_PROP_SUPPORTED_BANDS, MM_GENERIC_GSM_PROP_SUPPORTED_MODES, MM_GENERIC_GSM_PROP_INIT_CMD_OPTIONAL, + MM_GENERIC_GSM_PROP_ALLOWED_MODE, MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY } MMGenericGsmProp; @@ -78,6 +79,17 @@ typedef struct { GError *error, MMCallbackInfo *info); + /* Called by the generic class to set the allowed operating mode of the device */ + void (*set_allowed_mode) (MMGenericGsm *self, + MMModemGsmMode mode, + MMModemFn callback, + gpointer user_data); + + /* Called by the generic class to get the allowed operating mode of the device */ + void (*get_allowed_mode) (MMGenericGsm *self, + MMModemUIntFn callback, + gpointer user_data); + /* Called by the generic class to the current radio access technology the * device is using while communicating with the base station. */ @@ -105,6 +117,15 @@ guint32 mm_generic_gsm_get_cid (MMGenericGsm *modem); void mm_generic_gsm_set_reg_status (MMGenericGsm *modem, MMModemGsmNetworkRegStatus status); +/* Called to asynchronously update the current allowed operating mode that the + * device is allowed to use when connecting to a network. This isn't the + * specific access technology the device is currently using (see + * mm_generic_gsm_set_access_technology() for that) but the mode the device is + * allowed to choose from when connecting. + */ +void mm_generic_gsm_update_allowed_mode (MMGenericGsm *modem, + MMModemGsmMode mode); + /* Called to asynchronously update the current access technology of the device; * this is NOT the 2G/3G mode preference, but the current radio access * technology being used to communicate with the base station. diff --git a/src/mm-modem-gsm-network.c b/src/mm-modem-gsm-network.c index ca00decc..aae55574 100644 --- a/src/mm-modem-gsm-network.c +++ b/src/mm-modem-gsm-network.c @@ -43,12 +43,12 @@ static void impl_gsm_modem_set_band (MMModemGsmNetwork *modem, static void impl_gsm_modem_get_band (MMModemGsmNetwork *modem, DBusGMethodInvocation *context); -static void impl_gsm_modem_set_allowed_modes (MMModemGsmNetwork *modem, - MMModemGsmMode mode, - DBusGMethodInvocation *context); +static void impl_gsm_modem_set_allowed_mode (MMModemGsmNetwork *modem, + MMModemGsmMode mode, + DBusGMethodInvocation *context); static void impl_gsm_modem_set_network_mode (MMModemGsmNetwork *modem, - MMModemGsmMode mode, + MMModemDeprecatedMode old_mode, DBusGMethodInvocation *context); static void impl_gsm_modem_get_network_mode (MMModemGsmNetwork *modem, @@ -371,35 +371,21 @@ mm_modem_gsm_network_get_band (MMModemGsmNetwork *self, } void -mm_modem_gsm_network_set_mode (MMModemGsmNetwork *self, - MMModemGsmMode mode, - MMModemFn callback, - gpointer user_data) +mm_modem_gsm_network_set_allowed_mode (MMModemGsmNetwork *self, + MMModemGsmMode mode, + MMModemFn callback, + gpointer user_data) { g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self)); g_return_if_fail (callback != NULL); - if (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->set_network_mode) - MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->set_network_mode (self, mode, callback, user_data); + if (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->set_allowed_mode) + MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->set_allowed_mode (self, mode, callback, user_data); else async_call_not_supported (self, callback, user_data); } void -mm_modem_gsm_network_get_mode (MMModemGsmNetwork *self, - MMModemUIntFn callback, - gpointer user_data) -{ - g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self)); - g_return_if_fail (callback != NULL); - - if (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->get_network_mode) - MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->get_network_mode (self, callback, user_data); - else - uint_call_not_supported (self, callback, user_data); -} - -void mm_modem_gsm_network_get_registration_info (MMModemGsmNetwork *self, MMModemGsmNetworkRegInfoFn callback, gpointer user_data) @@ -435,15 +421,6 @@ mm_modem_gsm_network_registration_info (MMModemGsmNetwork *self, oper_name ? oper_name : ""); } -void -mm_modem_gsm_network_mode (MMModemGsmNetwork *self, - MMModemGsmMode mode) -{ - g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self)); - - g_signal_emit (self, signals[NETWORK_MODE], 0, mode); -} - /*****************************************************************************/ static void @@ -558,15 +535,28 @@ impl_gsm_modem_get_band (MMModemGsmNetwork *modem, } static void -impl_gsm_modem_set_allowed_modes (MMModemGsmNetwork *modem, - MMModemGsmMode mode, - DBusGMethodInvocation *context) +impl_gsm_modem_set_network_mode (MMModemGsmNetwork *modem, + MMModemDeprecatedMode old_mode, + DBusGMethodInvocation *context) { - dbus_g_method_return (context); + if (!check_for_single_value (old_mode)) { + GError *error; + + error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED, + "Invalid arguments (more than one value given)"); + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + mm_modem_gsm_network_set_allowed_mode (modem, + mm_modem_gsm_network_old_mode_to_new (old_mode), + async_call_done, + context); } static void -impl_gsm_modem_set_network_mode (MMModemGsmNetwork *modem, +impl_gsm_modem_set_allowed_mode (MMModemGsmNetwork *modem, MMModemGsmMode mode, DBusGMethodInvocation *context) { @@ -580,14 +570,20 @@ impl_gsm_modem_set_network_mode (MMModemGsmNetwork *modem, return; } - mm_modem_gsm_network_set_mode (modem, mode, async_call_done, context); + mm_modem_gsm_network_set_allowed_mode (modem, mode, async_call_done, context); } static void impl_gsm_modem_get_network_mode (MMModemGsmNetwork *modem, DBusGMethodInvocation *context) { - mm_modem_gsm_network_get_mode (modem, uint_call_done, context); + MMModemGsmMode mode = MM_MODEM_GSM_MODE_ANY; + + /* DEPRECATED; it's now a property so it's quite easy to handle */ + g_object_get (G_OBJECT (modem), + MM_MODEM_GSM_NETWORK_ALLOWED_MODE, &mode, + NULL); + dbus_g_method_return (context, mm_modem_gsm_network_new_mode_to_old (mode)); } static void @@ -608,6 +604,17 @@ mm_modem_gsm_network_init (gpointer g_iface) if (initialized) return; + /* Properties */ + g_object_interface_install_property + (g_iface, + g_param_spec_uint (MM_MODEM_GSM_NETWORK_ALLOWED_MODE, + "Allowed Mode", + "Allowed network access mode", + MM_MODEM_GSM_MODE_UNKNOWN, + G_MAXUINT32, + MM_MODEM_GSM_MODE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_interface_install_property (g_iface, g_param_spec_uint (MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY, @@ -615,7 +622,7 @@ mm_modem_gsm_network_init (gpointer g_iface) "Current access technology in use when connected to " "a mobile network.", MM_MODEM_GSM_MODE_UNKNOWN, - MM_MODEM_GSM_MODE_LAST, + G_MAXUINT32, MM_MODEM_GSM_MODE_UNKNOWN, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); @@ -644,8 +651,7 @@ mm_modem_gsm_network_init (gpointer g_iface) g_signal_new ("network-mode", iface_type, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MMModemGsmNetwork, network_mode), - NULL, NULL, + 0, NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); diff --git a/src/mm-modem-gsm-network.h b/src/mm-modem-gsm-network.h index 3aa6ce30..bfd754ed 100644 --- a/src/mm-modem-gsm-network.h +++ b/src/mm-modem-gsm-network.h @@ -27,12 +27,14 @@ #define MM_IS_MODEM_GSM_NETWORK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_GSM_NETWORK)) #define MM_MODEM_GSM_NETWORK_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM_GSM_NETWORK, MMModemGsmNetwork)) +#define MM_MODEM_GSM_NETWORK_ALLOWED_MODE "allowed-mode" #define MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY "access-technology" typedef enum { MM_MODEM_GSM_NETWORK_PROP_FIRST = 0x1200, - MM_MODEM_GSM_NETWORK_PROP_ACCESS_TECHNOLOGY = MM_MODEM_GSM_NETWORK_PROP_FIRST, + MM_MODEM_GSM_NETWORK_PROP_ALLOWED_MODE = MM_MODEM_GSM_NETWORK_PROP_FIRST, + MM_MODEM_GSM_NETWORK_PROP_ACCESS_TECHNOLOGY, } MMModemGsmNetworkProp; typedef enum { @@ -90,15 +92,11 @@ struct _MMModemGsmNetwork { MMModemUIntFn callback, gpointer user_data); - void (*set_network_mode) (MMModemGsmNetwork *self, + void (*set_allowed_mode) (MMModemGsmNetwork *self, MMModemGsmMode mode, MMModemFn callback, gpointer user_data); - void (*get_network_mode) (MMModemGsmNetwork *self, - MMModemUIntFn callback, - gpointer user_data); - void (*get_registration_info) (MMModemGsmNetwork *self, MMModemGsmNetworkRegInfoFn callback, gpointer user_data); @@ -111,9 +109,6 @@ struct _MMModemGsmNetwork { MMModemGsmNetworkRegStatus status, const char *open_code, const char *oper_name); - - void (*network_mode) (MMModemGsmNetwork *self, - MMModemGsmMode mode); }; GType mm_modem_gsm_network_get_type (void); @@ -163,14 +158,17 @@ void mm_modem_gsm_network_get_registration_info (MMModemGsmNetwork *self, void mm_modem_gsm_network_signal_quality (MMModemGsmNetwork *self, guint32 quality); +void mm_modem_gsm_network_set_allowed_mode (MMModemGsmNetwork *self, + MMModemGsmMode mode, + MMModemFn callback, + gpointer user_data); + void mm_modem_gsm_network_registration_info (MMModemGsmNetwork *self, MMModemGsmNetworkRegStatus status, const char *oper_code, const char *oper_name); -void mm_modem_gsm_network_mode (MMModemGsmNetwork *self, - MMModemGsmMode mode); - +/* Private */ MMModemDeprecatedMode mm_modem_gsm_network_new_mode_to_old (MMModemGsmMode new_mode); MMModemGsmMode mm_modem_gsm_network_old_mode_to_new (MMModemDeprecatedMode old_mode); diff --git a/src/mm-modem-gsm.h b/src/mm-modem-gsm.h index 8f1155ec..e64f6804 100644 --- a/src/mm-modem-gsm.h +++ b/src/mm-modem-gsm.h @@ -32,8 +32,6 @@ typedef enum { MM_MODEM_GSM_MODE_HSPA = 0x00000400, MM_MODEM_GSM_MODE_GSM = 0x00000800, MM_MODEM_GSM_MODE_GSM_COMPACT = 0x00001000, - - MM_MODEM_GSM_MODE_LAST = MM_MODEM_GSM_MODE_GSM_COMPACT } MMModemGsmMode; typedef enum { |