summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2012-11-28 19:09:58 (GMT)
committerDan Williams <dcbw@redhat.com>2012-12-05 17:27:54 (GMT)
commite3a71711bfbb0998b85bdb00fe7857c34b560dec (patch)
treeab7381b61d840858b07e272f56516e610fa79631
parentc3984d3982ecce269451cb6d3a1ac2281bfc57b5 (diff)
huawei: handle CDMA allowed modes
-rw-r--r--plugins/huawei/mm-broadband-modem-huawei.c107
1 files changed, 89 insertions, 18 deletions
diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c
index dcfa020..44e6f6e 100644
--- a/plugins/huawei/mm-broadband-modem-huawei.c
+++ b/plugins/huawei/mm-broadband-modem-huawei.c
@@ -655,6 +655,31 @@ set_bands (MMIfaceModem *self,
/* Load initial allowed/preferred modes (Modem interface) */
static gboolean
+parse_prefmode (const gchar *response, MMModemMode *preferred, GError **error)
+{
+ int a;
+
+ response = mm_strip_tag (response, "^PREFMODE:");
+ a = atoi (response);
+ if (a == 2) {
+ *preferred = MM_MODEM_MODE_2G;
+ return TRUE;
+ } else if (a == 4) {
+ *preferred = MM_MODEM_MODE_3G;
+ return TRUE;
+ } else if (a == 8) {
+ *preferred = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G;
+ return TRUE;
+ }
+
+ g_set_error_literal (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Failed to parse ^PREFMODE response");
+ return FALSE;
+}
+
+static gboolean
load_allowed_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
MMModemMode *allowed,
@@ -667,6 +692,14 @@ load_allowed_modes_finish (MMIfaceModem *self,
if (!response)
return FALSE;
+ if (mm_iface_modem_is_cdma_only (self)) {
+ /* CDMA-only devices always support 2G and 3G if they have 3G, so just
+ * use the modes from GCAP as the list of allowed modes.
+ */
+ *allowed = mm_iface_modem_get_supported_modes (self);
+ return parse_prefmode (response, preferred, error);
+ }
+
return parse_syscfg (response, NULL, allowed, preferred, error);
}
@@ -675,9 +708,13 @@ load_allowed_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ const char *command;
+
mm_dbg ("loading allowed_modes (huawei)...");
+
+ command = mm_iface_modem_is_cdma_only (self) ? "^PREFMODE?" : "^SYSCFG?";
mm_base_modem_at_command (MM_BASE_MODEM (self),
- "^SYSCFG?",
+ command,
3,
FALSE,
callback,
@@ -688,6 +725,33 @@ load_allowed_modes (MMIfaceModem *self,
/* Set allowed modes (Modem interface) */
static gboolean
+allowed_mode_to_prefmode (MMModemMode allowed, guint *huawei_mode, GError **error)
+{
+ char *allowed_str;
+
+ *huawei_mode = 0;
+ if (allowed == MM_MODEM_MODE_ANY)
+ *huawei_mode = 8;
+ else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G))
+ *huawei_mode = 8;
+ else if (allowed == MM_MODEM_MODE_2G)
+ *huawei_mode = 2;
+ else if (allowed == MM_MODEM_MODE_3G)
+ *huawei_mode = 4;
+ else {
+ /* Not supported */
+ allowed_str = mm_modem_mode_build_string_from_mask (allowed);
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Requested mode (allowed: '%s') not supported by the modem.",
+ allowed_str);
+ g_free (allowed_str);
+ }
+ return *huawei_mode ? TRUE : FALSE;
+}
+
+static gboolean
set_allowed_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
@@ -720,8 +784,8 @@ set_allowed_modes (MMIfaceModem *self,
gpointer user_data)
{
GSimpleAsyncResult *result;
- gchar *command;
- guint mode;
+ gchar *command = NULL;
+ guint mode = 0;
guint acquisition_order;
GError *error = NULL;
@@ -730,25 +794,32 @@ set_allowed_modes (MMIfaceModem *self,
user_data,
set_allowed_modes);
- if (!allowed_mode_to_huawei (allowed,
- preferred,
- &mode,
- &acquisition_order,
- &error)) {
+ if (mm_iface_modem_is_cdma_only (self)) {
+ if (allowed_mode_to_prefmode (allowed, &mode, &error))
+ command = g_strdup_printf ("^PREFMODE=%d", mode);
+ } else {
+ if (allowed_mode_to_huawei (allowed,
+ preferred,
+ &mode,
+ &acquisition_order,
+ &error))
+ command = g_strdup_printf ("AT^SYSCFG=%d,%d,40000000,2,4", mode, acquisition_order);
+ }
+
+ if (command) {
+ mm_base_modem_at_command (
+ MM_BASE_MODEM (self),
+ command,
+ 3,
+ FALSE,
+ (GAsyncReadyCallback)allowed_mode_update_ready,
+ result);
+ } else {
+ g_assert (error);
g_simple_async_result_take_error (result, error);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
- return;
}
-
- command = g_strdup_printf ("AT^SYSCFG=%d,%d,40000000,2,4", mode, acquisition_order);
- mm_base_modem_at_command (
- MM_BASE_MODEM (self),
- command,
- 3,
- FALSE,
- (GAsyncReadyCallback)allowed_mode_update_ready,
- result);
g_free (command);
}