summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-08-23 17:01:18 +0200
committerThomas Haller <thaller@redhat.com>2019-09-22 16:05:50 +0200
commit6d644c66a8baf0489188bcdd8137abcca79b0e1b (patch)
treea33a892376eeb11a2ad975ee8a3edcc479366cb4
parenteae69e33dd1865f24544c135b366eb343c5a46e6 (diff)
downloadNetworkManager-6d644c66a8baf0489188bcdd8137abcca79b0e1b.tar.gz
wwan: mark modems that are taken by a NMDevice as "claimed"
NMModem-s are either used by NMDeviceModem or by NMDeviceBt. The mechanism how that is coordinated it odd: - the factory emits component-added, and then NMDeviceBt might take the device (and claim it). In that case, component-added would return TRUE to indicate that the modem should not be also used by NMDeviceModem. - next, if the modem has a driver that looks like bluetooth, NMDeviceModem ignores it too. - finally, NMDeviceModem claims the modem (which is now considered to be non-bluetooth). I think the first problem is that the device factory tries to have this generic mechanism of "component-added". It's literally only used to cover this special case. Note that NMDeviceBt is aware of modems. So, abstracting this just adds lots of code that could be solved better by handling the case (of giving the modem to either NMDeviceBt or NMDeviceModem) specifically. NMWWanFactory itself registers to the NM_MODEM_MANAGER_MODEM_ADDED signal and emits nm_device_factory_emit_component_added(). We could just have NMWWanFactory and NMDeviceBt both register to that signal. Signals even support priorities, so we could have NMDeviceBt be called first to claim the device. Anyway, as the modem can only have one owner, the modem should have a flag that indicates whether it's claimed or not. That will allow multiple components all look at the same modem and moderate who is going to take ownership.
-rw-r--r--src/devices/bluetooth/nm-device-bt.c13
-rw-r--r--src/devices/wwan/libnm-wwan.ver5
-rw-r--r--src/devices/wwan/nm-device-modem.c4
-rw-r--r--src/devices/wwan/nm-modem.c49
-rw-r--r--src/devices/wwan/nm-modem.h4
-rw-r--r--src/devices/wwan/nm-wwan-factory.c7
6 files changed, 70 insertions, 12 deletions
diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c
index b8acc90577..1511f42188 100644
--- a/src/devices/bluetooth/nm-device-bt.c
+++ b/src/devices/bluetooth/nm-device-bt.c
@@ -577,7 +577,7 @@ modem_cleanup (NMDeviceBt *self)
if (priv->modem) {
g_signal_handlers_disconnect_matched (priv->modem, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
- g_clear_object (&priv->modem);
+ nm_clear_pointer (&priv->modem, nm_modem_unclaim);
}
}
@@ -646,6 +646,10 @@ component_added (NMDevice *device, GObject *component)
return FALSE;
modem = NM_MODEM (component);
+
+ if (nm_modem_is_claimed (modem))
+ return FALSE;
+
if (!priv->rfcomm_iface)
return FALSE;
@@ -675,12 +679,9 @@ component_added (NMDevice *device, GObject *component)
_LOGI (LOGD_BT | LOGD_MB,
"Activation: (bluetooth) Stage 2 of 5 (Device Configure) modem found.");
- if (priv->modem) {
- g_warn_if_reached ();
- modem_cleanup (self);
- }
+ modem_cleanup (self);
- priv->modem = g_object_ref (modem);
+ priv->modem = nm_modem_claim (modem);
g_signal_connect (modem, NM_MODEM_PPP_STATS, G_CALLBACK (ppp_stats), self);
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);
diff --git a/src/devices/wwan/libnm-wwan.ver b/src/devices/wwan/libnm-wwan.ver
index 7ccebcb5ee..b63a5066bc 100644
--- a/src/devices/wwan/libnm-wwan.ver
+++ b/src/devices/wwan/libnm-wwan.ver
@@ -3,6 +3,7 @@ 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;
@@ -14,14 +15,15 @@ global:
nm_modem_get_device_id;
nm_modem_get_driver;
nm_modem_get_iid;
- nm_modem_get_path;
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_type;
nm_modem_manager_name_owner_get;
@@ -32,6 +34,7 @@ global:
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/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
index 9a8faeff23..b380612f63 100644
--- a/src/devices/wwan/nm-device-modem.c
+++ b/src/devices/wwan/nm-device-modem.c
@@ -716,7 +716,7 @@ set_modem (NMDeviceModem *self, NMModem *modem)
g_return_if_fail (modem != NULL);
- priv->modem = g_object_ref (modem);
+ 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);
@@ -844,7 +844,7 @@ dispose (GObject *object)
if (priv->modem) {
g_signal_handlers_disconnect_by_data (priv->modem, NM_DEVICE_MODEM (object));
- g_clear_object (&priv->modem);
+ nm_clear_pointer (&priv->modem, nm_modem_unclaim);
}
g_clear_pointer (&priv->device_id, g_free);
diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c
index a21cebc350..e8109628b3 100644
--- a/src/devices/wwan/nm-modem.c
+++ b/src/devices/wwan/nm-modem.c
@@ -97,6 +97,8 @@ typedef struct _NMModemPrivate {
/* PPP stats */
guint32 in_bytes;
guint32 out_bytes;
+
+ bool claimed:1;
} NMModemPrivate;
G_DEFINE_TYPE (NMModem, nm_modem, G_TYPE_OBJECT)
@@ -174,6 +176,53 @@ nm_modem_state_to_string (NMModemState 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)
{
diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h
index c29630c025..5541c9363b 100644
--- a/src/devices/wwan/nm-modem.h
+++ b/src/devices/wwan/nm-modem.h
@@ -154,6 +154,10 @@ typedef struct {
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);
diff --git a/src/devices/wwan/nm-wwan-factory.c b/src/devices/wwan/nm-wwan-factory.c
index 59512cf38e..7a93b47c7b 100644
--- a/src/devices/wwan/nm-wwan-factory.c
+++ b/src/devices/wwan/nm-wwan-factory.c
@@ -64,13 +64,16 @@ modem_added_cb (NMModemManager *manager,
gpointer user_data)
{
NMWwanFactory *self = NM_WWAN_FACTORY (user_data);
- NMDevice *device;
+ gs_unref_object NMDevice *device = NULL;
const char *driver;
/* Do nothing if the modem was consumed by some other plugin */
if (nm_device_factory_emit_component_added (NM_DEVICE_FACTORY (self), G_OBJECT (modem)))
return;
+ 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
@@ -85,9 +88,7 @@ modem_added_cb (NMModemManager *manager,
/* Make the new modem device */
device = nm_device_modem_new (modem);
- g_assert (device);
g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device);
- g_object_unref (device);
}
static NMDevice *