diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2013-02-22 17:19:58 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2013-02-22 17:33:49 +0100 |
commit | 50ecf2a7d91221ea1db4a26e26222c048062a7a2 (patch) | |
tree | 008be13587b66e0ac6eb9982fc442e2c5ed3fd6b | |
parent | c0ce165d09d5ed80fff31ffd4bceb168e6c10b26 (diff) |
mbm: implement custom modem_power_down()
Cache last valid allowed mode always, so that we re-use it when powering up
again.
-rw-r--r-- | plugins/mbm/mm-broadband-modem-mbm.c | 112 |
1 files changed, 84 insertions, 28 deletions
diff --git a/plugins/mbm/mm-broadband-modem-mbm.c b/plugins/mbm/mm-broadband-modem-mbm.c index 08535a1e..6412c2a2 100644 --- a/plugins/mbm/mm-broadband-modem-mbm.c +++ b/plugins/mbm/mm-broadband-modem-mbm.c @@ -70,6 +70,8 @@ struct _MMBroadbandModemMbmPrivate { GRegex *estksmenu_regex; GRegex *emwi_regex; GRegex *erinfo_regex; + + guint mbm_mode; }; /*****************************************************************************/ @@ -167,12 +169,13 @@ modem_after_sim_unlock (MMIfaceModem *self, /* Load initial allowed/preferred modes (Modem interface) */ static gboolean -load_allowed_modes_finish (MMIfaceModem *self, +load_allowed_modes_finish (MMIfaceModem *_self, GAsyncResult *res, MMModemMode *allowed, MMModemMode *preferred, GError **error) { + MMBroadbandModemMbm *self = MM_BROADBAND_MODEM_MBM (_self); const gchar *response; guint a; @@ -187,15 +190,19 @@ load_allowed_modes_finish (MMIfaceModem *self, switch (a) { case MBM_NETWORK_MODE_OFFLINE: case MBM_NETWORK_MODE_LOW_POWER: + /* Do not update internal mbm_mode */ *allowed = MM_MODEM_MODE_NONE; break; case MBM_NETWORK_MODE_2G: + self->priv->mbm_mode = MBM_NETWORK_MODE_2G; *allowed = MM_MODEM_MODE_2G; break; case MBM_NETWORK_MODE_3G: + self->priv->mbm_mode = MBM_NETWORK_MODE_3G; *allowed = MM_MODEM_MODE_3G; break; default: + /* Do not update internal mbm_mode */ *allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); break; } @@ -227,6 +234,21 @@ load_allowed_modes (MMIfaceModem *self, /*****************************************************************************/ /* Set allowed modes (Modem interface) */ +typedef struct { + MMBroadbandModemMbm *self; + GSimpleAsyncResult *result; + gint mbm_mode; +} SetAllowedModesContext; + +static void +set_allowed_modes_context_complete_and_free (SetAllowedModesContext *ctx) +{ + g_simple_async_result_complete_in_idle (ctx->result); + g_object_unref (ctx->result); + g_object_unref (ctx->self); + g_slice_free (SetAllowedModesContext, ctx); +} + static gboolean set_allowed_modes_finish (MMIfaceModem *self, GAsyncResult *res, @@ -238,53 +260,56 @@ set_allowed_modes_finish (MMIfaceModem *self, static void allowed_mode_update_ready (MMBaseModem *self, GAsyncResult *res, - GSimpleAsyncResult *operation_result) + SetAllowedModesContext *ctx) { GError *error = NULL; mm_base_modem_at_command_finish (self, res, &error); if (error) /* Let the error be critical. */ - g_simple_async_result_take_error (operation_result, error); - else - g_simple_async_result_set_op_res_gboolean (operation_result, TRUE); - g_simple_async_result_complete (operation_result); - g_object_unref (operation_result); + g_simple_async_result_take_error (ctx->result, error); + else { + /* Cache current allowed mode */ + ctx->self->priv->mbm_mode = ctx->mbm_mode; + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + } + set_allowed_modes_context_complete_and_free (ctx); } static void -set_allowed_modes (MMIfaceModem *_self, +set_allowed_modes (MMIfaceModem *self, MMModemMode allowed, MMModemMode preferred, GAsyncReadyCallback callback, gpointer user_data) { - MMBroadbandModemMbm *self = MM_BROADBAND_MODEM_MBM (_self); - GSimpleAsyncResult *result; + SetAllowedModesContext *ctx; gchar *command; - gint mbm_mode = -1; - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - set_allowed_modes); + ctx = g_slice_new (SetAllowedModesContext); + ctx->self = g_object_ref (self); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + set_allowed_modes); + ctx->mbm_mode = -1; if (allowed == MM_MODEM_MODE_2G) - mbm_mode = MBM_NETWORK_MODE_2G; + ctx->mbm_mode = MBM_NETWORK_MODE_2G; else if (allowed == MM_MODEM_MODE_3G) - mbm_mode = MBM_NETWORK_MODE_3G; + ctx->mbm_mode = MBM_NETWORK_MODE_3G; else if ((allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G) || allowed == MM_MODEM_MODE_ANY) && preferred == MM_MODEM_MODE_NONE) - mbm_mode = MBM_NETWORK_MODE_ANY; + ctx->mbm_mode = MBM_NETWORK_MODE_ANY; - if (mbm_mode < 0) { + if (ctx->mbm_mode < 0) { gchar *allowed_str; gchar *preferred_str; allowed_str = mm_modem_mode_build_string_from_mask (allowed); preferred_str = mm_modem_mode_build_string_from_mask (preferred); - g_simple_async_result_set_error (result, + g_simple_async_result_set_error (ctx->result, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Requested mode (allowed: '%s', preferred: '%s') not " @@ -294,19 +319,18 @@ set_allowed_modes (MMIfaceModem *_self, g_free (allowed_str); g_free (preferred_str); - g_simple_async_result_complete_in_idle (result); - g_object_unref (result); + set_allowed_modes_context_complete_and_free (ctx); return; } - command = g_strdup_printf ("+CFUN=%d", mbm_mode); + command = g_strdup_printf ("+CFUN=%d", ctx->mbm_mode); mm_base_modem_at_command ( MM_BASE_MODEM (self), command, 3, FALSE, (GAsyncReadyCallback)allowed_mode_update_ready, - result); + ctx); g_free (command); } @@ -425,6 +449,32 @@ enabling_modem_init (MMBroadbandModem *self, } /*****************************************************************************/ +/* Modem power down (Modem interface) */ + +static gboolean +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 +modem_power_down (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + /* Use AT+CFUN=4 for power down. It will stop the RF (IMSI detach), and + * keeps access to the SIM */ + mm_base_modem_at_command (MM_BASE_MODEM (self), + "+CFUN=4", + 3, + FALSE, + callback, + user_data); +} + +/*****************************************************************************/ /* Powering up the modem (Modem interface) */ static gboolean @@ -445,9 +495,11 @@ modem_power_up (MMIfaceModem *_self, MMBroadbandModemMbm *self = MM_BROADBAND_MODEM_MBM (_self); gchar *command; - /* The power-up command will be run *only* during the first enabling - * of the modem, as there is no power-down command implemented */ - command = g_strdup_printf ("+CFUN=%u", MBM_NETWORK_MODE_ANY); + g_assert (self->priv->mbm_mode == MBM_NETWORK_MODE_ANY || + self->priv->mbm_mode == MBM_NETWORK_MODE_2G || + self->priv->mbm_mode == MBM_NETWORK_MODE_3G); + + command = g_strdup_printf ("+CFUN=%u", self->priv->mbm_mode); mm_base_modem_at_command (MM_BASE_MODEM (self), command, 5, @@ -1128,7 +1180,9 @@ mm_broadband_modem_mbm_init (MMBroadbandModemMbm *self) self->priv->emwi_regex = g_regex_new ("\\r\\n\\*EMWI: (\\d),(\\d).*\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); self->priv->erinfo_regex = g_regex_new ("\\r\\n\\*ERINFO:\\s*(\\d),(\\d),(\\d).*\\r\\n", - G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);; + G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + + self->priv->mbm_mode = MBM_NETWORK_MODE_ANY; } static void @@ -1168,6 +1222,8 @@ iface_modem_init (MMIfaceModem *iface) iface->load_power_state_finish = load_power_state_finish; iface->modem_power_up = modem_power_up; iface->modem_power_up_finish = modem_power_up_finish; + iface->modem_power_down = modem_power_down; + iface->modem_power_down_finish = modem_power_down_finish; } static void |