|
|
334fdc |
From 3e76601295d8a43acb7c36e62e89fb7e9205f7f0 Mon Sep 17 00:00:00 2001
|
|
|
334fdc |
From: Lubomir Rintel <lkundrak@v3.sk>
|
|
|
334fdc |
Date: Wed, 1 Oct 2014 12:02:36 +0200
|
|
|
334fdc |
Subject: [PATCH 1/3] device: Keep track of devices as they are move across
|
|
|
334fdc |
sysfs
|
|
|
334fdc |
|
|
|
334fdc |
For certain devices the name changes with their status. Notably, RFCOMM
|
|
|
334fdc |
devices move from /devices/virtual/ to underneath the HCI that is used
|
|
|
334fdc |
for the connection as the session is estabilished, and return back when
|
|
|
334fdc |
it's torn down.
|
|
|
334fdc |
---
|
|
|
334fdc |
src/mm-device.c | 10 ++++++++++
|
|
|
334fdc |
1 file changed, 10 insertions(+)
|
|
|
334fdc |
|
|
|
334fdc |
diff --git a/src/mm-device.c b/src/mm-device.c
|
|
|
334fdc |
index 54f6456..46824ee 100644
|
|
|
334fdc |
--- a/src/mm-device.c
|
|
|
334fdc |
+++ b/src/mm-device.c
|
|
|
334fdc |
@@ -85,6 +85,11 @@ device_find_probe_with_device (MMDevice *self,
|
|
|
334fdc |
for (l = self->priv->port_probes; l; l = g_list_next (l)) {
|
|
|
334fdc |
MMPortProbe *probe = MM_PORT_PROBE (l->data);
|
|
|
334fdc |
|
|
|
334fdc |
+ if ( g_udev_device_has_property (udev_port, "DEVPATH_OLD")
|
|
|
334fdc |
+ && g_str_has_suffix (g_udev_device_get_sysfs_path (mm_port_probe_peek_port (probe)),
|
|
|
334fdc |
+ g_udev_device_get_property (udev_port, "DEVPATH_OLD")))
|
|
|
334fdc |
+ return probe;
|
|
|
334fdc |
+
|
|
|
334fdc |
if (g_str_equal (g_udev_device_get_sysfs_path (mm_port_probe_peek_port (probe)),
|
|
|
334fdc |
g_udev_device_get_sysfs_path (udev_port)))
|
|
|
334fdc |
return probe;
|
|
|
334fdc |
@@ -96,6 +101,11 @@ device_find_probe_with_device (MMDevice *self,
|
|
|
334fdc |
for (l = self->priv->ignored_port_probes; l; l = g_list_next (l)) {
|
|
|
334fdc |
MMPortProbe *probe = MM_PORT_PROBE (l->data);
|
|
|
334fdc |
|
|
|
334fdc |
+ if ( g_udev_device_has_property (udev_port, "DEVPATH_OLD")
|
|
|
334fdc |
+ && g_str_has_suffix (g_udev_device_get_sysfs_path (mm_port_probe_peek_port (probe)),
|
|
|
334fdc |
+ g_udev_device_get_property (udev_port, "DEVPATH_OLD")))
|
|
|
334fdc |
+ return probe;
|
|
|
334fdc |
+
|
|
|
334fdc |
if (g_str_equal (g_udev_device_get_sysfs_path (mm_port_probe_peek_port (probe)),
|
|
|
334fdc |
g_udev_device_get_sysfs_path (udev_port)))
|
|
|
334fdc |
return probe;
|
|
|
334fdc |
--
|
|
|
334fdc |
2.4.3
|
|
|
334fdc |
|
|
|
334fdc |
From c3ea9c4f6fecdd2363bdaeceb660e21c4139ab47 Mon Sep 17 00:00:00 2001
|
|
|
334fdc |
From: Lubomir Rintel <lkundrak@v3.sk>
|
|
|
334fdc |
Date: Wed, 1 Oct 2014 12:00:14 +0200
|
|
|
334fdc |
Subject: [PATCH 2/3] manager: Remove devices which are deemed unfit during
|
|
|
334fdc |
addition attempt
|
|
|
334fdc |
|
|
|
334fdc |
device_added() might be called in response to a "change" or "move" attempt that
|
|
|
334fdc |
might have changed a candidate device to a non-candidate one.
|
|
|
334fdc |
---
|
|
|
334fdc |
src/mm-manager.c | 118 +++++++++++++++++++++++++++++--------------------------
|
|
|
334fdc |
1 file changed, 62 insertions(+), 56 deletions(-)
|
|
|
334fdc |
|
|
|
334fdc |
diff --git a/src/mm-manager.c b/src/mm-manager.c
|
|
|
334fdc |
index 7103a00..73173e8 100644
|
|
|
334fdc |
--- a/src/mm-manager.c
|
|
|
334fdc |
+++ b/src/mm-manager.c
|
|
|
334fdc |
@@ -220,6 +220,61 @@ find_physical_device (GUdevDevice *child)
|
|
|
334fdc |
}
|
|
|
334fdc |
|
|
|
334fdc |
static void
|
|
|
334fdc |
+device_removed (MMManager *self,
|
|
|
334fdc |
+ GUdevDevice *udev_device)
|
|
|
334fdc |
+{
|
|
|
334fdc |
+ MMDevice *device;
|
|
|
334fdc |
+ const gchar *subsys;
|
|
|
334fdc |
+ const gchar *name;
|
|
|
334fdc |
+
|
|
|
334fdc |
+ g_return_if_fail (udev_device != NULL);
|
|
|
334fdc |
+
|
|
|
334fdc |
+ subsys = g_udev_device_get_subsystem (udev_device);
|
|
|
334fdc |
+ name = g_udev_device_get_name (udev_device);
|
|
|
334fdc |
+
|
|
|
334fdc |
+ if (!g_str_has_prefix (subsys, "usb") ||
|
|
|
334fdc |
+ (name && g_str_has_prefix (name, "cdc-wdm"))) {
|
|
|
334fdc |
+ /* Handle tty/net/wdm port removal */
|
|
|
334fdc |
+ device = find_device_by_port (self, udev_device);
|
|
|
334fdc |
+ if (device) {
|
|
|
334fdc |
+ mm_info ("(%s/%s): released by modem %s",
|
|
|
334fdc |
+ subsys,
|
|
|
334fdc |
+ name,
|
|
|
334fdc |
+ g_udev_device_get_sysfs_path (mm_device_peek_udev_device (device)));
|
|
|
334fdc |
+ mm_device_release_port (device, udev_device);
|
|
|
334fdc |
+
|
|
|
334fdc |
+ /* If port probe list gets empty, remove the device object iself */
|
|
|
334fdc |
+ if (!mm_device_peek_port_probe_list (device)) {
|
|
|
334fdc |
+ mm_dbg ("Removing empty device '%s'", mm_device_get_path (device));
|
|
|
334fdc |
+ mm_device_remove_modem (device);
|
|
|
334fdc |
+ g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
|
|
|
334fdc |
+ }
|
|
|
334fdc |
+ }
|
|
|
334fdc |
+
|
|
|
334fdc |
+ return;
|
|
|
334fdc |
+ }
|
|
|
334fdc |
+
|
|
|
334fdc |
+ /* This case is designed to handle the case where, at least with kernel 2.6.31, unplugging
|
|
|
334fdc |
+ * an in-use ttyACMx device results in udev generating remove events for the usb, but the
|
|
|
334fdc |
+ * ttyACMx device (subsystem tty) is not removed, since it was in-use. So if we have not
|
|
|
334fdc |
+ * found a modem for the port (above), we're going to look here to see if we have a modem
|
|
|
334fdc |
+ * associated with the newly removed device. If so, we'll remove the modem, since the
|
|
|
334fdc |
+ * device has been removed. That way, if the device is reinserted later, we'll go through
|
|
|
334fdc |
+ * the process of exporting it.
|
|
|
334fdc |
+ */
|
|
|
334fdc |
+ device = find_device_by_udev_device (self, udev_device);
|
|
|
334fdc |
+ if (device) {
|
|
|
334fdc |
+ mm_dbg ("Removing device '%s'", mm_device_get_path (device));
|
|
|
334fdc |
+ mm_device_remove_modem (device);
|
|
|
334fdc |
+ g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
|
|
|
334fdc |
+ return;
|
|
|
334fdc |
+ }
|
|
|
334fdc |
+
|
|
|
334fdc |
+ /* Maybe a plugin is checking whether or not the port is supported.
|
|
|
334fdc |
+ * TODO: Cancel every possible supports check in this port. */
|
|
|
334fdc |
+}
|
|
|
334fdc |
+
|
|
|
334fdc |
+static void
|
|
|
334fdc |
device_added (MMManager *manager,
|
|
|
334fdc |
GUdevDevice *port,
|
|
|
334fdc |
gboolean hotplugged,
|
|
|
334fdc |
@@ -247,8 +302,14 @@ device_added (MMManager *manager,
|
|
|
334fdc |
* rules have been processed before handling a device.
|
|
|
334fdc |
*/
|
|
|
334fdc |
is_candidate = g_udev_device_get_property_as_boolean (port, "ID_MM_CANDIDATE");
|
|
|
334fdc |
- if (!is_candidate)
|
|
|
334fdc |
+ if (!is_candidate) {
|
|
|
334fdc |
+ /* This could mean that device changed, loosing its ID_MM_CANDIDATE
|
|
|
334fdc |
+ * flags (such as Bluetooth RFCOMM devices upon disconnect.
|
|
|
334fdc |
+ * Try to forget it. */
|
|
|
334fdc |
+ if (hotplugged && !manual_scan)
|
|
|
334fdc |
+ device_removed (manager, port);
|
|
|
334fdc |
return;
|
|
|
334fdc |
+ }
|
|
|
334fdc |
|
|
|
334fdc |
if (find_device_by_port (manager, port))
|
|
|
334fdc |
return;
|
|
|
334fdc |
@@ -332,61 +393,6 @@ out:
|
|
|
334fdc |
}
|
|
|
334fdc |
|
|
|
334fdc |
static void
|
|
|
334fdc |
-device_removed (MMManager *self,
|
|
|
334fdc |
- GUdevDevice *udev_device)
|
|
|
334fdc |
-{
|
|
|
334fdc |
- MMDevice *device;
|
|
|
334fdc |
- const gchar *subsys;
|
|
|
334fdc |
- const gchar *name;
|
|
|
334fdc |
-
|
|
|
334fdc |
- g_return_if_fail (udev_device != NULL);
|
|
|
334fdc |
-
|
|
|
334fdc |
- subsys = g_udev_device_get_subsystem (udev_device);
|
|
|
334fdc |
- name = g_udev_device_get_name (udev_device);
|
|
|
334fdc |
-
|
|
|
334fdc |
- if (!g_str_has_prefix (subsys, "usb") ||
|
|
|
334fdc |
- (name && g_str_has_prefix (name, "cdc-wdm"))) {
|
|
|
334fdc |
- /* Handle tty/net/wdm port removal */
|
|
|
334fdc |
- device = find_device_by_port (self, udev_device);
|
|
|
334fdc |
- if (device) {
|
|
|
334fdc |
- mm_info ("(%s/%s): released by modem %s",
|
|
|
334fdc |
- subsys,
|
|
|
334fdc |
- name,
|
|
|
334fdc |
- g_udev_device_get_sysfs_path (mm_device_peek_udev_device (device)));
|
|
|
334fdc |
- mm_device_release_port (device, udev_device);
|
|
|
334fdc |
-
|
|
|
334fdc |
- /* If port probe list gets empty, remove the device object iself */
|
|
|
334fdc |
- if (!mm_device_peek_port_probe_list (device)) {
|
|
|
334fdc |
- mm_dbg ("Removing empty device '%s'", mm_device_get_path (device));
|
|
|
334fdc |
- mm_device_remove_modem (device);
|
|
|
334fdc |
- g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
|
|
|
334fdc |
- }
|
|
|
334fdc |
- }
|
|
|
334fdc |
-
|
|
|
334fdc |
- return;
|
|
|
334fdc |
- }
|
|
|
334fdc |
-
|
|
|
334fdc |
- /* This case is designed to handle the case where, at least with kernel 2.6.31, unplugging
|
|
|
334fdc |
- * an in-use ttyACMx device results in udev generating remove events for the usb, but the
|
|
|
334fdc |
- * ttyACMx device (subsystem tty) is not removed, since it was in-use. So if we have not
|
|
|
334fdc |
- * found a modem for the port (above), we're going to look here to see if we have a modem
|
|
|
334fdc |
- * associated with the newly removed device. If so, we'll remove the modem, since the
|
|
|
334fdc |
- * device has been removed. That way, if the device is reinserted later, we'll go through
|
|
|
334fdc |
- * the process of exporting it.
|
|
|
334fdc |
- */
|
|
|
334fdc |
- device = find_device_by_udev_device (self, udev_device);
|
|
|
334fdc |
- if (device) {
|
|
|
334fdc |
- mm_dbg ("Removing device '%s'", mm_device_get_path (device));
|
|
|
334fdc |
- mm_device_remove_modem (device);
|
|
|
334fdc |
- g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
|
|
|
334fdc |
- return;
|
|
|
334fdc |
- }
|
|
|
334fdc |
-
|
|
|
334fdc |
- /* Maybe a plugin is checking whether or not the port is supported.
|
|
|
334fdc |
- * TODO: Cancel every possible supports check in this port. */
|
|
|
334fdc |
-}
|
|
|
334fdc |
-
|
|
|
334fdc |
-static void
|
|
|
334fdc |
handle_uevent (GUdevClient *client,
|
|
|
334fdc |
const char *action,
|
|
|
334fdc |
GUdevDevice *device,
|
|
|
334fdc |
--
|
|
|
334fdc |
2.4.3
|
|
|
334fdc |
|
|
|
334fdc |
From 71665f3a81000db156b72d135cffc0c9355d12df Mon Sep 17 00:00:00 2001
|
|
|
334fdc |
From: Lubomir Rintel <lkundrak@v3.sk>
|
|
|
334fdc |
Date: Wed, 1 Oct 2014 12:00:14 +0200
|
|
|
334fdc |
Subject: [PATCH 3/3] udev: Don't mark disconnected RFCOMM ttys as candidates
|
|
|
334fdc |
|
|
|
334fdc |
Bluetooth serial devices are weird. They begin life being bound with
|
|
|
334fdc |
RFCOMMCREATEDEV ioctl() and then move around the sysfs tree when they are
|
|
|
334fdc |
connected and disconnected. The connection is estabilished upon the first
|
|
|
334fdc |
open() and torn down upon last close(), their first user virtually being
|
|
|
334fdc |
"owner" of the connection. We don't want to be that process, we're only
|
|
|
334fdc |
interested in actually connected modems. However, currently we have no
|
|
|
334fdc |
knowledge of that and therefore we connect and disconnect multiple times while
|
|
|
334fdc |
probing.
|
|
|
334fdc |
|
|
|
334fdc |
This patch marks unconnected RFCOMM devices as uninteresting to us.
|
|
|
334fdc |
The actual connection and disconnection will be handled by NetworkManager.
|
|
|
334fdc |
---
|
|
|
334fdc |
src/80-mm-candidate.rules | 4 ++++
|
|
|
334fdc |
1 file changed, 4 insertions(+)
|
|
|
334fdc |
|
|
|
334fdc |
diff --git a/src/80-mm-candidate.rules b/src/80-mm-candidate.rules
|
|
|
334fdc |
index 2e938d7..52e6882 100644
|
|
|
334fdc |
--- a/src/80-mm-candidate.rules
|
|
|
334fdc |
+++ b/src/80-mm-candidate.rules
|
|
|
334fdc |
@@ -9,6 +9,10 @@
|
|
|
334fdc |
|
|
|
334fdc |
ACTION!="add|change|move", GOTO="mm_candidate_end"
|
|
|
334fdc |
|
|
|
334fdc |
+# Opening bound but disconnected Bluetooth RFCOMM ttys would initiate the
|
|
|
334fdc |
+# connection. Don't do that.
|
|
|
334fdc |
+KERNEL=="rfcomm[0-9]*", DEVPATH=="*/virtual/*", GOTO="mm_candidate_end"
|
|
|
334fdc |
+
|
|
|
334fdc |
SUBSYSTEM=="tty", ENV{ID_MM_CANDIDATE}="1"
|
|
|
334fdc |
SUBSYSTEM=="net", ENV{ID_MM_CANDIDATE}="1"
|
|
|
334fdc |
KERNEL=="cdc-wdm*", SUBSYSTEM=="usb", ENV{ID_MM_CANDIDATE}="1"
|
|
|
334fdc |
--
|
|
|
334fdc |
2.4.3
|
|
|
334fdc |
|