merge: branch 'lr/gsm-default-apn'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/98
This commit is contained in:
Lubomir Rintel 2019-09-11 14:34:48 +02:00
commit beab85520a
22 changed files with 1000 additions and 78 deletions

1
.gitignore vendored
View file

@ -209,6 +209,7 @@ test-*.trs
/src/devices/tests/test-acd
/src/devices/tests/test-lldp
/src/devices/wifi/tests/test-devices-wifi
/src/devices/wwan/tests/test-service-providers
/src/dhcp/nm-dhcp-helper
/src/dhcp/tests/test-dhcp-dhclient
/src/dhcp/tests/test-dhcp-options

View file

@ -3315,7 +3315,10 @@ src_devices_wwan_libnm_wwan_la_SOURCES = \
src/devices/wwan/nm-modem-manager.c \
src/devices/wwan/nm-modem-manager.h \
src/devices/wwan/nm-modem.c \
src/devices/wwan/nm-modem.h
src/devices/wwan/nm-modem.h \
src/devices/wwan/nm-service-providers.c \
src/devices/wwan/nm-service-providers.h \
$(NULL)
if WITH_OFONO
src_devices_wwan_libnm_wwan_la_SOURCES += \
@ -3364,11 +3367,35 @@ check-local-devices-wwan: src/devices/wwan/libnm-device-plugin-wwan.la src/devic
check_local += check-local-devices-wwan
src_devices_wwan_tests_test_service_providers_SOURCES = \
src/devices/wwan/tests/test-service-providers.c \
src/devices/wwan/nm-service-providers.c \
src/devices/wwan/nm-service-providers.h \
$(NULL)
src_devices_wwan_tests_test_service_providers_CPPFLAGS = \
$(src_cppflags_base_test) \
-I$(srcdir)/src/devices/wwan \
$(NULL)
src_devices_wwan_tests_test_service_providers_LDFLAGS = \
$(SANITIZER_EXEC_LDFLAGS) \
$(NULL)
src_devices_wwan_tests_test_service_providers_LDADD = \
src/libNetworkManagerTest.la \
$(GLIB_LIBS) \
$(NULL)
check_programs += src/devices/wwan/tests/test-service-providers
endif
EXTRA_DIST += \
src/devices/wwan/libnm-wwan.ver \
src/devices/wwan/meson.build
src/devices/wwan/meson.build \
src/devices/wwan/tests/test-service-providers.xml \
$(NULL)
###############################################################################
# src/devices/bluetooth

View file

@ -5365,6 +5365,9 @@ static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = {
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_GSM
static const NMMetaPropertyInfo *const property_infos_GSM[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_AUTO_CONFIG,
.property_type = &_pt_gobject_bool,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_NUMBER,
.property_type = &_pt_gobject_string,
),

View file

@ -170,6 +170,7 @@
#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH N_("An array of 8 boolean values, where the array index corresponds to the User Priority (0 - 7) and the value indicates whether or not the priority may use all of the bandwidth allocated to its assigned group.")
#define DESCRIBE_DOC_NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS N_("An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the traffic class (0 - 7) to which the priority is mapped.")
#define DESCRIBE_DOC_NM_SETTING_GSM_APN N_("The GPRS Access Point Name specifying the APN used when establishing a data session with the GSM-based network. The APN often determines how the user will be billed for their network usage and whether the user has access to the Internet or just a provider-specific walled-garden, so it is important to use the correct APN for the user's mobile broadband plan. The APN may only be composed of the characters a-z, 0-9, ., and - per GSM 03.60 Section 14.9.")
#define DESCRIBE_DOC_NM_SETTING_GSM_AUTO_CONFIG N_("When TRUE, the settings such as APN, username, or password will default to values that match the network the modem will register to in the Mobile Broadband Provider database.")
#define DESCRIBE_DOC_NM_SETTING_GSM_DEVICE_ID N_("The device unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will only apply to the specified device.")
#define DESCRIBE_DOC_NM_SETTING_GSM_HOME_ONLY N_("When TRUE, only connections to the home network will be allowed. Connections to roaming networks will not be made.")
#define DESCRIBE_DOC_NM_SETTING_GSM_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.")

View file

@ -150,12 +150,12 @@ id
path
uuid
<<<
size: 4116
size: 4159
location: clients/tests/test-client.py:911:test_003()/12
cmd: $NMCLI con s con-gsm1
lang: C
returncode: 0
stdout: 3982 bytes
stdout: 4025 bytes
>>>
connection.id: con-gsm1
connection.uuid: UUID-con-gsm1-REPLACED-REPLACED-REPL
@ -228,6 +228,7 @@ serial.bits: 8
serial.parity: even
serial.stopbits: 1
serial.send-delay: 100
gsm.auto-config: no
gsm.number: --
gsm.username: --
gsm.password: <hidden>
@ -247,12 +248,12 @@ proxy.pac-url: --
proxy.pac-script: --
<<<
size: 4145
size: 4189
location: clients/tests/test-client.py:911:test_003()/13
cmd: $NMCLI con s con-gsm1
lang: pl_PL.UTF-8
returncode: 0
stdout: 4001 bytes
stdout: 4045 bytes
>>>
connection.id: con-gsm1
connection.uuid: UUID-con-gsm1-REPLACED-REPLACED-REPL
@ -325,6 +326,7 @@ serial.bits: 8
serial.parity: even
serial.stopbits: 1
serial.send-delay: 100
gsm.auto-config: nie
gsm.number: --
gsm.username: --
gsm.password: <hidden>

View file

@ -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

View file

@ -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,

View file

@ -22,6 +22,7 @@ install \
\
ModemManager-devel \
ModemManager-glib-devel \
mobile-broadband-provider-info-devel \
audit-libs-devel \
bash-completion \
bluez-libs-devel \

View file

@ -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

View file

@ -1041,7 +1041,7 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_infiniband_mtu (NMConnection *self, GHashTable *parameters)
_normalize_infiniband_mtu (NMConnection *self)
{
NMSettingInfiniband *s_infini = nm_connection_get_setting_infiniband (self);
@ -1056,7 +1056,7 @@ _normalize_infiniband_mtu (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_bond_mode (NMConnection *self, GHashTable *parameters)
_normalize_bond_mode (NMConnection *self)
{
NMSettingBond *s_bond = nm_connection_get_setting_bond (self);
@ -1077,7 +1077,7 @@ _normalize_bond_mode (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_bond_options (NMConnection *self, GHashTable *parameters)
_normalize_bond_options (NMConnection *self)
{
NMSettingBond *s_bond = nm_connection_get_setting_bond (self);
gboolean changed = FALSE;
@ -1107,7 +1107,7 @@ again:
}
static gboolean
_normalize_wireless_mac_address_randomization (NMConnection *self, GHashTable *parameters)
_normalize_wireless_mac_address_randomization (NMConnection *self)
{
NMSettingWireless *s_wifi = nm_connection_get_setting_wireless (self);
const char *cloned_mac_address;
@ -1153,7 +1153,7 @@ _normalize_wireless_mac_address_randomization (NMConnection *self, GHashTable *p
}
static gboolean
_normalize_macsec (NMConnection *self, GHashTable *parameters)
_normalize_macsec (NMConnection *self)
{
NMSettingMacsec *s_macsec = nm_connection_get_setting_macsec (self);
gboolean changed = FALSE;
@ -1176,7 +1176,7 @@ _normalize_macsec (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_team_config (NMConnection *self, GHashTable *parameters)
_normalize_team_config (NMConnection *self)
{
NMSettingTeam *s_team = nm_connection_get_setting_team (self);
@ -1192,7 +1192,7 @@ _normalize_team_config (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_team_port_config (NMConnection *self, GHashTable *parameters)
_normalize_team_port_config (NMConnection *self)
{
NMSettingTeamPort *s_team_port = nm_connection_get_setting_team_port (self);
@ -1208,7 +1208,7 @@ _normalize_team_port_config (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_bluetooth_type (NMConnection *self, GHashTable *parameters)
_normalize_bluetooth_type (NMConnection *self)
{
const char *type = _nm_connection_detect_bluetooth_type (self);
@ -1222,7 +1222,7 @@ _normalize_bluetooth_type (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_ovs_interface_type (NMConnection *self, GHashTable *parameters)
_normalize_ovs_interface_type (NMConnection *self)
{
NMSettingOvsInterface *s_ovs_interface = nm_connection_get_setting_ovs_interface (self);
gboolean modified;
@ -1243,7 +1243,7 @@ _normalize_ovs_interface_type (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_ip_tunnel_wired_setting (NMConnection *self, GHashTable *parameters)
_normalize_ip_tunnel_wired_setting (NMConnection *self)
{
NMSettingIPTunnel *s_ip_tunnel;
@ -1263,7 +1263,7 @@ _normalize_ip_tunnel_wired_setting (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_sriov_vf_order (NMConnection *self, GHashTable *parameters)
_normalize_sriov_vf_order (NMConnection *self)
{
NMSettingSriov *s_sriov;
@ -1275,7 +1275,7 @@ _normalize_sriov_vf_order (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_bridge_vlan_order (NMConnection *self, GHashTable *parameters)
_normalize_bridge_vlan_order (NMConnection *self)
{
NMSettingBridge *s_bridge;
@ -1287,7 +1287,7 @@ _normalize_bridge_vlan_order (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_bridge_port_vlan_order (NMConnection *self, GHashTable *parameters)
_normalize_bridge_port_vlan_order (NMConnection *self)
{
NMSettingBridgePort *s_port;
@ -1299,7 +1299,30 @@ _normalize_bridge_port_vlan_order (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_required_settings (NMConnection *self, GHashTable *parameters)
_normalize_gsm_auto_config (NMConnection *self)
{
NMSettingGsm *s_gsm;
s_gsm = nm_connection_get_setting_gsm (self);
if (!s_gsm)
return FALSE;
if (!nm_setting_gsm_get_auto_config (s_gsm))
return FALSE;
if ( !nm_setting_gsm_get_apn (s_gsm)
&& !nm_setting_gsm_get_username (s_gsm)
&& !nm_setting_gsm_get_password (s_gsm))
return FALSE;
g_object_set (s_gsm,
NM_SETTING_GSM_AUTO_CONFIG, FALSE,
NULL);
return TRUE;
}
static gboolean
_normalize_required_settings (NMConnection *self)
{
NMSettingBluetooth *s_bt = nm_connection_get_setting_bluetooth (self);
NMSetting *s_bridge;
@ -1323,7 +1346,7 @@ _normalize_required_settings (NMConnection *self, GHashTable *parameters)
}
static gboolean
_normalize_invalid_slave_port_settings (NMConnection *self, GHashTable *parameters)
_normalize_invalid_slave_port_settings (NMConnection *self)
{
NMSettingConnection *s_con = nm_connection_get_setting_connection (self);
const char *slave_type;
@ -1597,23 +1620,24 @@ _connection_normalize (NMConnection *connection,
was_modified |= _normalize_connection_uuid (connection);
was_modified |= _normalize_connection_type (connection);
was_modified |= _normalize_connection_slave_type (connection);
was_modified |= _normalize_required_settings (connection, parameters);
was_modified |= _normalize_invalid_slave_port_settings (connection, parameters);
was_modified |= _normalize_required_settings (connection);
was_modified |= _normalize_invalid_slave_port_settings (connection);
was_modified |= _normalize_ip_config (connection, parameters);
was_modified |= _normalize_ethernet_link_neg (connection);
was_modified |= _normalize_infiniband_mtu (connection, parameters);
was_modified |= _normalize_bond_mode (connection, parameters);
was_modified |= _normalize_bond_options (connection, parameters);
was_modified |= _normalize_wireless_mac_address_randomization (connection, parameters);
was_modified |= _normalize_macsec (connection, parameters);
was_modified |= _normalize_team_config (connection, parameters);
was_modified |= _normalize_team_port_config (connection, parameters);
was_modified |= _normalize_bluetooth_type (connection, parameters);
was_modified |= _normalize_ovs_interface_type (connection, parameters);
was_modified |= _normalize_ip_tunnel_wired_setting (connection, parameters);
was_modified |= _normalize_sriov_vf_order (connection, parameters);
was_modified |= _normalize_bridge_vlan_order (connection, parameters);
was_modified |= _normalize_bridge_port_vlan_order (connection, parameters);
was_modified |= _normalize_infiniband_mtu (connection);
was_modified |= _normalize_bond_mode (connection);
was_modified |= _normalize_bond_options (connection);
was_modified |= _normalize_wireless_mac_address_randomization (connection);
was_modified |= _normalize_macsec (connection);
was_modified |= _normalize_team_config (connection);
was_modified |= _normalize_team_port_config (connection);
was_modified |= _normalize_bluetooth_type (connection);
was_modified |= _normalize_ovs_interface_type (connection);
was_modified |= _normalize_ip_tunnel_wired_setting (connection);
was_modified |= _normalize_sriov_vf_order (connection);
was_modified |= _normalize_bridge_vlan_order (connection);
was_modified |= _normalize_bridge_port_vlan_order (connection);
was_modified |= _normalize_gsm_auto_config (connection);
was_modified = !!was_modified;

View file

@ -24,6 +24,7 @@
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
PROP_AUTO_CONFIG,
PROP_NUMBER,
PROP_USERNAME,
PROP_PASSWORD,
@ -40,6 +41,8 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
gboolean auto_config;
char *number; /* For dialing, duh */
char *username;
char *password;
@ -66,6 +69,22 @@ G_DEFINE_TYPE (NMSettingGsm, nm_setting_gsm, NM_TYPE_SETTING)
/*****************************************************************************/
/**
* nm_setting_gsm_get_auto_config:
* @setting: the #NMSettingGsm
*
* Returns: the #NMSettingGsm:auto-config property of the setting
*
* Since: 1.22
**/
gboolean
nm_setting_gsm_get_auto_config (NMSettingGsm *setting)
{
g_return_val_if_fail (NM_IS_SETTING_GSM (setting), FALSE);
return NM_SETTING_GSM_GET_PRIVATE (setting)->auto_config;
}
/**
* nm_setting_gsm_get_number:
* @setting: the #NMSettingGsm
@ -273,10 +292,10 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
if (priv->apn) {
guint32 apn_len = strlen (priv->apn);
guint32 i;
gsize apn_len = strlen (priv->apn);
gsize i;
if (apn_len < 1 || apn_len > 64) {
if (apn_len > 64) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
@ -320,7 +339,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
if (priv->username && !strlen (priv->username)) {
if ( priv->username
&& priv->username[0] == '\0') {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
@ -330,8 +350,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
if (priv->network_id) {
guint32 nid_len = strlen (priv->network_id);
guint32 i;
gsize nid_len = strlen (priv->network_id);
gsize i;
/* Accept both 5 and 6 digit MCC/MNC codes */
if ((nid_len < 5) || (nid_len > 6)) {
@ -400,6 +420,16 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
if ( priv->auto_config
&& (priv->apn || priv->username || priv->password)) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("can't be enabled when manual configuration is present"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_AUTO_CONFIG);
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
return TRUE;
}
@ -440,6 +470,9 @@ get_property (GObject *object, guint prop_id,
NMSettingGsm *setting = NM_SETTING_GSM (object);
switch (prop_id) {
case PROP_AUTO_CONFIG:
g_value_set_boolean (value, nm_setting_gsm_get_auto_config (setting));
break;
case PROP_NUMBER:
g_value_set_string (value, nm_setting_gsm_get_number (setting));
break;
@ -493,6 +526,9 @@ set_property (GObject *object, guint prop_id,
char *tmp;
switch (prop_id) {
case PROP_AUTO_CONFIG:
priv->auto_config = g_value_get_boolean (value);
break;
case PROP_NUMBER:
g_free (priv->number);
priv->number = g_value_dup_string (value);
@ -608,6 +644,21 @@ nm_setting_gsm_class_init (NMSettingGsmClass *klass)
setting_class->verify_secrets = verify_secrets;
setting_class->need_secrets = need_secrets;
/**
* NMSettingGsm:auto-config:
*
* When %TRUE, the settings such as APN, username, or password will
* default to values that match the network the modem will register
* to in the Mobile Broadband Provider database.
*
* Since: 1.22
**/
obj_properties[PROP_AUTO_CONFIG] =
g_param_spec_boolean (NM_SETTING_GSM_AUTO_CONFIG, "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* NMSettingGsm:number:
*

View file

@ -24,6 +24,7 @@ G_BEGIN_DECLS
#define NM_SETTING_GSM_SETTING_NAME "gsm"
#define NM_SETTING_GSM_AUTO_CONFIG "auto-config"
#define NM_SETTING_GSM_USERNAME "username"
#define NM_SETTING_GSM_PASSWORD "password"
#define NM_SETTING_GSM_PASSWORD_FLAGS "password-flags"
@ -59,6 +60,10 @@ typedef struct {
GType nm_setting_gsm_get_type (void);
NMSetting *nm_setting_gsm_new (void);
NM_AVAILABLE_IN_1_22
gboolean nm_setting_gsm_get_auto_config (NMSettingGsm *setting);
const char *nm_setting_gsm_get_username (NMSettingGsm *setting);
const char *nm_setting_gsm_get_password (NMSettingGsm *setting);
const char *nm_setting_gsm_get_apn (NMSettingGsm *setting);

View file

@ -1747,7 +1747,7 @@ test_setting_gsm_apn_bad_chars (void)
/* 0 characters long */
g_object_set (s_gsm, NM_SETTING_GSM_APN, "", NULL);
g_assert (!nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL));
g_assert (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL));
/* 65-character long */
g_object_set (s_gsm, NM_SETTING_GSM_APN, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl1", NULL);

View file

@ -1628,3 +1628,8 @@ global:
nm_setting_wireguard_get_ip6_auto_default_route;
nm_settings_add_connection2_flags_get_type;
} libnm_1_18_0;
libnm_1_22_0 {
global:
nm_setting_gsm_get_auto_config;
} libnm_1_20_0;

View file

@ -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

View file

@ -2,6 +2,7 @@ sources = files(
'nm-modem-broadband.c',
'nm-modem.c',
'nm-modem-manager.c',
'nm-service-providers.c',
)
deps = [
@ -28,8 +29,10 @@ libnm_wwan = shared_module(
install_dir: nm_plugindir,
)
wwan_inc = include_directories('.')
libnm_wwan_dep = declare_dependency(
include_directories: include_directories('.'),
include_directories: wwan_inc,
link_with: libnm_wwan,
)
@ -74,3 +77,7 @@ check-local-devices-wwan: src/devices/wwan/libnm-device-plugin-wwan.la src/devic
$(srcdir)/tools/check-exports.sh $(builddir)/src/devices/wwan/.libs/libnm-wwan.so "$(srcdir)/src/devices/wwan/libnm-wwan.ver"
$(call check_so_symbols,$(builddir)/src/devices/wwan/.libs/libnm-wwan.so)
'''
if enable_tests
subdir('tests')
endif

View file

@ -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);
@ -443,6 +442,95 @@ send_pin_ready (MMSim *sim, GAsyncResult *result, NMModemBroadband *self)
connect_context_step (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)
{
@ -487,22 +575,8 @@ connect_context_step (NMModemBroadband *self)
if (mm_modem_get_state (self->_priv.modem_iface) <= MM_MODEM_STATE_LOCKED)
break;
/* Create core connect properties based on the modem capabilities */
g_assert (!ctx->connect_properties);
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_assert (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);
@ -521,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;
@ -533,7 +610,7 @@ connect_context_step (NMModemBroadband *self)
else if (current == NM_MODEM_IP_TYPE_IPV4V6)
mm_simple_connect_properties_set_ip_type (ctx->connect_properties, MM_BEARER_IP_FAMILY_IPV4V6);
else
g_assert_not_reached ();
g_return_if_reached ();
_nm_modem_set_apn (NM_MODEM (self), mm_simple_connect_properties_get_apn (ctx->connect_properties));
@ -676,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)) {
@ -863,8 +943,8 @@ static_stage3_ip4_done (NMModemBroadband *self)
guint32 ip4_route_table, ip4_route_metric;
NMPlatformIP4Route *r;
g_assert (self->_priv.ipv4_config);
g_assert (self->_priv.bearer);
g_return_val_if_fail (self->_priv.ipv4_config, FALSE);
g_return_val_if_fail (self->_priv.bearer, FALSE);
self->_priv.idle_id_ip4 = 0;
@ -895,7 +975,7 @@ static_stage3_ip4_done (NMModemBroadband *self)
}
data_port = mm_bearer_get_interface (self->_priv.bearer);
g_assert (data_port);
g_return_val_if_fail (data_port, FALSE);
config = nm_ip4_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET),
nm_platform_link_get_ifindex (NM_PLATFORM_GET, data_port));
@ -970,7 +1050,7 @@ stage3_ip6_done (NMModemBroadband *self)
const char **dns;
guint i;
g_assert (self->_priv.ipv6_config);
g_return_val_if_fail (self->_priv.ipv6_config, FALSE);
self->_priv.idle_id_ip6 = 0;
memset (&address, 0, sizeof (address));
@ -1002,7 +1082,8 @@ stage3_ip6_done (NMModemBroadband *self)
_LOGI ("IPv6 base configuration:");
data_port = mm_bearer_get_interface (self->_priv.bearer);
g_assert (data_port);
g_return_val_if_fail (data_port, FALSE);
config = nm_ip6_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET),
nm_platform_link_get_ifindex (NM_PLATFORM_GET, data_port));
@ -1370,8 +1451,9 @@ set_property (GObject *object,
/* construct-only */
self->_priv.modem_object = g_value_dup_object (value);
self->_priv.modem_iface = mm_object_get_modem (self->_priv.modem_object);
g_return_if_fail (self->_priv.modem_iface);
self->_priv.modem_3gpp_iface = mm_object_get_modem_3gpp (self->_priv.modem_object);
g_assert (self->_priv.modem_iface != NULL);
g_signal_connect (self->_priv.modem_iface,
"state-changed",
G_CALLBACK (modem_state_changed),

View file

@ -0,0 +1,460 @@
// SPDX-License-Identifier: LGPL-2.1+
/*
* Copyright (C) 2009 Novell, Inc.
* Author: Tambet Ingo (tambet@gmail.com).
*
* Copyright (C) 2009 - 2019 Red Hat, Inc.
* Copyright (C) 2012 Lanedo GmbH
*/
#include "nm-default.h"
#include "nm-service-providers.h"
typedef enum {
PARSER_TOPLEVEL = 0,
PARSER_COUNTRY,
PARSER_PROVIDER,
PARSER_METHOD_GSM,
PARSER_METHOD_GSM_APN,
PARSER_METHOD_CDMA,
PARSER_DONE,
PARSER_ERROR
} ParseContextState;
typedef struct {
char *mccmnc;
NMServiceProvidersGsmApnCallback callback;
gpointer user_data;
GCancellable *cancellable;
GMarkupParseContext *ctx;
char buffer[4096];
char *text_buffer;
ParseContextState state;
gboolean mccmnc_matched;
gboolean found_internet_apn;
char *apn;
char *username;
char *password;
char *gateway;
char *auth_method;
GSList *dns;
} ParseContext;
/*****************************************************************************/
static void
parser_toplevel_start (ParseContext *parse_context,
const char *name,
const char **attribute_names,
const char **attribute_values)
{
int i;
if (strcmp (name, "serviceproviders") == 0) {
for (i = 0; attribute_names && attribute_names[i]; i++) {
if (strcmp (attribute_names[i], "format") == 0) {
if (strcmp (attribute_values[i], "2.0")) {
g_warning ("%s: mobile broadband provider database format '%s'"
" not supported.", __func__, attribute_values[i]);
parse_context->state = PARSER_ERROR;
break;
}
}
}
} else if (strcmp (name, "country") == 0) {
parse_context->state = PARSER_COUNTRY;
}
}
static void
parser_country_start (ParseContext *parse_context,
const char *name,
const char **attribute_names,
const char **attribute_values)
{
if (strcmp (name, "provider") == 0)
parse_context->state = PARSER_PROVIDER;
}
static void
parser_provider_start (ParseContext *parse_context,
const char *name,
const char **attribute_names,
const char **attribute_values)
{
parse_context->mccmnc_matched = FALSE;
if (strcmp (name, "gsm") == 0)
parse_context->state = PARSER_METHOD_GSM;
else if (strcmp (name, "cdma") == 0)
parse_context->state = PARSER_METHOD_CDMA;
}
static void
parser_gsm_start (ParseContext *parse_context,
const char *name,
const char **attribute_names,
const char **attribute_values)
{
int i;
if (strcmp (name, "network-id") == 0) {
const char *mcc = NULL, *mnc = NULL;
for (i = 0; attribute_names && attribute_names[i]; i++) {
if (strcmp (attribute_names[i], "mcc") == 0)
mcc = attribute_values[i];
else if (strcmp (attribute_names[i], "mnc") == 0)
mnc = attribute_values[i];
if (mcc && strlen (mcc) && mnc && strlen (mnc)) {
char *mccmnc = g_strdup_printf ("%s%s", mcc, mnc);
if (strcmp (mccmnc, parse_context->mccmnc) == 0)
parse_context->mccmnc_matched = TRUE;
g_free (mccmnc);
break;
}
}
} else if (strcmp (name, "apn") == 0) {
parse_context->found_internet_apn = FALSE;
g_clear_pointer (&parse_context->apn, g_free);
g_clear_pointer (&parse_context->username, g_free);
g_clear_pointer (&parse_context->password, g_free);
g_clear_pointer (&parse_context->gateway, g_free);
g_clear_pointer (&parse_context->auth_method, g_free);
g_slist_free_full (parse_context->dns, g_free);
parse_context->dns = NULL;
for (i = 0; attribute_names && attribute_names[i]; i++) {
if (strcmp (attribute_names[i], "value") == 0) {
parse_context->state = PARSER_METHOD_GSM_APN;
parse_context->apn = g_strstrip (g_strdup (attribute_values[i]));
break;
}
}
}
}
static void
parser_gsm_apn_start (ParseContext *parse_context,
const char *name,
const char **attribute_names,
const char **attribute_values)
{
int i;
if (strcmp (name, "usage") == 0) {
for (i = 0; attribute_names && attribute_names[i]; i++) {
if ( (strcmp (attribute_names[i], "type") == 0)
&& (strcmp (attribute_values[i], "internet") == 0)) {
parse_context->found_internet_apn = TRUE;
break;
}
}
} else if (strcmp (name, "authentication") == 0) {
for (i = 0; attribute_names && attribute_names[i]; i++) {
if (strcmp (attribute_names[i], "method") == 0) {
g_clear_pointer (&parse_context->auth_method, g_free);
parse_context->auth_method = g_strstrip (g_strdup (attribute_values[i]));
break;
}
}
}
}
static void
parser_start_element (GMarkupParseContext *context,
const char *element_name,
const char **attribute_names,
const char **attribute_values,
gpointer user_data,
GError **error)
{
ParseContext *parse_context = user_data;
g_clear_pointer (&parse_context->text_buffer, g_free);
switch (parse_context->state) {
case PARSER_TOPLEVEL:
parser_toplevel_start (parse_context, element_name, attribute_names, attribute_values);
break;
case PARSER_COUNTRY:
parser_country_start (parse_context, element_name, attribute_names, attribute_values);
break;
case PARSER_PROVIDER:
parser_provider_start (parse_context, element_name, attribute_names, attribute_values);
break;
case PARSER_METHOD_GSM:
parser_gsm_start (parse_context, element_name, attribute_names, attribute_values);
break;
case PARSER_METHOD_GSM_APN:
parser_gsm_apn_start (parse_context, element_name, attribute_names, attribute_values);
break;
case PARSER_METHOD_CDMA:
break;
case PARSER_ERROR:
break;
case PARSER_DONE:
break;
}
}
static void
parser_country_end (ParseContext *parse_context,
const char *name)
{
if (strcmp (name, "country") == 0) {
g_clear_pointer (&parse_context->text_buffer, g_free);
parse_context->state = PARSER_TOPLEVEL;
}
}
static void
parser_provider_end (ParseContext *parse_context,
const char *name)
{
if (strcmp (name, "provider") == 0) {
g_clear_pointer (&parse_context->text_buffer, g_free);
parse_context->state = PARSER_COUNTRY;
}
}
static void
parser_gsm_end (ParseContext *parse_context,
const char *name)
{
if (strcmp (name, "gsm") == 0) {
g_clear_pointer (&parse_context->text_buffer, g_free);
parse_context->state = PARSER_PROVIDER;
}
}
static void
parser_gsm_apn_end (ParseContext *parse_context,
const char *name)
{
if (strcmp (name, "username") == 0) {
g_clear_pointer (&parse_context->username, g_free);
parse_context->username = g_steal_pointer (&parse_context->text_buffer);
} else if (strcmp (name, "password") == 0) {
g_clear_pointer (&parse_context->password, g_free);
parse_context->password = g_steal_pointer (&parse_context->text_buffer);
} else if (strcmp (name, "dns") == 0) {
parse_context->dns = g_slist_prepend (parse_context->dns,
g_steal_pointer (&parse_context->text_buffer));
} else if (strcmp (name, "gateway") == 0) {
g_clear_pointer (&parse_context->gateway, g_free);
parse_context->gateway = g_steal_pointer (&parse_context->text_buffer);
} else if (strcmp (name, "apn") == 0) {
g_clear_pointer (&parse_context->text_buffer, g_free);
if (parse_context->mccmnc_matched && parse_context->found_internet_apn)
parse_context->state = PARSER_DONE;
else
parse_context->state = PARSER_METHOD_GSM;
}
}
static void
parser_cdma_end (ParseContext *parse_context,
const char *name)
{
if (strcmp (name, "cdma") == 0) {
g_clear_pointer (&parse_context->text_buffer, g_free);
parse_context->state = PARSER_PROVIDER;
}
}
static void
parser_end_element (GMarkupParseContext *context,
const char *element_name,
gpointer user_data,
GError **error)
{
ParseContext *parse_context = user_data;
switch (parse_context->state) {
case PARSER_TOPLEVEL:
break;
case PARSER_COUNTRY:
parser_country_end (parse_context, element_name);
break;
case PARSER_PROVIDER:
parser_provider_end (parse_context, element_name);
break;
case PARSER_METHOD_GSM:
parser_gsm_end (parse_context, element_name);
break;
case PARSER_METHOD_GSM_APN:
parser_gsm_apn_end (parse_context, element_name);
break;
case PARSER_METHOD_CDMA:
parser_cdma_end (parse_context, element_name);
break;
case PARSER_ERROR:
break;
case PARSER_DONE:
break;
}
}
static void
parser_text (GMarkupParseContext *context,
const char *text,
gsize text_len,
gpointer user_data,
GError **error)
{
ParseContext *parse_context = user_data;
g_free (parse_context->text_buffer);
parse_context->text_buffer = g_strdup (text);
}
static const GMarkupParser parser = {
.start_element = parser_start_element,
.end_element = parser_end_element,
.text = parser_text,
.passthrough = NULL,
.error = NULL,
};
/*****************************************************************************/
static void
finish_parse_context (ParseContext *parse_context, GError *error)
{
if (parse_context->callback) {
if (error) {
parse_context->callback (NULL, NULL, NULL, NULL, NULL,
NULL, error,
parse_context->user_data);
} else {
parse_context->callback (parse_context->apn,
parse_context->username,
parse_context->password,
parse_context->gateway,
parse_context->auth_method,
parse_context->dns,
error,
parse_context->user_data);
}
}
g_free (parse_context->mccmnc);
g_markup_parse_context_free (parse_context->ctx);
g_free (parse_context->text_buffer);
g_free (parse_context->apn);
g_free (parse_context->username);
g_free (parse_context->password);
g_free (parse_context->gateway);
g_free (parse_context->auth_method);
g_slist_free_full (parse_context->dns, g_free);
g_slice_free (ParseContext, parse_context);
}
static void
read_next_chunk (GInputStream *stream, ParseContext *parse_context);
static void
stream_read_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
GInputStream *stream = G_INPUT_STREAM (source_object);
ParseContext *parse_context = user_data;
gssize len;
GError *error = NULL;
len = g_input_stream_read_finish (stream, res, &error);
if (len == -1) {
g_prefix_error (&error, "Error reading service provider database: ");
finish_parse_context (parse_context, error);
g_clear_error (&error);
return;
}
if (len == 0) {
g_set_error (&error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
"Operator ID '%s' not found in service provider database",
parse_context->mccmnc);
finish_parse_context (parse_context, error);
g_clear_error (&error);
return;
}
if (!g_markup_parse_context_parse (parse_context->ctx, parse_context->buffer, len, &error)) {
g_prefix_error (&error, "Error parsing service provider database: ");
finish_parse_context (parse_context, error);
g_clear_error (&error);
return;
}
if (parse_context->state == PARSER_DONE) {
finish_parse_context (parse_context, NULL);
return;
}
read_next_chunk (stream, parse_context);
}
static void
read_next_chunk (GInputStream *stream, ParseContext *parse_context)
{
g_input_stream_read_async (stream,
parse_context->buffer,
sizeof (parse_context->buffer),
G_PRIORITY_DEFAULT,
parse_context->cancellable,
stream_read_cb,
parse_context);
}
static void
file_read_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
GFile *file = G_FILE (source_object);
ParseContext *parse_context = user_data;
GFileInputStream *stream;
gs_free_error GError *error = NULL;
stream = g_file_read_finish (file, res, &error);
if (!stream) {
g_prefix_error (&error, "Error opening service provider database: ");
finish_parse_context (parse_context, error);
return;
}
read_next_chunk (G_INPUT_STREAM (stream), parse_context);
g_object_unref (stream);
}
/*****************************************************************************/
void
nm_service_providers_find_gsm_apn (const char *service_providers,
const char *mccmnc,
GCancellable *cancellable,
NMServiceProvidersGsmApnCallback callback,
gpointer user_data)
{
GFile *file;
ParseContext *parse_context;
parse_context = g_slice_new0 (ParseContext);
parse_context->mccmnc = g_strdup (mccmnc);
parse_context->cancellable = cancellable;
parse_context->callback = callback;
parse_context->user_data = user_data;
parse_context->ctx = g_markup_parse_context_new (&parser, 0, parse_context, NULL);
file = g_file_new_for_path (service_providers);
g_file_read_async (file, G_PRIORITY_DEFAULT, cancellable, file_read_cb, parse_context);
g_object_unref (file);
}

View file

@ -0,0 +1,24 @@
// SPDX-License-Identifier: LGPL-2.1+
/*
* Copyright (C) 2019 Red Hat, Inc.
*/
#ifndef __NETWORKMANAGER_SERVICE_PROVIDERS_H__
#define __NETWORKMANAGER_SERVICE_PROVIDERS_H__
typedef void (*NMServiceProvidersGsmApnCallback) (const char *apn,
const char *username,
const char *password,
const char *gateway,
const char *auth_method,
const GSList *dns,
GError *error,
gpointer user_data);
void nm_service_providers_find_gsm_apn (const char *service_providers,
const char *mccmnc,
GCancellable *cancellable,
NMServiceProvidersGsmApnCallback callback,
gpointer user_data);
#endif /* __NETWORKMANAGER_SERVICE_PROVIDERS_H__ */

View file

@ -0,0 +1,13 @@
exe = executable(
'test-service-providers',
sources: files('test-service-providers.c',
'../nm-service-providers.c'),
dependencies: test_nm_dep,
include_directories: wwan_inc,
)
test(
'wwan/test-service-providers',
test_script,
timeout: default_test_timeout,
args: test_args + [exe.full_path()],
)

View file

@ -0,0 +1,124 @@
// SPDX-License-Identifier: LGPL-2.1+
/*
* Copyright (C) 2019 Red Hat
*/
#include "nm-default.h"
#include "nm-service-providers.h"
#include "nm-test-utils-core.h"
static void
test_positive_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)
{
GMainLoop *loop = user_data;
g_main_loop_quit (loop);
g_assert_no_error (error);
g_assert_cmpstr (apn, ==, "gprs.example.com");
g_assert_cmpstr (username, ==, "praise");
g_assert_cmpstr (password, ==, "santa");
g_assert_cmpstr (gateway, ==, "192.0.2.3");
g_assert_cmpstr (auth_method, ==, "pap");
g_assert_nonnull (dns);
g_assert_cmpstr (dns->data, ==, "192.0.2.2");
dns = dns->next;
g_assert_nonnull (dns);
g_assert_cmpstr (dns->data, ==, "192.0.2.1");
g_assert_null (dns->next);
}
static void
test_positive (void)
{
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
nm_service_providers_find_gsm_apn (NM_BUILD_SRCDIR"/src/devices/wwan/tests/test-service-providers.xml",
"13337", NULL, test_positive_cb, loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
}
/*****************************************************************************/
static void
test_negative_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)
{
GMainLoop *loop = user_data;
g_main_loop_quit (loop);
g_assert_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN);
}
static void
test_negative (void)
{
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
nm_service_providers_find_gsm_apn (NM_BUILD_SRCDIR"/src/devices/wwan/tests/test-service-providers.xml",
"78130", NULL, test_negative_cb, loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
}
/*****************************************************************************/
static void
test_nonexistent_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)
{
GMainLoop *loop = user_data;
g_main_loop_quit (loop);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_AGAIN);
}
static void
test_nonexistent (void)
{
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
nm_service_providers_find_gsm_apn ("nonexistent.xml", "13337", NULL,
test_nonexistent_cb, loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
}
/*****************************************************************************/
NMTST_DEFINE ();
int
main (int argc, char **argv)
{
nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT");
g_test_add_func ("/service-providers/positive", test_positive);
g_test_add_func ("/service-providers/negative", test_negative);
g_test_add_func ("/service-providers/nonexistent", test_nonexistent);
return g_test_run ();
}

View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding='utf-8'?>
<!DOCTYPE serviceproviders SYSTEM "serviceproviders.2.dtd">
<serviceproviders format="2.0">
<country code="feh">
<provider>
<name>Sophia</name>
<gsm>
<network-id mcc="666" mnc="999"/>
<apn value="access.example.com">
<plan type="postpaid"/>
<usage type="internet"/>
<name>APN</name>
<dns>192.0.2.1</dns>
<dns>192.0.2.2</dns>
</apn>
</gsm>
</provider>
</country>
<country code="meh">
<provider>
<name>Demiurge</name>
<gsm>
<network-id mcc="133" mnc="37"/>
<network-id mcc="133" mnc="666"/>
<apn value="mms">
<usage type="mms"/>
<name>Unsolicited Nudes MMS</name>
<username>mms</username>
<password>mms</password>
<mmsc>http://mms.example.com/</mmsc>
<mmsproxy>192.0.2.1:8080</mmsproxy>
</apn>
<apn value="gprs.example.com">
<plan type="postpaid"/>
<usage type="internet"/>
<name>GPRS</name>
<username>praise</username>
<password>santa</password>
<dns>192.0.2.1</dns>
<dns>192.0.2.2</dns>
<gateway>192.0.2.3</gateway>
<authentication method="pap"/>
</apn>
<apn value="second.example.com">
<plan type="postpaid"/>
<usage type="internet"/>
<name>Second</name>
<username>worship</username>
<password>doom</password>
</apn>
</gsm>
</provider>
<provider>
<name>Personal</name>
<gsm>
<network-id mcc="666" mnc="999"/>
<apn value="access.example.com">
<plan type="postpaid"/>
<usage type="internet"/>
<name>APN</name>
<dns>192.0.2.1</dns>
<dns>192.0.2.2</dns>
</apn>
</gsm>
</provider>
</country>
</serviceproviders>