summary refs log tree commit diff
path: root/src/devices/wwan
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/wwan')
-rw-r--r--src/devices/wwan/libnm-wwan.ver41
-rw-r--r--src/devices/wwan/meson.build92
-rw-r--r--src/devices/wwan/nm-device-modem.c957
-rw-r--r--src/devices/wwan/nm-device-modem.h36
-rw-r--r--src/devices/wwan/nm-modem-broadband.c1625
-rw-r--r--src/devices/wwan/nm-modem-broadband.h29
-rw-r--r--src/devices/wwan/nm-modem-manager.c876
-rw-r--r--src/devices/wwan/nm-modem-manager.h45
-rw-r--r--src/devices/wwan/nm-modem-ofono.c1239
-rw-r--r--src/devices/wwan/nm-modem-ofono.h35
-rw-r--r--src/devices/wwan/nm-modem.c2037
-rw-r--r--src/devices/wwan/nm-modem.h269
-rw-r--r--src/devices/wwan/nm-service-providers.c455
-rw-r--r--src/devices/wwan/nm-service-providers.h24
-rw-r--r--src/devices/wwan/nm-wwan-factory.c146
-rw-r--r--src/devices/wwan/tests/test-service-providers.c130
-rw-r--r--src/devices/wwan/tests/test-service-providers.xml73
17 files changed, 0 insertions, 8109 deletions
diff --git a/src/devices/wwan/libnm-wwan.ver b/src/devices/wwan/libnm-wwan.ver
deleted file mode 100644
index c368a590..00000000
--- a/src/devices/wwan/libnm-wwan.ver
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-global:
-	nm_modem_act_stage1_prepare;
-	nm_modem_act_stage2_config;
-	nm_modem_check_connection_compatible;
-	nm_modem_claim;
-	nm_modem_complete_connection;
-	nm_modem_deactivate;
-	nm_modem_deactivate_async;
-	nm_modem_device_state_changed;
-	nm_modem_get_apn;
-	nm_modem_get_capabilities;
-	nm_modem_get_configured_mtu;
-	nm_modem_get_control_port;
-	nm_modem_get_device_id;
-	nm_modem_get_driver;
-	nm_modem_get_iid;
-	nm_modem_get_ip_ifindex;
-	nm_modem_get_operator_code;
-	nm_modem_get_path;
-	nm_modem_get_secrets;
-	nm_modem_get_state;
-	nm_modem_get_type;
-	nm_modem_get_uid;
-	nm_modem_ip4_pre_commit;
-	nm_modem_is_claimed;
-	nm_modem_manager_get;
-	nm_modem_manager_get_modems;
-	nm_modem_manager_get_type;
-	nm_modem_manager_name_owner_get;
-	nm_modem_manager_name_owner_ref;
-	nm_modem_manager_name_owner_unref;
-	nm_modem_owns_port;
-	nm_modem_set_mm_enabled;
-	nm_modem_stage3_ip4_config_start;
-	nm_modem_stage3_ip6_config_start;
-	nm_modem_state_to_string;
-	nm_modem_unclaim;
-local:
-	*;
-};
diff --git a/src/devices/wwan/meson.build b/src/devices/wwan/meson.build
deleted file mode 100644
index 97252edc..00000000
--- a/src/devices/wwan/meson.build
+++ /dev/null
@@ -1,92 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1+
-
-nm_service_providers_source = files('nm-service-providers.c')
-
-sources = nm_service_providers_source + files(
-  'nm-modem-broadband.c',
-  'nm-modem.c',
-  'nm-modem-manager.c',
-)
-
-deps = [
-  daemon_nm_default_dep,
-  libsystemd_dep,
-  mm_glib_dep,
-]
-
-if enable_ofono
-  sources += files('nm-modem-ofono.c')
-endif
-
-linker_script = join_paths(meson.current_source_dir(), 'libnm-wwan.ver')
-
-libnm_wwan = shared_module(
-  'nm-wwan',
-  sources: sources,
-  dependencies: deps,
-  c_args: daemon_c_flags,
-  link_args: '-Wl,--version-script,@0@'.format(linker_script),
-  link_depends: linker_script,
-  install: true,
-  install_dir: nm_plugindir,
-)
-
-wwan_inc = include_directories('.')
-
-libnm_wwan_dep = declare_dependency(
-  include_directories: wwan_inc,
-  link_with: libnm_wwan,
-)
-
-core_plugins += libnm_wwan
-
-test(
-  'check-wwan',
-  check_exports,
-  args: [libnm_wwan.full_path(), linker_script],
-)
-
-sources = files(
-  'nm-device-modem.c',
-  'nm-wwan-factory.c',
-)
-
-libnm_device_plugin_wwan = shared_module(
-  'nm-device-plugin-wwan',
-  sources: sources,
-  dependencies: deps,
-  c_args: daemon_c_flags,
-  link_with: libnm_wwan,
-  link_args: ldflags_linker_script_devices,
-  link_depends: linker_script_devices,
-  install: true,
-  install_dir: nm_plugindir,
-  install_rpath: nm_plugindir,
-)
-
-core_plugins += libnm_device_plugin_wwan
-
-run_target(
-  'check-local-devices-wwan',
-  command: [check_exports, libnm_device_plugin_wwan.full_path(), linker_script_devices],
-  depends: libnm_device_plugin_wwan,
-)
-
-if enable_tests
-  test_unit = 'test-service-providers'
-
-  exe = executable(
-    test_unit,
-    ['tests/' + test_unit + '.c'] + nm_service_providers_source,
-    include_directories: wwan_inc,
-    dependencies: libnetwork_manager_test_dep,
-    c_args: test_c_flags,
-  )
-
-  test(
-    'wwan/' + test_unit,
-    test_script,
-    timeout: default_test_timeout,
-    args: test_args + [exe.full_path()],
-  )
-endif
diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
deleted file mode 100644
index f77de85a..00000000
--- a/src/devices/wwan/nm-device-modem.c
+++ /dev/null
@@ -1,957 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2009 - 2019 Red Hat, Inc.
- */
-
-#include "nm-default.h"
-
-#include "nm-device-modem.h"
-
-#include "nm-modem.h"
-#include "nm-ip4-config.h"
-#include "devices/nm-device-private.h"
-#include "nm-rfkill-manager.h"
-#include "settings/nm-settings-connection.h"
-#include "nm-modem-broadband.h"
-#include "NetworkManagerUtils.h"
-#include "nm-core-internal.h"
-
-#include "devices/nm-device-logging.h"
-_LOG_DECLARE_SELF(NMDeviceModem);
-
-/*****************************************************************************/
-
-NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceModem,
-                             PROP_MODEM,
-                             PROP_CAPABILITIES,
-                             PROP_CURRENT_CAPABILITIES,
-                             PROP_DEVICE_ID,
-                             PROP_OPERATOR_CODE,
-                             PROP_APN, );
-
-typedef struct {
-    NMModem *                 modem;
-    NMDeviceModemCapabilities caps;
-    NMDeviceModemCapabilities current_caps;
-    char *                    device_id;
-    char *                    operator_code;
-    char *                    apn;
-    bool                      rf_enabled : 1;
-    NMDeviceStageState        stage1_state : 3;
-} NMDeviceModemPrivate;
-
-struct _NMDeviceModem {
-    NMDevice             parent;
-    NMDeviceModemPrivate _priv;
-};
-
-struct _NMDeviceModemClass {
-    NMDeviceClass parent;
-};
-
-G_DEFINE_TYPE(NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE)
-
-#define NM_DEVICE_MODEM_GET_PRIVATE(self) \
-    _NM_GET_PRIVATE(self, NMDeviceModem, NM_IS_DEVICE_MODEM, NMDevice)
-
-/*****************************************************************************/
-
-static void
-ppp_failed(NMModem *modem, guint i_reason, gpointer user_data)
-{
-    NMDevice *          device = NM_DEVICE(user_data);
-    NMDeviceModem *     self   = NM_DEVICE_MODEM(user_data);
-    NMDeviceStateReason reason = i_reason;
-
-    switch (nm_device_get_state(device)) {
-    case NM_DEVICE_STATE_PREPARE:
-    case NM_DEVICE_STATE_CONFIG:
-    case NM_DEVICE_STATE_NEED_AUTH:
-        nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, reason);
-        break;
-    case NM_DEVICE_STATE_IP_CONFIG:
-    case NM_DEVICE_STATE_IP_CHECK:
-    case NM_DEVICE_STATE_SECONDARIES:
-    case NM_DEVICE_STATE_ACTIVATED:
-        if (nm_device_activate_ip4_state_in_conf(device))
-            nm_device_activate_schedule_ip_config_timeout(device, AF_INET);
-        else if (nm_device_activate_ip6_state_in_conf(device))
-            nm_device_activate_schedule_ip_config_timeout(device, AF_INET6);
-        else if (nm_device_activate_ip4_state_done(device)) {
-            nm_device_ip_method_failed(device,
-                                       AF_INET,
-                                       NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
-        } else if (nm_device_activate_ip6_state_done(device)) {
-            nm_device_ip_method_failed(device,
-                                       AF_INET6,
-                                       NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
-        } else {
-            _LOGW(LOGD_MB,
-                  "PPP failure in unexpected state %u",
-                  (guint) nm_device_get_state(device));
-            nm_device_state_changed(device,
-                                    NM_DEVICE_STATE_FAILED,
-                                    NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
-        }
-        break;
-    default:
-        break;
-    }
-}
-
-static void
-modem_prepare_result(NMModem *modem, gboolean success, guint i_reason, gpointer user_data)
-{
-    NMDeviceModem *       self   = NM_DEVICE_MODEM(user_data);
-    NMDeviceModemPrivate *priv   = NM_DEVICE_MODEM_GET_PRIVATE(self);
-    NMDevice *            device = NM_DEVICE(self);
-    NMDeviceStateReason   reason = i_reason;
-
-    if (nm_device_get_state(device) != NM_DEVICE_STATE_PREPARE
-        || priv->stage1_state != NM_DEVICE_STAGE_STATE_PENDING) {
-        nm_assert_not_reached();
-        success = FALSE;
-    }
-
-    if (!success) {
-        /* There are several reasons to block autoconnection at device level:
-         *
-         *  - Wrong SIM-PIN: The device won't autoconnect because it doesn't make sense
-         *    to retry the connection with the same PIN. This error also makes autoconnection
-         *    blocked at settings level, so not even a modem unplug and replug will allow
-         *    autoconnection again. It is somewhat redundant to block autoconnection at
-         *    both device and setting level really.
-         *
-         *  - SIM wrong or not inserted: If the modem is reporting a SIM not inserted error,
-         *    we can block autoconnection at device level, so that if the same device is
-         *    unplugged and replugged with a SIM (or if a SIM hotplug event happens in MM,
-         *    recreating the device completely), we can try the autoconnection again.
-         *
-         *  - Modem initialization failed: For some reason unknown to NM, the modem wasn't
-         *    initialized correctly, which leads to an unusable device. A device unplug and
-         *    replug may solve the issue, so make it a device-level autoconnection blocking
-         *    reason.
-         */
-        switch (nm_device_state_reason_check(reason)) {
-        case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED:
-        case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED:
-        case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT:
-            nm_device_autoconnect_blocked_set(device, NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN);
-            break;
-        case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED:
-        case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG:
-            nm_device_autoconnect_blocked_set(device, NM_DEVICE_AUTOCONNECT_BLOCKED_SIM_MISSING);
-            break;
-        case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED:
-            nm_device_autoconnect_blocked_set(device, NM_DEVICE_AUTOCONNECT_BLOCKED_INIT_FAILED);
-            break;
-        default:
-            break;
-        }
-        nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, reason);
-        return;
-    }
-
-    priv->stage1_state = NM_DEVICE_STAGE_STATE_COMPLETED;
-    nm_device_activate_schedule_stage1_device_prepare(device, FALSE);
-}
-
-static void
-modem_auth_requested(NMModem *modem, gpointer user_data)
-{
-    NMDevice *device = NM_DEVICE(user_data);
-
-    /* Auth requests (PIN, PAP/CHAP passwords, etc) only get handled
-     * during activation.
-     */
-    if (!nm_device_is_activating(device))
-        return;
-
-    nm_device_state_changed(device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
-}
-
-static void
-modem_auth_result(NMModem *modem, GError *error, gpointer user_data)
-{
-    NMDevice *            device = NM_DEVICE(user_data);
-    NMDeviceModemPrivate *priv   = NM_DEVICE_MODEM_GET_PRIVATE(device);
-
-    g_return_if_fail(nm_device_get_state(device) == NM_DEVICE_STATE_NEED_AUTH);
-
-    if (error) {
-        nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
-        return;
-    }
-
-    priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT;
-    nm_device_activate_schedule_stage1_device_prepare(device, FALSE);
-}
-
-static void
-modem_ip4_config_result(NMModem *modem, NMIP4Config *config, GError *error, gpointer user_data)
-{
-    NMDeviceModem *self   = NM_DEVICE_MODEM(user_data);
-    NMDevice *     device = NM_DEVICE(self);
-
-    g_return_if_fail(nm_device_activate_ip4_state_in_conf(device) == TRUE);
-
-    if (error) {
-        _LOGW(LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: %s", error->message);
-        nm_device_ip_method_failed(device, AF_INET, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
-    } else {
-        nm_device_set_dev2_ip_config(device, AF_INET, NM_IP_CONFIG_CAST(config));
-        nm_device_activate_schedule_ip_config_result(device, AF_INET, NULL);
-    }
-}
-
-static void
-modem_ip6_config_result(NMModem *    modem,
-                        NMIP6Config *config,
-                        gboolean     do_slaac,
-                        GError *     error,
-                        gpointer     user_data)
-{
-    NMDeviceModem *     self   = NM_DEVICE_MODEM(user_data);
-    NMDevice *          device = NM_DEVICE(self);
-    NMActStageReturn    ret;
-    NMDeviceStateReason failure_reason      = NM_DEVICE_STATE_REASON_NONE;
-    gs_unref_object NMIP6Config *ignored    = NULL;
-    gboolean                     got_config = !!config;
-
-    g_return_if_fail(nm_device_activate_ip6_state_in_conf(device) == TRUE);
-
-    if (error) {
-        _LOGW(LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s", error->message);
-        nm_device_ip_method_failed(device, AF_INET6, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
-        return;
-    }
-
-    /* Re-enable IPv6 on the interface */
-    nm_device_sysctl_ip_conf_set(device, AF_INET6, "disable_ipv6", "0");
-
-    if (config)
-        nm_device_set_dev2_ip_config(device, AF_INET6, NM_IP_CONFIG_CAST(config));
-
-    if (do_slaac == FALSE) {
-        if (got_config)
-            nm_device_activate_schedule_ip_config_result(device, AF_INET6, NULL);
-        else {
-            _LOGW(LOGD_MB | LOGD_IP6,
-                  "retrieving IPv6 configuration failed: SLAAC not requested and no addresses");
-            nm_device_ip_method_failed(device,
-                                       AF_INET6,
-                                       NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
-        }
-        return;
-    }
-
-    /* Start SLAAC now that we have a link-local address from the modem */
-    ret =
-        NM_DEVICE_CLASS(nm_device_modem_parent_class)
-            ->act_stage3_ip_config_start(device, AF_INET6, (gpointer *) &ignored, &failure_reason);
-
-    nm_assert(ignored == NULL);
-
-    switch (ret) {
-    case NM_ACT_STAGE_RETURN_FAILURE:
-        nm_device_ip_method_failed(device, AF_INET6, failure_reason);
-        break;
-    case NM_ACT_STAGE_RETURN_IP_FAIL:
-        /* all done */
-        nm_device_activate_schedule_ip_config_result(device, AF_INET6, NULL);
-        break;
-    case NM_ACT_STAGE_RETURN_POSTPONE:
-        /* let SLAAC run */
-        break;
-    default:
-        /* Should never get here since we've assured that the IPv6 method
-         * will either be "auto" or "ignored" when starting IPv6 configuration.
-         */
-        nm_assert_not_reached();
-    }
-}
-
-static void
-ip_ifindex_changed_cb(NMModem *modem, GParamSpec *pspec, gpointer user_data)
-{
-    NMDevice *device = NM_DEVICE(user_data);
-
-    if (!nm_device_is_activating(device))
-        return;
-
-    if (!nm_device_set_ip_ifindex(device, nm_modem_get_ip_ifindex(modem))) {
-        nm_device_state_changed(device,
-                                NM_DEVICE_STATE_FAILED,
-                                NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
-        return;
-    }
-
-    /* Disable IPv6 immediately on the interface since NM handles IPv6
-     * internally, and leaving it enabled could allow the kernel's IPv6
-     * RA handling code to run before NM is ready.
-     */
-    nm_device_sysctl_ip_conf_set(device, AF_INET6, "disable_ipv6", "1");
-}
-
-static void
-operator_code_changed_cb(NMModem *modem, GParamSpec *pspec, gpointer user_data)
-{
-    NMDeviceModem *       self          = NM_DEVICE_MODEM(user_data);
-    NMDeviceModemPrivate *priv          = NM_DEVICE_MODEM_GET_PRIVATE(self);
-    const char *          operator_code = nm_modem_get_operator_code(modem);
-
-    if (g_strcmp0(priv->operator_code, operator_code) != 0) {
-        g_free(priv->operator_code);
-        priv->operator_code = g_strdup(operator_code);
-        _notify(self, PROP_OPERATOR_CODE);
-    }
-}
-
-static void
-apn_changed_cb(NMModem *modem, GParamSpec *pspec, gpointer user_data)
-{
-    NMDeviceModem *       self = NM_DEVICE_MODEM(user_data);
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self);
-    const char *          apn  = nm_modem_get_apn(modem);
-
-    if (g_strcmp0(priv->apn, apn) != 0) {
-        g_free(priv->apn);
-        priv->apn = g_strdup(apn);
-        _notify(self, PROP_APN);
-    }
-}
-
-static void
-ids_changed_cb(NMModem *modem, GParamSpec *pspec, gpointer user_data)
-{
-    nm_device_recheck_available_connections(NM_DEVICE(user_data));
-}
-
-static void
-modem_state_cb(NMModem *modem, int new_state_i, int old_state_i, gpointer user_data)
-{
-    NMModemState          new_state = new_state_i;
-    NMModemState          old_state = old_state_i;
-    NMDevice *            device    = NM_DEVICE(user_data);
-    NMDeviceModemPrivate *priv      = NM_DEVICE_MODEM_GET_PRIVATE(device);
-    NMDeviceState         dev_state = nm_device_get_state(device);
-
-    if (new_state <= NM_MODEM_STATE_DISABLING && old_state > NM_MODEM_STATE_DISABLING
-        && priv->rf_enabled) {
-        /* Called when the ModemManager modem enabled state is changed externally
-         * to NetworkManager (eg something using MM's D-Bus API directly).
-         */
-        if (nm_device_is_activating(device) || dev_state == NM_DEVICE_STATE_ACTIVATED) {
-            /* user-initiated action, hence DISCONNECTED not FAILED */
-            nm_device_state_changed(device,
-                                    NM_DEVICE_STATE_DISCONNECTED,
-                                    NM_DEVICE_STATE_REASON_USER_REQUESTED);
-            return;
-        }
-    }
-
-    if (new_state < NM_MODEM_STATE_CONNECTING && old_state >= NM_MODEM_STATE_CONNECTING
-        && dev_state >= NM_DEVICE_STATE_NEED_AUTH && dev_state <= NM_DEVICE_STATE_ACTIVATED) {
-        /* Fail the device if the modem disconnects unexpectedly while the
-         * device is activating/activated. */
-        nm_device_state_changed(device,
-                                NM_DEVICE_STATE_FAILED,
-                                NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER);
-        return;
-    }
-
-    if (new_state > NM_MODEM_STATE_LOCKED && old_state == NM_MODEM_STATE_LOCKED) {
-        /* If the modem is now unlocked, enable/disable it according to the
-         * device's enabled/disabled state.
-         */
-        nm_modem_set_mm_enabled(priv->modem, priv->rf_enabled);
-
-        if (dev_state == NM_DEVICE_STATE_NEED_AUTH) {
-            /* The modem was unlocked externally to NetworkManager,
-             * deactivate so the default connection can be
-             * automatically activated again */
-            nm_device_state_changed(device,
-                                    NM_DEVICE_STATE_DEACTIVATING,
-                                    NM_DEVICE_STATE_REASON_MODEM_AVAILABLE);
-        }
-
-        /* Now allow connections without a PIN to be available */
-        nm_device_recheck_available_connections(device);
-    }
-
-    nm_device_queue_recheck_available(device,
-                                      NM_DEVICE_STATE_REASON_MODEM_AVAILABLE,
-                                      NM_DEVICE_STATE_REASON_MODEM_FAILED);
-}
-
-static void
-modem_removed_cb(NMModem *modem, gpointer user_data)
-{
-    g_signal_emit_by_name(NM_DEVICE(user_data), NM_DEVICE_REMOVED);
-}
-
-/*****************************************************************************/
-
-static gboolean
-owns_iface(NMDevice *device, const char *iface)
-{
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device);
-
-    g_return_val_if_fail(priv->modem, FALSE);
-
-    return nm_modem_owns_port(priv->modem, iface);
-}
-
-/*****************************************************************************/
-
-static void
-device_state_changed(NMDevice *          device,
-                     NMDeviceState       new_state,
-                     NMDeviceState       old_state,
-                     NMDeviceStateReason reason)
-{
-    NMDeviceModem *       self = NM_DEVICE_MODEM(device);
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self);
-
-    g_return_if_fail(priv->modem);
-
-    if (new_state == NM_DEVICE_STATE_UNAVAILABLE && old_state < NM_DEVICE_STATE_UNAVAILABLE) {
-        /* Log initial modem state */
-        _LOGI(LOGD_MB,
-              "modem state '%s'",
-              nm_modem_state_to_string(nm_modem_get_state(priv->modem)));
-    }
-    nm_modem_device_state_changed(priv->modem, new_state, old_state);
-}
-
-static NMDeviceCapabilities
-get_generic_capabilities(NMDevice *device)
-{
-    return NM_DEVICE_CAP_IS_NON_KERNEL;
-}
-
-static const char *
-get_type_description(NMDevice *device)
-{
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device);
-
-    if (NM_FLAGS_HAS(priv->current_caps, NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS))
-        return "gsm";
-    if (NM_FLAGS_HAS(priv->current_caps, NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO))
-        return "cdma";
-    return NM_DEVICE_CLASS(nm_device_modem_parent_class)->get_type_description(device);
-}
-
-static gboolean
-check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error)
-{
-    GError *local = NULL;
-
-    if (!NM_DEVICE_CLASS(nm_device_modem_parent_class)
-             ->check_connection_compatible(device, connection, error))
-        return FALSE;
-
-    if (!nm_modem_check_connection_compatible(NM_DEVICE_MODEM_GET_PRIVATE(device)->modem,
-                                              connection,
-                                              error ? &local : NULL)) {
-        if (error) {
-            g_set_error(error,
-                        NM_UTILS_ERROR,
-                        g_error_matches(local,
-                                        NM_UTILS_ERROR,
-                                        NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE)
-                            ? NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE
-                            : NM_UTILS_ERROR_UNKNOWN,
-                        "modem is incompatible with connection: %s",
-                        local->message);
-            g_error_free(local);
-        }
-        return FALSE;
-    }
-    return TRUE;
-}
-
-static gboolean
-check_connection_available(NMDevice *                     device,
-                           NMConnection *                 connection,
-                           NMDeviceCheckConAvailableFlags flags,
-                           const char *                   specific_object,
-                           GError **                      error)
-{
-    NMDeviceModem *       self = NM_DEVICE_MODEM(device);
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self);
-    NMModemState          state;
-
-    if (!priv->rf_enabled) {
-        nm_utils_error_set_literal(error,
-                                   NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                                   "RFKILL for modem enabled");
-        return FALSE;
-    }
-
-    if (!priv->modem) {
-        nm_utils_error_set_literal(error,
-                                   NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                                   "modem not available");
-        return FALSE;
-    }
-
-    state = nm_modem_get_state(priv->modem);
-    if (state <= NM_MODEM_STATE_INITIALIZING) {
-        nm_utils_error_set_literal(error,
-                                   NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                                   "modem not initialized");
-        return FALSE;
-    }
-
-    if (state == NM_MODEM_STATE_LOCKED) {
-        if (!nm_connection_get_setting_gsm(connection)) {
-            nm_utils_error_set_literal(error,
-                                       NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                                       "modem is locked without pin available");
-            return FALSE;
-        }
-    }
-
-    return TRUE;
-}
-
-static gboolean
-complete_connection(NMDevice *           device,
-                    NMConnection *       connection,
-                    const char *         specific_object,
-                    NMConnection *const *existing_connections,
-                    GError **            error)
-{
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device);
-
-    return nm_modem_complete_connection(priv->modem,
-                                        nm_device_get_iface(device),
-                                        connection,
-                                        existing_connections,
-                                        error);
-}
-
-static void
-deactivate(NMDevice *device)
-{
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device);
-
-    nm_modem_deactivate(priv->modem, device);
-    priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT;
-}
-
-/*****************************************************************************/
-
-static void
-modem_deactivate_async_cb(NMModem *modem, GError *error, gpointer user_data)
-{
-    gs_unref_object NMDevice * self = NULL;
-    NMDeviceDeactivateCallback callback;
-    gpointer                   callback_user_data;
-
-    nm_utils_user_data_unpack(user_data, &self, &callback, &callback_user_data);
-    callback(self, error, callback_user_data);
-}
-
-static void
-deactivate_async(NMDevice *                 self,
-                 GCancellable *             cancellable,
-                 NMDeviceDeactivateCallback callback,
-                 gpointer                   user_data)
-{
-    nm_assert(G_IS_CANCELLABLE(cancellable));
-    nm_assert(callback);
-
-    nm_modem_deactivate_async(NM_DEVICE_MODEM_GET_PRIVATE(self)->modem,
-                              self,
-                              cancellable,
-                              modem_deactivate_async_cb,
-                              nm_utils_user_data_pack(g_object_ref(self), callback, user_data));
-}
-
-/*****************************************************************************/
-
-static NMActStageReturn
-act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
-{
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device);
-    NMActRequest *        req;
-
-    req = nm_device_get_act_request(device);
-    g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE);
-
-    if (priv->stage1_state == NM_DEVICE_STAGE_STATE_INIT) {
-        priv->stage1_state = NM_DEVICE_STAGE_STATE_PENDING;
-        return nm_modem_act_stage1_prepare(NM_DEVICE_MODEM_GET_PRIVATE(device)->modem,
-                                           req,
-                                           out_failure_reason);
-    }
-
-    if (priv->stage1_state == NM_DEVICE_STAGE_STATE_PENDING)
-        return NM_ACT_STAGE_RETURN_POSTPONE;
-
-    nm_assert(priv->stage1_state == NM_DEVICE_STAGE_STATE_COMPLETED);
-    return NM_ACT_STAGE_RETURN_SUCCESS;
-}
-
-static NMActStageReturn
-act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
-{
-    nm_modem_act_stage2_config(NM_DEVICE_MODEM_GET_PRIVATE(device)->modem);
-    return NM_ACT_STAGE_RETURN_SUCCESS;
-}
-
-static NMActStageReturn
-act_stage3_ip_config_start(NMDevice *           device,
-                           int                  addr_family,
-                           gpointer *           out_config,
-                           NMDeviceStateReason *out_failure_reason)
-{
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device);
-
-    nm_assert_addr_family(addr_family);
-
-    if (addr_family == AF_INET) {
-        return nm_modem_stage3_ip4_config_start(priv->modem,
-                                                device,
-                                                NM_DEVICE_CLASS(nm_device_modem_parent_class),
-                                                out_failure_reason);
-    } else {
-        return nm_modem_stage3_ip6_config_start(priv->modem, device, out_failure_reason);
-    }
-}
-
-static void
-ip4_config_pre_commit(NMDevice *device, NMIP4Config *config)
-{
-    nm_modem_ip4_pre_commit(NM_DEVICE_MODEM_GET_PRIVATE(device)->modem, device, config);
-}
-
-static gboolean
-get_ip_iface_identifier(NMDevice *device, NMUtilsIPv6IfaceId *out_iid)
-{
-    NMDeviceModem *       self = NM_DEVICE_MODEM(device);
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self);
-    gboolean              success;
-
-    g_return_val_if_fail(priv->modem, FALSE);
-    success = nm_modem_get_iid(priv->modem, out_iid);
-    if (!success)
-        success =
-            NM_DEVICE_CLASS(nm_device_modem_parent_class)->get_ip_iface_identifier(device, out_iid);
-    return success;
-}
-
-/*****************************************************************************/
-
-static gboolean
-get_enabled(NMDevice *device)
-{
-    NMDeviceModemPrivate *priv        = NM_DEVICE_MODEM_GET_PRIVATE(device);
-    NMModemState          modem_state = nm_modem_get_state(priv->modem);
-
-    return priv->rf_enabled && (modem_state >= NM_MODEM_STATE_LOCKED);
-}
-
-static void
-set_enabled(NMDevice *device, gboolean enabled)
-{
-    NMDeviceModem *       self = NM_DEVICE_MODEM(device);
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self);
-
-    /* Called only by the Manager in response to rfkill switch changes or
-     * global user WWAN enable/disable preference changes.
-     */
-    priv->rf_enabled = enabled;
-
-    if (priv->modem) {
-        /* Sync the ModemManager modem enabled/disabled with rfkill/user preference */
-        nm_modem_set_mm_enabled(priv->modem, enabled);
-    }
-
-    if (enabled == FALSE) {
-        nm_device_state_changed(device, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_NONE);
-    }
-}
-
-static gboolean
-is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
-{
-    NMDeviceModem *       self = NM_DEVICE_MODEM(device);
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self);
-    NMModemState          modem_state;
-
-    if (!priv->rf_enabled)
-        return FALSE;
-
-    g_assert(priv->modem);
-    modem_state = nm_modem_get_state(priv->modem);
-    if (modem_state <= NM_MODEM_STATE_INITIALIZING)
-        return FALSE;
-
-    return TRUE;
-}
-
-/*****************************************************************************/
-
-static void
-set_modem(NMDeviceModem *self, NMModem *modem)
-{
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self);
-
-    g_return_if_fail(modem != NULL);
-
-    priv->modem = nm_modem_claim(modem);
-
-    g_signal_connect(modem, NM_MODEM_PPP_FAILED, G_CALLBACK(ppp_failed), self);
-    g_signal_connect(modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK(modem_prepare_result), self);
-    g_signal_connect(modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK(modem_ip4_config_result), self);
-    g_signal_connect(modem, NM_MODEM_IP6_CONFIG_RESULT, G_CALLBACK(modem_ip6_config_result), self);
-    g_signal_connect(modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK(modem_auth_requested), self);
-    g_signal_connect(modem, NM_MODEM_AUTH_RESULT, G_CALLBACK(modem_auth_result), self);
-    g_signal_connect(modem, NM_MODEM_STATE_CHANGED, G_CALLBACK(modem_state_cb), self);
-    g_signal_connect(modem, NM_MODEM_REMOVED, G_CALLBACK(modem_removed_cb), self);
-
-    g_signal_connect(modem,
-                     "notify::" NM_MODEM_IP_IFINDEX,
-                     G_CALLBACK(ip_ifindex_changed_cb),
-                     self);
-    g_signal_connect(modem, "notify::" NM_MODEM_DEVICE_ID, G_CALLBACK(ids_changed_cb), self);
-    g_signal_connect(modem, "notify::" NM_MODEM_SIM_ID, G_CALLBACK(ids_changed_cb), self);
-    g_signal_connect(modem, "notify::" NM_MODEM_SIM_OPERATOR_ID, G_CALLBACK(ids_changed_cb), self);
-    g_signal_connect(modem,
-                     "notify::" NM_MODEM_OPERATOR_CODE,
-                     G_CALLBACK(operator_code_changed_cb),
-                     self);
-    g_signal_connect(modem, "notify::" NM_MODEM_APN, G_CALLBACK(apn_changed_cb), self);
-}
-
-static guint32
-get_dhcp_timeout_for_device(NMDevice *device, int addr_family)
-{
-    /* DHCP is always done by the modem firmware, not by the network, and
-     * by the time we get around to DHCP the firmware should already know
-     * the IP addressing details.  So the DHCP timeout can be much shorter.
-     */
-    return 15;
-}
-
-/*****************************************************************************/
-
-static void
-get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(object);
-
-    switch (prop_id) {
-    case PROP_MODEM:
-        g_value_set_object(value, priv->modem);
-        break;
-    case PROP_CAPABILITIES:
-        g_value_set_uint(value, priv->caps);
-        break;
-    case PROP_CURRENT_CAPABILITIES:
-        g_value_set_uint(value, priv->current_caps);
-        break;
-    case PROP_DEVICE_ID:
-        g_value_set_string(value, priv->device_id);
-        break;
-    case PROP_OPERATOR_CODE:
-        g_value_set_string(value, priv->operator_code);
-        break;
-    case PROP_APN:
-        g_value_set_string(value, priv->apn);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(object);
-
-    switch (prop_id) {
-    case PROP_MODEM:
-        /* construct-only */
-        set_modem(NM_DEVICE_MODEM(object), g_value_get_object(value));
-        break;
-    case PROP_CAPABILITIES:
-        priv->caps = g_value_get_uint(value);
-        break;
-    case PROP_CURRENT_CAPABILITIES:
-        priv->current_caps = g_value_get_uint(value);
-        break;
-    case PROP_DEVICE_ID:
-        /* construct-only */
-        priv->device_id = g_value_dup_string(value);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-/*****************************************************************************/
-
-static void
-nm_device_modem_init(NMDeviceModem *self)
-{}
-
-NMDevice *
-nm_device_modem_new(NMModem *modem)
-{
-    NMDeviceModemCapabilities caps         = NM_DEVICE_MODEM_CAPABILITY_NONE;
-    NMDeviceModemCapabilities current_caps = NM_DEVICE_MODEM_CAPABILITY_NONE;
-
-    g_return_val_if_fail(NM_IS_MODEM(modem), NULL);
-
-    /* Load capabilities */
-    nm_modem_get_capabilities(modem, &caps, &current_caps);
-
-    return g_object_new(NM_TYPE_DEVICE_MODEM,
-                        NM_DEVICE_UDI,
-                        nm_modem_get_path(modem),
-                        NM_DEVICE_IFACE,
-                        nm_modem_get_uid(modem),
-                        NM_DEVICE_DRIVER,
-                        nm_modem_get_driver(modem),
-                        NM_DEVICE_TYPE_DESC,
-                        "Broadband",
-                        NM_DEVICE_DEVICE_TYPE,
-                        NM_DEVICE_TYPE_MODEM,
-                        NM_DEVICE_RFKILL_TYPE,
-                        RFKILL_TYPE_WWAN,
-                        NM_DEVICE_MODEM_MODEM,
-                        modem,
-                        NM_DEVICE_MODEM_CAPABILITIES,
-                        caps,
-                        NM_DEVICE_MODEM_CURRENT_CAPABILITIES,
-                        current_caps,
-                        NM_DEVICE_MODEM_DEVICE_ID,
-                        nm_modem_get_device_id(modem),
-                        NULL);
-}
-
-static void
-dispose(GObject *object)
-{
-    NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(object);
-
-    if (priv->modem) {
-        g_signal_handlers_disconnect_by_data(priv->modem, NM_DEVICE_MODEM(object));
-        nm_clear_pointer(&priv->modem, nm_modem_unclaim);
-    }
-
-    nm_clear_g_free(&priv->device_id);
-    nm_clear_g_free(&priv->operator_code);
-    nm_clear_g_free(&priv->apn);
-
-    G_OBJECT_CLASS(nm_device_modem_parent_class)->dispose(object);
-}
-
-static const NMDBusInterfaceInfoExtended interface_info_device_modem = {
-    .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
-        NM_DBUS_INTERFACE_DEVICE_MODEM,
-        .signals    = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ),
-        .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
-            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("ModemCapabilities",
-                                                             "u",
-                                                             NM_DEVICE_MODEM_CAPABILITIES),
-            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("CurrentCapabilities",
-                                                             "u",
-                                                             NM_DEVICE_MODEM_CURRENT_CAPABILITIES),
-            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DeviceId",
-                                                           "s",
-                                                           NM_DEVICE_MODEM_DEVICE_ID),
-            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("OperatorCode",
-                                                           "s",
-                                                           NM_DEVICE_MODEM_OPERATOR_CODE),
-            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Apn", "s", NM_DEVICE_MODEM_APN), ), ),
-    .legacy_property_changed = TRUE,
-};
-
-static void
-nm_device_modem_class_init(NMDeviceModemClass *klass)
-{
-    GObjectClass *     object_class      = G_OBJECT_CLASS(klass);
-    NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
-    NMDeviceClass *    device_class      = NM_DEVICE_CLASS(klass);
-
-    object_class->dispose      = dispose;
-    object_class->get_property = get_property;
-    object_class->set_property = set_property;
-
-    dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_modem);
-
-    device_class->get_generic_capabilities    = get_generic_capabilities;
-    device_class->get_type_description        = get_type_description;
-    device_class->check_connection_compatible = check_connection_compatible;
-    device_class->check_connection_available  = check_connection_available;
-    device_class->complete_connection         = complete_connection;
-    device_class->deactivate_async            = deactivate_async;
-    device_class->deactivate                  = deactivate;
-    device_class->act_stage1_prepare          = act_stage1_prepare;
-    device_class->act_stage2_config           = act_stage2_config;
-    device_class->act_stage3_ip_config_start  = act_stage3_ip_config_start;
-    device_class->ip4_config_pre_commit       = ip4_config_pre_commit;
-    device_class->get_enabled                 = get_enabled;
-    device_class->set_enabled                 = set_enabled;
-    device_class->owns_iface                  = owns_iface;
-    device_class->is_available                = is_available;
-    device_class->get_ip_iface_identifier     = get_ip_iface_identifier;
-    device_class->get_configured_mtu          = nm_modem_get_configured_mtu;
-    device_class->get_dhcp_timeout_for_device = get_dhcp_timeout_for_device;
-
-    device_class->state_changed = device_state_changed;
-
-    obj_properties[PROP_MODEM] =
-        g_param_spec_object(NM_DEVICE_MODEM_MODEM,
-                            "",
-                            "",
-                            NM_TYPE_MODEM,
-                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_CAPABILITIES] =
-        g_param_spec_uint(NM_DEVICE_MODEM_CAPABILITIES,
-                          "",
-                          "",
-                          0,
-                          G_MAXUINT32,
-                          NM_DEVICE_MODEM_CAPABILITY_NONE,
-                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_CURRENT_CAPABILITIES] =
-        g_param_spec_uint(NM_DEVICE_MODEM_CURRENT_CAPABILITIES,
-                          "",
-                          "",
-                          0,
-                          G_MAXUINT32,
-                          NM_DEVICE_MODEM_CAPABILITY_NONE,
-                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_DEVICE_ID] =
-        g_param_spec_string(NM_DEVICE_MODEM_DEVICE_ID,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_OPERATOR_CODE] =
-        g_param_spec_string(NM_DEVICE_MODEM_OPERATOR_CODE,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_APN] = g_param_spec_string(NM_DEVICE_MODEM_APN,
-                                                   "",
-                                                   "",
-                                                   NULL,
-                                                   G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-}
diff --git a/src/devices/wwan/nm-device-modem.h b/src/devices/wwan/nm-device-modem.h
deleted file mode 100644
index caabeb6c..00000000
--- a/src/devices/wwan/nm-device-modem.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2011 Red Hat, Inc.
- */
-
-#ifndef __NETWORKMANAGER_DEVICE_MODEM_H__
-#define __NETWORKMANAGER_DEVICE_MODEM_H__
-
-#include "devices/nm-device.h"
-#include "nm-modem.h"
-
-#define NM_TYPE_DEVICE_MODEM (nm_device_modem_get_type())
-#define NM_DEVICE_MODEM(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_MODEM, NMDeviceModem))
-#define NM_DEVICE_MODEM_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_MODEM, NMDeviceModemClass))
-#define NM_IS_DEVICE_MODEM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_MODEM))
-#define NM_IS_DEVICE_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_MODEM))
-#define NM_DEVICE_MODEM_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_MODEM, NMDeviceModemClass))
-
-#define NM_DEVICE_MODEM_MODEM                "modem"
-#define NM_DEVICE_MODEM_CAPABILITIES         "modem-capabilities"
-#define NM_DEVICE_MODEM_CURRENT_CAPABILITIES "current-capabilities"
-#define NM_DEVICE_MODEM_DEVICE_ID            "device-id"
-#define NM_DEVICE_MODEM_OPERATOR_CODE        "operator-code"
-#define NM_DEVICE_MODEM_APN                  "apn"
-
-typedef struct _NMDeviceModem      NMDeviceModem;
-typedef struct _NMDeviceModemClass NMDeviceModemClass;
-
-GType nm_device_modem_get_type(void);
-
-NMDevice *nm_device_modem_new(NMModem *modem);
-
-#endif /* __NETWORKMANAGER_DEVICE_MODEM_H__ */
diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c
deleted file mode 100644
index 7b3a13a3..00000000
--- a/src/devices/wwan/nm-modem-broadband.c
+++ /dev/null
@@ -1,1625 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org>
- */
-
-#include "nm-default.h"
-
-#include "nm-modem-broadband.h"
-#include "nm-service-providers.h"
-
-#include <arpa/inet.h>
-#include <libmm-glib.h>
-
-#include "nm-core-internal.h"
-#include "NetworkManagerUtils.h"
-#include "devices/nm-device-private.h"
-#include "platform/nm-platform.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
-
-#define NM_MODEM_BROADBAND_MODEM "modem"
-
-static gboolean
-MODEM_CAPS_3GPP(MMModemCapability caps)
-{
-    G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-    /* MM_MODEM_CAPABILITY_LTE_ADVANCED is marked as deprecated since ModemManager 1.14.0.
-     *
-     * The flag probably was never used, it certainly isn't used since 1.14.0.
-     *
-     * Still, just to be sure, there is no harm in checking it here. Suppress the
-     * warning, it should have no bad effect.
-     */
-    return NM_FLAGS_ANY(caps,
-                        (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_LTE
-                         | MM_MODEM_CAPABILITY_LTE_ADVANCED));
-    G_GNUC_END_IGNORE_DEPRECATIONS
-}
-
-#define MODEM_CAPS_3GPP2(caps) (caps & (MM_MODEM_CAPABILITY_CDMA_EVDO))
-
-/* Maximum time to keep the DBus call waiting for a connection result.
- * This value is greater than the default timeout in ModemManager (180s since
- * 1.16), so that whenever possible the timeout happens first there instead of
- * in NetworkManager. */
-#define MODEM_CONNECT_TIMEOUT_SECS 200
-
-/*****************************************************************************/
-
-typedef enum {
-    CONNECT_STEP_FIRST,
-    CONNECT_STEP_WAIT_FOR_SIM,
-    CONNECT_STEP_UNLOCK,
-    CONNECT_STEP_WAIT_FOR_READY,
-    CONNECT_STEP_CONNECT,
-    CONNECT_STEP_LAST,
-} ConnectStep;
-
-typedef struct {
-    NMModemBroadband *self;
-    ConnectStep       step;
-
-    MMModemCapability          caps;
-    NMConnection *             connection;
-    GCancellable *             cancellable;
-    MMSimpleConnectProperties *connect_properties;
-    GArray *                   ip_types;
-    guint                      ip_types_i;
-    guint                      ip_type_tries;
-    GError *                   first_error;
-} ConnectContext;
-
-/*****************************************************************************/
-
-NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_MODEM, );
-
-typedef struct {
-    /* The modem object from dbus */
-    MMObject *modem_object;
-    /* Per-interface objects */
-    MMModem *      modem_iface;
-    MMModem3gpp *  modem_3gpp_iface;
-    MMModemSimple *simple_iface;
-    MMSim *        sim_iface;
-
-    /* Connection setup */
-    ConnectContext *ctx;
-
-    MMBearer *        bearer;
-    MMBearerIpConfig *ipv4_config;
-    MMBearerIpConfig *ipv6_config;
-
-    guint idle_id_ip4;
-    guint idle_id_ip6;
-
-    guint32 pin_tries;
-} NMModemBroadbandPrivate;
-
-struct _NMModemBroadband {
-    NMModem                 parent;
-    NMModemBroadbandPrivate _priv;
-};
-
-struct _NMModemBroadbandClass {
-    NMModemClass parent;
-};
-
-G_DEFINE_TYPE(NMModemBroadband, nm_modem_broadband, NM_TYPE_MODEM)
-
-#define NM_MODEM_BROADBAND_GET_PRIVATE(self) \
-    _NM_GET_PRIVATE(self, NMModemBroadband, NM_IS_MODEM_BROADBAND)
-
-/*****************************************************************************/
-
-#define _NMLOG_DOMAIN      LOGD_MB
-#define _NMLOG_PREFIX_NAME "modem-broadband"
-#define _NMLOG(level, ...)                                                       \
-    G_STMT_START                                                                 \
-    {                                                                            \
-        const NMLogLevel _level = (level);                                       \
-                                                                                 \
-        if (nm_logging_enabled(_level, (_NMLOG_DOMAIN))) {                       \
-            NMModemBroadband *const __self = (self);                             \
-            char                    __prefix_name[128];                          \
-            const char *            __uid;                                       \
-                                                                                 \
-            _nm_log(_level,                                                      \
-                    (_NMLOG_DOMAIN),                                             \
-                    0,                                                           \
-                    NULL,                                                        \
-                    ((__self && __self->_priv.ctx)                               \
-                         ? nm_connection_get_uuid(__self->_priv.ctx->connection) \
-                         : NULL),                                                \
-                    "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__),                 \
-                    _NMLOG_PREFIX_NAME,                                          \
-                    (__self ? ({                                                 \
-                        ((__uid = nm_modem_get_uid((NMModem *) __self))          \
-                             ? nm_sprintf_buf(__prefix_name, "[%s]", __uid)      \
-                             : "(null)");                                        \
-                    })                                                           \
-                            : "") _NM_UTILS_MACRO_REST(__VA_ARGS__));            \
-        }                                                                        \
-    }                                                                            \
-    G_STMT_END
-
-/*****************************************************************************/
-
-static NMDeviceStateReason
-translate_mm_error(NMModemBroadband *self, GError *error)
-{
-    NMDeviceStateReason reason;
-
-    g_return_val_if_fail(error != NULL, NM_DEVICE_STATE_REASON_UNKNOWN);
-
-    if (g_error_matches(error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_CARRIER))
-        reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER;
-    else if (g_error_matches(error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_DIALTONE))
-        reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE;
-    else if (g_error_matches(error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_BUSY))
-        reason = NM_DEVICE_STATE_REASON_MODEM_BUSY;
-    else if (g_error_matches(error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_ANSWER))
-        reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT;
-    else if (g_error_matches(error,
-                             MM_MOBILE_EQUIPMENT_ERROR,
-                             MM_MOBILE_EQUIPMENT_ERROR_NETWORK_NOT_ALLOWED))
-        reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED;
-    else if (g_error_matches(error,
-                             MM_MOBILE_EQUIPMENT_ERROR,
-                             MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT))
-        reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT;
-    else if (g_error_matches(error,
-                             MM_MOBILE_EQUIPMENT_ERROR,
-                             MM_MOBILE_EQUIPMENT_ERROR_NO_NETWORK))
-        reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING;
-    else if (g_error_matches(error,
-                             MM_MOBILE_EQUIPMENT_ERROR,
-                             MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED))
-        reason = NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED;
-    else if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN))
-        reason = NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED;
-    else if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK))
-        reason = NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED;
-    else if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG))
-        reason = NM_DEVICE_STATE_REASON_GSM_SIM_WRONG;
-    else if (g_error_matches(error,
-                             MM_MOBILE_EQUIPMENT_ERROR,
-                             MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD))
-        reason = NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT;
-    else {
-        /* unable to map the ModemManager error to a NM_DEVICE_STATE_REASON */
-        _LOGD("unmapped error detected: '%s'", error->message);
-        reason = NM_DEVICE_STATE_REASON_UNKNOWN;
-    }
-
-    return reason;
-}
-
-/*****************************************************************************/
-
-static void
-get_capabilities(NMModem *                  _self,
-                 NMDeviceModemCapabilities *modem_caps,
-                 NMDeviceModemCapabilities *current_caps)
-{
-    NMModemBroadband * self          = NM_MODEM_BROADBAND(_self);
-    MMModemCapability  all_supported = MM_MODEM_CAPABILITY_NONE;
-    MMModemCapability *supported;
-    guint              n_supported;
-
-    /* For now, we don't care about the capability combinations, just merge all
-     * combinations in a single mask */
-    if (mm_modem_get_supported_capabilities(self->_priv.modem_iface, &supported, &n_supported)) {
-        guint i;
-
-        for (i = 0; i < n_supported; i++)
-            all_supported |= supported[i];
-
-        g_free(supported);
-    }
-
-    *modem_caps = (NMDeviceModemCapabilities) all_supported;
-    *current_caps =
-        (NMDeviceModemCapabilities) mm_modem_get_current_capabilities(self->_priv.modem_iface);
-}
-
-static gboolean
-owns_port(NMModem *_self, const char *iface)
-{
-    NMModemBroadband *     self    = NM_MODEM_BROADBAND(_self);
-    const MMModemPortInfo *ports   = NULL;
-    guint                  n_ports = 0, i;
-
-    mm_modem_peek_ports(self->_priv.modem_iface, &ports, &n_ports);
-    for (i = 0; i < n_ports; i++) {
-        if (nm_streq0(iface, ports[i].name))
-            return TRUE;
-    }
-    return FALSE;
-}
-
-/*****************************************************************************/
-
-static void
-ask_for_pin(NMModemBroadband *self)
-{
-    guint32 tries;
-
-    tries = self->_priv.pin_tries++;
-    nm_modem_get_secrets(NM_MODEM(self),
-                         NM_SETTING_GSM_SETTING_NAME,
-                         tries ? TRUE : FALSE,
-                         NM_SETTING_GSM_PIN);
-}
-
-static NMModemIPMethod
-get_bearer_ip_method(MMBearerIpConfig *config)
-{
-    MMBearerIpMethod mm_method;
-
-    mm_method = mm_bearer_ip_config_get_method(config);
-    if (mm_method == MM_BEARER_IP_METHOD_PPP)
-        return NM_MODEM_IP_METHOD_PPP;
-    else if (mm_method == MM_BEARER_IP_METHOD_STATIC)
-        return NM_MODEM_IP_METHOD_STATIC;
-    else if (mm_method == MM_BEARER_IP_METHOD_DHCP)
-        return NM_MODEM_IP_METHOD_AUTO;
-    return NM_MODEM_IP_METHOD_UNKNOWN;
-}
-
-static MMSimpleConnectProperties *
-create_cdma_connect_properties(NMConnection *connection)
-{
-    MMSimpleConnectProperties *properties;
-
-    properties = mm_simple_connect_properties_new();
-
-#if !MM_CHECK_VERSION(1, 9, 1)
-    {
-        NMSettingCdma *setting;
-        const char *   str;
-
-        setting = nm_connection_get_setting_cdma(connection);
-        str     = nm_setting_cdma_get_number(setting);
-        if (str)
-            mm_simple_connect_properties_set_number(properties, str);
-    }
-#endif
-
-    return properties;
-}
-
-static MMSimpleConnectProperties *
-create_gsm_connect_properties(NMConnection *connection,
-                              const char *  apn,
-                              const char *  username,
-                              const char *  password)
-{
-    NMSettingGsm *             setting;
-    NMSettingPpp *             s_ppp;
-    MMSimpleConnectProperties *properties;
-    const char *               str;
-
-    setting = nm_connection_get_setting_gsm(connection);
-
-    properties = mm_simple_connect_properties_new();
-
-    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)
-        mm_simple_connect_properties_set_operator_id(properties, str);
-
-    str = nm_setting_gsm_get_pin(setting);
-    if (str)
-        mm_simple_connect_properties_set_pin(properties, str);
-
-    /* Roaming */
-    if (nm_setting_gsm_get_home_only(setting))
-        mm_simple_connect_properties_set_allow_roaming(properties, FALSE);
-
-    /* For IpMethod == STATIC or DHCP */
-    s_ppp = nm_connection_get_setting_ppp(connection);
-    if (s_ppp) {
-        MMBearerAllowedAuth allowed_auth = MM_BEARER_ALLOWED_AUTH_UNKNOWN;
-
-        if (nm_setting_ppp_get_noauth(s_ppp))
-            allowed_auth = MM_BEARER_ALLOWED_AUTH_NONE;
-        if (!nm_setting_ppp_get_refuse_pap(s_ppp))
-            allowed_auth |= MM_BEARER_ALLOWED_AUTH_PAP;
-        if (!nm_setting_ppp_get_refuse_chap(s_ppp))
-            allowed_auth |= MM_BEARER_ALLOWED_AUTH_CHAP;
-        if (!nm_setting_ppp_get_refuse_mschap(s_ppp))
-            allowed_auth |= MM_BEARER_ALLOWED_AUTH_MSCHAP;
-        if (!nm_setting_ppp_get_refuse_mschapv2(s_ppp))
-            allowed_auth |= MM_BEARER_ALLOWED_AUTH_MSCHAPV2;
-        if (!nm_setting_ppp_get_refuse_eap(s_ppp))
-            allowed_auth |= MM_BEARER_ALLOWED_AUTH_EAP;
-
-        mm_simple_connect_properties_set_allowed_auth(properties, allowed_auth);
-    }
-
-    return properties;
-}
-
-static void
-connect_context_clear(NMModemBroadband *self)
-{
-    if (self->_priv.ctx) {
-        ConnectContext *ctx = self->_priv.ctx;
-
-        g_clear_error(&ctx->first_error);
-        nm_clear_pointer(&ctx->ip_types, g_array_unref);
-        nm_clear_g_cancellable(&ctx->cancellable);
-        g_clear_object(&ctx->connection);
-        g_clear_object(&ctx->connect_properties);
-        g_clear_object(&ctx->self);
-        g_slice_free(ConnectContext, ctx);
-        self->_priv.ctx = NULL;
-    }
-}
-
-static void connect_context_step(NMModemBroadband *self);
-
-static void
-connect_ready(MMModemSimple *simple_iface, GAsyncResult *res, NMModemBroadband *self)
-{
-    ConnectContext *ctx;
-    GError *        error      = NULL;
-    NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN;
-    NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN;
-    MMBearer *      bearer;
-
-    bearer = mm_modem_simple_connect_finish(simple_iface, res, &error);
-
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-        g_error_free(error);
-        return;
-    }
-
-    ctx = self->_priv.ctx;
-
-    if (!ctx)
-        return;
-
-    self->_priv.bearer = bearer;
-
-    if (!self->_priv.bearer) {
-        if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN)
-            || (g_error_matches(error, MM_CORE_ERROR, MM_CORE_ERROR_UNAUTHORIZED)
-                && mm_modem_get_unlock_required(self->_priv.modem_iface)
-                       == MM_MODEM_LOCK_SIM_PIN)) {
-            g_error_free(error);
-
-            /* Request PIN */
-            ask_for_pin(self);
-            connect_context_clear(self);
-            return;
-        }
-
-        /* Save the error, if it's the first one */
-        if (!ctx->first_error) {
-            /* Strip remote error info before saving it */
-            if (g_dbus_error_is_remote_error(error))
-                g_dbus_error_strip_remote_error(error);
-            ctx->first_error = error;
-        } else
-            g_clear_error(&error);
-
-        if (ctx->ip_type_tries == 0 && g_error_matches(error, MM_CORE_ERROR, MM_CORE_ERROR_RETRY)) {
-            /* Try one more time */
-            ctx->ip_type_tries++;
-        } else {
-            /* If the modem/provider lies and the IP type we tried isn't supported,
-             * retry with the next one, if any.
-             */
-            ctx->ip_types_i++;
-            ctx->ip_type_tries = 0;
-        }
-        connect_context_step(self);
-        return;
-    }
-
-    /* Grab IP configurations */
-    self->_priv.ipv4_config = mm_bearer_get_ipv4_config(self->_priv.bearer);
-    if (self->_priv.ipv4_config)
-        ip4_method = get_bearer_ip_method(self->_priv.ipv4_config);
-
-    self->_priv.ipv6_config = mm_bearer_get_ipv6_config(self->_priv.bearer);
-    if (self->_priv.ipv6_config)
-        ip6_method = get_bearer_ip_method(self->_priv.ipv6_config);
-
-    if (!nm_modem_set_data_port(NM_MODEM(self),
-                                NM_PLATFORM_GET,
-                                mm_bearer_get_interface(self->_priv.bearer),
-                                ip4_method,
-                                ip6_method,
-                                mm_bearer_get_ip_timeout(self->_priv.bearer),
-                                &error)) {
-        _LOGW("failed to connect modem: %s", error->message);
-        g_error_free(error);
-        nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
-        connect_context_clear(self);
-        return;
-    }
-
-    ctx->step++;
-    connect_context_step(self);
-}
-
-static void
-send_pin_ready(MMSim *sim, GAsyncResult *result, NMModemBroadband *self)
-{
-    gs_free_error GError *error = NULL;
-
-    mm_sim_send_pin_finish(sim, result, &error);
-
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    if (!self->_priv.ctx || self->_priv.ctx->step != CONNECT_STEP_UNLOCK)
-        g_return_if_reached();
-
-    if (error) {
-        if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN)
-            || (g_error_matches(error, MM_CORE_ERROR, MM_CORE_ERROR_UNAUTHORIZED)
-                && mm_modem_get_unlock_required(self->_priv.modem_iface) == MM_MODEM_LOCK_SIM_PIN))
-            ask_for_pin(self);
-        else
-            nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, translate_mm_error(self, error));
-        return;
-    }
-
-    self->_priv.ctx->step++;
-    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)
-{
-    ConnectContext *ctx = self->_priv.ctx;
-
-    switch (ctx->step) {
-    case CONNECT_STEP_FIRST:
-        ctx->step++;
-        /* fall-through */
-
-    case CONNECT_STEP_WAIT_FOR_SIM:
-        if (MODEM_CAPS_3GPP(ctx->caps) && !self->_priv.sim_iface) {
-            /* Have to wait for the SIM to show up */
-            break;
-        }
-        ctx->step++;
-        /* fall-through */
-
-    case CONNECT_STEP_UNLOCK:
-        if (MODEM_CAPS_3GPP(ctx->caps)
-            && mm_modem_get_unlock_required(self->_priv.modem_iface) == MM_MODEM_LOCK_SIM_PIN) {
-            NMSettingGsm *s_gsm = nm_connection_get_setting_gsm(ctx->connection);
-            const char *  pin   = nm_setting_gsm_get_pin(s_gsm);
-
-            /* If we have a PIN already, send it.  If we don't, get it. */
-            if (pin) {
-                mm_sim_send_pin(self->_priv.sim_iface,
-                                pin,
-                                ctx->cancellable,
-                                (GAsyncReadyCallback) send_pin_ready,
-                                self);
-            } else {
-                ask_for_pin(self);
-            }
-            break;
-        }
-        ctx->step++;
-        /* fall-through */
-    case CONNECT_STEP_WAIT_FOR_READY:
-    {
-        GError *error = NULL;
-
-        if (mm_modem_get_state(self->_priv.modem_iface) <= MM_MODEM_STATE_LOCKED)
-            break;
-
-        if (!try_create_connect_properties(self))
-            break;
-
-        if (!self->_priv.ctx)
-            break;
-
-        /* 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);
-        if (!ctx->ip_types) {
-            _LOGW("failed to connect '%s': %s",
-                  nm_connection_get_id(ctx->connection),
-                  error->message);
-            g_clear_error(&error);
-
-            nm_modem_emit_prepare_result(NM_MODEM(self),
-                                         FALSE,
-                                         NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
-            connect_context_clear(self);
-            break;
-        }
-
-        ctx->step++;
-    }
-        /* fall-through */
-    case CONNECT_STEP_CONNECT:
-        if (!ctx->connect_properties)
-            break;
-
-        if (ctx->ip_types_i < ctx->ip_types->len) {
-            NMModemIPType current;
-
-            current = g_array_index(ctx->ip_types, NMModemIPType, ctx->ip_types_i);
-
-            if (current == NM_MODEM_IP_TYPE_IPV4)
-                mm_simple_connect_properties_set_ip_type(ctx->connect_properties,
-                                                         MM_BEARER_IP_FAMILY_IPV4);
-            else if (current == NM_MODEM_IP_TYPE_IPV6)
-                mm_simple_connect_properties_set_ip_type(ctx->connect_properties,
-                                                         MM_BEARER_IP_FAMILY_IPV6);
-            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_return_if_reached();
-
-            _nm_modem_set_apn(NM_MODEM(self),
-                              mm_simple_connect_properties_get_apn(ctx->connect_properties));
-
-            _LOGD("launching connection with ip type '%s' (try %d)",
-                  nm_modem_ip_type_to_string(current),
-                  ctx->ip_type_tries + 1);
-
-            mm_modem_simple_connect(self->_priv.simple_iface,
-                                    ctx->connect_properties,
-                                    ctx->cancellable,
-                                    (GAsyncReadyCallback) connect_ready,
-                                    self);
-            break;
-        }
-
-        ctx->step++;
-        /* fall-through */
-
-    case CONNECT_STEP_LAST:
-        if (self->_priv.ipv4_config || self->_priv.ipv6_config)
-            nm_modem_emit_prepare_result(NM_MODEM(self), TRUE, NM_DEVICE_STATE_REASON_NONE);
-        else {
-            /* If we have a saved error from a previous attempt, use it */
-            if (!ctx->first_error)
-                ctx->first_error = g_error_new_literal(NM_DEVICE_ERROR,
-                                                       NM_DEVICE_ERROR_INVALID_CONNECTION,
-                                                       "invalid bearer IP configuration");
-
-            _LOGW("failed to connect modem: %s", ctx->first_error->message);
-            nm_modem_emit_prepare_result(NM_MODEM(self),
-                                         FALSE,
-                                         translate_mm_error(self, ctx->first_error));
-        }
-
-        connect_context_clear(self);
-        break;
-    }
-}
-
-static NMActStageReturn
-modem_act_stage1_prepare(NMModem *            _self,
-                         NMConnection *       connection,
-                         NMDeviceStateReason *out_failure_reason)
-{
-    NMModemBroadband *self = NM_MODEM_BROADBAND(_self);
-
-    /* Make sure we can get the Simple interface from the modem */
-    if (!self->_priv.simple_iface) {
-        self->_priv.simple_iface = mm_object_get_modem_simple(self->_priv.modem_object);
-        if (!self->_priv.simple_iface) {
-            _LOGW("cannot access the Simple mobile broadband modem interface");
-            NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
-            return NM_ACT_STAGE_RETURN_FAILURE;
-        }
-    }
-
-    connect_context_clear(self);
-
-    /* Allocate new context for this connect stage attempt */
-    self->_priv.ctx              = g_slice_new0(ConnectContext);
-    self->_priv.ctx->caps        = mm_modem_get_current_capabilities(self->_priv.modem_iface);
-    self->_priv.ctx->cancellable = g_cancellable_new();
-    self->_priv.ctx->connection  = g_object_ref(connection);
-
-    g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(self->_priv.simple_iface),
-                                     MODEM_CONNECT_TIMEOUT_SECS * 1000);
-    connect_context_step(self);
-
-    return NM_ACT_STAGE_RETURN_POSTPONE;
-}
-
-/*****************************************************************************/
-
-static gboolean
-check_connection_compatible_with_modem(NMModem *_self, NMConnection *connection, GError **error)
-{
-    NMModemBroadband *self = NM_MODEM_BROADBAND(_self);
-    MMModemCapability modem_caps;
-
-    modem_caps = mm_modem_get_current_capabilities(self->_priv.modem_iface);
-
-    if (MODEM_CAPS_3GPP(modem_caps)) {
-        if (!_nm_connection_check_main_setting(connection, NM_SETTING_GSM_SETTING_NAME, error))
-            return FALSE;
-
-        return TRUE;
-    }
-
-    if (MODEM_CAPS_3GPP2(modem_caps)) {
-        if (!_nm_connection_check_main_setting(connection, NM_SETTING_CDMA_SETTING_NAME, error))
-            return FALSE;
-
-        return TRUE;
-    }
-
-    if (!_nm_connection_check_main_setting(connection, NM_SETTING_GSM_SETTING_NAME, NULL)
-        && !_nm_connection_check_main_setting(connection, NM_SETTING_CDMA_SETTING_NAME, NULL)) {
-        nm_utils_error_set(error,
-                           NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE,
-                           "connection type %s is not supported by modem",
-                           nm_connection_get_connection_type(connection));
-        return FALSE;
-    }
-
-    nm_utils_error_set(error,
-                       NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                       "modem lacks capabilities for %s profile",
-                       nm_connection_get_connection_type(connection));
-    return FALSE;
-}
-
-/*****************************************************************************/
-
-static gboolean
-complete_connection(NMModem *            modem,
-                    const char *         iface,
-                    NMConnection *       connection,
-                    NMConnection *const *existing_connections,
-                    GError **            error)
-{
-    NMModemBroadband *self = NM_MODEM_BROADBAND(modem);
-    MMModemCapability modem_caps;
-    NMSettingPpp *    s_ppp;
-
-    modem_caps = mm_modem_get_current_capabilities(self->_priv.modem_iface);
-
-    /* PPP settings common to 3GPP and 3GPP2 */
-    s_ppp = nm_connection_get_setting_ppp(connection);
-    if (!s_ppp) {
-        s_ppp = (NMSettingPpp *) nm_setting_ppp_new();
-        g_object_set(G_OBJECT(s_ppp),
-                     NM_SETTING_PPP_LCP_ECHO_FAILURE,
-                     5,
-                     NM_SETTING_PPP_LCP_ECHO_INTERVAL,
-                     30,
-                     NULL);
-        nm_connection_add_setting(connection, NM_SETTING(s_ppp));
-    }
-
-    if (MODEM_CAPS_3GPP(modem_caps)) {
-        NMSettingGsm *s_gsm;
-
-        s_gsm = nm_connection_get_setting_gsm(connection);
-        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)) {
-            g_object_set(G_OBJECT(s_gsm),
-                         NM_SETTING_GSM_DEVICE_ID,
-                         nm_modem_get_device_id(modem),
-                         NULL);
-        }
-
-        nm_utils_complete_generic(NM_PLATFORM_GET,
-                                  connection,
-                                  NM_SETTING_GSM_SETTING_NAME,
-                                  existing_connections,
-                                  NULL,
-                                  _("GSM connection"),
-                                  NULL,
-                                  NULL,
-                                  FALSE); /* No IPv6 yet by default */
-
-        return TRUE;
-    }
-
-    if (MODEM_CAPS_3GPP2(modem_caps)) {
-        NMSettingCdma *s_cdma;
-
-        s_cdma = nm_connection_get_setting_cdma(connection);
-        if (!s_cdma) {
-            s_cdma = (NMSettingCdma *) nm_setting_cdma_new();
-            nm_connection_add_setting(connection, NM_SETTING(s_cdma));
-        }
-
-        if (!nm_setting_cdma_get_number(s_cdma))
-            g_object_set(G_OBJECT(s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL);
-
-        nm_utils_complete_generic(NM_PLATFORM_GET,
-                                  connection,
-                                  NM_SETTING_CDMA_SETTING_NAME,
-                                  existing_connections,
-                                  NULL,
-                                  _("CDMA connection"),
-                                  NULL,
-                                  iface,
-                                  FALSE); /* No IPv6 yet by default */
-
-        return TRUE;
-    }
-
-    g_set_error(error,
-                NM_DEVICE_ERROR,
-                NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
-                "Device is not a mobile broadband modem");
-    return FALSE;
-}
-
-/*****************************************************************************/
-
-static gboolean
-get_user_pass(NMModem *modem, NMConnection *connection, const char **user, const char **pass)
-{
-    NMSettingGsm * s_gsm;
-    NMSettingCdma *s_cdma;
-
-    s_gsm  = nm_connection_get_setting_gsm(connection);
-    s_cdma = nm_connection_get_setting_cdma(connection);
-    if (!s_gsm && !s_cdma)
-        return FALSE;
-
-    if (user) {
-        if (s_gsm)
-            *user = nm_setting_gsm_get_username(s_gsm);
-        else if (s_cdma)
-            *user = nm_setting_cdma_get_username(s_cdma);
-    }
-    if (pass) {
-        if (s_gsm)
-            *pass = nm_setting_gsm_get_password(s_gsm);
-        else if (s_cdma)
-            *pass = nm_setting_cdma_get_password(s_cdma);
-    }
-
-    return TRUE;
-}
-
-/*****************************************************************************/
-/* Query/Update enabled state */
-
-static void
-set_power_state_low_ready(MMModem *modem, GAsyncResult *result, NMModemBroadband *self)
-{
-    GError *error = NULL;
-
-    if (!mm_modem_set_power_state_finish(modem, result, &error)) {
-        /* Log but ignore errors; not all modems support low power state */
-        _LOGD("failed to set modem low power state: %s", NM_G_ERROR_MSG(error));
-        g_clear_error(&error);
-    }
-
-    /* Balance refcount */
-    g_object_unref(self);
-}
-
-static void
-modem_disable_ready(MMModem *modem_iface, GAsyncResult *res, NMModemBroadband *self)
-{
-    GError *error = NULL;
-
-    if (mm_modem_disable_finish(modem_iface, res, &error)) {
-        /* Once disabled, move to low-power mode */
-        mm_modem_set_power_state(modem_iface,
-                                 MM_MODEM_POWER_STATE_LOW,
-                                 NULL,
-                                 (GAsyncReadyCallback) set_power_state_low_ready,
-                                 g_object_ref(self));
-    } else {
-        _LOGW("failed to disable modem: %s", NM_G_ERROR_MSG(error));
-        nm_modem_set_prev_state(NM_MODEM(self), "disable failed");
-        g_clear_error(&error);
-    }
-
-    /* Balance refcount */
-    g_object_unref(self);
-}
-
-static void
-modem_enable_ready(MMModem *modem_iface, GAsyncResult *res, NMModemBroadband *self)
-{
-    GError *error = NULL;
-
-    if (!mm_modem_enable_finish(modem_iface, res, &error)) {
-        _LOGW("failed to enable modem: %s", NM_G_ERROR_MSG(error));
-        nm_modem_set_prev_state(NM_MODEM(self), "enable failed");
-        g_clear_error(&error);
-    }
-
-    /* Balance refcount */
-    g_object_unref(self);
-}
-
-static void
-set_mm_enabled(NMModem *_self, gboolean enabled)
-{
-    NMModemBroadband *self = NM_MODEM_BROADBAND(_self);
-
-    if (enabled) {
-        mm_modem_enable(self->_priv.modem_iface,
-                        NULL, /* cancellable */
-                        (GAsyncReadyCallback) modem_enable_ready,
-                        g_object_ref(self));
-    } else {
-        mm_modem_disable(self->_priv.modem_iface,
-                         NULL, /* cancellable */
-                         (GAsyncReadyCallback) modem_disable_ready,
-                         g_object_ref(self));
-    }
-}
-
-/*****************************************************************************/
-/* IPv4 method static */
-
-static gboolean
-static_stage3_ip4_done(NMModemBroadband *self)
-{
-    GError *        error               = NULL;
-    gs_unref_object NMIP4Config *config = NULL;
-    const char *                 data_port;
-    const char *                 address_string;
-    const char *                 gw_string;
-    guint32                      address_network;
-    guint32                      gw = 0;
-    NMPlatformIP4Address         address;
-    const char **                dns;
-    guint                        i;
-    guint32                      ip4_route_table, ip4_route_metric;
-    NMPlatformIP4Route *         r;
-    guint32                      mtu_n;
-
-    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;
-
-    _LOGI("IPv4 static configuration:");
-
-    /* Fully fail if invalid IP address retrieved */
-    address_string = mm_bearer_ip_config_get_address(self->_priv.ipv4_config);
-    if (!address_string
-        || !nm_utils_parse_inaddr_bin(AF_INET, address_string, NULL, &address_network)) {
-        error =
-            g_error_new(NM_DEVICE_ERROR,
-                        NM_DEVICE_ERROR_INVALID_CONNECTION,
-                        "(%s) retrieving IP4 configuration failed: invalid address given %s%s%s",
-                        nm_modem_get_uid(NM_MODEM(self)),
-                        NM_PRINT_FMT_QUOTE_STRING(address_string));
-        goto out;
-    }
-
-    /* Missing gateway not a hard failure */
-    gw_string = mm_bearer_ip_config_get_gateway(self->_priv.ipv4_config);
-    if (gw_string && !nm_utils_parse_inaddr_bin(AF_INET, gw_string, NULL, &gw)) {
-        error =
-            g_error_new(NM_DEVICE_ERROR,
-                        NM_DEVICE_ERROR_INVALID_CONNECTION,
-                        "(%s) retrieving IP4 configuration failed: invalid gateway address \"%s\"",
-                        nm_modem_get_uid(NM_MODEM(self)),
-                        gw_string);
-        goto out;
-    }
-
-    data_port = mm_bearer_get_interface(self->_priv.bearer);
-    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));
-
-    memset(&address, 0, sizeof(address));
-    address.address      = address_network;
-    address.peer_address = address_network;
-    address.plen         = mm_bearer_ip_config_get_prefix(self->_priv.ipv4_config);
-    address.addr_source  = NM_IP_CONFIG_SOURCE_WWAN;
-    if (address.plen <= 32)
-        nm_ip4_config_add_address(config, &address);
-
-    _LOGI("  address %s/%d", address_string, address.plen);
-
-    nm_modem_get_route_parameters(NM_MODEM(self), &ip4_route_table, &ip4_route_metric, NULL, NULL);
-    r = &(NMPlatformIP4Route){
-        .rt_source     = NM_IP_CONFIG_SOURCE_WWAN,
-        .gateway       = gw,
-        .table_coerced = nm_platform_route_table_coerce(ip4_route_table),
-        .metric        = ip4_route_metric,
-    };
-    nm_ip4_config_add_route(config, r, NULL);
-    _LOGI("  gateway %s", gw_string);
-
-    /* DNS servers */
-    dns = mm_bearer_ip_config_get_dns(self->_priv.ipv4_config);
-    for (i = 0; dns && dns[i]; i++) {
-        if (nm_utils_parse_inaddr_bin(AF_INET, dns[i], NULL, &address_network)
-            && address_network > 0) {
-            nm_ip4_config_add_nameserver(config, address_network);
-            _LOGI("  DNS %s", dns[i]);
-        }
-    }
-
-#if MM_CHECK_VERSION(1, 4, 0)
-    mtu_n = mm_bearer_ip_config_get_mtu(self->_priv.ipv4_config);
-    if (mtu_n) {
-        nm_ip4_config_set_mtu(config, mtu_n, NM_IP_CONFIG_SOURCE_WWAN);
-        _LOGI("  MTU %u", mtu_n);
-    }
-#endif
-
-out:
-    g_signal_emit_by_name(self, NM_MODEM_IP4_CONFIG_RESULT, config, error);
-    g_clear_error(&error);
-    return FALSE;
-}
-
-static NMActStageReturn
-static_stage3_ip4_config_start(NMModem *            modem,
-                               NMActRequest *       req,
-                               NMDeviceStateReason *out_failure_reason)
-{
-    NMModemBroadband *       self = NM_MODEM_BROADBAND(modem);
-    NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self);
-
-    /* We schedule it in an idle just to follow the same logic as in the
-     * generic modem implementation. */
-    nm_clear_g_source(&priv->idle_id_ip4);
-    priv->idle_id_ip4 = g_idle_add((GSourceFunc) static_stage3_ip4_done, self);
-
-    return NM_ACT_STAGE_RETURN_POSTPONE;
-}
-
-/*****************************************************************************/
-/* IPv6 method static */
-
-static gboolean
-stage3_ip6_done(NMModemBroadband *self)
-{
-    GError *             error  = NULL;
-    NMIP6Config *        config = NULL;
-    const char *         data_port;
-    const char *         address_string;
-    NMPlatformIP6Address address;
-    NMModemIPMethod      ip_method;
-    const char **        dns;
-    guint                i;
-
-    g_return_val_if_fail(self->_priv.ipv6_config, FALSE);
-
-    self->_priv.idle_id_ip6 = 0;
-    memset(&address, 0, sizeof(address));
-
-    ip_method = get_bearer_ip_method(self->_priv.ipv6_config);
-
-    address_string = mm_bearer_ip_config_get_address(self->_priv.ipv6_config);
-    if (!address_string) {
-        /* DHCP/SLAAC is allowed to skip addresses; other methods require it */
-        if (ip_method != NM_MODEM_IP_METHOD_AUTO) {
-            error = g_error_new(NM_DEVICE_ERROR,
-                                NM_DEVICE_ERROR_INVALID_CONNECTION,
-                                "(%s) retrieving IPv6 configuration failed: no address given",
-                                nm_modem_get_uid(NM_MODEM(self)));
-        }
-        goto out;
-    }
-
-    /* Fail if invalid IP address retrieved */
-    if (!inet_pton(AF_INET6, address_string, (void *) &(address.address))) {
-        error = g_error_new(NM_DEVICE_ERROR,
-                            NM_DEVICE_ERROR_INVALID_CONNECTION,
-                            "(%s) retrieving IPv6 configuration failed: invalid address given '%s'",
-                            nm_modem_get_uid(NM_MODEM(self)),
-                            address_string);
-        goto out;
-    }
-
-    _LOGI("IPv6 base configuration:");
-
-    data_port = mm_bearer_get_interface(self->_priv.bearer);
-    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));
-
-    address.plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv6_config);
-    if (address.plen <= 128)
-        nm_ip6_config_add_address(config, &address);
-
-    _LOGI("  address %s/%d", address_string, address.plen);
-
-    address_string = mm_bearer_ip_config_get_gateway(self->_priv.ipv6_config);
-    if (address_string) {
-        guint32 ip6_route_table, ip6_route_metric;
-
-        if (inet_pton(AF_INET6, address_string, &address.address) != 1) {
-            error =
-                g_error_new(NM_DEVICE_ERROR,
-                            NM_DEVICE_ERROR_INVALID_CONNECTION,
-                            "(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'",
-                            nm_modem_get_uid(NM_MODEM(self)),
-                            address_string);
-            goto out;
-        }
-
-        nm_modem_get_route_parameters(NM_MODEM(self),
-                                      NULL,
-                                      NULL,
-                                      &ip6_route_table,
-                                      &ip6_route_metric);
-        {
-            const NMPlatformIP6Route r = {
-                .rt_source     = NM_IP_CONFIG_SOURCE_WWAN,
-                .gateway       = address.address,
-                .table_coerced = nm_platform_route_table_coerce(ip6_route_table),
-                .metric        = ip6_route_metric,
-            };
-
-            _LOGI("  gateway %s", address_string);
-            nm_ip6_config_add_route(config, &r, NULL);
-        }
-    } else if (ip_method == NM_MODEM_IP_METHOD_STATIC) {
-        /* Gateway required for the 'static' method */
-        error = g_error_new(NM_DEVICE_ERROR,
-                            NM_DEVICE_ERROR_INVALID_CONNECTION,
-                            "(%s) retrieving IPv6 configuration failed: missing gateway",
-                            nm_modem_get_uid(NM_MODEM(self)));
-        goto out;
-    }
-
-    /* DNS servers */
-    dns = mm_bearer_ip_config_get_dns(self->_priv.ipv6_config);
-    for (i = 0; dns && dns[i]; i++) {
-        struct in6_addr addr;
-
-        if (inet_pton(AF_INET6, dns[i], &addr)) {
-            nm_ip6_config_add_nameserver(config, &addr);
-            _LOGI("  DNS %s", dns[i]);
-        }
-    }
-
-out:
-    nm_modem_emit_ip6_config_result(NM_MODEM(self), config, error);
-    g_clear_object(&config);
-    g_clear_error(&error);
-    return FALSE;
-}
-
-static NMActStageReturn
-stage3_ip6_config_request(NMModem *modem, NMDeviceStateReason *out_failure_reason)
-{
-    NMModemBroadband *       self = NM_MODEM_BROADBAND(modem);
-    NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self);
-
-    /* We schedule it in an idle just to follow the same logic as in the
-     * generic modem implementation. */
-    nm_clear_g_source(&priv->idle_id_ip6);
-    priv->idle_id_ip6 = g_idle_add((GSourceFunc) stage3_ip6_done, self);
-
-    return NM_ACT_STAGE_RETURN_POSTPONE;
-}
-
-/*****************************************************************************/
-/* Disconnect */
-
-typedef struct {
-    NMModemBroadband *         self;
-    _NMModemDisconnectCallback callback;
-    gpointer                   callback_user_data;
-    GCancellable *             cancellable;
-    gboolean                   warn;
-} DisconnectContext;
-
-static void
-disconnect_context_complete(DisconnectContext *ctx, GError *error)
-{
-    if (ctx->callback)
-        ctx->callback(NM_MODEM(ctx->self), error, ctx->callback_user_data);
-    nm_g_object_unref(ctx->cancellable);
-    g_object_unref(ctx->self);
-    g_slice_free(DisconnectContext, ctx);
-}
-
-static void
-disconnect_context_complete_on_idle(gpointer user_data, GCancellable *cancellable)
-{
-    DisconnectContext *ctx                = user_data;
-    gs_free_error GError *cancelled_error = NULL;
-
-    g_cancellable_set_error_if_cancelled(cancellable, &cancelled_error);
-    disconnect_context_complete(ctx, cancelled_error);
-}
-
-static void
-simple_disconnect_ready(GObject *source_object, GAsyncResult *res, gpointer user_data)
-{
-    MMModemSimple *    modem_iface = MM_MODEM_SIMPLE(source_object);
-    DisconnectContext *ctx         = user_data;
-    gs_free_error GError *error    = NULL;
-
-    if (!mm_modem_simple_disconnect_finish(modem_iface, res, &error)) {
-        if (ctx->warn && !g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) {
-            NMModemBroadband *self = ctx->self;
-
-            _LOGW("failed to disconnect modem: %s", error->message);
-        }
-    }
-
-    disconnect_context_complete(ctx, error);
-}
-
-static void
-disconnect(NMModem *                  modem,
-           gboolean                   warn,
-           GCancellable *             cancellable,
-           _NMModemDisconnectCallback callback,
-           gpointer                   user_data)
-{
-    NMModemBroadband * self = NM_MODEM_BROADBAND(modem);
-    DisconnectContext *ctx;
-
-    connect_context_clear(self);
-    _nm_modem_set_apn(NM_MODEM(self), NULL);
-
-    ctx                     = g_slice_new0(DisconnectContext);
-    ctx->self               = g_object_ref(self);
-    ctx->cancellable        = nm_g_object_ref(cancellable);
-    ctx->callback           = callback;
-    ctx->callback_user_data = user_data;
-
-    /* Don't bother warning on FAILED since the modem is already gone */
-    ctx->warn = warn;
-
-    /* Already cancelled or no simple-iface? We are done. */
-    if (!ctx->self->_priv.simple_iface || g_cancellable_is_cancelled(cancellable)) {
-        nm_utils_invoke_on_idle(cancellable, disconnect_context_complete_on_idle, ctx);
-        return;
-    }
-
-    _LOGD("notifying ModemManager about the modem disconnection");
-    mm_modem_simple_disconnect(self->_priv.simple_iface,
-                               NULL, /* bearer path; if NULL given ALL get disconnected */
-                               cancellable,
-                               simple_disconnect_ready,
-                               ctx);
-}
-
-/*****************************************************************************/
-
-static void
-deactivate_cleanup(NMModem *modem, NMDevice *device, gboolean stop_ppp_manager)
-{
-    NMModemBroadband *self = NM_MODEM_BROADBAND(modem);
-
-    /* TODO: cancel SimpleConnect() if any */
-
-    /* Cleanup IPv4 addresses and routes */
-    g_clear_object(&self->_priv.ipv4_config);
-    g_clear_object(&self->_priv.ipv6_config);
-    g_clear_object(&self->_priv.bearer);
-
-    self->_priv.pin_tries = 0;
-
-    NM_MODEM_CLASS(nm_modem_broadband_parent_class)
-        ->deactivate_cleanup(modem, device, stop_ppp_manager);
-}
-
-/*****************************************************************************/
-
-#define MAP_STATE(name)         \
-    case MM_MODEM_STATE_##name: \
-        return NM_MODEM_STATE_##name;
-
-static NMModemState
-mm_state_to_nm(MMModemState mm_state)
-{
-    switch (mm_state) {
-        MAP_STATE(UNKNOWN)
-        MAP_STATE(FAILED)
-        MAP_STATE(INITIALIZING)
-        MAP_STATE(LOCKED)
-        MAP_STATE(DISABLED)
-        MAP_STATE(DISABLING)
-        MAP_STATE(ENABLING)
-        MAP_STATE(ENABLED)
-        MAP_STATE(SEARCHING)
-        MAP_STATE(REGISTERED)
-        MAP_STATE(DISCONNECTING)
-        MAP_STATE(CONNECTING)
-        MAP_STATE(CONNECTED)
-    }
-    return NM_MODEM_STATE_UNKNOWN;
-}
-
-static void
-modem_state_changed(MMModem *                modem,
-                    MMModemState             old_state,
-                    MMModemState             new_state,
-                    MMModemStateChangeReason reason,
-                    NMModemBroadband *       self)
-{
-    /* After the SIM is unlocked MM1 will move the device to INITIALIZING which
-     * is an unavailable state.  That makes state handling confusing here, so
-     * suppress this state change and let the modem move from LOCKED to DISABLED.
-     */
-    if (new_state == MM_MODEM_STATE_INITIALIZING && old_state == MM_MODEM_STATE_LOCKED)
-        return;
-
-    nm_modem_set_state(NM_MODEM(self),
-                       mm_state_to_nm(new_state),
-                       mm_modem_state_change_reason_get_string(reason));
-
-    if (self->_priv.ctx && self->_priv.ctx->step == CONNECT_STEP_WAIT_FOR_READY)
-        connect_context_step(self);
-}
-
-/*****************************************************************************/
-
-static NMModemIPType
-mm_ip_family_to_nm(MMBearerIpFamily family)
-{
-    NMModemIPType nm_type = NM_MODEM_IP_TYPE_UNKNOWN;
-
-    if (family & MM_BEARER_IP_FAMILY_IPV4)
-        nm_type |= NM_MODEM_IP_TYPE_IPV4;
-    if (family & MM_BEARER_IP_FAMILY_IPV6)
-        nm_type |= NM_MODEM_IP_TYPE_IPV6;
-    if (family & MM_BEARER_IP_FAMILY_IPV4V6)
-        nm_type |= MM_BEARER_IP_FAMILY_IPV4V6;
-
-    return nm_type;
-}
-
-static void
-get_sim_ready(MMModem *modem, GAsyncResult *res, NMModemBroadband *self)
-{
-    GError *error = NULL;
-    MMSim * new_sim;
-
-    new_sim = mm_modem_get_sim_finish(modem, res, &error);
-    if (new_sim != self->_priv.sim_iface) {
-        g_clear_object(&self->_priv.sim_iface);
-        self->_priv.sim_iface = new_sim;
-    } else
-        g_clear_object(&new_sim);
-
-    if (self->_priv.sim_iface) {
-        g_object_set(G_OBJECT(self),
-                     NM_MODEM_SIM_ID,
-                     mm_sim_get_identifier(self->_priv.sim_iface),
-                     NM_MODEM_SIM_OPERATOR_ID,
-                     mm_sim_get_operator_identifier(self->_priv.sim_iface),
-                     NULL);
-
-        /* If we're waiting for the SIM during a connect, proceed with the connect */
-        if (self->_priv.ctx && self->_priv.ctx->step == CONNECT_STEP_WAIT_FOR_SIM)
-            connect_context_step(self);
-    } else {
-        _NMLOG(g_error_matches(error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND) ? LOGL_INFO
-                                                                              : LOGL_WARN,
-               "failed to retrieve SIM object: %s",
-               NM_G_ERROR_MSG(error));
-    }
-    g_clear_error(&error);
-    g_object_unref(self);
-}
-
-static void
-sim_changed(MMModem *modem, GParamSpec *pspec, gpointer user_data)
-{
-    NMModemBroadband *self = NM_MODEM_BROADBAND(user_data);
-
-    g_return_if_fail(modem == self->_priv.modem_iface);
-
-    if (mm_modem_get_sim_path(self->_priv.modem_iface)) {
-        mm_modem_get_sim(self->_priv.modem_iface,
-                         NULL, /* cancellable */
-                         (GAsyncReadyCallback) get_sim_ready,
-                         g_object_ref(self));
-    } else
-        g_object_set(G_OBJECT(self), NM_MODEM_SIM_ID, NULL, NM_MODEM_SIM_OPERATOR_ID, NULL, NULL);
-}
-
-static void
-supported_ip_families_changed(MMModem *modem, GParamSpec *pspec, gpointer user_data)
-{
-    NMModemBroadband *self = NM_MODEM_BROADBAND(user_data);
-
-    g_return_if_fail(modem == self->_priv.modem_iface);
-
-    g_object_set(G_OBJECT(self),
-                 NM_MODEM_IP_TYPES,
-                 mm_ip_family_to_nm(mm_modem_get_supported_ip_families(modem)),
-                 NULL);
-}
-
-static void
-operator_code_changed(MMModem3gpp *modem_3gpp, GParamSpec *pspec, gpointer user_data)
-{
-    NMModemBroadband *self = NM_MODEM_BROADBAND(user_data);
-
-    g_return_if_fail(modem_3gpp == self->_priv.modem_3gpp_iface);
-    _nm_modem_set_operator_code(NM_MODEM(self), mm_modem_3gpp_get_operator_code(modem_3gpp));
-}
-
-/*****************************************************************************/
-
-static void
-get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
-    NMModemBroadband *self = NM_MODEM_BROADBAND(object);
-
-    switch (prop_id) {
-    case PROP_MODEM:
-        g_value_set_object(value, self->_priv.modem_object);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
-    NMModemBroadband *self = NM_MODEM_BROADBAND(object);
-
-    switch (prop_id) {
-    case PROP_MODEM:
-        /* 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_signal_connect(self->_priv.modem_iface,
-                         "state-changed",
-                         G_CALLBACK(modem_state_changed),
-                         self);
-        g_signal_connect(self->_priv.modem_iface, "notify::sim", G_CALLBACK(sim_changed), self);
-        sim_changed(self->_priv.modem_iface, NULL, self);
-        g_signal_connect(self->_priv.modem_iface,
-                         "notify::supported-ip-families",
-                         G_CALLBACK(supported_ip_families_changed),
-                         self);
-
-        if (self->_priv.modem_3gpp_iface) {
-            g_signal_connect(self->_priv.modem_3gpp_iface,
-                             "notify::operator-code",
-                             G_CALLBACK(operator_code_changed),
-                             self);
-        }
-
-        /* Note: don't grab the Simple iface here; the Modem interface is the
-         * only one assumed to be always valid and available */
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-/*****************************************************************************/
-
-static void
-nm_modem_broadband_init(NMModemBroadband *self)
-{}
-
-NMModem *
-nm_modem_broadband_new(GObject *object, GError **error)
-{
-    MMObject *         modem_object;
-    MMModem *          modem_iface;
-    MMModem3gpp *      modem_3gpp_iface;
-    const char *const *drivers;
-    const char *       operator_code = NULL;
-    gs_free char *     driver        = NULL;
-
-    g_return_val_if_fail(MM_IS_OBJECT(object), NULL);
-    modem_object = MM_OBJECT(object);
-
-    /* Ensure we have the 'Modem' interface and the primary port at least */
-    modem_iface = mm_object_peek_modem(modem_object);
-    g_return_val_if_fail(modem_iface, NULL);
-    g_return_val_if_fail(mm_modem_get_primary_port(modem_iface), NULL);
-
-    /* Build a single string with all drivers listed */
-    drivers = mm_modem_get_drivers(modem_iface);
-    if (drivers)
-        driver = g_strjoinv(", ", (char **) drivers);
-
-    modem_3gpp_iface = mm_object_peek_modem_3gpp(modem_object);
-    if (modem_3gpp_iface)
-        operator_code = mm_modem_3gpp_get_operator_code(modem_3gpp_iface);
-
-    return g_object_new(NM_TYPE_MODEM_BROADBAND,
-                        NM_MODEM_PATH,
-                        mm_object_get_path(modem_object),
-                        NM_MODEM_UID,
-                        mm_modem_get_primary_port(modem_iface),
-                        NM_MODEM_CONTROL_PORT,
-                        mm_modem_get_primary_port(modem_iface),
-                        NM_MODEM_IP_TYPES,
-                        mm_ip_family_to_nm(mm_modem_get_supported_ip_families(modem_iface)),
-                        NM_MODEM_STATE,
-                        (int) mm_state_to_nm(mm_modem_get_state(modem_iface)),
-                        NM_MODEM_DEVICE_ID,
-                        mm_modem_get_device_identifier(modem_iface),
-                        NM_MODEM_BROADBAND_MODEM,
-                        modem_object,
-                        NM_MODEM_DRIVER,
-                        driver,
-                        NM_MODEM_OPERATOR_CODE,
-                        operator_code,
-                        NULL);
-}
-
-static void
-dispose(GObject *object)
-{
-    NMModemBroadband *       self = NM_MODEM_BROADBAND(object);
-    NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self);
-
-    nm_clear_g_source(&priv->idle_id_ip4);
-    nm_clear_g_source(&priv->idle_id_ip6);
-
-    connect_context_clear(self);
-    g_clear_object(&self->_priv.ipv4_config);
-    g_clear_object(&self->_priv.ipv6_config);
-    g_clear_object(&self->_priv.bearer);
-
-    if (self->_priv.modem_iface) {
-        g_signal_handlers_disconnect_by_data(self->_priv.modem_iface, self);
-        g_clear_object(&self->_priv.modem_iface);
-    }
-
-    if (self->_priv.modem_3gpp_iface) {
-        g_signal_handlers_disconnect_by_data(self->_priv.modem_3gpp_iface, self);
-        g_clear_object(&self->_priv.modem_3gpp_iface);
-    }
-
-    g_clear_object(&self->_priv.simple_iface);
-    g_clear_object(&self->_priv.sim_iface);
-    g_clear_object(&self->_priv.modem_object);
-
-    G_OBJECT_CLASS(nm_modem_broadband_parent_class)->dispose(object);
-}
-
-static void
-nm_modem_broadband_class_init(NMModemBroadbandClass *klass)
-{
-    GObjectClass *object_class = G_OBJECT_CLASS(klass);
-    NMModemClass *modem_class  = NM_MODEM_CLASS(klass);
-
-    object_class->dispose      = dispose;
-    object_class->get_property = get_property;
-    object_class->set_property = set_property;
-
-    modem_class->get_capabilities                       = get_capabilities;
-    modem_class->static_stage3_ip4_config_start         = static_stage3_ip4_config_start;
-    modem_class->stage3_ip6_config_request              = stage3_ip6_config_request;
-    modem_class->disconnect                             = disconnect;
-    modem_class->deactivate_cleanup                     = deactivate_cleanup;
-    modem_class->set_mm_enabled                         = set_mm_enabled;
-    modem_class->get_user_pass                          = get_user_pass;
-    modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem;
-    modem_class->complete_connection                    = complete_connection;
-    modem_class->modem_act_stage1_prepare               = modem_act_stage1_prepare;
-    modem_class->owns_port                              = owns_port;
-
-    obj_properties[PROP_MODEM] =
-        g_param_spec_object(NM_MODEM_BROADBAND_MODEM,
-                            "",
-                            "",
-                            MM_GDBUS_TYPE_OBJECT,
-                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-}
diff --git a/src/devices/wwan/nm-modem-broadband.h b/src/devices/wwan/nm-modem-broadband.h
deleted file mode 100644
index 5a822f6f..00000000
--- a/src/devices/wwan/nm-modem-broadband.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2012 - Aleksander Morgado <aleksander@gnu.org>
- */
-
-#ifndef __NETWORKMANAGER_MODEM_BROADBAND_H__
-#define __NETWORKMANAGER_MODEM_BROADBAND_H__
-
-#include "nm-modem.h"
-
-#define NM_TYPE_MODEM_BROADBAND (nm_modem_broadband_get_type())
-#define NM_MODEM_BROADBAND(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MODEM_BROADBAND, NMModemBroadband))
-#define NM_MODEM_BROADBAND_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_MODEM_BROADBAND, NMModemBroadbandClass))
-#define NM_IS_MODEM_BROADBAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_MODEM_BROADBAND))
-#define NM_IS_MODEM_BROADBAND_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_MODEM_BROADBAND))
-#define NM_MODEM_BROADBAND_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_MODEM_BROADBAND, NMModemBroadbandClass))
-
-typedef struct _NMModemBroadband      NMModemBroadband;
-typedef struct _NMModemBroadbandClass NMModemBroadbandClass;
-
-GType nm_modem_broadband_get_type(void);
-
-NMModem *nm_modem_broadband_new(GObject *object, GError **error);
-
-#endif /* __NETWORKMANAGER_MODEM_BROADBAND_H__ */
diff --git a/src/devices/wwan/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c
deleted file mode 100644
index 65f7c9f9..00000000
--- a/src/devices/wwan/nm-modem-manager.c
+++ /dev/null
@@ -1,876 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2009 - 2014 Red Hat, Inc.
- * Copyright (C) 2009 Novell, Inc.
- * Copyright (C) 2009 - 2013 Canonical Ltd.
- */
-
-#include "nm-default.h"
-
-#include "nm-modem-manager.h"
-
-#include <libmm-glib.h>
-
-#if HAVE_LIBSYSTEMD
-    #include <systemd/sd-daemon.h>
-#else
-    #define sd_booted() FALSE
-#endif
-
-#include "nm-std-aux/nm-dbus-compat.h"
-#include "nm-modem.h"
-#include "nm-modem-broadband.h"
-
-#if WITH_OFONO
-    #include "nm-modem-ofono.h"
-#endif
-
-#define MODEM_POKE_INTERVAL 120
-
-/*****************************************************************************/
-
-NM_GOBJECT_PROPERTIES_DEFINE(NMModemManager, PROP_NAME_OWNER, );
-
-enum {
-    MODEM_ADDED,
-    LAST_SIGNAL,
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-typedef struct {
-    GDBusConnection *dbus_connection;
-
-    /* used during g_bus_get() and later during mm_manager_new(). */
-    GCancellable *main_cancellable;
-
-    struct {
-        MMManager *   manager;
-        GCancellable *poke_cancellable;
-        gulong        handle_name_owner_changed_id;
-        gulong        handle_object_added_id;
-        gulong        handle_object_removed_id;
-        guint         relaunch_id;
-
-        /* this only has one use: that the <info> logging line about
-         * ModemManager available distinguishes between first-time
-         * and later name-owner-changed. */
-        enum {
-            LOG_AVAILABLE_NOT_INITIALIZED = 0,
-            LOG_AVAILABLE_YES,
-            LOG_AVAILABLE_NO,
-        } log_available : 3;
-
-        GDBusProxy *  proxy;
-        GCancellable *proxy_cancellable;
-        guint         proxy_ref_count;
-        char *        proxy_name_owner;
-    } modm;
-
-#if WITH_OFONO
-    struct {
-        GDBusProxy *  proxy;
-        GCancellable *cancellable;
-    } ofono;
-#endif
-
-    GHashTable *modems;
-} NMModemManagerPrivate;
-
-struct _NMModemManager {
-    GObject               parent;
-    NMModemManagerPrivate _priv;
-};
-
-struct _NMModemManagerClass {
-    GObjectClass parent;
-};
-
-G_DEFINE_TYPE(NMModemManager, nm_modem_manager, G_TYPE_OBJECT)
-
-#define NM_MODEM_MANAGER_GET_PRIVATE(self) \
-    _NM_GET_PRIVATE(self, NMModemManager, NM_IS_MODEM_MANAGER)
-
-/*****************************************************************************/
-
-#define _NMLOG_DOMAIN      LOGD_MB
-#define _NMLOG(level, ...) __NMLOG_DEFAULT(level, _NMLOG_DOMAIN, "modem-manager", __VA_ARGS__)
-
-/*****************************************************************************/
-
-NM_DEFINE_SINGLETON_GETTER(NMModemManager, nm_modem_manager_get, NM_TYPE_MODEM_MANAGER);
-
-/*****************************************************************************/
-
-static void modm_schedule_manager_relaunch(NMModemManager *self, guint n_seconds);
-static void modm_ensure_manager(NMModemManager *self);
-
-/*****************************************************************************/
-
-static void
-handle_new_modem(NMModemManager *self, NMModem *modem)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-    const char *           path;
-
-    path = nm_modem_get_path(modem);
-    if (g_hash_table_lookup(priv->modems, path)) {
-        g_warn_if_reached();
-        return;
-    }
-
-    /* Track the new modem */
-    g_hash_table_insert(priv->modems, g_strdup(path), modem);
-    g_signal_emit(self, signals[MODEM_ADDED], 0, modem);
-}
-
-static gboolean
-remove_one_modem(gpointer key, gpointer value, gpointer user_data)
-{
-    nm_modem_emit_removed(NM_MODEM(value));
-    return TRUE;
-}
-
-/*****************************************************************************/
-
-NMModem **
-nm_modem_manager_get_modems(NMModemManager *self, guint *out_len)
-{
-    g_return_val_if_fail(NM_IS_MODEM_MANAGER(self), NULL);
-
-    return (NMModem **) nm_utils_hash_values_to_array(NM_MODEM_MANAGER_GET_PRIVATE(self)->modems,
-                                                      NULL,
-                                                      NULL,
-                                                      out_len);
-}
-
-/*****************************************************************************/
-
-static void
-modm_clear_manager(NMModemManager *self)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    if (!priv->modm.manager)
-        return;
-    nm_clear_g_signal_handler(priv->modm.manager, &priv->modm.handle_name_owner_changed_id);
-    nm_clear_g_signal_handler(priv->modm.manager, &priv->modm.handle_object_added_id);
-    nm_clear_g_signal_handler(priv->modm.manager, &priv->modm.handle_object_removed_id);
-    g_clear_object(&priv->modm.manager);
-}
-
-static void
-modm_handle_object_added(MMManager *modem_manager, MMObject *modem_object, NMModemManager *self)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-    const char *           path;
-    MMModem *              modem_iface;
-    NMModem *              modem;
-    GError *               error = NULL;
-
-    /* Ensure we don't have the same modem already */
-    path = mm_object_get_path(modem_object);
-    if (g_hash_table_lookup(priv->modems, path)) {
-        _LOGW("modem with path %s already exists, ignoring", path);
-        return;
-    }
-
-    /* Ensure we have the 'Modem' interface at least */
-    modem_iface = mm_object_peek_modem(modem_object);
-    if (!modem_iface) {
-        _LOGW("modem with path %s doesn't have the Modem interface, ignoring", path);
-        return;
-    }
-
-    /* Ensure we have a primary port reported */
-    if (!mm_modem_get_primary_port(modem_iface)) {
-        _LOGW("modem with path %s has unknown primary port, ignoring", path);
-        return;
-    }
-
-    /* Create a new modem object */
-    modem = nm_modem_broadband_new(G_OBJECT(modem_object), &error);
-    if (modem)
-        handle_new_modem(self, modem);
-    else
-        _LOGW("failed to create modem: %s", error->message);
-    g_clear_error(&error);
-}
-
-static void
-modm_handle_object_removed(MMManager *manager, MMObject *modem_object, NMModemManager *self)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-    NMModem *              modem;
-    const char *           path;
-
-    path  = mm_object_get_path(modem_object);
-    modem = (NMModem *) g_hash_table_lookup(priv->modems, path);
-    if (!modem)
-        return;
-
-    nm_modem_emit_removed(modem);
-    g_hash_table_remove(priv->modems, path);
-}
-
-static void
-modm_manager_available(NMModemManager *self)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-    GList *                modems, *l;
-
-    if (priv->modm.log_available != LOG_AVAILABLE_YES) {
-        _LOGI("ModemManager %savailable", priv->modm.log_available ? "now " : "");
-        priv->modm.log_available = LOG_AVAILABLE_YES;
-    }
-
-    /* Update initial modems list */
-    modems = g_dbus_object_manager_get_objects(G_DBUS_OBJECT_MANAGER(priv->modm.manager));
-    for (l = modems; l; l = g_list_next(l))
-        modm_handle_object_added(priv->modm.manager, MM_OBJECT(l->data), self);
-    g_list_free_full(modems, (GDestroyNotify) g_object_unref);
-}
-
-static void
-modm_handle_name_owner_changed(MMManager *modem_manager, GParamSpec *pspec, NMModemManager *self)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-    char *                 name_owner;
-
-    /* Quit poking, if any */
-    nm_clear_g_source(&priv->modm.relaunch_id);
-
-    name_owner =
-        g_dbus_object_manager_client_get_name_owner(G_DBUS_OBJECT_MANAGER_CLIENT(modem_manager));
-    if (!name_owner) {
-        if (priv->modm.log_available != LOG_AVAILABLE_NO) {
-            _LOGI("ModemManager %savailable", priv->modm.log_available ? "no longer " : "not ");
-            priv->modm.log_available = LOG_AVAILABLE_NO;
-        }
-
-        /* If not managed by systemd, schedule relaunch */
-        if (!sd_booted())
-            modm_schedule_manager_relaunch(self, 0);
-
-        return;
-    }
-
-    /* Available! */
-    g_free(name_owner);
-
-    /* Hack alert: GDBusObjectManagerClient won't signal neither 'object-added'
-     * nor 'object-removed' if it was created while there was no ModemManager in
-     * the bus. This hack avoids this issue until we get a GIO with the fix
-     * included... */
-    modm_clear_manager(self);
-    modm_ensure_manager(self);
-
-    /* Whenever GDBusObjectManagerClient is fixed, we can just do the following:
-     * modm_manager_available (self);
-     */
-}
-
-static void
-modm_manager_poke_cb(GObject *connection, GAsyncResult *res, gpointer user_data)
-{
-    NMModemManager *       self;
-    NMModemManagerPrivate *priv;
-    gs_free_error GError *error       = NULL;
-    gs_unref_variant GVariant *result = NULL;
-
-    result = g_dbus_connection_call_finish(G_DBUS_CONNECTION(connection), res, &error);
-
-    if (!result && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = user_data;
-    priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    g_clear_object(&priv->modm.poke_cancellable);
-
-    if (error) {
-        _LOGW("error poking ModemManager: %s", error->message);
-
-        /* Don't reschedule poke is MM service doesn't exist. */
-        if (!g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)
-            && !g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) {
-            /* Setup timeout to relaunch */
-            modm_schedule_manager_relaunch(self, MODEM_POKE_INTERVAL);
-        }
-    }
-}
-
-static void
-modm_manager_poke(NMModemManager *self)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    nm_clear_g_cancellable(&priv->modm.poke_cancellable);
-    priv->modm.poke_cancellable = g_cancellable_new();
-
-    /* If there is no current owner right away, ensure we poke to get one */
-    g_dbus_connection_call(priv->dbus_connection,
-                           NM_MODEM_MANAGER_MM_DBUS_SERVICE,
-                           NM_MODEM_MANAGER_MM_DBUS_PATH,
-                           DBUS_INTERFACE_PEER,
-                           "Ping",
-                           NULL,
-                           NULL,
-                           G_DBUS_CALL_FLAGS_NONE,
-                           -1,
-                           priv->modm.poke_cancellable,
-                           modm_manager_poke_cb,
-                           self);
-}
-
-static void
-modm_manager_check_name_owner(NMModemManager *self)
-{
-    NMModemManagerPrivate *priv       = NM_MODEM_MANAGER_GET_PRIVATE(self);
-    gs_free char *         name_owner = NULL;
-
-    name_owner = g_dbus_object_manager_client_get_name_owner(
-        G_DBUS_OBJECT_MANAGER_CLIENT(priv->modm.manager));
-    if (name_owner) {
-        modm_manager_available(self);
-        return;
-    }
-
-    /* If the lifecycle is not managed by systemd, poke */
-    if (!sd_booted())
-        modm_manager_poke(self);
-}
-
-static void
-modm_manager_new_cb(GObject *source, GAsyncResult *res, gpointer user_data)
-{
-    NMModemManager *       self;
-    NMModemManagerPrivate *priv;
-    gs_free_error GError *error = NULL;
-    MMManager *           modem_manager;
-
-    modem_manager = mm_manager_new_finish(res, &error);
-    if (!modem_manager && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = user_data;
-    priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    nm_assert(!priv->modm.manager);
-
-    g_clear_object(&priv->main_cancellable);
-
-    if (!modem_manager) {
-        /* We're not really supposed to get any error here. If we do get one,
-         * though, just re-schedule the MMManager creation after some time.
-         * During this period, name-owner changes won't be followed. */
-        _LOGW("error creating ModemManager client: %s", error->message);
-        /* Setup timeout to relaunch */
-        modm_schedule_manager_relaunch(self, MODEM_POKE_INTERVAL);
-        return;
-    }
-
-    priv->modm.manager = modem_manager;
-
-    /* Setup signals in the GDBusObjectManagerClient */
-    priv->modm.handle_name_owner_changed_id =
-        g_signal_connect(priv->modm.manager,
-                         "notify::name-owner",
-                         G_CALLBACK(modm_handle_name_owner_changed),
-                         self);
-    priv->modm.handle_object_added_id   = g_signal_connect(priv->modm.manager,
-                                                         "object-added",
-                                                         G_CALLBACK(modm_handle_object_added),
-                                                         self);
-    priv->modm.handle_object_removed_id = g_signal_connect(priv->modm.manager,
-                                                           "object-removed",
-                                                           G_CALLBACK(modm_handle_object_removed),
-                                                           self);
-
-    modm_manager_check_name_owner(self);
-}
-
-static void
-modm_ensure_manager(NMModemManager *self)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    g_assert(priv->dbus_connection);
-
-    /* Create the GDBusObjectManagerClient. We do not request to autostart, as
-     * we don't really want the MMManager creation to fail. We can always poke
-     * later on if we want to request the autostart */
-    if (!priv->modm.manager) {
-        if (!priv->main_cancellable)
-            priv->main_cancellable = g_cancellable_new();
-        mm_manager_new(priv->dbus_connection,
-                       G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START,
-                       priv->main_cancellable,
-                       modm_manager_new_cb,
-                       self);
-        return;
-    }
-
-    /* If already available, recheck name owner! */
-    modm_manager_check_name_owner(self);
-}
-
-static gboolean
-modm_schedule_manager_relaunch_cb(NMModemManager *self)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    priv->modm.relaunch_id = 0;
-    modm_ensure_manager(self);
-    return G_SOURCE_REMOVE;
-}
-
-static void
-modm_schedule_manager_relaunch(NMModemManager *self, guint n_seconds)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    /* No need to pass an extra reference to self; timeout/idle will be
-     * cancelled if the object gets disposed. */
-    if (n_seconds)
-        priv->modm.relaunch_id =
-            g_timeout_add_seconds(n_seconds, (GSourceFunc) modm_schedule_manager_relaunch_cb, self);
-    else
-        priv->modm.relaunch_id = g_idle_add((GSourceFunc) modm_schedule_manager_relaunch_cb, self);
-}
-
-/*****************************************************************************/
-
-static void
-modm_proxy_name_owner_reset(NMModemManager *self)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-    char *                 name = NULL;
-
-    if (priv->modm.proxy)
-        name = g_dbus_proxy_get_name_owner(priv->modm.proxy);
-
-    if (nm_streq0(priv->modm.proxy_name_owner, name)) {
-        g_free(name);
-        return;
-    }
-    g_free(priv->modm.proxy_name_owner);
-    priv->modm.proxy_name_owner = name;
-
-    _notify(self, PROP_NAME_OWNER);
-}
-
-static void
-modm_proxy_name_owner_changed_cb(GObject *object, GParamSpec *pspec, gpointer user_data)
-{
-    modm_proxy_name_owner_reset(user_data);
-}
-
-static void
-modm_proxy_new_cb(GObject *source_object, GAsyncResult *result, gpointer user_data)
-{
-    NMModemManager *       self;
-    NMModemManagerPrivate *priv;
-    GDBusProxy *           proxy;
-    gs_free_error GError *error = NULL;
-
-    proxy = g_dbus_proxy_new_for_bus_finish(result, &error);
-    if (!proxy && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = user_data;
-    priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    g_clear_object(&priv->modm.proxy_cancellable);
-
-    if (!proxy) {
-        _LOGW("could not obtain D-Bus proxy for ModemManager: %s", error->message);
-        return;
-    }
-
-    priv->modm.proxy = proxy;
-    g_signal_connect(priv->modm.proxy,
-                     "notify::g-name-owner",
-                     G_CALLBACK(modm_proxy_name_owner_changed_cb),
-                     self);
-
-    modm_proxy_name_owner_reset(self);
-}
-
-void
-nm_modem_manager_name_owner_ref(NMModemManager *self)
-{
-    NMModemManagerPrivate *priv;
-
-    g_return_if_fail(NM_IS_MODEM_MANAGER(self));
-
-    priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    if (priv->modm.proxy_ref_count++ > 0) {
-        /* only try once to create the proxy. If proxy creation
-         * for the first "ref" failed, it's unclear what to do.
-         * The proxy is hosed. */
-        return;
-    }
-
-    nm_assert(!priv->modm.proxy && !priv->modm.proxy_cancellable);
-
-    priv->modm.proxy_cancellable = g_cancellable_new();
-
-    g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
-                             G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
-                                 | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS
-                                 | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
-                             NULL,
-                             NM_MODEM_MANAGER_MM_DBUS_SERVICE,
-                             NM_MODEM_MANAGER_MM_DBUS_PATH,
-                             NM_MODEM_MANAGER_MM_DBUS_INTERFACE,
-                             priv->modm.proxy_cancellable,
-                             modm_proxy_new_cb,
-                             self);
-}
-
-void
-nm_modem_manager_name_owner_unref(NMModemManager *self)
-{
-    NMModemManagerPrivate *priv;
-
-    g_return_if_fail(NM_IS_MODEM_MANAGER(self));
-
-    priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    g_return_if_fail(priv->modm.proxy_ref_count > 0);
-
-    if (--priv->modm.proxy_ref_count > 0)
-        return;
-
-    nm_clear_g_cancellable(&priv->modm.proxy_cancellable);
-    g_clear_object(&priv->modm.proxy);
-
-    modm_proxy_name_owner_reset(self);
-}
-
-const char *
-nm_modem_manager_name_owner_get(NMModemManager *self)
-{
-    g_return_val_if_fail(NM_IS_MODEM_MANAGER(self), NULL);
-    nm_assert(NM_MODEM_MANAGER_GET_PRIVATE(self)->modm.proxy_ref_count > 0);
-
-    return NM_MODEM_MANAGER_GET_PRIVATE(self)->modm.proxy_name_owner;
-}
-
-/*****************************************************************************/
-
-#if WITH_OFONO
-
-static void
-ofono_create_modem(NMModemManager *self, const char *path)
-{
-    NMModemManagerPrivate *priv  = NM_MODEM_MANAGER_GET_PRIVATE(self);
-    NMModem *              modem = NULL;
-
-    /* Ensure duplicate modems aren't created.  Because we're not using the
-     * ObjectManager interface there's a race during oFono startup where we
-     * receive ModemAdded signals before GetModems() returns, so some of the
-     * modems returned from GetModems() may already have been created.
-     */
-    if (!g_hash_table_lookup(priv->modems, path)) {
-        modem = nm_modem_ofono_new(path);
-        if (modem)
-            handle_new_modem(self, modem);
-        else
-            _LOGW("Failed to create oFono modem for %s", path);
-    }
-}
-
-static void
-ofono_signal_cb(GDBusProxy *proxy,
-                char *      sender_name,
-                char *      signal_name,
-                GVariant *  parameters,
-                gpointer    user_data)
-{
-    NMModemManager *       self = NM_MODEM_MANAGER(user_data);
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-    char *                 object_path;
-    NMModem *              modem;
-
-    if (g_strcmp0(signal_name, "ModemAdded") == 0) {
-        g_variant_get(parameters, "(oa{sv})", &object_path, NULL);
-        _LOGI("oFono modem appeared: %s", object_path);
-
-        ofono_create_modem(NM_MODEM_MANAGER(user_data), object_path);
-        g_free(object_path);
-    } else if (g_strcmp0(signal_name, "ModemRemoved") == 0) {
-        g_variant_get(parameters, "(o)", &object_path);
-        _LOGI("oFono modem removed: %s", object_path);
-
-        modem = (NMModem *) g_hash_table_lookup(priv->modems, object_path);
-        if (modem) {
-            nm_modem_emit_removed(modem);
-            g_hash_table_remove(priv->modems, object_path);
-        } else {
-            _LOGW("could not remove modem %s, not found in table", object_path);
-        }
-        g_free(object_path);
-    }
-}
-
-static void
-ofono_enumerate_devices_done(GObject *proxy, GAsyncResult *res, gpointer user_data)
-{
-    NMModemManager *       self;
-    NMModemManagerPrivate *priv;
-    gs_free_error GError *error = NULL;
-    GVariant *            results;
-    GVariantIter *        iter;
-    const char *          path;
-
-    results = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error);
-    if (!results && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = NM_MODEM_MANAGER(user_data);
-    priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    g_clear_object(&priv->ofono.cancellable);
-
-    if (!results) {
-        _LOGW("failed to enumerate oFono devices: %s", error->message);
-        return;
-    }
-
-    g_variant_get(results, "(a(oa{sv}))", &iter);
-    while (g_variant_iter_loop(iter, "(&oa{sv})", &path, NULL))
-        ofono_create_modem(self, path);
-    g_variant_iter_free(iter);
-    g_variant_unref(results);
-}
-
-static void
-ofono_check_name_owner(NMModemManager *self, gboolean first_invocation)
-{
-    NMModemManagerPrivate *priv       = NM_MODEM_MANAGER_GET_PRIVATE(self);
-    gs_free char *         name_owner = NULL;
-
-    name_owner = g_dbus_proxy_get_name_owner(G_DBUS_PROXY(priv->ofono.proxy));
-    if (name_owner) {
-        _LOGI("oFono is %savailable", first_invocation ? "" : "now ");
-
-        nm_clear_g_cancellable(&priv->ofono.cancellable);
-        priv->ofono.cancellable = g_cancellable_new();
-
-        g_dbus_proxy_call(priv->ofono.proxy,
-                          "GetModems",
-                          NULL,
-                          G_DBUS_CALL_FLAGS_NONE,
-                          -1,
-                          priv->ofono.cancellable,
-                          ofono_enumerate_devices_done,
-                          self);
-    } else {
-        GHashTableIter iter;
-        NMModem *      modem;
-
-        _LOGI("oFono is %savailable", first_invocation ? "not " : "no longer ");
-
-        /* Remove any oFono modems that might be left around */
-        g_hash_table_iter_init(&iter, priv->modems);
-        while (g_hash_table_iter_next(&iter, NULL, (gpointer) &modem)) {
-            if (NM_IS_MODEM_OFONO(modem)) {
-                nm_modem_emit_removed(modem);
-                g_hash_table_iter_remove(&iter);
-            }
-        }
-    }
-}
-
-static void
-ofono_name_owner_changed(GDBusProxy *ofono_proxy, GParamSpec *pspec, NMModemManager *self)
-{
-    ofono_check_name_owner(self, FALSE);
-}
-
-static void
-ofono_proxy_new_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
-{
-    NMModemManager *       self;
-    NMModemManagerPrivate *priv;
-    gs_free_error GError *error = NULL;
-    GDBusProxy *          proxy;
-
-    proxy = g_dbus_proxy_new_finish(res, &error);
-    if (!proxy && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = NM_MODEM_MANAGER(user_data);
-    priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    g_clear_object(&priv->ofono.cancellable);
-
-    if (!proxy) {
-        _LOGW("error getting oFono bus proxy: %s", error->message);
-        return;
-    }
-
-    priv->ofono.proxy = proxy;
-
-    g_signal_connect(priv->ofono.proxy,
-                     "notify::g-name-owner",
-                     G_CALLBACK(ofono_name_owner_changed),
-                     self);
-
-    g_signal_connect(priv->ofono.proxy, "g-signal", G_CALLBACK(ofono_signal_cb), self);
-
-    ofono_check_name_owner(self, TRUE);
-}
-
-static void
-ofono_init_proxy(NMModemManager *self)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    nm_assert(priv->dbus_connection);
-    nm_assert(!priv->ofono.cancellable);
-
-    priv->ofono.cancellable = g_cancellable_new();
-
-    g_dbus_proxy_new(priv->dbus_connection,
-                     G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
-                     NULL,
-                     OFONO_DBUS_SERVICE,
-                     OFONO_DBUS_PATH,
-                     OFONO_DBUS_INTERFACE,
-                     priv->ofono.cancellable,
-                     ofono_proxy_new_cb,
-                     self);
-}
-#endif
-
-/*****************************************************************************/
-
-static void
-bus_get_ready(GObject *source, GAsyncResult *res, gpointer user_data)
-{
-    NMModemManager *       self;
-    NMModemManagerPrivate *priv;
-    gs_free_error GError *error = NULL;
-    GDBusConnection *     connection;
-
-    connection = g_bus_get_finish(res, &error);
-    if (!connection && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = NM_MODEM_MANAGER(user_data);
-    priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    if (!connection) {
-        _LOGW("error getting bus connection: %s", error->message);
-        return;
-    }
-
-    priv->dbus_connection = connection;
-
-    modm_ensure_manager(self);
-#if WITH_OFONO
-    ofono_init_proxy(self);
-#endif
-}
-
-/*****************************************************************************/
-
-static void
-get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
-    NMModemManager *       self = NM_MODEM_MANAGER(object);
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    switch (prop_id) {
-    case PROP_NAME_OWNER:
-        g_value_set_string(value, priv->modm.proxy_name_owner);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-/*****************************************************************************/
-
-static void
-nm_modem_manager_init(NMModemManager *self)
-{
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    priv->modems = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_object_unref);
-
-    priv->main_cancellable = g_cancellable_new();
-
-    g_bus_get(G_BUS_TYPE_SYSTEM, priv->main_cancellable, bus_get_ready, self);
-}
-
-static void
-dispose(GObject *object)
-{
-    NMModemManager *       self = NM_MODEM_MANAGER(object);
-    NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self);
-
-    nm_clear_g_cancellable(&priv->main_cancellable);
-    nm_clear_g_cancellable(&priv->modm.poke_cancellable);
-
-    nm_clear_g_source(&priv->modm.relaunch_id);
-
-    nm_clear_g_cancellable(&priv->modm.proxy_cancellable);
-    g_clear_object(&priv->modm.proxy);
-    nm_clear_g_free(&priv->modm.proxy_name_owner);
-
-    modm_clear_manager(self);
-
-#if WITH_OFONO
-    if (priv->ofono.proxy) {
-        g_signal_handlers_disconnect_by_func(priv->ofono.proxy, ofono_name_owner_changed, self);
-        g_signal_handlers_disconnect_by_func(priv->ofono.proxy, ofono_signal_cb, self);
-        g_clear_object(&priv->ofono.proxy);
-    }
-    nm_clear_g_cancellable(&priv->ofono.cancellable);
-#endif
-
-    g_clear_object(&priv->dbus_connection);
-
-    if (priv->modems) {
-        g_hash_table_foreach_remove(priv->modems, remove_one_modem, object);
-        g_hash_table_destroy(priv->modems);
-        priv->modems = NULL;
-    }
-
-    G_OBJECT_CLASS(nm_modem_manager_parent_class)->dispose(object);
-}
-
-static void
-nm_modem_manager_class_init(NMModemManagerClass *klass)
-{
-    GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
-    object_class->dispose      = dispose;
-    object_class->get_property = get_property;
-
-    obj_properties[PROP_NAME_OWNER] =
-        g_param_spec_string(NM_MODEM_MANAGER_NAME_OWNER,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-
-    signals[MODEM_ADDED] = g_signal_new(NM_MODEM_MANAGER_MODEM_ADDED,
-                                        G_OBJECT_CLASS_TYPE(object_class),
-                                        G_SIGNAL_RUN_FIRST,
-                                        0,
-                                        NULL,
-                                        NULL,
-                                        NULL,
-                                        G_TYPE_NONE,
-                                        1,
-                                        NM_TYPE_MODEM);
-}
diff --git a/src/devices/wwan/nm-modem-manager.h b/src/devices/wwan/nm-modem-manager.h
deleted file mode 100644
index 895d4ced..00000000
--- a/src/devices/wwan/nm-modem-manager.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2009 - 2014 Red Hat, Inc.
- * Copyright (C) 2009 Novell, Inc.
- * Copyright (C) 2009 Canonical Ltd.
- */
-
-#ifndef __NETWORKMANAGER_MODEM_MANAGER_H__
-#define __NETWORKMANAGER_MODEM_MANAGER_H__
-
-#include "nm-modem.h"
-
-#define NM_TYPE_MODEM_MANAGER (nm_modem_manager_get_type())
-#define NM_MODEM_MANAGER(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MODEM_MANAGER, NMModemManager))
-#define NM_MODEM_MANAGER_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_MODEM_MANAGER, NMModemManagerClass))
-#define NM_IS_MODEM_MANAGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_MODEM_MANAGER))
-#define NM_IS_MODEM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_MODEM_MANAGER))
-#define NM_MODEM_MANAGER_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_MODEM_MANAGER, NMModemManagerClass))
-
-#define NM_MODEM_MANAGER_MODEM_ADDED "modem-added"
-
-#define NM_MODEM_MANAGER_NAME_OWNER "name-owner"
-
-#define NM_MODEM_MANAGER_MM_DBUS_SERVICE   "org.freedesktop.ModemManager1"
-#define NM_MODEM_MANAGER_MM_DBUS_PATH      "/org/freedesktop/ModemManager1"
-#define NM_MODEM_MANAGER_MM_DBUS_INTERFACE "org.freedesktop.ModemManager1"
-
-typedef struct _NMModemManager      NMModemManager;
-typedef struct _NMModemManagerClass NMModemManagerClass;
-
-GType nm_modem_manager_get_type(void);
-
-NMModemManager *nm_modem_manager_get(void);
-
-void nm_modem_manager_name_owner_ref(NMModemManager *self);
-void nm_modem_manager_name_owner_unref(NMModemManager *self);
-
-const char *nm_modem_manager_name_owner_get(NMModemManager *self);
-
-NMModem **nm_modem_manager_get_modems(NMModemManager *self, guint *out_len);
-
-#endif /* __NETWORKMANAGER_MODEM_MANAGER_H__ */
diff --git a/src/devices/wwan/nm-modem-ofono.c b/src/devices/wwan/nm-modem-ofono.c
deleted file mode 100644
index d8d0893b..00000000
--- a/src/devices/wwan/nm-modem-ofono.c
+++ /dev/null
@@ -1,1239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2013 - 2016 Canonical Ltd.
- */
-
-#include "nm-default.h"
-
-#include "nm-modem-ofono.h"
-
-#include "nm-core-internal.h"
-#include "devices/nm-device-private.h"
-#include "nm-modem.h"
-#include "platform/nm-platform.h"
-#include "nm-ip4-config.h"
-
-#define VARIANT_IS_OF_TYPE_BOOLEAN(v) \
-    ((v) != NULL && (g_variant_is_of_type((v), G_VARIANT_TYPE_BOOLEAN)))
-#define VARIANT_IS_OF_TYPE_STRING(v) \
-    ((v) != NULL && (g_variant_is_of_type((v), G_VARIANT_TYPE_STRING)))
-#define VARIANT_IS_OF_TYPE_OBJECT_PATH(v) \
-    ((v) != NULL && (g_variant_is_of_type((v), G_VARIANT_TYPE_OBJECT_PATH)))
-#define VARIANT_IS_OF_TYPE_STRING_ARRAY(v) \
-    ((v) != NULL && (g_variant_is_of_type((v), G_VARIANT_TYPE_STRING_ARRAY)))
-#define VARIANT_IS_OF_TYPE_DICTIONARY(v) \
-    ((v) != NULL && (g_variant_is_of_type((v), G_VARIANT_TYPE_DICTIONARY)))
-
-/*****************************************************************************/
-
-typedef struct {
-    GHashTable *connect_properties;
-
-    GDBusProxy *modem_proxy;
-    GDBusProxy *connman_proxy;
-    GDBusProxy *context_proxy;
-    GDBusProxy *sim_proxy;
-
-    GCancellable *modem_proxy_cancellable;
-    GCancellable *connman_proxy_cancellable;
-    GCancellable *context_proxy_cancellable;
-    GCancellable *sim_proxy_cancellable;
-
-    GError *property_error;
-
-    char *context_path;
-    char *imsi;
-
-    gboolean modem_online;
-    gboolean gprs_attached;
-
-    NMIP4Config *ip4_config;
-} NMModemOfonoPrivate;
-
-struct _NMModemOfono {
-    NMModem             parent;
-    NMModemOfonoPrivate _priv;
-};
-
-struct _NMModemOfonoClass {
-    NMModemClass parent;
-};
-
-G_DEFINE_TYPE(NMModemOfono, nm_modem_ofono, NM_TYPE_MODEM)
-
-#define NM_MODEM_OFONO_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMModemOfono, NM_IS_MODEM_OFONO)
-
-/*****************************************************************************/
-
-#define _NMLOG_DOMAIN      LOGD_MB
-#define _NMLOG_PREFIX_NAME "modem-ofono"
-#define _NMLOG(level, ...)                                                  \
-    G_STMT_START                                                            \
-    {                                                                       \
-        const NMLogLevel _level = (level);                                  \
-                                                                            \
-        if (nm_logging_enabled(_level, (_NMLOG_DOMAIN))) {                  \
-            NMModemOfono *const __self = (self);                            \
-            char                __prefix_name[128];                         \
-            const char *        __uid;                                      \
-                                                                            \
-            _nm_log(_level,                                                 \
-                    (_NMLOG_DOMAIN),                                        \
-                    0,                                                      \
-                    NULL,                                                   \
-                    NULL,                                                   \
-                    "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__),            \
-                    _NMLOG_PREFIX_NAME,                                     \
-                    (__self ? ({                                            \
-                        ((__uid = nm_modem_get_uid((NMModem *) __self))     \
-                             ? nm_sprintf_buf(__prefix_name, "[%s]", __uid) \
-                             : "(null)");                                   \
-                    })                                                      \
-                            : "") _NM_UTILS_MACRO_REST(__VA_ARGS__));       \
-        }                                                                   \
-    }                                                                       \
-    G_STMT_END
-
-/*****************************************************************************/
-
-static void
-get_capabilities(NMModem *                  _self,
-                 NMDeviceModemCapabilities *modem_caps,
-                 NMDeviceModemCapabilities *current_caps)
-{
-    /* FIXME: auto-detect capabilities to allow LTE */
-    *modem_caps   = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
-    *current_caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
-}
-
-static void
-update_modem_state(NMModemOfono *self)
-{
-    NMModemOfonoPrivate *priv      = NM_MODEM_OFONO_GET_PRIVATE(self);
-    NMModemState         state     = nm_modem_get_state(NM_MODEM(self));
-    NMModemState         new_state = NM_MODEM_STATE_DISABLED;
-    const char *         reason    = NULL;
-
-    _LOGI("'Attached': %s 'Online': %s 'IMSI': %s",
-          priv->gprs_attached ? "true" : "false",
-          priv->modem_online ? "true" : "false",
-          priv->imsi);
-
-    if (priv->modem_online == FALSE) {
-        reason = "modem 'Online=false'";
-    } else if (priv->imsi == NULL && state != NM_MODEM_STATE_ENABLING) {
-        reason = "modem not ready";
-    } else if (priv->gprs_attached == FALSE) {
-        new_state = NM_MODEM_STATE_SEARCHING;
-        reason    = "modem searching";
-    } else {
-        new_state = NM_MODEM_STATE_REGISTERED;
-        reason    = "modem ready";
-    }
-
-    if (state != new_state)
-        nm_modem_set_state(NM_MODEM(self), new_state, reason);
-}
-
-/* Disconnect */
-typedef struct {
-    NMModemOfono *             self;
-    _NMModemDisconnectCallback callback;
-    gpointer                   callback_user_data;
-    GCancellable *             cancellable;
-    gboolean                   warn;
-} DisconnectContext;
-
-static void
-disconnect_context_complete(DisconnectContext *ctx, GError *error)
-{
-    if (ctx->callback)
-        ctx->callback(NM_MODEM(ctx->self), error, ctx->callback_user_data);
-    nm_g_object_unref(ctx->cancellable);
-    g_object_unref(ctx->self);
-    g_slice_free(DisconnectContext, ctx);
-}
-
-static void
-disconnect_context_complete_on_idle(gpointer user_data, GCancellable *cancellable)
-{
-    DisconnectContext *ctx      = user_data;
-    gs_free_error GError *error = NULL;
-
-    if (!g_cancellable_set_error_if_cancelled(cancellable, &error)) {
-        g_set_error_literal(&error,
-                            NM_UTILS_ERROR,
-                            NM_UTILS_ERROR_UNKNOWN,
-                            ("modem is currently not connected"));
-    }
-    disconnect_context_complete(ctx, error);
-}
-
-static void
-disconnect_done(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    DisconnectContext *ctx       = user_data;
-    NMModemOfono *     self      = ctx->self;
-    gs_free_error GError *error  = NULL;
-    gs_unref_variant GVariant *v = NULL;
-
-    v = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), result, &error);
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-        disconnect_context_complete(ctx, error);
-        return;
-    }
-
-    if (error && ctx->warn)
-        _LOGW("failed to disconnect modem: %s", error->message);
-
-    _LOGD("modem disconnected");
-
-    update_modem_state(self);
-    disconnect_context_complete(ctx, error);
-}
-
-static void
-disconnect(NMModem *                  modem,
-           gboolean                   warn,
-           GCancellable *             cancellable,
-           _NMModemDisconnectCallback callback,
-           gpointer                   user_data)
-{
-    NMModemOfono *       self = NM_MODEM_OFONO(modem);
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-    DisconnectContext *  ctx;
-    NMModemState         state = nm_modem_get_state(NM_MODEM(self));
-
-    _LOGD("warn: %s modem_state: %s", warn ? "TRUE" : "FALSE", nm_modem_state_to_string(state));
-
-    ctx                     = g_slice_new0(DisconnectContext);
-    ctx->self               = g_object_ref(self);
-    ctx->cancellable        = nm_g_object_ref(cancellable);
-    ctx->warn               = warn;
-    ctx->callback           = callback;
-    ctx->callback_user_data = user_data;
-
-    if (state != NM_MODEM_STATE_CONNECTED || g_cancellable_is_cancelled(cancellable)) {
-        nm_utils_invoke_on_idle(cancellable, disconnect_context_complete_on_idle, ctx);
-        return;
-    }
-
-    nm_modem_set_state(NM_MODEM(self),
-                       NM_MODEM_STATE_DISCONNECTING,
-                       nm_modem_state_to_string(NM_MODEM_STATE_DISCONNECTING));
-
-    g_dbus_proxy_call(priv->context_proxy,
-                      "SetProperty",
-                      g_variant_new("(sv)", "Active", g_variant_new("b", warn)),
-                      G_DBUS_CALL_FLAGS_NONE,
-                      20000,
-                      ctx->cancellable,
-                      disconnect_done,
-                      ctx);
-}
-
-static void
-deactivate_cleanup(NMModem *modem, NMDevice *device, gboolean stop_ppp_manager)
-{
-    NMModemOfono *       self = NM_MODEM_OFONO(modem);
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    /* TODO: cancel SimpleConnect() if any */
-
-    g_clear_object(&priv->ip4_config);
-
-    NM_MODEM_CLASS(nm_modem_ofono_parent_class)
-        ->deactivate_cleanup(modem, device, stop_ppp_manager);
-}
-
-static gboolean
-check_connection_compatible_with_modem(NMModem *modem, NMConnection *connection, GError **error)
-{
-    NMModemOfono *       self = NM_MODEM_OFONO(modem);
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-    const char *         id;
-
-    if (!_nm_connection_check_main_setting(connection, NM_SETTING_GSM_SETTING_NAME, NULL)) {
-        nm_utils_error_set(error,
-                           NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE,
-                           "connection type %s is not supported by ofono modem",
-                           nm_connection_get_connection_type(connection));
-        return FALSE;
-    }
-
-    if (!priv->imsi) {
-        nm_utils_error_set_literal(error,
-                                   NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                                   "modem has no IMSI");
-        return FALSE;
-    }
-
-    id = nm_connection_get_id(connection);
-
-    if (!strstr(id, "/context")) {
-        nm_utils_error_set_literal(error,
-                                   NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                                   "the connection ID has no context");
-        return FALSE;
-    }
-
-    if (!strstr(id, priv->imsi)) {
-        nm_utils_error_set_literal(error,
-                                   NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                                   "the connection ID does not contain the IMSI");
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-static void
-handle_sim_property(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data)
-{
-    NMModemOfono *       self = NM_MODEM_OFONO(user_data);
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    if (g_strcmp0(property, "SubscriberIdentity") == 0 && VARIANT_IS_OF_TYPE_STRING(v)) {
-        gsize       length;
-        const char *value_str = g_variant_get_string(v, &length);
-
-        _LOGD("SubscriberIdentify found");
-
-        /* Check for empty DBus string value */
-        if (length && g_strcmp0(value_str, "(null)") != 0
-            && g_strcmp0(value_str, priv->imsi) != 0) {
-            if (priv->imsi != NULL) {
-                _LOGW("SimManager:'SubscriberIdentity' changed: %s", priv->imsi);
-                g_free(priv->imsi);
-            }
-
-            priv->imsi = g_strdup(value_str);
-            update_modem_state(self);
-        }
-    }
-}
-
-static void
-sim_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data)
-{
-    GVariant *v_child = g_variant_get_child_value(v, 0);
-
-    handle_sim_property(proxy, property, v_child, user_data);
-    g_variant_unref(v_child);
-}
-
-static void
-sim_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMModemOfono *       self;
-    NMModemOfonoPrivate *priv;
-    gs_free_error GError *error             = NULL;
-    gs_unref_variant GVariant *v_properties = NULL;
-    gs_unref_variant GVariant *v_dict       = NULL;
-    GVariant *                 v;
-    GVariantIter               i;
-    const char *               property;
-
-    v_properties =
-        _nm_dbus_proxy_call_finish(G_DBUS_PROXY(source), result, G_VARIANT_TYPE("(a{sv})"), &error);
-    if (!v_properties && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = NM_MODEM_OFONO(user_data);
-    priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    g_clear_object(&priv->sim_proxy_cancellable);
-
-    if (!v_properties) {
-        g_dbus_error_strip_remote_error(error);
-        _LOGW("error getting sim properties: %s", error->message);
-        return;
-    }
-
-    _LOGD("sim v_properties is type: %s", g_variant_get_type_string(v_properties));
-
-    v_dict = g_variant_get_child_value(v_properties, 0);
-    if (!v_dict) {
-        _LOGW("error getting sim properties: no v_dict");
-        return;
-    }
-
-    _LOGD("sim v_dict is type: %s", g_variant_get_type_string(v_dict));
-
-    /*
-     * TODO:
-     * 1) optimize by looking up properties ( Online, Interfaces ), instead
-     *    of iterating
-     *
-     * 2) reduce code duplication between all of the get_properties_done
-     *    functions in this class.
-     */
-
-    g_variant_iter_init(&i, v_dict);
-    while (g_variant_iter_next(&i, "{&sv}", &property, &v)) {
-        handle_sim_property(NULL, property, v, self);
-        g_variant_unref(v);
-    }
-}
-
-static void
-_sim_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMModemOfono *       self;
-    NMModemOfonoPrivate *priv;
-    gs_free_error GError *error = NULL;
-    GDBusProxy *          proxy;
-
-    proxy = g_dbus_proxy_new_for_bus_finish(result, &error);
-    if (!proxy && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = user_data;
-    priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    if (!proxy) {
-        _LOGW("failed to create SimManager proxy: %s", error->message);
-        g_clear_object(&priv->sim_proxy_cancellable);
-        return;
-    }
-
-    priv->sim_proxy = proxy;
-
-    /* Watch for custom ofono PropertyChanged signals */
-    _nm_dbus_signal_connect(priv->sim_proxy,
-                            "PropertyChanged",
-                            G_VARIANT_TYPE("(sv)"),
-                            G_CALLBACK(sim_property_changed),
-                            self);
-
-    g_dbus_proxy_call(priv->sim_proxy,
-                      "GetProperties",
-                      NULL,
-                      G_DBUS_CALL_FLAGS_NONE,
-                      20000,
-                      priv->sim_proxy_cancellable,
-                      sim_get_properties_done,
-                      self);
-}
-
-static void
-handle_sim_iface(NMModemOfono *self, gboolean found)
-{
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    _LOGD("SimManager interface %sfound", found ? "" : "not ");
-
-    if (!found && (priv->sim_proxy || priv->sim_proxy_cancellable)) {
-        _LOGI("SimManager interface disappeared");
-        nm_clear_g_cancellable(&priv->sim_proxy_cancellable);
-        if (priv->sim_proxy) {
-            g_signal_handlers_disconnect_by_data(priv->sim_proxy, self);
-            g_clear_object(&priv->sim_proxy);
-        }
-        nm_clear_g_free(&priv->imsi);
-        update_modem_state(self);
-    } else if (found && (!priv->sim_proxy && !priv->sim_proxy_cancellable)) {
-        _LOGI("found new SimManager interface");
-
-        priv->sim_proxy_cancellable = g_cancellable_new();
-
-        g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
-                                 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
-                                     | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
-                                 NULL, /* GDBusInterfaceInfo */
-                                 OFONO_DBUS_SERVICE,
-                                 nm_modem_get_path(NM_MODEM(self)),
-                                 OFONO_DBUS_INTERFACE_SIM_MANAGER,
-                                 priv->sim_proxy_cancellable, /* GCancellable */
-                                 _sim_proxy_new_cb,
-                                 self);
-    }
-}
-
-static void
-handle_connman_property(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data)
-{
-    NMModemOfono *       self = NM_MODEM_OFONO(user_data);
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    if (g_strcmp0(property, "Attached") == 0 && VARIANT_IS_OF_TYPE_BOOLEAN(v)) {
-        gboolean attached     = g_variant_get_boolean(v);
-        gboolean old_attached = priv->gprs_attached;
-
-        _LOGD("Attached: %s", attached ? "True" : "False");
-
-        if (priv->gprs_attached != attached) {
-            priv->gprs_attached = attached;
-
-            _LOGI("Attached %s -> %s",
-                  old_attached ? "true" : "false",
-                  attached ? "true" : "false");
-
-            update_modem_state(self);
-        }
-    }
-}
-
-static void
-connman_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data)
-{
-    GVariant *v_child = g_variant_get_child_value(v, 0);
-
-    handle_connman_property(proxy, property, v_child, user_data);
-    g_variant_unref(v_child);
-}
-
-static void
-connman_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMModemOfono *       self;
-    NMModemOfonoPrivate *priv;
-    gs_free_error GError *error             = NULL;
-    gs_unref_variant GVariant *v_properties = NULL;
-    gs_unref_variant GVariant *v_dict       = NULL;
-    GVariant *                 v;
-    GVariantIter               i;
-    const char *               property;
-
-    v_properties =
-        _nm_dbus_proxy_call_finish(G_DBUS_PROXY(source), result, G_VARIANT_TYPE("(a{sv})"), &error);
-    if (!v_properties && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = NM_MODEM_OFONO(user_data);
-    priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    g_clear_object(&priv->connman_proxy_cancellable);
-
-    if (!v_properties) {
-        g_dbus_error_strip_remote_error(error);
-        _LOGW("error getting connman properties: %s", error->message);
-        return;
-    }
-
-    v_dict = g_variant_get_child_value(v_properties, 0);
-
-    /*
-     * TODO:
-     * 1) optimize by looking up properties ( Online, Interfaces ), instead
-     *    of iterating
-     *
-     * 2) reduce code duplication between all of the get_properties_done
-     *    functions in this class.
-     */
-
-    g_variant_iter_init(&i, v_dict);
-    while (g_variant_iter_next(&i, "{&sv}", &property, &v)) {
-        handle_connman_property(NULL, property, v, self);
-        g_variant_unref(v);
-    }
-}
-
-static void
-_connman_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMModemOfono *       self;
-    NMModemOfonoPrivate *priv;
-    gs_free_error GError *error = NULL;
-    GDBusProxy *          proxy;
-
-    proxy = g_dbus_proxy_new_for_bus_finish(result, &error);
-    if (!proxy && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = user_data;
-    priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    if (!proxy) {
-        _LOGW("failed to create ConnectionManager proxy: %s", error->message);
-        g_clear_object(&priv->connman_proxy_cancellable);
-        return;
-    }
-
-    priv->connman_proxy = proxy;
-
-    _nm_dbus_signal_connect(priv->connman_proxy,
-                            "PropertyChanged",
-                            G_VARIANT_TYPE("(sv)"),
-                            G_CALLBACK(connman_property_changed),
-                            self);
-
-    g_dbus_proxy_call(priv->connman_proxy,
-                      "GetProperties",
-                      NULL,
-                      G_DBUS_CALL_FLAGS_NONE,
-                      20000,
-                      priv->connman_proxy_cancellable,
-                      connman_get_properties_done,
-                      self);
-}
-
-static void
-handle_connman_iface(NMModemOfono *self, gboolean found)
-{
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    _LOGD("ConnectionManager interface %sfound", found ? "" : "not ");
-
-    if (!found && (priv->connman_proxy || priv->connman_proxy_cancellable)) {
-        _LOGI("ConnectionManager interface disappeared");
-        nm_clear_g_cancellable(&priv->connman_proxy_cancellable);
-        if (priv->connman_proxy) {
-            g_signal_handlers_disconnect_by_data(priv->connman_proxy, self);
-            g_clear_object(&priv->connman_proxy);
-        }
-
-        /* The connection manager proxy disappeared, we should
-         * consider the modem disabled.
-         */
-        priv->gprs_attached = FALSE;
-
-        update_modem_state(self);
-    } else if (found && (!priv->connman_proxy && !priv->connman_proxy_cancellable)) {
-        _LOGI("found new ConnectionManager interface");
-
-        priv->connman_proxy_cancellable = g_cancellable_new();
-
-        g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
-                                 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
-                                     | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
-                                 NULL, /* GDBusInterfaceInfo */
-                                 OFONO_DBUS_SERVICE,
-                                 nm_modem_get_path(NM_MODEM(self)),
-                                 OFONO_DBUS_INTERFACE_CONNECTION_MANAGER,
-                                 priv->connman_proxy_cancellable,
-                                 _connman_proxy_new_cb,
-                                 self);
-    }
-}
-
-static void
-handle_modem_property(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data)
-{
-    NMModemOfono *       self = NM_MODEM_OFONO(user_data);
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    if ((g_strcmp0(property, "Online") == 0) && VARIANT_IS_OF_TYPE_BOOLEAN(v)) {
-        gboolean online = g_variant_get_boolean(v);
-
-        _LOGD("Online: %s", online ? "True" : "False");
-
-        if (online != priv->modem_online) {
-            priv->modem_online = online;
-            _LOGI("modem is now %s", online ? "Online" : "Offline");
-            update_modem_state(self);
-        }
-
-    } else if ((g_strcmp0(property, "Interfaces") == 0) && VARIANT_IS_OF_TYPE_STRING_ARRAY(v)) {
-        const char **array, **iter;
-        gboolean     found_connman = FALSE;
-        gboolean     found_sim     = FALSE;
-
-        _LOGD("Interfaces found");
-
-        array = g_variant_get_strv(v, NULL);
-        if (array) {
-            for (iter = array; *iter; iter++) {
-                if (g_strcmp0(OFONO_DBUS_INTERFACE_SIM_MANAGER, *iter) == 0)
-                    found_sim = TRUE;
-                else if (g_strcmp0(OFONO_DBUS_INTERFACE_CONNECTION_MANAGER, *iter) == 0)
-                    found_connman = TRUE;
-            }
-            g_free(array);
-        }
-
-        handle_sim_iface(self, found_sim);
-        handle_connman_iface(self, found_connman);
-    }
-}
-
-static void
-modem_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data)
-{
-    GVariant *v_child = g_variant_get_child_value(v, 0);
-
-    handle_modem_property(proxy, property, v_child, user_data);
-    g_variant_unref(v_child);
-}
-
-static void
-modem_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMModemOfono *       self;
-    NMModemOfonoPrivate *priv;
-    gs_free_error GError *error             = NULL;
-    gs_unref_variant GVariant *v_properties = NULL;
-    gs_unref_variant GVariant *v_dict       = NULL;
-    GVariant *                 v;
-    GVariantIter               i;
-    const char *               property;
-
-    v_properties =
-        _nm_dbus_proxy_call_finish(G_DBUS_PROXY(source), result, G_VARIANT_TYPE("(a{sv})"), &error);
-    if (!v_properties && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = NM_MODEM_OFONO(user_data);
-    priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    g_clear_object(&priv->modem_proxy_cancellable);
-
-    if (!v_properties) {
-        g_dbus_error_strip_remote_error(error);
-        _LOGW("error getting modem properties: %s", error->message);
-        return;
-    }
-
-    v_dict = g_variant_get_child_value(v_properties, 0);
-    if (!v_dict) {
-        _LOGW("error getting modem properties: no v_dict");
-        return;
-    }
-
-    /*
-     * TODO:
-     * 1) optimize by looking up properties ( Online, Interfaces ), instead
-     *    of iterating
-     *
-     * 2) reduce code duplication between all of the get_properties_done
-     *    functions in this class.
-     */
-
-    g_variant_iter_init(&i, v_dict);
-    while (g_variant_iter_next(&i, "{&sv}", &property, &v)) {
-        handle_modem_property(NULL, property, v, self);
-        g_variant_unref(v);
-    }
-}
-
-static void
-stage1_prepare_done(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMModemOfono *       self;
-    NMModemOfonoPrivate *priv;
-    gs_free_error GError *error  = NULL;
-    gs_unref_variant GVariant *v = NULL;
-
-    v = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), result, &error);
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = NM_MODEM_OFONO(user_data);
-    priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    g_clear_object(&priv->context_proxy_cancellable);
-
-    nm_clear_pointer(&priv->connect_properties, g_hash_table_destroy);
-
-    if (error) {
-        _LOGW("connection failed: %s", error->message);
-
-        nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY);
-        /*
-         * FIXME: add code to check for InProgress so that the
-         * connection doesn't continue to try and activate,
-         * leading to the connection being disabled, and a 5m
-         * timeout...
-         */
-    }
-}
-
-static void
-context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data)
-{
-    NMModemOfono *       self = NM_MODEM_OFONO(user_data);
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-    NMPlatformIP4Address addr;
-    gboolean             ret          = FALSE;
-    gs_unref_variant GVariant *v_dict = NULL;
-    const char *               interface;
-    const char *               s;
-    const char **              array, **iter;
-    guint32                    address_network, gateway_network;
-    guint32                    ip4_route_table, ip4_route_metric;
-    int                        ifindex;
-    GError *                   error = NULL;
-
-    _LOGD("PropertyChanged: %s", property);
-
-    /*
-     * TODO: might be a good idea and re-factor this to mimic bluez-device,
-     * ie. have this function just check the key, and call a sub-func to
-     * handle the action.
-     */
-
-    if (g_strcmp0(property, "Settings") != 0)
-        return;
-
-    v_dict = g_variant_get_child_value(v, 0);
-    if (!v_dict) {
-        _LOGW("error getting IPv4 Settings: no v_dict");
-        goto out;
-    }
-
-    _LOGI("IPv4 static Settings:");
-
-    if (!g_variant_lookup(v_dict, "Interface", "&s", &interface)) {
-        _LOGW("Settings 'Interface' missing");
-        goto out;
-    }
-
-    _LOGD("Interface: %s", interface);
-    if (!nm_modem_set_data_port(NM_MODEM(self),
-                                NM_PLATFORM_GET,
-                                interface,
-                                NM_MODEM_IP_METHOD_STATIC,
-                                NM_MODEM_IP_METHOD_UNKNOWN,
-                                0,
-                                &error)) {
-        _LOGW("failed to connect to modem: %s", error->message);
-        g_clear_error(&error);
-        goto out;
-    }
-
-    ifindex = nm_modem_get_ip_ifindex(NM_MODEM(self));
-    nm_assert(ifindex > 0);
-
-    /* TODO: verify handling of ip4_config; check other places it's used... */
-    g_clear_object(&priv->ip4_config);
-
-    priv->ip4_config = nm_ip4_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), ifindex);
-
-    if (!g_variant_lookup(v_dict, "Address", "&s", &s)) {
-        _LOGW("Settings 'Address' missing");
-        goto out;
-    }
-    if (!s || !nm_utils_parse_inaddr_bin(AF_INET, s, NULL, &address_network)) {
-        _LOGW("can't convert 'Address' %s to addr", s ?: "");
-        goto out;
-    }
-    memset(&addr, 0, sizeof(addr));
-    addr.ifindex     = ifindex;
-    addr.address     = address_network;
-    addr.addr_source = NM_IP_CONFIG_SOURCE_WWAN;
-
-    if (!g_variant_lookup(v_dict, "Netmask", "&s", &s)) {
-        _LOGW("Settings 'Netmask' missing");
-        goto out;
-    }
-    if (!s || !nm_utils_parse_inaddr_bin(AF_INET, s, NULL, &address_network)) {
-        _LOGW("invalid 'Netmask': %s", s ?: "");
-        goto out;
-    }
-    addr.plen = nm_utils_ip4_netmask_to_prefix(address_network);
-
-    _LOGI("Address: %s", nm_platform_ip4_address_to_string(&addr, NULL, 0));
-    nm_ip4_config_add_address(priv->ip4_config, &addr);
-
-    if (!g_variant_lookup(v_dict, "Gateway", "&s", &s) || !s) {
-        _LOGW("Settings 'Gateway' missing");
-        goto out;
-    }
-    if (!nm_utils_parse_inaddr_bin(AF_INET, s, NULL, &gateway_network)) {
-        _LOGW("invalid 'Gateway': %s", s);
-        goto out;
-    }
-    nm_modem_get_route_parameters(NM_MODEM(self), &ip4_route_table, &ip4_route_metric, NULL, NULL);
-    {
-        const NMPlatformIP4Route r = {
-            .rt_source     = NM_IP_CONFIG_SOURCE_WWAN,
-            .gateway       = gateway_network,
-            .table_coerced = nm_platform_route_table_coerce(ip4_route_table),
-            .metric        = ip4_route_metric,
-        };
-
-        _LOGI("Gateway: %s", s);
-        nm_ip4_config_add_route(priv->ip4_config, &r, NULL);
-    }
-
-    if (!g_variant_lookup(v_dict, "DomainNameServers", "^a&s", &array)) {
-        _LOGW("Settings 'DomainNameServers' missing");
-        goto out;
-    }
-    if (array) {
-        for (iter = array; *iter; iter++) {
-            if (nm_utils_parse_inaddr_bin(AF_INET, *iter, NULL, &address_network)
-                && address_network) {
-                _LOGI("DNS: %s", *iter);
-                nm_ip4_config_add_nameserver(priv->ip4_config, address_network);
-            } else {
-                _LOGW("invalid NameServer: %s", *iter);
-            }
-        }
-
-        if (iter == array) {
-            _LOGW("Settings: 'DomainNameServers': none specified");
-            g_free(array);
-            goto out;
-        }
-        g_free(array);
-    }
-
-    if (g_variant_lookup(v_dict, "MessageProxy", "&s", &s)) {
-        _LOGI("MessageProxy: %s", s);
-        if (s && nm_utils_parse_inaddr_bin(AF_INET, s, NULL, &address_network)) {
-            nm_modem_get_route_parameters(NM_MODEM(self),
-                                          &ip4_route_table,
-                                          &ip4_route_metric,
-                                          NULL,
-                                          NULL);
-
-            {
-                const NMPlatformIP4Route mms_route = {
-                    .network       = address_network,
-                    .plen          = 32,
-                    .gateway       = gateway_network,
-                    .table_coerced = nm_platform_route_table_coerce(ip4_route_table),
-                    .metric        = ip4_route_metric,
-                };
-
-                nm_ip4_config_add_route(priv->ip4_config, &mms_route, NULL);
-            }
-        } else {
-            _LOGW("invalid MessageProxy: %s", s);
-        }
-    }
-
-    ret = TRUE;
-
-out:
-    if (nm_modem_get_state(NM_MODEM(self)) != NM_MODEM_STATE_CONNECTED) {
-        _LOGI("emitting PREPARE_RESULT: %s", ret ? "TRUE" : "FALSE");
-        nm_modem_emit_prepare_result(NM_MODEM(self),
-                                     ret,
-                                     ret ? NM_DEVICE_STATE_REASON_NONE
-                                         : NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
-    } else {
-        _LOGW("MODEM_PPP_FAILED");
-        nm_modem_emit_ppp_failed(NM_MODEM(self), NM_DEVICE_STATE_REASON_PPP_FAILED);
-    }
-}
-
-static NMActStageReturn
-static_stage3_ip4_config_start(NMModem *            modem,
-                               NMActRequest *       req,
-                               NMDeviceStateReason *out_failure_reason)
-{
-    NMModemOfono *       self  = NM_MODEM_OFONO(modem);
-    NMModemOfonoPrivate *priv  = NM_MODEM_OFONO_GET_PRIVATE(self);
-    GError *             error = NULL;
-
-    if (!priv->ip4_config) {
-        _LOGD("IP4 config not ready(?)");
-        return NM_ACT_STAGE_RETURN_FAILURE;
-    }
-
-    _LOGD("IP4 config is done; setting modem_state -> CONNECTED");
-    g_signal_emit_by_name(self, NM_MODEM_IP4_CONFIG_RESULT, priv->ip4_config, error);
-
-    /* Signal listener takes ownership of the IP4Config */
-    priv->ip4_config = NULL;
-
-    nm_modem_set_state(NM_MODEM(self),
-                       NM_MODEM_STATE_CONNECTED,
-                       nm_modem_state_to_string(NM_MODEM_STATE_CONNECTED));
-    return NM_ACT_STAGE_RETURN_POSTPONE;
-}
-
-static void
-context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMModemOfono *       self;
-    NMModemOfonoPrivate *priv;
-    gs_free_error GError *error = NULL;
-    GDBusProxy *          proxy;
-
-    proxy = g_dbus_proxy_new_for_bus_finish(result, &error);
-    if (!proxy || g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = NM_MODEM_OFONO(user_data);
-    priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    if (!proxy) {
-        _LOGE("failed to create ofono ConnectionContext DBus proxy: %s", error->message);
-        g_clear_object(&priv->context_proxy_cancellable);
-        nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY);
-        return;
-    }
-
-    priv->context_proxy = proxy;
-
-    if (!priv->gprs_attached) {
-        g_clear_object(&priv->context_proxy_cancellable);
-        nm_modem_emit_prepare_result(NM_MODEM(self),
-                                     FALSE,
-                                     NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER);
-        return;
-    }
-
-    /* We have an old copy of the settings from a previous activation,
-     * clear it so that we can gate getting the IP config from oFono
-     * on whether or not we have already received them
-     */
-    g_clear_object(&priv->ip4_config);
-
-    _nm_dbus_signal_connect(priv->context_proxy,
-                            "PropertyChanged",
-                            G_VARIANT_TYPE("(sv)"),
-                            G_CALLBACK(context_property_changed),
-                            self);
-
-    g_dbus_proxy_call(priv->context_proxy,
-                      "SetProperty",
-                      g_variant_new("(sv)", "Active", g_variant_new("b", TRUE)),
-                      G_DBUS_CALL_FLAGS_NONE,
-                      20000,
-                      priv->context_proxy_cancellable,
-                      stage1_prepare_done,
-                      self);
-}
-
-static void
-do_context_activate(NMModemOfono *self)
-{
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    g_return_if_fail(NM_IS_MODEM_OFONO(self));
-
-    nm_clear_g_cancellable(&priv->context_proxy_cancellable);
-    g_clear_object(&priv->context_proxy);
-
-    priv->context_proxy_cancellable = g_cancellable_new();
-
-    g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
-                             G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
-                             NULL,
-                             OFONO_DBUS_SERVICE,
-                             priv->context_path,
-                             OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT,
-                             priv->context_proxy_cancellable,
-                             context_proxy_new_cb,
-                             self);
-}
-
-static GHashTable *
-create_connect_properties(NMConnection *connection)
-{
-    NMSettingGsm *setting;
-    GHashTable *  properties;
-    const char *  str;
-
-    setting    = nm_connection_get_setting_gsm(connection);
-    properties = g_hash_table_new(nm_str_hash, g_str_equal);
-
-    str = nm_setting_gsm_get_apn(setting);
-    if (str)
-        g_hash_table_insert(properties, "AccessPointName", g_strdup(str));
-
-    str = nm_setting_gsm_get_username(setting);
-    if (str)
-        g_hash_table_insert(properties, "Username", g_strdup(str));
-
-    str = nm_setting_gsm_get_password(setting);
-    if (str)
-        g_hash_table_insert(properties, "Password", g_strdup(str));
-
-    return properties;
-}
-
-static NMActStageReturn
-modem_act_stage1_prepare(NMModem *            modem,
-                         NMConnection *       connection,
-                         NMDeviceStateReason *out_failure_reason)
-{
-    NMModemOfono *       self = NM_MODEM_OFONO(modem);
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-    const char *         context_id;
-    char **              id = NULL;
-
-    context_id = nm_connection_get_id(connection);
-    id         = g_strsplit(context_id, "/", 0);
-    g_return_val_if_fail(id[2], NM_ACT_STAGE_RETURN_FAILURE);
-
-    _LOGD("trying %s %s", id[1], id[2]);
-
-    g_free(priv->context_path);
-    priv->context_path = g_strdup_printf("%s/%s", nm_modem_get_path(modem), id[2]);
-    g_strfreev(id);
-
-    if (!priv->context_path) {
-        NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_GSM_APN_FAILED);
-        return NM_ACT_STAGE_RETURN_FAILURE;
-    }
-
-    if (priv->connect_properties)
-        g_hash_table_destroy(priv->connect_properties);
-
-    priv->connect_properties = create_connect_properties(connection);
-
-    _LOGI("activating context %s", priv->context_path);
-
-    if (nm_modem_get_state(modem) == NM_MODEM_STATE_REGISTERED) {
-        do_context_activate(self);
-    } else {
-        _LOGW("could not activate context: modem is not registered.");
-        NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER);
-        return NM_ACT_STAGE_RETURN_FAILURE;
-    }
-
-    return NM_ACT_STAGE_RETURN_POSTPONE;
-}
-
-static void
-modem_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMModemOfono *       self;
-    NMModemOfonoPrivate *priv;
-    gs_free_error GError *error = NULL;
-    GDBusProxy *          proxy;
-
-    proxy = g_dbus_proxy_new_for_bus_finish(result, &error);
-    if (!proxy && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-        return;
-
-    self = NM_MODEM_OFONO(user_data);
-    priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    if (!proxy) {
-        _LOGE("failed to create ofono modem DBus proxy: %s", error->message);
-        g_clear_object(&priv->modem_proxy_cancellable);
-        return;
-    }
-
-    priv->modem_proxy = proxy;
-
-    _nm_dbus_signal_connect(priv->modem_proxy,
-                            "PropertyChanged",
-                            G_VARIANT_TYPE("(sv)"),
-                            G_CALLBACK(modem_property_changed),
-                            self);
-
-    g_dbus_proxy_call(priv->modem_proxy,
-                      "GetProperties",
-                      NULL,
-                      G_DBUS_CALL_FLAGS_NONE,
-                      20000,
-                      priv->modem_proxy_cancellable,
-                      modem_get_properties_done,
-                      self);
-}
-
-/*****************************************************************************/
-
-static void
-nm_modem_ofono_init(NMModemOfono *self)
-{}
-
-static void
-constructed(GObject *object)
-{
-    NMModemOfono *       self = NM_MODEM_OFONO(object);
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    priv->modem_proxy_cancellable = g_cancellable_new();
-
-    g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
-                             G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
-                             NULL,
-                             OFONO_DBUS_SERVICE,
-                             nm_modem_get_path(NM_MODEM(self)),
-                             OFONO_DBUS_INTERFACE_MODEM,
-                             priv->modem_proxy_cancellable,
-                             modem_proxy_new_cb,
-                             self);
-
-    G_OBJECT_CLASS(nm_modem_ofono_parent_class)->constructed(object);
-}
-
-NMModem *
-nm_modem_ofono_new(const char *path)
-{
-    gs_free char *basename = NULL;
-
-    g_return_val_if_fail(path != NULL, NULL);
-
-    nm_log_info(LOGD_MB, "ofono: creating new Ofono modem path %s", path);
-
-    /* Use short modem name (not its object path) as the NM device name (which
-     * comes from NM_MODEM_UID)and the device ID.
-     */
-    basename = g_path_get_basename(path);
-
-    return (NMModem *) g_object_new(NM_TYPE_MODEM_OFONO,
-                                    NM_MODEM_PATH,
-                                    path,
-                                    NM_MODEM_UID,
-                                    basename,
-                                    NM_MODEM_DEVICE_ID,
-                                    basename,
-                                    NM_MODEM_CONTROL_PORT,
-                                    "ofono", /* mandatory */
-                                    NM_MODEM_DRIVER,
-                                    "ofono",
-                                    NM_MODEM_STATE,
-                                    (int) NM_MODEM_STATE_INITIALIZING,
-                                    NULL);
-}
-
-static void
-dispose(GObject *object)
-{
-    NMModemOfono *       self = NM_MODEM_OFONO(object);
-    NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self);
-
-    nm_clear_g_cancellable(&priv->modem_proxy_cancellable);
-    nm_clear_g_cancellable(&priv->connman_proxy_cancellable);
-    nm_clear_g_cancellable(&priv->context_proxy_cancellable);
-    nm_clear_g_cancellable(&priv->sim_proxy_cancellable);
-
-    if (priv->connect_properties) {
-        g_hash_table_destroy(priv->connect_properties);
-        priv->connect_properties = NULL;
-    }
-
-    g_clear_object(&priv->ip4_config);
-
-    if (priv->modem_proxy) {
-        g_signal_handlers_disconnect_by_data(priv->modem_proxy, self);
-        g_clear_object(&priv->modem_proxy);
-    }
-
-    if (priv->connman_proxy) {
-        g_signal_handlers_disconnect_by_data(priv->connman_proxy, self);
-        g_clear_object(&priv->connman_proxy);
-    }
-
-    if (priv->context_proxy) {
-        g_signal_handlers_disconnect_by_data(priv->context_proxy, self);
-        g_clear_object(&priv->context_proxy);
-    }
-
-    if (priv->sim_proxy) {
-        g_signal_handlers_disconnect_by_data(priv->sim_proxy, self);
-        g_clear_object(&priv->sim_proxy);
-    }
-
-    g_free(priv->imsi);
-    priv->imsi = NULL;
-
-    G_OBJECT_CLASS(nm_modem_ofono_parent_class)->dispose(object);
-}
-
-static void
-nm_modem_ofono_class_init(NMModemOfonoClass *klass)
-{
-    GObjectClass *object_class = G_OBJECT_CLASS(klass);
-    NMModemClass *modem_class  = NM_MODEM_CLASS(klass);
-
-    object_class->constructed = constructed;
-    object_class->dispose     = dispose;
-
-    modem_class->get_capabilities                       = get_capabilities;
-    modem_class->disconnect                             = disconnect;
-    modem_class->deactivate_cleanup                     = deactivate_cleanup;
-    modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem;
-
-    modem_class->modem_act_stage1_prepare       = modem_act_stage1_prepare;
-    modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start;
-}
diff --git a/src/devices/wwan/nm-modem-ofono.h b/src/devices/wwan/nm-modem-ofono.h
deleted file mode 100644
index 10b4a385..00000000
--- a/src/devices/wwan/nm-modem-ofono.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2013 - Canonical Ltd.
- */
-
-#ifndef NM_MODEM_OFONO_H
-#define NM_MODEM_OFONO_H
-
-#include "nm-modem.h"
-
-#define NM_TYPE_MODEM_OFONO    (nm_modem_ofono_get_type())
-#define NM_MODEM_OFONO(obj)    (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MODEM_OFONO, NMModemOfono))
-#define NM_IS_MODEM_OFONO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_MODEM_OFONO))
-#define NM_MODEM_OFONO_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_MODEM_OFONO, NMModemOfonoClass))
-#define NM_IS_MODEM_OFONO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_MODEM_OFONO))
-#define NM_MODEM_OFONO_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_MODEM_OFONO, NMModemOfonoClass))
-
-#define OFONO_DBUS_SERVICE                      "org.ofono"
-#define OFONO_DBUS_PATH                         "/"
-#define OFONO_DBUS_INTERFACE                    "org.ofono.Manager"
-#define OFONO_DBUS_INTERFACE_MODEM              "org.ofono.Modem"
-#define OFONO_DBUS_INTERFACE_CONNECTION_MANAGER "org.ofono.ConnectionManager"
-#define OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT "org.ofono.ConnectionContext"
-#define OFONO_DBUS_INTERFACE_SIM_MANAGER        "org.ofono.SimManager"
-
-typedef struct _NMModemOfono      NMModemOfono;
-typedef struct _NMModemOfonoClass NMModemOfonoClass;
-
-GType nm_modem_ofono_get_type(void);
-
-NMModem *nm_modem_ofono_new(const char *path);
-
-#endif /* NM_MODEM_OFONO_H */
diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c
deleted file mode 100644
index 9e16420e..00000000
--- a/src/devices/wwan/nm-modem.c
+++ /dev/null
@@ -1,2037 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2009 - 2014 Red Hat, Inc.
- * Copyright (C) 2009 Novell, Inc.
- */
-
-#include "nm-default.h"
-
-#include "nm-modem.h"
-
-#include <fcntl.h>
-#include <termios.h>
-#include <linux/rtnetlink.h>
-
-#include "nm-core-internal.h"
-#include "platform/nm-platform.h"
-#include "nm-setting-connection.h"
-#include "NetworkManagerUtils.h"
-#include "devices/nm-device-private.h"
-#include "nm-netns.h"
-#include "nm-act-request.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
-#include "ppp/nm-ppp-manager-call.h"
-#include "ppp/nm-ppp-status.h"
-
-/*****************************************************************************/
-
-NM_GOBJECT_PROPERTIES_DEFINE(NMModem,
-                             PROP_CONTROL_PORT,
-                             PROP_IP_IFINDEX,
-                             PROP_PATH,
-                             PROP_UID,
-                             PROP_DRIVER,
-                             PROP_STATE,
-                             PROP_DEVICE_ID,
-                             PROP_SIM_ID,
-                             PROP_IP_TYPES,
-                             PROP_SIM_OPERATOR_ID,
-                             PROP_OPERATOR_CODE,
-                             PROP_APN, );
-
-enum {
-    PPP_STATS,
-    PPP_FAILED,
-    PREPARE_RESULT,
-    IP4_CONFIG_RESULT,
-    IP6_CONFIG_RESULT,
-    AUTH_REQUESTED,
-    AUTH_RESULT,
-    REMOVED,
-    STATE_CHANGED,
-    LAST_SIGNAL,
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-typedef struct _NMModemPrivate {
-    char *uid;
-    char *path;
-    char *driver;
-    char *control_port;
-    char *data_port;
-
-    /* TODO: ip_iface is solely used for nm_modem_owns_port().
-     * We should rework the code that it's not necessary */
-    char *ip_iface;
-
-    int                ip_ifindex;
-    NMModemIPMethod    ip4_method;
-    NMModemIPMethod    ip6_method;
-    NMUtilsIPv6IfaceId iid;
-    NMModemState       state;
-    NMModemState       prev_state; /* revert to this state if enable/disable fails */
-    char *             device_id;
-    char *             sim_id;
-    NMModemIPType      ip_types;
-    char *             sim_operator_id;
-    char *             operator_code;
-    char *             apn;
-
-    NMPPPManager *ppp_manager;
-
-    NMActRequest *                act_request;
-    guint32                       secrets_tries;
-    NMActRequestGetSecretsCallId *secrets_id;
-
-    guint mm_ip_timeout;
-
-    guint32 ip4_route_table;
-    guint32 ip4_route_metric;
-    guint32 ip6_route_table;
-    guint32 ip6_route_metric;
-
-    /* PPP stats */
-    guint32 in_bytes;
-    guint32 out_bytes;
-
-    bool claimed : 1;
-} NMModemPrivate;
-
-G_DEFINE_TYPE(NMModem, nm_modem, G_TYPE_OBJECT)
-
-#define NM_MODEM_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMModem, NM_IS_MODEM)
-
-/*****************************************************************************/
-
-#define _NMLOG_PREFIX_BUFLEN 64
-#define _NMLOG_PREFIX_NAME   "modem"
-#define _NMLOG_DOMAIN        LOGD_MB
-
-static const char *
-_nmlog_prefix(char *prefix, NMModem *self)
-{
-    const char *uuid;
-    int         c;
-
-    if (!self)
-        return "";
-
-    uuid = nm_modem_get_uid(self);
-
-    if (uuid) {
-        char pp[_NMLOG_PREFIX_BUFLEN - 5];
-
-        c = g_snprintf(prefix, _NMLOG_PREFIX_BUFLEN, "[%s]", nm_strquote(pp, sizeof(pp), uuid));
-    } else
-        c = g_snprintf(prefix, _NMLOG_PREFIX_BUFLEN, "[%p]", self);
-    nm_assert(c < _NMLOG_PREFIX_BUFLEN);
-
-    return prefix;
-}
-
-#define _NMLOG(level, ...)                                                        \
-    G_STMT_START                                                                  \
-    {                                                                             \
-        char _prefix[_NMLOG_PREFIX_BUFLEN];                                       \
-                                                                                  \
-        nm_log((level),                                                           \
-               _NMLOG_DOMAIN,                                                     \
-               NULL,                                                              \
-               NULL,                                                              \
-               "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__),                       \
-               _NMLOG_PREFIX_NAME,                                                \
-               _nmlog_prefix(_prefix, (self)) _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
-    }                                                                             \
-    G_STMT_END
-
-/*****************************************************************************/
-
-static void _set_ip_ifindex(NMModem *self, int ifindex, const char *ifname);
-
-/*****************************************************************************/
-/* State/enabled/connected */
-
-static const char *state_table[] = {
-    [NM_MODEM_STATE_UNKNOWN]       = "unknown",
-    [NM_MODEM_STATE_FAILED]        = "failed",
-    [NM_MODEM_STATE_INITIALIZING]  = "initializing",
-    [NM_MODEM_STATE_LOCKED]        = "locked",
-    [NM_MODEM_STATE_DISABLED]      = "disabled",
-    [NM_MODEM_STATE_DISABLING]     = "disabling",
-    [NM_MODEM_STATE_ENABLING]      = "enabling",
-    [NM_MODEM_STATE_ENABLED]       = "enabled",
-    [NM_MODEM_STATE_SEARCHING]     = "searching",
-    [NM_MODEM_STATE_REGISTERED]    = "registered",
-    [NM_MODEM_STATE_DISCONNECTING] = "disconnecting",
-    [NM_MODEM_STATE_CONNECTING]    = "connecting",
-    [NM_MODEM_STATE_CONNECTED]     = "connected",
-};
-
-const char *
-nm_modem_state_to_string(NMModemState state)
-{
-    if ((gsize) state < G_N_ELEMENTS(state_table))
-        return state_table[state];
-    return NULL;
-}
-
-/*****************************************************************************/
-
-gboolean
-nm_modem_is_claimed(NMModem *self)
-{
-    g_return_val_if_fail(NM_IS_MODEM(self), FALSE);
-
-    return NM_MODEM_GET_PRIVATE(self)->claimed;
-}
-
-NMModem *
-nm_modem_claim(NMModem *self)
-{
-    NMModemPrivate *priv;
-
-    g_return_val_if_fail(NM_IS_MODEM(self), NULL);
-
-    priv = NM_MODEM_GET_PRIVATE(self);
-
-    g_return_val_if_fail(!priv->claimed, NULL);
-
-    priv->claimed = TRUE;
-    return g_object_ref(self);
-}
-
-void
-nm_modem_unclaim(NMModem *self)
-{
-    NMModemPrivate *priv;
-
-    g_return_if_fail(NM_IS_MODEM(self));
-
-    priv = NM_MODEM_GET_PRIVATE(self);
-
-    g_return_if_fail(priv->claimed);
-
-    /* we don't actually unclaim the instance. This instance should not be re-used
-     * by another owner, that is because we only claim modems as we receive them.
-     * There is no mechanism that somebody else would later re-use them again.
-     *
-     * // priv->claimed = FALSE; */
-
-    g_object_unref(self);
-}
-
-/*****************************************************************************/
-
-NMModemState
-nm_modem_get_state(NMModem *self)
-{
-    return NM_MODEM_GET_PRIVATE(self)->state;
-}
-
-void
-nm_modem_set_state(NMModem *self, NMModemState new_state, const char *reason)
-{
-    NMModemPrivate *priv      = NM_MODEM_GET_PRIVATE(self);
-    NMModemState    old_state = priv->state;
-
-    priv->prev_state = NM_MODEM_STATE_UNKNOWN;
-
-    if (new_state != old_state) {
-        _LOGI("modem state changed, '%s' --> '%s' (reason: %s)",
-              nm_modem_state_to_string(old_state),
-              nm_modem_state_to_string(new_state),
-              reason ?: "none");
-
-        priv->state = new_state;
-        _notify(self, PROP_STATE);
-        g_signal_emit(self, signals[STATE_CHANGED], 0, (int) new_state, (int) old_state);
-    }
-}
-
-void
-nm_modem_set_prev_state(NMModem *self, const char *reason)
-{
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self);
-
-    /* Reset modem to previous state if the state hasn't already changed */
-    if (priv->prev_state != NM_MODEM_STATE_UNKNOWN)
-        nm_modem_set_state(self, priv->prev_state, reason);
-}
-
-void
-nm_modem_set_mm_enabled(NMModem *self, gboolean enabled)
-{
-    NMModemPrivate *priv       = NM_MODEM_GET_PRIVATE(self);
-    NMModemState    prev_state = priv->state;
-
-    if (enabled && priv->state >= NM_MODEM_STATE_ENABLING) {
-        _LOGD("cannot enable modem: already enabled");
-        return;
-    }
-    if (!enabled && priv->state <= NM_MODEM_STATE_DISABLING) {
-        _LOGD("cannot disable modem: already disabled");
-        return;
-    }
-
-    if (priv->state <= NM_MODEM_STATE_INITIALIZING) {
-        _LOGD("cannot enable/disable modem: initializing or failed");
-        return;
-    } else if (priv->state == NM_MODEM_STATE_LOCKED) {
-        /* Don't try to enable if the modem is locked since that will fail */
-        _LOGW("cannot enable/disable modem: locked");
-
-        /* Try to unlock the modem if it's being enabled */
-        if (enabled)
-            g_signal_emit(self, signals[AUTH_REQUESTED], 0);
-        return;
-    }
-
-    /* Not all modem classes support set_mm_enabled */
-    if (NM_MODEM_GET_CLASS(self)->set_mm_enabled)
-        NM_MODEM_GET_CLASS(self)->set_mm_enabled(self, enabled);
-
-    /* Pre-empt the state change signal */
-    nm_modem_set_state(self,
-                       enabled ? NM_MODEM_STATE_ENABLING : NM_MODEM_STATE_DISABLING,
-                       "user preference");
-    priv->prev_state = prev_state;
-}
-
-void
-nm_modem_emit_removed(NMModem *self)
-{
-    g_signal_emit(self, signals[REMOVED], 0);
-}
-
-void
-nm_modem_emit_prepare_result(NMModem *self, gboolean success, NMDeviceStateReason reason)
-{
-    nm_assert(NM_IS_MODEM(self));
-
-    g_signal_emit(self, signals[PREPARE_RESULT], 0, success, (guint) reason);
-}
-
-void
-nm_modem_emit_ppp_failed(NMModem *self, NMDeviceStateReason reason)
-{
-    nm_assert(NM_IS_MODEM(self));
-
-    g_signal_emit(self, signals[PPP_FAILED], 0, (guint) reason);
-}
-
-NMModemIPType
-nm_modem_get_supported_ip_types(NMModem *self)
-{
-    return NM_MODEM_GET_PRIVATE(self)->ip_types;
-}
-
-const char *
-nm_modem_ip_type_to_string(NMModemIPType ip_type)
-{
-    switch (ip_type) {
-    case NM_MODEM_IP_TYPE_IPV4:
-        return "ipv4";
-    case NM_MODEM_IP_TYPE_IPV6:
-        return "ipv6";
-    case NM_MODEM_IP_TYPE_IPV4V6:
-        return "ipv4v6";
-    default:
-        g_return_val_if_reached("unknown");
-    }
-}
-
-static GArray *
-build_single_ip_type_array(NMModemIPType type)
-{
-    return g_array_append_val(g_array_sized_new(FALSE, FALSE, sizeof(NMModemIPType), 1), type);
-}
-
-/**
- * nm_modem_get_connection_ip_type:
- * @self: the #NMModem
- * @connection: the #NMConnection to determine IP type to use
- *
- * Given a modem and a connection, determine which #NMModemIPTypes to use
- * when connecting.
- *
- * Returns: an array of #NMModemIpType values, in the order in which they
- * should be tried.
- */
-GArray *
-nm_modem_get_connection_ip_type(NMModem *self, NMConnection *connection, GError **error)
-{
-    NMModemPrivate *   priv = NM_MODEM_GET_PRIVATE(self);
-    NMSettingIPConfig *s_ip4, *s_ip6;
-    const char *       method;
-    gboolean           ip4 = TRUE, ip6 = TRUE;
-    gboolean           ip4_may_fail = TRUE, ip6_may_fail = TRUE;
-
-    s_ip4 = nm_connection_get_setting_ip4_config(connection);
-    if (s_ip4) {
-        method = nm_setting_ip_config_get_method(s_ip4);
-        if (g_strcmp0(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0)
-            ip4 = FALSE;
-        ip4_may_fail = nm_setting_ip_config_get_may_fail(s_ip4);
-    }
-
-    s_ip6 = nm_connection_get_setting_ip6_config(connection);
-    if (s_ip6) {
-        method = nm_setting_ip_config_get_method(s_ip6);
-        if (NM_IN_STRSET(method,
-                         NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
-                         NM_SETTING_IP6_CONFIG_METHOD_DISABLED))
-            ip6 = FALSE;
-        ip6_may_fail = nm_setting_ip_config_get_may_fail(s_ip6);
-    }
-
-    if (ip4 && !ip6) {
-        if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV4)) {
-            g_set_error_literal(error,
-                                NM_DEVICE_ERROR,
-                                NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
-                                "Connection requested IPv4 but IPv4 is "
-                                "unsupported by the modem.");
-            return NULL;
-        }
-        return build_single_ip_type_array(NM_MODEM_IP_TYPE_IPV4);
-    }
-
-    if (ip6 && !ip4) {
-        if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV6)) {
-            g_set_error_literal(error,
-                                NM_DEVICE_ERROR,
-                                NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
-                                "Connection requested IPv6 but IPv6 is "
-                                "unsupported by the modem.");
-            return NULL;
-        }
-        return build_single_ip_type_array(NM_MODEM_IP_TYPE_IPV6);
-    }
-
-    if (ip4 && ip6) {
-        NMModemIPType type;
-        GArray *      out;
-
-        out = g_array_sized_new(FALSE, FALSE, sizeof(NMModemIPType), 3);
-
-        /* Modem supports dual-stack? */
-        if (priv->ip_types & NM_MODEM_IP_TYPE_IPV4V6) {
-            type = NM_MODEM_IP_TYPE_IPV4V6;
-            g_array_append_val(out, type);
-        }
-
-        /* If IPv6 may-fail=false, we should NOT try IPv4 as fallback */
-        if ((priv->ip_types & NM_MODEM_IP_TYPE_IPV4) && ip6_may_fail) {
-            type = NM_MODEM_IP_TYPE_IPV4;
-            g_array_append_val(out, type);
-        }
-
-        /* If IPv4 may-fail=false, we should NOT try IPv6 as fallback */
-        if ((priv->ip_types & NM_MODEM_IP_TYPE_IPV6) && ip4_may_fail) {
-            type = NM_MODEM_IP_TYPE_IPV6;
-            g_array_append_val(out, type);
-        }
-
-        if (out->len > 0)
-            return out;
-
-        /* Error... */
-        g_array_unref(out);
-        g_set_error_literal(error,
-                            NM_DEVICE_ERROR,
-                            NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
-                            "Connection requested both IPv4 and IPv6 "
-                            "but dual-stack addressing is unsupported "
-                            "by the modem.");
-        return NULL;
-    }
-
-    g_set_error_literal(error,
-                        NM_DEVICE_ERROR,
-                        NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
-                        "Connection specified no IP configuration!");
-    return NULL;
-}
-
-const char *
-nm_modem_get_device_id(NMModem *self)
-{
-    return NM_MODEM_GET_PRIVATE(self)->device_id;
-}
-
-const char *
-nm_modem_get_sim_id(NMModem *self)
-{
-    return NM_MODEM_GET_PRIVATE(self)->sim_id;
-}
-
-const char *
-nm_modem_get_sim_operator_id(NMModem *self)
-{
-    return NM_MODEM_GET_PRIVATE(self)->sim_operator_id;
-}
-
-const char *
-nm_modem_get_operator_code(NMModem *self)
-{
-    return NM_MODEM_GET_PRIVATE(self)->operator_code;
-}
-
-const char *
-nm_modem_get_apn(NMModem *self)
-{
-    return NM_MODEM_GET_PRIVATE(self)->apn;
-}
-
-/*****************************************************************************/
-/* IP method PPP */
-
-static void
-ppp_state_changed(NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data)
-{
-    switch (status) {
-    case NM_PPP_STATUS_DISCONNECT:
-        nm_modem_emit_ppp_failed(user_data, NM_DEVICE_STATE_REASON_PPP_DISCONNECT);
-        break;
-    case NM_PPP_STATUS_DEAD:
-        nm_modem_emit_ppp_failed(user_data, NM_DEVICE_STATE_REASON_PPP_FAILED);
-        break;
-    default:
-        break;
-    }
-}
-
-static void
-ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpointer user_data)
-{
-    NMModem *self = NM_MODEM(user_data);
-
-    nm_assert(ifindex >= 0);
-    nm_assert(NM_MODEM_GET_PRIVATE(self)->ppp_manager == ppp_manager);
-
-    if (ifindex <= 0 && iface) {
-        /* this might happen, if the ifname was already deleted
-         * and we failed to resolve ifindex.
-         *
-         * Forget about the name. */
-        iface = NULL;
-    }
-    _set_ip_ifindex(self, ifindex, iface);
-}
-
-static void
-ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data)
-{
-    NMModem *self = NM_MODEM(user_data);
-    guint32  i, num;
-    guint32  bad_dns1       = htonl(0x0A0B0C0D);
-    guint32  good_dns1      = htonl(0x04020201); /* GTE nameserver */
-    guint32  bad_dns2       = htonl(0x0A0B0C0E);
-    guint32  good_dns2      = htonl(0x04020202); /* GTE nameserver */
-    gboolean dns_workaround = FALSE;
-
-    /* Work around a PPP bug (#1732) which causes many mobile broadband
-     * providers to return 10.11.12.13 and 10.11.12.14 for the DNS servers.
-     * Apparently fixed in ppp-2.4.5 but we've had some reports that this is
-     * not the case.
-     *
-     * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=2e09ef6886bbf00bc5a9a641110f801e372ffde6
-     * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=f8191bf07df374f119a07910a79217c7618f113e
-     */
-
-    num = nm_ip4_config_get_num_nameservers(config);
-    if (num == 2) {
-        gboolean found1 = FALSE, found2 = FALSE;
-
-        for (i = 0; i < num; i++) {
-            guint32 ns = nm_ip4_config_get_nameserver(config, i);
-
-            if (ns == bad_dns1)
-                found1 = TRUE;
-            else if (ns == bad_dns2)
-                found2 = TRUE;
-        }
-
-        /* Be somewhat conservative about substitutions; the "bad" nameservers
-         * could actually be valid in some cases, so only substitute if ppp
-         * returns *only* the two bad nameservers.
-         */
-        dns_workaround = (found1 && found2);
-    }
-
-    if (!num || dns_workaround) {
-        _LOGW("compensating for invalid PPP-provided nameservers");
-        nm_ip4_config_reset_nameservers(config);
-        nm_ip4_config_add_nameserver(config, good_dns1);
-        nm_ip4_config_add_nameserver(config, good_dns2);
-    }
-
-    g_signal_emit(self, signals[IP4_CONFIG_RESULT], 0, config, NULL);
-}
-
-static void
-ppp_ip6_config(NMPPPManager *            ppp_manager,
-               const NMUtilsIPv6IfaceId *iid,
-               NMIP6Config *             config,
-               gpointer                  user_data)
-{
-    NMModem *self = NM_MODEM(user_data);
-
-    NM_MODEM_GET_PRIVATE(self)->iid = *iid;
-
-    nm_modem_emit_ip6_config_result(self, config, NULL);
-}
-
-static void
-ppp_stats(NMPPPManager *ppp_manager, guint i_in_bytes, guint i_out_bytes, gpointer user_data)
-{
-    NMModem *       self      = NM_MODEM(user_data);
-    NMModemPrivate *priv      = NM_MODEM_GET_PRIVATE(self);
-    guint32         in_bytes  = i_in_bytes;
-    guint32         out_bytes = i_out_bytes;
-
-    if (priv->in_bytes != in_bytes || priv->out_bytes != out_bytes) {
-        priv->in_bytes  = in_bytes;
-        priv->out_bytes = out_bytes;
-        g_signal_emit(self, signals[PPP_STATS], 0, (guint) in_bytes, (guint) out_bytes);
-    }
-}
-
-static gboolean
-port_speed_is_zero(const char *port)
-{
-    struct termios    options;
-    nm_auto_close int fd   = -1;
-    gs_free char *    path = NULL;
-
-    nm_assert(port);
-
-    if (port[0] != '/') {
-        if (!port[0] || strchr(port, '/') || NM_IN_STRSET(port, ".", ".."))
-            return FALSE;
-        path = g_build_path("/sys/class/tty", port, NULL);
-        port = path;
-    }
-
-    fd = open(port, O_RDWR | O_NONBLOCK | O_NOCTTY | O_CLOEXEC);
-    if (fd < 0)
-        return FALSE;
-
-    memset(&options, 0, sizeof(struct termios));
-    if (tcgetattr(fd, &options) != 0)
-        return FALSE;
-
-    return cfgetospeed(&options) == B0;
-}
-
-static NMActStageReturn
-ppp_stage3_ip_config_start(NMModem *            self,
-                           NMActRequest *       req,
-                           NMDeviceStateReason *out_failure_reason)
-{
-    NMModemPrivate *priv          = NM_MODEM_GET_PRIVATE(self);
-    const char *    ppp_name      = NULL;
-    GError *        error         = NULL;
-    guint           ip_timeout    = 30;
-    guint           baud_override = 0;
-
-    g_return_val_if_fail(NM_IS_MODEM(self), NM_ACT_STAGE_RETURN_FAILURE);
-    g_return_val_if_fail(NM_IS_ACT_REQUEST(req), NM_ACT_STAGE_RETURN_FAILURE);
-
-    /* If we're already running PPP don't restart it; for example, if both
-     * IPv4 and IPv6 are requested, IPv4 gets started first, but we use the
-     * same pppd for both v4 and v6.
-     */
-    if (priv->ppp_manager)
-        return NM_ACT_STAGE_RETURN_POSTPONE;
-
-    if (NM_MODEM_GET_CLASS(self)->get_user_pass) {
-        NMConnection *connection = nm_act_request_get_applied_connection(req);
-
-        g_assert(connection);
-        if (!NM_MODEM_GET_CLASS(self)->get_user_pass(self, connection, &ppp_name, NULL))
-            return NM_ACT_STAGE_RETURN_FAILURE;
-    }
-
-    if (!priv->data_port) {
-        _LOGE("error starting PPP (no data port)");
-        NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED);
-        return NM_ACT_STAGE_RETURN_FAILURE;
-    }
-
-    /* Check if ModemManager requested a specific IP timeout to be used. If 0 reported,
-     * use the default one (30s) */
-    if (priv->mm_ip_timeout > 0) {
-        _LOGI("using modem-specified IP timeout: %u seconds", priv->mm_ip_timeout);
-        ip_timeout = priv->mm_ip_timeout;
-    }
-
-    /* Some tty drivers and modems ignore port speed, but pppd requires the
-     * port speed to be > 0 or it exits. If the port speed is 0 pass an
-     * explicit speed to pppd to prevent the exit.
-     * https://bugzilla.redhat.com/show_bug.cgi?id=1281731
-     */
-    if (port_speed_is_zero(priv->data_port))
-        baud_override = 57600;
-
-    priv->ppp_manager = nm_ppp_manager_create(priv->data_port, &error);
-
-    if (priv->ppp_manager) {
-        nm_ppp_manager_set_route_parameters(priv->ppp_manager,
-                                            priv->ip4_route_table,
-                                            priv->ip4_route_metric,
-                                            priv->ip6_route_table,
-                                            priv->ip6_route_metric);
-    }
-
-    if (!priv->ppp_manager
-        || !nm_ppp_manager_start(priv->ppp_manager,
-                                 req,
-                                 ppp_name,
-                                 ip_timeout,
-                                 baud_override,
-                                 &error)) {
-        _LOGE("error starting PPP: %s", error->message);
-        g_error_free(error);
-        g_clear_object(&priv->ppp_manager);
-        NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED);
-        return NM_ACT_STAGE_RETURN_FAILURE;
-    }
-
-    g_signal_connect(priv->ppp_manager,
-                     NM_PPP_MANAGER_SIGNAL_STATE_CHANGED,
-                     G_CALLBACK(ppp_state_changed),
-                     self);
-    g_signal_connect(priv->ppp_manager,
-                     NM_PPP_MANAGER_SIGNAL_IFINDEX_SET,
-                     G_CALLBACK(ppp_ifindex_set),
-                     self);
-    g_signal_connect(priv->ppp_manager,
-                     NM_PPP_MANAGER_SIGNAL_IP4_CONFIG,
-                     G_CALLBACK(ppp_ip4_config),
-                     self);
-    g_signal_connect(priv->ppp_manager,
-                     NM_PPP_MANAGER_SIGNAL_IP6_CONFIG,
-                     G_CALLBACK(ppp_ip6_config),
-                     self);
-    g_signal_connect(priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_STATS, G_CALLBACK(ppp_stats), self);
-
-    return NM_ACT_STAGE_RETURN_POSTPONE;
-}
-
-/*****************************************************************************/
-
-NMActStageReturn
-nm_modem_stage3_ip4_config_start(NMModem *            self,
-                                 NMDevice *           device,
-                                 NMDeviceClass *      device_class,
-                                 NMDeviceStateReason *out_failure_reason)
-{
-    NMModemPrivate * priv;
-    NMActRequest *   req;
-    NMConnection *   connection;
-    const char *     method;
-    NMActStageReturn ret;
-
-    _LOGD("ip4_config_start");
-
-    g_return_val_if_fail(NM_IS_MODEM(self), NM_ACT_STAGE_RETURN_FAILURE);
-    g_return_val_if_fail(NM_IS_DEVICE(device), NM_ACT_STAGE_RETURN_FAILURE);
-    g_return_val_if_fail(NM_IS_DEVICE_CLASS(device_class), NM_ACT_STAGE_RETURN_FAILURE);
-
-    req = nm_device_get_act_request(device);
-    g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE);
-
-    connection = nm_act_request_get_applied_connection(req);
-    g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
-
-    nm_modem_set_route_parameters_from_device(self, device);
-
-    method = nm_utils_get_ip_config_method(connection, AF_INET);
-
-    /* Only Disabled and Auto methods make sense for WWAN */
-    if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED))
-        return NM_ACT_STAGE_RETURN_SUCCESS;
-
-    if (!nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
-        _LOGE("unhandled WWAN IPv4 method '%s'; will fail", method);
-        NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED);
-        return NM_ACT_STAGE_RETURN_FAILURE;
-    }
-
-    priv = NM_MODEM_GET_PRIVATE(self);
-    switch (priv->ip4_method) {
-    case NM_MODEM_IP_METHOD_PPP:
-        ret = ppp_stage3_ip_config_start(self, req, out_failure_reason);
-        break;
-    case NM_MODEM_IP_METHOD_STATIC:
-        _LOGD("MODEM_IP_METHOD_STATIC");
-        ret =
-            NM_MODEM_GET_CLASS(self)->static_stage3_ip4_config_start(self, req, out_failure_reason);
-        break;
-    case NM_MODEM_IP_METHOD_AUTO:
-        _LOGD("MODEM_IP_METHOD_AUTO");
-        ret = device_class->act_stage3_ip_config_start(device, AF_INET, NULL, out_failure_reason);
-        break;
-    default:
-        _LOGI("IPv4 configuration disabled");
-        ret = NM_ACT_STAGE_RETURN_IP_FAIL;
-        break;
-    }
-
-    return ret;
-}
-
-void
-nm_modem_ip4_pre_commit(NMModem *modem, NMDevice *device, NMIP4Config *config)
-{
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(modem);
-
-    /* If the modem has an ethernet-type data interface (ie, not PPP and thus
-     * not point-to-point) and IP config has a /32 prefix, then we assume that
-     * ARP will be pointless and we turn it off.
-     */
-    if (priv->ip4_method == NM_MODEM_IP_METHOD_STATIC
-        || priv->ip4_method == NM_MODEM_IP_METHOD_AUTO) {
-        const NMPlatformIP4Address *address = nm_ip4_config_get_first_address(config);
-
-        g_assert(address);
-        if (address->plen == 32)
-            nm_platform_link_set_noarp(nm_device_get_platform(device),
-                                       nm_device_get_ip_ifindex(device));
-    }
-}
-
-/*****************************************************************************/
-
-void
-nm_modem_emit_ip6_config_result(NMModem *self, NMIP6Config *config, GError *error)
-{
-    NMModemPrivate *            priv = NM_MODEM_GET_PRIVATE(self);
-    NMDedupMultiIter            ipconf_iter;
-    const NMPlatformIP6Address *addr;
-    gboolean                    do_slaac = TRUE;
-
-    if (error) {
-        g_signal_emit(self, signals[IP6_CONFIG_RESULT], 0, NULL, FALSE, error);
-        return;
-    }
-
-    if (config) {
-        /* If the IPv6 configuration only included a Link-Local address, then
-         * we have to run SLAAC to get the full IPv6 configuration.
-         */
-        nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, config, &addr) {
-            if (IN6_IS_ADDR_LINKLOCAL(&addr->address)) {
-                if (!priv->iid.id)
-                    priv->iid.id = ((guint64 *) (&addr->address.s6_addr))[1];
-            } else
-                do_slaac = FALSE;
-        }
-    }
-    g_assert(config || do_slaac);
-
-    g_signal_emit(self, signals[IP6_CONFIG_RESULT], 0, config, do_slaac, NULL);
-}
-
-static NMActStageReturn
-stage3_ip6_config_request(NMModem *self, NMDeviceStateReason *out_failure_reason)
-{
-    NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
-    return NM_ACT_STAGE_RETURN_FAILURE;
-}
-
-NMActStageReturn
-nm_modem_stage3_ip6_config_start(NMModem *            self,
-                                 NMDevice *           device,
-                                 NMDeviceStateReason *out_failure_reason)
-{
-    NMModemPrivate * priv;
-    NMActRequest *   req;
-    NMActStageReturn ret;
-    NMConnection *   connection;
-    const char *     method;
-
-    g_return_val_if_fail(NM_IS_MODEM(self), NM_ACT_STAGE_RETURN_FAILURE);
-
-    req = nm_device_get_act_request(device);
-    g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE);
-
-    connection = nm_act_request_get_applied_connection(req);
-    g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
-
-    nm_modem_set_route_parameters_from_device(self, device);
-
-    method = nm_utils_get_ip_config_method(connection, AF_INET6);
-
-    /* Only Ignore, Disabled and Auto methods make sense for WWAN */
-    if (NM_IN_STRSET(method,
-                     NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
-                     NM_SETTING_IP6_CONFIG_METHOD_DISABLED))
-        return NM_ACT_STAGE_RETURN_IP_DONE;
-
-    if (!nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
-        _LOGW("unhandled WWAN IPv6 method '%s'; will fail", method);
-        NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
-        return NM_ACT_STAGE_RETURN_FAILURE;
-    }
-
-    priv = NM_MODEM_GET_PRIVATE(self);
-    switch (priv->ip6_method) {
-    case NM_MODEM_IP_METHOD_PPP:
-        ret = ppp_stage3_ip_config_start(self, req, out_failure_reason);
-        break;
-    case NM_MODEM_IP_METHOD_STATIC:
-    case NM_MODEM_IP_METHOD_AUTO:
-        /* Both static and DHCP/Auto retrieve a base IP config from the modem
-         * which in the static case is the full config, and the DHCP/Auto case
-         * is just the IPv6LL address to use for SLAAC.
-         */
-        ret = NM_MODEM_GET_CLASS(self)->stage3_ip6_config_request(self, out_failure_reason);
-        break;
-    default:
-        _LOGI("IPv6 configuration disabled");
-        ret = NM_ACT_STAGE_RETURN_IP_FAIL;
-        break;
-    }
-
-    return ret;
-}
-
-guint32
-nm_modem_get_configured_mtu(NMDevice *self, NMDeviceMtuSource *out_source, gboolean *out_force)
-{
-    NMConnection *connection;
-    NMSetting *   setting;
-    gint64        mtu_default;
-    guint         mtu = 0;
-    const char *  property_name;
-
-    nm_assert(NM_IS_DEVICE(self));
-    nm_assert(out_source);
-
-    connection = nm_device_get_applied_connection(self);
-    if (!connection)
-        g_return_val_if_reached(0);
-
-    setting = (NMSetting *) nm_connection_get_setting_gsm(connection);
-    if (!setting)
-        setting = (NMSetting *) nm_connection_get_setting_cdma(connection);
-
-    if (setting) {
-        g_object_get(setting, "mtu", &mtu, NULL);
-        if (mtu) {
-            *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION;
-            return mtu;
-        }
-
-        property_name = NM_IS_SETTING_GSM(setting) ? "gsm.mtu" : "cdma.mtu";
-        mtu_default =
-            nm_device_get_configured_mtu_from_connection_default(self, property_name, G_MAXUINT32);
-        if (mtu_default >= 0) {
-            *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION;
-            return (guint32) mtu_default;
-        }
-    }
-
-    *out_source = NM_DEVICE_MTU_SOURCE_NONE;
-    return 0;
-}
-
-/*****************************************************************************/
-
-static void
-cancel_get_secrets(NMModem *self)
-{
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self);
-
-    if (priv->secrets_id)
-        nm_act_request_cancel_secrets(priv->act_request, priv->secrets_id);
-}
-
-static void
-modem_secrets_cb(NMActRequest *                req,
-                 NMActRequestGetSecretsCallId *call_id,
-                 NMSettingsConnection *        connection,
-                 GError *                      error,
-                 gpointer                      user_data)
-{
-    NMModem *       self = NM_MODEM(user_data);
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self);
-
-    g_return_if_fail(call_id == priv->secrets_id);
-
-    priv->secrets_id = NULL;
-
-    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)
-        || g_error_matches(error, NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_NO_SECRETS))
-        return;
-
-    if (error)
-        _LOGW("modem-secrets: %s", error->message);
-
-    g_signal_emit(self, signals[AUTH_RESULT], 0, error);
-}
-
-void
-nm_modem_get_secrets(NMModem *   self,
-                     const char *setting_name,
-                     gboolean    request_new,
-                     const char *hint)
-{
-    NMModemPrivate *             priv  = NM_MODEM_GET_PRIVATE(self);
-    NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
-
-    cancel_get_secrets(self);
-
-    if (request_new)
-        flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
-    priv->secrets_id = nm_act_request_get_secrets(priv->act_request,
-                                                  FALSE,
-                                                  setting_name,
-                                                  flags,
-                                                  NM_MAKE_STRV(hint),
-                                                  modem_secrets_cb,
-                                                  self);
-    g_return_if_fail(priv->secrets_id);
-    g_signal_emit(self, signals[AUTH_REQUESTED], 0);
-}
-
-/*****************************************************************************/
-
-static NMActStageReturn
-modem_act_stage1_prepare(NMModem *            modem,
-                         NMConnection *       connection,
-                         NMDeviceStateReason *out_failure_reason)
-{
-    NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_UNKNOWN);
-    return NM_ACT_STAGE_RETURN_FAILURE;
-}
-
-NMActStageReturn
-nm_modem_act_stage1_prepare(NMModem *            self,
-                            NMActRequest *       req,
-                            NMDeviceStateReason *out_failure_reason)
-{
-    NMModemPrivate *  priv                    = NM_MODEM_GET_PRIVATE(self);
-    gs_unref_ptrarray GPtrArray *hints        = NULL;
-    const char *                 setting_name = NULL;
-    NMSecretAgentGetSecretsFlags flags        = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
-    NMConnection *               connection;
-
-    g_return_val_if_fail(NM_IS_ACT_REQUEST(req), NM_ACT_STAGE_RETURN_FAILURE);
-
-    if (priv->act_request)
-        g_object_unref(priv->act_request);
-    priv->act_request = g_object_ref(req);
-
-    connection = nm_act_request_get_applied_connection(req);
-    g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
-
-    setting_name = nm_connection_need_secrets(connection, &hints);
-    if (!setting_name) {
-        nm_assert(!hints);
-        return NM_MODEM_GET_CLASS(self)->modem_act_stage1_prepare(self,
-                                                                  connection,
-                                                                  out_failure_reason);
-    }
-
-    /* Secrets required... */
-    if (priv->secrets_tries++)
-        flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
-
-    if (hints)
-        g_ptr_array_add(hints, NULL);
-
-    priv->secrets_id = nm_act_request_get_secrets(req,
-                                                  FALSE,
-                                                  setting_name,
-                                                  flags,
-                                                  hints ? (const char *const *) hints->pdata : NULL,
-                                                  modem_secrets_cb,
-                                                  self);
-    g_return_val_if_fail(priv->secrets_id, NM_ACT_STAGE_RETURN_FAILURE);
-    g_signal_emit(self, signals[AUTH_REQUESTED], 0);
-    return NM_ACT_STAGE_RETURN_POSTPONE;
-}
-
-/*****************************************************************************/
-
-void
-nm_modem_act_stage2_config(NMModem *self)
-{
-    NMModemPrivate *priv;
-
-    g_return_if_fail(NM_IS_MODEM(self));
-
-    priv = NM_MODEM_GET_PRIVATE(self);
-    /* Clear secrets tries counter since secrets were successfully used
-     * already if we get here.
-     */
-    priv->secrets_tries = 0;
-}
-
-/*****************************************************************************/
-
-gboolean
-nm_modem_check_connection_compatible(NMModem *self, NMConnection *connection, GError **error)
-{
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self);
-
-    if (nm_streq0(nm_connection_get_connection_type(connection), NM_SETTING_GSM_SETTING_NAME)) {
-        NMSettingGsm *s_gsm;
-        const char *  str;
-
-        s_gsm = _nm_connection_check_main_setting(connection, NM_SETTING_GSM_SETTING_NAME, error);
-        if (!s_gsm)
-            return FALSE;
-
-        str = nm_setting_gsm_get_device_id(s_gsm);
-        if (str) {
-            if (!priv->device_id) {
-                nm_utils_error_set_literal(error,
-                                           NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                                           "GSM profile has device-id, device does not");
-                return FALSE;
-            }
-            if (!nm_streq(str, priv->device_id)) {
-                nm_utils_error_set_literal(error,
-                                           NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                                           "device has differing device-id than GSM profile");
-                return FALSE;
-            }
-        }
-
-        /* SIM properties may not be available before the SIM is unlocked, so
-         * to ensure that autoconnect works, the connection's SIM properties
-         * are only compared if present on the device.
-         */
-
-        if (priv->sim_id && (str = nm_setting_gsm_get_sim_id(s_gsm))) {
-            if (!nm_streq(str, priv->sim_id)) {
-                nm_utils_error_set_literal(error,
-                                           NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                                           "device has differing sim-id than GSM profile");
-                return FALSE;
-            }
-        }
-
-        if (priv->sim_operator_id && (str = nm_setting_gsm_get_sim_operator_id(s_gsm))) {
-            if (!nm_streq(str, priv->sim_operator_id)) {
-                nm_utils_error_set_literal(error,
-                                           NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-                                           "device has differing sim-operator-id than GSM profile");
-                return FALSE;
-            }
-        }
-    }
-
-    return NM_MODEM_GET_CLASS(self)->check_connection_compatible_with_modem(self,
-                                                                            connection,
-                                                                            error);
-}
-
-/*****************************************************************************/
-
-gboolean
-nm_modem_complete_connection(NMModem *            self,
-                             const char *         iface,
-                             NMConnection *       connection,
-                             NMConnection *const *existing_connections,
-                             GError **            error)
-{
-    NMModemClass *klass;
-
-    klass = NM_MODEM_GET_CLASS(self);
-    if (!klass->complete_connection) {
-        g_set_error(error,
-                    NM_DEVICE_ERROR,
-                    NM_DEVICE_ERROR_INVALID_CONNECTION,
-                    "Modem class %s had no complete_connection method",
-                    G_OBJECT_TYPE_NAME(self));
-        return FALSE;
-    }
-
-    return klass->complete_connection(self, iface, connection, existing_connections, error);
-}
-
-/*****************************************************************************/
-
-static void
-deactivate_cleanup(NMModem *self, NMDevice *device, gboolean stop_ppp_manager)
-{
-    NMModemPrivate *priv;
-    int             ifindex;
-
-    g_return_if_fail(NM_IS_MODEM(self));
-
-    priv = NM_MODEM_GET_PRIVATE(self);
-
-    priv->secrets_tries = 0;
-
-    if (priv->act_request) {
-        cancel_get_secrets(self);
-        g_object_unref(priv->act_request);
-        priv->act_request = NULL;
-    }
-
-    priv->in_bytes = priv->out_bytes = 0;
-
-    if (priv->ppp_manager) {
-        g_signal_handlers_disconnect_by_data(priv->ppp_manager, self);
-        if (stop_ppp_manager)
-            nm_ppp_manager_stop(priv->ppp_manager, NULL, NULL, NULL);
-        g_clear_object(&priv->ppp_manager);
-    }
-
-    if (device) {
-        g_return_if_fail(NM_IS_DEVICE(device));
-
-        if (priv->ip4_method == NM_MODEM_IP_METHOD_STATIC
-            || priv->ip4_method == NM_MODEM_IP_METHOD_AUTO
-            || priv->ip6_method == NM_MODEM_IP_METHOD_STATIC
-            || priv->ip6_method == NM_MODEM_IP_METHOD_AUTO) {
-            ifindex = nm_device_get_ip_ifindex(device);
-            if (ifindex > 0) {
-                NMPlatform *platform = nm_device_get_platform(device);
-
-                nm_platform_ip_route_flush(platform, AF_UNSPEC, ifindex);
-                nm_platform_ip_address_flush(platform, AF_UNSPEC, ifindex);
-                nm_platform_link_set_down(platform, ifindex);
-            }
-        }
-    }
-
-    nm_clear_g_free(&priv->data_port);
-    priv->mm_ip_timeout = 0;
-    priv->ip4_method    = NM_MODEM_IP_METHOD_UNKNOWN;
-    priv->ip6_method    = NM_MODEM_IP_METHOD_UNKNOWN;
-    _set_ip_ifindex(self, -1, NULL);
-}
-
-/*****************************************************************************/
-
-typedef struct {
-    NMModem *                 self;
-    NMDevice *                device;
-    GCancellable *            cancellable;
-    NMModemDeactivateCallback callback;
-    gpointer                  callback_user_data;
-} DeactivateContext;
-
-static void
-deactivate_context_complete(DeactivateContext *ctx, GError *error)
-{
-    NMModem *self = ctx->self;
-
-    _LOGD("modem deactivation finished %s%s%s",
-          NM_PRINT_FMT_QUOTED(error, "with failure: ", error->message, "", "successfully"));
-
-    if (ctx->callback)
-        ctx->callback(ctx->self, error, ctx->callback_user_data);
-    nm_g_object_unref(ctx->cancellable);
-    g_object_unref(ctx->device);
-    g_object_unref(ctx->self);
-    g_slice_free(DeactivateContext, ctx);
-}
-
-static void
-_deactivate_call_disconnect_cb(NMModem *self, GError *error, gpointer user_data)
-{
-    deactivate_context_complete(user_data, error);
-}
-
-static void
-_deactivate_call_disconnect(DeactivateContext *ctx)
-{
-    NM_MODEM_GET_CLASS(ctx->self)->disconnect(ctx->self,
-                                              FALSE,
-                                              ctx->cancellable,
-                                              _deactivate_call_disconnect_cb,
-                                              ctx);
-}
-
-static void
-_deactivate_ppp_manager_stop_cb(NMPPPManager *          ppp_manager,
-                                NMPPPManagerStopHandle *handle,
-                                gboolean                was_cancelled,
-                                gpointer                user_data)
-{
-    DeactivateContext *ctx = user_data;
-
-    g_object_unref(ppp_manager);
-
-    if (was_cancelled) {
-        gs_free_error GError *error = NULL;
-
-        if (!g_cancellable_set_error_if_cancelled(ctx->cancellable, &error))
-            nm_assert_not_reached();
-        deactivate_context_complete(ctx, error);
-        return;
-    }
-
-    nm_assert(!g_cancellable_is_cancelled(ctx->cancellable));
-    _deactivate_call_disconnect(ctx);
-}
-
-void
-nm_modem_deactivate_async(NMModem *                 self,
-                          NMDevice *                device,
-                          GCancellable *            cancellable,
-                          NMModemDeactivateCallback callback,
-                          gpointer                  user_data)
-{
-    NMModemPrivate *   priv = NM_MODEM_GET_PRIVATE(self);
-    DeactivateContext *ctx;
-    NMPPPManager *     ppp_manager;
-
-    g_return_if_fail(NM_IS_MODEM(self));
-    g_return_if_fail(NM_IS_DEVICE(device));
-    g_return_if_fail(G_IS_CANCELLABLE(cancellable));
-
-    ctx                     = g_slice_new(DeactivateContext);
-    ctx->self               = g_object_ref(self);
-    ctx->device             = g_object_ref(device);
-    ctx->cancellable        = g_object_ref(cancellable);
-    ctx->callback           = callback;
-    ctx->callback_user_data = user_data;
-
-    ppp_manager = nm_g_object_ref(priv->ppp_manager);
-
-    NM_MODEM_GET_CLASS(self)->deactivate_cleanup(self, ctx->device, FALSE);
-
-    if (ppp_manager) {
-        /* If we have a PPP manager, stop it.
-         *
-         * Pass on the reference in @ppp_manager. */
-        nm_ppp_manager_stop(ppp_manager, ctx->cancellable, _deactivate_ppp_manager_stop_cb, ctx);
-        return;
-    }
-
-    _deactivate_call_disconnect(ctx);
-}
-
-/*****************************************************************************/
-
-void
-nm_modem_deactivate(NMModem *self, NMDevice *device)
-{
-    /* First cleanup */
-    NM_MODEM_GET_CLASS(self)->deactivate_cleanup(self, device, TRUE);
-    /* Then disconnect without waiting */
-    NM_MODEM_GET_CLASS(self)->disconnect(self, FALSE, NULL, NULL, NULL);
-}
-
-/*****************************************************************************/
-
-void
-nm_modem_device_state_changed(NMModem *self, NMDeviceState new_state, NMDeviceState old_state)
-{
-    gboolean        was_connected = FALSE, warn = TRUE;
-    NMModemPrivate *priv;
-
-    g_return_if_fail(NM_IS_MODEM(self));
-
-    if (old_state >= NM_DEVICE_STATE_PREPARE && old_state <= NM_DEVICE_STATE_DEACTIVATING)
-        was_connected = TRUE;
-
-    priv = NM_MODEM_GET_PRIVATE(self);
-
-    /* Make sure we don't leave the serial device open */
-    switch (new_state) {
-    case NM_DEVICE_STATE_UNMANAGED:
-    case NM_DEVICE_STATE_UNAVAILABLE:
-    case NM_DEVICE_STATE_FAILED:
-    case NM_DEVICE_STATE_DISCONNECTED:
-        if (priv->act_request) {
-            cancel_get_secrets(self);
-            g_object_unref(priv->act_request);
-            priv->act_request = NULL;
-        }
-
-        if (was_connected) {
-            /* Don't bother warning on FAILED since the modem is already gone */
-            if (new_state == NM_DEVICE_STATE_FAILED || new_state == NM_DEVICE_STATE_DISCONNECTED)
-                warn = FALSE;
-            /* First cleanup */
-            NM_MODEM_GET_CLASS(self)->deactivate_cleanup(self, NULL, TRUE);
-            NM_MODEM_GET_CLASS(self)->disconnect(self, warn, NULL, NULL, NULL);
-        }
-        break;
-    default:
-        break;
-    }
-}
-
-/*****************************************************************************/
-
-const char *
-nm_modem_get_uid(NMModem *self)
-{
-    g_return_val_if_fail(NM_IS_MODEM(self), NULL);
-
-    return NM_MODEM_GET_PRIVATE(self)->uid;
-}
-
-const char *
-nm_modem_get_path(NMModem *self)
-{
-    g_return_val_if_fail(NM_IS_MODEM(self), NULL);
-
-    return NM_MODEM_GET_PRIVATE(self)->path;
-}
-
-const char *
-nm_modem_get_driver(NMModem *self)
-{
-    g_return_val_if_fail(NM_IS_MODEM(self), NULL);
-
-    return NM_MODEM_GET_PRIVATE(self)->driver;
-}
-
-const char *
-nm_modem_get_control_port(NMModem *self)
-{
-    g_return_val_if_fail(NM_IS_MODEM(self), NULL);
-
-    return NM_MODEM_GET_PRIVATE(self)->control_port;
-}
-
-int
-nm_modem_get_ip_ifindex(NMModem *self)
-{
-    NMModemPrivate *priv;
-
-    g_return_val_if_fail(NM_IS_MODEM(self), 0);
-
-    priv = NM_MODEM_GET_PRIVATE(self);
-
-    /* internally we track an unset ip_ifindex as -1.
-     * For the caller of nm_modem_get_ip_ifindex(), this
-     * shall be zero too. */
-    return priv->ip_ifindex != -1 ? priv->ip_ifindex : 0;
-}
-
-static void
-_set_ip_ifindex(NMModem *self, int ifindex, const char *ifname)
-{
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self);
-
-    nm_assert(ifindex >= -1);
-    nm_assert((ifindex > 0) == !!ifname);
-
-    if (!nm_streq0(priv->ip_iface, ifname)) {
-        g_free(priv->ip_iface);
-        priv->ip_iface = g_strdup(ifname);
-    }
-
-    if (priv->ip_ifindex != ifindex) {
-        priv->ip_ifindex = ifindex;
-        _notify(self, PROP_IP_IFINDEX);
-    }
-}
-
-gboolean
-nm_modem_set_data_port(NMModem *       self,
-                       NMPlatform *    platform,
-                       const char *    data_port,
-                       NMModemIPMethod ip4_method,
-                       NMModemIPMethod ip6_method,
-                       guint           timeout,
-                       GError **       error)
-{
-    NMModemPrivate *priv;
-    gboolean        is_ppp;
-    int             ifindex = -1;
-
-    g_return_val_if_fail(NM_IS_MODEM(self), FALSE);
-    g_return_val_if_fail(NM_IS_PLATFORM(platform), FALSE);
-    g_return_val_if_fail(!error || !*error, FALSE);
-
-    priv = NM_MODEM_GET_PRIVATE(self);
-
-    if (priv->ppp_manager || priv->data_port || priv->ip_ifindex != -1) {
-        g_set_error_literal(error,
-                            NM_UTILS_ERROR,
-                            NM_UTILS_ERROR_UNKNOWN,
-                            "cannot set data port in activated state");
-        /* this really shouldn't happen. Assert. */
-        g_return_val_if_reached(FALSE);
-    }
-
-    if (!data_port) {
-        g_set_error_literal(error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "missing data port");
-        return FALSE;
-    }
-
-    is_ppp = (ip4_method == NM_MODEM_IP_METHOD_PPP) || (ip6_method == NM_MODEM_IP_METHOD_PPP);
-    if (is_ppp) {
-        if (!NM_IN_SET(ip4_method, NM_MODEM_IP_METHOD_UNKNOWN, NM_MODEM_IP_METHOD_PPP)
-            || !NM_IN_SET(ip6_method, NM_MODEM_IP_METHOD_UNKNOWN, NM_MODEM_IP_METHOD_PPP)) {
-            g_set_error_literal(error,
-                                NM_UTILS_ERROR,
-                                NM_UTILS_ERROR_UNKNOWN,
-                                "conflicting ip methods");
-            return FALSE;
-        }
-    } else if (!NM_IN_SET(ip4_method,
-                          NM_MODEM_IP_METHOD_UNKNOWN,
-                          NM_MODEM_IP_METHOD_STATIC,
-                          NM_MODEM_IP_METHOD_AUTO)
-               || !NM_IN_SET(ip6_method,
-                             NM_MODEM_IP_METHOD_UNKNOWN,
-                             NM_MODEM_IP_METHOD_STATIC,
-                             NM_MODEM_IP_METHOD_AUTO)
-               || (ip4_method == NM_MODEM_IP_METHOD_UNKNOWN
-                   && ip6_method == NM_MODEM_IP_METHOD_UNKNOWN)) {
-        g_set_error_literal(error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "invalid ip methods");
-        return FALSE;
-    }
-
-    if (!is_ppp) {
-        ifindex = nm_platform_if_nametoindex(platform, data_port);
-        if (ifindex <= 0) {
-            g_set_error(error,
-                        NM_UTILS_ERROR,
-                        NM_UTILS_ERROR_UNKNOWN,
-                        "cannot find network interface %s",
-                        data_port);
-            return FALSE;
-        }
-        if (!nm_platform_process_events_ensure_link(platform, ifindex, data_port)) {
-            g_set_error(error,
-                        NM_UTILS_ERROR,
-                        NM_UTILS_ERROR_UNKNOWN,
-                        "cannot find network interface %s in platform cache",
-                        data_port);
-            return FALSE;
-        }
-    }
-
-    priv->mm_ip_timeout = timeout;
-    priv->ip4_method    = ip4_method;
-    priv->ip6_method    = ip6_method;
-    if (is_ppp) {
-        priv->data_port = g_strdup(data_port);
-        _set_ip_ifindex(self, -1, NULL);
-    } else {
-        priv->data_port = NULL;
-        _set_ip_ifindex(self, ifindex, data_port);
-    }
-    return TRUE;
-}
-
-gboolean
-nm_modem_owns_port(NMModem *self, const char *iface)
-{
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self);
-
-    g_return_val_if_fail(iface != NULL, FALSE);
-
-    if (NM_MODEM_GET_CLASS(self)->owns_port)
-        return NM_MODEM_GET_CLASS(self)->owns_port(self, iface);
-
-    return NM_IN_STRSET(iface, priv->ip_iface, priv->data_port, priv->control_port);
-}
-
-gboolean
-nm_modem_get_iid(NMModem *self, NMUtilsIPv6IfaceId *out_iid)
-{
-    g_return_val_if_fail(NM_IS_MODEM(self), FALSE);
-
-    *out_iid = NM_MODEM_GET_PRIVATE(self)->iid;
-    return TRUE;
-}
-
-/*****************************************************************************/
-
-void
-nm_modem_get_route_parameters(NMModem *self,
-                              guint32 *out_ip4_route_table,
-                              guint32 *out_ip4_route_metric,
-                              guint32 *out_ip6_route_table,
-                              guint32 *out_ip6_route_metric)
-{
-    NMModemPrivate *priv;
-
-    g_return_if_fail(NM_IS_MODEM(self));
-
-    priv = NM_MODEM_GET_PRIVATE(self);
-    NM_SET_OUT(out_ip4_route_table, priv->ip4_route_table);
-    NM_SET_OUT(out_ip4_route_metric, priv->ip4_route_metric);
-    NM_SET_OUT(out_ip6_route_table, priv->ip6_route_table);
-    NM_SET_OUT(out_ip6_route_metric, priv->ip6_route_metric);
-}
-
-void
-nm_modem_set_route_parameters(NMModem *self,
-                              guint32  ip4_route_table,
-                              guint32  ip4_route_metric,
-                              guint32  ip6_route_table,
-                              guint32  ip6_route_metric)
-{
-    NMModemPrivate *priv;
-
-    g_return_if_fail(NM_IS_MODEM(self));
-
-    priv = NM_MODEM_GET_PRIVATE(self);
-    if (priv->ip4_route_table != ip4_route_table || priv->ip4_route_metric != ip4_route_metric
-        || priv->ip6_route_table != ip6_route_table || priv->ip6_route_metric != ip6_route_metric) {
-        priv->ip4_route_table  = ip4_route_table;
-        priv->ip4_route_metric = ip4_route_metric;
-        priv->ip6_route_table  = ip6_route_table;
-        priv->ip6_route_metric = ip6_route_metric;
-
-        _LOGT("route-parameters: table-v4: %u, metric-v4: %u, table-v6: %u, metric-v6: %u",
-              priv->ip4_route_table,
-              priv->ip4_route_metric,
-              priv->ip6_route_table,
-              priv->ip6_route_metric);
-    }
-
-    if (priv->ppp_manager) {
-        nm_ppp_manager_set_route_parameters(priv->ppp_manager,
-                                            priv->ip4_route_table,
-                                            priv->ip4_route_metric,
-                                            priv->ip6_route_table,
-                                            priv->ip6_route_metric);
-    }
-}
-
-void
-nm_modem_set_route_parameters_from_device(NMModem *self, NMDevice *device)
-{
-    g_return_if_fail(NM_IS_DEVICE(device));
-
-    nm_modem_set_route_parameters(self,
-                                  nm_device_get_route_table(device, AF_INET),
-                                  nm_device_get_route_metric(device, AF_INET),
-                                  nm_device_get_route_table(device, AF_INET6),
-                                  nm_device_get_route_metric(device, AF_INET6));
-}
-
-/*****************************************************************************/
-
-void
-nm_modem_get_capabilities(NMModem *                  self,
-                          NMDeviceModemCapabilities *modem_caps,
-                          NMDeviceModemCapabilities *current_caps)
-{
-    g_return_if_fail(NM_IS_MODEM(self));
-
-    NM_MODEM_GET_CLASS(self)->get_capabilities(self, modem_caps, current_caps);
-}
-
-/*****************************************************************************/
-
-void
-_nm_modem_set_operator_code(NMModem *self, const char *operator_code)
-{
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self);
-
-    if (g_strcmp0(priv->operator_code, operator_code) != 0) {
-        g_free(priv->operator_code);
-        priv->operator_code = g_strdup(operator_code);
-        _notify(self, PROP_OPERATOR_CODE);
-    }
-}
-
-void
-_nm_modem_set_apn(NMModem *self, const char *apn)
-{
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self);
-
-    if (g_strcmp0(priv->apn, apn) != 0) {
-        g_free(priv->apn);
-        priv->apn = g_strdup(apn);
-        _notify(self, PROP_APN);
-    }
-}
-
-static void
-get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
-    NMModem *       self = NM_MODEM(object);
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self);
-
-    switch (prop_id) {
-    case PROP_PATH:
-        g_value_set_string(value, priv->path);
-        break;
-    case PROP_DRIVER:
-        g_value_set_string(value, priv->driver);
-        break;
-    case PROP_CONTROL_PORT:
-        g_value_set_string(value, priv->control_port);
-        break;
-    case PROP_IP_IFINDEX:
-        g_value_set_int(value, nm_modem_get_ip_ifindex(self));
-        break;
-    case PROP_UID:
-        g_value_set_string(value, priv->uid);
-        break;
-    case PROP_STATE:
-        g_value_set_int(value, priv->state);
-        break;
-    case PROP_DEVICE_ID:
-        g_value_set_string(value, priv->device_id);
-        break;
-    case PROP_SIM_ID:
-        g_value_set_string(value, priv->sim_id);
-        break;
-    case PROP_IP_TYPES:
-        g_value_set_uint(value, priv->ip_types);
-        break;
-    case PROP_SIM_OPERATOR_ID:
-        g_value_set_string(value, priv->sim_operator_id);
-        break;
-    case PROP_OPERATOR_CODE:
-        g_value_set_string(value, priv->operator_code);
-        break;
-    case PROP_APN:
-        g_value_set_string(value, priv->apn);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(object);
-    const char *    s;
-
-    switch (prop_id) {
-    case PROP_PATH:
-        /* construct-only */
-        priv->path = g_value_dup_string(value);
-        g_return_if_fail(priv->path);
-        break;
-    case PROP_DRIVER:
-        /* construct-only */
-        priv->driver = g_value_dup_string(value);
-        break;
-    case PROP_CONTROL_PORT:
-        /* construct-only */
-        priv->control_port = g_value_dup_string(value);
-        break;
-    case PROP_UID:
-        /* construct-only */
-        priv->uid = g_value_dup_string(value);
-        break;
-    case PROP_STATE:
-        /* construct-only */
-        priv->state = g_value_get_int(value);
-        break;
-    case PROP_DEVICE_ID:
-        /* construct-only */
-        priv->device_id = g_value_dup_string(value);
-        break;
-    case PROP_SIM_ID:
-        g_free(priv->sim_id);
-        priv->sim_id = g_value_dup_string(value);
-        break;
-    case PROP_IP_TYPES:
-        priv->ip_types = g_value_get_uint(value);
-        break;
-    case PROP_SIM_OPERATOR_ID:
-        nm_clear_g_free(&priv->sim_operator_id);
-        s = g_value_get_string(value);
-        if (s && s[0])
-            priv->sim_operator_id = g_strdup(s);
-        break;
-    case PROP_OPERATOR_CODE:
-        /* construct-only */
-        priv->operator_code = g_value_dup_string(value);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-/*****************************************************************************/
-
-static void
-nm_modem_init(NMModem *self)
-{
-    NMModemPrivate *priv;
-
-    self->_priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_MODEM, NMModemPrivate);
-    priv        = self->_priv;
-
-    priv->ip_ifindex       = -1;
-    priv->ip4_route_table  = RT_TABLE_MAIN;
-    priv->ip4_route_metric = 700;
-    priv->ip6_route_table  = RT_TABLE_MAIN;
-    priv->ip6_route_metric = 700;
-}
-
-static void
-constructed(GObject *object)
-{
-    NMModemPrivate *priv;
-
-    G_OBJECT_CLASS(nm_modem_parent_class)->constructed(object);
-
-    priv = NM_MODEM_GET_PRIVATE(NM_MODEM(object));
-
-    g_return_if_fail(priv->control_port);
-}
-
-/*****************************************************************************/
-
-static void
-dispose(GObject *object)
-{
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(object);
-
-    g_clear_object(&priv->act_request);
-
-    G_OBJECT_CLASS(nm_modem_parent_class)->dispose(object);
-}
-
-static void
-finalize(GObject *object)
-{
-    NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(object);
-
-    g_free(priv->uid);
-    g_free(priv->path);
-    g_free(priv->driver);
-    g_free(priv->control_port);
-    g_free(priv->data_port);
-    g_free(priv->ip_iface);
-    g_free(priv->device_id);
-    g_free(priv->sim_id);
-    g_free(priv->sim_operator_id);
-    g_free(priv->operator_code);
-    g_free(priv->apn);
-
-    G_OBJECT_CLASS(nm_modem_parent_class)->finalize(object);
-}
-
-static void
-nm_modem_class_init(NMModemClass *klass)
-{
-    GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
-    g_type_class_add_private(object_class, sizeof(NMModemPrivate));
-
-    object_class->constructed  = constructed;
-    object_class->set_property = set_property;
-    object_class->get_property = get_property;
-    object_class->dispose      = dispose;
-    object_class->finalize     = finalize;
-
-    klass->modem_act_stage1_prepare  = modem_act_stage1_prepare;
-    klass->stage3_ip6_config_request = stage3_ip6_config_request;
-    klass->deactivate_cleanup        = deactivate_cleanup;
-
-    obj_properties[PROP_UID] =
-        g_param_spec_string(NM_MODEM_UID,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_PATH] =
-        g_param_spec_string(NM_MODEM_PATH,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_DRIVER] =
-        g_param_spec_string(NM_MODEM_DRIVER,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_CONTROL_PORT] =
-        g_param_spec_string(NM_MODEM_CONTROL_PORT,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_IP_IFINDEX] = g_param_spec_int(NM_MODEM_IP_IFINDEX,
-                                                       "",
-                                                       "",
-                                                       0,
-                                                       G_MAXINT,
-                                                       0,
-                                                       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_STATE] =
-        g_param_spec_int(NM_MODEM_STATE,
-                         "",
-                         "",
-                         NM_MODEM_STATE_UNKNOWN,
-                         _NM_MODEM_STATE_LAST,
-                         NM_MODEM_STATE_UNKNOWN,
-                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_DEVICE_ID] =
-        g_param_spec_string(NM_MODEM_DEVICE_ID,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_SIM_ID] =
-        g_param_spec_string(NM_MODEM_SIM_ID,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_IP_TYPES] =
-        g_param_spec_uint(NM_MODEM_IP_TYPES,
-                          "IP Types",
-                          "Supported IP types",
-                          0,
-                          G_MAXUINT32,
-                          NM_MODEM_IP_TYPE_IPV4,
-                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_SIM_OPERATOR_ID] =
-        g_param_spec_string(NM_MODEM_SIM_OPERATOR_ID,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_OPERATOR_CODE] =
-        g_param_spec_string(NM_MODEM_OPERATOR_CODE,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
-    obj_properties[PROP_APN] =
-        g_param_spec_string(NM_MODEM_APN, "", "", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-
-    signals[PPP_STATS] = g_signal_new(NM_MODEM_PPP_STATS,
-                                      G_OBJECT_CLASS_TYPE(object_class),
-                                      G_SIGNAL_RUN_FIRST,
-                                      0,
-                                      NULL,
-                                      NULL,
-                                      NULL,
-                                      G_TYPE_NONE,
-                                      2,
-                                      G_TYPE_UINT /*guint32 in_bytes*/,
-                                      G_TYPE_UINT /*guint32 out_bytes*/);
-
-    signals[PPP_FAILED] = g_signal_new(NM_MODEM_PPP_FAILED,
-                                       G_OBJECT_CLASS_TYPE(object_class),
-                                       G_SIGNAL_RUN_FIRST,
-                                       0,
-                                       NULL,
-                                       NULL,
-                                       NULL,
-                                       G_TYPE_NONE,
-                                       1,
-                                       G_TYPE_UINT);
-
-    signals[IP4_CONFIG_RESULT] = g_signal_new(NM_MODEM_IP4_CONFIG_RESULT,
-                                              G_OBJECT_CLASS_TYPE(object_class),
-                                              G_SIGNAL_RUN_FIRST,
-                                              0,
-                                              NULL,
-                                              NULL,
-                                              NULL,
-                                              G_TYPE_NONE,
-                                              2,
-                                              G_TYPE_OBJECT,
-                                              G_TYPE_POINTER);
-
-    /**
-     * NMModem::ip6-config-result:
-     * @modem: the #NMModem  on which the signal is emitted
-     * @config: the #NMIP6Config to apply to the modem's data port
-     * @do_slaac: %TRUE if IPv6 SLAAC should be started
-     * @error: a #GError if any error occurred during IP configuration
-     *
-     * This signal is emitted when IPv6 configuration has completed or failed.
-     * If @error is set the configuration failed.  If @config is set, then
-     * the details should be applied to the data port before any further
-     * configuration (like SLAAC) is done.  @do_slaac indicates whether SLAAC
-     * should be started after applying @config to the data port.
-     */
-    signals[IP6_CONFIG_RESULT] = g_signal_new(NM_MODEM_IP6_CONFIG_RESULT,
-                                              G_OBJECT_CLASS_TYPE(object_class),
-                                              G_SIGNAL_RUN_FIRST,
-                                              0,
-                                              NULL,
-                                              NULL,
-                                              NULL,
-                                              G_TYPE_NONE,
-                                              3,
-                                              G_TYPE_OBJECT,
-                                              G_TYPE_BOOLEAN,
-                                              G_TYPE_POINTER);
-
-    signals[PREPARE_RESULT] = g_signal_new(NM_MODEM_PREPARE_RESULT,
-                                           G_OBJECT_CLASS_TYPE(object_class),
-                                           G_SIGNAL_RUN_FIRST,
-                                           0,
-                                           NULL,
-                                           NULL,
-                                           NULL,
-                                           G_TYPE_NONE,
-                                           2,
-                                           G_TYPE_BOOLEAN,
-                                           G_TYPE_UINT);
-
-    signals[AUTH_REQUESTED] = g_signal_new(NM_MODEM_AUTH_REQUESTED,
-                                           G_OBJECT_CLASS_TYPE(object_class),
-                                           G_SIGNAL_RUN_FIRST,
-                                           0,
-                                           NULL,
-                                           NULL,
-                                           NULL,
-                                           G_TYPE_NONE,
-                                           0);
-
-    signals[AUTH_RESULT] = g_signal_new(NM_MODEM_AUTH_RESULT,
-                                        G_OBJECT_CLASS_TYPE(object_class),
-                                        G_SIGNAL_RUN_FIRST,
-                                        0,
-                                        NULL,
-                                        NULL,
-                                        NULL,
-                                        G_TYPE_NONE,
-                                        1,
-                                        G_TYPE_POINTER);
-
-    signals[REMOVED] = g_signal_new(NM_MODEM_REMOVED,
-                                    G_OBJECT_CLASS_TYPE(object_class),
-                                    G_SIGNAL_RUN_FIRST,
-                                    0,
-                                    NULL,
-                                    NULL,
-                                    NULL,
-                                    G_TYPE_NONE,
-                                    0);
-
-    signals[STATE_CHANGED] = g_signal_new(NM_MODEM_STATE_CHANGED,
-                                          G_OBJECT_CLASS_TYPE(object_class),
-                                          G_SIGNAL_RUN_FIRST,
-                                          0,
-                                          NULL,
-                                          NULL,
-                                          NULL,
-                                          G_TYPE_NONE,
-                                          2,
-                                          G_TYPE_INT,
-                                          G_TYPE_INT);
-}
diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h
deleted file mode 100644
index 4b275cf7..00000000
--- a/src/devices/wwan/nm-modem.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2009 - 2011 Red Hat, Inc.
- * Copyright (C) 2009 Novell, Inc.
- */
-
-#ifndef __NETWORKMANAGER_MODEM_H__
-#define __NETWORKMANAGER_MODEM_H__
-
-#include "ppp/nm-ppp-manager.h"
-#include "devices/nm-device.h"
-
-#define NM_TYPE_MODEM            (nm_modem_get_type())
-#define NM_MODEM(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MODEM, NMModem))
-#define NM_MODEM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_MODEM, NMModemClass))
-#define NM_IS_MODEM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_MODEM))
-#define NM_IS_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_MODEM))
-#define NM_MODEM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_MODEM, NMModemClass))
-
-/* Properties */
-#define NM_MODEM_UID             "uid"
-#define NM_MODEM_PATH            "path"
-#define NM_MODEM_DRIVER          "driver"
-#define NM_MODEM_CONTROL_PORT    "control-port"
-#define NM_MODEM_IP_IFINDEX      "ip-ifindex"
-#define NM_MODEM_STATE           "state"
-#define NM_MODEM_DEVICE_ID       "device-id"
-#define NM_MODEM_SIM_ID          "sim-id"
-#define NM_MODEM_IP_TYPES        "ip-types" /* Supported IP types */
-#define NM_MODEM_SIM_OPERATOR_ID "sim-operator-id"
-#define NM_MODEM_OPERATOR_CODE   "operator-code"
-#define NM_MODEM_APN             "apn"
-
-/* Signals */
-#define NM_MODEM_PPP_STATS         "ppp-stats"
-#define NM_MODEM_PPP_FAILED        "ppp-failed"
-#define NM_MODEM_PREPARE_RESULT    "prepare-result"
-#define NM_MODEM_IP4_CONFIG_RESULT "ip4-config-result"
-#define NM_MODEM_IP6_CONFIG_RESULT "ip6-config-result"
-#define NM_MODEM_AUTH_REQUESTED    "auth-requested"
-#define NM_MODEM_AUTH_RESULT       "auth-result"
-#define NM_MODEM_REMOVED           "removed"
-#define NM_MODEM_STATE_CHANGED     "state-changed"
-
-typedef enum {
-    NM_MODEM_IP_METHOD_UNKNOWN = 0,
-    NM_MODEM_IP_METHOD_PPP,
-    NM_MODEM_IP_METHOD_STATIC,
-    NM_MODEM_IP_METHOD_AUTO, /* DHCP and/or SLAAC */
-} NMModemIPMethod;
-
-/**
- * NMModemIPType:
- * @NM_MODEM_IP_TYPE_UNKNOWN: unknown or no IP support
- * @NM_MODEM_IP_TYPE_IPV4: IPv4-only bearers are supported
- * @NM_MODEM_IP_TYPE_IPV6: IPv6-only bearers are supported
- * @NM_MODEM_IP_TYPE_IPV4V6: dual-stack IPv4 + IPv6 bearers are supported
- *
- * Indicates what IP protocols the modem supports for an IP bearer.  Any
- * combination of flags is possible.  For example, (%NM_MODEM_IP_TYPE_IPV4 |
- * %NM_MODEM_IP_TYPE_IPV6) indicates that the modem supports IPv4 and IPv6
- * but not simultaneously on the same bearer.
- */
-typedef enum {
-    NM_MODEM_IP_TYPE_UNKNOWN = 0x0,
-    NM_MODEM_IP_TYPE_IPV4    = 0x1,
-    NM_MODEM_IP_TYPE_IPV6    = 0x2,
-    NM_MODEM_IP_TYPE_IPV4V6  = 0x4
-} NMModemIPType;
-
-typedef enum { /*< underscore_name=nm_modem_state >*/
-               NM_MODEM_STATE_UNKNOWN       = 0,
-               NM_MODEM_STATE_FAILED        = 1,
-               NM_MODEM_STATE_INITIALIZING  = 2,
-               NM_MODEM_STATE_LOCKED        = 3,
-               NM_MODEM_STATE_DISABLED      = 4,
-               NM_MODEM_STATE_DISABLING     = 5,
-               NM_MODEM_STATE_ENABLING      = 6,
-               NM_MODEM_STATE_ENABLED       = 7,
-               NM_MODEM_STATE_SEARCHING     = 8,
-               NM_MODEM_STATE_REGISTERED    = 9,
-               NM_MODEM_STATE_DISCONNECTING = 10,
-               NM_MODEM_STATE_CONNECTING    = 11,
-               NM_MODEM_STATE_CONNECTED     = 12,
-
-               _NM_MODEM_STATE_LAST0,
-               _NM_MODEM_STATE_LAST = _NM_MODEM_STATE_LAST0 - 1,
-} NMModemState;
-
-struct _NMModemPrivate;
-
-struct _NMModem {
-    GObject                 parent;
-    struct _NMModemPrivate *_priv;
-};
-
-typedef struct _NMModem NMModem;
-
-typedef void (*_NMModemDisconnectCallback)(NMModem *modem, GError *error, gpointer user_data);
-
-typedef struct {
-    GObjectClass parent;
-
-    void (*get_capabilities)(NMModem *                  self,
-                             NMDeviceModemCapabilities *modem_caps,
-                             NMDeviceModemCapabilities *current_caps);
-
-    gboolean (*get_user_pass)(NMModem *     modem,
-                              NMConnection *connection,
-                              const char ** user,
-                              const char ** pass);
-
-    gboolean (*check_connection_compatible_with_modem)(NMModem *     modem,
-                                                       NMConnection *connection,
-                                                       GError **     error);
-
-    gboolean (*complete_connection)(NMModem *            modem,
-                                    const char *         iface,
-                                    NMConnection *       connection,
-                                    NMConnection *const *existing_connections,
-                                    GError **            error);
-
-    NMActStageReturn (*modem_act_stage1_prepare)(NMModem *            modem,
-                                                 NMConnection *       connection,
-                                                 NMDeviceStateReason *out_failure_reason);
-
-    NMActStageReturn (*static_stage3_ip4_config_start)(NMModem *            self,
-                                                       NMActRequest *       req,
-                                                       NMDeviceStateReason *out_failure_reason);
-
-    /* Request the IP6 config; when the config returns the modem
-     * subclass should emit the ip6_config_result signal.
-     */
-    NMActStageReturn (*stage3_ip6_config_request)(NMModem *            self,
-                                                  NMDeviceStateReason *out_failure_reason);
-
-    void (*set_mm_enabled)(NMModem *self, gboolean enabled);
-
-    void (*disconnect)(NMModem *                  self,
-                       gboolean                   warn,
-                       GCancellable *             cancellable,
-                       _NMModemDisconnectCallback callback,
-                       gpointer                   user_data);
-
-    void (*deactivate_cleanup)(NMModem *self, NMDevice *device, gboolean stop_ppp_manager);
-
-    gboolean (*owns_port)(NMModem *self, const char *iface);
-} NMModemClass;
-
-GType nm_modem_get_type(void);
-
-gboolean nm_modem_is_claimed(NMModem *modem);
-NMModem *nm_modem_claim(NMModem *modem);
-void     nm_modem_unclaim(NMModem *modem);
-
-const char *nm_modem_get_path(NMModem *modem);
-const char *nm_modem_get_uid(NMModem *modem);
-const char *nm_modem_get_control_port(NMModem *modem);
-int         nm_modem_get_ip_ifindex(NMModem *modem);
-const char *nm_modem_get_driver(NMModem *modem);
-const char *nm_modem_get_device_id(NMModem *modem);
-const char *nm_modem_get_sim_id(NMModem *modem);
-const char *nm_modem_get_sim_operator_id(NMModem *modem);
-gboolean    nm_modem_get_iid(NMModem *modem, NMUtilsIPv6IfaceId *out_iid);
-const char *nm_modem_get_operator_code(NMModem *modem);
-const char *nm_modem_get_apn(NMModem *modem);
-
-gboolean nm_modem_set_data_port(NMModem *       self,
-                                NMPlatform *    platform,
-                                const char *    data_port,
-                                NMModemIPMethod ip4_method,
-                                NMModemIPMethod ip6_method,
-                                guint           timeout,
-                                GError **       error);
-
-gboolean nm_modem_owns_port(NMModem *modem, const char *iface);
-
-void nm_modem_get_capabilities(NMModem *                  self,
-                               NMDeviceModemCapabilities *modem_caps,
-                               NMDeviceModemCapabilities *current_caps);
-
-gboolean
-nm_modem_check_connection_compatible(NMModem *self, NMConnection *connection, GError **error);
-
-gboolean nm_modem_complete_connection(NMModem *            self,
-                                      const char *         iface,
-                                      NMConnection *       connection,
-                                      NMConnection *const *existing_connections,
-                                      GError **            error);
-
-void nm_modem_get_route_parameters(NMModem *self,
-                                   guint32 *out_ip4_route_table,
-                                   guint32 *out_ip4_route_metric,
-                                   guint32 *out_ip6_route_table,
-                                   guint32 *out_ip6_route_metric);
-
-void nm_modem_set_route_parameters(NMModem *self,
-                                   guint32  ip4_route_table,
-                                   guint32  ip4_route_metric,
-                                   guint32  ip6_route_table,
-                                   guint32  ip6_route_metric);
-
-void nm_modem_set_route_parameters_from_device(NMModem *modem, NMDevice *device);
-
-NMActStageReturn nm_modem_act_stage1_prepare(NMModem *            modem,
-                                             NMActRequest *       req,
-                                             NMDeviceStateReason *out_failure_reason);
-
-void nm_modem_act_stage2_config(NMModem *modem);
-
-NMActStageReturn nm_modem_stage3_ip4_config_start(NMModem *            modem,
-                                                  NMDevice *           device,
-                                                  NMDeviceClass *      device_class,
-                                                  NMDeviceStateReason *out_failure_reason);
-
-NMActStageReturn nm_modem_stage3_ip6_config_start(NMModem *            modem,
-                                                  NMDevice *           device,
-                                                  NMDeviceStateReason *out_failure_reason);
-
-void nm_modem_ip4_pre_commit(NMModem *modem, NMDevice *device, NMIP4Config *config);
-
-void nm_modem_get_secrets(NMModem *   modem,
-                          const char *setting_name,
-                          gboolean    request_new,
-                          const char *hint);
-
-void nm_modem_deactivate(NMModem *modem, NMDevice *device);
-
-typedef void (*NMModemDeactivateCallback)(NMModem *self, GError *error, gpointer user_data);
-
-void nm_modem_deactivate_async(NMModem *                 self,
-                               NMDevice *                device,
-                               GCancellable *            cancellable,
-                               NMModemDeactivateCallback callback,
-                               gpointer                  user_data);
-
-void
-nm_modem_device_state_changed(NMModem *modem, NMDeviceState new_state, NMDeviceState old_state);
-
-void nm_modem_set_mm_enabled(NMModem *self, gboolean enabled);
-
-NMModemState nm_modem_get_state(NMModem *self);
-void         nm_modem_set_state(NMModem *self, NMModemState new_state, const char *reason);
-void         nm_modem_set_prev_state(NMModem *self, const char *reason);
-const char * nm_modem_state_to_string(NMModemState state);
-
-NMModemIPType nm_modem_get_supported_ip_types(NMModem *self);
-
-/* For the modem-manager only */
-void nm_modem_emit_removed(NMModem *self);
-
-void nm_modem_emit_prepare_result(NMModem *self, gboolean success, NMDeviceStateReason reason);
-
-void nm_modem_emit_ppp_failed(NMModem *self, NMDeviceStateReason reason);
-
-GArray *nm_modem_get_connection_ip_type(NMModem *self, NMConnection *connection, GError **error);
-
-/* For subclasses */
-void nm_modem_emit_ip6_config_result(NMModem *self, NMIP6Config *config, GError *error);
-
-const char *nm_modem_ip_type_to_string(NMModemIPType ip_type);
-
-guint32
-nm_modem_get_configured_mtu(NMDevice *self, NMDeviceMtuSource *out_source, gboolean *out_force);
-
-void _nm_modem_set_operator_code(NMModem *self, const char *operator_code);
-void _nm_modem_set_apn(NMModem *self, const char *apn);
-
-#endif /* __NETWORKMANAGER_MODEM_H__ */
diff --git a/src/devices/wwan/nm-service-providers.c b/src/devices/wwan/nm-service-providers.c
deleted file mode 100644
index f7c6b5b8..00000000
--- a/src/devices/wwan/nm-service-providers.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/* 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;
-        nm_clear_g_free(&parse_context->apn);
-        nm_clear_g_free(&parse_context->username);
-        nm_clear_g_free(&parse_context->password);
-        nm_clear_g_free(&parse_context->gateway);
-        nm_clear_g_free(&parse_context->auth_method);
-        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) {
-                nm_clear_g_free(&parse_context->auth_method);
-                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;
-
-    nm_clear_g_free(&parse_context->text_buffer);
-
-    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) {
-        nm_clear_g_free(&parse_context->text_buffer);
-        parse_context->state = PARSER_TOPLEVEL;
-    }
-}
-
-static void
-parser_provider_end(ParseContext *parse_context, const char *name)
-{
-    if (strcmp(name, "provider") == 0) {
-        nm_clear_g_free(&parse_context->text_buffer);
-        parse_context->state = PARSER_COUNTRY;
-    }
-}
-
-static void
-parser_gsm_end(ParseContext *parse_context, const char *name)
-{
-    if (strcmp(name, "gsm") == 0) {
-        nm_clear_g_free(&parse_context->text_buffer);
-        parse_context->state = PARSER_PROVIDER;
-    }
-}
-
-static void
-parser_gsm_apn_end(ParseContext *parse_context, const char *name)
-{
-    if (strcmp(name, "username") == 0) {
-        nm_clear_g_free(&parse_context->username);
-        parse_context->username = g_steal_pointer(&parse_context->text_buffer);
-    } else if (strcmp(name, "password") == 0) {
-        nm_clear_g_free(&parse_context->password);
-        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) {
-        nm_clear_g_free(&parse_context->gateway);
-        parse_context->gateway = g_steal_pointer(&parse_context->text_buffer);
-    } else if (strcmp(name, "apn") == 0) {
-        nm_clear_g_free(&parse_context->text_buffer);
-
-        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) {
-        nm_clear_g_free(&parse_context->text_buffer);
-        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);
-}
diff --git a/src/devices/wwan/nm-service-providers.h b/src/devices/wwan/nm-service-providers.h
deleted file mode 100644
index 093bcd5b..00000000
--- a/src/devices/wwan/nm-service-providers.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 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__ */
diff --git a/src/devices/wwan/nm-wwan-factory.c b/src/devices/wwan/nm-wwan-factory.c
deleted file mode 100644
index 1c3406da..00000000
--- a/src/devices/wwan/nm-wwan-factory.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2014 Red Hat, Inc.
- */
-
-#include "nm-default.h"
-
-#include <gmodule.h>
-
-#include "devices/nm-device-factory.h"
-#include "nm-setting-gsm.h"
-#include "nm-setting-cdma.h"
-#include "nm-modem-manager.h"
-#include "nm-device-modem.h"
-#include "platform/nm-platform.h"
-
-/*****************************************************************************/
-
-#define NM_TYPE_WWAN_FACTORY (nm_wwan_factory_get_type())
-#define NM_WWAN_FACTORY(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WWAN_FACTORY, NMWwanFactory))
-#define NM_WWAN_FACTORY_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_WWAN_FACTORY, NMWwanFactoryClass))
-#define NM_IS_WWAN_FACTORY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_WWAN_FACTORY))
-#define NM_IS_WWAN_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_WWAN_FACTORY))
-#define NM_WWAN_FACTORY_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_WWAN_FACTORY, NMWwanFactoryClass))
-
-typedef struct {
-    NMModemManager *mm;
-} NMWwanFactoryPrivate;
-
-typedef struct {
-    NMDeviceFactory      parent;
-    NMWwanFactoryPrivate _priv;
-} NMWwanFactory;
-
-typedef struct {
-    NMDeviceFactoryClass parent;
-} NMWwanFactoryClass;
-
-static GType nm_wwan_factory_get_type(void);
-
-G_DEFINE_TYPE(NMWwanFactory, nm_wwan_factory, NM_TYPE_DEVICE_FACTORY)
-
-#define NM_WWAN_FACTORY_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMWwanFactory, NM_IS_WWAN_FACTORY)
-
-/*****************************************************************************/
-
-NM_DEVICE_FACTORY_DECLARE_TYPES(NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(
-    NM_LINK_TYPE_WWAN_NET) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_GSM_SETTING_NAME,
-                                                                   NM_SETTING_CDMA_SETTING_NAME))
-
-G_MODULE_EXPORT NMDeviceFactory *
-                nm_device_factory_create(GError **error)
-{
-    return (NMDeviceFactory *) g_object_new(NM_TYPE_WWAN_FACTORY, NULL);
-}
-
-/*****************************************************************************/
-
-static void
-modem_added_cb(NMModemManager *manager, NMModem *modem, gpointer user_data)
-{
-    NMWwanFactory * self             = NM_WWAN_FACTORY(user_data);
-    gs_unref_object NMDevice *device = NULL;
-    const char *              driver;
-
-    if (nm_modem_is_claimed(modem))
-        return;
-
-    driver = nm_modem_get_driver(modem);
-
-    /* If it was a Bluetooth modem and no bluetooth device claimed it, ignore
-     * it.  The rfcomm port (and thus the modem) gets created automatically
-     * by the Bluetooth code during the connection process.
-     */
-    if (driver && strstr(driver, "bluetooth")) {
-        nm_log_dbg(
-            LOGD_MB,
-            "WWAN factory ignores bluetooth modem '%s' which should be handled by bluetooth plugin",
-            nm_modem_get_control_port(modem));
-        return;
-    }
-
-    /* Make the new modem device */
-    device = nm_device_modem_new(modem);
-    g_signal_emit_by_name(self, NM_DEVICE_FACTORY_DEVICE_ADDED, device);
-}
-
-static NMDevice *
-create_device(NMDeviceFactory *     factory,
-              const char *          iface,
-              const NMPlatformLink *plink,
-              NMConnection *        connection,
-              gboolean *            out_ignore)
-{
-    g_return_val_if_fail(plink, NULL);
-    g_return_val_if_fail(plink->type == NM_LINK_TYPE_WWAN_NET, NULL);
-    *out_ignore = TRUE;
-    return NULL;
-}
-
-static void
-start(NMDeviceFactory *factory)
-{
-    NMWwanFactory *       self = NM_WWAN_FACTORY(factory);
-    NMWwanFactoryPrivate *priv = NM_WWAN_FACTORY_GET_PRIVATE(self);
-
-    priv->mm = g_object_ref(nm_modem_manager_get());
-
-    g_signal_connect(priv->mm, NM_MODEM_MANAGER_MODEM_ADDED, G_CALLBACK(modem_added_cb), self);
-}
-
-/*****************************************************************************/
-
-static void
-nm_wwan_factory_init(NMWwanFactory *self)
-{}
-
-static void
-dispose(GObject *object)
-{
-    NMWwanFactory *       self = NM_WWAN_FACTORY(object);
-    NMWwanFactoryPrivate *priv = NM_WWAN_FACTORY_GET_PRIVATE(self);
-
-    if (priv->mm)
-        g_signal_handlers_disconnect_by_func(priv->mm, modem_added_cb, self);
-    g_clear_object(&priv->mm);
-
-    /* Chain up to the parent class */
-    G_OBJECT_CLASS(nm_wwan_factory_parent_class)->dispose(object);
-}
-
-static void
-nm_wwan_factory_class_init(NMWwanFactoryClass *klass)
-{
-    GObjectClass *        object_class  = G_OBJECT_CLASS(klass);
-    NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS(klass);
-
-    object_class->dispose = dispose;
-
-    factory_class->get_supported_types = get_supported_types;
-    factory_class->create_device       = create_device;
-    factory_class->start               = start;
-}
diff --git a/src/devices/wwan/tests/test-service-providers.c b/src/devices/wwan/tests/test-service-providers.c
deleted file mode 100644
index ec19d588..00000000
--- a/src/devices/wwan/tests/test-service-providers.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/* 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();
-}
diff --git a/src/devices/wwan/tests/test-service-providers.xml b/src/devices/wwan/tests/test-service-providers.xml
deleted file mode 100644
index f0ca2deb..00000000
--- a/src/devices/wwan/tests/test-service-providers.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?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>
-