diff options
author | Sven Schwermer <sven.schwermer@disruptive-technologies.com> | 2022-08-09 13:26:41 +0200 |
---|---|---|
committer | Sven Schwermer <sven.schwermer@disruptive-technologies.com> | 2022-12-07 09:07:12 +0100 |
commit | 678a16565a8e9038e54012b25e9ea64d8933be8d (patch) | |
tree | fcde88bf3319f8fa0aff26d52ba4121a3ad42827 | |
parent | 2ab8996bac20bd12c9a0a2fa3c38e11cbd450682 (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.c | 75 | ||||
-rw-r--r-- | src/core/devices/wwan/nm-modem.c | 31 | ||||
-rw-r--r-- | src/core/devices/wwan/nm-modem.h | 2 |
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, |