[PATCH] huawei: implement modem power up and down
Ben Chan
benchan at chromium.org
Thu Aug 1 21:44:01 PDT 2013
From: Franko Fang <fangxiaozhi at huawei.com>
This patch is originally developed by:
Franko Fang <fangxiaozhi at huawei.com>
And then reviewed and updated by:
Ben Chan <benchan at chromium.org>
---
plugins/huawei/mm-broadband-modem-huawei.c | 159 +++++++++++++++++++++++++++++
1 file changed, 159 insertions(+)
diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c
index eb13a1b..8bc545b 100644
--- a/plugins/huawei/mm-broadband-modem-huawei.c
+++ b/plugins/huawei/mm-broadband-modem-huawei.c
@@ -67,6 +67,12 @@ typedef enum {
NDISDUP_SUPPORTED
} NdisdupSupport;
+typedef enum {
+ RFSWITCH_SUPPORT_UNKNOWN,
+ RFSWITCH_NOT_SUPPORTED,
+ RFSWITCH_SUPPORTED
+} RfswitchSupport;
+
struct _MMBroadbandModemHuaweiPrivate {
/* Regex for signal quality related notifications */
GRegex *rssi_regex;
@@ -92,6 +98,8 @@ struct _MMBroadbandModemHuaweiPrivate {
gboolean sysinfoex_supported;
gboolean sysinfoex_support_checked;
+
+ RfswitchSupport rfswitch_supported;
};
/*****************************************************************************/
@@ -2536,6 +2544,150 @@ modem_time_load_network_time (MMIfaceModemTime *self,
}
/*****************************************************************************/
+typedef struct {
+ MMIfaceModem *self;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+ void (*modem_power) (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+} PowerManagerContext;
+
+static void
+power_manager_context_complete_and_free (PowerManagerContext *ctx)
+{
+ ctx->modem_power = NULL;
+ g_slice_free (PowerManagerContext, ctx);
+}
+
+static void
+huawei_rfswitch_check_ready (MMBaseModem *self,
+ GAsyncResult *res,
+ PowerManagerContext *ctx)
+{
+ if (!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, NULL)) {
+ mm_dbg ("The device can not support ^rfswitch");
+ MM_BROADBAND_MODEM_HUAWEI (self)->priv->rfswitch_supported = RFSWITCH_NOT_SUPPORTED;
+ } else {
+ mm_dbg ("The device support ^rfswitch");
+ MM_BROADBAND_MODEM_HUAWEI (self)->priv->rfswitch_supported = RFSWITCH_SUPPORTED;
+ }
+
+ if (ctx->modem_power)
+ ctx->modem_power (ctx->self, ctx->callback, ctx->user_data);
+
+ power_manager_context_complete_and_free (ctx);
+}
+
+/*****************************************************************************/
+/* Modem power up (Modem interface) */
+
+static void
+huawei_modem_power_up (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ switch (MM_BROADBAND_MODEM_HUAWEI (self)->priv->rfswitch_supported) {
+ case RFSWITCH_SUPPORT_UNKNOWN:
+ {
+ PowerManagerContext *ctx;
+
+ ctx = g_slice_new0 (PowerManagerContext);
+ ctx->self = self;
+ ctx->callback = callback;
+ ctx->user_data = user_data;
+ ctx->modem_power = huawei_modem_power_up;
+
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "^RFSWITCH?",
+ 3,
+ FALSE,
+ (GAsyncReadyCallback)huawei_rfswitch_check_ready,
+ ctx);
+ break;
+ }
+ case RFSWITCH_NOT_SUPPORTED:
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+CFUN=1",
+ 30,
+ FALSE,
+ callback,
+ user_data);
+ break;
+ case RFSWITCH_SUPPORTED:
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "^RFSWITCH=1",
+ 30,
+ FALSE,
+ callback,
+ user_data);
+ break;
+ }
+}
+
+static gboolean
+huawei_modem_power_up_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return !!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
+}
+
+/*****************************************************************************/
+/* Modem power down (Modem interface) */
+
+static void
+huawei_modem_power_down (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ switch (MM_BROADBAND_MODEM_HUAWEI (self)->priv->rfswitch_supported) {
+ case RFSWITCH_SUPPORT_UNKNOWN:
+ {
+ PowerManagerContext *ctx;
+
+ ctx = g_slice_new0 (PowerManagerContext);
+ ctx->self = self;
+ ctx->callback = callback;
+ ctx->user_data = user_data;
+ ctx->modem_power = huawei_modem_power_down;
+
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "^RFSWITCH?",
+ 3,
+ FALSE,
+ (GAsyncReadyCallback)huawei_rfswitch_check_ready,
+ ctx);
+ break;
+ }
+ case RFSWITCH_NOT_SUPPORTED:
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+CFUN=0",
+ 30,
+ FALSE,
+ callback,
+ user_data);
+ break;
+ case RFSWITCH_SUPPORTED:
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "^RFSWITCH=0",
+ 30,
+ FALSE,
+ callback,
+ user_data);
+ break;
+ }
+}
+
+static gboolean
+huawei_modem_power_down_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return !!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
+}
+
+/*****************************************************************************/
/* Check support (Time interface) */
static gboolean
@@ -2701,6 +2853,8 @@ mm_broadband_modem_huawei_init (MMBroadbandModemHuawei *self)
self->priv->ndisdup_support = NDISDUP_SUPPORT_UNKNOWN;
+ self->priv->rfswitch_supported = RFSWITCH_SUPPORT_UNKNOWN;
+
self->priv->sysinfoex_supported = FALSE;
self->priv->sysinfoex_support_checked = FALSE;
}
@@ -2751,6 +2905,11 @@ iface_modem_init (MMIfaceModem *iface)
iface->load_signal_quality_finish = modem_load_signal_quality_finish;
iface->create_bearer = huawei_modem_create_bearer;
iface->create_bearer_finish = huawei_modem_create_bearer_finish;
+
+ iface->modem_power_up = huawei_modem_power_up;
+ iface->modem_power_up_finish = huawei_modem_power_up_finish;
+ iface->modem_power_down = huawei_modem_power_down;
+ iface->modem_power_down_finish = huawei_modem_power_down_finish;
}
static void
--
1.8.3
More information about the ModemManager-devel
mailing list