aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-base-bearer.c28
-rw-r--r--src/mm-broadband-modem.c37
-rw-r--r--src/mm-iface-modem-3gpp.c107
-rw-r--r--src/mm-iface-modem-3gpp.h16
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,