Re: [PATCH v5 02/10] plugins/udevng: Add support for PCIe MBIM modems * Parses through the sysfs tree and detects MBIM control nodes, net and AT nodes
Andres Salomon <[email protected]> Fri, 28 Nov 2025 03:07:42 -0500
| Newsgroups | dev.linux.lists.ofono |
|---|---|
| Message-ID | <[email protected]> |
Hi Muhammad!
On 11/27/25 12:49, Muhammad Asif wrote:
> ---
> plugins/udevng.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 56 insertions(+)
>
> diff --git a/plugins/udevng.c b/plugins/udevng.c
> index 18954d44..bae0be76 100644
> --- a/plugins/udevng.c
> +++ b/plugins/udevng.c
> @@ -1186,7 +1186,13 @@ static gboolean setup_mbim(struct modem_info *modem)
> {
> const char *ctl = NULL, *net = NULL, *atcmd = NULL;
> GSList *list;
> + const char *sub_subsystem = NULL, *type = NULL;
> + char path[512], wwan_path[1024], sub_path[2048];
> char descriptors[PATH_MAX];
> + struct udev *new_udev;
> + struct udev_device *wwan_device, *sub_device;
> + struct dirent *dir = NULL, *subdir = NULL;
> + DIR *d = NULL, *sd = NULL;
>
> DBG("%s [%s:%s]", modem->syspath, modem->vendor, modem->model);
>
> @@ -1206,6 +1212,56 @@ static gboolean setup_mbim(struct modem_info *modem)
> else if (g_strcmp0(subsystem, "tty") == 0) {
> if (g_strcmp0(info->number, "02") == 0)
> atcmd = info->devnode;
> + } else if (g_strcmp0(subsystem, "pci") == 0) {
> + sprintf(path, "%s/wwan", udev_device_get_syspath(info->udev_device));
This about doubles the size of the function. I would suggest creating a
new function (with a comment!) for traversing the subdirectories.
My understanding of this function is that if your modem has a "pci"
directory, you're looking at pci/*/* where subsystem == wwan, and type
== MBIM or AT. But a comment would help example that.
> +
> + d = opendir(path);
> + if (!d)
> + return FALSE;
> +
> + new_udev = udev_new();
This can fail, and you should probably check for NULL here.
> +
> + while ((dir = readdir(d))) {
> + if (g_strcmp0(dir->d_name, ".") == 0 ||
> + g_strcmp0(dir->d_name, "..") == 0)
> + continue;
> +
Glib provides wrappers for walking a directory:
<https://docs.gtk.org/glib/file-utils.html>
I suggest using g_dir_open() and friends instead of readdir(), etc. For
example, g_dir_read_name skips over '.' and '..' already. You can see
usage of it in src/plugin.c.
In addition, you've got some buffers above that may or may not be okay
depending on what's in sysfs; I would assume you wouldn't normally hit
PATH_MAX and overflow the buffer, but it'd be safer to just allocate
memory using g_build_filename(), g_strconcat(), or similar.
> + sprintf(wwan_path, "%s/%s", path, dir->d_name);
> +> + wwan_device = udev_device_new_from_syspath(new_udev,
> + wwan_path);
This can also fail, and NULL should be checked for. Same issue below for
sub_device.
> + net = udev_device_get_sysname(wwan_device);
> +
> + /* Parse all the subdirectories now */
> + sd = opendir(wwan_path);
> + while ((subdir = readdir(sd))) {
> + if (subdir->d_type != DT_DIR)
> + continue;
> +
If you decide to use GDir, here you'd do something like:
sub_path = g_build_filename(wwan_path, subdir, NULL);
if (g_file_test(sub_path, G_FILE_TEST_IS_DIR)) {
g_free(sub_path);
continue;
}
> + if (g_strcmp0(subdir->d_name, ".") == 0 ||
> + g_strcmp0(subdir->d_name, "..") == 0)
> + continue;
> +
> + sprintf(sub_path, "%s/%s", wwan_path, subdir->d_name);
> +
> + sub_device = udev_device_new_from_syspath(new_udev,
> + sub_path);
> + sub_subsystem = udev_device_get_subsystem(sub_device);
> +
> + if (g_strcmp0(sub_subsystem, "wwan") == 0) {
> + type = udev_device_get_sysattr_value(sub_device, "type");
> +
> + if (g_strcmp0(type, "MBIM") == 0)
> + ctl = udev_device_get_devnode(sub_device);
> + else if (g_strcmp0(type, "AT") == 0)
> + atcmd = udev_device_get_devnode(sub_device);
> + }
sub_device should be udev_device_unref'd here, otherwise it's leaked.
> + }
> + closedir(sd);
wwan_device should be udev_device_unref'd here, as well.
> + break;
> + }
> + closedir(d);> + udev_unref(new_udev);
> }> }
>