<div dir="ltr">Thanks Dan.  I've tested the patch on two modems that support RFSWITCH.<div><br></div><div>Ben</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Aug 5, 2013 at 9:06 PM, Dan Williams <span dir="ltr"><<a href="mailto:dcbw@redhat.com" target="_blank">dcbw@redhat.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Fri, 2013-08-02 at 18:07 -0700, Ben Chan wrote:<br>
> This patch is originally developed by:<br>
>   Franko Fang <<a href="mailto:fangxiaozhi@huawei.com">fangxiaozhi@huawei.com</a>><br>
><br>
> And then reviewed and updated by:<br>
>   Ben Chan <<a href="mailto:benchan@chromium.org">benchan@chromium.org</a>><br>
<br>
</div>Pushed this one, thanks.  I don't have a modem with RFSWITCH that I can<br>
find at the moment, but this worked for devices that do not support<br>
RFSWITCH.<br>
<br>
Thanks,<br>
Dan<br>
<div class="HOEnZb"><div class="h5"><br>
> ---<br>
>  plugins/huawei/mm-broadband-modem-huawei.c | 218 +++++++++++++++++++++++++++++<br>
>  1 file changed, 218 insertions(+)<br>
><br>
> diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c<br>
> index eb13a1b..15f3524 100644<br>
> --- a/plugins/huawei/mm-broadband-modem-huawei.c<br>
> +++ b/plugins/huawei/mm-broadband-modem-huawei.c<br>
> @@ -67,6 +67,12 @@ typedef enum {<br>
>      NDISDUP_SUPPORTED<br>
>  } NdisdupSupport;<br>
><br>
> +typedef enum {<br>
> +    RFSWITCH_SUPPORT_UNKNOWN,<br>
> +    RFSWITCH_NOT_SUPPORTED,<br>
> +    RFSWITCH_SUPPORTED<br>
> +} RfswitchSupport;<br>
> +<br>
>  struct _MMBroadbandModemHuaweiPrivate {<br>
>      /* Regex for signal quality related notifications */<br>
>      GRegex *rssi_regex;<br>
> @@ -89,6 +95,7 @@ struct _MMBroadbandModemHuaweiPrivate {<br>
>      GRegex *ndisstat_regex;<br>
><br>
>      NdisdupSupport ndisdup_support;<br>
> +    RfswitchSupport rfswitch_support;<br>
><br>
>      gboolean sysinfoex_supported;<br>
>      gboolean sysinfoex_support_checked;<br>
> @@ -2536,6 +2543,210 @@ modem_time_load_network_time (MMIfaceModemTime *self,<br>
>  }<br>
><br>
>  /*****************************************************************************/<br>
> +/* Power state loading (Modem interface) */<br>
> +<br>
> +static void<br>
> +parent_load_power_state_ready (MMIfaceModem *self,<br>
> +                               GAsyncResult *res,<br>
> +                               GSimpleAsyncResult *result)<br>
> +{<br>
> +    GError *error = NULL;<br>
> +    MMModemPowerState power_state;<br>
> +<br>
> +    power_state = iface_modem_parent->load_power_state_finish (self, res, &error);<br>
> +    if (error)<br>
> +        g_simple_async_result_take_error (result, error);<br>
> +    else<br>
> +        g_simple_async_result_set_op_res_gpointer (result, GUINT_TO_POINTER (power_state), NULL);<br>
> +<br>
> +    g_simple_async_result_complete (result);<br>
> +    g_object_unref (result);<br>
> +}<br>
> +<br>
> +static void<br>
> +huawei_rfswitch_check_ready (MMBaseModem *_self,<br>
> +                             GAsyncResult *res,<br>
> +                             GSimpleAsyncResult *result)<br>
> +{<br>
> +    MMBroadbandModemHuawei *self = MM_BROADBAND_MODEM_HUAWEI (_self);<br>
> +    GError *error = NULL;<br>
> +    const gchar *response;<br>
> +    gint sw_state;<br>
> +<br>
> +    response = mm_base_modem_at_command_finish (_self, res, &error);<br>
> +    if (response) {<br>
> +        response = mm_strip_tag (response, "^RFSWITCH:");<br>
> +        if (sscanf (response, "%d", &sw_state) != 1 ||<br>
> +            (sw_state != 0 && sw_state != 1)) {<br>
> +            mm_warn ("Couldn't parse ^RFSWITCH response: '%s'", response);<br>
> +            error = g_error_new (MM_CORE_ERROR,<br>
> +                                 MM_CORE_ERROR_FAILED,<br>
> +                                 "Couldn't parse ^RFSWITCH response: '%s'",<br>
> +                                 response);<br>
> +        }<br>
> +    }<br>
> +<br>
> +    switch (self->priv->rfswitch_support) {<br>
> +    case RFSWITCH_SUPPORT_UNKNOWN:<br>
> +        if (error) {<br>
> +            mm_dbg ("The device does not support ^RFSWITCH");<br>
> +            self->priv->rfswitch_support = RFSWITCH_NOT_SUPPORTED;<br>
> +            g_error_free (error);<br>
> +            /* Fall back to parent's load_power_state */<br>
> +            iface_modem_parent->load_power_state (MM_IFACE_MODEM (self),<br>
> +                                                  (GAsyncReadyCallback)parent_load_power_state_ready,<br>
> +                                                  result);<br>
> +            return;<br>
> +        }<br>
> +<br>
> +        mm_dbg ("The device supports ^RFSWITCH");<br>
> +        self->priv->rfswitch_support = RFSWITCH_SUPPORTED;<br>
> +        break;<br>
> +    case RFSWITCH_SUPPORTED:<br>
> +        break;<br>
> +    default:<br>
> +        g_assert_not_reached ();<br>
> +        break;<br>
> +    }<br>
> +<br>
> +    if (error)<br>
> +        g_simple_async_result_take_error (result, error);<br>
> +    else<br>
> +        g_simple_async_result_set_op_res_gpointer (result,<br>
> +                                                   sw_state ?<br>
> +                                                   GUINT_TO_POINTER (MM_MODEM_POWER_STATE_ON) :<br>
> +                                                   GUINT_TO_POINTER (MM_MODEM_POWER_STATE_LOW),<br>
> +                                                   NULL);<br>
> +<br>
> +    g_simple_async_result_complete (result);<br>
> +    g_object_unref (result);<br>
> +}<br>
> +<br>
> +static MMModemPowerState<br>
> +load_power_state_finish (MMIfaceModem *self,<br>
> +                         GAsyncResult *res,<br>
> +                         GError **error)<br>
> +{<br>
> +    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))<br>
> +        return MM_MODEM_POWER_STATE_UNKNOWN;<br>
> +<br>
> +    return (MMModemPowerState)GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));<br>
> +}<br>
> +<br>
> +static void<br>
> +load_power_state (MMIfaceModem *self,<br>
> +                  GAsyncReadyCallback callback,<br>
> +                  gpointer user_data)<br>
> +{<br>
> +    GSimpleAsyncResult *result;<br>
> +<br>
> +    result = g_simple_async_result_new (G_OBJECT (self),<br>
> +                                        callback,<br>
> +                                        user_data,<br>
> +                                        load_power_state);<br>
> +<br>
> +    switch (MM_BROADBAND_MODEM_HUAWEI (self)->priv->rfswitch_support) {<br>
> +    case RFSWITCH_SUPPORT_UNKNOWN:<br>
> +    case RFSWITCH_SUPPORTED: {<br>
> +        mm_base_modem_at_command (MM_BASE_MODEM (self),<br>
> +                                  "^RFSWITCH?",<br>
> +                                  3,<br>
> +                                  FALSE,<br>
> +                                  (GAsyncReadyCallback)huawei_rfswitch_check_ready,<br>
> +                                  result);<br>
> +        break;<br>
> +    }<br>
> +    case RFSWITCH_NOT_SUPPORTED:<br>
> +      /* Run parent's load_power_state */<br>
> +      iface_modem_parent->load_power_state (self,<br>
> +                                            (GAsyncReadyCallback)parent_load_power_state_ready,<br>
> +                                            result);<br>
> +      break;<br>
> +    default:<br>
> +      g_assert_not_reached ();<br>
> +      break;<br>
> +    }<br>
> +}<br>
> +<br>
> +/*****************************************************************************/<br>
> +/* Modem power up (Modem interface) */<br>
> +<br>
> +static gboolean<br>
> +huawei_modem_power_up_finish (MMIfaceModem *self,<br>
> +                              GAsyncResult *res,<br>
> +                              GError **error)<br>
> +{<br>
> +    return !!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);<br>
> +}<br>
> +<br>
> +static void<br>
> +huawei_modem_power_up (MMIfaceModem *self,<br>
> +                       GAsyncReadyCallback callback,<br>
> +                       gpointer user_data)<br>
> +{<br>
> +    switch (MM_BROADBAND_MODEM_HUAWEI (self)->priv->rfswitch_support) {<br>
> +    case RFSWITCH_NOT_SUPPORTED:<br>
> +        mm_base_modem_at_command (MM_BASE_MODEM (self),<br>
> +                                  "+CFUN=1",<br>
> +                                  30,<br>
> +                                  FALSE,<br>
> +                                  callback,<br>
> +                                  user_data);<br>
> +        break;<br>
> +    case RFSWITCH_SUPPORTED:<br>
> +        mm_base_modem_at_command (MM_BASE_MODEM (self),<br>
> +                                  "^RFSWITCH=1",<br>
> +                                  30,<br>
> +                                  FALSE,<br>
> +                                  callback,<br>
> +                                  user_data);<br>
> +        break;<br>
> +    default:<br>
> +        g_assert_not_reached ();<br>
> +        break;<br>
> +    }<br>
> +}<br>
> +<br>
> +/*****************************************************************************/<br>
> +/* Modem power down (Modem interface) */<br>
> +<br>
> +static gboolean<br>
> +huawei_modem_power_down_finish (MMIfaceModem *self,<br>
> +                                GAsyncResult *res,<br>
> +                                GError **error)<br>
> +{<br>
> +    return !!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);<br>
> +}<br>
> +<br>
> +static void<br>
> +huawei_modem_power_down (MMIfaceModem *self,<br>
> +                         GAsyncReadyCallback callback,<br>
> +                         gpointer user_data)<br>
> +{<br>
> +    switch (MM_BROADBAND_MODEM_HUAWEI (self)->priv->rfswitch_support) {<br>
> +    case RFSWITCH_NOT_SUPPORTED:<br>
> +        mm_base_modem_at_command (MM_BASE_MODEM (self),<br>
> +                                  "+CFUN=0",<br>
> +                                  30,<br>
> +                                  FALSE,<br>
> +                                  callback,<br>
> +                                  user_data);<br>
> +        break;<br>
> +    case RFSWITCH_SUPPORTED:<br>
> +        mm_base_modem_at_command (MM_BASE_MODEM (self),<br>
> +                                  "^RFSWITCH=0",<br>
> +                                  30,<br>
> +                                  FALSE,<br>
> +                                  callback,<br>
> +                                  user_data);<br>
> +        break;<br>
> +    default:<br>
> +        g_assert_not_reached ();<br>
> +        break;<br>
> +    }<br>
> +}<br>
> +<br>
> +/*****************************************************************************/<br>
>  /* Check support (Time interface) */<br>
><br>
>  static gboolean<br>
> @@ -2700,6 +2911,7 @@ mm_broadband_modem_huawei_init (MMBroadbandModemHuawei *self)<br>
>                                                G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);<br>
><br>
>      self->priv->ndisdup_support = NDISDUP_SUPPORT_UNKNOWN;<br>
> +    self->priv->rfswitch_support = RFSWITCH_SUPPORT_UNKNOWN;<br>
><br>
>      self->priv->sysinfoex_supported = FALSE;<br>
>      self->priv->sysinfoex_support_checked = FALSE;<br>
> @@ -2751,6 +2963,12 @@ iface_modem_init (MMIfaceModem *iface)<br>
>      iface->load_signal_quality_finish = modem_load_signal_quality_finish;<br>
>      iface->create_bearer = huawei_modem_create_bearer;<br>
>      iface->create_bearer_finish = huawei_modem_create_bearer_finish;<br>
> +    iface->load_power_state = load_power_state;<br>
> +    iface->load_power_state_finish = load_power_state_finish;<br>
> +    iface->modem_power_up = huawei_modem_power_up;<br>
> +    iface->modem_power_up_finish = huawei_modem_power_up_finish;<br>
> +    iface->modem_power_down = huawei_modem_power_down;<br>
> +    iface->modem_power_down_finish = huawei_modem_power_down_finish;<br>
>  }<br>
><br>
>  static void<br>
<br>
<br>
</div></div></blockquote></div><br></div>