aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2016-08-07 13:31:41 +0200
committerAleksander Morgado <aleksander@aleksander.es>2016-10-12 11:29:52 +0200
commit26d0d718f7834348146ab9e040051f7a538f04f0 (patch)
treecc4864393d33ea369a6f0627b8d645a570d4b472 /src
parent467b3c57f01b37dbcec8d32a449654aac40f90d0 (diff)
base-bearer: new periodic monitoring of connection status
Diffstat (limited to 'src')
-rw-r--r--src/mm-base-bearer.c80
-rw-r--r--src/mm-base-bearer.h11
2 files changed, 85 insertions, 6 deletions
diff --git a/src/mm-base-bearer.c b/src/mm-base-bearer.c
index 12b1d531..e4234ea7 100644
--- a/src/mm-base-bearer.c
+++ b/src/mm-base-bearer.c
@@ -14,7 +14,7 @@
* Copyright (C) 2009 - 2011 Red Hat, Inc.
* Copyright (C) 2011 Google, Inc.
* Copyright (C) 2015 Azimut Electronics
- * Copyright (C) 2011 - 2015 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2011 - 2016 Aleksander Morgado <aleksander@aleksander.es>
*/
#include <config.h>
@@ -46,6 +46,8 @@
#define BEARER_STATS_UPDATE_TIMEOUT 30
+#define BEARER_CONNECTION_MONITOR_TIMEOUT 5
+
G_DEFINE_TYPE (MMBaseBearer, mm_base_bearer, MM_GDBUS_TYPE_BEARER_SKELETON)
typedef enum {
@@ -87,6 +89,9 @@ struct _MMBaseBearerPrivate {
/* handler id for the disconnect + cancel connect request */
gulong disconnect_signal_handler;
+ /* Connection status monitoring */
+ guint connection_monitor_id;
+
/*-- 3GPP specific --*/
guint deferred_3gpp_unregistration_id;
/* Reason if 3GPP connection is forbidden */
@@ -136,6 +141,63 @@ mm_base_bearer_export (MMBaseBearer *self)
/*****************************************************************************/
static void
+connection_monitor_stop (MMBaseBearer *self)
+{
+ if (self->priv->connection_monitor_id) {
+ g_source_remove (self->priv->connection_monitor_id);
+ self->priv->connection_monitor_id = 0;
+ }
+}
+
+static void
+load_connection_status_ready (MMBaseBearer *self,
+ GAsyncResult *res)
+{
+ GError *error = NULL;
+ MMBearerConnectionStatus status;
+
+ status = MM_BASE_BEARER_GET_CLASS (self)->load_connection_status_finish (self, res, &error);
+ if (status == MM_BEARER_CONNECTION_STATUS_UNKNOWN) {
+ mm_warn ("checking if connected failed: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* Report connection or disconnection */
+ g_assert (status == MM_BEARER_CONNECTION_STATUS_CONNECTED || status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
+ mm_dbg ("connection status loaded: %s", mm_bearer_connection_status_get_string (status));
+ mm_base_bearer_report_connection_status (self, status);
+}
+
+static gboolean
+connection_monitor_cb (MMBaseBearer *self)
+{
+ /* If the implementation knows how to update stat values, run it */
+ MM_BASE_BEARER_GET_CLASS (self)->load_connection_status (
+ self,
+ (GAsyncReadyCallback)load_connection_status_ready,
+ NULL);
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+connection_monitor_start (MMBaseBearer *self)
+{
+ /* If not implemented, don't schedule anything */
+ if (!MM_BASE_BEARER_GET_CLASS (self)->load_connection_status ||
+ !MM_BASE_BEARER_GET_CLASS (self)->load_connection_status_finish)
+ return;
+
+ /* Schedule */
+ g_assert (!self->priv->connection_monitor_id);
+ self->priv->connection_monitor_id = g_timeout_add_seconds (BEARER_CONNECTION_MONITOR_TIMEOUT,
+ (GSourceFunc) connection_monitor_cb,
+ self);
+}
+
+/*****************************************************************************/
+
+static void
bearer_update_interface_stats (MMBaseBearer *self)
{
mm_gdbus_bearer_set_stats (
@@ -262,6 +324,8 @@ bearer_update_status (MMBaseBearer *self,
bearer_reset_interface_status (self);
/* Stop statistics */
bearer_stats_stop (self);
+ /* Stop connection monitoring */
+ connection_monitor_stop (self);
}
}
@@ -284,6 +348,9 @@ bearer_update_status_connected (MMBaseBearer *self,
/* Start statistics */
bearer_stats_start (self);
+ /* Start connection monitor, if supported */
+ connection_monitor_start (self);
+
/* Update the property value */
self->priv->status = MM_BEARER_STATUS_CONNECTED;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_STATUS]);
@@ -1100,15 +1167,15 @@ static void
report_connection_status (MMBaseBearer *self,
MMBearerConnectionStatus status)
{
- /* The only status expected at this point is DISCONNECTED.
- * No other status should have been given to the generic implementation
- * of report_connection_status (it would be an error).
+ /* The only status expected at this point is DISCONNECTED or CONNECTED,
+ * although here we just process the DISCONNECTED one.
*/
- g_assert (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
+ g_assert (status == MM_BEARER_CONNECTION_STATUS_CONNECTED || status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
/* In the generic bearer implementation we just need to reset the
* interface status */
- bearer_update_status (self, MM_BEARER_STATUS_DISCONNECTED);
+ if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED)
+ bearer_update_status (self, MM_BEARER_STATUS_DISCONNECTED);
}
void
@@ -1264,6 +1331,7 @@ dispose (GObject *object)
{
MMBaseBearer *self = MM_BASE_BEARER (object);
+ connection_monitor_stop (self);
bearer_stats_stop (self);
g_clear_object (&self->priv->stats);
diff --git a/src/mm-base-bearer.h b/src/mm-base-bearer.h
index 58954d40..1e020dc6 100644
--- a/src/mm-base-bearer.h
+++ b/src/mm-base-bearer.h
@@ -101,6 +101,17 @@ struct _MMBaseBearerClass {
GAsyncResult *res,
GError **error);
+ /* Monitor connection status:
+ * NOTE: only CONNECTED or DISCONNECTED should be reported here; this method
+ * is used to poll for connection status once the connection has been
+ * established */
+ void (* load_connection_status) (MMBaseBearer *bearer,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ MMBearerConnectionStatus (* load_connection_status_finish) (MMBaseBearer *bearer,
+ GAsyncResult *res,
+ GError **error);
+
/* Reload statistics */
void (* reload_stats) (MMBaseBearer *bearer,
GAsyncReadyCallback callback,