diff --git a/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid.h b/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid.h index eda529246..03a66abf2 100644 --- a/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid.h +++ b/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid.h @@ -98,6 +98,7 @@ struct USBPortInfo { QString friendName; ///< Friendly name. QString physName; QString enumName; ///< It seems its the only one with meaning + QString serialNumber; // As a string as it can be anything, really... int vendorID; ///< Vendor ID. int productID; ///< Product ID }; diff --git a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor.h b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor.h index 9d8b2fe64..e740d3cfa 100644 --- a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor.h +++ b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor.h @@ -72,6 +72,8 @@ public: USBMonitor(QObject *parent = 0); // USBMonitor(int vid, int pid); ~USBMonitor(); + QList availableDevices(); + QList availableDevices(int vid, int pid, int bcdDevice); signals: /*! @@ -109,6 +111,7 @@ private: struct udev *context; struct udev_monitor *monitor; QSocketNotifier *monitorNotifier; + USBPortInfo makePortInfo(struct udev_device *dev); #elif defined (Q_OS_WIN32) //TODO #endif diff --git a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_linux.cpp b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_linux.cpp index 310b91044..ae585042a 100644 --- a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_linux.cpp +++ b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_linux.cpp @@ -43,10 +43,14 @@ void USBMonitor::deviceEventReceived() { dev = udev_monitor_receive_device(this->monitor); if (dev) { printf("Got Device"); - printf(" Node: %s", udev_device_get_devnode(dev)); - printf(" Subsystem: %s", udev_device_get_subsystem(dev)); - printf(" Devtype: %s", udev_device_get_devtype(dev)); - printf(" Action: %s", udev_device_get_action(dev)); + QString action = QString(udev_device_get_action(dev)); + if (action == "add") { + emit deviceDiscovered(makePortInfo(dev)); + + } else if (action == "remove"){ + emit deviceRemoved(makePortInfo(dev)); + } + udev_device_unref(dev); } else { @@ -55,7 +59,9 @@ void USBMonitor::deviceEventReceived() { } - +/** + Initialize the udev monitor here + */ USBMonitor::USBMonitor(QObject *parent): QThread(parent) { this->context = udev_new(); @@ -77,3 +83,99 @@ USBMonitor::~USBMonitor() { quit(); } + +/** +Returns a list of all currently available devices +*/ +QList USBMonitor::availableDevices() +{ + QList devicesList; + struct udev_list_entry *devices, *dev_list_entry; + struct udev_enumerate *enumerate; + struct udev_device *dev; + + enumerate = udev_enumerate_new(this->context); + udev_enumerate_add_match_subsystem(enumerate,"hidwraw"); + udev_enumerate_scan_devices(enumerate); + devices = udev_enumerate_get_list_entry(enumerate); + // Will use the 'native' udev functions to loop: + udev_list_entry_foreach(dev_list_entry,devices) { + const char *path; + + /* Get the filename of the /sys entry for the device + and create a udev_device object (dev) representing it */ + path = udev_list_entry_get_name(dev_list_entry); + dev = udev_device_new_from_syspath(this->context, path); + + /* The device pointed to by dev contains information about + the hidraw device. In order to get information about the + USB device, get the parent device with the + subsystem/devtype pair of "usb"/"usb_device". This will + be several levels up the tree, but the function will find + it.*/ + dev = udev_device_get_parent_with_subsystem_devtype( + dev, + "usb", + "usb_device"); + if (!dev) { + printf("Unable to find parent usb device."); + return devicesList; + } + + /* From here, we can call get_sysattr_value() for each file + in the device's /sys entry. The strings passed into these + functions (idProduct, idVendor, serial, etc.) correspond + directly to the files in the directory which represents + the USB device. Note that USB strings are Unicode, UCS2 + encoded, but the strings returned from + udev_device_get_sysattr_value() are UTF-8 encoded. */ + printf(" VID/PID: %s %s\n", + udev_device_get_sysattr_value(dev,"idVendor"), + udev_device_get_sysattr_value(dev, "idProduct")); + printf(" %s\n %s\n", + udev_device_get_sysattr_value(dev,"manufacturer"), + udev_device_get_sysattr_value(dev,"product")); + printf(" serial: %s\n", + udev_device_get_sysattr_value(dev, "serial")); + devicesList.append(makePortInfo(dev)); + udev_device_unref(dev); + } + /* free the enumerator object */ + udev_enumerate_unref(enumerate); + + return devicesList; + +} + +/** + Be a bit more picky and ask only for a specific type of device: + */ +QList USBMonitor::availableDevices(int vid, int pid, int bcdDevice) +{ + QList allPorts = availableDevices(); + QList thePortsWeWant; + + foreach (USBPortInfo port, allPorts) { + thePortsWeWant.append(port); + } + + return thePortsWeWant; +} + + +USBPortInfo USBMonitor::makePortInfo(struct udev_device *dev) +{ + USBPortInfo prtInfo; + + printf(" Node: %s", udev_device_get_devnode(dev)); + printf(" Subsystem: %s", udev_device_get_subsystem(dev)); + printf(" Devtype: %s", udev_device_get_devtype(dev)); + printf(" Action: %s", udev_device_get_action(dev)); + + prtInfo.vendorID = QString(udev_device_get_sysattr_value(dev, "idVendor")).toInt(); + prtInfo.productID = QString(udev_device_get_sysattr_value(dev, "idProduct")).toInt(); + prtInfo.serialNumber = QString(udev_device_get_sysattr_value(dev, "serial")); + + return prtInfo; + +} diff --git a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_win.cpp b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_win.cpp index 2389d3fe1..354ebe4a8 100644 --- a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_win.cpp +++ b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_win.cpp @@ -48,3 +48,26 @@ USBMonitor::~USBMonitor() { quit(); } + +/** +Returns a list of all currently available devices +*/ +QList USBMonitor::availableDevices() +{ + +} + +/** + Be a bit more picky and ask only for a specific type of device: + */ +QList USBMonitor::availableDevices(int vid, int pid, int bcdDevice) +{ + QList allPorts = availableDevices(); + QList thePortsWeWant; + + foreach (USBPortInfo port, allPorts) { + thePortsWeWant.append(port); + } + + return thePortsWeWant; +}