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.
This commit is contained in:
Aleksander Morgado
2016-10-05 08:21:08 +02:00
parent 61fbab286c
commit 37bd614212
11 changed files with 128 additions and 1 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -534,12 +534,17 @@ static void
mm_broadband_bearer_sierra_class_init (MMBroadbandBearerSierraClass *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;

View File

@@ -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;

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -1909,6 +1909,99 @@ disconnect (MMBaseBearer *self,
g_object_unref (modem);
}
/*****************************************************************************/
/* 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
@@ -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;