hid-device.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2015 Intel Corporation. All Rights Reserved.
3 
4 #include <queue>
5 #include "hid-device.h"
6 
7 const int USB_REQUEST_COUNT = 1;
8 
9 namespace librealsense
10 {
11  namespace platform
12  {
13  std::vector<hid_device_info> query_hid_devices_info()
14  {
15  std::vector<std::string> hid_sensors = { gyro, accel, custom };
16 
17  std::vector<hid_device_info> rv;
19  for (auto&& info : usb_devices) {
20  if(info.cls != RS2_USB_CLASS_HID)
21  continue;
23  device_info.vid = hexify(info.vid);
24  device_info.pid = hexify(info.pid);
25  device_info.unique_id = info.unique_id;
26  device_info.device_path = info.unique_id;//the device unique_id is the USB port
27 
28  for(auto&& hs : hid_sensors)
29  {
30  device_info.id = hs;
31  // LOG_INFO("Found HID device: " << std::string(device_info).c_str());
32  rv.push_back(device_info);
33  }
34  }
35  return rv;
36  }
37 
38  std::shared_ptr<hid_device> create_rshid_device(hid_device_info info)
39  {
41  for (auto&& usb_info : devices)
42  {
43  if(usb_info.unique_id != info.unique_id || usb_info.cls != RS2_USB_CLASS_HID)
44  continue;
45 
46  auto dev = usb_enumerator::create_usb_device(usb_info);
47  return std::make_shared<rs_hid_device>(dev);
48  }
49 
50  return nullptr;
51  }
52 
54  : _usb_device(usb_device),
55  _action_dispatcher(10)
56  {
63 #ifdef __APPLE__
65  if(devices)
66  {
67  _hidapi_device = hid_open(devices[0].vendor_id, devices[0].product_id, devices[0].serial_number);
68  hidapi_PowerDevice(REPORT_ID_ACCELEROMETER_3D);
69  hidapi_PowerDevice(REPORT_ID_GYROMETER_3D);
70  }
71 #endif
73  }
74 
76  {
77 #ifdef __APPLE__
78  if( _hidapi_device )
79  hid_close( _hidapi_device );
80 #endif
82  }
83 
84  std::vector<hid_sensor> rs_hid_device::get_sensors()
85  {
86  std::vector<hid_sensor> sensors;
87 
88  for (auto& sensor : _hid_profiles)
89  sensors.push_back({ sensor.sensor_name });
90 
91  return sensors;
92  }
93 
94  void rs_hid_device::open(const std::vector<hid_profile>& hid_profiles)
95  {
96  for(auto&& p : hid_profiles)
97  {
98  set_feature_report(DEVICE_POWER_D0, _sensor_to_id[p.sensor_name], p.frequency);
99  }
100  _configured_profiles = hid_profiles;
101  }
102 
104  {
107  }
108 
110  {
112  {
113  if(!_running)
114  return;
115 #ifndef __APPLE__
116  _request_callback->cancel();
117 
118  _queue.clear();
119 
120  for (auto&& r : _requests)
121  _messenger->cancel_request(r);
122 
123  _requests.clear();
124 #endif
126 #ifndef __APPLE__
127  _messenger.reset();
128 #endif
129  _running = false;
130  }, [this](){ return !_running; });
131  }
132 
134  {
136  {
137  if(_running)
138  return;
139 
141 #ifndef __APPLE__
142  auto in = get_hid_interface()->get_number();
143  _messenger = _usb_device->open(in);
144 #endif
145  _handle_interrupts_thread = std::make_shared<active_object<>>([this](dispatcher::cancellable_timer cancellable_timer)
146  {
148  });
149 
150  _handle_interrupts_thread->start();
151 
152 #ifndef __APPLE__
153  _request_callback = std::make_shared<usb_request_callback>([&](platform::rs_usb_request r)
154  {
156  {
157  if(!_running)
158  return;
159  if(r->get_actual_length() == sizeof(REALSENSE_HID_REPORT))
160  {
161  REALSENSE_HID_REPORT report;
162  memcpy(&report, r->get_buffer().data(), r->get_actual_length());
163  _queue.enqueue(std::move(report));
164  }
165  auto sts = _messenger->submit_request(r);
167  LOG_ERROR("failed to submit UVC request");
168  });
169 
170  });
171 
172  _requests = std::vector<rs_usb_request>(USB_REQUEST_COUNT);
173  for(auto&& r : _requests)
174  {
175  r = _messenger->create_request(get_hid_endpoint());
176  r->set_buffer(std::vector<uint8_t>(sizeof(REALSENSE_HID_REPORT)));
177  r->set_callback(_request_callback);
178  }
179 #endif
180  _running = true;
181 #ifndef __APPLE__
182  for(auto&& r : _requests)
183  _messenger->submit_request(r);
184 #endif
185 
186  }, [this](){ return _running; });
187  }
188 
190  {
191  REALSENSE_HID_REPORT report;
192 #ifdef __APPLE__
193  hid_read(_hidapi_device, reinterpret_cast<unsigned char*>(&report), sizeof(REALSENSE_HID_REPORT));
194  sensor_data data{};
195  data.sensor = { _id_to_sensor[report.reportId] };
196 
197  hid_data hid{};
198  hid.x = report.x;
199  hid.y = report.y;
200  hid.z = report.z;
201 
202  data.fo.pixels = &(hid.x);
203  data.fo.metadata = &(report.timeStamp);
204  data.fo.frame_size = sizeof(REALSENSE_HID_REPORT);
205  data.fo.metadata_size = sizeof(report.timeStamp);
206 
207  _callback(data);
208 #else
209  if(_queue.dequeue(&report, 10))
210  {
211  if(std::find_if(_configured_profiles.begin(), _configured_profiles.end(), [&](hid_profile& p)
212  {
213  return _id_to_sensor[report.reportId].compare(p.sensor_name) == 0;
214 
215  }) != _configured_profiles.end())
216  {
217  sensor_data data{};
218  data.sensor = { _id_to_sensor[report.reportId] };
219 
220  hid_data hid{};
221  hid.x = report.x;
222  hid.y = report.y;
223  hid.z = report.z;
224 
225  data.fo.pixels = &(hid.x);
226  data.fo.metadata = &(report.timeStamp);
227  data.fo.frame_size = sizeof(REALSENSE_HID_REPORT);
228  data.fo.metadata_size = sizeof(report.timeStamp);
229 
230  _callback(data);
231  }
232  }
233 #endif
234  }
235 
236  usb_status rs_hid_device::set_feature_report(unsigned char power, int report_id, int fps)
237  {
238  uint32_t transferred;
239 
240 
241  int value = (HID_REPORT_TYPE_FEATURE << 8) + report_id;
242 
243  FEATURE_REPORT featureReport;
244  auto hid_interface = get_hid_interface()->get_number();
245 
246  auto dev = _usb_device->open(hid_interface);
247 
248  if (!dev)
250 
251  auto res = dev->control_transfer(USB_REQUEST_CODE_GET,
253  value,
254  hid_interface,
255  (uint8_t*) &featureReport,
256  sizeof(featureReport),
257  transferred,
258  1000);
259 
261  {
262  LOG_WARNING("control_transfer of USB_REQUEST_CODE_GET failed return value is: " << res);
263  return res;
264  }
265 
266  featureReport.power = power;
267 
268  if(fps > 0)
269  featureReport.report = (1000 / fps);
270 
271  res = dev->control_transfer(USB_REQUEST_CODE_SET,
273  value,
274  hid_interface,
275  (uint8_t*) &featureReport,
276  sizeof(featureReport),
277  transferred,
278  1000);
279 
281  {
282  LOG_WARNING("control_transfer of USB_REQUEST_CODE_SET failed return value is: " << res);
283  return res;
284  }
285 
286  res = dev->control_transfer(USB_REQUEST_CODE_GET,
288  value,
289  hid_interface,
290  (uint8_t*) &featureReport,
291  sizeof(featureReport),
292  transferred,
293  1000);
294 
296  {
297  LOG_WARNING("control_transfer of USB_REQUEST_CODE_GET failed return value is: " << res);
298  return res;
299  }
300 
301  if(featureReport.power != power)
302  {
303  LOG_WARNING("faild to set power: " << power);
304  return RS2_USB_STATUS_OTHER;
305  }
306  return res;
307  }
308 
309 #ifdef __APPLE__
310  int rs_hid_device::hidapi_PowerDevice(unsigned char reportId)
311  {
312  if (_hidapi_device == NULL)
313  return -1;
314 
315  REALSENSE_FEATURE_REPORT featureReport;
316  int ret;
317 
318  memset(&featureReport,0, sizeof(featureReport));
319  featureReport.reportId = reportId;
320  // Reading feature report.
321  ret = hid_get_feature_report(_hidapi_device, (unsigned char *)
322  &featureReport ,sizeof(featureReport) );
323 
324  if (ret == -1) {
325  LOG_ERROR("fail to read feature report from device");
326  return ret;
327  }
328 
329  // change report to power the device to D0
330 
331  featureReport.power = DEVICE_POWER_D0;
332 
333  // Write feature report back.
334  ret = hid_send_feature_report(_hidapi_device, (unsigned char *) &featureReport, sizeof(featureReport));
335 
336  if (ret == -1) {
337  LOG_ERROR("fail to write feature report from device");
338  return ret;
339  }
340 
341  ret = hid_get_feature_report(_hidapi_device, (unsigned char *) &featureReport ,sizeof(featureReport) );
342 
343  if (ret == -1) {
344  LOG_ERROR("fail to read feature report from device");
345  return ret;
346  }
347 
348  if (featureReport.power == DEVICE_POWER_D0) {
349  LOG_INFO("Device is powered up");
350  } else {
351  LOG_INFO("Device is powered off");
352  return -1;
353  }
354 
355  return 0;
356  }
357 #endif
358 
360  {
361  auto intfs = _usb_device->get_interfaces();
362 
363  auto it = std::find_if(intfs.begin(), intfs.end(),
364  [](const rs_usb_interface& i) { return i->get_class() == RS2_USB_CLASS_HID; });
365 
366  if (it == intfs.end())
367  throw std::runtime_error("can't find HID interface of device: " + _usb_device->get_info().id);
368 
369  return *it;
370  }
371 
373  {
374  auto hid_interface = get_hid_interface();
375 
376  auto ep = hid_interface->first_endpoint(RS2_USB_ENDPOINT_DIRECTION_READ, RS2_USB_ENDPOINT_INTERRUPT);
377  if(!ep)
378  throw std::runtime_error("can't find HID endpoint of device: " + _usb_device->get_info().id);
379 
380  return ep;
381  }
382  }
383 }
std::map< std::string, int > _sensor_to_id
Definition: hid-device.h:70
static rs_usb_device create_usb_device(const usb_device_info &info)
std::shared_ptr< usb_request > rs_usb_request
Definition: usb-request.h:41
#define REPORT_ID_CUSTOM
Definition: hid-types.h:19
std::shared_ptr< active_object<> > _handle_interrupts_thread
Definition: hid-device.h:73
static std::vector< usb_device_info > query_devices_info()
std::shared_ptr< usb_interface > rs_usb_interface
Definition: usb-interface.h:31
void start()
Definition: concurrency.h:286
GLfloat GLfloat p
Definition: glext.h:12687
#define LOG_WARNING(...)
Definition: src/types.h:241
const int USB_REQUEST_COUNT
Definition: hid-device.cpp:7
GLfloat value
std::vector< hid_sensor > get_sensors() override
Definition: hid-device.cpp:84
void open(const std::vector< hid_profile > &hid_profiles) override
Definition: hid-device.cpp:94
std::shared_ptr< hid_device > create_rshid_device(hid_device_info info)
Definition: hid-device.cpp:38
usb_status set_feature_report(unsigned char power, int report_id, int fps=0)
Definition: hid-device.cpp:236
unsigned char uint8_t
Definition: stdint.h:78
enum librealsense::platform::_usb_status usb_status
def info(name, value, persistent=False)
Definition: test.py:301
std::string hexify(const T &val)
Definition: src/types.h:185
void stop()
Definition: concurrency.h:294
#define DEVICE_POWER_D0
Definition: hid-types.h:14
static std::string accel
Definition: hid-types.h:24
const GLubyte * c
Definition: glext.h:12690
GLdouble GLdouble r
void start_capture(hid_callback callback) override
Definition: hid-device.cpp:133
std::vector< hid_device_info > query_hid_devices_info()
Definition: hid-device.cpp:13
unsigned int uint32_t
Definition: stdint.h:80
devices
Definition: test-fg.py:9
std::shared_ptr< usb_endpoint > rs_usb_endpoint
Definition: usb-endpoint.h:24
single_consumer_queue< REALSENSE_HID_REPORT > _queue
Definition: hid-device.h:72
#define REPORT_ID_GYROMETER_3D
Definition: hid-types.h:18
def callback(frame)
Definition: t265_stereo.py:91
std::shared_ptr< platform::usb_request_callback > _request_callback
Definition: hid-device.h:65
GLuint GLfloat x0
Definition: glext.h:9721
static std::string custom
Definition: hid-types.h:25
#define LOG_ERROR(...)
Definition: src/types.h:242
static std::string gyro
Definition: hid-types.h:23
int HID_API_EXPORT hid_read(hidapi_device *dev, unsigned char *data, size_t length)
Read an Input report from a HID device.
Definition: hidapi.cpp:907
rs_hid_device(rs_usb_device usb_device)
Definition: hid-device.cpp:53
std::vector< hid_profile > _hid_profiles
Definition: hid-device.h:68
LOG_INFO("Log message using LOG_INFO()")
std::vector< rs_usb_request > _requests
Definition: hid-device.h:64
std::map< int, std::string > _id_to_sensor
Definition: hid-device.h:69
static auto it
GLuint in
Definition: glext.h:8859
void invoke(T item, bool is_blocking=false)
Definition: concurrency.h:254
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
#define NULL
Definition: tinycthread.c:47
int i
GLuint res
Definition: glext.h:8856
std::function< void(const sensor_data &)> hid_callback
Definition: backend.h:327
struct hidapi_device_info HID_API_EXPORT * hid_enumerate(unsigned short vendor_id, unsigned short product_id)
Enumerate the HID Devices.
Definition: hidapi.cpp:372
std::vector< hid_profile > _configured_profiles
Definition: hid-device.h:71
#define HID_REPORT_TYPE_FEATURE
Definition: hid-types.h:12
int HID_API_EXPORT hid_get_feature_report(hidapi_device *dev, unsigned char *data, size_t length)
Get a feature report from a HID device.
Definition: hidapi.cpp:925
#define REPORT_ID_ACCELEROMETER_3D
Definition: hid-types.h:17
#define DEVICE_POWER_D4
Definition: hid-types.h:15
int HID_API_EXPORT hid_send_feature_report(hidapi_device *dev, const unsigned char *data, size_t length)
Send a Feature report to the device.
Definition: hidapi.cpp:920
Definition: parser.hpp:150
std::shared_ptr< usb_device > rs_usb_device
Definition: usb-device.h:29
void invoke_and_wait(T item, std::function< bool()> exit_condition, bool is_blocking=false)
Definition: concurrency.h:266


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:16