Skip to content

Instantly share code, notes, and snippets.

@idfumg
Last active December 7, 2018 11:55
Show Gist options
  • Save idfumg/4a7437be23a9699863536e86af46f6b5 to your computer and use it in GitHub Desktop.
Save idfumg/4a7437be23a9699863536e86af46f6b5 to your computer and use it in GitHub Desktop.
#include <cstdio>
#include <cstdlib>
#include <sys/epoll.h>
#include <libudev.h>
#include <string.h>
enum class DeviceAction : std::size_t {
Added = 0,
Removed
};
int main() {
std::printf("Monitoring usb devices...\n");
udev* const udev = udev_new();
udev_monitor* const udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device");
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL);
udev_monitor_set_receive_buffer_size(udev_monitor, 128*1024*1024);
const int fd = udev_monitor_get_fd(udev_monitor);
if (fd < 0) {
std::printf("Error! Can't get udev monitor fd\n");
return 1;
}
const int fd_epoll = epoll_create1(EPOLL_CLOEXEC);
if (fd_epoll < 0) {
std::printf("Error! Can't get epoll fd\n");
return 1;
}
udev_monitor_enable_receiving(udev_monitor);
struct epoll_event ep_udev = {};
ep_udev.events = EPOLLIN;
ep_udev.data.fd = fd;
const int ret = epoll_ctl(fd_epoll, EPOLL_CTL_ADD, fd, &ep_udev);
if (ret < 0) {
return 1;
}
while (true) {
struct epoll_event ev;
const int fdcount = epoll_wait(fd_epoll, &ev, 1, -1);
if (fdcount <= 0) {
continue;
}
struct udev_device* const device = udev_monitor_receive_device(udev_monitor);
if (!device) {
continue;
}
const char* const deviceType = udev_device_get_devtype(device);
if (!deviceType || strcmp(deviceType, "usb_device") != 0) {
udev_device_unref(device);
continue;
}
const char* const deviceActionString = udev_device_get_action(device);
if (!deviceActionString) {
udev_device_unref(device);
continue;
}
std::printf("Node: %s\n", udev_device_get_devnode(device));
std::printf("Subsystem: %s\n", udev_device_get_subsystem(device));
std::printf("Devtype: %s\n", udev_device_get_devtype(device));
std::printf("Action: %s\n", udev_device_get_action(device));
std::printf("Devname: %s\n", udev_device_get_sysname(device));
std::printf("Devpath: %s\n", udev_device_get_devpath(device));
std::printf("Macaddr: %s\n", udev_device_get_sysattr_value(device, "address"));
const char* const deviceVendorIdString = udev_device_get_sysattr_value(device,"idVendor");
if (!deviceVendorIdString) {
udev_device_unref(device);
continue;
}
const char* const deviceProductIdString = udev_device_get_sysattr_value(device,"idProduct");
if (!deviceProductIdString) {
udev_device_unref(device);
continue;
}
const auto deviceVendorId = std::strtol(deviceVendorIdString, NULL, 16);
const auto deviceProductId = std::strtol(deviceProductIdString, NULL, 16);
const auto deviceAction = strcmp(deviceActionString, "add") == 0 ? DeviceAction::Added : DeviceAction::Removed;
std::printf("VendorId: %ld\n", deviceVendorId);
std::printf("ProductId: %ld\n", deviceProductId);
std::printf("deviceAction: %lu\n", static_cast<std::size_t>(deviceAction));
std::printf("\n");
udev_device_unref(device);
}
udev_monitor_unref(udev_monitor);
udev_unref(udev);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment