linux/usb_sensor_enumerator.cpp
Go to the documentation of this file.
1 /*
2  * BSD 3-Clause License
3  *
4  * Copyright (c) 2019, Analog Devices, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  * list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from
19  * this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
36 #include "usb_buffer.pb.h"
37 #include "utils.h"
38 
39 #include <dirent.h>
40 #include <fcntl.h>
41 #ifdef USE_GLOG
42 #include <glog/logging.h>
43 #else
44 #include <aditof/log.h>
45 #include <unistd.h>
46 #endif
47 #include <linux/videodev2.h>
48 #include <memory>
49 #include <sys/stat.h>
50 
51 using namespace std;
52 using namespace aditof;
53 
55 
57  Status status = Status::OK;
58 
59  LOG(INFO) << "Looking for USB connected sensors";
60 
61  const char *path = "/dev/";
62  DIR *d;
63 
64  d = opendir(path);
65  if (!d) {
66  LOG(WARNING) << "Failed to open dir at path: " << path;
67  return Status::UNREACHABLE;
68  }
69 
70  struct dirent *dir;
71  char sset[] = "video";
72  while ((dir = readdir(d)) != nullptr) {
73  if (strspn(sset, (dir->d_name)) != 5) {
74  continue;
75  }
76  string driverPath(path);
77  driverPath += dir->d_name;
78 
79  struct stat st;
80  if (-1 == stat(driverPath.c_str(), &st)) {
81  LOG(WARNING) << "Cannot identify '" << driverPath
82  << "' error: " << errno << "(" << strerror(errno)
83  << ")";
84  continue;
85  }
86 
87  if (!S_ISCHR(st.st_mode)) {
88  LOG(WARNING) << driverPath << " is no device";
89  continue;
90  }
91 
92  fd = open(driverPath.c_str(), O_RDWR | O_NONBLOCK, 0);
93  if (-1 == fd) {
94  LOG(WARNING) << "Cannot open '" << driverPath
95  << "' error: " << errno << "(" << strerror(errno)
96  << ")";
97  continue;
98  }
99 
100  struct v4l2_capability cap;
101  if (-1 == UsbLinuxUtils::xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
102  if (EINVAL == errno) {
103  LOG(WARNING) << driverPath << " is not V4L2 device";
104  close(fd);
105  continue;
106  }
107  }
108 
109  // Skip device which does not support VIDIOC_G_FMT
110  struct v4l2_format fmt;
111  CLEAR(fmt);
112  fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
113  if (-1 == UsbLinuxUtils::xioctl(fd, VIDIOC_G_FMT, &fmt)) {
114  close(fd);
115  continue;
116  }
117 
118  std::string devName("ADI TOF USB Gadget");
119 
120  if (strncmp(reinterpret_cast<const char *>(cap.card), devName.c_str(),
121  devName.length()) != 0) {
122  close(fd);
123  continue;
124  }
125 
126  if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
127  LOG(WARNING) << driverPath << " is no video capture device";
128  close(fd);
129  continue;
130  }
131 
132  if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
133  LOG(WARNING) << driverPath << " does not support streaming i/o";
134  close(fd);
135  continue;
136  }
137 
138  SensorInfo sInfo;
139  sInfo.driverPath = driverPath;
140 
141  DLOG(INFO) << "Found USB capture device at: " << driverPath;
142 
143  // Query the sensors that are available on target
144 
145  // Send request
146  usb_payload::ClientRequest requestMsg;
147  requestMsg.set_func_name(usb_payload::FunctionName::SEARCH_SENSORS);
148  requestMsg.add_func_int32_param(
149  1); // TO DO: Check if this is needed. Without it, the serialized string will be empty.
150 
151  std::string requestStr;
152  requestMsg.SerializeToString(&requestStr);
153  status = UsbLinuxUtils::uvcExUnitSendRequest(fd, requestStr);
154  if (status != Status::OK) {
155  LOG(ERROR) << "Request to search for sensors failed";
156  return status;
157  }
158 
159  // Read UVC gadget response
162  if (status != Status::OK) {
163  LOG(ERROR) << "Request to search for sensors failed";
164  return status;
165  }
166  usb_payload::ServerResponse responseMsg;
167  bool parsed = responseMsg.ParseFromString(responseStr);
168  if (!parsed) {
169  LOG(ERROR) << "Failed to deserialize string containing UVC gadget "
170  "response";
172  }
173 
174  DLOG(INFO) << "Received the following message with "
175  "available sensors from target: "
176  << responseMsg.DebugString();
177 
178  if (responseMsg.status() != usb_payload::Status::OK) {
179  LOG(ERROR) << "Search for sensors operation failed on UVC gadget";
180  return static_cast<Status>(responseMsg.status());
181  }
182 
183  // If request and response went well, extract data from response
184  m_sensorsInfo.emplace_back(sInfo);
185  m_sensorName = responseMsg.sensors_info().image_sensors().name();
186 
187  m_sensorName = responseMsg.sensors_info().image_sensors().name();
188 
189  m_kernelVersion = responseMsg.card_image_version().kernelversion();
190  m_sdVersion = responseMsg.card_image_version().sdversion();
191  m_uBootVersion = responseMsg.card_image_version().ubootversion();
192  }
193 
194  closedir(d);
195 
196  return status;
197 }
198 
200  std::vector<std::shared_ptr<DepthSensorInterface>> &depthSensors) {
201 
202  depthSensors.clear();
203 
204  for (const auto &sInfo : m_sensorsInfo) {
205  auto sensor =
206  std::make_shared<UsbDepthSensor>(m_sensorName, sInfo.driverPath);
207  depthSensors.emplace_back(sensor);
208  }
209 
210  return Status::OK;
211 }
212 
215  uBootVersion = m_uBootVersion;
216  return aditof::Status::OK;
217 }
218 
221  kernelVersion = m_kernelVersion;
222  return aditof::Status::OK;
223 }
224 
226  sdVersion = m_sdVersion;
227  return aditof::Status::OK;
228 }
UsbSensorEnumerator::SensorInfo
Definition: usb_sensor_enumerator.h:54
usb_depth_sensor.h
INFO
const int INFO
Definition: log_severity.h:59
ERROR
const int ERROR
Definition: log_severity.h:60
UsbSensorEnumerator::getSdVersion
virtual aditof::Status getSdVersion(std::string &sdVersion) const override
Get the SD card image version on the embedded system that the camera is attached to.
Definition: linux/usb_sensor_enumerator.cpp:225
EINVAL
#define EINVAL
Definition: errno.hpp:25
readdir
static struct dirent * readdir(DIR *dirp)
Definition: dirent.h:732
UsbSensorEnumerator::getUbootVersion
virtual aditof::Status getUbootVersion(std::string &uBootVersion) const override
Get the U-Boot version that is installed on the embedded system that the camera is attached to.
Definition: linux/usb_sensor_enumerator.cpp:214
log.h
dirent::d_name
char d_name[PATH_MAX+1]
Definition: dirent.h:278
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
errno
int errno
usb_sensor_enumerator.h
WARNING
const int WARNING
Definition: log_severity.h:59
DLOG
#define DLOG(x)
Definition: sdk/include/aditof/log.h:73
closedir
static int closedir(DIR *dirp)
Definition: dirent.h:843
UsbSensorEnumerator::~UsbSensorEnumerator
~UsbSensorEnumerator()
responseStr
ROSCPP_DECL XmlRpc::XmlRpcValue responseStr(int code, const std::string &msg, const std::string &response)
dirent.h
path
GLsizei const GLchar ** path
Definition: glcorearb.h:3658
aditof
Namespace aditof.
Definition: adsd_errs.h:40
UsbSensorEnumerator::SensorInfo::driverPath
std::string driverPath
Definition: usb_sensor_enumerator.h:55
google::protobuf::util::error::OK
@ OK
Definition: status.h:47
dirent
Definition: dirent.h:261
testing::internal::fmt
GTEST_API_ const char * fmt
Definition: gtest.h:1835
d
d
google::protobuf::util::error::INVALID_ARGUMENT
@ INVALID_ARGUMENT
Definition: status.h:50
UsbSensorEnumerator::getDepthSensors
virtual aditof::Status getDepthSensors(std::vector< std::shared_ptr< aditof::DepthSensorInterface >> &depthSensors) override
Definition: linux/usb_sensor_enumerator.cpp:199
aditof::Status
Status
Status of any operation that the TOF sdk performs.
Definition: status_definitions.h:48
UsbSensorEnumerator::searchSensors
virtual aditof::Status searchSensors() override
Do a search for the available sensors.
Definition: linux/usb_sensor_enumerator.cpp:56
LOG
#define LOG(x)
Definition: sdk/include/aditof/log.h:72
aditof::Status::OK
@ OK
Success.
DIR
Definition: dirent.h:282
CLEAR
#define CLEAR(x)
Definition: adsd3500_sensor.cpp:43
usb_linux_utils.h
std
usb_utils.h
strerror
char * strerror(int errno)
UsbLinuxUtils::uvcExUnitGetResponse
static aditof::Status uvcExUnitGetResponse(int fd, std::string &responseStr)
Get the response (which is encoded in a protobuf message) for the last request that was made....
Definition: usb_linux_utils.cpp:343
opendir
static DIR * opendir(const char *dirname)
Definition: dirent.h:676
S_ISCHR
#define S_ISCHR(mode)
Definition: dirent.h:202
UsbSensorEnumerator::getKernelVersion
virtual aditof::Status getKernelVersion(std::string &kernelVersion) const override
Get the kernel version that is installed on the embedded system that the camera is attached to.
Definition: linux/usb_sensor_enumerator.cpp:220
UsbLinuxUtils::xioctl
static int xioctl(int fh, unsigned long request, void *arg)
Definition: usb_linux_utils.cpp:54
UsbLinuxUtils::uvcExUnitSendRequest
static aditof::Status uvcExUnitSendRequest(int fd, const std::string &requestStr)
Send a request (which is encoded in a protobuf message) via the UVC extension unit.
Definition: usb_linux_utils.cpp:302


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:07:01