huawei: load supported modes, not just assume them

This commit is contained in:
Aleksander Morgado
2013-11-08 21:15:53 +01:00
parent ef526395df
commit 8cc3eff661

View File

@@ -14,7 +14,7 @@
* Copyright (C) 2009 - 2012 Red Hat, Inc.
* Copyright (C) 2011 - 2012 Google Inc.
* Copyright (C) 2012 Huawei Technologies Co., Ltd
* Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
* Copyright (C) 2012 - 2013 Aleksander Morgado <aleksander@gnu.org>
*/
#include <config.h>
@@ -101,6 +101,13 @@ struct _MMBroadbandModemHuaweiPrivate {
FeatureSupport ndisdup_support;
FeatureSupport rfswitch_support;
FeatureSupport sysinfoex_support;
FeatureSupport syscfg_support;
FeatureSupport syscfgex_support;
FeatureSupport prefmode_support;
GArray *syscfg_supported_modes;
GArray *syscfgex_supported_modes;
GArray *prefmode_supported_modes;
};
/*****************************************************************************/
@@ -1008,73 +1015,209 @@ load_supported_modes_finish (MMIfaceModem *self,
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
syscfg_test_ready (MMBroadbandModemHuawei *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
const gchar *response;
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (response)
self->priv->syscfg_supported_modes = mm_huawei_parse_syscfg_test (response, &error);
if (self->priv->syscfg_supported_modes) {
MMModemModeCombination mode;
guint i;
GArray *combinations;
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* CDMA modems don't support 'preferred' setups */
if (!mm_iface_modem_is_cdma_only (self)) {
/* 2G and 3G, 2G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 2G and 3G, 3G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_3G;
combinations = g_array_sized_new (FALSE,
FALSE,
sizeof (MMModemModeCombination),
self->priv->syscfg_supported_modes->len);
for (i = 0; i < self->priv->syscfg_supported_modes->len; i++) {
MMHuaweiSyscfgCombination *huawei_mode;
huawei_mode = &g_array_index (self->priv->syscfg_supported_modes,
MMHuaweiSyscfgCombination,
i);
mode.allowed = huawei_mode->allowed;
mode.preferred = huawei_mode->preferred;
g_array_append_val (combinations, mode);
}
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
self->priv->syscfg_support = FEATURE_SUPPORTED;
g_simple_async_result_set_op_res_gpointer (simple,
combinations,
(GDestroyNotify)g_array_unref);
} else {
g_debug ("Error while checking ^SYSCFG format: %s", error->message);
/* If SIM-PIN error, don't mark as feature unsupported; we'll retry later */
if (!g_error_matches (error,
MM_MOBILE_EQUIPMENT_ERROR,
MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN))
self->priv->syscfg_support = FEATURE_NOT_SUPPORTED;
g_simple_async_result_take_error (simple, error);
}
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
syscfgex_test_ready (MMBroadbandModemHuawei *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
const gchar *response;
GError *error = NULL;
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (response)
self->priv->syscfgex_supported_modes = mm_huawei_parse_syscfgex_test (response, &error);
if (self->priv->syscfgex_supported_modes) {
MMModemModeCombination mode;
guint i;
GArray *combinations;
/* Build list of combinations */
combinations = g_array_sized_new (FALSE,
FALSE,
sizeof (MMModemModeCombination),
self->priv->syscfgex_supported_modes->len);
for (i = 0; i < self->priv->syscfgex_supported_modes->len; i++) {
MMHuaweiSyscfgexCombination *huawei_mode;
huawei_mode = &g_array_index (self->priv->syscfgex_supported_modes,
MMHuaweiSyscfgexCombination,
i);
mode.allowed = huawei_mode->allowed;
mode.preferred = huawei_mode->preferred;
g_array_append_val (combinations, mode);
}
self->priv->syscfgex_support = FEATURE_SUPPORTED;
g_simple_async_result_set_op_res_gpointer (simple,
combinations,
(GDestroyNotify)g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* If SIM-PIN error, don't mark as feature unsupported; we'll retry later */
if (error) {
g_debug ("Error while checking ^SYSCFGEX format: %s", error->message);
if (g_error_matches (error,
MM_MOBILE_EQUIPMENT_ERROR,
MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN)) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
g_error_free (error);
}
self->priv->syscfgex_support = FEATURE_NOT_SUPPORTED;
/* Try with SYSCFG */
mm_base_modem_at_command (MM_BASE_MODEM (self),
"^SYSCFG=?",
3,
TRUE,
(GAsyncReadyCallback)syscfg_test_ready,
simple);
}
static void
prefmode_test_ready (MMBroadbandModemHuawei *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
const gchar *response;
GError *error = NULL;
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (response)
self->priv->prefmode_supported_modes = mm_huawei_parse_prefmode_test (response, &error);
if (self->priv->prefmode_supported_modes) {
MMModemModeCombination mode;
guint i;
GArray *combinations;
/* Build list of combinations */
combinations = g_array_sized_new (FALSE,
FALSE,
sizeof (MMModemModeCombination),
self->priv->prefmode_supported_modes->len);
for (i = 0; i < self->priv->prefmode_supported_modes->len; i++) {
MMHuaweiPrefmodeCombination *huawei_mode;
huawei_mode = &g_array_index (self->priv->prefmode_supported_modes,
MMHuaweiPrefmodeCombination,
i);
mode.allowed = huawei_mode->allowed;
mode.preferred = huawei_mode->preferred;
g_array_append_val (combinations, mode);
}
self->priv->prefmode_support = FEATURE_SUPPORTED;
g_simple_async_result_set_op_res_gpointer (simple,
combinations,
(GDestroyNotify)g_array_unref);
} else {
g_debug ("Error while checking ^PREFMODE format: %s", error->message);
/* If SIM-PIN error, don't mark as feature unsupported; we'll retry later */
if (!g_error_matches (error,
MM_MOBILE_EQUIPMENT_ERROR,
MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN))
self->priv->prefmode_support = FEATURE_NOT_SUPPORTED;
g_simple_async_result_take_error (simple, error);
}
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
MMBroadbandModemHuawei *self = MM_BROADBAND_MODEM_HUAWEI (_self);
GSimpleAsyncResult *result;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
load_supported_modes);
if (mm_iface_modem_is_cdma_only (_self)) {
/* ^PREFMODE only in CDMA-only modems */
self->priv->syscfg_support = FEATURE_NOT_SUPPORTED;
self->priv->syscfgex_support = FEATURE_NOT_SUPPORTED;
mm_base_modem_at_command (MM_BASE_MODEM (self),
"^PREFMODE=?",
3,
TRUE,
(GAsyncReadyCallback)prefmode_test_ready,
result);
return;
}
/* Check SYSCFGEX */
self->priv->prefmode_support = FEATURE_NOT_SUPPORTED;
mm_base_modem_at_command (MM_BASE_MODEM (self),
"^SYSCFGEX=?",
3,
TRUE,
(GAsyncReadyCallback)syscfgex_test_ready,
result);
}
/*****************************************************************************/
@@ -3034,6 +3177,9 @@ mm_broadband_modem_huawei_init (MMBroadbandModemHuawei *self)
self->priv->ndisdup_support = FEATURE_SUPPORT_UNKNOWN;
self->priv->rfswitch_support = FEATURE_SUPPORT_UNKNOWN;
self->priv->sysinfoex_support = FEATURE_SUPPORT_UNKNOWN;
self->priv->syscfg_support = FEATURE_SUPPORT_UNKNOWN;
self->priv->syscfgex_support = FEATURE_SUPPORT_UNKNOWN;
self->priv->prefmode_support = FEATURE_SUPPORT_UNKNOWN;
}
static void
@@ -3061,6 +3207,13 @@ finalize (GObject *object)
g_regex_unref (self->priv->ndisend_regex);
g_regex_unref (self->priv->rfswitch_regex);
if (self->priv->syscfg_supported_modes)
g_array_unref (self->priv->syscfg_supported_modes);
if (self->priv->syscfgex_supported_modes)
g_array_unref (self->priv->syscfgex_supported_modes);
if (self->priv->prefmode_supported_modes)
g_array_unref (self->priv->prefmode_supported_modes);
G_OBJECT_CLASS (mm_broadband_modem_huawei_parent_class)->finalize (object);
}