summary refs log tree commit diff
path: root/src/core/devices/wwan
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2023-08-09 21:55:35 +0200
committerMichael Biebl <biebl@debian.org>2023-08-09 21:55:35 +0200
commit05e4a733f2141995181a551854d5df929f084adf (patch)
tree83bb937740a6667525ba0df046748ecaa829c269 /src/core/devices/wwan
parent14b0f3a9dc9ea90d60a3b057350fd4d637dc021a (diff)
New upstream version 1.44.0 upstream/1.44.0
Diffstat (limited to 'src/core/devices/wwan')
-rw-r--r--src/core/devices/wwan/nm-device-modem.c7
-rw-r--r--src/core/devices/wwan/nm-modem-broadband.c83
-rw-r--r--src/core/devices/wwan/nm-modem.c31
-rw-r--r--src/core/devices/wwan/nm-modem.h2
4 files changed, 121 insertions, 2 deletions
diff --git a/src/core/devices/wwan/nm-device-modem.c b/src/core/devices/wwan/nm-device-modem.c
index b83120f9..a1050c3f 100644
--- a/src/core/devices/wwan/nm-device-modem.c
+++ b/src/core/devices/wwan/nm-device-modem.c
@@ -383,12 +383,15 @@ get_type_description(NMDevice *device)
 }
 
 static gboolean
-check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error)
+check_connection_compatible(NMDevice     *device,
+                            NMConnection *connection,
+                            gboolean      check_properties,
+                            GError      **error)
 {
     GError *local = NULL;
 
     if (!NM_DEVICE_CLASS(nm_device_modem_parent_class)
-             ->check_connection_compatible(device, connection, error))
+             ->check_connection_compatible(device, connection, check_properties, error))
         return FALSE;
 
     if (!nm_modem_check_connection_compatible(NM_DEVICE_MODEM_GET_PRIVATE(device)->modem,
diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c
index f0907c46..a150040f 100644
--- a/src/core/devices/wwan/nm-modem-broadband.c
+++ b/src/core/devices/wwan/nm-modem-broadband.c
@@ -20,6 +20,8 @@
 
 #define NM_MODEM_BROADBAND_MODEM "modem"
 
+#define MM_SUPPORTS_INITIAL_EPS_BEARER_SETTINGS MM_CHECK_VERSION(1, 10, 0)
+
 #if !MM_CHECK_VERSION(1, 14, 0)
 #define MM_MODEM_CAPABILITY_5GNR ((MMModemCapability) (1 << 6))
 #endif
@@ -44,6 +46,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;
@@ -560,6 +563,36 @@ out:
     return TRUE;
 }
 
+#if MM_SUPPORTS_INITIAL_EPS_BEARER_SETTINGS
+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);
+}
+#endif
+
 static void
 connect_context_step(NMModemBroadband *self)
 {
@@ -629,6 +662,56 @@ 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) {
+#if MM_SUPPORTS_INITIAL_EPS_BEARER_SETTINGS
+                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;
+#else
+                _LOGD("cannot set initial EPS bearer settings due to old ModemManager version");
+#endif
+            }
+        }
+        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 0159d351..ea0fa7aa 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 ec001102..021d77b2 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,