summaryrefslogtreecommitdiff
path: root/src/devices/wwan/nm-device-modem.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2021-02-03 15:25:56 +0100
committerThomas Haller <thaller@redhat.com>2021-02-04 09:45:55 +0100
commitac1a9e03e4d6674e1e60529b47b325a8f62e67b3 (patch)
treeef0445da3fd804e6cc5ee1e9c48a352dd348df1f /src/devices/wwan/nm-device-modem.c
parent97ed143e04e74323a59a0f24a965d36341233670 (diff)
downloadNetworkManager-ac1a9e03e4d6674e1e60529b47b325a8f62e67b3.tar.gz
all: move "src/" directory to "src/core/"
Currently "src/" mostly contains the source code of the daemon. I say mostly, because that is not true, there are also the device, settings, wwan, ppp plugins, the initrd generator, the pppd and dhcp helper, and probably more. Also we have source code under libnm-core/, libnm/, clients/, and shared/ directories. That is all confusing. We should have one "src" directory, that contains subdirectories. Those subdirectories should contain individual parts (libraries or applications), that possibly have dependencies on other subdirectories. There should be a flat hierarchy of directories under src/, which contains individual modules. As the name "src/" is already taken, that prevents any sensible restructuring of the code. As a first step, move "src/" to "src/core/". This gives space to reorganize the code better by moving individual components into "src/". For inspiration, look at systemd's "src/" directory. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/743
Diffstat (limited to 'src/devices/wwan/nm-device-modem.c')
-rw-r--r--src/devices/wwan/nm-device-modem.c957
1 files changed, 0 insertions, 957 deletions
diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
deleted file mode 100644
index a715cebb61..0000000000
--- a/src/devices/wwan/nm-device-modem.c
+++ /dev/null
@@ -1,957 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * 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"
-
-#define _NMLOG_DEVICE_TYPE NMDeviceModem
-#include "devices/nm-device-logging.h"
-
-/*****************************************************************************/
-
-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);
-}