diff options
-rw-r--r-- | plugins/mm-modem-mbm.c | 82 | ||||
-rw-r--r-- | src/mm-generic-gsm.c | 111 | ||||
-rw-r--r-- | src/mm-modem-gsm.h | 4 |
3 files changed, 124 insertions, 73 deletions
diff --git a/plugins/mm-modem-mbm.c b/plugins/mm-modem-mbm.c index 25e24507..49442224 100644 --- a/plugins/mm-modem-mbm.c +++ b/plugins/mm-modem-mbm.c @@ -76,12 +76,6 @@ mbm_modem_authenticate (MMModemMbm *self, const char *password, gpointer user_data); -static const char * -mbm_simple_get_string_property (GHashTable *properties, const char *name, GError **error); - -static uint -mbm_simple_get_uint_property (GHashTable *properties, const char *name, GError **error); - MMModem * mm_modem_mbm_new (const char *device, const char *driver, @@ -298,6 +292,25 @@ get_allowed_mode (MMGenericGsm *gsm, /* Simple Modem class override functions */ /*****************************************************************************/ +static const char * +mbm_simple_get_string_property (GHashTable *properties, const char *name, GError **error) +{ + GValue *value; + + value = (GValue *) g_hash_table_lookup (properties, name); + if (!value) + return NULL; + + if (G_VALUE_HOLDS_STRING (value)) + return g_value_get_string (value); + + g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, + "Invalid property type for '%s': %s (string expected)", + name, G_VALUE_TYPE_NAME (value)); + + return NULL; +} + static void simple_connect (MMModemSimple *simple, GHashTable *properties, @@ -307,29 +320,10 @@ simple_connect (MMModemSimple *simple, MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (simple); MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMModemSimple *parent_iface; - uint network_mode = 0; priv->username = mbm_simple_get_string_property (properties, "username", &info->error); priv->password = mbm_simple_get_string_property (properties, "password", &info->error); - network_mode = mbm_simple_get_uint_property (properties, "network_mode", &info->error); - switch (network_mode) { - case MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY: - case MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_PREFERRED: - case MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_PREFERRED: - priv->network_mode = MBM_NETWORK_MODE_ANY; - break; - case MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_ONLY: - priv->network_mode = MBM_NETWORK_MODE_2G; - break; - case MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_ONLY: - priv->network_mode = MBM_NETWORK_MODE_3G; - break; - default: - priv->network_mode = MBM_NETWORK_MODE_ANY; - break; - } - parent_iface = g_type_interface_peek_parent (MM_MODEM_SIMPLE_GET_INTERFACE (simple)); parent_iface->connect (MM_MODEM_SIMPLE (simple), properties, callback, info); } @@ -737,44 +731,6 @@ mbm_modem_authenticate (MMModemMbm *self, mbm_auth_done (MM_SERIAL_PORT (primary), NULL, NULL, user_data); } -static const char * -mbm_simple_get_string_property (GHashTable *properties, const char *name, GError **error) -{ - GValue *value; - - value = (GValue *) g_hash_table_lookup (properties, name); - if (!value) - return NULL; - - if (G_VALUE_HOLDS_STRING (value)) - return g_value_get_string (value); - - g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, - "Invalid property type for '%s': %s (string expected)", - name, G_VALUE_TYPE_NAME (value)); - - return NULL; -} - -static uint -mbm_simple_get_uint_property (GHashTable *properties, const char *name, GError **error) -{ - GValue *value; - - value = (GValue *) g_hash_table_lookup (properties, name); - if (!value) - return 0; - - if (G_VALUE_HOLDS_UINT (value)) - return g_value_get_uint (value); - - g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, - "Invalid property type for '%s': %s (uint expected)", - name, G_VALUE_TYPE_NAME (value)); - - return 0; -} - /*****************************************************************************/ static gboolean diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index d24060ec..86d449fc 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -2922,30 +2922,111 @@ mm_generic_gsm_get_at_port (MMGenericGsm *modem, typedef enum { SIMPLE_STATE_CHECK_PIN = 0, SIMPLE_STATE_ENABLE, + SIMPLE_STATE_ALLOWED_MODE, SIMPLE_STATE_REGISTER, SIMPLE_STATE_SET_APN, SIMPLE_STATE_CONNECT, SIMPLE_STATE_DONE } SimpleState; -static const char * -simple_get_string_property (MMCallbackInfo *info, const char *name, GError **error) +/* Looks a value up in the simple connect properties dictionary. If the + * requested key is not present in the dict, NULL is returned. If the + * requested key is present but is not a string, an error is returned. + */ +static gboolean +simple_get_property (MMCallbackInfo *info, + const char *name, + GType expected_type, + const char **out_str, + guint32 *out_num, + GError **error) { GHashTable *properties = (GHashTable *) mm_callback_info_get_data (info, "simple-connect-properties"); GValue *value; + gint foo; + + g_return_val_if_fail (properties != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + if (out_str) + g_return_val_if_fail (*out_str == NULL, FALSE); value = (GValue *) g_hash_table_lookup (properties, name); if (!value) - return NULL; + return FALSE; - if (G_VALUE_HOLDS_STRING (value)) - return g_value_get_string (value); + if ((expected_type == G_TYPE_STRING) && G_VALUE_HOLDS_STRING (value)) { + *out_str = g_value_get_string (value); + return TRUE; + } else if (expected_type == G_TYPE_UINT) { + if (G_VALUE_HOLDS_UINT (value)) { + *out_num = g_value_get_uint (value); + return TRUE; + } else if (G_VALUE_HOLDS_INT (value)) { + /* handle ints for convenience, but only if they are >= 0 */ + foo = g_value_get_int (value); + if (foo >= 0) { + *out_num = (guint) foo; + return TRUE; + } + } + } g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, - "Invalid property type for '%s': %s (string expected)", - name, G_VALUE_TYPE_NAME (value)); + "Invalid property type for '%s': %s (%s expected)", + name, G_VALUE_TYPE_NAME (value), g_type_name (expected_type)); - return NULL; + return FALSE; +} + +static const char * +simple_get_string_property (MMCallbackInfo *info, const char *name, GError **error) +{ + const char *str = NULL; + + simple_get_property (info, name, G_TYPE_STRING, &str, NULL, error); + return str; +} + +static gboolean +simple_get_uint_property (MMCallbackInfo *info, const char *name, guint32 *out_val, GError **error) +{ + return simple_get_property (info, name, G_TYPE_UINT, NULL, out_val, error); +} + +static gboolean +simple_get_allowed_mode (MMCallbackInfo *info, + MMModemGsmAllowedMode *out_mode, + GError **error) +{ + MMModemDeprecatedMode old_mode = MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY; + MMModemGsmAllowedMode allowed_mode = MM_MODEM_GSM_ALLOWED_MODE_ANY; + GError *tmp_error = NULL; + + /* check for new allowed mode first */ + if (simple_get_uint_property (info, "allowed_mode", &allowed_mode, &tmp_error)) { + if (allowed_mode > MM_MODEM_GSM_ALLOWED_MODE_LAST) { + g_set_error (&tmp_error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, + "Invalid allowed mode %d", old_mode); + } else { + *out_mode = allowed_mode; + return TRUE; + } + } else if (!tmp_error) { + /* and if not, the old allowed mode */ + if (simple_get_uint_property (info, "network_mode", &old_mode, &tmp_error)) { + if (old_mode > MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_LAST) { + g_set_error (&tmp_error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, + "Invalid allowed mode %d", old_mode); + } else { + *out_mode = mm_modem_gsm_network_old_mode_to_allowed (old_mode); + return TRUE; + } + } + } + + if (error) + *error = tmp_error; + return FALSE; } static void @@ -2956,6 +3037,7 @@ simple_state_machine (MMModem *modem, GError *error, gpointer user_data) SimpleState state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "simple-connect-state")); SimpleState next_state = state; gboolean done = FALSE; + MMModemGsmAllowedMode allowed_mode; if (error) { info->error = g_error_copy (error); @@ -2984,9 +3066,20 @@ simple_state_machine (MMModem *modem, GError *error, gpointer user_data) } /* Fall through if no PIN required */ case SIMPLE_STATE_ENABLE: - next_state = SIMPLE_STATE_REGISTER; + next_state = SIMPLE_STATE_ALLOWED_MODE; mm_modem_enable (modem, simple_state_machine, info); break; + case SIMPLE_STATE_ALLOWED_MODE: + next_state = SIMPLE_STATE_REGISTER; + if (simple_get_allowed_mode (info, &allowed_mode, &info->error)) { + mm_modem_gsm_network_set_allowed_mode (MM_MODEM_GSM_NETWORK (modem), + allowed_mode, + simple_state_machine, + info); + break; + } else if (info->error) + break; + /* otherwise fall through as no allowed mode was sent */ case SIMPLE_STATE_REGISTER: next_state = SIMPLE_STATE_SET_APN; str = simple_get_string_property (info, "network_id", &info->error); diff --git a/src/mm-modem-gsm.h b/src/mm-modem-gsm.h index 5f20b20d..a11e2c46 100644 --- a/src/mm-modem-gsm.h +++ b/src/mm-modem-gsm.h @@ -88,7 +88,9 @@ typedef enum { MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_ONLY, MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_ONLY, MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSUPA, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA + MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA, + + MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_LAST = MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA } MMModemDeprecatedMode; #endif /* MM_MODEM_GSM_H */ |