[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