summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2019-03-18 15:01:38 +0100
committerLubomir Rintel <lkundrak@v3.sk>2019-09-11 14:32:05 +0200
commit7c53930ceb1561182deb8f47dd9927e049fc396d (patch)
treee005df8fb2ef256f63d4f28cab8898d046623c1e
parent0d44b640fcd120c0661f8fbaf98a5b80c0490b60 (diff)
downloadNetworkManager-lr/gsm-default-apn.tar.gz
wwan/modem-broadband: add capability to look up default APN/username/passwordlr/gsm-default-apn
This allows the GSM connection to Just Work most of the time, as in: "nmcli d connect ttyUSB0".
-rw-r--r--config.h.meson3
-rw-r--r--configure.ac10
-rwxr-xr-xcontrib/fedora/REQUIRED_PACKAGES1
-rw-r--r--contrib/fedora/rpm/NetworkManager.spec3
-rw-r--r--meson.build3
-rw-r--r--src/devices/wwan/nm-modem-broadband.c135
6 files changed, 127 insertions, 28 deletions
diff --git a/config.h.meson b/config.h.meson
index a8c694011f..7ba9f9af56 100644
--- a/config.h.meson
+++ b/config.h.meson
@@ -73,6 +73,9 @@
/* Define to path of the kernel firmware directory */
#mesondefine KERNEL_FIRMWARE_DIR
+/* Mobile Broadband Service Provider Information Database location */
+#mesondefine MOBILE_BROADBAND_PROVIDER_INFO_DATABASE
+
/* Path to netconfig */
#mesondefine NETCONFIG_PATH
diff --git a/configure.ac b/configure.ac
index 951f51b9a0..68507e2884 100644
--- a/configure.ac
+++ b/configure.ac
@@ -747,10 +747,20 @@ if (test "${with_modem_manager_1}" != "no"); then
fi
else
with_modem_manager_1="yes"
+
+ PKG_CHECK_MODULES(MOBILE_BROADBAND_PROVIDER_INFO, [mobile-broadband-provider-info],
+ [MOBILE_BROADBAND_PROVIDER_INFO_DATABASE=`$PKG_CONFIG --variable=database mobile-broadband-provider-info`],
+ [MOBILE_BROADBAND_PROVIDER_INFO_DATABASE="$prefix/share/mobile-broadband-provider-info/serviceproviders.xml"])
+ AC_DEFINE_UNQUOTED([MOBILE_BROADBAND_PROVIDER_INFO_DATABASE],
+ ["$MOBILE_BROADBAND_PROVIDER_INFO_DATABASE"],
+ [Mobile Broadband Service Provider Information Database location])
fi
fi
AM_CONDITIONAL(WITH_MODEM_MANAGER_1, test "${with_modem_manager_1}" = "yes")
+
+
+
# Bluez5 DUN support
PKG_CHECK_MODULES(BLUEZ5, [bluez >= 5], [have_bluez5=yes],[have_bluez5=no])
AC_ARG_ENABLE(bluez5-dun,
diff --git a/contrib/fedora/REQUIRED_PACKAGES b/contrib/fedora/REQUIRED_PACKAGES
index 00164cc669..7579e9a983 100755
--- a/contrib/fedora/REQUIRED_PACKAGES
+++ b/contrib/fedora/REQUIRED_PACKAGES
@@ -22,6 +22,7 @@ install \
\
ModemManager-devel \
ModemManager-glib-devel \
+ mobile-broadband-provider-info-devel \
audit-libs-devel \
bash-completion \
bluez-libs-devel \
diff --git a/contrib/fedora/rpm/NetworkManager.spec b/contrib/fedora/rpm/NetworkManager.spec
index b7957d602c..4eddef793a 100644
--- a/contrib/fedora/rpm/NetworkManager.spec
+++ b/contrib/fedora/rpm/NetworkManager.spec
@@ -219,6 +219,9 @@ BuildRequires: libndp-devel >= 1.0
%if 0%{?with_modem_manager_1}
BuildRequires: ModemManager-glib-devel >= 1.0
%endif
+%if %{with wwan}
+BuildRequires: mobile-broadband-provider-info-devel
+%endif
%if %{with nmtui}
BuildRequires: newt-devel
%endif
diff --git a/meson.build b/meson.build
index 9fc9ad2684..db0fcbd29f 100644
--- a/meson.build
+++ b/meson.build
@@ -502,6 +502,9 @@ config_h.set10('WITH_PPP', enable_ppp)
enable_modem_manager = get_option('modem_manager')
if enable_modem_manager
mm_glib_dep = dependency('mm-glib', version: '>= 0.7.991')
+
+ service_provider_db = dependency('mobile-broadband-provider-info').get_pkgconfig_variable('database')
+ config_h.set_quoted('MOBILE_BROADBAND_PROVIDER_INFO_DATABASE', service_provider_db)
endif
# Bluez5 DUN support
diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c
index a9239fca34..820c343a31 100644
--- a/src/devices/wwan/nm-modem-broadband.c
+++ b/src/devices/wwan/nm-modem-broadband.c
@@ -7,6 +7,7 @@
#include "nm-default.h"
#include "nm-modem-broadband.h"
+#include "nm-service-providers.h"
#include <arpa/inet.h>
#include <libmm-glib.h>
@@ -261,7 +262,10 @@ create_cdma_connect_properties (NMConnection *connection)
}
static MMSimpleConnectProperties *
-create_gsm_connect_properties (NMConnection *connection)
+create_gsm_connect_properties (NMConnection *connection,
+ const char *apn,
+ const char *username,
+ const char *password)
{
NMSettingGsm *setting;
NMSettingPpp *s_ppp;
@@ -269,11 +273,14 @@ create_gsm_connect_properties (NMConnection *connection)
const char *str;
setting = nm_connection_get_setting_gsm (connection);
+
properties = mm_simple_connect_properties_new ();
- /* Blank APN ("") means the default subscription APN */
- str = nm_setting_gsm_get_apn (setting);
- mm_simple_connect_properties_set_apn (properties, str ?: "");
+ mm_simple_connect_properties_set_apn (properties, apn ?: "");
+ if (username)
+ mm_simple_connect_properties_set_user (properties, username);
+ if (password)
+ mm_simple_connect_properties_set_password (properties, password);
str = nm_setting_gsm_get_network_id (setting);
if (str)
@@ -283,14 +290,6 @@ create_gsm_connect_properties (NMConnection *connection)
if (str)
mm_simple_connect_properties_set_pin (properties, str);
- str = nm_setting_gsm_get_username (setting);
- if (str)
- mm_simple_connect_properties_set_user (properties, str);
-
- str = nm_setting_gsm_get_password (setting);
- if (str)
- mm_simple_connect_properties_set_password (properties, str);
-
/* Roaming */
if (nm_setting_gsm_get_home_only (setting))
mm_simple_connect_properties_set_allow_roaming (properties, FALSE);
@@ -444,6 +443,95 @@ send_pin_ready (MMSim *sim, GAsyncResult *result, NMModemBroadband *self)
}
static void
+find_gsm_apn_cb (const char *apn,
+ const char *username,
+ const char *password,
+ const char *gateway,
+ const char *auth_method,
+ const GSList *dns,
+ GError *error,
+ gpointer user_data)
+{
+ NMModemBroadband *self = user_data;
+ NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE (self);
+ ConnectContext *ctx = priv->ctx;
+
+ if (error) {
+ _LOGW ("failed to connect '%s': APN not found: %s",
+ nm_connection_get_id (ctx->connection), error->message);
+
+ nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, NM_DEVICE_STATE_REASON_GSM_APN_FAILED);
+ connect_context_clear (self);
+ return;
+ }
+
+ /* Blank APN ("") means the default subscription APN */
+ ctx->connect_properties = create_gsm_connect_properties (ctx->connection,
+ apn,
+ username,
+ password);
+ g_return_if_fail (ctx->connect_properties);
+ connect_context_step (self);
+}
+
+static gboolean
+try_create_connect_properties (NMModemBroadband *self)
+{
+ NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE (self);
+ ConnectContext *ctx = priv->ctx;
+
+ if (MODEM_CAPS_3GPP (ctx->caps)) {
+ NMSettingGsm *s_gsm = nm_connection_get_setting_gsm (ctx->connection);
+
+ if (!s_gsm || nm_setting_gsm_get_auto_config (s_gsm)) {
+ gs_unref_object MMModem3gpp *modem_3gpp = NULL;
+ const char *network_id = NULL;
+
+ s_gsm = nm_connection_get_setting_gsm (ctx->connection);
+ if (s_gsm)
+ network_id = nm_setting_gsm_get_network_id (s_gsm);
+ if (!network_id) {
+ if (mm_modem_get_state (self->_priv.modem_iface) < MM_MODEM_STATE_REGISTERED)
+ return FALSE;
+ modem_3gpp = mm_object_get_modem_3gpp (priv->modem_object);
+ network_id = mm_modem_3gpp_get_operator_code (modem_3gpp);
+ }
+ if (!network_id) {
+ _LOGW ("failed to connect '%s': unable to determine the network id",
+ nm_connection_get_id (ctx->connection));
+ goto out;
+ }
+
+ nm_service_providers_find_gsm_apn (MOBILE_BROADBAND_PROVIDER_INFO_DATABASE,
+ network_id,
+ ctx->cancellable,
+ find_gsm_apn_cb,
+ self);
+ } else {
+ ctx->connect_properties = create_gsm_connect_properties (ctx->connection,
+ nm_setting_gsm_get_apn (s_gsm),
+ nm_setting_gsm_get_username (s_gsm),
+ nm_setting_gsm_get_password (s_gsm));
+ g_return_val_if_fail (ctx->connect_properties, TRUE);
+ }
+
+ return TRUE;
+ } else if (MODEM_CAPS_3GPP2 (ctx->caps)) {
+ ctx->connect_properties = create_cdma_connect_properties (ctx->connection);
+ g_return_val_if_fail (ctx->connect_properties, FALSE);
+ return TRUE;
+ } else {
+ _LOGW ("failed to connect '%s': not a mobile broadband modem",
+ nm_connection_get_id (ctx->connection));
+ }
+
+out:
+ nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
+ connect_context_clear (self);
+ return TRUE;
+}
+
+static void
connect_context_step (NMModemBroadband *self)
{
ConnectContext *ctx = self->_priv.ctx;
@@ -487,23 +575,8 @@ connect_context_step (NMModemBroadband *self)
if (mm_modem_get_state (self->_priv.modem_iface) <= MM_MODEM_STATE_LOCKED)
break;
- g_return_if_fail (!ctx->connect_properties);
-
- /* Create core connect properties based on the modem capabilities */
- if (MODEM_CAPS_3GPP (ctx->caps))
- ctx->connect_properties = create_gsm_connect_properties (ctx->connection);
- else if (MODEM_CAPS_3GPP2 (ctx->caps))
- ctx->connect_properties = create_cdma_connect_properties (ctx->connection);
- else {
- _LOGW ("failed to connect '%s': not a mobile broadband modem",
- nm_connection_get_id (ctx->connection));
-
- nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
- connect_context_clear (self);
+ if (!try_create_connect_properties (self))
break;
- }
-
- g_return_if_fail (ctx->connect_properties);
/* Build up list of IP types that we need to use in the retries */
ctx->ip_types = nm_modem_get_connection_ip_type (NM_MODEM (self), ctx->connection, &error);
@@ -522,6 +595,9 @@ connect_context_step (NMModemBroadband *self)
}
/* fall through */
case CONNECT_STEP_CONNECT:
+ if (!ctx->connect_properties)
+ break;
+
if (ctx->ip_types_i < ctx->ip_types->len) {
NMModemIPType current;
@@ -677,6 +753,9 @@ complete_connection (NMModem *modem,
if (!s_gsm) {
s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
nm_connection_add_setting (connection, NM_SETTING (s_gsm));
+ g_object_set (G_OBJECT (s_gsm),
+ NM_SETTING_GSM_AUTO_CONFIG, TRUE,
+ NULL);
}
if (!nm_setting_gsm_get_device_id (s_gsm)) {