diff --git a/src/xrt/drivers/xreal_air/xreal_air_hmd.c b/src/xrt/drivers/xreal_air/xreal_air_hmd.c index dc9a3134a..2bd7d0b91 100644 --- a/src/xrt/drivers/xreal_air/xreal_air_hmd.c +++ b/src/xrt/drivers/xreal_air/xreal_air_hmd.c @@ -1,9 +1,9 @@ -// Copyright 2023-2024, Tobias Frisch +// Copyright 2023-2025, Tobias Frisch // SPDX-License-Identifier: BSL-1.0 /*! * @file * @brief Xreal Air packet parsing implementation. - * @author Tobias Frisch + * @author Tobias Frisch * @ingroup drv_xreal_air */ @@ -34,7 +34,7 @@ #define XREAL_AIR_DEBUG(hmd, ...) U_LOG_XDEV_IFL_D(&hmd->base, hmd->log_level, __VA_ARGS__) #define XREAL_AIR_ERROR(hmd, ...) U_LOG_XDEV_IFL_E(&hmd->base, hmd->log_level, __VA_ARGS__) -#define SENSOR_BUFFER_SIZE 64 +#define SENSOR_BUFFER_SIZE 512 #define CONTROL_BUFFER_SIZE 64 #define SENSOR_HEAD 0xFD @@ -88,9 +88,12 @@ struct xreal_air_hmd uint32_t static_id; bool display_on; + uint8_t blend_state; + uint8_t control_mode; uint8_t imu_stream_state; enum u_logging_level log_level; + uint16_t max_sensor_buffer_size; uint32_t calibration_buffer_len; uint32_t calibration_buffer_pos; @@ -406,6 +409,7 @@ handle_sensor_control_get_cal_data_length(struct xreal_air_hmd *hmd, ((data->data[0] << 0u) | (data->data[1] << 8u) | (data->data[2] << 16u) | (data->data[3] << 24u)); hmd->calibration_buffer_len = calibration_data_length; + hmd->calibration_valid = false; if (hmd->calibration_buffer_len > 0) { if (hmd->calibration_buffer) { @@ -426,7 +430,9 @@ static void handle_sensor_control_cal_data_get_next_segment(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_sensor_control_data *data) { - if (hmd->calibration_buffer_len == 0) { + if (hmd->calibration_valid) { + return; + } else if (hmd->calibration_buffer_len == 0) { request_sensor_control_get_cal_data_length(hmd); return; } @@ -437,8 +443,21 @@ handle_sensor_control_cal_data_get_next_segment(struct xreal_air_hmd *hmd, return; } + uint16_t data_buffer_size = SENSOR_BUFFER_SIZE; + + if (data_buffer_size > hmd->max_sensor_buffer_size) { + data_buffer_size = hmd->max_sensor_buffer_size; + } + + if (data_buffer_size <= 8) { + XREAL_AIR_ERROR(hmd, "Failed to receive next calibration data from buffer!"); + return; + } + + data_buffer_size -= 8; + const uint32_t remaining = (hmd->calibration_buffer_len - hmd->calibration_buffer_pos); - const uint8_t next = (remaining > 56 ? 56 : remaining); + const uint16_t next = (remaining > data_buffer_size ? data_buffer_size : remaining); if (hmd->calibration_buffer) { memcpy(hmd->calibration_buffer + hmd->calibration_buffer_pos, data->data, next); @@ -453,6 +472,8 @@ handle_sensor_control_cal_data_get_next_segment(struct xreal_air_hmd *hmd, // Parse calibration data from raw json. if (!xreal_air_parse_calibration_buffer(&hmd->calibration, hmd->calibration_buffer, hmd->calibration_buffer_len)) { + hmd->calibration_valid = false; + XREAL_AIR_ERROR(hmd, "Failed parse calibration data!"); } else { hmd->calibration_valid = true; @@ -481,7 +502,7 @@ handle_sensor_control_start_imu_data(struct xreal_air_hmd *hmd, const struct xre if (hmd->static_id == 0) { request_sensor_control_get_static_id(hmd); - } else if (!hmd->calibration_valid) { + } else if ((!hmd->calibration_valid) && (!hmd->calibration_buffer_len)) { request_sensor_control_get_cal_data_length(hmd); } } @@ -495,17 +516,17 @@ handle_sensor_control_get_static_id(struct xreal_air_hmd *hmd, const struct xrea hmd->static_id = static_id; - if (!hmd->calibration_valid) { + if ((!hmd->calibration_valid) && (!hmd->calibration_buffer_len)) { request_sensor_control_get_cal_data_length(hmd); } } static void -handle_sensor_control_data_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, int size) +handle_sensor_control_data_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, size_t size) { struct xreal_air_parsed_sensor_control_data data; - if (!xreal_air_parse_sensor_control_data_packet(&data, buffer, size)) { + if (!xreal_air_parse_sensor_control_data_packet(&data, buffer, size, hmd->max_sensor_buffer_size)) { XREAL_AIR_ERROR(hmd, "Could not decode sensor control data packet"); } @@ -526,7 +547,7 @@ handle_sensor_control_data_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, } static void -handle_sensor_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, int size) +handle_sensor_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, size_t size) { if (buffer[0] == 0xAA) { handle_sensor_control_data_msg(hmd, buffer, size); @@ -536,7 +557,7 @@ handle_sensor_msg(struct xreal_air_hmd *hmd, unsigned char *buffer, int size) timepoint_ns now_ns = (timepoint_ns)os_monotonic_get_ns(); uint64_t last_timestamp = hmd->last.timestamp; - if (!xreal_air_parse_sensor_packet(&hmd->last, buffer, size)) { + if (!xreal_air_parse_sensor_packet(&hmd->last, buffer, size, hmd->max_sensor_buffer_size)) { XREAL_AIR_ERROR(hmd, "Could not decode sensor packet"); } else { hmd->imu_stream_state = 0x1; @@ -576,8 +597,13 @@ static void sensor_clear_queue(struct xreal_air_hmd *hmd) { uint8_t buffer[SENSOR_BUFFER_SIZE]; + size_t buffer_size = SENSOR_BUFFER_SIZE; - while (os_hid_read(hmd->hid_sensor, buffer, SENSOR_BUFFER_SIZE, 0) > 0) { + if (buffer_size > hmd->max_sensor_buffer_size) { + buffer_size = hmd->max_sensor_buffer_size; + } + + while (os_hid_read(hmd->hid_sensor, buffer, buffer_size, 0) > 0) { // Just drop the packets. } } @@ -586,13 +612,18 @@ static int sensor_read_one_packet(struct xreal_air_hmd *hmd) { uint8_t buffer[SENSOR_BUFFER_SIZE]; + size_t buffer_size = SENSOR_BUFFER_SIZE; - int size = os_hid_read(hmd->hid_sensor, buffer, SENSOR_BUFFER_SIZE, 0); + if (buffer_size > hmd->max_sensor_buffer_size) { + buffer_size = hmd->max_sensor_buffer_size; + } + + int size = os_hid_read(hmd->hid_sensor, buffer, buffer_size, 0); if (size <= 0) { return size; } - handle_sensor_msg(hmd, buffer, size); + handle_sensor_msg(hmd, buffer, (size_t)size); return 0; } @@ -710,6 +741,15 @@ handle_control_heartbeat_start(struct xreal_air_hmd *hmd, const struct xreal_air // TODO } +static void +handle_control_display_toggled(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_control *control) +{ + // State of display + const uint8_t display_state = control->data[0]; + + hmd->display_on = (display_state != 0); +} + static void handle_control_button(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_control *control) { @@ -736,24 +776,56 @@ handle_control_button(struct xreal_air_hmd *hmd, const struct xreal_air_parsed_c hmd->wants.brightness = brightness; break; } - case XREAL_AIR_BUTTON_VIRT_MODE_UP: { - const uint8_t display_mode = hmd->state.display_mode; + case XREAL_AIR_BUTTON_VIRT_UP: { + switch (hmd->control_mode) { + case XREAL_AIR_CONTROL_MODE_BRIGHTNESS: break; + case XREAL_AIR_CONTROL_MODE_VOLUME: break; + default: { + XREAL_AIR_ERROR(hmd, "Got unknown mode increase, 0x%02x (0x%02x)", hmd->control_mode, value); + break; + } + } - if (display_mode == XREAL_AIR_DISPLAY_MODE_2D) { - hmd->wants.display_mode = XREAL_AIR_DISPLAY_MODE_3D; + break; + } + case XREAL_AIR_BUTTON_VIRT_DOWN: { + switch (hmd->control_mode) { + case XREAL_AIR_CONTROL_MODE_BRIGHTNESS: break; + case XREAL_AIR_CONTROL_MODE_VOLUME: break; + default: { + XREAL_AIR_ERROR(hmd, "Got unknown mode decrease, 0x%02x (0x%02x)", hmd->control_mode, value); + break; + } } break; } - case XREAL_AIR_BUTTON_VIRT_MODE_DOWN: { + case XREAL_AIR_BUTTON_VIRT_MODE_2D: { const uint8_t display_mode = hmd->state.display_mode; - if (display_mode == XREAL_AIR_DISPLAY_MODE_3D) { + if (display_mode != XREAL_AIR_DISPLAY_MODE_2D) { hmd->wants.display_mode = XREAL_AIR_DISPLAY_MODE_2D; } break; } + case XREAL_AIR_BUTTON_VIRT_MODE_3D: { + const uint8_t display_mode = hmd->state.display_mode; + + if (display_mode != XREAL_AIR_DISPLAY_MODE_3D) { + hmd->wants.display_mode = XREAL_AIR_DISPLAY_MODE_3D; + } + + break; + } + case XREAL_AIR_BUTTON_VIRT_BLEND_CYCLE: { + hmd->blend_state = value; + break; + } + case XREAL_AIR_BUTTON_VIRT_CONTROL_TOGGLE: { + hmd->control_mode = value; + break; + } default: { XREAL_AIR_ERROR(hmd, "Got unknown button pressed, 0x%02x (0x%02x)", virt_button, phys_button); break; @@ -785,6 +857,7 @@ handle_control_action_locked(struct xreal_air_hmd *hmd, const struct xreal_air_p case XREAL_AIR_MSG_R_DISP_MODE: handle_control_display_mode(hmd, control); break; case XREAL_AIR_MSG_W_DISP_MODE: break; case XREAL_AIR_MSG_P_START_HEARTBEAT: handle_control_heartbeat_start(hmd, control); break; + case XREAL_AIR_MSG_P_DISPLAY_TOGGLED: handle_control_display_toggled(hmd, control); break; case XREAL_AIR_MSG_P_BUTTON_PRESSED: handle_control_button(hmd, control); break; case XREAL_AIR_MSG_P_ASYNC_TEXT_LOG: handle_control_async_text(hmd, control); break; case XREAL_AIR_MSG_P_END_HEARTBEAT: handle_control_heartbeat_end(hmd, control); break; @@ -1065,17 +1138,22 @@ xreal_air_hmd_get_tracked_pose(struct xrt_device *xdev, const enum xrt_space_relation_flags flags = (enum xrt_space_relation_flags)( XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT); - struct xrt_space_relation relation; - U_ZERO(&relation); // Clear out the relation. + struct xrt_space_relation relation = XRT_SPACE_RELATION_ZERO; relation.relation_flags = flags; m_relation_history_get(hmd->relation_hist, at_timestamp_ns, &relation); relation.relation_flags = flags; // Needed after history_get *out_relation = relation; + struct xrt_quat *orientation = &out_relation->pose.orientation; // Make sure that the orientation is valid. - math_quat_normalize(&out_relation->pose.orientation); + if (math_quat_dot(orientation, orientation) > 0.0f) { + math_quat_normalize(orientation); + } else { + orientation->w = 1.0f; + } + return XRT_SUCCESS; } @@ -1104,7 +1182,8 @@ xreal_air_hmd_compute_distortion( struct xrt_device * xreal_air_hmd_create_device(struct os_hid_device *sensor_device, struct os_hid_device *control_device, - enum u_logging_level log_level) + enum u_logging_level log_level, + uint16_t max_sensor_buffer_size) { enum u_device_alloc_flags flags = (enum u_device_alloc_flags)(U_DEVICE_ALLOC_HMD | U_DEVICE_ALLOC_TRACKING_NONE); @@ -1112,6 +1191,7 @@ xreal_air_hmd_create_device(struct os_hid_device *sensor_device, int ret; hmd->log_level = log_level; + hmd->max_sensor_buffer_size = max_sensor_buffer_size; hmd->base.update_inputs = xreal_air_hmd_update_inputs; hmd->base.get_tracked_pose = xreal_air_hmd_get_tracked_pose; hmd->base.get_view_poses = u_device_get_view_poses; @@ -1134,6 +1214,8 @@ xreal_air_hmd_create_device(struct os_hid_device *sensor_device, hmd->static_id = 0; hmd->display_on = false; + hmd->blend_state = XREAL_AIR_BLEND_STATE_DEFAULT; + hmd->control_mode = XREAL_AIR_CONTROL_MODE_BRIGHTNESS; hmd->imu_stream_state = 0; hmd->calibration_buffer = NULL; diff --git a/src/xrt/drivers/xreal_air/xreal_air_hmd.h b/src/xrt/drivers/xreal_air/xreal_air_hmd.h index 35b07aa1b..7328a7a84 100644 --- a/src/xrt/drivers/xreal_air/xreal_air_hmd.h +++ b/src/xrt/drivers/xreal_air/xreal_air_hmd.h @@ -1,9 +1,9 @@ -// Copyright 2023-2024, Tobias Frisch +// Copyright 2023-2025, Tobias Frisch // SPDX-License-Identifier: BSL-1.0 /*! * @file * @brief Xreal Air packet parsing implementation. - * @author Tobias Frisch + * @author Tobias Frisch * @ingroup drv_xreal_air */ @@ -20,15 +20,13 @@ extern "C" { #endif -#define XREAL_AIR_HANDLE_IFACE 3 -#define XREAL_AIR_CONTROL_IFACE 4 - #define XREAL_AIR_MSG_R_BRIGHTNESS 0x03 #define XREAL_AIR_MSG_W_BRIGHTNESS 0x04 #define XREAL_AIR_MSG_R_DISP_MODE 0x07 #define XREAL_AIR_MSG_W_DISP_MODE 0x08 #define XREAL_AIR_MSG_P_START_HEARTBEAT 0x6c02 +#define XREAL_AIR_MSG_P_DISPLAY_TOGGLED 0x6C04 #define XREAL_AIR_MSG_P_BUTTON_PRESSED 0x6C05 #define XREAL_AIR_MSG_P_END_HEARTBEAT 0x6c12 #define XREAL_AIR_MSG_P_ASYNC_TEXT_LOG 0x6c09 @@ -41,8 +39,20 @@ extern "C" { #define XREAL_AIR_BUTTON_VIRT_MENU_TOGGLE 0x3 #define XREAL_AIR_BUTTON_VIRT_BRIGHTNESS_UP 0x6 #define XREAL_AIR_BUTTON_VIRT_BRIGHTNESS_DOWN 0x7 -#define XREAL_AIR_BUTTON_VIRT_MODE_UP 0x8 -#define XREAL_AIR_BUTTON_VIRT_MODE_DOWN 0x9 +#define XREAL_AIR_BUTTON_VIRT_UP 0x8 +#define XREAL_AIR_BUTTON_VIRT_DOWN 0x9 +#define XREAL_AIR_BUTTON_VIRT_MODE_2D 0xA +#define XREAL_AIR_BUTTON_VIRT_MODE_3D 0xB +#define XREAL_AIR_BUTTON_VIRT_BLEND_CYCLE 0xC +#define XREAL_AIR_BUTTON_VIRT_CONTROL_TOGGLE 0xF + +#define XREAL_AIR_BLEND_STATE_LOW 0x0 +#define XREAL_AIR_BLEND_STATE_DEFAULT 0x1 +#define XREAL_AIR_BLEND_STATE_MEDIUM 0x2 +#define XREAL_AIR_BLEND_STATE_FULL 0x3 + +#define XREAL_AIR_CONTROL_MODE_BRIGHTNESS 0x0 +#define XREAL_AIR_CONTROL_MODE_VOLUME 0x1 #define XREAL_AIR_BRIGHTNESS_MIN 0 #define XREAL_AIR_BRIGHTNESS_MAX 7 @@ -122,7 +132,7 @@ struct xreal_air_parsed_sensor_control_data uint16_t length; uint8_t msgid; - uint8_t data[56]; + uint8_t data[512 - 8]; }; /*! @@ -147,18 +157,23 @@ struct xreal_air_parsed_control struct xrt_device * xreal_air_hmd_create_device(struct os_hid_device *sensor_device, struct os_hid_device *control_device, - enum u_logging_level log_level); + enum u_logging_level log_level, + uint16_t max_sensor_buffer_size); bool xreal_air_parse_calibration_buffer(struct xreal_air_parsed_calibration *calibration, const char *buffer, size_t size); bool -xreal_air_parse_sensor_packet(struct xreal_air_parsed_sensor *sensor, const uint8_t *buffer, int size); +xreal_air_parse_sensor_packet(struct xreal_air_parsed_sensor *sensor, + const uint8_t *buffer, + size_t size, + size_t max_size); bool xreal_air_parse_sensor_control_data_packet(struct xreal_air_parsed_sensor_control_data *data, const uint8_t *buffer, - int size); + size_t size, + size_t max_size); bool xreal_air_parse_control_packet(struct xreal_air_parsed_control *control, const uint8_t *buffer, int size); diff --git a/src/xrt/drivers/xreal_air/xreal_air_interface.h b/src/xrt/drivers/xreal_air/xreal_air_interface.h index 1112456b1..587e3c9d2 100644 --- a/src/xrt/drivers/xreal_air/xreal_air_interface.h +++ b/src/xrt/drivers/xreal_air/xreal_air_interface.h @@ -1,9 +1,9 @@ -// Copyright 2023-2024, Tobias Frisch +// Copyright 2023-2025, Tobias Frisch // SPDX-License-Identifier: BSL-1.0 /*! * @file * @brief Xreal Air packet parsing implementation. - * @author Tobias Frisch + * @author Tobias Frisch * @ingroup drv_xreal_air */ @@ -48,6 +48,13 @@ extern "C" { */ #define XREAL_AIR_2_PRO_PID 0x0432 +/*! + * Product id for Xreal Air 2 Ultra. + * + * @ingroup drv_xreal_air + */ +#define XREAL_AIR_2_ULTRA_PID 0x0426 + /*! * Builder setup for Xreal Air glasses. * diff --git a/src/xrt/drivers/xreal_air/xreal_air_packet.c b/src/xrt/drivers/xreal_air/xreal_air_packet.c index f2ad7e582..e837c79e8 100644 --- a/src/xrt/drivers/xreal_air/xreal_air_packet.c +++ b/src/xrt/drivers/xreal_air/xreal_air_packet.c @@ -1,9 +1,9 @@ -// Copyright 2023-2024, Tobias Frisch +// Copyright 2023-2025, Tobias Frisch // SPDX-License-Identifier: BSL-1.0 /*! * @file * @brief Xreal Air packet parsing implementation. - * @author Tobias Frisch + * @author Tobias Frisch * @ingroup drv_xreal_air */ @@ -227,43 +227,62 @@ read_sample(const uint8_t **buffer, struct xreal_air_parsed_sample *sample) read_i15_to_i32(buffer, &sample->mag.z); } +static void +parse_calibration_json(struct xreal_air_parsed_calibration *calibration, cJSON *dev1) +{ + read_json_vec3(dev1, "accel_bias", &calibration->accel_bias); + read_json_quat(dev1, "accel_q_gyro", &calibration->accel_q_gyro); + read_json_vec3(dev1, "gyro_bias", &calibration->gyro_bias); + read_json_quat(dev1, "gyro_q_mag", &calibration->gyro_q_mag); + read_json_vec3(dev1, "mag_bias", &calibration->mag_bias); + + read_json_vec3(dev1, "scale_accel", &calibration->scale_accel); + read_json_vec3(dev1, "scale_gyro", &calibration->scale_gyro); + read_json_vec3(dev1, "scale_mag", &calibration->scale_mag); + + read_json_array(dev1, "imu_noises", 4, calibration->imu_noises); +} + /* * * Exported functions. * */ +#include bool xreal_air_parse_calibration_buffer(struct xreal_air_parsed_calibration *calibration, const char *buffer, size_t size) { - cJSON *root = cJSON_ParseWithLength(buffer, size); + bool result = false; + cJSON *root = cJSON_ParseWithLength(buffer, size); cJSON *imu = cJSON_GetObjectItem(root, "IMU"); - cJSON *dev1 = cJSON_GetObjectItem(imu, "device_1"); - read_json_vec3(dev1, "accel_bias", &calibration->accel_bias); - read_json_quat(dev1, "accel_q_gyro", &calibration->accel_q_gyro); - read_json_vec3(dev1, "gyro_bias", &calibration->gyro_bias); - read_json_quat(dev1, "gyro_q_mag", &calibration->gyro_q_mag); - read_json_vec3(dev1, "mag_bias", &calibration->mag_bias); - - read_json_vec3(dev1, "scale_accel", &calibration->scale_accel); - read_json_vec3(dev1, "scale_gyro", &calibration->scale_gyro); - read_json_vec3(dev1, "scale_mag", &calibration->scale_mag); + if (imu) { + cJSON *dev1 = cJSON_GetObjectItem(imu, "device_1"); - read_json_array(dev1, "imu_noises", 4, calibration->imu_noises); + if (dev1) { + parse_calibration_json(calibration, dev1); + result = true; + } + } cJSON_Delete(root); - return true; + return result; } +#include + bool -xreal_air_parse_sensor_packet(struct xreal_air_parsed_sensor *sensor, const uint8_t *buffer, int size) +xreal_air_parse_sensor_packet(struct xreal_air_parsed_sensor *sensor, + const uint8_t *buffer, + size_t size, + size_t max_size) { const uint8_t *start = buffer; - if (size != 64) { + if ((size != max_size) || (size < 64)) { return false; } @@ -295,11 +314,12 @@ xreal_air_parse_sensor_packet(struct xreal_air_parsed_sensor *sensor, const uint bool xreal_air_parse_sensor_control_data_packet(struct xreal_air_parsed_sensor_control_data *data, const uint8_t *buffer, - int size) + size_t size, + size_t max_size) { const uint8_t *start = buffer; - if (size != 64) { + if ((size != max_size) || (size < 8)) { return false; } @@ -316,9 +336,9 @@ xreal_air_parse_sensor_control_data_packet(struct xreal_air_parsed_sensor_contro read_u8(&buffer, &data->msgid); // Sensor control data depending on action - read_u8_array(&buffer, data->data, 56); + read_u8_array(&buffer, data->data, size - 8); - return (size_t)buffer - (size_t)start == 64; + return (size_t)buffer - (size_t)start == max_size; } bool diff --git a/src/xrt/targets/common/target_builder_xreal_air.c b/src/xrt/targets/common/target_builder_xreal_air.c index eb8fdef38..6f5eaa0fc 100644 --- a/src/xrt/targets/common/target_builder_xreal_air.c +++ b/src/xrt/targets/common/target_builder_xreal_air.c @@ -1,9 +1,9 @@ -// Copyright 2023-2024, Tobias Frisch +// Copyright 2023-2025, Tobias Frisch // SPDX-License-Identifier: BSL-1.0 /*! * @file * @brief Xreal Air prober code. - * @author Tobias Frisch + * @author Tobias Frisch * @ingroup drv_xreal_air */ @@ -46,12 +46,34 @@ static const char *driver_list[] = { "xreal_air", }; -#define XREAL_AIR_DRIVER_PRODUCT_IDS 3 +#define XREAL_AIR_DRIVER_PRODUCT_IDS 4 static const uint16_t driver_product_ids[XREAL_AIR_DRIVER_PRODUCT_IDS] = { XREAL_AIR_PID, XREAL_AIR_2_PID, XREAL_AIR_2_PRO_PID, + XREAL_AIR_2_ULTRA_PID, +}; + +static const uint16_t driver_handle_ifaces[XREAL_AIR_DRIVER_PRODUCT_IDS] = { + 3, + 3, + 3, + 2, +}; + +static const uint16_t driver_control_ifaces[XREAL_AIR_DRIVER_PRODUCT_IDS] = { + 4, + 4, + 4, + 0, +}; + +static const uint16_t driver_max_sensor_buffer_sizes[XREAL_AIR_DRIVER_PRODUCT_IDS] = { + 64, + 64, + 64, + 512, }; @@ -142,7 +164,7 @@ xreal_air_open_system_impl(struct xrt_builder *xb, } struct os_hid_device *hid_handle = NULL; - int result = xrt_prober_open_hid_interface(xp, dev_hmd, XREAL_AIR_HANDLE_IFACE, &hid_handle); + int result = xrt_prober_open_hid_interface(xp, dev_hmd, driver_handle_ifaces[product_index], &hid_handle); if (result != 0) { XREAL_AIR_ERROR("Failed to open Xreal Air handle interface"); @@ -150,7 +172,7 @@ xreal_air_open_system_impl(struct xrt_builder *xb, } struct os_hid_device *hid_control = NULL; - result = xrt_prober_open_hid_interface(xp, dev_hmd, XREAL_AIR_CONTROL_IFACE, &hid_control); + result = xrt_prober_open_hid_interface(xp, dev_hmd, driver_control_ifaces[product_index], &hid_control); if (result != 0) { os_hid_destroy(hid_handle); @@ -172,7 +194,8 @@ xreal_air_open_system_impl(struct xrt_builder *xb, goto fail; } - struct xrt_device *xreal_air_device = xreal_air_hmd_create_device(hid_handle, hid_control, xreal_air_log_level); + struct xrt_device *xreal_air_device = xreal_air_hmd_create_device( + hid_handle, hid_control, xreal_air_log_level, driver_max_sensor_buffer_sizes[product_index]); if (xreal_air_device == NULL) { XREAL_AIR_ERROR("Failed to initialise Xreal Air driver");