diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-base-bearer.c | 28 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 37 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.c | 107 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.h | 16 |
4 files changed, 183 insertions, 5 deletions
diff --git a/src/mm-base-bearer.c b/src/mm-base-bearer.c index b2e07e19..6b7e1e5d 100644 --- a/src/mm-base-bearer.c +++ b/src/mm-base-bearer.c @@ -764,8 +764,18 @@ mm_base_bearer_connect (MMBaseBearer *self, { GTask *task; - g_assert (MM_BASE_BEARER_GET_CLASS (self)->connect != NULL); - g_assert (MM_BASE_BEARER_GET_CLASS (self)->connect_finish != NULL); + if (!MM_BASE_BEARER_GET_CLASS (self)->connect) { + g_assert (!MM_BASE_BEARER_GET_CLASS (self)->connect_finish); + g_task_report_new_error ( + self, + callback, + user_data, + mm_base_bearer_connect, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Bearer doesn't allow explicit connection requests"); + return; + } /* If already connecting, return error, don't allow a second request. */ if (self->priv->status == MM_BEARER_STATUS_CONNECTING) { @@ -975,11 +985,19 @@ mm_base_bearer_disconnect (MMBaseBearer *self, { GTask *task; - g_assert (MM_BASE_BEARER_GET_CLASS (self)->disconnect != NULL); - g_assert (MM_BASE_BEARER_GET_CLASS (self)->disconnect_finish != NULL); - task = g_task_new (self, NULL, callback, user_data); + if (!MM_BASE_BEARER_GET_CLASS (self)->disconnect) { + g_assert (!MM_BASE_BEARER_GET_CLASS (self)->disconnect_finish); + g_task_return_new_error ( + task, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Bearer doesn't allow explicit disconnection requests"); + g_object_unref (task); + return; + } + /* If already disconnected, done */ if (self->priv->status == MM_BEARER_STATUS_DISCONNECTED) { g_task_return_boolean (task, TRUE); diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 7c7250e6..952bc30a 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -106,6 +106,7 @@ enum { PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED, PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED, PROP_MODEM_3GPP_IGNORED_FACILITY_LOCKS, + PROP_MODEM_3GPP_INITIAL_EPS_BEARER, PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE, PROP_MODEM_CDMA_EVDO_REGISTRATION_STATE, PROP_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED, @@ -171,6 +172,7 @@ struct _MMBroadbandModemPrivate { /* Implementation helpers */ GPtrArray *modem_3gpp_registration_regex; MMModem3gppFacility modem_3gpp_ignored_facility_locks; + MMBaseBearer *modem_3gpp_initial_eps_bearer; /*<--- Modem 3GPP USSD interface --->*/ /* Properties */ @@ -4870,6 +4872,28 @@ modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self, } /*****************************************************************************/ +/* Create initial EPS bearer object */ + +static MMBaseBearer * +modem_3gpp_create_initial_eps_bearer (MMIfaceModem3gpp *self, + MMBearerProperties *config) +{ + MMBaseBearer *bearer; + + /* NOTE: by default we create a bearer object that is CONNECTED but which doesn't + * have an associated data interface already set. This is so that upper layers don't + * attempt connection through this bearer object. */ + bearer = g_object_new (MM_TYPE_BASE_BEARER, + MM_BASE_BEARER_MODEM, MM_BASE_MODEM (self), + MM_BASE_BEARER_CONFIG, config, + "bearer-type", MM_BEARER_TYPE_DEFAULT_ATTACH, + "connected", TRUE, + NULL); + mm_base_bearer_export (bearer); + return bearer; +} + +/*****************************************************************************/ /* Enable/Disable unsolicited registration events (3GPP interface) */ typedef struct { @@ -11117,6 +11141,10 @@ set_property (GObject *object, case PROP_MODEM_3GPP_IGNORED_FACILITY_LOCKS: self->priv->modem_3gpp_ignored_facility_locks = g_value_get_flags (value); break; + case PROP_MODEM_3GPP_INITIAL_EPS_BEARER: + g_clear_object (&self->priv->modem_3gpp_initial_eps_bearer); + self->priv->modem_3gpp_initial_eps_bearer = g_value_dup_object (value); + break; case PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE: self->priv->modem_cdma_cdma1x_registration_state = g_value_get_enum (value); break; @@ -11234,6 +11262,9 @@ get_property (GObject *object, case PROP_MODEM_3GPP_IGNORED_FACILITY_LOCKS: g_value_set_flags (value, self->priv->modem_3gpp_ignored_facility_locks); break; + case PROP_MODEM_3GPP_INITIAL_EPS_BEARER: + g_value_set_object (value, self->priv->modem_3gpp_initial_eps_bearer); + break; case PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE: g_value_set_enum (value, self->priv->modem_cdma_cdma1x_registration_state); break; @@ -11381,6 +11412,7 @@ dispose (GObject *object) g_clear_object (&self->priv->modem_simple_dbus_skeleton); } + g_clear_object (&self->priv->modem_3gpp_initial_eps_bearer); g_clear_object (&self->priv->modem_sim); g_clear_object (&self->priv->modem_bearer_list); g_clear_object (&self->priv->modem_messaging_sms_list); @@ -11489,6 +11521,7 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface) iface->scan_networks_finish = modem_3gpp_scan_networks_finish; iface->set_eps_ue_mode_operation = modem_3gpp_set_eps_ue_mode_operation; iface->set_eps_ue_mode_operation_finish = modem_3gpp_set_eps_ue_mode_operation_finish; + iface->create_initial_eps_bearer = modem_3gpp_create_initial_eps_bearer; } static void @@ -11745,6 +11778,10 @@ mm_broadband_modem_class_init (MMBroadbandModemClass *klass) MM_IFACE_MODEM_3GPP_IGNORED_FACILITY_LOCKS); g_object_class_override_property (object_class, + PROP_MODEM_3GPP_INITIAL_EPS_BEARER, + MM_IFACE_MODEM_3GPP_INITIAL_EPS_BEARER); + + g_object_class_override_property (object_class, PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE, MM_IFACE_MODEM_CDMA_CDMA1X_REGISTRATION_STATE); diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c index 9e626126..a90c7204 100644 --- a/src/mm-iface-modem-3gpp.c +++ b/src/mm-iface-modem-3gpp.c @@ -1488,11 +1488,56 @@ mm_iface_modem_3gpp_update_pco_list (MMIfaceModem3gpp *self, /*****************************************************************************/ +void +mm_iface_modem_3gpp_update_initial_eps_bearer (MMIfaceModem3gpp *self, + MMBearerProperties *properties) +{ + MmGdbusModem3gpp *skeleton = NULL; + MMBaseBearer *attach = NULL; + gboolean skip_update = FALSE; + + g_object_get (self, + MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton, + MM_IFACE_MODEM_3GPP_INITIAL_EPS_BEARER, &attach, + NULL); + g_assert (skeleton); + + if (attach) { + skip_update = (properties && mm_bearer_properties_cmp (properties, mm_base_bearer_peek_config (MM_BASE_BEARER (attach)))); + g_object_unref (attach); + } + + if (skip_update) { + mm_dbg ("skipping initial EPS bearer update: configuration didn't change"); + } else if (properties) { + mm_dbg ("updating initial EPS bearer..."); + + g_assert (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->create_initial_eps_bearer); + attach = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->create_initial_eps_bearer (self, properties); + g_object_set (self, + MM_IFACE_MODEM_3GPP_INITIAL_EPS_BEARER, attach, + NULL); + mm_gdbus_modem3gpp_set_initial_eps_bearer (skeleton, mm_base_bearer_get_path (attach)); + g_object_unref (attach); + } else { + mm_dbg ("clearing initial EPS bearer..."); + g_object_set (self, + MM_IFACE_MODEM_3GPP_INITIAL_EPS_BEARER, NULL, + NULL); + mm_gdbus_modem3gpp_set_initial_eps_bearer (skeleton, NULL); + } + + g_object_unref (skeleton); +} + +/*****************************************************************************/ + typedef struct _DisablingContext DisablingContext; static void interface_disabling_step (GTask *task); typedef enum { DISABLING_STEP_FIRST, + DISABLING_STEP_INITIAL_EPS_BEARER, DISABLING_STEP_PERIODIC_REGISTRATION_CHECKS, DISABLING_STEP_DISABLE_UNSOLICITED_REGISTRATION_EVENTS, DISABLING_STEP_CLEANUP_UNSOLICITED_REGISTRATION_EVENTS, @@ -1568,6 +1613,11 @@ interface_disabling_step (GTask *task) /* Fall down to next step */ ctx->step++; + case DISABLING_STEP_INITIAL_EPS_BEARER: + mm_iface_modem_3gpp_update_initial_eps_bearer (self, NULL); + /* Fall down to next step */ + ctx->step++; + case DISABLING_STEP_PERIODIC_REGISTRATION_CHECKS: /* Disable periodic registration checks, if they were set */ periodic_registration_check_disable (self); @@ -1693,6 +1743,7 @@ typedef enum { ENABLING_STEP_ENABLE_UNSOLICITED_EVENTS, ENABLING_STEP_SETUP_UNSOLICITED_REGISTRATION_EVENTS, ENABLING_STEP_ENABLE_UNSOLICITED_REGISTRATION_EVENTS, + ENABLING_STEP_INITIAL_EPS_BEARER, ENABLING_STEP_LAST } EnablingStep; @@ -1820,6 +1871,33 @@ enable_unsolicited_registration_events_ready (MMIfaceModem3gpp *self, } static void +load_initial_eps_bearer_ready (MMIfaceModem3gpp *self, + GAsyncResult *res, + GTask *task) +{ + MMBearerProperties *properties; + EnablingContext *ctx; + GError *error = NULL; + + ctx = g_task_get_task_data (task); + + properties = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer_finish (self, res, &error); + if (!properties) { + mm_dbg ("couldn't load initial default bearer properties: '%s'", error->message); + g_error_free (error); + goto out; + } + + mm_iface_modem_3gpp_update_initial_eps_bearer (self, properties); + g_object_unref (properties); + +out: + /* Go on to next step */ + ctx->step++; + interface_enabling_step (task); +} + +static void interface_enabling_step (GTask *task) { MMIfaceModem3gpp *self; @@ -1901,6 +1979,26 @@ interface_enabling_step (GTask *task) ctx->step++; } + case ENABLING_STEP_INITIAL_EPS_BEARER: { + gboolean eps_supported = FALSE; + + g_object_get (self, + MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, &eps_supported, + NULL); + + if (eps_supported && + MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer && + MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer_finish) { + MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer ( + self, + (GAsyncReadyCallback)load_initial_eps_bearer_ready, + task); + return; + } + /* Fall down to next step */ + ctx->step++; + } + case ENABLING_STEP_LAST: /* We are done without errors! */ g_task_return_boolean (task, TRUE); @@ -2191,6 +2289,7 @@ mm_iface_modem_3gpp_initialize (MMIfaceModem3gpp *self, mm_gdbus_modem3gpp_set_enabled_facility_locks (skeleton, MM_MODEM_3GPP_FACILITY_NONE); mm_gdbus_modem3gpp_set_subscription_state (skeleton, MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN); mm_gdbus_modem3gpp_set_pco (skeleton, NULL); + mm_gdbus_modem3gpp_set_initial_eps_bearer (skeleton, NULL); /* Bind our RegistrationState property */ g_object_bind_property (self, MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, @@ -2301,6 +2400,14 @@ iface_modem_3gpp_init (gpointer g_iface) MM_MODEM_3GPP_FACILITY_NONE, G_PARAM_READWRITE)); + g_object_interface_install_property + (g_iface, + g_param_spec_object (MM_IFACE_MODEM_3GPP_INITIAL_EPS_BEARER, + "Initial EPS bearer", + "Initial EPS bearer setup during registration", + MM_TYPE_BASE_BEARER, + G_PARAM_READWRITE)); + initialized = TRUE; } diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h index 920d01a0..90b3eedd 100644 --- a/src/mm-iface-modem-3gpp.h +++ b/src/mm-iface-modem-3gpp.h @@ -21,6 +21,7 @@ #define _LIBMM_INSIDE_MM #include <libmm-glib.h> +#include "mm-base-bearer.h" #include "mm-port-serial-at.h" #define MM_TYPE_IFACE_MODEM_3GPP (mm_iface_modem_3gpp_get_type ()) @@ -34,6 +35,7 @@ #define MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED "iface-modem-3gpp-ps-network-supported" #define MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED "iface-modem-3gpp-eps-network-supported" #define MM_IFACE_MODEM_3GPP_IGNORED_FACILITY_LOCKS "iface-modem-3gpp-ignored-facility-locks" +#define MM_IFACE_MODEM_3GPP_INITIAL_EPS_BEARER "iface-modem-3gpp-initial-eps-bearer" #define MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK \ (MM_MODEM_ACCESS_TECHNOLOGY_GSM | \ @@ -145,6 +147,18 @@ struct _MMIfaceModem3gpp { GAsyncResult *res, GError **error); + /* Asynchronous initial default EPS bearer loading */ + void (*load_initial_eps_bearer) (MMIfaceModem3gpp *self, + GAsyncReadyCallback callback, + gpointer user_data); + MMBearerProperties * (*load_initial_eps_bearer_finish) (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error); + + /* Create initial default EPS bearer object */ + MMBaseBearer * (*create_initial_eps_bearer) (MMIfaceModem3gpp *self, + MMBearerProperties *properties); + /* Run CS/PS/EPS registration state checks.. * Note that no registration state is returned, implementations should call * mm_iface_modem_3gpp_update_registration_state(). */ @@ -253,6 +267,8 @@ void mm_iface_modem_3gpp_update_location (MMIfaceModem3gpp *self, gulong cell_id); void mm_iface_modem_3gpp_update_pco_list (MMIfaceModem3gpp *self, const GList *pco_list); +void mm_iface_modem_3gpp_update_initial_eps_bearer (MMIfaceModem3gpp *self, + MMBearerProperties *properties); /* Run all registration checks */ void mm_iface_modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self, |