The open source OpenXR runtime

d/xreal_air: Implement changes to support Xreal Air 2 Ultra

Signed-off-by: Jacki <jacki@thejackimonster.de>
Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2436>

authored by

TheJackiMonster and committed by
Simon Zeni
80040ff3 2bf7f5c1

+211 -64
+106 -24
src/xrt/drivers/xreal_air/xreal_air_hmd.c
··· 1 - // Copyright 2023-2024, Tobias Frisch 1 + // Copyright 2023-2025, Tobias Frisch 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file 5 5 * @brief Xreal Air packet parsing implementation. 6 - * @author Tobias Frisch <thejackimonster@gmail.com> 6 + * @author Tobias Frisch <jacki@thejackimonster.de> 7 7 * @ingroup drv_xreal_air 8 8 */ 9 9 ··· 34 34 #define XREAL_AIR_DEBUG(hmd, ...) U_LOG_XDEV_IFL_D(&hmd->base, hmd->log_level, __VA_ARGS__) 35 35 #define XREAL_AIR_ERROR(hmd, ...) U_LOG_XDEV_IFL_E(&hmd->base, hmd->log_level, __VA_ARGS__) 36 36 37 - #define SENSOR_BUFFER_SIZE 64 37 + #define SENSOR_BUFFER_SIZE 512 38 38 #define CONTROL_BUFFER_SIZE 64 39 39 40 40 #define SENSOR_HEAD 0xFD ··· 88 88 89 89 uint32_t static_id; 90 90 bool display_on; 91 + uint8_t blend_state; 92 + uint8_t control_mode; 91 93 uint8_t imu_stream_state; 92 94 93 95 enum u_logging_level log_level; 96 + uint16_t max_sensor_buffer_size; 94 97 95 98 uint32_t calibration_buffer_len; 96 99 uint32_t calibration_buffer_pos; ··· 406 409 ((data->data[0] << 0u) | (data->data[1] << 8u) | (data->data[2] << 16u) | (data->data[3] << 24u)); 407 410 408 411 hmd->calibration_buffer_len = calibration_data_length; 412 + hmd->calibration_valid = false; 409 413 410 414 if (hmd->calibration_buffer_len > 0) { 411 415 if (hmd->calibration_buffer) { ··· 426 430 handle_sensor_control_cal_data_get_next_segment(struct xreal_air_hmd *hmd, 427 431 const struct xreal_air_parsed_sensor_control_data *data) 428 432 { 429 - if (hmd->calibration_buffer_len == 0) { 433 + if (hmd->calibration_valid) { 434 + return; 435 + } else if (hmd->calibration_buffer_len == 0) { 430 436 request_sensor_control_get_cal_data_length(hmd); 431 437 return; 432 438 } ··· 437 443 return; 438 444 } 439 445 446 + uint16_t data_buffer_size = SENSOR_BUFFER_SIZE; 447 + 448 + if (data_buffer_size > hmd->max_sensor_buffer_size) { 449 + data_buffer_size = hmd->max_sensor_buffer_size; 450 + } 451 + 452 + if (data_buffer_size <= 8) { 453 + XREAL_AIR_ERROR(hmd, "Failed to receive next calibration data from buffer!"); 454 + return; 455 + } 456 + 457 + data_buffer_size -= 8; 458 + 440 459 const uint32_t remaining = (hmd->calibration_buffer_len - hmd->calibration_buffer_pos); 441 - const uint8_t next = (remaining > 56 ? 56 : remaining); 460 + const uint16_t next = (remaining > data_buffer_size ? data_buffer_size : remaining); 442 461 443 462 if (hmd->calibration_buffer) { 444 463 memcpy(hmd->calibration_buffer + hmd->calibration_buffer_pos, data->data, next); ··· 453 472 // Parse calibration data from raw json. 454 473 if (!xreal_air_parse_calibration_buffer(&hmd->calibration, hmd->calibration_buffer, 455 474 hmd->calibration_buffer_len)) { 475 + hmd->calibration_valid = false; 476 + 456 477 XREAL_AIR_ERROR(hmd, "Failed parse calibration data!"); 457 478 } else { 458 479 hmd->calibration_valid = true; ··· 481 502 482 503 if (hmd->static_id == 0) { 483 504 request_sensor_control_get_static_id(hmd); 484 - } else if (!hmd->calibration_valid) { 505 + } else if ((!hmd->calibration_valid) && (!hmd->calibration_buffer_len)) { 485 506 request_sensor_control_get_cal_data_length(hmd); 486 507 } 487 508 } ··· 495 516 496 517 hmd->static_id = static_id; 497 518 498 - if (!hmd->calibration_valid) { 519 + if ((!hmd->calibration_valid) && (!hmd->calibration_buffer_len)) { 499 520 request_sensor_control_get_cal_data_length(hmd); 500 521 } 501 522 } 502 523 503 524 static void 504 - handle_sensor_control_data_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, int size) 525 + handle_sensor_control_data_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, size_t size) 505 526 { 506 527 struct xreal_air_parsed_sensor_control_data data; 507 528 508 - if (!xreal_air_parse_sensor_control_data_packet(&data, buffer, size)) { 529 + if (!xreal_air_parse_sensor_control_data_packet(&data, buffer, size, hmd->max_sensor_buffer_size)) { 509 530 XREAL_AIR_ERROR(hmd, "Could not decode sensor control data packet"); 510 531 } 511 532 ··· 526 547 } 527 548 528 549 static void 529 - handle_sensor_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, int size) 550 + handle_sensor_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, size_t size) 530 551 { 531 552 if (buffer[0] == 0xAA) { 532 553 handle_sensor_control_data_msg(hmd, buffer, size); ··· 536 557 timepoint_ns now_ns = (timepoint_ns)os_monotonic_get_ns(); 537 558 uint64_t last_timestamp = hmd->last.timestamp; 538 559 539 - if (!xreal_air_parse_sensor_packet(&hmd->last, buffer, size)) { 560 + if (!xreal_air_parse_sensor_packet(&hmd->last, buffer, size, hmd->max_sensor_buffer_size)) { 540 561 XREAL_AIR_ERROR(hmd, "Could not decode sensor packet"); 541 562 } else { 542 563 hmd->imu_stream_state = 0x1; ··· 576 597 sensor_clear_queue(struct xreal_air_hmd *hmd) 577 598 { 578 599 uint8_t buffer[SENSOR_BUFFER_SIZE]; 600 + size_t buffer_size = SENSOR_BUFFER_SIZE; 579 601 580 - while (os_hid_read(hmd->hid_sensor, buffer, SENSOR_BUFFER_SIZE, 0) > 0) { 602 + if (buffer_size > hmd->max_sensor_buffer_size) { 603 + buffer_size = hmd->max_sensor_buffer_size; 604 + } 605 + 606 + while (os_hid_read(hmd->hid_sensor, buffer, buffer_size, 0) > 0) { 581 607 // Just drop the packets. 582 608 } 583 609 } ··· 586 612 sensor_read_one_packet(struct xreal_air_hmd *hmd) 587 613 { 588 614 uint8_t buffer[SENSOR_BUFFER_SIZE]; 615 + size_t buffer_size = SENSOR_BUFFER_SIZE; 589 616 590 - int size = os_hid_read(hmd->hid_sensor, buffer, SENSOR_BUFFER_SIZE, 0); 617 + if (buffer_size > hmd->max_sensor_buffer_size) { 618 + buffer_size = hmd->max_sensor_buffer_size; 619 + } 620 + 621 + int size = os_hid_read(hmd->hid_sensor, buffer, buffer_size, 0); 591 622 if (size <= 0) { 592 623 return size; 593 624 } 594 625 595 - handle_sensor_msg(hmd, buffer, size); 626 + handle_sensor_msg(hmd, buffer, (size_t)size); 596 627 return 0; 597 628 } 598 629 ··· 711 742 } 712 743 713 744 static void 745 + handle_control_display_toggled(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_control *control) 746 + { 747 + // State of display 748 + const uint8_t display_state = control->data[0]; 749 + 750 + hmd->display_on = (display_state != 0); 751 + } 752 + 753 + static void 714 754 handle_control_button(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_control *control) 715 755 { 716 756 // Physical button ··· 736 776 hmd->wants.brightness = brightness; 737 777 break; 738 778 } 739 - case XREAL_AIR_BUTTON_VIRT_MODE_UP: { 740 - const uint8_t display_mode = hmd->state.display_mode; 779 + case XREAL_AIR_BUTTON_VIRT_UP: { 780 + switch (hmd->control_mode) { 781 + case XREAL_AIR_CONTROL_MODE_BRIGHTNESS: break; 782 + case XREAL_AIR_CONTROL_MODE_VOLUME: break; 783 + default: { 784 + XREAL_AIR_ERROR(hmd, "Got unknown mode increase, 0x%02x (0x%02x)", hmd->control_mode, value); 785 + break; 786 + } 787 + } 741 788 742 - if (display_mode == XREAL_AIR_DISPLAY_MODE_2D) { 743 - hmd->wants.display_mode = XREAL_AIR_DISPLAY_MODE_3D; 789 + break; 790 + } 791 + case XREAL_AIR_BUTTON_VIRT_DOWN: { 792 + switch (hmd->control_mode) { 793 + case XREAL_AIR_CONTROL_MODE_BRIGHTNESS: break; 794 + case XREAL_AIR_CONTROL_MODE_VOLUME: break; 795 + default: { 796 + XREAL_AIR_ERROR(hmd, "Got unknown mode decrease, 0x%02x (0x%02x)", hmd->control_mode, value); 797 + break; 798 + } 744 799 } 745 800 746 801 break; 747 802 } 748 - case XREAL_AIR_BUTTON_VIRT_MODE_DOWN: { 803 + case XREAL_AIR_BUTTON_VIRT_MODE_2D: { 749 804 const uint8_t display_mode = hmd->state.display_mode; 750 805 751 - if (display_mode == XREAL_AIR_DISPLAY_MODE_3D) { 806 + if (display_mode != XREAL_AIR_DISPLAY_MODE_2D) { 752 807 hmd->wants.display_mode = XREAL_AIR_DISPLAY_MODE_2D; 753 808 } 754 809 810 + break; 811 + } 812 + case XREAL_AIR_BUTTON_VIRT_MODE_3D: { 813 + const uint8_t display_mode = hmd->state.display_mode; 814 + 815 + if (display_mode != XREAL_AIR_DISPLAY_MODE_3D) { 816 + hmd->wants.display_mode = XREAL_AIR_DISPLAY_MODE_3D; 817 + } 818 + 819 + break; 820 + } 821 + case XREAL_AIR_BUTTON_VIRT_BLEND_CYCLE: { 822 + hmd->blend_state = value; 823 + break; 824 + } 825 + case XREAL_AIR_BUTTON_VIRT_CONTROL_TOGGLE: { 826 + hmd->control_mode = value; 755 827 break; 756 828 } 757 829 default: { ··· 785 857 case XREAL_AIR_MSG_R_DISP_MODE: handle_control_display_mode(hmd, control); break; 786 858 case XREAL_AIR_MSG_W_DISP_MODE: break; 787 859 case XREAL_AIR_MSG_P_START_HEARTBEAT: handle_control_heartbeat_start(hmd, control); break; 860 + case XREAL_AIR_MSG_P_DISPLAY_TOGGLED: handle_control_display_toggled(hmd, control); break; 788 861 case XREAL_AIR_MSG_P_BUTTON_PRESSED: handle_control_button(hmd, control); break; 789 862 case XREAL_AIR_MSG_P_ASYNC_TEXT_LOG: handle_control_async_text(hmd, control); break; 790 863 case XREAL_AIR_MSG_P_END_HEARTBEAT: handle_control_heartbeat_end(hmd, control); break; ··· 1065 1138 const enum xrt_space_relation_flags flags = (enum xrt_space_relation_flags)( 1066 1139 XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT); 1067 1140 1068 - struct xrt_space_relation relation; 1069 - U_ZERO(&relation); // Clear out the relation. 1141 + struct xrt_space_relation relation = XRT_SPACE_RELATION_ZERO; 1070 1142 relation.relation_flags = flags; 1071 1143 1072 1144 m_relation_history_get(hmd->relation_hist, at_timestamp_ns, &relation); 1073 1145 relation.relation_flags = flags; // Needed after history_get 1074 1146 1075 1147 *out_relation = relation; 1148 + struct xrt_quat *orientation = &out_relation->pose.orientation; 1076 1149 1077 1150 // Make sure that the orientation is valid. 1078 - math_quat_normalize(&out_relation->pose.orientation); 1151 + if (math_quat_dot(orientation, orientation) > 0.0f) { 1152 + math_quat_normalize(orientation); 1153 + } else { 1154 + orientation->w = 1.0f; 1155 + } 1156 + 1079 1157 return XRT_SUCCESS; 1080 1158 } 1081 1159 ··· 1104 1182 struct xrt_device * 1105 1183 xreal_air_hmd_create_device(struct os_hid_device *sensor_device, 1106 1184 struct os_hid_device *control_device, 1107 - enum u_logging_level log_level) 1185 + enum u_logging_level log_level, 1186 + uint16_t max_sensor_buffer_size) 1108 1187 { 1109 1188 enum u_device_alloc_flags flags = 1110 1189 (enum u_device_alloc_flags)(U_DEVICE_ALLOC_HMD | U_DEVICE_ALLOC_TRACKING_NONE); ··· 1112 1191 int ret; 1113 1192 1114 1193 hmd->log_level = log_level; 1194 + hmd->max_sensor_buffer_size = max_sensor_buffer_size; 1115 1195 hmd->base.update_inputs = xreal_air_hmd_update_inputs; 1116 1196 hmd->base.get_tracked_pose = xreal_air_hmd_get_tracked_pose; 1117 1197 hmd->base.get_view_poses = u_device_get_view_poses; ··· 1134 1214 1135 1215 hmd->static_id = 0; 1136 1216 hmd->display_on = false; 1217 + hmd->blend_state = XREAL_AIR_BLEND_STATE_DEFAULT; 1218 + hmd->control_mode = XREAL_AIR_CONTROL_MODE_BRIGHTNESS; 1137 1219 hmd->imu_stream_state = 0; 1138 1220 1139 1221 hmd->calibration_buffer = NULL;
+26 -11
src/xrt/drivers/xreal_air/xreal_air_hmd.h
··· 1 - // Copyright 2023-2024, Tobias Frisch 1 + // Copyright 2023-2025, Tobias Frisch 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file 5 5 * @brief Xreal Air packet parsing implementation. 6 - * @author Tobias Frisch <thejackimonster@gmail.com> 6 + * @author Tobias Frisch <jacki@thejackimonster.de> 7 7 * @ingroup drv_xreal_air 8 8 */ 9 9 ··· 20 20 extern "C" { 21 21 #endif 22 22 23 - #define XREAL_AIR_HANDLE_IFACE 3 24 - #define XREAL_AIR_CONTROL_IFACE 4 25 - 26 23 #define XREAL_AIR_MSG_R_BRIGHTNESS 0x03 27 24 #define XREAL_AIR_MSG_W_BRIGHTNESS 0x04 28 25 #define XREAL_AIR_MSG_R_DISP_MODE 0x07 29 26 #define XREAL_AIR_MSG_W_DISP_MODE 0x08 30 27 31 28 #define XREAL_AIR_MSG_P_START_HEARTBEAT 0x6c02 29 + #define XREAL_AIR_MSG_P_DISPLAY_TOGGLED 0x6C04 32 30 #define XREAL_AIR_MSG_P_BUTTON_PRESSED 0x6C05 33 31 #define XREAL_AIR_MSG_P_END_HEARTBEAT 0x6c12 34 32 #define XREAL_AIR_MSG_P_ASYNC_TEXT_LOG 0x6c09 ··· 41 39 #define XREAL_AIR_BUTTON_VIRT_MENU_TOGGLE 0x3 42 40 #define XREAL_AIR_BUTTON_VIRT_BRIGHTNESS_UP 0x6 43 41 #define XREAL_AIR_BUTTON_VIRT_BRIGHTNESS_DOWN 0x7 44 - #define XREAL_AIR_BUTTON_VIRT_MODE_UP 0x8 45 - #define XREAL_AIR_BUTTON_VIRT_MODE_DOWN 0x9 42 + #define XREAL_AIR_BUTTON_VIRT_UP 0x8 43 + #define XREAL_AIR_BUTTON_VIRT_DOWN 0x9 44 + #define XREAL_AIR_BUTTON_VIRT_MODE_2D 0xA 45 + #define XREAL_AIR_BUTTON_VIRT_MODE_3D 0xB 46 + #define XREAL_AIR_BUTTON_VIRT_BLEND_CYCLE 0xC 47 + #define XREAL_AIR_BUTTON_VIRT_CONTROL_TOGGLE 0xF 48 + 49 + #define XREAL_AIR_BLEND_STATE_LOW 0x0 50 + #define XREAL_AIR_BLEND_STATE_DEFAULT 0x1 51 + #define XREAL_AIR_BLEND_STATE_MEDIUM 0x2 52 + #define XREAL_AIR_BLEND_STATE_FULL 0x3 53 + 54 + #define XREAL_AIR_CONTROL_MODE_BRIGHTNESS 0x0 55 + #define XREAL_AIR_CONTROL_MODE_VOLUME 0x1 46 56 47 57 #define XREAL_AIR_BRIGHTNESS_MIN 0 48 58 #define XREAL_AIR_BRIGHTNESS_MAX 7 ··· 122 132 uint16_t length; 123 133 uint8_t msgid; 124 134 125 - uint8_t data[56]; 135 + uint8_t data[512 - 8]; 126 136 }; 127 137 128 138 /*! ··· 147 157 struct xrt_device * 148 158 xreal_air_hmd_create_device(struct os_hid_device *sensor_device, 149 159 struct os_hid_device *control_device, 150 - enum u_logging_level log_level); 160 + enum u_logging_level log_level, 161 + uint16_t max_sensor_buffer_size); 151 162 152 163 bool 153 164 xreal_air_parse_calibration_buffer(struct xreal_air_parsed_calibration *calibration, const char *buffer, size_t size); 154 165 155 166 bool 156 - xreal_air_parse_sensor_packet(struct xreal_air_parsed_sensor *sensor, const uint8_t *buffer, int size); 167 + xreal_air_parse_sensor_packet(struct xreal_air_parsed_sensor *sensor, 168 + const uint8_t *buffer, 169 + size_t size, 170 + size_t max_size); 157 171 158 172 bool 159 173 xreal_air_parse_sensor_control_data_packet(struct xreal_air_parsed_sensor_control_data *data, 160 174 const uint8_t *buffer, 161 - int size); 175 + size_t size, 176 + size_t max_size); 162 177 163 178 bool 164 179 xreal_air_parse_control_packet(struct xreal_air_parsed_control *control, const uint8_t *buffer, int size);
+9 -2
src/xrt/drivers/xreal_air/xreal_air_interface.h
··· 1 - // Copyright 2023-2024, Tobias Frisch 1 + // Copyright 2023-2025, Tobias Frisch 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file 5 5 * @brief Xreal Air packet parsing implementation. 6 - * @author Tobias Frisch <thejackimonster@gmail.com> 6 + * @author Tobias Frisch <jacki@thejackimonster.de> 7 7 * @ingroup drv_xreal_air 8 8 */ 9 9 ··· 47 47 * @ingroup drv_xreal_air 48 48 */ 49 49 #define XREAL_AIR_2_PRO_PID 0x0432 50 + 51 + /*! 52 + * Product id for Xreal Air 2 Ultra. 53 + * 54 + * @ingroup drv_xreal_air 55 + */ 56 + #define XREAL_AIR_2_ULTRA_PID 0x0426 50 57 51 58 /*! 52 59 * Builder setup for Xreal Air glasses.
+41 -21
src/xrt/drivers/xreal_air/xreal_air_packet.c
··· 1 - // Copyright 2023-2024, Tobias Frisch 1 + // Copyright 2023-2025, Tobias Frisch 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file 5 5 * @brief Xreal Air packet parsing implementation. 6 - * @author Tobias Frisch <thejackimonster@gmail.com> 6 + * @author Tobias Frisch <jacki@thejackimonster.de> 7 7 * @ingroup drv_xreal_air 8 8 */ 9 9 ··· 227 227 read_i15_to_i32(buffer, &sample->mag.z); 228 228 } 229 229 230 + static void 231 + parse_calibration_json(struct xreal_air_parsed_calibration *calibration, cJSON *dev1) 232 + { 233 + read_json_vec3(dev1, "accel_bias", &calibration->accel_bias); 234 + read_json_quat(dev1, "accel_q_gyro", &calibration->accel_q_gyro); 235 + read_json_vec3(dev1, "gyro_bias", &calibration->gyro_bias); 236 + read_json_quat(dev1, "gyro_q_mag", &calibration->gyro_q_mag); 237 + read_json_vec3(dev1, "mag_bias", &calibration->mag_bias); 238 + 239 + read_json_vec3(dev1, "scale_accel", &calibration->scale_accel); 240 + read_json_vec3(dev1, "scale_gyro", &calibration->scale_gyro); 241 + read_json_vec3(dev1, "scale_mag", &calibration->scale_mag); 242 + 243 + read_json_array(dev1, "imu_noises", 4, calibration->imu_noises); 244 + } 245 + 230 246 231 247 /* 232 248 * 233 249 * Exported functions. 234 250 * 235 251 */ 252 + #include <stdio.h> 236 253 237 254 bool 238 255 xreal_air_parse_calibration_buffer(struct xreal_air_parsed_calibration *calibration, const char *buffer, size_t size) 239 256 { 257 + bool result = false; 258 + 240 259 cJSON *root = cJSON_ParseWithLength(buffer, size); 241 - 242 260 cJSON *imu = cJSON_GetObjectItem(root, "IMU"); 243 - cJSON *dev1 = cJSON_GetObjectItem(imu, "device_1"); 244 261 245 - read_json_vec3(dev1, "accel_bias", &calibration->accel_bias); 246 - read_json_quat(dev1, "accel_q_gyro", &calibration->accel_q_gyro); 247 - read_json_vec3(dev1, "gyro_bias", &calibration->gyro_bias); 248 - read_json_quat(dev1, "gyro_q_mag", &calibration->gyro_q_mag); 249 - read_json_vec3(dev1, "mag_bias", &calibration->mag_bias); 250 - 251 - read_json_vec3(dev1, "scale_accel", &calibration->scale_accel); 252 - read_json_vec3(dev1, "scale_gyro", &calibration->scale_gyro); 253 - read_json_vec3(dev1, "scale_mag", &calibration->scale_mag); 262 + if (imu) { 263 + cJSON *dev1 = cJSON_GetObjectItem(imu, "device_1"); 254 264 255 - read_json_array(dev1, "imu_noises", 4, calibration->imu_noises); 265 + if (dev1) { 266 + parse_calibration_json(calibration, dev1); 267 + result = true; 268 + } 269 + } 256 270 257 271 cJSON_Delete(root); 258 - return true; 272 + return result; 259 273 } 260 274 275 + #include <stdio.h> 276 + 261 277 bool 262 - xreal_air_parse_sensor_packet(struct xreal_air_parsed_sensor *sensor, const uint8_t *buffer, int size) 278 + xreal_air_parse_sensor_packet(struct xreal_air_parsed_sensor *sensor, 279 + const uint8_t *buffer, 280 + size_t size, 281 + size_t max_size) 263 282 { 264 283 const uint8_t *start = buffer; 265 284 266 - if (size != 64) { 285 + if ((size != max_size) || (size < 64)) { 267 286 return false; 268 287 } 269 288 ··· 295 314 bool 296 315 xreal_air_parse_sensor_control_data_packet(struct xreal_air_parsed_sensor_control_data *data, 297 316 const uint8_t *buffer, 298 - int size) 317 + size_t size, 318 + size_t max_size) 299 319 { 300 320 const uint8_t *start = buffer; 301 321 302 - if (size != 64) { 322 + if ((size != max_size) || (size < 8)) { 303 323 return false; 304 324 } 305 325 ··· 316 336 read_u8(&buffer, &data->msgid); 317 337 318 338 // Sensor control data depending on action 319 - read_u8_array(&buffer, data->data, 56); 339 + read_u8_array(&buffer, data->data, size - 8); 320 340 321 - return (size_t)buffer - (size_t)start == 64; 341 + return (size_t)buffer - (size_t)start == max_size; 322 342 } 323 343 324 344 bool
+29 -6
src/xrt/targets/common/target_builder_xreal_air.c
··· 1 - // Copyright 2023-2024, Tobias Frisch 1 + // Copyright 2023-2025, Tobias Frisch 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file 5 5 * @brief Xreal Air prober code. 6 - * @author Tobias Frisch <thejackimonster@gmail.com> 6 + * @author Tobias Frisch <jacki@thejackimonster.de> 7 7 * @ingroup drv_xreal_air 8 8 */ 9 9 ··· 46 46 "xreal_air", 47 47 }; 48 48 49 - #define XREAL_AIR_DRIVER_PRODUCT_IDS 3 49 + #define XREAL_AIR_DRIVER_PRODUCT_IDS 4 50 50 51 51 static const uint16_t driver_product_ids[XREAL_AIR_DRIVER_PRODUCT_IDS] = { 52 52 XREAL_AIR_PID, 53 53 XREAL_AIR_2_PID, 54 54 XREAL_AIR_2_PRO_PID, 55 + XREAL_AIR_2_ULTRA_PID, 56 + }; 57 + 58 + static const uint16_t driver_handle_ifaces[XREAL_AIR_DRIVER_PRODUCT_IDS] = { 59 + 3, 60 + 3, 61 + 3, 62 + 2, 63 + }; 64 + 65 + static const uint16_t driver_control_ifaces[XREAL_AIR_DRIVER_PRODUCT_IDS] = { 66 + 4, 67 + 4, 68 + 4, 69 + 0, 70 + }; 71 + 72 + static const uint16_t driver_max_sensor_buffer_sizes[XREAL_AIR_DRIVER_PRODUCT_IDS] = { 73 + 64, 74 + 64, 75 + 64, 76 + 512, 55 77 }; 56 78 57 79 ··· 142 164 } 143 165 144 166 struct os_hid_device *hid_handle = NULL; 145 - int result = xrt_prober_open_hid_interface(xp, dev_hmd, XREAL_AIR_HANDLE_IFACE, &hid_handle); 167 + int result = xrt_prober_open_hid_interface(xp, dev_hmd, driver_handle_ifaces[product_index], &hid_handle); 146 168 147 169 if (result != 0) { 148 170 XREAL_AIR_ERROR("Failed to open Xreal Air handle interface"); ··· 150 172 } 151 173 152 174 struct os_hid_device *hid_control = NULL; 153 - result = xrt_prober_open_hid_interface(xp, dev_hmd, XREAL_AIR_CONTROL_IFACE, &hid_control); 175 + result = xrt_prober_open_hid_interface(xp, dev_hmd, driver_control_ifaces[product_index], &hid_control); 154 176 155 177 if (result != 0) { 156 178 os_hid_destroy(hid_handle); ··· 172 194 goto fail; 173 195 } 174 196 175 - struct xrt_device *xreal_air_device = xreal_air_hmd_create_device(hid_handle, hid_control, xreal_air_log_level); 197 + struct xrt_device *xreal_air_device = xreal_air_hmd_create_device( 198 + hid_handle, hid_control, xreal_air_log_level, driver_max_sensor_buffer_sizes[product_index]); 176 199 177 200 if (xreal_air_device == NULL) { 178 201 XREAL_AIR_ERROR("Failed to initialise Xreal Air driver");