diff options
-rw-r--r-- | plugins/novatel/mm-broadband-bearer-novatel.c | 112 |
1 files changed, 79 insertions, 33 deletions
diff --git a/plugins/novatel/mm-broadband-bearer-novatel.c b/plugins/novatel/mm-broadband-bearer-novatel.c index 04fd01a2..20f87c14 100644 --- a/plugins/novatel/mm-broadband-bearer-novatel.c +++ b/plugins/novatel/mm-broadband-bearer-novatel.c @@ -32,6 +32,8 @@ #include "mm-modem-helpers.h" #include "mm-utils.h" +#define CONNECTION_CHECK_TIMEOUT_SEC 5 + G_DEFINE_TYPE (MMBroadbandBearerNovatel, mm_broadband_bearer_novatel, MM_TYPE_BROADBAND_BEARER); enum { @@ -48,6 +50,8 @@ static GParamSpec *properties[PROP_LAST]; struct _MMBroadbandBearerNovatelPrivate { + /* timeout id for checking whether we're still connected */ + guint connection_poller; /* Username for authenticating to APN */ gchar *user; /* Password for authenticating to APN */ @@ -105,19 +109,6 @@ detailed_connect_context_complete_and_free (DetailedConnectContext *ctx) g_free (ctx); } -static void -detailed_connect_context_complete_and_free_successful (DetailedConnectContext *ctx) -{ - MMBearerIpConfig *config; - - config = mm_bearer_ip_config_new (); - mm_bearer_ip_config_set_method (config, MM_BEARER_IP_METHOD_DHCP); - g_simple_async_result_set_op_res_gpointer (ctx->result, - config, - (GDestroyNotify)g_object_unref); - detailed_connect_context_complete_and_free (ctx); -} - static gboolean connect_3gpp_finish (MMBroadbandBearer *self, GAsyncResult *res, @@ -141,6 +132,46 @@ connect_3gpp_finish (MMBroadbandBearer *self, static gboolean connect_3gpp_qmistatus (DetailedConnectContext *ctx); static void +poll_connection_ready (MMBaseModem *modem, + GAsyncResult *res, + MMBroadbandBearerNovatel *bearer) +{ + const gchar *result; + GError *error = NULL; + + result = mm_base_modem_at_command_finish (modem, res, &error); + if (!result) { + mm_warn ("QMI connection status failed: %s", error->message); + g_error_free (error); + } else { + result = mm_strip_tag (result, "$NWQMISTATUS:"); + if (g_strrstr(result, "QMI State: DISCONNECTED")) { + mm_bearer_report_disconnection (MM_BEARER (bearer)); + g_source_remove (bearer->priv->connection_poller); + bearer->priv->connection_poller = 0; + } + } +} + +static gboolean +poll_connection (MMBroadbandBearerNovatel *bearer) +{ + MMBaseModem *modem = NULL; + g_object_get (MM_BEARER (bearer), + MM_BEARER_MODEM, &modem, + NULL); + mm_base_modem_at_command ( + modem, + "$NWQMISTATUS", + 3, + FALSE, + (GAsyncReadyCallback)poll_connection_ready, + bearer); + g_object_unref (modem); + return TRUE; +} + +static void connect_3gpp_qmistatus_ready (MMBaseModem *modem, GAsyncResult *res, DetailedConnectContext *ctx) @@ -154,28 +185,34 @@ connect_3gpp_qmistatus_ready (MMBaseModem *modem, if (!result) { mm_warn ("QMI connection status failed: %s", error->message); g_simple_async_result_take_error (ctx->result, error); - detailed_connect_context_complete_and_free (ctx); - return; - } - - result = mm_strip_tag (result, "$NWQMISTATUS:"); - if (g_strrstr(result, "QMI State: CONNECTED")) { - mm_dbg("Connected"); - detailed_connect_context_complete_and_free_successful (ctx); - return; } else { - mm_dbg("Error: '%s'", result); - if (ctx->retries > 0) { - ctx->retries--; - mm_dbg("Retrying status check in a second. %d retries left.", - ctx->retries); - g_timeout_add_seconds(1, (GSourceFunc)connect_3gpp_qmistatus, ctx); - return; + result = mm_strip_tag (result, "$NWQMISTATUS:"); + if (g_strrstr(result, "QMI State: CONNECTED")) { + MMBearerIpConfig *config; + MMBroadbandBearerNovatel *bearer = MM_BROADBAND_BEARER_NOVATEL (ctx->self); + mm_dbg("Connected"); + bearer->priv->connection_poller = g_timeout_add_seconds (CONNECTION_CHECK_TIMEOUT_SEC, + (GSourceFunc)poll_connection, + bearer); + config = mm_bearer_ip_config_new (); + mm_bearer_ip_config_set_method (config, MM_BEARER_IP_METHOD_DHCP); + g_simple_async_result_set_op_res_gpointer (ctx->result, + config, + (GDestroyNotify)g_object_unref); + } else { + mm_dbg("Error: '%s'", result); + if (ctx->retries > 0) { + ctx->retries--; + mm_dbg("Retrying status check in a second. %d retries left.", + ctx->retries); + g_timeout_add_seconds(1, (GSourceFunc)connect_3gpp_qmistatus, ctx); + return; + } + g_simple_async_result_set_error (ctx->result, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "%s", result); } - g_simple_async_result_set_error (ctx->result, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "%s", result); } detailed_connect_context_complete_and_free (ctx); } @@ -379,6 +416,12 @@ disconnect_3gpp (MMBroadbandBearer *self, gpointer user_data) { DetailedDisconnectContext *ctx; + MMBroadbandBearerNovatel *bearer = MM_BROADBAND_BEARER_NOVATEL (self); + + if (bearer->priv->connection_poller) { + g_source_remove (bearer->priv->connection_poller); + bearer->priv->connection_poller = 0; + } ctx = detailed_disconnect_context_new (self, modem, primary, secondary, data, callback, user_data); @@ -400,6 +443,8 @@ finalize (GObject *object) g_free (self->priv->user); g_free (self->priv->password); + if (self->priv->connection_poller) + g_source_remove (self->priv->connection_poller); G_OBJECT_CLASS (mm_broadband_bearer_novatel_parent_class)->finalize (object); } @@ -493,6 +538,7 @@ mm_broadband_bearer_novatel_init (MMBroadbandBearerNovatel *self) self->priv->user = NULL; self->priv->password = NULL; + self->priv->connection_poller = 0; } static void |