summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Schwermer <sven.schwermer@disruptive-technologies.com>2022-08-09 13:26:41 +0200
committerSven Schwermer <sven.schwermer@disruptive-technologies.com>2022-12-07 09:07:12 +0100
commit678a16565a8e9038e54012b25e9ea64d8933be8d (patch)
treefcde88bf3319f8fa0aff26d52ba4121a3ad42827
parent2ab8996bac20bd12c9a0a2fa3c38e11cbd450682 (diff)
wwan: Set initial EPS bearer settingsth/pr/1331
Signed-off-by: Sven Schwermer <sven.schwermer@disruptive-technologies.com>
-rw-r--r--src/core/devices/wwan/nm-modem-broadband.c75
-rw-r--r--src/core/devices/wwan/nm-modem.c31
-rw-r--r--src/core/devices/wwan/nm-modem.h2
3 files changed, 108 insertions, 0 deletions
diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c
index 556df83198..976e51b427 100644
--- a/src/core/devices/wwan/nm-modem-broadband.c
+++ b/src/core/devices/wwan/nm-modem-broadband.c
@@ -44,6 +44,7 @@ typedef enum {
CONNECT_STEP_WAIT_FOR_SIM,
CONNECT_STEP_UNLOCK,
CONNECT_STEP_WAIT_FOR_READY,
+ CONNECT_STEP_INTIAL_EPS_BEARER,
CONNECT_STEP_CONNECT,
CONNECT_STEP_LAST,
} ConnectStep;
@@ -561,6 +562,34 @@ out:
}
static void
+set_initial_eps_bearer_settings_ready(MMModem3gpp *modem_3gpp_iface,
+ GAsyncResult *res,
+ NMModemBroadband *self)
+{
+ gs_free_error GError *error = NULL;
+
+ if (!mm_modem_3gpp_set_initial_eps_bearer_settings_finish(modem_3gpp_iface, res, &error)) {
+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ if (!g_error_matches(error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED)) {
+ _LOGW("failed to set initial EPS bearer settings: %s", error->message);
+ nm_modem_emit_prepare_result(NM_MODEM(self),
+ FALSE,
+ NM_DEVICE_STATE_REASON_GSM_APN_FAILED);
+ connect_context_clear(self);
+ return;
+ }
+
+ _LOGD("failed to set initial EPS bearer settings due to lack of support: %s",
+ error->message);
+ }
+
+ self->_priv.ctx->step++;
+ connect_context_step(self);
+}
+
+static void
connect_context_step(NMModemBroadband *self)
{
ConnectContext *ctx = self->_priv.ctx;
@@ -629,6 +658,52 @@ connect_context_step(NMModemBroadband *self)
ctx->step++;
}
/* fall-through */
+
+ case CONNECT_STEP_INTIAL_EPS_BEARER:
+ if (MODEM_CAPS_3GPP(ctx->caps)) {
+ NMSettingGsm *s_gsm = nm_connection_get_setting_gsm(ctx->connection);
+ const char *apn = nm_setting_gsm_get_initial_eps_apn(s_gsm);
+ gboolean do_config = nm_setting_gsm_get_initial_eps_config(s_gsm);
+
+ /* assume do_config is true if an APN is set */
+ if (apn || do_config) {
+ gs_unref_object MMBearerProperties *config = NULL;
+ NMModemIPType ip_type = nm_modem_get_initial_eps_bearer_ip_type(ctx->ip_types);
+
+ config = mm_bearer_properties_new();
+ switch (ip_type) {
+ case NM_MODEM_IP_TYPE_IPV4:
+ mm_bearer_properties_set_ip_type(config, MM_BEARER_IP_FAMILY_IPV4);
+ break;
+ case NM_MODEM_IP_TYPE_IPV6:
+ mm_bearer_properties_set_ip_type(config, MM_BEARER_IP_FAMILY_IPV6);
+ break;
+ case NM_MODEM_IP_TYPE_IPV4V6:
+ mm_bearer_properties_set_ip_type(config, MM_BEARER_IP_FAMILY_IPV4V6);
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+ if (apn)
+ mm_bearer_properties_set_apn(config, apn);
+
+ /*
+ * Setting the initial EPS bearer settings is a no-op in
+ * ModemManager if the desired configuration is already active.
+ */
+ mm_modem_3gpp_set_initial_eps_bearer_settings(
+ self->_priv.modem_3gpp_iface,
+ config,
+ ctx->cancellable,
+ (GAsyncReadyCallback) set_initial_eps_bearer_settings_ready,
+ self);
+ break;
+ }
+ }
+ ctx->step++;
+ /* fall-through */
+
case CONNECT_STEP_CONNECT:
if (!ctx->connect_properties)
break;
diff --git a/src/core/devices/wwan/nm-modem.c b/src/core/devices/wwan/nm-modem.c
index 0159d35109..ea0fa7aac5 100644
--- a/src/core/devices/wwan/nm-modem.c
+++ b/src/core/devices/wwan/nm-modem.c
@@ -558,6 +558,37 @@ nm_modem_get_connection_ip_type(NMModem *self, NMConnection *connection, GError
return NULL;
}
+/**
+ * nm_modem_get_initial_eps_bearer_ip_type:
+ * @connection_ip_types: the #NMModemIPType as returned by
+ * nm_modem_get_connection_ip_type
+ *
+ * Given the connection IP types, this function returns which IP type to use when
+ * configuring the initial EPS bearer.
+ *
+ * Returns: the #NMModemIpType value to use for the initial EPS bearer
+ */
+NMModemIPType
+nm_modem_get_initial_eps_bearer_ip_type(const GArray *connection_ip_types)
+{
+ NMModemIPType ip_types = NM_MODEM_IP_TYPE_UNKNOWN;
+ guint i;
+
+ nm_assert(connection_ip_types);
+
+ for (i = 0; i < connection_ip_types->len; i++)
+ ip_types |= nm_g_array_index(connection_ip_types, NMModemIPType, i);
+
+ nm_assert(ip_types != NM_MODEM_IP_TYPE_UNKNOWN);
+
+ if (ip_types & NM_MODEM_IP_TYPE_IPV4V6)
+ return NM_MODEM_IP_TYPE_IPV4V6;
+ if (ip_types & NM_MODEM_IP_TYPE_IPV4)
+ return NM_MODEM_IP_TYPE_IPV4;
+
+ return NM_MODEM_IP_TYPE_IPV6;
+}
+
const char *
nm_modem_get_device_id(NMModem *self)
{
diff --git a/src/core/devices/wwan/nm-modem.h b/src/core/devices/wwan/nm-modem.h
index ca5410738c..a19dbfc742 100644
--- a/src/core/devices/wwan/nm-modem.h
+++ b/src/core/devices/wwan/nm-modem.h
@@ -226,6 +226,8 @@ void nm_modem_emit_ppp_failed(NMModem *self, NMDeviceStateReason reason);
GArray *nm_modem_get_connection_ip_type(NMModem *self, NMConnection *connection, GError **error);
+NMModemIPType nm_modem_get_initial_eps_bearer_ip_type(const GArray *connection_ip_types);
+
/* For subclasses */
void nm_modem_emit_signal_new_config(NMModem *self,