/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2014 Red Hat, Inc. */ #include "src/core/nm-default-daemon.h" #include #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 "libnm-platform/nm-platform.h" /*****************************************************************************/ #define NM_TYPE_WWAN_FACTORY (nm_wwan_factory_get_type()) #define NM_WWAN_FACTORY(obj) \ (_NM_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 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; }