[PATCH v2] huawei: implement modem power up and down
Ben Chan
benchan at chromium.org
Mon Aug 5 22:01:19 PDT 2013
Thanks Dan. I've tested the patch on two modems that support RFSWITCH.
Ben
On Mon, Aug 5, 2013 at 9:06 PM, Dan Williams <dcbw at redhat.com> wrote:
> On Fri, 2013-08-02 at 18:07 -0700, Ben Chan wrote:
> > This patch is originally developed by:
> > Franko Fang <fangxiaozhi at huawei.com>
> >
> > And then reviewed and updated by:
> > Ben Chan <benchan at chromium.org>
>
> Pushed this one, thanks. I don't have a modem with RFSWITCH that I can
> find at the moment, but this worked for devices that do not support
> RFSWITCH.
>
> Thanks,
> Dan
>
> > ---
> > plugins/huawei/mm-broadband-modem-huawei.c | 218
> +++++++++++++++++++++++++++++
> > 1 file changed, 218 insertions(+)
> >
> > diff --git a/plugins/huawei/mm-broadband-modem-huawei.c
> b/plugins/huawei/mm-broadband-modem-huawei.c
> > index eb13a1b..15f3524 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;
> > @@ -89,6 +95,7 @@ struct _MMBroadbandModemHuaweiPrivate {
> > GRegex *ndisstat_regex;
> >
> > NdisdupSupport ndisdup_support;
> > + RfswitchSupport rfswitch_support;
> >
> > gboolean sysinfoex_supported;
> > gboolean sysinfoex_support_checked;
> > @@ -2536,6 +2543,210 @@ modem_time_load_network_time (MMIfaceModemTime
> *self,
> > }
> >
> >
> /*****************************************************************************/
> > +/* Power state loading (Modem interface) */
> > +
> > +static void
> > +parent_load_power_state_ready (MMIfaceModem *self,
> > + GAsyncResult *res,
> > + GSimpleAsyncResult *result)
> > +{
> > + GError *error = NULL;
> > + MMModemPowerState power_state;
> > +
> > + power_state = iface_modem_parent->load_power_state_finish (self,
> res, &error);
> > + if (error)
> > + g_simple_async_result_take_error (result, error);
> > + else
> > + g_simple_async_result_set_op_res_gpointer (result,
> GUINT_TO_POINTER (power_state), NULL);
> > +
> > + g_simple_async_result_complete (result);
> > + g_object_unref (result);
> > +}
> > +
> > +static void
> > +huawei_rfswitch_check_ready (MMBaseModem *_self,
> > + GAsyncResult *res,
> > + GSimpleAsyncResult *result)
> > +{
> > + MMBroadbandModemHuawei *self = MM_BROADBAND_MODEM_HUAWEI (_self);
> > + GError *error = NULL;
> > + const gchar *response;
> > + gint sw_state;
> > +
> > + response = mm_base_modem_at_command_finish (_self, res, &error);
> > + if (response) {
> > + response = mm_strip_tag (response, "^RFSWITCH:");
> > + if (sscanf (response, "%d", &sw_state) != 1 ||
> > + (sw_state != 0 && sw_state != 1)) {
> > + mm_warn ("Couldn't parse ^RFSWITCH response: '%s'",
> response);
> > + error = g_error_new (MM_CORE_ERROR,
> > + MM_CORE_ERROR_FAILED,
> > + "Couldn't parse ^RFSWITCH response:
> '%s'",
> > + response);
> > + }
> > + }
> > +
> > + switch (self->priv->rfswitch_support) {
> > + case RFSWITCH_SUPPORT_UNKNOWN:
> > + if (error) {
> > + mm_dbg ("The device does not support ^RFSWITCH");
> > + self->priv->rfswitch_support = RFSWITCH_NOT_SUPPORTED;
> > + g_error_free (error);
> > + /* Fall back to parent's load_power_state */
> > + iface_modem_parent->load_power_state (MM_IFACE_MODEM (self),
> > +
> (GAsyncReadyCallback)parent_load_power_state_ready,
> > + result);
> > + return;
> > + }
> > +
> > + mm_dbg ("The device supports ^RFSWITCH");
> > + self->priv->rfswitch_support = RFSWITCH_SUPPORTED;
> > + break;
> > + case RFSWITCH_SUPPORTED:
> > + break;
> > + default:
> > + g_assert_not_reached ();
> > + break;
> > + }
> > +
> > + if (error)
> > + g_simple_async_result_take_error (result, error);
> > + else
> > + g_simple_async_result_set_op_res_gpointer (result,
> > + sw_state ?
> > + GUINT_TO_POINTER
> (MM_MODEM_POWER_STATE_ON) :
> > + GUINT_TO_POINTER
> (MM_MODEM_POWER_STATE_LOW),
> > + NULL);
> > +
> > + g_simple_async_result_complete (result);
> > + g_object_unref (result);
> > +}
> > +
> > +static MMModemPowerState
> > +load_power_state_finish (MMIfaceModem *self,
> > + GAsyncResult *res,
> > + GError **error)
> > +{
> > + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT
> (res), error))
> > + return MM_MODEM_POWER_STATE_UNKNOWN;
> > +
> > + return (MMModemPowerState)GPOINTER_TO_UINT
> (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
> > +}
> > +
> > +static void
> > +load_power_state (MMIfaceModem *self,
> > + GAsyncReadyCallback callback,
> > + gpointer user_data)
> > +{
> > + GSimpleAsyncResult *result;
> > +
> > + result = g_simple_async_result_new (G_OBJECT (self),
> > + callback,
> > + user_data,
> > + load_power_state);
> > +
> > + switch (MM_BROADBAND_MODEM_HUAWEI (self)->priv->rfswitch_support) {
> > + case RFSWITCH_SUPPORT_UNKNOWN:
> > + case RFSWITCH_SUPPORTED: {
> > + mm_base_modem_at_command (MM_BASE_MODEM (self),
> > + "^RFSWITCH?",
> > + 3,
> > + FALSE,
> > +
> (GAsyncReadyCallback)huawei_rfswitch_check_ready,
> > + result);
> > + break;
> > + }
> > + case RFSWITCH_NOT_SUPPORTED:
> > + /* Run parent's load_power_state */
> > + iface_modem_parent->load_power_state (self,
> > +
> (GAsyncReadyCallback)parent_load_power_state_ready,
> > + result);
> > + break;
> > + default:
> > + g_assert_not_reached ();
> > + break;
> > + }
> > +}
> > +
> >
> +/*****************************************************************************/
> > +/* Modem power up (Modem interface) */
> > +
> > +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);
> > +}
> > +
> > +static void
> > +huawei_modem_power_up (MMIfaceModem *self,
> > + GAsyncReadyCallback callback,
> > + gpointer user_data)
> > +{
> > + switch (MM_BROADBAND_MODEM_HUAWEI (self)->priv->rfswitch_support) {
> > + 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;
> > + default:
> > + g_assert_not_reached ();
> > + break;
> > + }
> > +}
> > +
> >
> +/*****************************************************************************/
> > +/* Modem power down (Modem interface) */
> > +
> > +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);
> > +}
> > +
> > +static void
> > +huawei_modem_power_down (MMIfaceModem *self,
> > + GAsyncReadyCallback callback,
> > + gpointer user_data)
> > +{
> > + switch (MM_BROADBAND_MODEM_HUAWEI (self)->priv->rfswitch_support) {
> > + 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;
> > + default:
> > + g_assert_not_reached ();
> > + break;
> > + }
> > +}
> > +
> >
> +/*****************************************************************************/
> > /* Check support (Time interface) */
> >
> > static gboolean
> > @@ -2700,6 +2911,7 @@ mm_broadband_modem_huawei_init
> (MMBroadbandModemHuawei *self)
> > G_REGEX_RAW |
> G_REGEX_OPTIMIZE, 0, NULL);
> >
> > self->priv->ndisdup_support = NDISDUP_SUPPORT_UNKNOWN;
> > + self->priv->rfswitch_support = RFSWITCH_SUPPORT_UNKNOWN;
> >
> > self->priv->sysinfoex_supported = FALSE;
> > self->priv->sysinfoex_support_checked = FALSE;
> > @@ -2751,6 +2963,12 @@ 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->load_power_state = load_power_state;
> > + iface->load_power_state_finish = load_power_state_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
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/modemmanager-devel/attachments/20130805/eb9fec59/attachment-0001.html>
More information about the ModemManager-devel
mailing list