aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2016-10-05 08:21:08 +0200
committerAleksander Morgado <aleksander@aleksander.es>2016-10-12 11:29:52 +0200
commit37bd61421245de87d2c04852109d2a1b14d338cb (patch)
treec8153517bc4071cf8586fdd6798d264977770133
parent61fbab286c3ab231f7fd16c345cc7e352f33bae4 (diff)
broadband-modem: implement default connection monitoring logic
A default implementation to monitor the ongoing connection is provided in the generic MMBroadbandModem, based on AT+CGACT? to check whether the PDP context of the connection (identified by the cached cid) is active or not. This commit also disables the connection monitoring logic in those plugins that have custom connection methods.
-rw-r--r--plugins/altair/mm-broadband-bearer-altair-lte.c4
-rw-r--r--plugins/huawei/mm-broadband-bearer-huawei.c4
-rw-r--r--plugins/icera/mm-broadband-bearer-icera.c4
-rw-r--r--plugins/iridium/mm-bearer-iridium.c2
-rw-r--r--plugins/mbm/mm-broadband-bearer-mbm.c3
-rw-r--r--plugins/option/mm-broadband-bearer-hso.c3
-rw-r--r--plugins/sierra/mm-broadband-bearer-sierra.c7
-rw-r--r--plugins/ublox/mm-broadband-bearer-ublox.c3
-rw-r--r--src/mm-bearer-mbim.c2
-rw-r--r--src/mm-bearer-qmi.c2
-rw-r--r--src/mm-broadband-bearer.c95
11 files changed, 128 insertions, 1 deletions
diff --git a/plugins/altair/mm-broadband-bearer-altair-lte.c b/plugins/altair/mm-broadband-bearer-altair-lte.c
index 1d188d58..6c59d220 100644
--- a/plugins/altair/mm-broadband-bearer-altair-lte.c
+++ b/plugins/altair/mm-broadband-bearer-altair-lte.c
@@ -409,8 +409,12 @@ mm_broadband_bearer_altair_lte_init (MMBroadbandBearerAltairLte *self)
static void
mm_broadband_bearer_altair_lte_class_init (MMBroadbandBearerAltairLteClass *klass)
{
+ MMBaseBearerClass *base_bearer_class = MM_BASE_BEARER_CLASS (klass);
MMBroadbandBearerClass *broadband_bearer_class = MM_BROADBAND_BEARER_CLASS (klass);
+ base_bearer_class->load_connection_status = NULL;
+ base_bearer_class->load_connection_status_finish = NULL;
+
broadband_bearer_class->connect_3gpp = connect_3gpp;
broadband_bearer_class->connect_3gpp_finish = connect_3gpp_finish;
broadband_bearer_class->disconnect_3gpp = disconnect_3gpp;
diff --git a/plugins/huawei/mm-broadband-bearer-huawei.c b/plugins/huawei/mm-broadband-bearer-huawei.c
index 60a91e55..124b8ed1 100644
--- a/plugins/huawei/mm-broadband-bearer-huawei.c
+++ b/plugins/huawei/mm-broadband-bearer-huawei.c
@@ -921,7 +921,11 @@ mm_broadband_bearer_huawei_class_init (MMBroadbandBearerHuaweiClass *klass)
g_type_class_add_private (object_class, sizeof (MMBroadbandBearerHuaweiPrivate));
object_class->dispose = dispose;
+
base_bearer_class->report_connection_status = report_connection_status;
+ base_bearer_class->load_connection_status = NULL;
+ base_bearer_class->load_connection_status_finish = NULL;
+
broadband_bearer_class->connect_3gpp = connect_3gpp;
broadband_bearer_class->connect_3gpp_finish = connect_3gpp_finish;
broadband_bearer_class->disconnect_3gpp = disconnect_3gpp;
diff --git a/plugins/icera/mm-broadband-bearer-icera.c b/plugins/icera/mm-broadband-bearer-icera.c
index ec5779cd..c08acc4f 100644
--- a/plugins/icera/mm-broadband-bearer-icera.c
+++ b/plugins/icera/mm-broadband-bearer-icera.c
@@ -1091,7 +1091,11 @@ mm_broadband_bearer_icera_class_init (MMBroadbandBearerIceraClass *klass)
object_class->get_property = get_property;
object_class->set_property = set_property;
+
base_bearer_class->report_connection_status = report_connection_status;
+ base_bearer_class->load_connection_status = NULL;
+ base_bearer_class->load_connection_status_finish = NULL;
+
broadband_bearer_class->dial_3gpp = dial_3gpp;
broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
broadband_bearer_class->get_ip_config_3gpp = get_ip_config_3gpp;
diff --git a/plugins/iridium/mm-bearer-iridium.c b/plugins/iridium/mm-bearer-iridium.c
index fd54647d..a7e50a46 100644
--- a/plugins/iridium/mm-bearer-iridium.c
+++ b/plugins/iridium/mm-bearer-iridium.c
@@ -270,4 +270,6 @@ mm_bearer_iridium_class_init (MMBearerIridiumClass *klass)
/* Virtual methods */
base_bearer_class->connect = connect;
base_bearer_class->connect_finish = connect_finish;
+ base_bearer_class->load_connection_status = NULL;
+ base_bearer_class->load_connection_status_finish = NULL;
}
diff --git a/plugins/mbm/mm-broadband-bearer-mbm.c b/plugins/mbm/mm-broadband-bearer-mbm.c
index 19660464..0fea7190 100644
--- a/plugins/mbm/mm-broadband-bearer-mbm.c
+++ b/plugins/mbm/mm-broadband-bearer-mbm.c
@@ -840,6 +840,9 @@ mm_broadband_bearer_mbm_class_init (MMBroadbandBearerMbmClass *klass)
g_type_class_add_private (object_class, sizeof (MMBroadbandBearerMbmPrivate));
base_bearer_class->report_connection_status = report_connection_status;
+ base_bearer_class->load_connection_status = NULL;
+ base_bearer_class->load_connection_status_finish = NULL;
+
broadband_bearer_class->dial_3gpp = dial_3gpp;
broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
broadband_bearer_class->get_ip_config_3gpp = get_ip_config_3gpp;
diff --git a/plugins/option/mm-broadband-bearer-hso.c b/plugins/option/mm-broadband-bearer-hso.c
index 275dff83..746f96e5 100644
--- a/plugins/option/mm-broadband-bearer-hso.c
+++ b/plugins/option/mm-broadband-bearer-hso.c
@@ -844,6 +844,9 @@ mm_broadband_bearer_hso_class_init (MMBroadbandBearerHsoClass *klass)
g_type_class_add_private (object_class, sizeof (MMBroadbandBearerHsoPrivate));
base_bearer_class->report_connection_status = report_connection_status;
+ base_bearer_class->load_connection_status = NULL;
+ base_bearer_class->load_connection_status_finish = NULL;
+
broadband_bearer_class->dial_3gpp = dial_3gpp;
broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
broadband_bearer_class->get_ip_config_3gpp = get_ip_config_3gpp;
diff --git a/plugins/sierra/mm-broadband-bearer-sierra.c b/plugins/sierra/mm-broadband-bearer-sierra.c
index 0d872199..1f590a37 100644
--- a/plugins/sierra/mm-broadband-bearer-sierra.c
+++ b/plugins/sierra/mm-broadband-bearer-sierra.c
@@ -533,13 +533,18 @@ mm_broadband_bearer_sierra_init (MMBroadbandBearerSierra *self)
static void
mm_broadband_bearer_sierra_class_init (MMBroadbandBearerSierraClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ MMBaseBearerClass *base_bearer_class = MM_BASE_BEARER_CLASS (klass);
MMBroadbandBearerClass *broadband_bearer_class = MM_BROADBAND_BEARER_CLASS (klass);
g_type_class_add_private (object_class, sizeof (MMBroadbandBearerSierraPrivate));
object_class->set_property = set_property;
object_class->get_property = get_property;
+
+ base_bearer_class->load_connection_status = NULL;
+ base_bearer_class->load_connection_status_finish = NULL;
+
broadband_bearer_class->dial_3gpp = dial_3gpp;
broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
broadband_bearer_class->disconnect_3gpp = disconnect_3gpp;
diff --git a/plugins/ublox/mm-broadband-bearer-ublox.c b/plugins/ublox/mm-broadband-bearer-ublox.c
index 0621780c..bef7a53d 100644
--- a/plugins/ublox/mm-broadband-bearer-ublox.c
+++ b/plugins/ublox/mm-broadband-bearer-ublox.c
@@ -544,6 +544,9 @@ mm_broadband_bearer_ublox_class_init (MMBroadbandBearerUbloxClass *klass)
object_class->get_property = get_property;
object_class->set_property = set_property;
+ /* Note: the ublox plugin uses the generic AT+CGACT? based check to monitor
+ * the connection status (i.e. default load_connection_status()) */
+
broadband_bearer_class->disconnect_3gpp = disconnect_3gpp;
broadband_bearer_class->disconnect_3gpp_finish = disconnect_3gpp_finish;
broadband_bearer_class->dial_3gpp = dial_3gpp;
diff --git a/src/mm-bearer-mbim.c b/src/mm-bearer-mbim.c
index 5db5f32a..44c1c861 100644
--- a/src/mm-bearer-mbim.c
+++ b/src/mm-bearer-mbim.c
@@ -1375,6 +1375,8 @@ mm_bearer_mbim_class_init (MMBearerMbimClass *klass)
base_bearer_class->report_connection_status = report_connection_status;
base_bearer_class->reload_stats = reload_stats;
base_bearer_class->reload_stats_finish = reload_stats_finish;
+ base_bearer_class->load_connection_status = NULL;
+ base_bearer_class->load_connection_status_finish = NULL;
properties[PROP_SESSION_ID] =
g_param_spec_uint (MM_BEARER_MBIM_SESSION_ID,
diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c
index 1e507659..40bfa8cb 100644
--- a/src/mm-bearer-qmi.c
+++ b/src/mm-bearer-qmi.c
@@ -1674,4 +1674,6 @@ mm_bearer_qmi_class_init (MMBearerQmiClass *klass)
base_bearer_class->report_connection_status = report_connection_status;
base_bearer_class->reload_stats = reload_stats;
base_bearer_class->reload_stats_finish = reload_stats_finish;
+ base_bearer_class->load_connection_status = NULL;
+ base_bearer_class->load_connection_status_finish = NULL;
}
diff --git a/src/mm-broadband-bearer.c b/src/mm-broadband-bearer.c
index 24e36b82..eb8ce198 100644
--- a/src/mm-broadband-bearer.c
+++ b/src/mm-broadband-bearer.c
@@ -1910,6 +1910,99 @@ disconnect (MMBaseBearer *self,
}
/*****************************************************************************/
+/* Connection status monitoring */
+
+static MMBearerConnectionStatus
+load_connection_status_finish (MMBaseBearer *bearer,
+ GAsyncResult *res,
+ GError **error)
+{
+ gssize value;
+
+ value = g_task_propagate_int (G_TASK (res), error);
+ return (value < 0 ? MM_BEARER_CONNECTION_STATUS_UNKNOWN : (MMBearerConnectionStatus) value);
+}
+
+static void
+cgact_periodic_query_ready (MMBaseModem *modem,
+ GAsyncResult *res,
+ GTask *task)
+{
+ MMBroadbandBearer *self;
+ const gchar *response;
+ GError *error = NULL;
+ GList *pdp_active_list = NULL;
+ GList *l;
+ MMBearerConnectionStatus status = MM_BEARER_CONNECTION_STATUS_UNKNOWN;
+
+ self = MM_BROADBAND_BEARER (g_task_get_source_object (task));
+
+ response = mm_base_modem_at_command_finish (modem, res, &error);
+ if (response)
+ pdp_active_list = mm_3gpp_parse_cgact_read_response (response, &error);
+
+ if (error) {
+ g_assert (!pdp_active_list);
+ g_prefix_error (&error, "Couldn't check current list of active PDP contexts: ");
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ for (l = pdp_active_list; l; l = g_list_next (l)) {
+ MM3gppPdpContextActive *pdp_active;
+
+ /* We look for he just assume the first active PDP context found is the one we're
+ * looking for. */
+ pdp_active = (MM3gppPdpContextActive *)(l->data);
+ if (pdp_active->cid == self->priv->cid) {
+ status = (pdp_active->active ? MM_BEARER_CONNECTION_STATUS_CONNECTED : MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
+ break;
+ }
+ }
+ mm_3gpp_pdp_context_active_list_free (pdp_active_list);
+
+ /* PDP context not found? This shouldn't happen, error out */
+ if (status == MM_BEARER_CONNECTION_STATUS_UNKNOWN)
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "PDP context not found in the known contexts list");
+ else
+ g_task_return_int (task, (gssize) status);
+ g_object_unref (task);
+}
+
+static void
+load_connection_status (MMBaseBearer *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ MMBaseModem *modem = NULL;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ if (!MM_BROADBAND_BEARER (self)->priv->cid) {
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Couldn't load connection status: cid not defined");
+ g_object_unref (task);
+ return;
+ }
+
+ g_object_get (MM_BASE_BEARER (self),
+ MM_BASE_BEARER_MODEM, &modem,
+ NULL);
+
+ mm_base_modem_at_command (MM_BASE_MODEM (modem),
+ "+CGACT?",
+ 3,
+ FALSE,
+ (GAsyncReadyCallback) cgact_periodic_query_ready,
+ task);
+
+ g_object_unref (modem);
+}
+
+/*****************************************************************************/
static void
report_connection_status (MMBaseBearer *self,
@@ -2184,6 +2277,8 @@ mm_broadband_bearer_class_init (MMBroadbandBearerClass *klass)
base_bearer_class->disconnect = disconnect;
base_bearer_class->disconnect_finish = disconnect_finish;
base_bearer_class->report_connection_status = report_connection_status;
+ base_bearer_class->load_connection_status = load_connection_status;
+ base_bearer_class->load_connection_status_finish = load_connection_status_finish;
klass->connect_3gpp = connect_3gpp;
klass->connect_3gpp_finish = detailed_connect_finish;