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:
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user