30 #include <boost/filesystem.hpp> 
   31 #include <boost/range/iterator_range.hpp> 
   32 #include <boost/algorithm/string.hpp> 
   41 #include <linux/serial.h>  
   42 #include <sys/ioctl.h>     
   60         boost::optional<USBSerialDevice>
 
   61         make_USBSerialDevice(
const std::string &device) {
 
   70             boost::filesystem::path uevent_file =
 
   71                 "/sys/class/tty/" + device + 
"/device/uevent";
 
   72             if (!boost::filesystem::exists(uevent_file)) {
 
   76             std::ifstream uevent_input(uevent_file.generic_string());
 
   78             while (std::getline(uevent_input, line)) {
 
   79                 if (!boost::starts_with(line, 
"PRODUCT="))
 
   83                 const auto first = line.find(
"=");
 
   84                 const auto second = line.find(
"/", first);
 
   85                 const auto third = line.find(
"/", second + 1);
 
   87                 const std::string vendor_id_str =
 
   88                     line.substr(first + 1, second - first - 1);
 
   89                 const std::string product_id_str =
 
   90                     line.substr(second + 1, third - second - 1);
 
   92                 const uint16_t detected_vendor_id =
 
   93                     std::stoi(vendor_id_str.c_str(), 0, 16);
 
   94                 const uint16_t detected_product_id =
 
   95                     std::stoi(product_id_str.c_str(), 0, 16);
 
   98                 const std::string device_name =
 
   99                     (boost::filesystem::path(
"/dev") / device).generic_string();
 
  100                 USBSerialDevice usb_serial_device(detected_vendor_id,
 
  102                                                   device_name, device_name);
 
  103                 return usb_serial_device;
 
  116         bool serial8250_device_connected(
const std::string &port) {
 
  117             const int fd = open(port.c_str(), O_RDWR | O_NONBLOCK | O_NOCTTY);
 
  122             struct serial_struct serial_info;
 
  123             const int ret = ioctl(fd, TIOCGSERIAL, &serial_info);
 
  129             if (PORT_UNKNOWN == serial_info.type) {
 
  148         bool matches_ids(
const USBSerialDevice &device,
 
  149                          const boost::optional<uint16_t> &vendorID,
 
  150                          const boost::optional<uint16_t> &productID) {
 
  151             const bool vendor_matches =
 
  152                 (!vendorID || *vendorID == device.getVID());
 
  153             const bool product_matches =
 
  154                 (!productID || *productID == device.getPID());
 
  156             return (vendor_matches && product_matches);
 
  161     std::vector<USBSerialDevice>
 
  162     getSerialDeviceList(boost::optional<uint16_t> vendorID,
 
  163                         boost::optional<uint16_t> productID) {
 
  165         std::vector<USBSerialDevice> devices;
 
  168         const boost::filesystem::path sys_class_tty = 
"/sys/class/tty";
 
  169         for (
const auto &path_name : boost::make_iterator_range(
 
  170                  boost::filesystem::directory_iterator(sys_class_tty),
 
  171                  boost::filesystem::directory_iterator())) {
 
  173             const boost::filesystem::path device_candidate = path_name;
 
  174             const boost::filesystem::path driver_file =
 
  175                 device_candidate / 
"device" / 
"driver";
 
  176             if (!boost::filesystem::exists(driver_file)) {
 
  181             const boost::filesystem::path basename =
 
  182                 boost::filesystem::basename(device_candidate);
 
  184             auto usb_serial_device =
 
  185                 make_USBSerialDevice(basename.generic_string());
 
  186             if (!usb_serial_device)
 
  190             if (!matches_ids(*usb_serial_device, vendorID, productID))
 
  195             if (boost::filesystem::exists(driver_file / 
"serial8250")) {
 
  196                 const bool is_connected = serial8250_device_connected(
 
  197                     "/dev/" + basename.generic_string());
 
  203             devices.push_back(*usb_serial_device);