diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-08-22 12:25:03 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-08-23 18:56:22 +0200 |
commit | 4195a3f1a3ee3a7b15457a965b04489d9b091c22 (patch) | |
tree | 9d7843078cda54ada9724d31b8046da5433e0353 | |
parent | d517b611e9fbc24a5d0e58cc7bd87f2d448412cf (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.am | 2 | ||||
-rw-r--r-- | plugins/sierra/mm-broadband-modem-sierra.c | 3 | ||||
-rw-r--r-- | plugins/sierra/mm-common-sierra.c | 137 | ||||
-rw-r--r-- | plugins/sierra/mm-common-sierra.h | 31 |
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 */ |