Найти номер шины и номер устройства с помощью символической ссылки на файл устройства

У меня есть файл устройства (SYMLINK) /dev/CDMAModem генерируется udev править. Я хочу найти номер шины и номер фактического устройства. На самом деле я хочу выполнить USBDEVFS_RESET ioctl на устройстве /dev/bus/usb/BUS_NO/DEVICE_NO в моей C ++ программе.

—-Правило Удев —-

SUBSYSTEMS=="usb", ACTION=="add", DRIVERS=="zte_ev", ATTRS{bNumEndpoints}=="03", SYMLINK+="CDMAModem"SUBSYSTEMS=="usb", ACTION=="remove", DRIVERS=="zte_ev", ATTRS{bNumEndpoints}=="03", SYMLINK-="CDMAModem"

4

Решение

Я думаю, что libudev даст вам это:

#include <libudev.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>

int main(int argc, char **argv)
{

struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *dev_list_entry;
struct udev_device *dev;

udev = udev_new();

enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, "CDMAModem");
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);

udev_list_entry_foreach(dev_list_entry, devices) {
const char *path;

path = udev_list_entry_get_name(dev_list_entry);
dev = udev_device_new_from_syspath(udev, path);

fprintf(stderr, "devnum: %s\n",
udev_device_get_sysattr_value(dev, "devnum"));
fprintf(stderr, "busnum: %s\n",
udev_device_get_sysattr_value(dev, 'busnum:));
udev_device_unref(dev);
}

udev_enumerate_unref(enumerate);
udev_unref(udev);

return 0;
}

Затем вы можете использовать эту информацию с ioctl (), как в:

[charles@localhost 2-1]$ cd /sys/class/mem/random
[charles@localhost 2-1]$echo $PWD
/sys/devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb2/2-1
4

Другие решения

Вы можете выполнить ioctl в файле, представленном символической ссылкой /dev/CDMAModem как и в файле под /dev/bus/ состав.

#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>

int f = open("/dev/CDMAModem", O_RDWR);
ioctl(f, USBDEVFS_RESET);

Если вы действительно хотите найти, куда указывает эта ссылка, file Команда скажет вам.

> file /dev/CDMAModem
/dev/CDMAModem: symbolic link to `bus/usb/BUS/DEV'
2

я думаю stat() библиотечный вызов был бы хорошим местом для начала … Наряду с libusb.

1

Если все, что вы хотите сделать, это разрешить ссылку, вы можете использовать readlink и проанализировать информацию позже с помощью строковых функций.

Функция: ssize_t readlink (const char * имя файла, char * буфер, размер size_t)

Функция readlink получает значение имени файла символьной ссылки. Имя файла, на которое указывает ссылка, копируется в буфер. Эта строка имени файла не заканчивается нулем; readlink обычно возвращает количество скопированных символов. Аргумент size указывает максимальное количество копируемых символов, обычно размер буфера.

1
~$ sudo udevadm info -a -p $(sudo udevadm info -q path -n /dev/CDMAModem)
[sudo] password for gowtham:

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/ttyUSB0/tty/ttyUSB0':
KERNEL=="ttyUSB0"SUBSYSTEM=="tty"DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/ttyUSB0':
KERNELS=="ttyUSB0"SUBSYSTEMS=="usb-serial"DRIVERS=="zte_ev"ATTRS{port_number}=="0"
looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0':
KERNELS=="2-1.2:1.0"SUBSYSTEMS=="usb"DRIVERS=="zte_ev"ATTRS{bInterfaceClass}=="ff"ATTRS{bInterfaceSubClass}=="ff"ATTRS{bInterfaceProtocol}=="ff"ATTRS{bNumEndpoints}=="03"ATTRS{supports_autosuspend}=="1"ATTRS{bAlternateSetting}==" 0"ATTRS{bInterfaceNumber}=="00"ATTRS{interface}=="Data Interface"
looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2':
KERNELS=="2-1.2"SUBSYSTEMS=="usb"DRIVERS=="usb"ATTRS{bDeviceSubClass}=="00"ATTRS{bDeviceProtocol}=="00"ATTRS{devpath}=="1.2"ATTRS{idVendor}=="19d2"ATTRS{speed}=="12"ATTRS{bNumInterfaces}==" 6"ATTRS{bConfigurationValue}=="1"ATTRS{bMaxPacketSize0}=="64"ATTRS{busnum}=="2"ATTRS{devnum}=="8"
  ATTRS{busnum}=="2"ATTRS{devnum}=="8"

Хотя это некрасиво, но работает. Из вызова программы C ++ udevadm и фильтр для busnum а также devnum атрибуты из вывода. Я надеюсь, что некоторые разработчики, которые участвуют в libudev развитие должно помочь и может быть udev рассылка поможет.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector