The open source OpenXR runtime
at main 446 lines 12 kB view raw
1// Copyright 2019-2022, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief drv_vive prober code. 6 * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com> 7 * @ingroup drv_vive 8 */ 9 10#include <stdio.h> 11 12 13#include "util/u_debug.h" 14#include "util/u_prober.h" 15#include "util/u_trace_marker.h" 16 17#include "vive/vive_common.h" 18 19#include "vive_device.h" 20#include "vive_controller.h" 21#include "vive_prober.h" 22 23#include "xrt/xrt_config_drivers.h" 24 25 26static const char VIVE_PRODUCT_STRING[] = "HTC Vive"; 27static const char VIVE_PRO_PRODUCT_STRING[] = "VIVE Pro"; 28static const char VIVE_PRO2_PRODUCT_STRING[] = "VIVE Pro 2"; 29static const char VALVE_INDEX_PRODUCT_STRING[] = "Index HMD"; 30static const char VALVE_INDEX_MANUFACTURER_STRING[] = "Valve"; 31static const char VIVE_MANUFACTURER_STRING[] = "HTC"; 32 33DEBUG_GET_ONCE_LOG_OPTION(vive_log, "VIVE_LOG", U_LOGGING_WARN) 34 35static int 36log_vive_string(struct xrt_prober *xp, struct xrt_prober_device *dev, enum xrt_prober_string type) 37{ 38 unsigned char s[256] = {0}; 39 40 int len = xrt_prober_get_string_descriptor(xp, dev, type, s, sizeof(s)); 41 if (len > 0) { 42 U_LOG_I("%s: %s", u_prober_string_to_string(type), s); 43 } 44 45 return len; 46} 47 48static void 49log_vive_device(enum u_logging_level log_level, struct xrt_prober *xp, struct xrt_prober_device *dev) 50{ 51 if (log_level > U_LOGGING_INFO) { 52 return; 53 } 54 55 U_LOG_I("====== vive device ======"); 56 U_LOG_I("Vendor: %04x", dev->vendor_id); 57 U_LOG_I("Product: %04x", dev->product_id); 58 U_LOG_I("Class: %d", dev->usb_dev_class); 59 U_LOG_I("Bus type: %s", u_prober_bus_type_to_string(dev->bus)); 60 log_vive_string(xp, dev, XRT_PROBER_STRING_MANUFACTURER); 61 log_vive_string(xp, dev, XRT_PROBER_STRING_PRODUCT); 62 log_vive_string(xp, dev, XRT_PROBER_STRING_SERIAL_NUMBER); 63} 64 65static void 66init_vive1(struct xrt_prober *xp, 67 struct xrt_prober_device *dev, 68 struct xrt_prober_device **devices, 69 size_t device_count, 70 enum u_logging_level log_level, 71 struct vive_tracking_status tstatus, 72 struct vive_source *vs, 73 struct vive_device **out_vdev) 74{ 75 log_vive_device(log_level, xp, dev); 76 77 if (!u_prober_match_string(xp, dev, XRT_PROBER_STRING_MANUFACTURER, VIVE_MANUFACTURER_STRING) || 78 !u_prober_match_string(xp, dev, XRT_PROBER_STRING_PRODUCT, VIVE_PRODUCT_STRING)) { 79 return; 80 } 81 82 struct os_hid_device *sensors_dev = NULL; 83 struct os_hid_device *watchman_dev = NULL; 84 85 for (uint32_t i = 0; i < device_count; i++) { 86 struct xrt_prober_device *d = devices[i]; 87 88 if (d->vendor_id != VALVE_VID && d->product_id != VIVE_LIGHTHOUSE_FPGA_RX) 89 continue; 90 91 log_vive_device(log_level, xp, d); 92 93 int result = xrt_prober_open_hid_interface(xp, d, 0, &sensors_dev); 94 if (result != 0) { 95 U_LOG_E("Could not open Vive sensors device."); 96 return; 97 } 98 99 result = xrt_prober_open_hid_interface(xp, d, 1, &watchman_dev); 100 if (result != 0) { 101 U_LOG_E("Could not open headset watchman device."); 102 return; 103 } 104 105 break; 106 } 107 108 if (sensors_dev == NULL) { 109 U_LOG_E("Could not find Vive sensors device."); 110 return; 111 } 112 113 if (watchman_dev == NULL) { 114 U_LOG_E("Could not find headset watchman device."); 115 return; 116 } 117 118 struct os_hid_device *mainboard_dev = NULL; 119 120 int result = xrt_prober_open_hid_interface(xp, dev, 0, &mainboard_dev); 121 if (result != 0) { 122 U_LOG_E("Could not open Vive mainboard device."); 123 free(sensors_dev); 124 return; 125 } 126 struct vive_device *d = 127 vive_device_create(mainboard_dev, sensors_dev, watchman_dev, VIVE_VARIANT_VIVE, tstatus, vs); 128 if (d == NULL) { 129 free(sensors_dev); 130 free(mainboard_dev); 131 return; 132 } 133 134 *out_vdev = d; 135 136 return; 137} 138 139static void 140init_vive_pro(struct xrt_prober *xp, 141 struct xrt_prober_device *dev, 142 struct xrt_prober_device **devices, 143 size_t device_count, 144 enum u_logging_level log_level, 145 struct vive_tracking_status tstatus, 146 struct vive_source *vs, 147 struct vive_device **out_vdev) 148{ 149 XRT_TRACE_MARKER(); 150 151 log_vive_device(log_level, xp, dev); 152 153 if (!u_prober_match_string(xp, dev, XRT_PROBER_STRING_MANUFACTURER, VIVE_MANUFACTURER_STRING) || 154 !u_prober_match_string(xp, dev, XRT_PROBER_STRING_PRODUCT, VIVE_PRO_PRODUCT_STRING)) { 155 U_LOG_D("Vive Pro manufacturer string did not match."); 156 return; 157 } 158 159 struct os_hid_device *sensors_dev = NULL; 160 struct os_hid_device *watchman_dev = NULL; 161 162 for (uint32_t i = 0; i < device_count; i++) { 163 struct xrt_prober_device *d = devices[i]; 164 165 if (d->vendor_id != VALVE_VID && d->product_id != VIVE_PRO_LHR_PID) 166 continue; 167 168 log_vive_device(log_level, xp, d); 169 170 int result = xrt_prober_open_hid_interface(xp, d, 0, &sensors_dev); 171 if (result != 0) { 172 U_LOG_E("Could not open Vive sensors device."); 173 return; 174 } 175 176 result = xrt_prober_open_hid_interface(xp, d, 1, &watchman_dev); 177 if (result != 0) { 178 U_LOG_E("Could not open headset watchman device."); 179 return; 180 } 181 182 break; 183 } 184 185 if (sensors_dev == NULL) { 186 U_LOG_E("Could not find Vive Pro sensors device."); 187 return; 188 } 189 190 if (watchman_dev == NULL) { 191 U_LOG_E("Could not find headset watchman device."); 192 return; 193 } 194 195 struct os_hid_device *mainboard_dev = NULL; 196 197 int result = xrt_prober_open_hid_interface(xp, dev, 0, &mainboard_dev); 198 if (result != 0) { 199 U_LOG_E("Could not open Vive mainboard device."); 200 free(sensors_dev); 201 return; 202 } 203 struct vive_device *d = 204 vive_device_create(mainboard_dev, sensors_dev, watchman_dev, VIVE_VARIANT_PRO, tstatus, vs); 205 if (d == NULL) { 206 free(sensors_dev); 207 free(mainboard_dev); 208 return; 209 } 210 211 *out_vdev = d; 212 213 return; 214} 215 216static void 217init_vive_pro2(struct xrt_prober *xp, 218 struct xrt_prober_device *dev, 219 struct xrt_prober_device **devices, 220 size_t device_count, 221 enum u_logging_level log_level, 222 struct vive_tracking_status tstatus, 223 struct vive_source *vs, 224 struct vive_device **out_vdev) 225{ 226 XRT_TRACE_MARKER(); 227 228 log_vive_device(log_level, xp, dev); 229 230 if (!u_prober_match_string(xp, dev, XRT_PROBER_STRING_MANUFACTURER, VIVE_MANUFACTURER_STRING) || 231 !u_prober_match_string(xp, dev, XRT_PROBER_STRING_PRODUCT, VIVE_PRO2_PRODUCT_STRING)) { 232 U_LOG_D("Vive Pro 2 manufacturer string did not match."); 233 return; 234 } 235 236 struct os_hid_device *sensors_dev = NULL; 237 struct os_hid_device *watchman_dev = NULL; 238 239 for (uint32_t i = 0; i < device_count; i++) { 240 struct xrt_prober_device *d = devices[i]; 241 242 if (d->vendor_id != VALVE_VID && d->product_id != VIVE_PRO_LHR_PID) 243 continue; 244 245 log_vive_device(log_level, xp, d); 246 247 int result = xrt_prober_open_hid_interface(xp, d, 0, &sensors_dev); 248 if (result != 0) { 249 U_LOG_E("Could not open Vive Pro 2 sensors device."); 250 return; 251 } 252 253 result = xrt_prober_open_hid_interface(xp, d, 1, &watchman_dev); 254 if (result != 0) { 255 U_LOG_E("Could not open headset watchman device."); 256 return; 257 } 258 259 break; 260 } 261 262 if (sensors_dev == NULL) { 263 U_LOG_E("Could not find Vive Pro 2 sensors device."); 264 return; 265 } 266 267 if (watchman_dev == NULL) { 268 U_LOG_E("Could not find headset watchman device."); 269 return; 270 } 271 272 struct os_hid_device *mainboard_dev = NULL; 273 274 int result = xrt_prober_open_hid_interface(xp, dev, 0, &mainboard_dev); 275 if (result != 0) { 276 U_LOG_E("Could not open Vive mainboard device."); 277 free(sensors_dev); 278 return; 279 } 280 struct vive_device *d = 281 vive_device_create(mainboard_dev, sensors_dev, watchman_dev, VIVE_VARIANT_PRO, tstatus, vs); 282 if (d == NULL) { 283 free(sensors_dev); 284 free(mainboard_dev); 285 return; 286 } 287 288 *out_vdev = d; 289 290 return; 291} 292 293 294static void 295init_valve_index(struct xrt_prober *xp, 296 struct xrt_prober_device *dev, 297 struct xrt_prober_device **devices, 298 size_t device_count, 299 enum u_logging_level log_level, 300 struct vive_tracking_status tstatus, 301 struct vive_source *vs, 302 struct vive_device **out_vdev) 303{ 304 XRT_TRACE_MARKER(); 305 306 log_vive_device(log_level, xp, dev); 307 308 if (!u_prober_match_string(xp, dev, XRT_PROBER_STRING_MANUFACTURER, VALVE_INDEX_MANUFACTURER_STRING) || 309 !u_prober_match_string(xp, dev, XRT_PROBER_STRING_PRODUCT, VALVE_INDEX_PRODUCT_STRING)) { 310 U_LOG_E("Valve Index manufacturer string did not match."); 311 return; 312 } 313 314 struct os_hid_device *sensors_dev = NULL; 315 struct os_hid_device *watchman_dev = NULL; 316 317 int result = xrt_prober_open_hid_interface(xp, dev, 0, &sensors_dev); 318 if (result != 0) { 319 U_LOG_E("Could not open Index sensors device."); 320 return; 321 } 322 323 result = xrt_prober_open_hid_interface(xp, dev, 1, &watchman_dev); 324 if (result != 0) { 325 U_LOG_E("Could not open headset watchman device."); 326 return; 327 } 328 329 if (sensors_dev == NULL) { 330 U_LOG_E("Could not find Index sensors device."); 331 return; 332 } 333 334 if (watchman_dev == NULL) { 335 U_LOG_E("Could not find headset watchman device."); 336 return; 337 } 338 339 struct vive_device *d = vive_device_create(NULL, sensors_dev, watchman_dev, VIVE_VARIANT_INDEX, tstatus, vs); 340 if (d == NULL) { 341 return; 342 } 343 344 *out_vdev = d; 345} 346 347int 348vive_found(struct xrt_prober *xp, 349 struct xrt_prober_device **devices, 350 size_t device_count, 351 size_t index, 352 cJSON *attached_data, 353 struct vive_tracking_status tstatus, 354 struct vive_source *vs, 355 struct vive_config **out_vive_config, 356 struct xrt_device **out_xdev) 357{ 358 XRT_TRACE_MARKER(); 359 360 struct xrt_prober_device *dev = devices[index]; 361 362 enum u_logging_level log_level = debug_get_log_option_vive_log(); 363 364 log_vive_device(log_level, xp, dev); 365 366 if (!xrt_prober_can_open(xp, dev)) { 367 U_LOG_E("Could not open Vive device."); 368 return 0; 369 } 370 371 struct vive_device *vdev = NULL; 372 373 switch (dev->product_id) { 374 case VIVE_PID: { 375 init_vive1(xp, dev, devices, device_count, log_level, tstatus, vs, &vdev); 376 break; 377 } 378 case VIVE_PRO_MAINBOARD_PID: { 379 init_vive_pro(xp, dev, devices, device_count, log_level, tstatus, vs, &vdev); 380 break; 381 } 382 case VIVE_PRO2_MAINBOARD_PID: { 383 init_vive_pro2(xp, dev, devices, device_count, log_level, tstatus, vs, &vdev); 384 break; 385 } 386 case VIVE_PRO_LHR_PID: { 387 init_valve_index(xp, dev, devices, device_count, log_level, tstatus, vs, &vdev); 388 break; 389 } 390 default: U_LOG_E("No product ids matched %.4x", dev->product_id); return 0; 391 } 392 393 if (vdev == NULL) { 394 U_LOG_E("Failed after opening Vive device?"); 395 return 0; 396 } 397 398 *out_vive_config = &vdev->config; 399 *out_xdev = &vdev->base; 400 401 return 1; 402} 403 404int 405vive_controller_found(struct xrt_prober *xp, 406 struct xrt_prober_device **devices, 407 size_t device_count, 408 size_t index, 409 cJSON *attached_data, 410 struct xrt_device **out_xdevs) 411{ 412 XRT_TRACE_MARKER(); 413 414 struct xrt_prober_device *dev = devices[index]; 415 int ret; 416 417 static int controller_num = 0; 418 419 struct os_hid_device *controller_hid = NULL; 420 ret = xp->open_hid_interface(xp, dev, 0, &controller_hid); 421 if (ret != 0) { 422 U_LOG_E("Could not open Vive controller device."); 423 return 0; 424 } 425 426 enum watchman_gen gen = WATCHMAN_GEN_UNKNOWN; 427 if (dev->vendor_id == VALVE_VID && dev->product_id == VIVE_WATCHMAN_DONGLE) { 428 gen = WATCHMAN_GEN1; 429 } else if (dev->vendor_id == VALVE_VID && dev->product_id == VIVE_WATCHMAN_DONGLE_GEN2) { 430 gen = WATCHMAN_GEN2; 431 } else { 432 U_LOG_E("Unknown watchman gen"); 433 } 434 435 struct vive_controller_device *d = vive_controller_create(controller_hid, gen, controller_num); 436 437 if (d == NULL) { 438 return 0; 439 } 440 441 *out_xdevs = &d->base; 442 443 controller_num++; 444 445 return 1; 446}