aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-08-22 12:25:03 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-08-23 18:56:22 +0200
commit4195a3f1a3ee3a7b15457a965b04489d9b091c22 (patch)
tree9d7843078cda54ada9724d31b8046da5433e0353
parentd517b611e9fbc24a5d0e58cc7bd87f2d448412cf (diff)
sierra: implement custom power up sequence
It is split in a new set of `mm-common-sierra.[hc]' files as this sequence will also be used in Icera-based modems.
-rw-r--r--plugins/Makefile.am2
-rw-r--r--plugins/sierra/mm-broadband-modem-sierra.c3
-rw-r--r--plugins/sierra/mm-common-sierra.c137
-rw-r--r--plugins/sierra/mm-common-sierra.h31
4 files changed, 173 insertions, 0 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index fce1aaee..42217853 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -148,6 +148,8 @@ libmm_plugin_hso_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
libmm_plugin_sierra_la_SOURCES = \
sierra/mm-plugin-sierra.c \
sierra/mm-plugin-sierra.h \
+ sierra/mm-common-sierra.c \
+ sierra/mm-common-sierra.h \
sierra/mm-broadband-modem-sierra.c \
sierra/mm-broadband-modem-sierra.h
libmm_plugin_sierra_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(ICERA_COMMON_COMPILER_FLAGS)
diff --git a/plugins/sierra/mm-broadband-modem-sierra.c b/plugins/sierra/mm-broadband-modem-sierra.c
index 0a5ca6a3..77377543 100644
--- a/plugins/sierra/mm-broadband-modem-sierra.c
+++ b/plugins/sierra/mm-broadband-modem-sierra.c
@@ -31,6 +31,7 @@
#include "mm-errors-types.h"
#include "mm-iface-modem.h"
#include "mm-iface-modem-3gpp.h"
+#include "mm-common-sierra.h"
static void iface_modem_init (MMIfaceModem *iface);
@@ -152,6 +153,8 @@ iface_modem_init (MMIfaceModem *iface)
{
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
+ iface->modem_power_up = mm_common_sierra_modem_power_up;
+ iface->modem_power_up_finish = mm_common_sierra_modem_power_up_finish;
}
static void
diff --git a/plugins/sierra/mm-common-sierra.c b/plugins/sierra/mm-common-sierra.c
new file mode 100644
index 00000000..8d41580e
--- /dev/null
+++ b/plugins/sierra/mm-common-sierra.c
@@ -0,0 +1,137 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details:
+ *
+ * Copyright (C) 2008 - 2009 Novell, Inc.
+ * Copyright (C) 2009 - 2012 Red Hat, Inc.
+ * Copyright (C) 2012 Lanedo GmbH
+ */
+
+#include "mm-common-sierra.h"
+#include "mm-base-modem-at.h"
+#include "mm-log.h"
+#include "mm-modem-helpers.h"
+
+/*****************************************************************************/
+/* Modem power up (Modem interface) */
+
+gboolean
+mm_common_sierra_modem_power_up_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+}
+
+static gboolean
+sierra_power_up_wait_cb (GSimpleAsyncResult *result)
+{
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
+ g_simple_async_result_complete (result);
+ g_object_unref (result);
+ return FALSE;
+}
+
+static void
+full_functionality_status_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ GSimpleAsyncResult *simple)
+{
+ GError *error = NULL;
+
+ if (!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error)) {
+ g_simple_async_result_take_error (simple, error);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ return;
+ }
+
+ /* Old Sierra devices (like the PCMCIA-based 860) return OK on +CFUN=1 right
+ * away but need some time to finish initialization. Anything driven by
+ * 'sierra' is new enough to need no delay.
+ */
+ if (g_str_equal (mm_base_modem_get_driver (MM_BASE_MODEM (self)), "sierra")) {
+ g_simple_async_result_set_op_res_gboolean (simple, TRUE);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ return;
+ }
+
+ /* The modem object will be valid in the callback as 'result' keeps a
+ * reference to it. */
+ g_timeout_add_seconds (10, (GSourceFunc)sierra_power_up_wait_cb, simple);
+}
+
+static void
+get_current_functionality_status_ready (MMBaseModem *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) {
+ mm_warn ("Failed checking if power-up command is needed: '%s'. "
+ "Will assume it isn't.",
+ error->message);
+ g_error_free (error);
+ /* On error, just assume we don't need the power-up command */
+ g_simple_async_result_set_op_res_gboolean (simple, TRUE);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ return;
+ }
+
+ response = mm_strip_tag (response, "+CFUN:");
+ if (response && *response == '1') {
+ /* If reported functionality status is '1', then we do not need to
+ * issue the power-up command. Otherwise, do it. */
+ mm_dbg ("Already in full functionality status, skipping power-up command");
+ g_simple_async_result_set_op_res_gboolean (simple, TRUE);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ return;
+ }
+
+ mm_warn ("Not in full functionality status, power-up command is needed. "
+ "Note that it may reboot the modem.");
+
+ /* Try to go to full functionality mode without rebooting the system.
+ * Works well if we previously switched off the power with CFUN=4
+ */
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+CFUN=1",
+ 3,
+ FALSE,
+ (GAsyncReadyCallback)full_functionality_status_ready,
+ simple);
+}
+
+void
+mm_common_sierra_modem_power_up (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+
+ result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ mm_common_sierra_modem_power_up);
+
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+CFUN?",
+ 3,
+ FALSE,
+ (GAsyncReadyCallback)get_current_functionality_status_ready,
+ result);
+}
diff --git a/plugins/sierra/mm-common-sierra.h b/plugins/sierra/mm-common-sierra.h
new file mode 100644
index 00000000..6cbce02f
--- /dev/null
+++ b/plugins/sierra/mm-common-sierra.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details:
+ *
+ * Copyright (C) 2008 - 2009 Novell, Inc.
+ * Copyright (C) 2009 - 2012 Red Hat, Inc.
+ * Copyright (C) 2012 Lanedo GmbH
+ */
+
+#ifndef MM_COMMON_SIERRA_H
+#define MM_COMMON_SIERRA_H
+
+#include "mm-broadband-modem.h"
+#include "mm-iface-modem.h"
+
+void mm_common_sierra_modem_power_up (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean mm_common_sierra_modem_power_up_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error);
+
+#endif /* MM_COMMON_SIERRA_H */