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