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 std::vector<std::string> devNames;
37
38 devName = "";
39 devNames = mx::ioutils::getFileNames("/sys/class/tty/", "ttyUSB", "", "");
40
41 if(devNames.size() == 0) return TTY_E_NODEVNAMES;
42
43 struct udev *udev;
44
45
46 /* Create the udev object */
47 udev = udev_new();
48 if (!udev) return TTY_E_UDEVNEWFAILED;
49
50 for(size_t i=0; i< devNames.size(); ++i)
51 {
52 struct udev_device *dev0;
53
54 dev0 = udev_device_new_from_syspath(udev, devNames[i].c_str());
55
56 if(!dev0)
57 {
58 std::cerr << "udev_device_new_from_syspath failed: " << strerror(errno) << "\n";
59 perror("");
60 continue;
61 }
62
63 struct udev_device *dev;
64
65 dev = udev_device_get_parent_with_subsystem_devtype( dev0, "usb", "usb_device");
66
67 if (!dev)
68 {
69 std::cerr << "udev_device_get_parent_with_subsystem_devtype failed: " << strerror(errno) << "\n";
70 perror("");
71 udev_device_unref(dev0);
72 continue;
73 }
74
75 const char * idVendor = udev_device_get_sysattr_value( dev, "idVendor" );
76
77 if(idVendor == nullptr)
78 {
79 udev_device_unref(dev0);
80 continue;
81 }
82
83 if( strcmp( idVendor, vendor.c_str()) != 0)
84 {
85 udev_device_unref(dev0);
86 continue;
87 }
88
89 const char * idProduct = udev_device_get_sysattr_value( dev, "idProduct" );
90
91 if(idProduct == nullptr)
92 {
93 udev_device_unref(dev0);
94 continue;
95 }
96
97 if( strcmp( idProduct, product.c_str()) != 0)
98 {
99 udev_device_unref(dev0);
100 continue;
101 }
102
103 const char * dserial = udev_device_get_sysattr_value( dev, "serial" );
104
105 if(dserial == nullptr)
106 {
107 if( serial != "")
108 {
109 udev_device_unref(dev0);
110 continue;
111 }
112 }
113 else if( strcmp( dserial, serial.c_str()) != 0 )
114 {
115 udev_device_unref(dev0);
116 continue;
117 }
118
119 //If we make it through all comparisons we found it!
120 boost::filesystem::path p(devNames[i]);
121 devName = "/dev/" + p.filename().string();
122
123 udev_device_unref(dev0);
124
125 udev_unref(udev);
126
127 return TTY_E_NOERROR;
128 }
129
130 devName = "";
131
132 udev_unref(udev);
133
134 return TTY_E_DEVNOTFOUND;
135}
136
137int ttyUSBDevNames( std::vector<std::string> & devNames, // [out] the /dev/ttyUSBX device names for all matching devices.
138 const std::string & vendor, // [in] the 4-digit vendor identifier.
139 const std::string & product // [in] the 4-digit product identifier.
140 )
141{
142 std::vector<std::string> pdevNames;
143
144 devNames.clear();
145
146 pdevNames = mx::ioutils::getFileNames("/sys/class/tty/", "ttyUSB", "", "");
147
148 if(pdevNames.size() == 0) return TTY_E_NODEVNAMES;
149
150 struct udev *udev;
151
152 /* Create the udev object */
153 udev = udev_new();
154 if (!udev) return TTY_E_UDEVNEWFAILED;
155
156 for(size_t i=0; i< pdevNames.size(); ++i)
157 {
158 struct udev_device *dev0;
159
160 dev0 = udev_device_new_from_syspath(udev, pdevNames[i].c_str());
161
162 if(!dev0)
163 {
164 continue;
165 }
166
167 struct udev_device * dev;
168 dev = udev_device_get_parent_with_subsystem_devtype( dev0, "usb", "usb_device");
169
170 if (!dev)
171 {
172 udev_device_unref(dev0);
173 continue;
174 }
175
176 const char * idVendor = udev_device_get_sysattr_value( dev, "idVendor" );
177
178 if(idVendor == nullptr)
179 {
180 udev_device_unref(dev0);
181 continue;
182 }
183
184 if( strcmp( idVendor, vendor.c_str()) != 0)
185 {
186 udev_device_unref(dev0);
187 continue;
188 }
189
190 const char * idProduct = udev_device_get_sysattr_value( dev, "idProduct" );
191
192 if(idProduct == nullptr)
193 {
194 udev_device_unref(dev0);
195 continue;
196 }
197
198 if( strcmp( idProduct, product.c_str()) != 0)
199 {
200 udev_device_unref(dev0);
201 continue;
202 }
203
204 //If we make it through all comparisons we found it!
205 boost::filesystem::path p(pdevNames[i]);
206 devNames.push_back( "/dev/" + p.filename().string());
207
208 udev_device_unref(dev0);
209 }
210
211 udev_unref(udev);
212
213 if( devNames.size() > 0) return TTY_E_NOERROR;
214 else return TTY_E_DEVNOTFOUND;
215
216}
217} //namespace tty
218} //namespace MagAOX
219
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:137
Definition dm.hpp:24
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.