diff --git a/SOURCES/rh1200958-fix-MODEM_STATE_IS_INTERMEDIATE-macro.patch b/SOURCES/rh1200958-fix-MODEM_STATE_IS_INTERMEDIATE-macro.patch new file mode 100644 index 0000000..a1d0d0c --- /dev/null +++ b/SOURCES/rh1200958-fix-MODEM_STATE_IS_INTERMEDIATE-macro.patch @@ -0,0 +1,39 @@ +From aa74ea1aa64470b2b4ec76dbc707f30fc22e3f83 Mon Sep 17 00:00:00 2001 +From: Ben Chan +Date: Tue, 17 Sep 2013 14:47:09 -0700 +Subject: [PATCH] iface-modem: fix MODEM_STATE_IS_INTERMEDIATE macro +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiří Klimeš +--- + src/mm-iface-modem.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c +index 748a720..02b03db 100644 +--- a/src/mm-iface-modem.c ++++ b/src/mm-iface-modem.c +@@ -80,12 +80,12 @@ mm_iface_modem_bind_simple_status (MMIfaceModem *self, + /*****************************************************************************/ + /* Helper method to wait for a final state */ + +-#define MODEM_STATE_IS_INTERMEDIATE(state) \ +- (state == MM_MODEM_STATE_INITIALIZING || \ +- state == MM_MODEM_STATE_INITIALIZING || \ +- state == MM_MODEM_STATE_INITIALIZING || \ +- state == MM_MODEM_STATE_INITIALIZING || \ +- state == MM_MODEM_STATE_INITIALIZING) ++#define MODEM_STATE_IS_INTERMEDIATE(state) \ ++ (state == MM_MODEM_STATE_INITIALIZING || \ ++ state == MM_MODEM_STATE_DISABLING || \ ++ state == MM_MODEM_STATE_ENABLING || \ ++ state == MM_MODEM_STATE_DISCONNECTING || \ ++ state == MM_MODEM_STATE_CONNECTING) + + typedef struct { + MMIfaceModem *self; +-- +2.1.0 + diff --git a/SOURCES/rh1251954-ignore-unconnected-rfcomm.patch b/SOURCES/rh1251954-ignore-unconnected-rfcomm.patch new file mode 100644 index 0000000..7b189ed --- /dev/null +++ b/SOURCES/rh1251954-ignore-unconnected-rfcomm.patch @@ -0,0 +1,242 @@ +From 3e76601295d8a43acb7c36e62e89fb7e9205f7f0 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Wed, 1 Oct 2014 12:02:36 +0200 +Subject: [PATCH 1/3] device: Keep track of devices as they are move across + sysfs + +For certain devices the name changes with their status. Notably, RFCOMM +devices move from /devices/virtual/ to underneath the HCI that is used +for the connection as the session is estabilished, and return back when +it's torn down. +--- + src/mm-device.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/mm-device.c b/src/mm-device.c +index 54f6456..46824ee 100644 +--- a/src/mm-device.c ++++ b/src/mm-device.c +@@ -85,6 +85,11 @@ device_find_probe_with_device (MMDevice *self, + for (l = self->priv->port_probes; l; l = g_list_next (l)) { + MMPortProbe *probe = MM_PORT_PROBE (l->data); + ++ if ( g_udev_device_has_property (udev_port, "DEVPATH_OLD") ++ && g_str_has_suffix (g_udev_device_get_sysfs_path (mm_port_probe_peek_port (probe)), ++ g_udev_device_get_property (udev_port, "DEVPATH_OLD"))) ++ return probe; ++ + if (g_str_equal (g_udev_device_get_sysfs_path (mm_port_probe_peek_port (probe)), + g_udev_device_get_sysfs_path (udev_port))) + return probe; +@@ -96,6 +101,11 @@ device_find_probe_with_device (MMDevice *self, + for (l = self->priv->ignored_port_probes; l; l = g_list_next (l)) { + MMPortProbe *probe = MM_PORT_PROBE (l->data); + ++ if ( g_udev_device_has_property (udev_port, "DEVPATH_OLD") ++ && g_str_has_suffix (g_udev_device_get_sysfs_path (mm_port_probe_peek_port (probe)), ++ g_udev_device_get_property (udev_port, "DEVPATH_OLD"))) ++ return probe; ++ + if (g_str_equal (g_udev_device_get_sysfs_path (mm_port_probe_peek_port (probe)), + g_udev_device_get_sysfs_path (udev_port))) + return probe; +-- +2.4.3 + +From c3ea9c4f6fecdd2363bdaeceb660e21c4139ab47 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Wed, 1 Oct 2014 12:00:14 +0200 +Subject: [PATCH 2/3] manager: Remove devices which are deemed unfit during + addition attempt + +device_added() might be called in response to a "change" or "move" attempt that +might have changed a candidate device to a non-candidate one. +--- + src/mm-manager.c | 118 +++++++++++++++++++++++++++++-------------------------- + 1 file changed, 62 insertions(+), 56 deletions(-) + +diff --git a/src/mm-manager.c b/src/mm-manager.c +index 7103a00..73173e8 100644 +--- a/src/mm-manager.c ++++ b/src/mm-manager.c +@@ -220,6 +220,61 @@ find_physical_device (GUdevDevice *child) + } + + static void ++device_removed (MMManager *self, ++ GUdevDevice *udev_device) ++{ ++ MMDevice *device; ++ const gchar *subsys; ++ const gchar *name; ++ ++ g_return_if_fail (udev_device != NULL); ++ ++ subsys = g_udev_device_get_subsystem (udev_device); ++ name = g_udev_device_get_name (udev_device); ++ ++ if (!g_str_has_prefix (subsys, "usb") || ++ (name && g_str_has_prefix (name, "cdc-wdm"))) { ++ /* Handle tty/net/wdm port removal */ ++ device = find_device_by_port (self, udev_device); ++ if (device) { ++ mm_info ("(%s/%s): released by modem %s", ++ subsys, ++ name, ++ g_udev_device_get_sysfs_path (mm_device_peek_udev_device (device))); ++ mm_device_release_port (device, udev_device); ++ ++ /* If port probe list gets empty, remove the device object iself */ ++ if (!mm_device_peek_port_probe_list (device)) { ++ mm_dbg ("Removing empty device '%s'", mm_device_get_path (device)); ++ mm_device_remove_modem (device); ++ g_hash_table_remove (self->priv->devices, mm_device_get_path (device)); ++ } ++ } ++ ++ return; ++ } ++ ++ /* This case is designed to handle the case where, at least with kernel 2.6.31, unplugging ++ * an in-use ttyACMx device results in udev generating remove events for the usb, but the ++ * ttyACMx device (subsystem tty) is not removed, since it was in-use. So if we have not ++ * found a modem for the port (above), we're going to look here to see if we have a modem ++ * associated with the newly removed device. If so, we'll remove the modem, since the ++ * device has been removed. That way, if the device is reinserted later, we'll go through ++ * the process of exporting it. ++ */ ++ device = find_device_by_udev_device (self, udev_device); ++ if (device) { ++ mm_dbg ("Removing device '%s'", mm_device_get_path (device)); ++ mm_device_remove_modem (device); ++ g_hash_table_remove (self->priv->devices, mm_device_get_path (device)); ++ return; ++ } ++ ++ /* Maybe a plugin is checking whether or not the port is supported. ++ * TODO: Cancel every possible supports check in this port. */ ++} ++ ++static void + device_added (MMManager *manager, + GUdevDevice *port, + gboolean hotplugged, +@@ -247,8 +302,14 @@ device_added (MMManager *manager, + * rules have been processed before handling a device. + */ + is_candidate = g_udev_device_get_property_as_boolean (port, "ID_MM_CANDIDATE"); +- if (!is_candidate) ++ if (!is_candidate) { ++ /* This could mean that device changed, loosing its ID_MM_CANDIDATE ++ * flags (such as Bluetooth RFCOMM devices upon disconnect. ++ * Try to forget it. */ ++ if (hotplugged && !manual_scan) ++ device_removed (manager, port); + return; ++ } + + if (find_device_by_port (manager, port)) + return; +@@ -332,61 +393,6 @@ out: + } + + static void +-device_removed (MMManager *self, +- GUdevDevice *udev_device) +-{ +- MMDevice *device; +- const gchar *subsys; +- const gchar *name; +- +- g_return_if_fail (udev_device != NULL); +- +- subsys = g_udev_device_get_subsystem (udev_device); +- name = g_udev_device_get_name (udev_device); +- +- if (!g_str_has_prefix (subsys, "usb") || +- (name && g_str_has_prefix (name, "cdc-wdm"))) { +- /* Handle tty/net/wdm port removal */ +- device = find_device_by_port (self, udev_device); +- if (device) { +- mm_info ("(%s/%s): released by modem %s", +- subsys, +- name, +- g_udev_device_get_sysfs_path (mm_device_peek_udev_device (device))); +- mm_device_release_port (device, udev_device); +- +- /* If port probe list gets empty, remove the device object iself */ +- if (!mm_device_peek_port_probe_list (device)) { +- mm_dbg ("Removing empty device '%s'", mm_device_get_path (device)); +- mm_device_remove_modem (device); +- g_hash_table_remove (self->priv->devices, mm_device_get_path (device)); +- } +- } +- +- return; +- } +- +- /* This case is designed to handle the case where, at least with kernel 2.6.31, unplugging +- * an in-use ttyACMx device results in udev generating remove events for the usb, but the +- * ttyACMx device (subsystem tty) is not removed, since it was in-use. So if we have not +- * found a modem for the port (above), we're going to look here to see if we have a modem +- * associated with the newly removed device. If so, we'll remove the modem, since the +- * device has been removed. That way, if the device is reinserted later, we'll go through +- * the process of exporting it. +- */ +- device = find_device_by_udev_device (self, udev_device); +- if (device) { +- mm_dbg ("Removing device '%s'", mm_device_get_path (device)); +- mm_device_remove_modem (device); +- g_hash_table_remove (self->priv->devices, mm_device_get_path (device)); +- return; +- } +- +- /* Maybe a plugin is checking whether or not the port is supported. +- * TODO: Cancel every possible supports check in this port. */ +-} +- +-static void + handle_uevent (GUdevClient *client, + const char *action, + GUdevDevice *device, +-- +2.4.3 + +From 71665f3a81000db156b72d135cffc0c9355d12df Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Wed, 1 Oct 2014 12:00:14 +0200 +Subject: [PATCH 3/3] udev: Don't mark disconnected RFCOMM ttys as candidates + +Bluetooth serial devices are weird. They begin life being bound with +RFCOMMCREATEDEV ioctl() and then move around the sysfs tree when they are +connected and disconnected. The connection is estabilished upon the first +open() and torn down upon last close(), their first user virtually being +"owner" of the connection. We don't want to be that process, we're only +interested in actually connected modems. However, currently we have no +knowledge of that and therefore we connect and disconnect multiple times while +probing. + +This patch marks unconnected RFCOMM devices as uninteresting to us. +The actual connection and disconnection will be handled by NetworkManager. +--- + src/80-mm-candidate.rules | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/80-mm-candidate.rules b/src/80-mm-candidate.rules +index 2e938d7..52e6882 100644 +--- a/src/80-mm-candidate.rules ++++ b/src/80-mm-candidate.rules +@@ -9,6 +9,10 @@ + + ACTION!="add|change|move", GOTO="mm_candidate_end" + ++# Opening bound but disconnected Bluetooth RFCOMM ttys would initiate the ++# connection. Don't do that. ++KERNEL=="rfcomm[0-9]*", DEVPATH=="*/virtual/*", GOTO="mm_candidate_end" ++ + SUBSYSTEM=="tty", ENV{ID_MM_CANDIDATE}="1" + SUBSYSTEM=="net", ENV{ID_MM_CANDIDATE}="1" + KERNEL=="cdc-wdm*", SUBSYSTEM=="usb", ENV{ID_MM_CANDIDATE}="1" +-- +2.4.3 + diff --git a/SPECS/ModemManager.spec b/SPECS/ModemManager.spec index 2f424a9..b9a6d9e 100644 --- a/SPECS/ModemManager.spec +++ b/SPECS/ModemManager.spec @@ -7,7 +7,7 @@ Summary: Mobile broadband modem management service Name: ModemManager Version: 1.1.0 -Release: 6%{snapshot}%{?dist} +Release: 8%{snapshot}%{?dist} # # Source from git://anongit.freedesktop.org/ModemManager/ModemManager # tarball built with: @@ -33,6 +33,8 @@ BuildRequires: gobject-introspection-devel >= 0.10.3 BuildRequires: vala-tools vala-devel Patch0: buildsys-hates-openpty.patch +Patch1: rh1200958-fix-MODEM_STATE_IS_INTERMEDIATE-macro.patch +Patch2: rh1251954-ignore-unconnected-rfcomm.patch %description The ModemManager service manages WWAN modems and provides a consistent API for @@ -81,6 +83,8 @@ Vala bindings for ModemManager %prep %setup -q %patch0 -p1 -b .pty +%patch1 -p1 -b .rh1200958-fix-MODEM_STATE_IS_INTERMEDIATE-macro +%patch2 -p1 -b .rh1251954-ignore-unconnected-rfcomm %build @@ -165,6 +169,12 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %{_datadir}/vala/vapi/libmm-glib.* %changelog +* Thu Aug 13 2015 Lubomir Rintel - 1.1.0-8.git20130913 +- rfcomm: don't open the ttys until NetworkManager connects them (rh #1251954) + +* Thu Jul 9 2015 Jiří Klimeš - 1.1.0-7.git20130913 +- iface-modem: fix MODEM_STATE_IS_INTERMEDIATE macro (rh #1200958) + * Wed Mar 12 2014 Dan Williams - 1.1.0-6.git20130913 - Fix hardened build (rh #1065046)