summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2012-11-28 13:09:58 -0600
committerDan Williams <dcbw@redhat.com>2012-12-05 11:27:54 -0600
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 dcfa020d..44e6f6ed 100644
--- a/plugins/huawei/mm-broadband-modem-huawei.c
+++ b/plugins/huawei/mm-broadband-modem-huawei.c
@@ -652,45 +652,109 @@ 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,
MMModemMode *preferred,
GError **error)
{
const gchar *response;
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
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);
}
static void
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,
user_data);
}
/*****************************************************************************/
/* 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)
{
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}
@@ -717,41 +781,48 @@ set_allowed_modes (MMIfaceModem *self,
MMModemMode allowed,
MMModemMode preferred,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *result;
- gchar *command;
- guint mode;
+ gchar *command = NULL;
+ guint mode = 0;
guint acquisition_order;
GError *error = NULL;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
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);
}
/*****************************************************************************/
/* Setup/Cleanup unsolicited events (3GPP interface) */