API
 
Loading...
Searching...
No Matches
ttyUSB.cpp
Go to the documentation of this file.
1/** \file ttyUSB.cpp
2 * \author Jared R. Males
3 * \brief Find the details for USB serial devices
4 *
5 * \ingroup tty_files
6 *
7 */
8
9
10#include <iostream>
11
12#include <libudev.h>
13
14#include <string>
15#include <cstring>
16
17#include <boost/filesystem.hpp>
18#include <mx/ioutils/fileUtils.hpp>
19
20#include "ttyUSB.hpp"
21
22#include "ttyErrors.hpp"
23
24
25namespace MagAOX
26{
27namespace tty
28{
29
30int ttyUSBDevName( std::string & devName, // [out] the /dev/ttyUSBX device name.
31 const std::string & vendor, // [in] the 4-digit vendor identifier.
32 const std::string & product, // [in] the 4-digit product identifier.
33 const std::string & serial // [in] the serial number. Can be "".
34 )
35{
36 typedef mx::verbose::vvv verboseT;
37
38 std::vector<std::string> devNames;
39
40 devName = "";
41 mx_error_check_rv(mx::ioutils::getFileNames(devNames, "/sys/class/tty/", "ttyUSB", "", ""),-1);
42
43 if(devNames.size() == 0) return TTY_E_NODEVNAMES;
44
45 struct udev *udev;
46
47
48 /* Create the udev object */
49 udev = udev_new();
50 if (!udev) return TTY_E_UDEVNEWFAILED;
51
52 for(size_t i=0; i< devNames.size(); ++i)
53 {
54 struct udev_device *dev0;
55
56 dev0 = udev_device_new_from_syspath(udev, devNames[i].c_str());
57
58 if(!dev0)
59 {
60 std::cerr << "udev_device_new_from_syspath failed: " << strerror(errno) << "\n";
61 perror("");
62 continue;
63 }
64
65 struct udev_device *dev;
66
67 dev = udev_device_get_parent_with_subsystem_devtype( dev0, "usb", "usb_device");
68
69 if (!dev)
70 {
71 std::cerr << "udev_device_get_parent_with_subsystem_devtype failed: " << strerror(errno) << "\n";
72 perror("");
73 udev_device_unref(dev0);
74 continue;
75 }
76
77 const char * idVendor = udev_device_get_sysattr_value( dev, "idVendor" );
78
79 if(idVendor == nullptr)
80 {
81 udev_device_unref(dev0);
82 continue;
83 }
84
85 if( strcmp( idVendor, vendor.c_str()) != 0)
86 {
87 udev_device_unref(dev0);
88 continue;
89 }
90
91 const char * idProduct = udev_device_get_sysattr_value( dev, "idProduct" );
92
93 if(idProduct == nullptr)
94 {
95 udev_device_unref(dev0);
96 continue;
97 }
98
99 if( strcmp( idProduct, product.c_str()) != 0)
100 {
101 udev_device_unref(dev0);
102 continue;
103 }
104
105 const char * dserial = udev_device_get_sysattr_value( dev, "serial" );
106
107 if(dserial == nullptr)
108 {
109 if( serial != "")
110 {
111 udev_device_unref(dev0);
112 continue;
113 }
114 }
115 else if( strcmp( dserial, serial.c_str()) != 0 )
116 {
117 udev_device_unref(dev0);
118 continue;
119 }
120
121 //If we make it through all comparisons we found it!
122 boost::filesystem::path p(devNames[i]);
123 devName = "/dev/" + p.filename().string();
124
125 udev_device_unref(dev0);
126
127 udev_unref(udev);
128
129 return TTY_E_NOERROR;
130 }
131
132 devName = "";
133
134 udev_unref(udev);
135
136 return TTY_E_DEVNOTFOUND;
137}
138
139int ttyUSBDevNames( std::vector<std::string> & devNames, // [out] the /dev/ttyUSBX device names for all matching devices.
140 const std::string & vendor, // [in] the 4-digit vendor identifier.
141 const std::string & product // [in] the 4-digit product identifier.
142 )
143{
144 std::vector<std::string> pdevNames;
145
146 devNames.clear();
147
148 typedef mx::verbose::vvv verboseT;
149 mx_error_check_rv(mx::ioutils::getFileNames(pdevNames, "/sys/class/tty/", "ttyUSB", "", ""), -1);
150
151 if(pdevNames.size() == 0) return TTY_E_NODEVNAMES;
152
153 struct udev *udev;
154
155 /* Create the udev object */
156 udev = udev_new();
157 if (!udev) return TTY_E_UDEVNEWFAILED;
158
159 for(size_t i=0; i< pdevNames.size(); ++i)
160 {
161 struct udev_device *dev0;
162
163 dev0 = udev_device_new_from_syspath(udev, pdevNames[i].c_str());
164
165 if(!dev0)
166 {
167 continue;
168 }
169
170 struct udev_device * dev;
171 dev = udev_device_get_parent_with_subsystem_devtype( dev0, "usb", "usb_device");
172
173 if (!dev)
174 {
175 udev_device_unref(dev0);
176 continue;
177 }
178
179 const char * idVendor = udev_device_get_sysattr_value( dev, "idVendor" );
180
181 if(idVendor == nullptr)
182 {
183 udev_device_unref(dev0);
184 continue;
185 }
186
187 if( strcmp( idVendor, vendor.c_str()) != 0)
188 {
189 udev_device_unref(dev0);
190 continue;
191 }
192
193 const char * idProduct = udev_device_get_sysattr_value( dev, "idProduct" );
194
195 if(idProduct == nullptr)
196 {
197 udev_device_unref(dev0);
198 continue;
199 }
200
201 if( strcmp( idProduct, product.c_str()) != 0)
202 {
203 udev_device_unref(dev0);
204 continue;
205 }
206
207 //If we make it through all comparisons we found it!
208 boost::filesystem::path p(pdevNames[i]);
209 devNames.push_back( "/dev/" + p.filename().string());
210
211 udev_device_unref(dev0);
212 }
213
214 udev_unref(udev);
215
216 if( devNames.size() > 0) return TTY_E_NOERROR;
217 else return TTY_E_DEVNOTFOUND;
218
219}
220} //namespace tty
221} //namespace MagAOX
222
int ttyUSBDevName(std::string &devName, const std::string &vendor, const std::string &product, const std::string &serial)
Get the ttyUSB device name for a specific device.
Definition ttyUSB.cpp:30
int ttyUSBDevNames(std::vector< std::string > &devNames, const std::string &vendor, const std::string &product)
Get the ttyUSB device name for a set of devices specified by their vendor and product ids.
Definition ttyUSB.cpp:139
Definition dm.hpp:28
Error numbers for the tty utilities.
#define TTY_E_UDEVNEWFAILED
Definition ttyErrors.hpp:29
#define TTY_E_NODEVNAMES
Definition ttyErrors.hpp:28
#define TTY_E_DEVNOTFOUND
Definition ttyErrors.hpp:30
#define TTY_E_NOERROR
Definition ttyErrors.hpp:15
Find the details for USB serial devices.