Last active
December 7, 2018 11:55
-
-
Save idfumg/4a7437be23a9699863536e86af46f6b5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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