Sometimes, Udev device 'remove' event could not report correct parent
node of current udev_device. Current code replies on the devpath
attached on the parent node to find modem and then remove it.
This fix is to change the way to store the devpath info into a
hashtable. So that we search hashtable to get devpath and remove the
modem.
---
plugins/udev.c | 58 +++++++++++++++++++++++++++++++++++++------------------
1 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/plugins/udev.c b/plugins/udev.c
index 4aaeeb9..3a6ea28 100644
--- a/plugins/udev.c
+++ b/plugins/udev.c
@@ -36,6 +36,7 @@
#include <ofono/log.h>
static GSList *modem_list = NULL;
+static GHashTable *devpath_list = NULL;
static struct ofono_modem *find_modem(const char *devpath)
{
@@ -259,7 +260,7 @@ static void add_modem(struct udev_device *udev_device)
{
struct ofono_modem *modem;
struct udev_device *parent;
- const char *devpath, *driver;
+ const char *devpath, *curpath, *driver;
parent = udev_device_get_parent(udev_device);
if (parent == NULL)
@@ -295,6 +296,12 @@ static void add_modem(struct udev_device *udev_device)
modem_list = g_slist_prepend(modem_list, modem);
}
+ curpath = udev_device_get_devpath(udev_device);
+ if (curpath == NULL)
+ return;
+
+ g_hash_table_insert(devpath_list, g_strdup(curpath), g_strdup(devpath));
+
if (g_strcmp0(driver, "mbm") == 0)
add_mbm(modem, udev_device);
else if (g_strcmp0(driver, "hso") == 0)
@@ -307,30 +314,25 @@ static void add_modem(struct udev_device *udev_device)
add_novatel(modem, udev_device);
}
+static gboolean devpath_remove(gpointer key, gpointer value, gpointer user_data)
+{
+ const char *path = value;
+ const char *devpath = user_data;
+
+ return g_str_equal(path, devpath);
+}
+
static void remove_modem(struct udev_device *udev_device)
{
struct ofono_modem *modem;
- struct udev_device *parent;
- const char *devpath, *driver = NULL;
+ const char *curpath = udev_device_get_devpath(udev_device);
+ char *devpath, *remove;
- parent = udev_device_get_parent(udev_device);
- if (parent == NULL)
+ if (curpath == NULL)
return;
- driver = get_driver(parent);
- if (driver == NULL) {
- parent = udev_device_get_parent(parent);
- driver = get_driver(parent);
- if (driver == NULL) {
- parent = udev_device_get_parent(parent);
- driver = get_driver(parent);
- if (driver == NULL)
- return;
- }
- }
-
- devpath = udev_device_get_devpath(parent);
- if (devpath == NULL)
+ devpath = g_hash_table_lookup(devpath_list, curpath);
+ if (!devpath)
return;
modem = find_modem(devpath);
@@ -340,6 +342,12 @@ static void remove_modem(struct udev_device *udev_device)
modem_list = g_slist_remove(modem_list, modem);
ofono_modem_remove(modem);
+
+ remove = g_strdup(devpath);
+
+ g_hash_table_foreach_remove(devpath_list, devpath_remove, remove);
+
+ g_free(remove);
}
static void enumerate_devices(struct udev *context)
@@ -444,15 +452,24 @@ static void udev_start(void)
static int udev_init(void)
{
+ devpath_list = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, g_free);
+ if (!devpath_list) {
+ ofono_error("Failed to create udev path list");
+ return -ENOMEM;
+ }
+
udev_ctx = udev_new();
if (udev_ctx == NULL) {
ofono_error("Failed to create udev context");
+ g_hash_table_destroy(devpath_list);
return -EIO;
}
udev_mon = udev_monitor_new_from_netlink(udev_ctx, "udev");
if (udev_mon == NULL) {
ofono_error("Failed to create udev monitor");
+ g_hash_table_destroy(devpath_list);
udev_unref(udev_ctx);
udev_ctx = NULL;
return -EIO;
@@ -484,6 +501,9 @@ static void udev_exit(void)
g_slist_free(modem_list);
modem_list = NULL;
+ g_hash_table_destroy(devpath_list);
+ devpath_list = NULL;
+
if (udev_ctx == NULL)
return;
--
1.6.3.3
Show replies by date
This fix is for Meego bug #389. Dell 5530 modem reports 'ERROR' when
'AT+CGATT=0'. In the error case, we need to wait until the context
deactivation returns and then check netreg status. If status is zero,
we update driver_attached to FALSE.
---
src/gprs.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/src/gprs.c b/src/gprs.c
index dfb6d16..8e065d2 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -1325,6 +1325,14 @@ void ofono_gprs_status_notify(struct ofono_gprs *gprs, int status)
if (gprs->driver_attached == FALSE)
return;
+ /* Dell 5530 reports 'ERROR' when we try to detach by 'AT+CGATT=0'
+ * immediately after deactivating the context. So we wait until
+ * the context deactivation returns and then set driver_attached to
+ * FALSE when the netreg status is not registered & not searching
+ */
+ if (status == NETWORK_REGISTRATION_STATUS_NOT_REGISTERED)
+ gprs->driver_attached = FALSE;
+
gprs->status = status;
gprs_attached_update(gprs);
}
--
1.6.3.3
Hi Zhenhua,
Sometimes, Udev device 'remove' event could not report
correct parent
node of current udev_device. Current code replies on the devpath
attached on the parent node to find modem and then remove it.
This fix is to change the way to store the devpath info into a
hashtable. So that we search hashtable to get devpath and remove the
modem.
Patch has been applied, thanks.
Regards,
-Denis