aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Williams <njw@chromium.org>2012-04-06 13:12:15 -0400
committerAleksander Morgado <aleksander@lanedo.com>2012-05-02 21:05:06 +0200
commit1c1a6a16ec7c7eab81f4a9eb026982aa2d77e348 (patch)
treef021282a0446a0243a41a244de61fa8ad168a5ff
parent83bc51edcbc814f687d3653c841a2ff0040d4f6e (diff)
novatel: Poll for whether the connection still exists.
Novatel E362 firmware doesn't notify us by unsolicited message if the connection goes away, so set up a polling loop to check. While here, inline a method that's only used in one place so that the containing function is single-exit and single-cleanup. Change-Id: If72f7c6ef06de3fb22530d42f62a8dddc6fecfda
-rw-r--r--plugins/novatel/mm-broadband-bearer-novatel.c112
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