From 1d1c343f462b37767f2985b483916ca60d646040 Mon Sep 17 00:00:00 2001 From: shiritbrook <31325683+shiritbrook@users.noreply.github.com> Date: Wed, 17 Jun 2020 15:01:51 -0700 Subject: [PATCH 01/61] Update readme.md --- examples/post-processing/readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/post-processing/readme.md b/examples/post-processing/readme.md index bea240c828..c3364d1b13 100644 --- a/examples/post-processing/readme.md +++ b/examples/post-processing/readme.md @@ -14,6 +14,7 @@ This example demonstrates usage of the following processing blocks: * Temporal * Filters depth data by looking into previous frames. +For further infomration please refer to [Depth Post-Processing for Intel® RealSense™ D400 Depth Cameras](https://dev.intelrealsense.com/docs/depth-post-processing) ## Expected Output ![expected output](https://user-images.githubusercontent.com/22654243/35924136-dd9cd1b6-0c2a-11e8-925a-84a52c0a5b96.gif) From 475a62d08dcc5a7959353b0b6954018597d6bc83 Mon Sep 17 00:00:00 2001 From: shiritbrook <31325683+shiritbrook@users.noreply.github.com> Date: Wed, 17 Jun 2020 15:04:41 -0700 Subject: [PATCH 02/61] Update readme.md --- examples/post-processing/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/post-processing/readme.md b/examples/post-processing/readme.md index c3364d1b13..2818e65c73 100644 --- a/examples/post-processing/readme.md +++ b/examples/post-processing/readme.md @@ -14,7 +14,7 @@ This example demonstrates usage of the following processing blocks: * Temporal * Filters depth data by looking into previous frames. -For further infomration please refer to [Depth Post-Processing for Intel® RealSense™ D400 Depth Cameras](https://dev.intelrealsense.com/docs/depth-post-processing) +For further infomration please refer to [Depth Post-Processing for Intel® RealSense™ Depth Camera D400 Series](https://dev.intelrealsense.com/docs/depth-post-processing) ## Expected Output ![expected output](https://user-images.githubusercontent.com/22654243/35924136-dd9cd1b6-0c2a-11e8-925a-84a52c0a5b96.gif) From e21bdcc32e3778f97b91e1bee466e2681892670d Mon Sep 17 00:00:00 2001 From: remibettan Date: Tue, 5 May 2020 22:25:47 +0300 Subject: [PATCH 03/61] fw_logger class started --- src/fw_logger.cpp | 23 +++++++++++++++++++++++ src/fw_logger.h | 21 +++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/fw_logger.cpp create mode 100644 src/fw_logger.h diff --git a/src/fw_logger.cpp b/src/fw_logger.cpp new file mode 100644 index 0000000000..efeb2a9808 --- /dev/null +++ b/src/fw_logger.cpp @@ -0,0 +1,23 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +#include "fw_logger.h" +#include + +namespace librealsense +{ + fw_logger::fw_logger(const char* camera_op_code) + { + auto op_code = static_cast(std::stoi(camera_op_code)); + _input_code = { 0x14, 0x00, 0xab, 0xcd, op_code, 0x00, 0x00, 0x00, + 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + } + + + std::vector fw_logger::get_fw_logs() const + { + return _debug_interface->send_receive_raw_data + } +} \ No newline at end of file diff --git a/src/fw_logger.h b/src/fw_logger.h new file mode 100644 index 0000000000..c0a5829de5 --- /dev/null +++ b/src/fw_logger.h @@ -0,0 +1,21 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +#pragma once + +#include + +namespace librealsense +{ + class fw_logger + { + public: + fw_logger(const char* camera_op_code); + + std::vector get_fw_logs() const; + + private: + std::vector _input_code; + }; + +} \ No newline at end of file From 783fd9adfa54486aa58755cf5da2436e1d41a789 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 6 May 2020 21:13:03 +0300 Subject: [PATCH 04/61] API and example added - FW logs received without any filter and without xml translation --- examples/CMakeLists.txt | 1 + examples/firmware-logs/CMakeLists.txt | 16 +++ examples/firmware-logs/rs-firmware-logs.cpp | 114 ++++++++++++++++++++ include/librealsense2/h/rs_device.h | 3 + include/librealsense2/h/rs_types.h | 1 + include/librealsense2/hpp/rs_device.hpp | 35 ++++++ include/librealsense2/rs.h | 7 ++ src/CMakeLists.txt | 2 + src/ds5/ds5-factory.cpp | 8 +- src/firmware_logger_device.cpp | 29 +++++ src/firmware_logger_device.h | 34 ++++++ src/fw_logger.cpp | 23 ---- src/fw_logger.h | 21 ---- src/realsense.def | 4 +- src/rs.cpp | 13 ++- src/types.cpp | 1 + 16 files changed, 264 insertions(+), 48 deletions(-) create mode 100644 examples/firmware-logs/CMakeLists.txt create mode 100644 examples/firmware-logs/rs-firmware-logs.cpp create mode 100644 src/firmware_logger_device.cpp create mode 100644 src/firmware_logger_device.h delete mode 100644 src/fw_logger.cpp delete mode 100644 src/fw_logger.h diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index cf04932166..c01d08be23 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -47,3 +47,4 @@ add_subdirectory(ar-basic) add_subdirectory(ar-advanced) add_subdirectory(pose-apriltag) add_subdirectory(tracking-and-depth) +add_subdirectory(firmware-logs) diff --git a/examples/firmware-logs/CMakeLists.txt b/examples/firmware-logs/CMakeLists.txt new file mode 100644 index 0000000000..929185ad15 --- /dev/null +++ b/examples/firmware-logs/CMakeLists.txt @@ -0,0 +1,16 @@ +# License: Apache 2.0. See LICENSE file in root directory. +# Copyright(c) 2020 Intel Corporation. All Rights Reserved. +# minimum required cmake version: 3.1.0 +cmake_minimum_required(VERSION 3.1.0) + +project(RealsenseExamplesFirmwareLogs) + +if(BUILD_GRAPHICAL_EXAMPLES) + add_executable(rs-firmware-logs rs-firmware-logs.cpp ../example.hpp) + set_property(TARGET rs-firmware-logs PROPERTY CXX_STANDARD 11) + target_link_libraries(rs-firmware-logs ${DEPENDENCIES}) + include_directories(rs-firmware-logs ../ ../../third-party/tclap/include) + set_target_properties (rs-firmware-logs PROPERTIES FOLDER "Examples") + + install(TARGETS rs-firmware-logs RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() diff --git a/examples/firmware-logs/rs-firmware-logs.cpp b/examples/firmware-logs/rs-firmware-logs.cpp new file mode 100644 index 0000000000..8f5265ba67 --- /dev/null +++ b/examples/firmware-logs/rs-firmware-logs.cpp @@ -0,0 +1,114 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2017 Intel Corporation. All Rights Reserved. + +#include // Include RealSense Cross Platform API +#include "example.hpp" // Include short list of convenience functions for rendering +#include +#include +#include + +using namespace std; + + +string hexify(unsigned char n) +{ + string res; + + do + { + res += "0123456789ABCDEF"[n % 16]; + n >>= 4; + } while (n); + + reverse(res.begin(), res.end()); + + if (res.size() == 1) + { + res.insert(0, "0"); + } + + return res; +} + +string datetime_string() +{ + auto t = time(nullptr); + char buffer[20] = {}; + const tm* time = localtime(&t); + if (nullptr != time) + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", time); + + return string(buffer); +} + +// Capture Example demonstrates how to +// capture depth and color video streams and render them to the screen +int main(int argc, char * argv[]) +{ + // Declare RealSense pipeline, encapsulating the actual device and sensors + rs2::pipeline pipe; + + // Start streaming with default recommended configuration + // The default video configuration contains Depth and Color streams + // If a device is capable to stream IMU data, both Gyro and Accelerometer are enabled by default + auto res = pipe.start(); + + rs2::context ctx; + rs2::device_hub hub(ctx); + while (true) + { + try + { + cout << "\nWaiting for RealSense device to connect...\n"; + auto dev = hub.wait_for_device(); + cout << "RealSense device was connected...\n"; + + setvbuf(stdout, NULL, _IONBF, 0); // unbuffering stdout + + while (hub.is_connected(dev)) + { + this_thread::sleep_for(chrono::milliseconds(100)); + + auto fw_log = res.get_device().as(); + std::vector raw_data = fw_log.get_firmware_logs(); + vector fw_log_lines = { "" }; + if (raw_data.size() <= 4) + continue; + + /*if (use_xml_file) + { + fw_logs_binary_data fw_logs_binary_data = { raw_data }; + fw_logs_binary_data.logs_buffer.erase(fw_logs_binary_data.logs_buffer.begin(), fw_logs_binary_data.logs_buffer.begin() + 4); + fw_log_lines = fw_log_parser->get_fw_log_lines(fw_logs_binary_data); + for (auto& elem : fw_log_lines) + elem = datetime_string() + " " + elem; + } + else + { + stringstream sstr; + sstr << datetime_string() << " FW_Log_Data:"; + for (size_t i = 0; i < raw_data.size(); ++i) + sstr << hexify(raw_data[i]) << " "; + + fw_log_lines.push_back(sstr.str()); + }*/ + + stringstream sstr; + sstr << datetime_string() << " FW_Log_Data:"; + for (size_t i = 0; i < raw_data.size(); ++i) + sstr << hexify(raw_data[i]) << " "; + + fw_log_lines.push_back(sstr.str()); + + for (auto& line : fw_log_lines) + cout << line << endl; + } + } + catch (const rs2::error & e) + { + cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << endl; + } + } + + return EXIT_SUCCESS; +} diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index 43ba91b8d3..885fc6df9f 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -353,6 +353,9 @@ rs2_raw_data_buffer* rs2_serialize_json(rs2_device* dev, rs2_error** error); /* Load JSON and apply advanced-mode controls */ void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_size, rs2_error** error); +/* Get firmware Logs */ +const rs2_raw_data_buffer* rs2_get_firmware_logs(rs2_device* dev, rs2_error** error); + #ifdef __cplusplus } #endif diff --git a/include/librealsense2/h/rs_types.h b/include/librealsense2/h/rs_types.h index 02415278b3..ef4262013c 100644 --- a/include/librealsense2/h/rs_types.h +++ b/include/librealsense2/h/rs_types.h @@ -180,6 +180,7 @@ typedef enum rs2_extension RS2_EXTENSION_FISHEYE_SENSOR, RS2_EXTENSION_DEPTH_HUFFMAN_DECODER, RS2_EXTENSION_SERIALIZABLE, + RS2_EXTENSION_FW_LOGGER, RS2_EXTENSION_COUNT } rs2_extension; const char* rs2_extension_type_to_string(rs2_extension type); diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index 2ea37487a0..6ee943e893 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -312,6 +312,41 @@ return results; } }; + class firmware_logger : public device + { + public: + firmware_logger(device d) + : device(d.get()) + { + rs2_error* e = nullptr; + if (rs2_is_device_extendable_to(_dev.get(), RS2_EXTENSION_FW_LOGGER, &e) == 0 && !e) + { + _dev.reset(); + } + error::handle(e); + } + + std::vector get_firmware_logs() const + { + std::vector results; + + rs2_error* e = nullptr; + std::shared_ptr list( + rs2_get_firmware_logs(_dev.get(), &e), + rs2_delete_raw_data); + error::handle(e); + + auto size = rs2_get_raw_data_size(list.get(), &e); + error::handle(e); + + auto start = rs2_get_raw_data(list.get(), &e); + + results.insert(results.begin(), start, start + size); + + return results; + } + }; + class auto_calibrated_device : public calibrated_device { public: diff --git a/include/librealsense2/rs.h b/include/librealsense2/rs.h index f43e816461..65fa5be7fe 100644 --- a/include/librealsense2/rs.h +++ b/include/librealsense2/rs.h @@ -110,6 +110,13 @@ float rs2_depth_frame_get_distance(const rs2_frame* frame_ref, int x, int y, rs2 */ rs2_time_t rs2_get_time( rs2_error** error); +/** + * Get Firmware logs + * \param[in] dev The Device + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ +const rs2_raw_data_buffer* rs2_get_firmware_logs(rs2_device* dev, rs2_error** error); + #ifdef __cplusplus } #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d26732bacf..f3022f6ba5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -77,6 +77,7 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/device_hub.cpp" "${CMAKE_CURRENT_LIST_DIR}/environment.cpp" "${CMAKE_CURRENT_LIST_DIR}/error-handling.cpp" + "${CMAKE_CURRENT_LIST_DIR}/firmware_logger_device.cpp" "${CMAKE_CURRENT_LIST_DIR}/global_timestamp_reader.cpp" "${CMAKE_CURRENT_LIST_DIR}/hw-monitor.cpp" "${CMAKE_CURRENT_LIST_DIR}/image.cpp" @@ -105,6 +106,7 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/environment.h" "${CMAKE_CURRENT_LIST_DIR}/log.h" "${CMAKE_CURRENT_LIST_DIR}/error-handling.h" + "${CMAKE_CURRENT_LIST_DIR}/firmware_logger_device.h" "${CMAKE_CURRENT_LIST_DIR}/frame-archive.h" "${CMAKE_CURRENT_LIST_DIR}/global_timestamp_reader.h" "${CMAKE_CURRENT_LIST_DIR}/hw-monitor.h" diff --git a/src/ds5/ds5-factory.cpp b/src/ds5/ds5-factory.cpp index f039dc429d..1923da4ede 100644 --- a/src/ds5/ds5-factory.cpp +++ b/src/ds5/ds5-factory.cpp @@ -22,6 +22,8 @@ #include "ds5-motion.h" #include "sync.h" +#include "../firmware_logger_device.h" + namespace librealsense { // PSR @@ -471,7 +473,8 @@ namespace librealsense // AWGC class rs435_device : public ds5_active, public ds5_color, - public ds5_advanced_mode_base + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs435_device(std::shared_ptr ctx, @@ -481,7 +484,8 @@ namespace librealsense ds5_device(ctx, group), ds5_active(ctx, group), ds5_color(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor().get_info(RS2_CAMERA_INFO_DEBUG_OP_CODE)) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp new file mode 100644 index 0000000000..970c567a95 --- /dev/null +++ b/src/firmware_logger_device.cpp @@ -0,0 +1,29 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +#include "firmware_logger_device.h" +#include + +namespace librealsense +{ + firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor, + std::string camera_op_code) : + _hw_monitor(hardware_monitor) + { + auto op_code = static_cast(std::stoi(camera_op_code.c_str())); + _input_code = { 0x14, 0x00, 0xab, 0xcd, op_code, 0x00, 0x00, 0x00, + 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + } + + + std::vector firmware_logger_device::get_fw_logs() const + { + auto res = _hw_monitor->send(_input_code); + if (res.empty()) + { + throw std::runtime_error("Getting Firmware logs failed!"); + } + return res; + } +} \ No newline at end of file diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h new file mode 100644 index 0000000000..4456988a98 --- /dev/null +++ b/src/firmware_logger_device.h @@ -0,0 +1,34 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +#pragma once + +#include "core/extension.h" +#include "device.h" +#include + +namespace librealsense +{ + class firmware_logger_extensions + { + public: + virtual std::vector get_fw_logs() const = 0; + virtual ~firmware_logger_extensions() = default; + }; + MAP_EXTENSION(RS2_EXTENSION_FW_LOGGER, librealsense::firmware_logger_extensions); + + + class firmware_logger_device : public virtual device, public firmware_logger_extensions + { + public: + firmware_logger_device(std::shared_ptr hardware_monitor, + std::string camera_op_code); + + std::vector get_fw_logs() const override; + + private: + std::vector _input_code; + std::shared_ptr _hw_monitor; + }; + +} \ No newline at end of file diff --git a/src/fw_logger.cpp b/src/fw_logger.cpp deleted file mode 100644 index efeb2a9808..0000000000 --- a/src/fw_logger.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2020 Intel Corporation. All Rights Reserved. - -#include "fw_logger.h" -#include - -namespace librealsense -{ - fw_logger::fw_logger(const char* camera_op_code) - { - auto op_code = static_cast(std::stoi(camera_op_code)); - _input_code = { 0x14, 0x00, 0xab, 0xcd, op_code, 0x00, 0x00, 0x00, - 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - } - - - std::vector fw_logger::get_fw_logs() const - { - return _debug_interface->send_receive_raw_data - } -} \ No newline at end of file diff --git a/src/fw_logger.h b/src/fw_logger.h deleted file mode 100644 index c0a5829de5..0000000000 --- a/src/fw_logger.h +++ /dev/null @@ -1,21 +0,0 @@ -// License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2020 Intel Corporation. All Rights Reserved. - -#pragma once - -#include - -namespace librealsense -{ - class fw_logger - { - public: - fw_logger(const char* camera_op_code); - - std::vector get_fw_logs() const; - - private: - std::vector _input_code; - }; - -} \ No newline at end of file diff --git a/src/realsense.def b/src/realsense.def index c7fcea8299..e0bdd94163 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -355,7 +355,9 @@ EXPORTS rs2_run_tare_calibration rs2_get_calibration_table rs2_set_calibration_table - + + rs2_get_firmware_logs + rs2_create_terminal_parser rs2_delete_terminal_parser rs2_terminal_parse_command diff --git a/src/rs.cpp b/src/rs.cpp index 9e3e2a9d27..4fd4942e2a 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -42,6 +42,7 @@ #include "global_timestamp_reader.h" #include "auto-calibrated-device.h" #include "terminal-parser.h" +#include "firmware_logger_device.h" //////////////////////// // API implementation // //////////////////////// @@ -1292,6 +1293,7 @@ int rs2_is_device_extendable_to(const rs2_device* dev, rs2_extension extension, case RS2_EXTENSION_GLOBAL_TIMER : return VALIDATE_INTERFACE_NO_THROW(dev->device, librealsense::global_time_interface) != nullptr; case RS2_EXTENSION_AUTO_CALIBRATED_DEVICE: return VALIDATE_INTERFACE_NO_THROW(dev->device, librealsense::auto_calibrated_interface) != nullptr; case RS2_EXTENSION_SERIALIZABLE : return VALIDATE_INTERFACE_NO_THROW(dev->device, librealsense::serializable_interface) != nullptr; + case RS2_EXTENSION_FW_LOGGER : return VALIDATE_INTERFACE_NO_THROW(dev->device, librealsense::firmware_logger_extensions) != nullptr; default: return false; @@ -2969,6 +2971,16 @@ void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_s } HANDLE_EXCEPTIONS_AND_RETURN(, dev, json_content, content_size) +const rs2_raw_data_buffer* rs2_get_firmware_logs(rs2_device* dev, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(dev); + auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + + std::vector buffer = fw_loggerable->get_fw_logs(); + return new rs2_raw_data_buffer{ buffer }; +} +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev) + rs2_terminal_parser* rs2_create_terminal_parser(const char* xml_content, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(xml_content); @@ -3019,4 +3031,3 @@ rs2_raw_data_buffer* rs2_terminal_parse_response(rs2_terminal_parser* terminal_p return new rs2_raw_data_buffer{ result }; } HANDLE_EXCEPTIONS_AND_RETURN(nullptr, terminal_parser, command, response) - diff --git a/src/types.cpp b/src/types.cpp index 7d03962288..fa56fde3f2 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -216,6 +216,7 @@ namespace librealsense CASE(FISHEYE_SENSOR) CASE(DEPTH_HUFFMAN_DECODER) CASE(SERIALIZABLE) + CASE(FW_LOGGER) default: assert(!is_valid(value)); return UNKNOWN_VALUE; } #undef CASE From 39326f0681cf332b06031e86d4344eb659775f8b Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 13 May 2020 12:30:46 +0300 Subject: [PATCH 05/61] FW logs parsed, using new line as delimiter --- examples/firmware-logs/rs-firmware-logs.cpp | 38 ++- include/librealsense2/h/rs_device.h | 25 ++ include/librealsense2/h/rs_types.h | 1 + include/librealsense2/hpp/rs_device.hpp | 55 +++- src/CMakeLists.txt | 1 + src/fw-logs-parser/CMakeLists.txt | 14 + src/fw-logs-parser/fw-log-data.cpp | 60 ++++ src/fw-logs-parser/fw-log-data.h | 94 ++++++ .../fw-logs-formating-options.cpp | 95 ++++++ .../fw-logs-formating-options.h | 54 +++ src/fw-logs-parser/fw-logs-parser.cpp | 103 ++++++ src/fw-logs-parser/fw-logs-parser.h | 30 ++ src/fw-logs-parser/fw-logs-xml-helper.cpp | 311 ++++++++++++++++++ src/fw-logs-parser/fw-logs-xml-helper.h | 48 +++ src/fw-logs-parser/fw-string-formatter.cpp | 138 ++++++++ src/fw-logs-parser/fw-string-formatter.h | 28 ++ src/realsense.def | 3 + src/rs.cpp | 50 +++ 18 files changed, 1131 insertions(+), 17 deletions(-) create mode 100644 src/fw-logs-parser/CMakeLists.txt create mode 100644 src/fw-logs-parser/fw-log-data.cpp create mode 100644 src/fw-logs-parser/fw-log-data.h create mode 100644 src/fw-logs-parser/fw-logs-formating-options.cpp create mode 100644 src/fw-logs-parser/fw-logs-formating-options.h create mode 100644 src/fw-logs-parser/fw-logs-parser.cpp create mode 100644 src/fw-logs-parser/fw-logs-parser.h create mode 100644 src/fw-logs-parser/fw-logs-xml-helper.cpp create mode 100644 src/fw-logs-parser/fw-logs-xml-helper.h create mode 100644 src/fw-logs-parser/fw-string-formatter.cpp create mode 100644 src/fw-logs-parser/fw-string-formatter.h diff --git a/examples/firmware-logs/rs-firmware-logs.cpp b/examples/firmware-logs/rs-firmware-logs.cpp index 8f5265ba67..40c0ac3765 100644 --- a/examples/firmware-logs/rs-firmware-logs.cpp +++ b/examples/firmware-logs/rs-firmware-logs.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace std; @@ -68,20 +69,32 @@ int main(int argc, char * argv[]) while (hub.is_connected(dev)) { this_thread::sleep_for(chrono::milliseconds(100)); - + auto fw_log = res.get_device().as(); std::vector raw_data = fw_log.get_firmware_logs(); vector fw_log_lines = { "" }; if (raw_data.size() <= 4) continue; - /*if (use_xml_file) + static bool usingParser = true; + if (usingParser) { - fw_logs_binary_data fw_logs_binary_data = { raw_data }; - fw_logs_binary_data.logs_buffer.erase(fw_logs_binary_data.logs_buffer.begin(), fw_logs_binary_data.logs_buffer.begin() + 4); - fw_log_lines = fw_log_parser->get_fw_log_lines(fw_logs_binary_data); - for (auto& elem : fw_log_lines) - elem = datetime_string() + " " + elem; + std::string xml_path("HWLoggerEventsDS5.xml"); + if (!xml_path.empty()) + { + ifstream f(xml_path); + if (f.good()) + { + unique_ptr parser = + unique_ptr(new rs2::firmware_logs_parser(xml_path)); + bool datetime = true; + fw_log_lines = parser->get_firmware_logs_parsed(raw_data); + + for (auto& elem : fw_log_lines) + elem = datetime_string() + " " + elem; + } + } + } else { @@ -91,15 +104,8 @@ int main(int argc, char * argv[]) sstr << hexify(raw_data[i]) << " "; fw_log_lines.push_back(sstr.str()); - }*/ - - stringstream sstr; - sstr << datetime_string() << " FW_Log_Data:"; - for (size_t i = 0; i < raw_data.size(); ++i) - sstr << hexify(raw_data[i]) << " "; - - fw_log_lines.push_back(sstr.str()); - + } + for (auto& line : fw_log_lines) cout << line << endl; } diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index 885fc6df9f..31903d5905 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -356,6 +356,31 @@ void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_s /* Get firmware Logs */ const rs2_raw_data_buffer* rs2_get_firmware_logs(rs2_device* dev, rs2_error** error); +/** +* \brief Creates RealSense firmware logs parser. +* \param[in] xml_path path to xml file needed for parsing +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return firmware logs parser object +*/ +rs2_firmware_logs_parser* rs2_create_firmware_logs_parser(const char* xml_path, rs2_error** error); + +/** +* \brief Frees the relevant firmware logs parser object. +* \param[in] firmware logs parser object that is no longer needed +*/ +void rs2_delete_firmware_logs_parser(rs2_firmware_logs_parser* parser); + +/** +* \brief Parses firmware logs. +* \param[in] fw_logs_parser firmware logs parser object +* \param[in] raw_data firmware logs not parsed +* \param[in] raw_data_size firmware logs not parsed size +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return firmware logs parsed +*/ +rs2_raw_data_buffer* rs2_get_firmware_logs_parsed(rs2_firmware_logs_parser* fw_logs_parser, + const void* raw_data, const int raw_data_size, rs2_error** error); + #ifdef __cplusplus } #endif diff --git a/include/librealsense2/h/rs_types.h b/include/librealsense2/h/rs_types.h index ef4262013c..8c9d01c96f 100644 --- a/include/librealsense2/h/rs_types.h +++ b/include/librealsense2/h/rs_types.h @@ -253,6 +253,7 @@ typedef void (*rs2_devices_changed_callback_ptr)(rs2_device_list*, rs2_device_li typedef void (*rs2_frame_callback_ptr)(rs2_frame*, void*); typedef void (*rs2_frame_processor_callback_ptr)(rs2_frame*, rs2_source*, void*); typedef void(*rs2_update_progress_callback_ptr)(const float, void*); +typedef struct rs2_firmware_logs_parser rs2_firmware_logs_parser; typedef double rs2_time_t; /**< Timestamp format. units are milliseconds */ typedef long long rs2_metadata_type; /**< Metadata attribute type is defined as 64 bit signed integer*/ diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index 6ee943e893..27421d2958 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -226,7 +226,7 @@ namespace rs2 results.insert(results.begin(), start, start + size); -return results; + return results; } // Update an updatable device to the provided unsigned firmware. This call is executed on the caller's thread. @@ -347,6 +347,59 @@ return results; } }; + class firmware_logs_parser + { + public: + firmware_logs_parser(std::string xml_path) + { + rs2_error* e = nullptr; + _firmware_logs_parser = std::shared_ptr( + rs2_create_firmware_logs_parser(xml_path.data(), &e), + rs2_delete_firmware_logs_parser); + error::handle(e); + } + + std::vector firmware_logs_parser::get_firmware_logs_parsed(const std::vector& raw_data) + { + std::string results; + + rs2_error* e = nullptr; + std::shared_ptr parsed_logs( + rs2_get_firmware_logs_parsed(_firmware_logs_parser.get(), (const void*)raw_data.data(), (const int)raw_data.size(), &e), + rs2_delete_raw_data); + rs2::error::handle(e); + + auto size = rs2_get_raw_data_size(parsed_logs.get(), &e); + rs2::error::handle(e); + + auto start = rs2_get_raw_data(parsed_logs.get(), &e); + rs2::error::handle(e); + + results.insert(results.begin(), start, start + size); + + //transforming the string to vector delimiter is '\n' + std::vector log_lines; + std::size_t current_start = 0; + std::size_t delimiter_found = results.find_first_of("\n"); + while (delimiter_found != std::string::npos) + { + log_lines.push_back(std::string(results.substr(current_start, delimiter_found - current_start))); + current_start = delimiter_found + 1; + delimiter_found = results.find_first_of("\n", delimiter_found + 1); + } + + return log_lines; + } + + firmware_logs_parser(std::shared_ptr fw_logs_parser) + : _firmware_logs_parser(fw_logs_parser) {} + + explicit operator std::shared_ptr() { return _firmware_logs_parser; }; + + protected: + std::shared_ptr _firmware_logs_parser; + }; + class auto_calibrated_device : public calibrated_device { public: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f3022f6ba5..9052efa050 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,6 +11,7 @@ include(${_rel_path}/proc/CMakeLists.txt) include(${_rel_path}/res/CMakeLists.txt) include(${_rel_path}/pipeline/CMakeLists.txt) include(${_rel_path}/usb/CMakeLists.txt) +include(${_rel_path}/fw-logs-parser/CMakeLists.txt) include(${_rel_path}/fw-update/CMakeLists.txt) message(STATUS "using ${BACKEND}") diff --git a/src/fw-logs-parser/CMakeLists.txt b/src/fw-logs-parser/CMakeLists.txt new file mode 100644 index 0000000000..33f79d0b81 --- /dev/null +++ b/src/fw-logs-parser/CMakeLists.txt @@ -0,0 +1,14 @@ +# License: Apache 2.0. See LICENSE file in root directory. +# Copyright(c) 2020 Intel Corporation. All Rights Reserved. +target_sources(${LRS_TARGET} + PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/fw-log-data.h" + "${CMAKE_CURRENT_LIST_DIR}/fw-logs-formating-options.cpp" + "${CMAKE_CURRENT_LIST_DIR}/fw-logs-formating-options.h" + "${CMAKE_CURRENT_LIST_DIR}/fw-logs-parser.cpp" + "${CMAKE_CURRENT_LIST_DIR}/fw-logs-parser.h" + "${CMAKE_CURRENT_LIST_DIR}/fw-logs-xml-helper.cpp" + "${CMAKE_CURRENT_LIST_DIR}/fw-logs-xml-helper.h" + "${CMAKE_CURRENT_LIST_DIR}/fw-string-formatter.cpp" + "${CMAKE_CURRENT_LIST_DIR}/fw-string-formatter.h" +) diff --git a/src/fw-logs-parser/fw-log-data.cpp b/src/fw-logs-parser/fw-log-data.cpp new file mode 100644 index 0000000000..50d3d4860f --- /dev/null +++ b/src/fw-logs-parser/fw-log-data.cpp @@ -0,0 +1,60 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2019 Intel Corporation. All Rights Reserved. +#include "fw-log-data.h" +#include +#include +#include +#include + +using namespace std; + +# define SET_WIDTH_AND_FILL(num, element) \ +setfill(' ') << setw(num) << left << element \ + +namespace librealsense +{ + namespace fw_logs_parsing + { + fw_log_data::fw_log_data(void) + { + magic_number = 0; + severity = 0; + file_id = 0; + group_id = 0; + event_id = 0; + line = 0; + sequence = 0; + p1 = 0; + p2 = 0; + p3 = 0; + timestamp = 0; + delta = 0; + message = ""; + file_name = ""; + } + + + fw_log_data::~fw_log_data(void) + { + } + + + string fw_log_data::to_string() + { + stringstream fmt; + + fmt << SET_WIDTH_AND_FILL(6, sequence) + << SET_WIDTH_AND_FILL(30, file_name) + << SET_WIDTH_AND_FILL(6, group_id) + << SET_WIDTH_AND_FILL(15, thread_name) + << SET_WIDTH_AND_FILL(6, severity) + << SET_WIDTH_AND_FILL(6, line) + << SET_WIDTH_AND_FILL(15, timestamp) + << SET_WIDTH_AND_FILL(15, delta) + << SET_WIDTH_AND_FILL(30, message); + + auto str = fmt.str(); + return str; + } + } +} diff --git a/src/fw-logs-parser/fw-log-data.h b/src/fw-logs-parser/fw-log-data.h new file mode 100644 index 0000000000..606d680894 --- /dev/null +++ b/src/fw-logs-parser/fw-log-data.h @@ -0,0 +1,94 @@ +/* License: Apache 2.0. See LICENSE file in root directory. */ +/* Copyright(c) 2019 Intel Corporation. All Rights Reserved. */ +#pragma once +#include +#include +#include + + +namespace librealsense +{ + namespace fw_logs_parsing + { + struct fw_logs_binary_data + { + std::vector logs_buffer; + }; + + typedef union + { + uint32_t value; + struct + { + uint32_t magic_number : 8; + uint32_t severity : 5; + uint32_t thread_id : 3; + uint32_t file_id : 11; + uint32_t group_id : 5; + } bits; + } fw_log_header_dword1; + + typedef union + { + uint32_t value; + struct + { + uint32_t event_id : 16; + uint32_t line_id : 12; + uint32_t seq_id : 4; + } bits; + } fw_log_header_dword2; + + struct fw_log_header_dword3 + { + uint16_t p1; + uint16_t p2; + }; + + struct fw_log_header_dword4 + { + uint32_t p3; + }; + + struct fw_log_header_dword5 + { + uint32_t timestamp; + }; + + struct fw_log_binary + { + fw_log_header_dword1 dword1; + fw_log_header_dword2 dword2; + fw_log_header_dword3 dword3; + fw_log_header_dword4 dword4; + fw_log_header_dword5 dword5; + }; + + + class fw_log_data + { + public: + fw_log_data(void); + ~fw_log_data(void); + + uint32_t magic_number; + uint32_t severity; + uint32_t file_id; + uint32_t group_id; + uint32_t event_id; + uint32_t line; + uint32_t sequence; + uint32_t p1; + uint32_t p2; + uint32_t p3; + uint64_t timestamp; + double delta; + + std::string message; + std::string file_name; + std::string thread_name; + + std::string to_string(); + }; + } +} diff --git a/src/fw-logs-parser/fw-logs-formating-options.cpp b/src/fw-logs-parser/fw-logs-formating-options.cpp new file mode 100644 index 0000000000..43e30acf61 --- /dev/null +++ b/src/fw-logs-parser/fw-logs-formating-options.cpp @@ -0,0 +1,95 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2019 Intel Corporation. All Rights Reserved. +#include "fw-logs-formating-options.h" +#include "fw-logs-xml-helper.h" +#include + + +using namespace std; +namespace librealsense +{ + namespace fw_logs_parsing + { + fw_log_event::fw_log_event() + : num_of_params(0), + line("") + {} + + fw_log_event::fw_log_event(int input_num_of_params, const string& input_line) + : num_of_params(input_num_of_params), + line(input_line) + {} + + + fw_logs_formating_options::fw_logs_formating_options(const string& xml_full_file_path) + : _xml_full_file_path(xml_full_file_path) + {} + + + fw_logs_formating_options::~fw_logs_formating_options(void) + { + } + + bool fw_logs_formating_options::get_event_data(int id, fw_log_event* log_event_data) const + { + auto event_it = _fw_logs_event_list.find(id); + if (event_it != _fw_logs_event_list.end()) + { + *log_event_data = event_it->second; + return true; + } + else + { + stringstream ss; + ss << "*** Unrecognized Log Id: "; + ss << id; + ss << "! P1 = 0x{0:x}, P2 = 0x{1:x}, P3 = 0x{2:x}"; + log_event_data->line = ss.str(); + log_event_data->num_of_params = 3; + return false; + } + } + + bool fw_logs_formating_options::get_file_name(int id, string* file_name) const + { + auto file_it = _fw_logs_file_names_list.find(id); + if (file_it != _fw_logs_file_names_list.end()) + { + *file_name = file_it->second; + return true; + } + else + { + *file_name = "Unknown"; + return false; + } + } + + bool fw_logs_formating_options::get_thread_name(uint32_t thread_id, string* thread_name) const + { + auto file_it = _fw_logs_thread_names_list.find(thread_id); + if (file_it != _fw_logs_thread_names_list.end()) + { + *thread_name = file_it->second; + return true; + } + else + { + *thread_name = "Unknown"; + return false; + } + } + + std::unordered_map> fw_logs_formating_options::get_enums() const + { + return _fw_logs_enum_names_list; + } + + bool fw_logs_formating_options::initialize_from_xml() + { + fw_logs_xml_helper fw_logs_xml(_xml_full_file_path); + return fw_logs_xml.build_log_meta_data(this); + } + } +} + diff --git a/src/fw-logs-parser/fw-logs-formating-options.h b/src/fw-logs-parser/fw-logs-formating-options.h new file mode 100644 index 0000000000..f67a198c95 --- /dev/null +++ b/src/fw-logs-parser/fw-logs-formating-options.h @@ -0,0 +1,54 @@ +/* License: Apache 2.0. See LICENSE file in root directory. */ +/* Copyright(c) 2019 Intel Corporation. All Rights Reserved. */ +#pragma once +#include +#include +#include +#include + +#ifdef ANDROID +#include "../../common/android_helpers.h" +#endif + + +namespace librealsense +{ + namespace fw_logs_parsing + { + struct fw_log_event + { + size_t num_of_params; + std::string line; + + fw_log_event(); + fw_log_event(int input_num_of_params, const std::string& input_line); + }; + + typedef std::pair kvp; // XML key/value pair + + class fw_logs_xml_helper; + + class fw_logs_formating_options + { + public: + fw_logs_formating_options(const std::string& xml_full_file_path); + ~fw_logs_formating_options(void); + + + bool get_event_data(int id, fw_log_event* log_event_data) const; + bool get_file_name(int id, std::string* file_name) const; + bool get_thread_name(uint32_t thread_id, std::string* thread_name) const; + std::unordered_map> get_enums() const; + bool initialize_from_xml(); + + private: + friend fw_logs_xml_helper; + std::unordered_map _fw_logs_event_list; + std::unordered_map _fw_logs_file_names_list; + std::unordered_map _fw_logs_thread_names_list; + std::unordered_map>> _fw_logs_enum_names_list; + + std::string _xml_full_file_path; + }; + } +} diff --git a/src/fw-logs-parser/fw-logs-parser.cpp b/src/fw-logs-parser/fw-logs-parser.cpp new file mode 100644 index 0000000000..37c1827cdf --- /dev/null +++ b/src/fw-logs-parser/fw-logs-parser.cpp @@ -0,0 +1,103 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2019 Intel Corporation. All Rights Reserved. +#include "fw-logs-parser.h" +#include +#include +#include "fw-string-formatter.h" +#include "stdint.h" + +using namespace std; + +namespace librealsense +{ + namespace fw_logs_parsing + { + fw_logs_parser::fw_logs_parser(string xml_full_file_path) + : _fw_logs_formating_options(xml_full_file_path), + _last_timestamp(0), + _timestamp_factor(0.00001) + { + _fw_logs_formating_options.initialize_from_xml(); + } + + + fw_logs_parser::~fw_logs_parser(void) + { + } + + vector fw_logs_parser::get_fw_log_lines(const fw_logs_binary_data& fw_logs_data_binary) + { + fw_logs_binary_data binary_data = { fw_logs_data_binary }; + binary_data.logs_buffer.erase(binary_data.logs_buffer.begin(), binary_data.logs_buffer.begin() + 4); + vector string_vector; + int num_of_lines = int(binary_data.logs_buffer.size()) / sizeof(fw_log_binary); + auto temp_pointer = reinterpret_cast(binary_data.logs_buffer.data()); + + for (int i = 0; i < num_of_lines; i++) + { + string line; + auto log = const_cast(reinterpret_cast(temp_pointer)); + line = generate_log_line(log); + string_vector.push_back(line); + temp_pointer++; + } + return string_vector; + } + + string fw_logs_parser::generate_log_line(char* fw_logs) + { + fw_log_data log_data; + fill_log_data(fw_logs, &log_data); + + return log_data.to_string(); + } + + void fw_logs_parser::fill_log_data(const char* fw_logs, fw_log_data* log_data) + { + fw_string_formatter reg_exp(_fw_logs_formating_options.get_enums()); + fw_log_event log_event_data; + + auto* log_binary = reinterpret_cast(fw_logs); + + //parse first DWORD + log_data->magic_number = static_cast(log_binary->dword1.bits.magic_number); + log_data->severity = static_cast(log_binary->dword1.bits.severity); + + log_data->file_id = static_cast(log_binary->dword1.bits.file_id); + log_data->group_id = static_cast(log_binary->dword1.bits.group_id); + + //parse second DWORD + log_data->event_id = static_cast(log_binary->dword2.bits.event_id); + log_data->line = static_cast(log_binary->dword2.bits.line_id); + log_data->sequence = static_cast(log_binary->dword2.bits.seq_id); + + //parse third DWORD + log_data->p1 = static_cast(log_binary->dword3.p1); + log_data->p2 = static_cast(log_binary->dword3.p2); + + //parse forth DWORD + log_data->p3 = static_cast(log_binary->dword4.p3); + + //parse fifth DWORD + log_data->timestamp = log_binary->dword5.timestamp; + + if (_last_timestamp == 0) + { + log_data->delta = 0; + } + else + { + log_data->delta = (log_data->timestamp - _last_timestamp) * _timestamp_factor; + } + + _last_timestamp = log_data->timestamp; + _fw_logs_formating_options.get_event_data(log_data->event_id, &log_event_data); + uint32_t params[3] = { log_data->p1, log_data->p2, log_data->p3 }; + reg_exp.generate_message(log_event_data.line, log_event_data.num_of_params, params, &log_data->message); + + _fw_logs_formating_options.get_file_name(log_data->file_id, &log_data->file_name); + _fw_logs_formating_options.get_thread_name(static_cast(log_binary->dword1.bits.thread_id), + &log_data->thread_name); + } + } +} diff --git a/src/fw-logs-parser/fw-logs-parser.h b/src/fw-logs-parser/fw-logs-parser.h new file mode 100644 index 0000000000..7ed135558b --- /dev/null +++ b/src/fw-logs-parser/fw-logs-parser.h @@ -0,0 +1,30 @@ +/* License: Apache 2.0. See LICENSE file in root directory. */ +/* Copyright(c) 2019 Intel Corporation. All Rights Reserved. */ +#pragma once +#include +#include +#include +#include "fw-logs-formating-options.h" +#include "fw-log-data.h" + +namespace librealsense +{ + namespace fw_logs_parsing + { + class fw_logs_parser : public std::enable_shared_from_this + { + public: + explicit fw_logs_parser(std::string xml_full_file_path); + ~fw_logs_parser(void); + std::vector get_fw_log_lines(const fw_logs_binary_data& fw_logs_data_binary); + + private: + std::string generate_log_line(char* fw_logs); + void fill_log_data(const char* fw_logs, fw_log_data* log_data); + uint64_t _last_timestamp; + + fw_logs_formating_options _fw_logs_formating_options; + const double _timestamp_factor; + }; + } +} diff --git a/src/fw-logs-parser/fw-logs-xml-helper.cpp b/src/fw-logs-parser/fw-logs-xml-helper.cpp new file mode 100644 index 0000000000..a17e1b05e1 --- /dev/null +++ b/src/fw-logs-parser/fw-logs-xml-helper.cpp @@ -0,0 +1,311 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2019 Intel Corporation. All Rights Reserved. +#include "fw-logs-xml-helper.h" +#include +#include +#include +#include + +using namespace std; + +namespace librealsense +{ + namespace fw_logs_parsing + { + fw_logs_xml_helper::fw_logs_xml_helper(string xml_full_file_path) + : _init_done(false), + _xml_full_file_path(xml_full_file_path) + {} + + + fw_logs_xml_helper::~fw_logs_xml_helper(void) + { + // TODO: Add cleanup code + } + + bool fw_logs_xml_helper::get_root_node(xml_node<>** node) + { + if (_init_done) + { + *node = _xml_doc.first_node(); + return true; + } + + return false; + } + + bool fw_logs_xml_helper::try_load_external_xml() + { + try + { + if (_xml_full_file_path.empty()) + return false; + + rapidxml::file<> xml_file(_xml_full_file_path.c_str()); + + _document_buffer.resize(xml_file.size() + 2); + memcpy(_document_buffer.data(), xml_file.data(), xml_file.size()); + _document_buffer[xml_file.size()] = '\0'; + _document_buffer[xml_file.size() + 1] = '\0'; + _xml_doc.parse<0>(_document_buffer.data()); + + return true; + } + catch (...) + { + _document_buffer.clear(); + throw; + } + + return false; + } + + bool fw_logs_xml_helper::init() + { + _init_done = try_load_external_xml(); + return _init_done; + } + + bool fw_logs_xml_helper::build_log_meta_data(fw_logs_formating_options* log_meta_data) + { + xml_node<>* xml_root_node_list; + + if (!init()) + return false; + + if (!get_root_node(&xml_root_node_list)) + { + return false; + } + + string root_name(xml_root_node_list->name(), xml_root_node_list->name() + xml_root_node_list->name_size()); + + // check if Format is the first root name. + if (root_name.compare("Format") != 0) + return false; + + xml_node<>* events_node = xml_root_node_list->first_node(); + + + if (!build_meta_data_structure(events_node, log_meta_data)) + return false; + + return true; + } + + + bool fw_logs_xml_helper::build_meta_data_structure(xml_node<>* xml_node_list_of_events, fw_logs_formating_options* logs_formating_options) + { + node_type res = none; + int id{}; + int num_of_params{}; + string line; + + // loop through all elements in the Format. + for (xml_node<>* node = xml_node_list_of_events; node; node = node->next_sibling()) + { + line.clear(); + res = get_next_node(node, &id, &num_of_params, &line); + if (res == event) + { + fw_log_event log_event(num_of_params, line); + logs_formating_options->_fw_logs_event_list.insert(pair(id, log_event)); + } + else if (res == file) + { + logs_formating_options->_fw_logs_file_names_list.insert(kvp(id, line)); + } + else if (res == thread) + { + logs_formating_options->_fw_logs_thread_names_list.insert(kvp(id, line)); + } + else if (res == enums) + { + for (xml_node<>* enum_node = node->first_node(); enum_node; enum_node = enum_node->next_sibling()) + { + for (xml_attribute<>* attribute = enum_node->first_attribute(); attribute; attribute = attribute->next_attribute()) + { + string attr(attribute->name(), attribute->name() + attribute->name_size()); + if (attr.compare("Name") == 0) + { + string name_attr_str(attribute->value(), attribute->value() + attribute->value_size()); + vector xml_kvp; + + for (xml_node<>* enum_value_node = enum_node->first_node(); enum_value_node; enum_value_node = enum_value_node->next_sibling()) + { + int key = 0; + string value_str; + for (xml_attribute<>* attribute = enum_value_node->first_attribute(); attribute; attribute = attribute->next_attribute()) + { + string attr(attribute->name(), attribute->name() + attribute->name_size()); + if (attr.compare("Value") == 0) + { + value_str = std::string(attribute->value(), attribute->value() + attribute->value_size()); + } + if (attr.compare("Key") == 0) + { + try + { + auto key_str = std::string(attribute->value()); + key = std::stoi(key_str, nullptr); + } + catch (...) {} + } + } + xml_kvp.push_back(std::make_pair(key, value_str)); + } + logs_formating_options->_fw_logs_enum_names_list.insert(pair>(name_attr_str, xml_kvp)); + } + } + } + } + else + return false; + } + + return true; + } + + fw_logs_xml_helper::node_type fw_logs_xml_helper::get_next_node(xml_node<>* node, int* id, int* num_of_params, string* line) + { + + string tag(node->name(), node->name() + node->name_size()); + + if (tag.compare("Event") == 0) + { + if (get_event_node(node, id, num_of_params, line)) + return event; + } + else if (tag.compare("File") == 0) + { + if (get_file_node(node, id, line)) + return file; + } + else if (tag.compare("Thread") == 0) + { + if (get_thread_node(node, id, line)) + return thread; + } + else if (tag.compare("Enums") == 0) + { + return enums; + } + return none; + } + + bool fw_logs_xml_helper::get_enum_name_node(xml_node<>* node_file, int* thread_id, string* enum_name) + { + for (xml_attribute<>* attribute = node_file->first_attribute(); attribute; attribute = attribute->next_attribute()) + { + string attr(attribute->name(), attribute->name() + attribute->name_size()); + + if (attr.compare("Name") == 0) + { + string name_attr_str(attribute->value(), attribute->value() + attribute->value_size()); + *enum_name = name_attr_str; + continue; + } + else + return false; + } + + return true; + } + bool fw_logs_xml_helper::get_enum_value_node(xml_node<>* node_file, int* thread_id, string* enum_name) + { + for (xml_attribute<>* attribute = node_file->first_attribute(); attribute; attribute = attribute->next_attribute()) + { + string attr(attribute->name(), attribute->name() + attribute->name_size()); + + if (attr.compare("Value") == 0) + { + string name_attr_str(attribute->value(), attribute->value() + attribute->value_size()); + *enum_name = name_attr_str; + continue; + } + else + return false; + } + + return true; + } + bool fw_logs_xml_helper::get_thread_node(xml_node<>* node_file, int* thread_id, string* thread_name) + { + for (xml_attribute<>* attribute = node_file->first_attribute(); attribute; attribute = attribute->next_attribute()) + { + string attr(attribute->name(), attribute->name() + attribute->name_size()); + + if (attr.compare("id") == 0) + { + string id_attr_str(attribute->value(), attribute->value() + attribute->value_size()); + *thread_id = stoi(id_attr_str); + continue; + } + else if (attr.compare("Name") == 0) + { + string name_attr_str(attribute->value(), attribute->value() + attribute->value_size()); + *thread_name = name_attr_str; + continue; + } + else + return false; + } + + return true; + } + + bool fw_logs_xml_helper::get_file_node(xml_node<>* node_file, int* file_id, string* file_name) + { + for (xml_attribute<>* attribute = node_file->first_attribute(); attribute; attribute = attribute->next_attribute()) + { + string attr(attribute->name(), attribute->name() + attribute->name_size()); + + if (attr.compare("id") == 0) + { + string id_attr_str(attribute->value(), attribute->value() + attribute->value_size()); + *file_id = stoi(id_attr_str); + continue; + } + else if (attr.compare("Name") == 0) + { + string name_attr_str(attribute->value(), attribute->value() + attribute->value_size()); + *file_name = name_attr_str; + continue; + } + else + return false; + } + return true; + } + + bool fw_logs_xml_helper::get_event_node(xml_node<>* node_event, int* event_id, int* num_of_params, string* line) + { + for (xml_attribute<>* attribute = node_event->first_attribute(); attribute; attribute = attribute->next_attribute()) + { + string attr(attribute->name(), attribute->name() + attribute->name_size()); + + if (attr.compare("id") == 0) + { + string id_attr_str(attribute->value(), attribute->value() + attribute->value_size()); + *event_id = stoi(id_attr_str); + continue; + } + else if (attr.compare("numberOfArguments") == 0) + { + string num_of_args_attr_str(attribute->value(), attribute->value() + attribute->value_size()); + *num_of_params = stoi(num_of_args_attr_str); + continue; + } + else if (attr.compare("format") == 0) + { + string format_attr_str(attribute->value(), attribute->value() + attribute->value_size()); + *line = format_attr_str; + continue; + } + else + return false; + } + return true; + } + } +} diff --git a/src/fw-logs-parser/fw-logs-xml-helper.h b/src/fw-logs-parser/fw-logs-xml-helper.h new file mode 100644 index 0000000000..ecd3fdc32c --- /dev/null +++ b/src/fw-logs-parser/fw-logs-xml-helper.h @@ -0,0 +1,48 @@ +/* License: Apache 2.0. See LICENSE file in root directory. */ +/* Copyright(c) 2019 Intel Corporation. All Rights Reserved. */ +#pragma once +#include "../../third-party/rapidxml/rapidxml_utils.hpp" +#include "fw-logs-formating-options.h" + +using namespace rapidxml; + +namespace librealsense +{ + namespace fw_logs_parsing + { + class fw_logs_xml_helper + { + public: + enum node_type + { + event, + file, + thread, + enums, + none + }; + + fw_logs_xml_helper(std::string xml_full_file_path); + ~fw_logs_xml_helper(void); + + bool build_log_meta_data(fw_logs_formating_options* logs_formating_options); + + private: + bool init(); + bool build_meta_data_structure(xml_node<>* xml_node_list_of_events, fw_logs_formating_options* logs_formating_options); + node_type get_next_node(xml_node<>* xml_node_list_of_events, int* id, int* num_of_params, std::string* line); + bool get_thread_node(xml_node<>* node_file, int* thread_id, std::string* thread_name); + bool get_event_node(xml_node<>* node_event, int* event_id, int* num_of_params, std::string* line); + bool get_enum_name_node(xml_node<>* node_file, int* thread_id, std::string* thread_name); + bool get_enum_value_node(xml_node<>* node_file, int* thread_id, std::string* enum_name); + bool get_file_node(xml_node<>* node_file, int* file_id, std::string* file_name); + bool get_root_node(xml_node<>** node); + bool try_load_external_xml(); + + bool _init_done; + std::string _xml_full_file_path; + xml_document<> _xml_doc; + std::vector _document_buffer; + }; + } +} diff --git a/src/fw-logs-parser/fw-string-formatter.cpp b/src/fw-logs-parser/fw-string-formatter.cpp new file mode 100644 index 0000000000..72f1348b8a --- /dev/null +++ b/src/fw-logs-parser/fw-string-formatter.cpp @@ -0,0 +1,138 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2019 Intel Corporation. All Rights Reserved. +#include "fw-string-formatter.h" +#include "fw-logs-formating-options.h" +#include +#include +#include +#include + +using namespace std; + +namespace librealsense +{ + namespace fw_logs_parsing + { + fw_string_formatter::fw_string_formatter(std::unordered_map> enums) + :_enums(enums) + { + } + + + fw_string_formatter::~fw_string_formatter(void) + { + } + + bool fw_string_formatter::generate_message(const string& source, size_t num_of_params, const uint32_t* params, string* dest) + { + map exp_replace_map; + map enum_replace_map; + + if (params == nullptr && num_of_params > 0) return false; + + for (size_t i = 0; i < num_of_params; i++) + { + string regular_exp[4]; + string replacement[4]; + stringstream st_regular_exp[4]; + stringstream st_replacement[4]; + + st_regular_exp[0] << "\\{\\b(" << i << ")\\}"; + regular_exp[0] = st_regular_exp[0].str(); + + st_replacement[0] << params[i]; + replacement[0] = st_replacement[0].str(); + + exp_replace_map[regular_exp[0]] = replacement[0]; + + + st_regular_exp[1] << "\\{\\b(" << i << "):x\\}"; + regular_exp[1] = st_regular_exp[1].str(); + + st_replacement[1] << hex << setw(2) << setfill('0') << params[i]; + replacement[1] = st_replacement[1].str(); + + exp_replace_map[regular_exp[1]] = replacement[1]; + + st_regular_exp[2] << "\\{\\b(" << i << "):f\\}"; + regular_exp[2] = st_regular_exp[2].str(); + st_replacement[2] << params[i]; + replacement[2] = st_replacement[2].str(); + exp_replace_map[regular_exp[2]] = replacement[2]; + + + st_regular_exp[3] << "\\{\\b(" << i << "),[a-zA-Z]+\\}"; + regular_exp[3] = st_regular_exp[3].str(); + + enum_replace_map[regular_exp[3]] = params[i]; + } + + return replace_params(source, exp_replace_map, enum_replace_map, dest); + } + + bool fw_string_formatter::replace_params(const string& source, const map& exp_replace_map, const map& enum_replace_map, string* dest) + { + string source_temp(source); + + for (auto exp_replace_it = exp_replace_map.begin(); exp_replace_it != exp_replace_map.end(); exp_replace_it++) + { + string destTemp; + regex e(exp_replace_it->first); + auto res = regex_replace(back_inserter(destTemp), source_temp.begin(), source_temp.end(), e, exp_replace_it->second); + source_temp = destTemp; + } + + for (auto exp_replace_it = enum_replace_map.begin(); exp_replace_it != enum_replace_map.end(); exp_replace_it++) + { + string destTemp; + regex e(exp_replace_it->first); + std::smatch m; + std::regex_search(source_temp, m, std::regex(e)); + + string enum_name; + + string st_regular_exp = "[a-zA-Z]+"; + regex e1(st_regular_exp); + + for (size_t exp = 0; exp < m.size(); exp++) + { + string str = m[exp]; + + std::smatch m1; + + regex e2 = e1; + std::regex_search(str, m1, std::regex(e2)); + + for (size_t exp = 0; exp < m1.size(); exp++) + { + enum_name = m1[exp]; + if (_enums.size() > 0 && _enums.find(enum_name) != _enums.end()) + { + auto vec = _enums[enum_name]; + regex e3 = e; + // Verify user's input is within the enumerated range + int val = exp_replace_it->second; + auto it = std::find_if(vec.begin(), vec.end(), [val](kvp& entry) { return entry.first == val; }); + if (it != vec.end()) + { + regex_replace(back_inserter(destTemp), source_temp.begin(), source_temp.end(), e3, it->second); + } + else + { + stringstream s; + s << "Protocol Error recognized!\nImproper log message received: " << source_temp + << ", invalid parameter: " << exp_replace_it->second << ".\n The range of supported values is \n"; + for_each(vec.begin(), vec.end(), [&s](kvp& entry) { s << entry.first << ":" << entry.second << " ,"; }); + std::cout << s.str().c_str() << std::endl;; + } + source_temp = destTemp; + } + } + } + } + + *dest = source_temp; + return true; + } + } +} diff --git a/src/fw-logs-parser/fw-string-formatter.h b/src/fw-logs-parser/fw-string-formatter.h new file mode 100644 index 0000000000..e54e4a744d --- /dev/null +++ b/src/fw-logs-parser/fw-string-formatter.h @@ -0,0 +1,28 @@ +/* License: Apache 2.0. See LICENSE file in root directory. */ +/* Copyright(c) 2019 Intel Corporation. All Rights Reserved. */ +#pragma once +#include +#include +#include +#include +#include + +namespace librealsense +{ + namespace fw_logs_parsing + { + class fw_string_formatter + { + public: + fw_string_formatter(std::unordered_map>> enums); + ~fw_string_formatter(void); + + bool generate_message(const std::string& source, size_t num_of_params, const uint32_t* params, std::string* dest); + + private: + bool replace_params(const std::string& source, const std::map& exp_replace_map, const std::map& enum_replace_map, std::string* dest); + + std::unordered_map>> _enums; + }; + } +} diff --git a/src/realsense.def b/src/realsense.def index e0bdd94163..47c49f4c76 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -357,6 +357,9 @@ EXPORTS rs2_set_calibration_table rs2_get_firmware_logs + rs2_create_firmware_logs_parser + rs2_delete_firmware_logs_parser + rs2_get_firmware_logs_parsed rs2_create_terminal_parser rs2_delete_terminal_parser diff --git a/src/rs.cpp b/src/rs.cpp index 4fd4942e2a..a0f5941778 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -43,6 +43,7 @@ #include "auto-calibrated-device.h" #include "terminal-parser.h" #include "firmware_logger_device.h" +#include "fw-logs-parser/fw-logs-parser.h" //////////////////////// // API implementation // //////////////////////// @@ -121,6 +122,13 @@ struct rs2_terminal_parser std::shared_ptr terminal_parser; }; +struct rs2_firmware_logs_parser +{ + std::shared_ptr firmware_logs_parser; +}; + + + struct rs2_error { std::string message; @@ -2981,6 +2989,45 @@ const rs2_raw_data_buffer* rs2_get_firmware_logs(rs2_device* dev, rs2_error** er } HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev) +rs2_firmware_logs_parser* rs2_create_firmware_logs_parser(const char* xml_path, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(xml_path); + + return new rs2_firmware_logs_parser{ std::make_shared(xml_path)}; +} +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, xml_path) + +void rs2_delete_firmware_logs_parser(rs2_firmware_logs_parser* parser) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(parser); + delete parser; +} +NOEXCEPT_RETURN(, parser) + +rs2_raw_data_buffer* rs2_get_firmware_logs_parsed(rs2_firmware_logs_parser* fw_logs_parser, const void* raw_data, const int raw_data_size, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(fw_logs_parser); + VALIDATE_NOT_NULL(raw_data); + + std::vector raw_data_buffer((uint8_t*)raw_data, (uint8_t*)raw_data + raw_data_size); + librealsense::fw_logs_parsing::fw_logs_binary_data binary_data = + librealsense::fw_logs_parsing::fw_logs_binary_data{ raw_data_buffer }; + std::vector parsed_data_cpp = fw_logs_parser->firmware_logs_parser.get()->get_fw_log_lines(binary_data); + + // converting vector to vector + std::vector result; + + for (int i = 0; i < parsed_data_cpp.size(); ++i) + { + std::vector current_string_vec(parsed_data_cpp[i].begin(), parsed_data_cpp[i].end()); + result.insert(result.end(), current_string_vec.begin(), current_string_vec.end()); + result.push_back(10); + } + + return new rs2_raw_data_buffer { result }; +} +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, fw_logs_parser, raw_data) + rs2_terminal_parser* rs2_create_terminal_parser(const char* xml_content, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(xml_content); @@ -3031,3 +3078,6 @@ rs2_raw_data_buffer* rs2_terminal_parse_response(rs2_terminal_parser* terminal_p return new rs2_raw_data_buffer{ result }; } HANDLE_EXCEPTIONS_AND_RETURN(nullptr, terminal_parser, command, response) + + + From 367cb7237522a370abd2b8ae576e6fb1d8e13b09 Mon Sep 17 00:00:00 2001 From: remibettan Date: Sun, 17 May 2020 15:23:45 +0300 Subject: [PATCH 06/61] Design change - fw logs returned to user as structure, even without parser --- examples/firmware-logs/rs-firmware-logs.cpp | 36 +++-- include/librealsense2/h/rs_device.h | 14 +- include/librealsense2/hpp/rs_device.hpp | 132 ++++++++++++++++-- include/librealsense2/rs.h | 7 - src/CMakeLists.txt | 2 +- src/firmware_logger_device.cpp | 93 +++++++++++- src/firmware_logger_device.h | 10 +- .../CMakeLists.txt | 0 .../fw-log-data.cpp | 2 +- src/{fw-logs-parser => fw-logs}/fw-log-data.h | 6 +- .../fw-logs-formating-options.cpp | 2 +- .../fw-logs-formating-options.h | 2 +- .../fw-logs-parser.cpp | 29 +++- .../fw-logs-parser.h | 5 +- .../fw-logs-xml-helper.cpp | 2 +- .../fw-logs-xml-helper.h | 2 +- .../fw-string-formatter.cpp | 2 +- .../fw-string-formatter.h | 2 +- src/realsense.def | 1 + src/rs.cpp | 32 +++-- 20 files changed, 327 insertions(+), 54 deletions(-) rename src/{fw-logs-parser => fw-logs}/CMakeLists.txt (100%) rename src/{fw-logs-parser => fw-logs}/fw-log-data.cpp (97%) rename src/{fw-logs-parser => fw-logs}/fw-log-data.h (95%) rename src/{fw-logs-parser => fw-logs}/fw-logs-formating-options.cpp (98%) rename src/{fw-logs-parser => fw-logs}/fw-logs-formating-options.h (98%) rename src/{fw-logs-parser => fw-logs}/fw-logs-parser.cpp (79%) rename src/{fw-logs-parser => fw-logs}/fw-logs-parser.h (82%) rename src/{fw-logs-parser => fw-logs}/fw-logs-xml-helper.cpp (99%) rename src/{fw-logs-parser => fw-logs}/fw-logs-xml-helper.h (98%) rename src/{fw-logs-parser => fw-logs}/fw-string-formatter.cpp (99%) rename src/{fw-logs-parser => fw-logs}/fw-string-formatter.h (96%) diff --git a/examples/firmware-logs/rs-firmware-logs.cpp b/examples/firmware-logs/rs-firmware-logs.cpp index 40c0ac3765..79c6fc9e6d 100644 --- a/examples/firmware-logs/rs-firmware-logs.cpp +++ b/examples/firmware-logs/rs-firmware-logs.cpp @@ -71,15 +71,15 @@ int main(int argc, char * argv[]) this_thread::sleep_for(chrono::milliseconds(100)); auto fw_log = res.get_device().as(); - std::vector raw_data = fw_log.get_firmware_logs(); + std::vector fw_log_messages = fw_log.get_firmware_logs(); vector fw_log_lines = { "" }; - if (raw_data.size() <= 4) + if (fw_log_messages.size() <= 4) continue; - static bool usingParser = true; + static bool usingParser = false;; if (usingParser) { - std::string xml_path("HWLoggerEventsDS5.xml"); + /*std::string xml_path("HWLoggerEventsDS5.xml"); if (!xml_path.empty()) { ifstream f(xml_path); @@ -87,22 +87,34 @@ int main(int argc, char * argv[]) { unique_ptr parser = unique_ptr(new rs2::firmware_logs_parser(xml_path)); - bool datetime = true; - fw_log_lines = parser->get_firmware_logs_parsed(raw_data); + // first 4 bytes must be deleted - TODO REMI - check why + fw_log_messages.erase(fw_log_messages.begin(), fw_log_messages.begin() + 4); + std::vector one_raw_data; + + auto beginOfLogIterator = fw_log_messages.begin(); + + do { + auto endOfLogIterator = beginOfLogIterator + 20; + one_raw_data.insert(one_raw_data.begin(), beginOfLogIterator, endOfLogIterator); + fw_log_lines.push_back(parser->get_firmware_logs_parsed(one_raw_data)); + beginOfLogIterator = endOfLogIterator; + + if (endOfLogIterator == fw_log_messages.end()) + break; + } while (1); for (auto& elem : fw_log_lines) elem = datetime_string() + " " + elem; } - } - + }*/ } else { stringstream sstr; - sstr << datetime_string() << " FW_Log_Data:"; - for (size_t i = 0; i < raw_data.size(); ++i) - sstr << hexify(raw_data[i]) << " "; - + /*sstr << datetime_string() << " FW_Log_Data:";*/ + for (size_t i = 0; i < fw_log_messages.size(); ++i) + sstr << fw_log_messages[i].to_string() << "\n"; + fw_log_lines.push_back(sstr.str()); } diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index 31903d5905..8d4f496d94 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -353,9 +353,21 @@ rs2_raw_data_buffer* rs2_serialize_json(rs2_device* dev, rs2_error** error); /* Load JSON and apply advanced-mode controls */ void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_size, rs2_error** error); -/* Get firmware Logs */ +/** +* \brief Gets RealSense firmware logs. +* \param[in] dev Device from which the FW logs should be taken +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return firmware logs +*/ const rs2_raw_data_buffer* rs2_get_firmware_logs(rs2_device* dev, rs2_error** error); +/** +* \brief Gets size of one firmware log. +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return size of one firmware log +*/ +int rs2_get_firmware_logs_one_message_size(rs2_error** error); + /** * \brief Creates RealSense firmware logs parser. * \param[in] xml_path path to xml file needed for parsing diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index 27421d2958..e2de15151f 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -312,6 +312,106 @@ namespace rs2 } }; + class firmware_logger_message + { + public: + firmware_logger_message(const std::vector& fw_log_bytes) + { + int i = 0; + _magic_number = build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _severity = build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _file_id = build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _group_id = build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _event_id = build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _line = build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _sequence = build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _p1 = build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _p2 = build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _p3 = build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _timestamp = build_uint64_from8_uint8(fw_log_bytes.data() + i); + i += 8; + _delta = build_double_from8_uint8(fw_log_bytes.data() + i); + i += 8; + _thread_id = build_uint32_from4_uint8(fw_log_bytes.data() + i); + } + + std::string to_string() const + { + std::stringstream fmt; + fmt << "magic number = " << _magic_number << ",\t" + << "severity = " <<_severity << ",\t" + << "file = " <<_file_id << ",\t" + << "group = " << _group_id << ",\t" + << "line = " << _line << ",\t" + << "sequ = " <<_sequence << ",\t" + << "timestamp = " << _timestamp << ",\t" + << "delta = " << _delta << ",\t" + << "thread = " << _thread_id; + return fmt.str(); + } + + private: + uint32_t build_uint32_from4_uint8(const uint8_t* start) + { + uint8_t first = *(start); + uint8_t second = (*(start + 1)); + uint8_t third = (*(start + 2)); + uint8_t fourth = (*(start + 3)); + uint32_t res = first; + res += static_cast(second << 8); + res += static_cast(third << 16); + res += static_cast(fourth << 24); + return res; + } + + double build_double_from8_uint8(const uint8_t* start) + { + uint64_t resInInt = build_uint64_from8_uint8(start); + double res = *reinterpret_cast(&resInInt); + return res; + } + + uint64_t build_uint64_from8_uint8(const uint8_t* start) + { + uint32_t first = build_uint32_from4_uint8(start); + start += 4; + uint32_t second = build_uint32_from4_uint8(start); + uint64_t res = first; + res += static_cast(second << 32); + + return res; + } + uint32_t _magic_number; + uint32_t _severity; + uint32_t _file_id; + uint32_t _group_id; + uint32_t _event_id; + uint32_t _line; + uint32_t _sequence; + uint32_t _p1; + uint32_t _p2; + uint32_t _p3; + uint64_t _timestamp; + double _delta; + uint32_t _thread_id; + + std::string message; + std::string file_name; + std::string thread_name; + }; + + + class firmware_logger : public device { public: @@ -326,7 +426,7 @@ namespace rs2 error::handle(e); } - std::vector get_firmware_logs() const + std::vector get_firmware_logs() const { std::vector results; @@ -339,11 +439,25 @@ namespace rs2 auto size = rs2_get_raw_data_size(list.get(), &e); error::handle(e); - auto start = rs2_get_raw_data(list.get(), &e); - - results.insert(results.begin(), start, start + size); + auto sizeOfOneLog = rs2_get_firmware_logs_one_message_size(&e); + error::handle(e); - return results; + std::vector vec; + if (size > 0) + { + auto start = rs2_get_raw_data(list.get(), &e); + + results.insert(results.begin(), start, start + size); + auto startIt = results.begin(); + for (int i = 0; i < size / sizeOfOneLog; ++i) + { + std::vector resultsForOneLog; + resultsForOneLog.insert(resultsForOneLog.begin(), startIt, startIt + sizeOfOneLog); + vec.push_back(rs2::firmware_logger_message(resultsForOneLog)); + startIt += sizeOfOneLog; + } + } + return vec; } }; @@ -359,7 +473,7 @@ namespace rs2 error::handle(e); } - std::vector firmware_logs_parser::get_firmware_logs_parsed(const std::vector& raw_data) + std::string firmware_logs_parser::get_firmware_logs_parsed(std::vector& raw_data) { std::string results; @@ -378,7 +492,7 @@ namespace rs2 results.insert(results.begin(), start, start + size); //transforming the string to vector delimiter is '\n' - std::vector log_lines; + /*std::vector log_lines; std::size_t current_start = 0; std::size_t delimiter_found = results.find_first_of("\n"); while (delimiter_found != std::string::npos) @@ -386,9 +500,9 @@ namespace rs2 log_lines.push_back(std::string(results.substr(current_start, delimiter_found - current_start))); current_start = delimiter_found + 1; delimiter_found = results.find_first_of("\n", delimiter_found + 1); - } + }*/ - return log_lines; + return results; } firmware_logs_parser(std::shared_ptr fw_logs_parser) diff --git a/include/librealsense2/rs.h b/include/librealsense2/rs.h index 65fa5be7fe..f43e816461 100644 --- a/include/librealsense2/rs.h +++ b/include/librealsense2/rs.h @@ -110,13 +110,6 @@ float rs2_depth_frame_get_distance(const rs2_frame* frame_ref, int x, int y, rs2 */ rs2_time_t rs2_get_time( rs2_error** error); -/** - * Get Firmware logs - * \param[in] dev The Device - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - */ -const rs2_raw_data_buffer* rs2_get_firmware_logs(rs2_device* dev, rs2_error** error); - #ifdef __cplusplus } #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9052efa050..9fe5ce02c1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,7 +11,7 @@ include(${_rel_path}/proc/CMakeLists.txt) include(${_rel_path}/res/CMakeLists.txt) include(${_rel_path}/pipeline/CMakeLists.txt) include(${_rel_path}/usb/CMakeLists.txt) -include(${_rel_path}/fw-logs-parser/CMakeLists.txt) +include(${_rel_path}/fw-logs/CMakeLists.txt) include(${_rel_path}/fw-update/CMakeLists.txt) message(STATUS "using ${BACKEND}") diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 970c567a95..c8f093daab 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -8,7 +8,9 @@ namespace librealsense { firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor, std::string camera_op_code) : - _hw_monitor(hardware_monitor) + _hw_monitor(hardware_monitor), + _last_timestamp(0), + _timestamp_factor(0.00001) { auto op_code = static_cast(std::stoi(camera_op_code.c_str())); _input_code = { 0x14, 0x00, 0xab, 0xcd, op_code, 0x00, 0x00, 0x00, @@ -17,7 +19,7 @@ namespace librealsense } - std::vector firmware_logger_device::get_fw_logs() const + std::vector firmware_logger_device::get_fw_binary_logs() const { auto res = _hw_monitor->send(_input_code); if (res.empty()) @@ -26,4 +28,91 @@ namespace librealsense } return res; } + + std::vector firmware_logger_device::get_fw_logs() + { + auto res = _hw_monitor->send(_input_code); + if (res.empty()) + { + throw std::runtime_error("Getting Firmware logs failed!"); + } + + //TODO - REMI - check why this is required + res.erase(res.begin(), res.begin() + 4); + + std::vector vec; + auto beginOfLogIterator = res.begin(); + // convert bytes to fw_log_data + for (int i = 0; i < res.size() / fw_logs::BINARY_DATA_SIZE; ++i) + { + auto endOfLogIterator = beginOfLogIterator + fw_logs::BINARY_DATA_SIZE; + std::vector resultsForOneLog; + resultsForOneLog.insert(resultsForOneLog.begin(), beginOfLogIterator, endOfLogIterator); + auto temp_pointer = reinterpret_cast const*>(resultsForOneLog.data()); + auto log = const_cast(reinterpret_cast(temp_pointer)); + + fw_logs::fw_log_data data = fill_log_data(log); + beginOfLogIterator = endOfLogIterator; + + vec.push_back(data); + } + + return vec; + } + + fw_logs::fw_log_data firmware_logger_device::fill_log_data(const char* fw_logs) + { + fw_logs::fw_log_data log_data; + //fw_string_formatter reg_exp(_fw_logs_formating_options.get_enums()); + //fw_log_event log_event_data; + + auto* log_binary = reinterpret_cast(fw_logs); + + //parse first DWORD + log_data.magic_number = static_cast(log_binary->dword1.bits.magic_number); + log_data.severity = static_cast(log_binary->dword1.bits.severity); + + log_data.file_id = static_cast(log_binary->dword1.bits.file_id); + log_data.group_id = static_cast(log_binary->dword1.bits.group_id); + + //parse second DWORD + log_data.event_id = static_cast(log_binary->dword2.bits.event_id); + log_data.line = static_cast(log_binary->dword2.bits.line_id); + log_data.sequence = static_cast(log_binary->dword2.bits.seq_id); + + //parse third DWORD + log_data.p1 = static_cast(log_binary->dword3.p1); + log_data.p2 = static_cast(log_binary->dword3.p2); + + //parse forth DWORD + log_data.p3 = static_cast(log_binary->dword4.p3); + + //parse fifth DWORD + log_data.timestamp = log_binary->dword5.timestamp; + + //------------------------------------------------------------- + if (_last_timestamp == 0) + { + log_data.delta = 0; + } + else + { + log_data.delta = (log_data.timestamp - _last_timestamp) * _timestamp_factor; + } + + _last_timestamp = log_data.timestamp; + + log_data.thread_id = static_cast(log_binary->dword1.bits.thread_id); + //std::string message; + /* + _fw_logs_formating_options.get_event_data(log_data->event_id, &log_event_data); + uint32_t params[3] = { log_data->p1, log_data->p2, log_data->p3 }; + reg_exp.generate_message(log_event_data.line, log_event_data.num_of_params, params, &log_data->message); + + _fw_logs_formating_options.get_file_name(log_data->file_id, &log_data->file_name); + _fw_logs_formating_options.get_thread_name(static_cast(log_binary->dword1.bits.thread_id), + &log_data->thread_name);*/ + + return log_data; + } } \ No newline at end of file diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index 4456988a98..0b04ff9c65 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -6,13 +6,15 @@ #include "core/extension.h" #include "device.h" #include +#include "fw-logs/fw-log-data.h" namespace librealsense { class firmware_logger_extensions { public: - virtual std::vector get_fw_logs() const = 0; + virtual std::vector get_fw_binary_logs() const = 0; + virtual std::vector get_fw_logs() = 0; virtual ~firmware_logger_extensions() = default; }; MAP_EXTENSION(RS2_EXTENSION_FW_LOGGER, librealsense::firmware_logger_extensions); @@ -24,11 +26,15 @@ namespace librealsense firmware_logger_device(std::shared_ptr hardware_monitor, std::string camera_op_code); - std::vector get_fw_logs() const override; + std::vector get_fw_binary_logs() const override; + std::vector get_fw_logs() override; + fw_logs::fw_log_data fill_log_data(const char* fw_logs) ; private: std::vector _input_code; std::shared_ptr _hw_monitor; + uint64_t _last_timestamp; + const double _timestamp_factor; }; } \ No newline at end of file diff --git a/src/fw-logs-parser/CMakeLists.txt b/src/fw-logs/CMakeLists.txt similarity index 100% rename from src/fw-logs-parser/CMakeLists.txt rename to src/fw-logs/CMakeLists.txt diff --git a/src/fw-logs-parser/fw-log-data.cpp b/src/fw-logs/fw-log-data.cpp similarity index 97% rename from src/fw-logs-parser/fw-log-data.cpp rename to src/fw-logs/fw-log-data.cpp index 50d3d4860f..c9c870a9b8 100644 --- a/src/fw-logs-parser/fw-log-data.cpp +++ b/src/fw-logs/fw-log-data.cpp @@ -13,7 +13,7 @@ setfill(' ') << setw(num) << left << element \ namespace librealsense { - namespace fw_logs_parsing + namespace fw_logs { fw_log_data::fw_log_data(void) { diff --git a/src/fw-logs-parser/fw-log-data.h b/src/fw-logs/fw-log-data.h similarity index 95% rename from src/fw-logs-parser/fw-log-data.h rename to src/fw-logs/fw-log-data.h index 606d680894..f589f715d9 100644 --- a/src/fw-logs-parser/fw-log-data.h +++ b/src/fw-logs/fw-log-data.h @@ -8,13 +8,15 @@ namespace librealsense { - namespace fw_logs_parsing + namespace fw_logs { struct fw_logs_binary_data { std::vector logs_buffer; }; + static const int BINARY_DATA_SIZE = 20; + typedef union { uint32_t value; @@ -84,6 +86,8 @@ namespace librealsense uint64_t timestamp; double delta; + uint32_t thread_id; + std::string message; std::string file_name; std::string thread_name; diff --git a/src/fw-logs-parser/fw-logs-formating-options.cpp b/src/fw-logs/fw-logs-formating-options.cpp similarity index 98% rename from src/fw-logs-parser/fw-logs-formating-options.cpp rename to src/fw-logs/fw-logs-formating-options.cpp index 43e30acf61..1bab57c1af 100644 --- a/src/fw-logs-parser/fw-logs-formating-options.cpp +++ b/src/fw-logs/fw-logs-formating-options.cpp @@ -8,7 +8,7 @@ using namespace std; namespace librealsense { - namespace fw_logs_parsing + namespace fw_logs { fw_log_event::fw_log_event() : num_of_params(0), diff --git a/src/fw-logs-parser/fw-logs-formating-options.h b/src/fw-logs/fw-logs-formating-options.h similarity index 98% rename from src/fw-logs-parser/fw-logs-formating-options.h rename to src/fw-logs/fw-logs-formating-options.h index f67a198c95..241f92496f 100644 --- a/src/fw-logs-parser/fw-logs-formating-options.h +++ b/src/fw-logs/fw-logs-formating-options.h @@ -13,7 +13,7 @@ namespace librealsense { - namespace fw_logs_parsing + namespace fw_logs { struct fw_log_event { diff --git a/src/fw-logs-parser/fw-logs-parser.cpp b/src/fw-logs/fw-logs-parser.cpp similarity index 79% rename from src/fw-logs-parser/fw-logs-parser.cpp rename to src/fw-logs/fw-logs-parser.cpp index 37c1827cdf..7290a72549 100644 --- a/src/fw-logs-parser/fw-logs-parser.cpp +++ b/src/fw-logs/fw-logs-parser.cpp @@ -10,7 +10,7 @@ using namespace std; namespace librealsense { - namespace fw_logs_parsing + namespace fw_logs { fw_logs_parser::fw_logs_parser(string xml_full_file_path) : _fw_logs_formating_options(xml_full_file_path), @@ -28,7 +28,6 @@ namespace librealsense vector fw_logs_parser::get_fw_log_lines(const fw_logs_binary_data& fw_logs_data_binary) { fw_logs_binary_data binary_data = { fw_logs_data_binary }; - binary_data.logs_buffer.erase(binary_data.logs_buffer.begin(), binary_data.logs_buffer.begin() + 4); vector string_vector; int num_of_lines = int(binary_data.logs_buffer.size()) / sizeof(fw_log_binary); auto temp_pointer = reinterpret_cast(binary_data.logs_buffer.data()); @@ -52,6 +51,32 @@ namespace librealsense return log_data.to_string(); } + fw_log_data fw_logs_parser::generate_log_data(char* fw_logs) + { + fw_log_data log_data; + fill_log_data(fw_logs, &log_data); + + return log_data; + } + + vector fw_logs_parser::get_fw_log_data(const fw_logs_binary_data& fw_logs_data_binary) + { + fw_logs_binary_data binary_data = { fw_logs_data_binary }; + vector data_vector; + int num_of_lines = int(binary_data.logs_buffer.size()) / sizeof(fw_log_binary); + auto temp_pointer = reinterpret_cast(binary_data.logs_buffer.data()); + + for (int i = 0; i < num_of_lines; i++) + { + fw_log_data data; + auto log = const_cast(reinterpret_cast(temp_pointer)); + data = generate_log_data(log); + data_vector.push_back(data); + temp_pointer++; + } + return data_vector; + } + void fw_logs_parser::fill_log_data(const char* fw_logs, fw_log_data* log_data) { fw_string_formatter reg_exp(_fw_logs_formating_options.get_enums()); diff --git a/src/fw-logs-parser/fw-logs-parser.h b/src/fw-logs/fw-logs-parser.h similarity index 82% rename from src/fw-logs-parser/fw-logs-parser.h rename to src/fw-logs/fw-logs-parser.h index 7ed135558b..1bfc44ef83 100644 --- a/src/fw-logs-parser/fw-logs-parser.h +++ b/src/fw-logs/fw-logs-parser.h @@ -9,7 +9,7 @@ namespace librealsense { - namespace fw_logs_parsing + namespace fw_logs { class fw_logs_parser : public std::enable_shared_from_this { @@ -17,9 +17,12 @@ namespace librealsense explicit fw_logs_parser(std::string xml_full_file_path); ~fw_logs_parser(void); std::vector get_fw_log_lines(const fw_logs_binary_data& fw_logs_data_binary); + std::vector get_fw_log_data(const fw_logs_binary_data& fw_logs_data_binary); + private: std::string generate_log_line(char* fw_logs); + fw_log_data generate_log_data(char* fw_logs); void fill_log_data(const char* fw_logs, fw_log_data* log_data); uint64_t _last_timestamp; diff --git a/src/fw-logs-parser/fw-logs-xml-helper.cpp b/src/fw-logs/fw-logs-xml-helper.cpp similarity index 99% rename from src/fw-logs-parser/fw-logs-xml-helper.cpp rename to src/fw-logs/fw-logs-xml-helper.cpp index a17e1b05e1..03132f65b1 100644 --- a/src/fw-logs-parser/fw-logs-xml-helper.cpp +++ b/src/fw-logs/fw-logs-xml-helper.cpp @@ -10,7 +10,7 @@ using namespace std; namespace librealsense { - namespace fw_logs_parsing + namespace fw_logs { fw_logs_xml_helper::fw_logs_xml_helper(string xml_full_file_path) : _init_done(false), diff --git a/src/fw-logs-parser/fw-logs-xml-helper.h b/src/fw-logs/fw-logs-xml-helper.h similarity index 98% rename from src/fw-logs-parser/fw-logs-xml-helper.h rename to src/fw-logs/fw-logs-xml-helper.h index ecd3fdc32c..c9f5a31226 100644 --- a/src/fw-logs-parser/fw-logs-xml-helper.h +++ b/src/fw-logs/fw-logs-xml-helper.h @@ -8,7 +8,7 @@ using namespace rapidxml; namespace librealsense { - namespace fw_logs_parsing + namespace fw_logs { class fw_logs_xml_helper { diff --git a/src/fw-logs-parser/fw-string-formatter.cpp b/src/fw-logs/fw-string-formatter.cpp similarity index 99% rename from src/fw-logs-parser/fw-string-formatter.cpp rename to src/fw-logs/fw-string-formatter.cpp index 72f1348b8a..722a25d639 100644 --- a/src/fw-logs-parser/fw-string-formatter.cpp +++ b/src/fw-logs/fw-string-formatter.cpp @@ -11,7 +11,7 @@ using namespace std; namespace librealsense { - namespace fw_logs_parsing + namespace fw_logs { fw_string_formatter::fw_string_formatter(std::unordered_map> enums) :_enums(enums) diff --git a/src/fw-logs-parser/fw-string-formatter.h b/src/fw-logs/fw-string-formatter.h similarity index 96% rename from src/fw-logs-parser/fw-string-formatter.h rename to src/fw-logs/fw-string-formatter.h index e54e4a744d..7759e5b7ea 100644 --- a/src/fw-logs-parser/fw-string-formatter.h +++ b/src/fw-logs/fw-string-formatter.h @@ -9,7 +9,7 @@ namespace librealsense { - namespace fw_logs_parsing + namespace fw_logs { class fw_string_formatter { diff --git a/src/realsense.def b/src/realsense.def index 47c49f4c76..5907d008ab 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -357,6 +357,7 @@ EXPORTS rs2_set_calibration_table rs2_get_firmware_logs + rs2_get_firmware_logs_one_message_size rs2_create_firmware_logs_parser rs2_delete_firmware_logs_parser rs2_get_firmware_logs_parsed diff --git a/src/rs.cpp b/src/rs.cpp index a0f5941778..4f50dc2323 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -43,7 +43,7 @@ #include "auto-calibrated-device.h" #include "terminal-parser.h" #include "firmware_logger_device.h" -#include "fw-logs-parser/fw-logs-parser.h" +#include "fw-logs/fw-logs-parser.h" //////////////////////// // API implementation // //////////////////////// @@ -124,11 +124,9 @@ struct rs2_terminal_parser struct rs2_firmware_logs_parser { - std::shared_ptr firmware_logs_parser; + std::shared_ptr firmware_logs_parser; }; - - struct rs2_error { std::string message; @@ -2984,16 +2982,32 @@ const rs2_raw_data_buffer* rs2_get_firmware_logs(rs2_device* dev, rs2_error** er VALIDATE_NOT_NULL(dev); auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); - std::vector buffer = fw_loggerable->get_fw_logs(); - return new rs2_raw_data_buffer{ buffer }; + std::vector logs = fw_loggerable->get_fw_logs(); + std::vector buffer; + for (int i = 0; i < logs.size(); ++i) + { + uint32_t size = sizeof(logs[i]); + uint8_t* buf = reinterpret_cast(&logs[i]); + for (int j = 0; j < size; ++j) + { + buffer.push_back(*(buf + j)); + } + } + return new rs2_raw_data_buffer{ buffer }; } HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev) +int rs2_get_firmware_logs_one_message_size(rs2_error** error) BEGIN_API_CALL +{ + return sizeof(librealsense::fw_logs::fw_log_data); +} +NOEXCEPT_RETURN(0, error) + rs2_firmware_logs_parser* rs2_create_firmware_logs_parser(const char* xml_path, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(xml_path); - return new rs2_firmware_logs_parser{ std::make_shared(xml_path)}; + return new rs2_firmware_logs_parser{ std::make_shared(xml_path)}; } HANDLE_EXCEPTIONS_AND_RETURN(nullptr, xml_path) @@ -3010,8 +3024,8 @@ rs2_raw_data_buffer* rs2_get_firmware_logs_parsed(rs2_firmware_logs_parser* fw_l VALIDATE_NOT_NULL(raw_data); std::vector raw_data_buffer((uint8_t*)raw_data, (uint8_t*)raw_data + raw_data_size); - librealsense::fw_logs_parsing::fw_logs_binary_data binary_data = - librealsense::fw_logs_parsing::fw_logs_binary_data{ raw_data_buffer }; + librealsense::fw_logs::fw_logs_binary_data binary_data = + librealsense::fw_logs::fw_logs_binary_data{ raw_data_buffer }; std::vector parsed_data_cpp = fw_logs_parser->firmware_logs_parser.get()->get_fw_log_lines(binary_data); // converting vector to vector From 7ead7a1ae922997ec7a3a3b40e6f6a27186299c8 Mon Sep 17 00:00:00 2001 From: remibettan Date: Mon, 18 May 2020 10:05:04 +0300 Subject: [PATCH 07/61] FW logs parsing works --- examples/firmware-logs/rs-firmware-logs.cpp | 35 ++-- include/librealsense2/h/rs_device.h | 12 +- include/librealsense2/hpp/rs_device.hpp | 185 ++++++++++++-------- src/fw-logs/CMakeLists.txt | 1 + src/fw-logs/fw-logs-parser.cpp | 104 ++--------- src/fw-logs/fw-logs-parser.h | 8 +- src/realsense.def | 5 +- src/rs.cpp | 39 +++-- 8 files changed, 171 insertions(+), 218 deletions(-) diff --git a/examples/firmware-logs/rs-firmware-logs.cpp b/examples/firmware-logs/rs-firmware-logs.cpp index 79c6fc9e6d..0db73492af 100644 --- a/examples/firmware-logs/rs-firmware-logs.cpp +++ b/examples/firmware-logs/rs-firmware-logs.cpp @@ -72,14 +72,16 @@ int main(int argc, char * argv[]) auto fw_log = res.get_device().as(); std::vector fw_log_messages = fw_log.get_firmware_logs(); - vector fw_log_lines = { "" }; - if (fw_log_messages.size() <= 4) + + if (fw_log_messages.size() == 0) continue; - static bool usingParser = false;; + std::vector fw_log_lines; + + static bool usingParser = true; if (usingParser) { - /*std::string xml_path("HWLoggerEventsDS5.xml"); + std::string xml_path("HWLoggerEventsDS5.xml"); if (!xml_path.empty()) { ifstream f(xml_path); @@ -87,26 +89,17 @@ int main(int argc, char * argv[]) { unique_ptr parser = unique_ptr(new rs2::firmware_logs_parser(xml_path)); - // first 4 bytes must be deleted - TODO REMI - check why - fw_log_messages.erase(fw_log_messages.begin(), fw_log_messages.begin() + 4); - std::vector one_raw_data; - - auto beginOfLogIterator = fw_log_messages.begin(); - do { - auto endOfLogIterator = beginOfLogIterator + 20; - one_raw_data.insert(one_raw_data.begin(), beginOfLogIterator, endOfLogIterator); - fw_log_lines.push_back(parser->get_firmware_logs_parsed(one_raw_data)); - beginOfLogIterator = endOfLogIterator; - - if (endOfLogIterator == fw_log_messages.end()) - break; - } while (1); + for each (rs2::firmware_logger_message msg in fw_log_messages) + { + parser->parse_firmware_log(msg); + fw_log_lines.push_back(msg.to_string()); + } - for (auto& elem : fw_log_lines) - elem = datetime_string() + " " + elem; + /*for (auto& elem : fw_log_lines) + elem = datetime_string() + " " + elem;*/ } - }*/ + } } else { diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index 8d4f496d94..9a1977060f 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -385,13 +385,17 @@ void rs2_delete_firmware_logs_parser(rs2_firmware_logs_parser* parser); /** * \brief Parses firmware logs. * \param[in] fw_logs_parser firmware logs parser object -* \param[in] raw_data firmware logs not parsed -* \param[in] raw_data_size firmware logs not parsed size +* \param[in] event_id code for event +* \param[in] p1 parameter used to parse the message +* \param[in] p2 parameter used to parse the message +* \param[in] p3 parameter used to parse the message +* \param[in] file_id code for file +* \param[in] thread_id code for the thread * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return firmware logs parsed */ -rs2_raw_data_buffer* rs2_get_firmware_logs_parsed(rs2_firmware_logs_parser* fw_logs_parser, - const void* raw_data, const int raw_data_size, rs2_error** error); +rs2_raw_data_buffer* rs2_parse_firmware_log(rs2_firmware_logs_parser* fw_logs_parser, + int event_id, int p1, int p2, int p3, int file_id, int thread_id, rs2_error** error); #ifdef __cplusplus } diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index e2de15151f..e249cb142a 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -312,56 +312,10 @@ namespace rs2 } }; - class firmware_logger_message + class firmware_logs_helper { public: - firmware_logger_message(const std::vector& fw_log_bytes) - { - int i = 0; - _magic_number = build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _severity = build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _file_id = build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _group_id = build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _event_id = build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _line = build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _sequence = build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _p1 = build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _p2 = build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _p3 = build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _timestamp = build_uint64_from8_uint8(fw_log_bytes.data() + i); - i += 8; - _delta = build_double_from8_uint8(fw_log_bytes.data() + i); - i += 8; - _thread_id = build_uint32_from4_uint8(fw_log_bytes.data() + i); - } - - std::string to_string() const - { - std::stringstream fmt; - fmt << "magic number = " << _magic_number << ",\t" - << "severity = " <<_severity << ",\t" - << "file = " <<_file_id << ",\t" - << "group = " << _group_id << ",\t" - << "line = " << _line << ",\t" - << "sequ = " <<_sequence << ",\t" - << "timestamp = " << _timestamp << ",\t" - << "delta = " << _delta << ",\t" - << "thread = " << _thread_id; - return fmt.str(); - } - - private: - uint32_t build_uint32_from4_uint8(const uint8_t* start) + static uint32_t build_uint32_from4_uint8(const uint8_t* start) { uint8_t first = *(start); uint8_t second = (*(start + 1)); @@ -374,14 +328,14 @@ namespace rs2 return res; } - double build_double_from8_uint8(const uint8_t* start) + static double build_double_from8_uint8(const uint8_t* start) { uint64_t resInInt = build_uint64_from8_uint8(start); double res = *reinterpret_cast(&resInInt); return res; } - uint64_t build_uint64_from8_uint8(const uint8_t* start) + static uint64_t build_uint64_from8_uint8(const uint8_t* start) { uint32_t first = build_uint32_from4_uint8(start); start += 4; @@ -391,6 +345,77 @@ namespace rs2 return res; } + + static std::string build_string_from_uint8_and_size(const uint8_t* start, uint8_t size) + { + std::string res; + res.insert(res.begin(), start, start + size); + return res; + } + }; + + class firmware_logger_message + { + public: + firmware_logger_message(const std::vector& fw_log_bytes) + { + int i = 0; + _magic_number = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _severity = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _file_id = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _group_id = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _event_id = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _line = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _sequence = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _p1 = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _p2 = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _p3 = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); + i += 4; + _timestamp = firmware_logs_helper::build_uint64_from8_uint8(fw_log_bytes.data() + i); + i += 8; + _delta = firmware_logs_helper::build_double_from8_uint8(fw_log_bytes.data() + i); + i += 8; + _thread_id = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); + } + + std::string to_string() const + { + std::stringstream fmt; + if (_message.size() == 0) + { + fmt << "magic number = " << _magic_number << ",\t" + << "severity = " << _severity << ",\t" + << "file = " << _file_id << ",\t" + << "group = " << _group_id << ",\t" + << "line = " << _line << ",\t" + << "sequ = " << _sequence << ",\t" + << "timestamp = " << _timestamp << ",\t" + << "delta = " << _delta << ",\t" + << "thread = " << _thread_id; + } + else + { + fmt << "severity = " << _severity << ",\t" + << "file_name = " << _file_name << ",\t" + << "line = " << _line << ",\t" + << "timestamp = " << _timestamp << ",\t" + << "message = " << _message << ",\t" + << "thread = " << _thread_name; + } + + return fmt.str(); + } + + uint32_t _magic_number; uint32_t _severity; uint32_t _file_id; @@ -405,13 +430,11 @@ namespace rs2 double _delta; uint32_t _thread_id; - std::string message; - std::string file_name; - std::string thread_name; + std::string _message; + std::string _file_name; + std::string _thread_name; }; - - class firmware_logger : public device { public: @@ -473,36 +496,48 @@ namespace rs2 error::handle(e); } - std::string firmware_logs_parser::get_firmware_logs_parsed(std::vector& raw_data) + void parse_firmware_log(rs2::firmware_logger_message& msg) { - std::string results; - rs2_error* e = nullptr; + std::shared_ptr parsed_logs( - rs2_get_firmware_logs_parsed(_firmware_logs_parser.get(), (const void*)raw_data.data(), (const int)raw_data.size(), &e), + rs2_parse_firmware_log(_firmware_logs_parser.get(), + msg._event_id, msg._p1, msg._p2, msg._p3, msg._file_id, msg._thread_id, &e), rs2_delete_raw_data); rs2::error::handle(e); auto size = rs2_get_raw_data_size(parsed_logs.get(), &e); rs2::error::handle(e); - auto start = rs2_get_raw_data(parsed_logs.get(), &e); - rs2::error::handle(e); - - results.insert(results.begin(), start, start + size); - - //transforming the string to vector delimiter is '\n' - /*std::vector log_lines; - std::size_t current_start = 0; - std::size_t delimiter_found = results.find_first_of("\n"); - while (delimiter_found != std::string::npos) + + if (size > 0) { - log_lines.push_back(std::string(results.substr(current_start, delimiter_found - current_start))); - current_start = delimiter_found + 1; - delimiter_found = results.find_first_of("\n", delimiter_found + 1); - }*/ - - return results; + auto start = rs2_get_raw_data(parsed_logs.get(), &e); + + int i = 0; + //retreive message + uint8_t messageSize = *start; + i += 1; + std::string message(firmware_logs_helper::build_string_from_uint8_and_size(start + i, messageSize)); + i += messageSize; + + //retreive file_name + uint8_t fileNameSize = *(start + i); + i += 1; + std::string file_name(firmware_logs_helper::build_string_from_uint8_and_size(start + i, fileNameSize)); + i += fileNameSize; + + //retreive thread_name + uint8_t threadNameSize = *(start + i); + i += 1; + std::string thread_name(firmware_logs_helper::build_string_from_uint8_and_size(start + i, threadNameSize)); + i += threadNameSize; + + //replace in input message + msg._message = message; + msg._file_name = file_name; + msg._thread_name = thread_name; + } } firmware_logs_parser(std::shared_ptr fw_logs_parser) diff --git a/src/fw-logs/CMakeLists.txt b/src/fw-logs/CMakeLists.txt index 33f79d0b81..426bc350ad 100644 --- a/src/fw-logs/CMakeLists.txt +++ b/src/fw-logs/CMakeLists.txt @@ -2,6 +2,7 @@ # Copyright(c) 2020 Intel Corporation. All Rights Reserved. target_sources(${LRS_TARGET} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/fw-log-data.cpp" "${CMAKE_CURRENT_LIST_DIR}/fw-log-data.h" "${CMAKE_CURRENT_LIST_DIR}/fw-logs-formating-options.cpp" "${CMAKE_CURRENT_LIST_DIR}/fw-logs-formating-options.h" diff --git a/src/fw-logs/fw-logs-parser.cpp b/src/fw-logs/fw-logs-parser.cpp index 7290a72549..0f8231e791 100644 --- a/src/fw-logs/fw-logs-parser.cpp +++ b/src/fw-logs/fw-logs-parser.cpp @@ -13,9 +13,7 @@ namespace librealsense namespace fw_logs { fw_logs_parser::fw_logs_parser(string xml_full_file_path) - : _fw_logs_formating_options(xml_full_file_path), - _last_timestamp(0), - _timestamp_factor(0.00001) + : _fw_logs_formating_options(xml_full_file_path) { _fw_logs_formating_options.initialize_from_xml(); } @@ -25,104 +23,22 @@ namespace librealsense { } - vector fw_logs_parser::get_fw_log_lines(const fw_logs_binary_data& fw_logs_data_binary) + fw_log_data fw_logs_parser::parse_fw_log(uint32_t event_id, uint32_t p1, uint32_t p2, uint32_t p3, + uint32_t file_id, uint32_t thread_id) { - fw_logs_binary_data binary_data = { fw_logs_data_binary }; - vector string_vector; - int num_of_lines = int(binary_data.logs_buffer.size()) / sizeof(fw_log_binary); - auto temp_pointer = reinterpret_cast(binary_data.logs_buffer.data()); + fw_log_data result; - for (int i = 0; i < num_of_lines; i++) - { - string line; - auto log = const_cast(reinterpret_cast(temp_pointer)); - line = generate_log_line(log); - string_vector.push_back(line); - temp_pointer++; - } - return string_vector; - } - - string fw_logs_parser::generate_log_line(char* fw_logs) - { - fw_log_data log_data; - fill_log_data(fw_logs, &log_data); - - return log_data.to_string(); - } - - fw_log_data fw_logs_parser::generate_log_data(char* fw_logs) - { - fw_log_data log_data; - fill_log_data(fw_logs, &log_data); - - return log_data; - } - - vector fw_logs_parser::get_fw_log_data(const fw_logs_binary_data& fw_logs_data_binary) - { - fw_logs_binary_data binary_data = { fw_logs_data_binary }; - vector data_vector; - int num_of_lines = int(binary_data.logs_buffer.size()) / sizeof(fw_log_binary); - auto temp_pointer = reinterpret_cast(binary_data.logs_buffer.data()); - - for (int i = 0; i < num_of_lines; i++) - { - fw_log_data data; - auto log = const_cast(reinterpret_cast(temp_pointer)); - data = generate_log_data(log); - data_vector.push_back(data); - temp_pointer++; - } - return data_vector; - } - - void fw_logs_parser::fill_log_data(const char* fw_logs, fw_log_data* log_data) - { fw_string_formatter reg_exp(_fw_logs_formating_options.get_enums()); fw_log_event log_event_data; - auto* log_binary = reinterpret_cast(fw_logs); - - //parse first DWORD - log_data->magic_number = static_cast(log_binary->dword1.bits.magic_number); - log_data->severity = static_cast(log_binary->dword1.bits.severity); - - log_data->file_id = static_cast(log_binary->dword1.bits.file_id); - log_data->group_id = static_cast(log_binary->dword1.bits.group_id); - - //parse second DWORD - log_data->event_id = static_cast(log_binary->dword2.bits.event_id); - log_data->line = static_cast(log_binary->dword2.bits.line_id); - log_data->sequence = static_cast(log_binary->dword2.bits.seq_id); - - //parse third DWORD - log_data->p1 = static_cast(log_binary->dword3.p1); - log_data->p2 = static_cast(log_binary->dword3.p2); - - //parse forth DWORD - log_data->p3 = static_cast(log_binary->dword4.p3); - - //parse fifth DWORD - log_data->timestamp = log_binary->dword5.timestamp; - - if (_last_timestamp == 0) - { - log_data->delta = 0; - } - else - { - log_data->delta = (log_data->timestamp - _last_timestamp) * _timestamp_factor; - } + _fw_logs_formating_options.get_event_data(event_id, &log_event_data); + uint32_t params[3] = { p1, p2, p3 }; + reg_exp.generate_message(log_event_data.line, log_event_data.num_of_params, params, &result.message); - _last_timestamp = log_data->timestamp; - _fw_logs_formating_options.get_event_data(log_data->event_id, &log_event_data); - uint32_t params[3] = { log_data->p1, log_data->p2, log_data->p3 }; - reg_exp.generate_message(log_event_data.line, log_event_data.num_of_params, params, &log_data->message); + _fw_logs_formating_options.get_file_name(file_id, &result.file_name); + _fw_logs_formating_options.get_thread_name(static_cast(thread_id), &result.thread_name); - _fw_logs_formating_options.get_file_name(log_data->file_id, &log_data->file_name); - _fw_logs_formating_options.get_thread_name(static_cast(log_binary->dword1.bits.thread_id), - &log_data->thread_name); + return result; } } } diff --git a/src/fw-logs/fw-logs-parser.h b/src/fw-logs/fw-logs-parser.h index 1bfc44ef83..7715561984 100644 --- a/src/fw-logs/fw-logs-parser.h +++ b/src/fw-logs/fw-logs-parser.h @@ -16,18 +16,14 @@ namespace librealsense public: explicit fw_logs_parser(std::string xml_full_file_path); ~fw_logs_parser(void); - std::vector get_fw_log_lines(const fw_logs_binary_data& fw_logs_data_binary); - std::vector get_fw_log_data(const fw_logs_binary_data& fw_logs_data_binary); + fw_log_data parse_fw_log(uint32_t event_id, uint32_t p1, uint32_t p2, uint32_t p3, + uint32_t file_id, uint32_t thread_id); private: - std::string generate_log_line(char* fw_logs); - fw_log_data generate_log_data(char* fw_logs); void fill_log_data(const char* fw_logs, fw_log_data* log_data); - uint64_t _last_timestamp; fw_logs_formating_options _fw_logs_formating_options; - const double _timestamp_factor; }; } } diff --git a/src/realsense.def b/src/realsense.def index 5907d008ab..5478e5b588 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -355,15 +355,16 @@ EXPORTS rs2_run_tare_calibration rs2_get_calibration_table rs2_set_calibration_table - + rs2_get_firmware_logs rs2_get_firmware_logs_one_message_size rs2_create_firmware_logs_parser rs2_delete_firmware_logs_parser - rs2_get_firmware_logs_parsed + rs2_parse_firmware_log rs2_create_terminal_parser rs2_delete_terminal_parser rs2_terminal_parse_command rs2_terminal_parse_response + diff --git a/src/rs.cpp b/src/rs.cpp index 4f50dc2323..cf32596431 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -3018,29 +3018,36 @@ void rs2_delete_firmware_logs_parser(rs2_firmware_logs_parser* parser) BEGIN_API } NOEXCEPT_RETURN(, parser) -rs2_raw_data_buffer* rs2_get_firmware_logs_parsed(rs2_firmware_logs_parser* fw_logs_parser, const void* raw_data, const int raw_data_size, rs2_error** error) BEGIN_API_CALL +rs2_raw_data_buffer* rs2_parse_firmware_log(rs2_firmware_logs_parser* fw_logs_parser, + int event_id, int p1, int p2, int p3, int file_id, int thread_id, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(fw_logs_parser); - VALIDATE_NOT_NULL(raw_data); - std::vector raw_data_buffer((uint8_t*)raw_data, (uint8_t*)raw_data + raw_data_size); - librealsense::fw_logs::fw_logs_binary_data binary_data = - librealsense::fw_logs::fw_logs_binary_data{ raw_data_buffer }; - std::vector parsed_data_cpp = fw_logs_parser->firmware_logs_parser.get()->get_fw_log_lines(binary_data); + librealsense::fw_logs::fw_log_data fw_log = fw_logs_parser->firmware_logs_parser.get()->parse_fw_log(event_id, p1, p2, p3, file_id, thread_id); - // converting vector to vector - std::vector result; + std::vector message_bytes(fw_log.message.begin(), fw_log.message.end()); + message_bytes.push_back('\0'); + uint8_t msg_bytes_size = message_bytes.size(); - for (int i = 0; i < parsed_data_cpp.size(); ++i) - { - std::vector current_string_vec(parsed_data_cpp[i].begin(), parsed_data_cpp[i].end()); - result.insert(result.end(), current_string_vec.begin(), current_string_vec.end()); - result.push_back(10); - } + std::vector file_name_bytes(fw_log.file_name.begin(), fw_log.file_name.end()); + file_name_bytes.push_back('\0'); + uint8_t file_name_bytes_size = file_name_bytes.size(); + + std::vector thread_name_bytes(fw_log.thread_name.begin(), fw_log.thread_name.end()); + thread_name_bytes.push_back('\0'); + uint8_t thread_name_bytes_size = thread_name_bytes.size(); + + std::vector msg_file_thread_bytes; + msg_file_thread_bytes.push_back(msg_bytes_size); + msg_file_thread_bytes.insert(msg_file_thread_bytes.end(), message_bytes.begin(), message_bytes.end()); + msg_file_thread_bytes.push_back(file_name_bytes_size); + msg_file_thread_bytes.insert(msg_file_thread_bytes.end(), file_name_bytes.begin(), file_name_bytes.end()); + msg_file_thread_bytes.push_back(thread_name_bytes_size); + msg_file_thread_bytes.insert(msg_file_thread_bytes.end(), thread_name_bytes.begin(), thread_name_bytes.end()); - return new rs2_raw_data_buffer { result }; + return new rs2_raw_data_buffer { msg_file_thread_bytes }; } -HANDLE_EXCEPTIONS_AND_RETURN(nullptr, fw_logs_parser, raw_data) +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, fw_logs_parser) rs2_terminal_parser* rs2_create_terminal_parser(const char* xml_content, rs2_error** error) BEGIN_API_CALL { From a599428432504da4ecb68c455d01a094931565a2 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 20 May 2020 21:21:38 +0300 Subject: [PATCH 08/61] FW logs corrected to work with C API - remaining work for the parsing to be more user-friendly --- include/librealsense2/h/rs_device.h | 10 +- include/librealsense2/h/rs_types.h | 28 ++++ include/librealsense2/hpp/rs_device.hpp | 62 +++++---- src/firmware_logger_device.cpp | 31 +++++ src/firmware_logger_device.h | 4 +- src/fw-logs/fw-log-data.cpp | 30 +++++ src/fw-logs/fw-log-data.h | 3 +- src/realsense.def | 4 +- src/rs.cpp | 75 +++++++++-- unit-tests/fw-logs/fw-logs-common.h | 30 +++++ .../fw-logs/test-c-get-fw-logs-not-parsed.cpp | 70 ++++++++++ .../fw-logs/test-c-get-fw-logs-parsed.cpp | 122 ++++++++++++++++++ 12 files changed, 422 insertions(+), 47 deletions(-) create mode 100644 unit-tests/fw-logs/fw-logs-common.h create mode 100644 unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp create mode 100644 unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index 9a1977060f..aeafe048e1 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -359,14 +359,14 @@ void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_s * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return firmware logs */ -const rs2_raw_data_buffer* rs2_get_firmware_logs(rs2_device* dev, rs2_error** error); +rs2_firmware_log_message_list* rs2_get_firmware_logs_list(rs2_device* dev, rs2_error** error); + /** -* \brief Gets size of one firmware log. -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return size of one firmware log +* \brief Frees the relevant firmware logs messages list object. +* \param[in] firmware logs messages list object that is no longer needed */ -int rs2_get_firmware_logs_one_message_size(rs2_error** error); +void rs2_delete_firmware_logs_list(rs2_firmware_log_message_list* fw_logs_list); /** * \brief Creates RealSense firmware logs parser. diff --git a/include/librealsense2/h/rs_types.h b/include/librealsense2/h/rs_types.h index 8c9d01c96f..c709906fce 100644 --- a/include/librealsense2/h/rs_types.h +++ b/include/librealsense2/h/rs_types.h @@ -117,6 +117,34 @@ typedef struct rs2_pose unsigned int mapper_confidence; /**< Pose map confidence 0x0 - Failed, 0x1 - Low, 0x2 - Medium, 0x3 - High */ } rs2_pose; +/** \brief Firmware log message. */ +typedef struct rs2_firmware_log_message +{ + unsigned int _magic_number; /**< magic number at start of the fw log */ + unsigned int _severity; /**< severity of the fw log */ + unsigned int _file_id; /**< id of the file from which the fw log has bee triggered */ + unsigned int _group_id; /**< id of the group from which the fw log has bee triggered */ + unsigned int _event_id; /**< id of the event that the fw log refers to */ + unsigned int _line; /**< line from which the fw log has bee triggered */ + unsigned int _sequence; /**< sequence number from which the fw log has bee triggered */ + unsigned int _p1; /**< parameter for parsing lthe fw log */ + unsigned int _p2; /**< parameter for parsing lthe fw log */ + unsigned int _p3; /**< parameter for parsing lthe fw log */ + unsigned long long _timestamp; /**< timestamp of the fw log */ + double _delta; /**< delta of the timestamp between current and previous fw logs */ + unsigned long long _thread_id; /**< id of the thread from which the fw log has bee triggered */ + + char* _message; /**< fw log message */ + char* _file_name; /**< name of the file from which the fw log has bee triggered */ + char* _thread_name; /**< name of the thread from which the fw log has bee triggered */ +} rs2_firmware_log_message; + +typedef struct rs2_firmware_log_message_list +{ + rs2_firmware_log_message* _messages;/**< pointer to firmware log messages */ + size_t _number_of_messages; /**< number of messages in the member _messages */ +} rs2_firmware_log_message_list; + /** \brief Severity of the librealsense logger. */ typedef enum rs2_log_severity { RS2_LOG_SEVERITY_DEBUG, /**< Detailed information about ordinary operations */ diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index e249cb142a..1fa2bb8483 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -387,6 +387,26 @@ namespace rs2 _thread_id = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); } + firmware_logger_message(const rs2_firmware_log_message& msg) + { + _magic_number = msg._magic_number; + _severity = msg._severity; + _file_id = msg._file_id; + _group_id = msg._group_id; + _event_id = msg._event_id; + _line = msg._line; + _sequence = msg._sequence; + _p1 = msg._p1; + _p2 = msg._p2; + _p3 = msg._p3; + _timestamp = msg._timestamp; + _delta = msg._delta; + _thread_id = msg._thread_id; + /*_message = std::string(msg._message); + _file_name = std::string(msg._file_name); + _thread_name = std::string(msg._thread_name);*/ + } + std::string to_string() const { std::stringstream fmt; @@ -451,35 +471,29 @@ namespace rs2 std::vector get_firmware_logs() const { - std::vector results; + rs2_error* e = nullptr; - rs2_error* e = nullptr; - std::shared_ptr list( - rs2_get_firmware_logs(_dev.get(), &e), - rs2_delete_raw_data); + std::shared_ptr msg_list( + rs2_get_firmware_logs_list(_dev.get(), &e), + rs2_delete_firmware_logs_list); error::handle(e); - auto size = rs2_get_raw_data_size(list.get(), &e); - error::handle(e); - - auto sizeOfOneLog = rs2_get_firmware_logs_one_message_size(&e); - error::handle(e); - std::vector vec; - if (size > 0) + + if (msg_list) { - auto start = rs2_get_raw_data(list.get(), &e); - - results.insert(results.begin(), start, start + size); - auto startIt = results.begin(); - for (int i = 0; i < size / sizeOfOneLog; ++i) + size_t number_of_messages = msg_list.get()->_number_of_messages > 0; + if (number_of_messages > 0) { - std::vector resultsForOneLog; - resultsForOneLog.insert(resultsForOneLog.begin(), startIt, startIt + sizeOfOneLog); - vec.push_back(rs2::firmware_logger_message(resultsForOneLog)); - startIt += sizeOfOneLog; + // for each message: convert rs2_firmware_log_message to rs2::firmware_log_message + for (int i = 0; i < number_of_messages; ++i) + { + rs2::firmware_logger_message message_received(msg_list.get()->_messages[i]); + vec.push_back(message_received); + } } } + return vec; } }; @@ -500,19 +514,19 @@ namespace rs2 { rs2_error* e = nullptr; - std::shared_ptr parsed_logs( + std::shared_ptr parsed_log( rs2_parse_firmware_log(_firmware_logs_parser.get(), msg._event_id, msg._p1, msg._p2, msg._p3, msg._file_id, msg._thread_id, &e), rs2_delete_raw_data); rs2::error::handle(e); - auto size = rs2_get_raw_data_size(parsed_logs.get(), &e); + auto size = rs2_get_raw_data_size(parsed_log.get(), &e); rs2::error::handle(e); if (size > 0) { - auto start = rs2_get_raw_data(parsed_logs.get(), &e); + auto start = rs2_get_raw_data(parsed_log.get(), &e); int i = 0; //retreive message diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index c8f093daab..4097270443 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -60,6 +60,37 @@ namespace librealsense return vec; } + std::vector firmware_logger_device::get_fw_logs_msg() + { + auto res = _hw_monitor->send(_input_code); + if (res.empty()) + { + throw std::runtime_error("Getting Firmware logs failed!"); + } + + //TODO - REMI - check why this is required + res.erase(res.begin(), res.begin() + 4); + + std::vector vec; + auto beginOfLogIterator = res.begin(); + // convert bytes to rs2_firmware_log_message + for (int i = 0; i < res.size() / fw_logs::BINARY_DATA_SIZE; ++i) + { + auto endOfLogIterator = beginOfLogIterator + fw_logs::BINARY_DATA_SIZE; + std::vector resultsForOneLog; + resultsForOneLog.insert(resultsForOneLog.begin(), beginOfLogIterator, endOfLogIterator); + auto temp_pointer = reinterpret_cast const*>(resultsForOneLog.data()); + auto log = const_cast(reinterpret_cast(temp_pointer)); + + fw_logs::fw_log_data data = fill_log_data(log); + rs2_firmware_log_message msg = data.to_rs2_firmware_log_message(); + beginOfLogIterator = endOfLogIterator; + + vec.push_back(msg); + } + return vec; + } + fw_logs::fw_log_data firmware_logger_device::fill_log_data(const char* fw_logs) { fw_logs::fw_log_data log_data; diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index 0b04ff9c65..f65db5ef3d 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -13,8 +13,9 @@ namespace librealsense class firmware_logger_extensions { public: - virtual std::vector get_fw_binary_logs() const = 0; + virtual std::vector get_fw_binary_logs() const = 0; virtual std::vector get_fw_logs() = 0; + virtual std::vector get_fw_logs_msg() = 0; virtual ~firmware_logger_extensions() = default; }; MAP_EXTENSION(RS2_EXTENSION_FW_LOGGER, librealsense::firmware_logger_extensions); @@ -28,6 +29,7 @@ namespace librealsense std::vector get_fw_binary_logs() const override; std::vector get_fw_logs() override; + std::vector get_fw_logs_msg() override; fw_logs::fw_log_data fill_log_data(const char* fw_logs) ; private: diff --git a/src/fw-logs/fw-log-data.cpp b/src/fw-logs/fw-log-data.cpp index c9c870a9b8..1f1b6ca5e8 100644 --- a/src/fw-logs/fw-log-data.cpp +++ b/src/fw-logs/fw-log-data.cpp @@ -56,5 +56,35 @@ namespace librealsense auto str = fmt.str(); return str; } + + rs2_firmware_log_message fw_log_data::to_rs2_firmware_log_message() + { + rs2_firmware_log_message msg; + msg._magic_number = this->magic_number; + msg._severity = this->severity; + msg._file_id = this->file_id; + msg._group_id = this->group_id; + msg._event_id = this->event_id; + msg._line = this->line; + msg._sequence = this->sequence; + msg._p1 = this->p1; + msg._p2 = this->p2; + msg._p3 = this->p3; + msg._timestamp = this->timestamp; + msg._thread_id = this->thread_id; + + + //TODO - REMI - check these pointers are deleted in rs2_firmware_log_message destructor + /*msg._message = new char[this->message.size()]; + strcpy(msg._message, this->message.c_str()); + + msg._file_name = new char[this->file_name.size()]; + strcpy(msg._file_name, this->file_name.c_str()); + + msg._thread_name = new char[this->thread_name.size()]; + strcpy(msg._thread_name, this->thread_name.c_str());*/ + + return msg; + } } } diff --git a/src/fw-logs/fw-log-data.h b/src/fw-logs/fw-log-data.h index f589f715d9..585252251e 100644 --- a/src/fw-logs/fw-log-data.h +++ b/src/fw-logs/fw-log-data.h @@ -4,7 +4,7 @@ #include #include #include - +#include "../types.h" //for rs2_firmware_log_message namespace librealsense { @@ -93,6 +93,7 @@ namespace librealsense std::string thread_name; std::string to_string(); + rs2_firmware_log_message to_rs2_firmware_log_message(); }; } } diff --git a/src/realsense.def b/src/realsense.def index 5478e5b588..d10da6b2c4 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -356,8 +356,8 @@ EXPORTS rs2_get_calibration_table rs2_set_calibration_table - rs2_get_firmware_logs - rs2_get_firmware_logs_one_message_size + rs2_get_firmware_logs_list + rs2_delete_firmware_logs_list rs2_create_firmware_logs_parser rs2_delete_firmware_logs_parser rs2_parse_firmware_log diff --git a/src/rs.cpp b/src/rs.cpp index cf32596431..ec64656763 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -2977,31 +2977,78 @@ void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_s } HANDLE_EXCEPTIONS_AND_RETURN(, dev, json_content, content_size) -const rs2_raw_data_buffer* rs2_get_firmware_logs(rs2_device* dev, rs2_error** error) BEGIN_API_CALL +rs2_firmware_log_message* rs2_get_firmware_logs(rs2_device* dev, int* number_of_messages, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(dev); + VALIDATE_NOT_NULL(number_of_messages); auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + + std::vector logs = fw_loggerable->get_fw_logs(); + *number_of_messages = logs.size(); + rs2_firmware_log_message* list = new rs2_firmware_log_message[*number_of_messages]; + for(int i = 0; i < *number_of_messages; ++i) + { + list[i] = logs[i].to_rs2_firmware_log_message(); + } + + return list; +} +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev, number_of_messages, error) + +rs2_firmware_log_message_list* rs2_get_firmware_logs_list(rs2_device* dev, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(dev); + auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + std::vector logs = fw_loggerable->get_fw_logs(); - std::vector buffer; - for (int i = 0; i < logs.size(); ++i) + size_t numOfLogs = logs.size(); + + rs2_firmware_log_message* messages = new rs2_firmware_log_message[numOfLogs]; + rs2_firmware_log_message_list* list = new rs2_firmware_log_message_list; + list->_messages = messages; + list->_number_of_messages = logs.size(); + for (size_t i = 0; i < numOfLogs; ++i) { - uint32_t size = sizeof(logs[i]); - uint8_t* buf = reinterpret_cast(&logs[i]); - for (int j = 0; j < size; ++j) - { - buffer.push_back(*(buf + j)); - } + list->_messages[i] = logs[i].to_rs2_firmware_log_message(); } - return new rs2_raw_data_buffer{ buffer }; + + return list; } -HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev) +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev, error) -int rs2_get_firmware_logs_one_message_size(rs2_error** error) BEGIN_API_CALL +void rs2_delete_firmware_logs(rs2_firmware_log_message* fw_logs_list) BEGIN_API_CALL { - return sizeof(librealsense::fw_logs::fw_log_data); + VALIDATE_NOT_NULL(fw_logs_list); + + delete[] fw_logs_list[0]._message; + delete[] fw_logs_list[0]._file_name; + delete[] fw_logs_list[0]._thread_name; + + delete[] fw_logs_list; +} +NOEXCEPT_RETURN(, fw_logs_list) + +void rs2_delete_firmware_logs_list(rs2_firmware_log_message_list* fw_logs_list) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(fw_logs_list); + + if (fw_logs_list->_messages) + { + /*for (int i = 0; i < fw_logs_list->_number_of_messages; ++i) + { + if (fw_logs_list->_messages[i]._message) + delete fw_logs_list->_messages[i]._message; + if (fw_logs_list->_messages[i]._file_name) + delete fw_logs_list->_messages[i]._file_name; + if (fw_logs_list->_messages[i]._thread_name) + delete fw_logs_list->_messages[i]._thread_name; + }*/ + delete[] fw_logs_list->_messages; + } + delete[] fw_logs_list; } -NOEXCEPT_RETURN(0, error) +NOEXCEPT_RETURN(, fw_logs_list) rs2_firmware_logs_parser* rs2_create_firmware_logs_parser(const char* xml_path, rs2_error** error) BEGIN_API_CALL { diff --git a/unit-tests/fw-logs/fw-logs-common.h b/unit-tests/fw-logs/fw-logs-common.h new file mode 100644 index 0000000000..5609f00be3 --- /dev/null +++ b/unit-tests/fw-logs/fw-logs-common.h @@ -0,0 +1,30 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +#pragma once + +#include // Include RealSense Cross Platform API + + +// Catch also defines CHECK(), and so we have to undefine it or we get compilation errors! +#undef CHECK + +// Let Catch define its own main() function +#define CATCH_CONFIG_MAIN +#include "../catch/catch.hpp" + +// Define our own logging macro for debugging to stdout +// Can possibly turn it on automatically based on the Catch options supplied +// on the command-line, with a custom main(): +// Catch::Session catch_session; +// int main (int argc, char * const argv[]) { +// return catch_session.run( argc, argv ); +// } +// #define TRACE(X) if( catch_session.configData().verbosity == ... ) {} +// With Catch2, we can turn this into SCOPED_INFO. +#define TRACE(X) do { \ + std::cout << X << std::endl; \ + } while(0) + + + diff --git a/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp b/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp new file mode 100644 index 0000000000..3b3b906e30 --- /dev/null +++ b/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp @@ -0,0 +1,70 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +//#cmake:add-file fw-logs-common.h +#include "fw-logs-common.h" + +/* Include the librealsense C header files */ +#include +#include +#include +#include +#include + +char* rs2_firmware_log_message_to_string(rs2_firmware_log_message msg) +{ + char* buffer = (char*)(malloc(50 * sizeof(char))); + sprintf(buffer, "sev = %d, file = %d, line = %d", msg._severity, msg._file_id, msg._line); + return buffer; +} + +//get fw logs using c api +TEST_CASE( "Getting FW logs in C", "[fw-logs]" ) { + + rs2_error* e = 0; + + // Create a context object. This object owns the handles to all connected realsense devices. + // The returned object should be released with rs2_delete_context(...) + rs2_context* ctx = rs2_create_context(RS2_API_VERSION, &e); + REQUIRE(e == 0); + + /* Get a list of all the connected devices. */ + // The returned object should be released with rs2_delete_device_list(...) + rs2_device_list* device_list = rs2_query_devices(ctx, &e); + REQUIRE(e == 0); + + int dev_count = rs2_get_device_count(device_list, &e); + REQUIRE(e == 0); + printf("There are %d connected RealSense devices.\n", dev_count); + REQUIRE(dev_count > 0); + + // Get the first connected device + // The returned object should be released with rs2_delete_device(...) + rs2_device* dev = rs2_create_device(device_list, 0, &e); + REQUIRE(e == 0); + + bool device_extendable_to_fw_logger = false; + if (rs2_is_device_extendable_to(dev, RS2_EXTENSION_FW_LOGGER, &e) != 0 && !e) + { + device_extendable_to_fw_logger = true; + } + REQUIRE(device_extendable_to_fw_logger); + + bool were_fw_logs_received_once = false; + while (!were_fw_logs_received_once) + { + rs2_firmware_log_message_list* fw_logs_list = rs2_get_firmware_logs_list(dev, &e); + REQUIRE(fw_logs_list); + + if (fw_logs_list->_number_of_messages > 0) + { + were_fw_logs_received_once = true; + for (int i = 0; i < fw_logs_list->_number_of_messages; ++i) + { + printf("message received: %s\n", rs2_firmware_log_message_to_string(fw_logs_list->_messages[i])); + } + } + rs2_delete_firmware_logs_list(fw_logs_list); + } + +} diff --git a/unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp b/unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp new file mode 100644 index 0000000000..f961c346a5 --- /dev/null +++ b/unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp @@ -0,0 +1,122 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +//#cmake:add-file fw-logs-common.h +#include "fw-logs-common.h" + +/* Include the librealsense C header files */ +#include +#include +#include +#include +#include + + +#include +#define GetCurrentDir _getcwd + +char* rs2_firmware_log_message_to_string(rs2_firmware_log_message msg) +{ + char* buffer = (char*)(malloc(50 * sizeof(char))); + sprintf(buffer, "sev = %d, file = %d, line = %d", msg._severity, msg._file_id, msg._line); + return buffer; +} + + +std::string get_current_dir() { + char buff[FILENAME_MAX]; //create string buffer to hold path + GetCurrentDir(buff, FILENAME_MAX); + std::string current_working_dir(buff); + return current_working_dir; +} + +//get fw logs using c api +TEST_CASE( "Getting FW logs in C", "[fw-logs]" ) { + + rs2_error* e = 0; + + // Create a context object. This object owns the handles to all connected realsense devices. + // The returned object should be released with rs2_delete_context(...) + rs2_context* ctx = rs2_create_context(RS2_API_VERSION, &e); + REQUIRE(e == 0); + + /* Get a list of all the connected devices. */ + // The returned object should be released with rs2_delete_device_list(...) + rs2_device_list* device_list = rs2_query_devices(ctx, &e); + REQUIRE(e == 0); + + int dev_count = rs2_get_device_count(device_list, &e); + REQUIRE(e == 0); + printf("There are %d connected RealSense devices.\n", dev_count); + REQUIRE(dev_count > 0); + + // Get the first connected device + // The returned object should be released with rs2_delete_device(...) + rs2_device* dev = rs2_create_device(device_list, 0, &e); + REQUIRE(e == 0); + + bool device_extendable_to_fw_logger = false; + if (rs2_is_device_extendable_to(dev, RS2_EXTENSION_FW_LOGGER, &e) != 0 && !e) + { + device_extendable_to_fw_logger = true; + } + REQUIRE(device_extendable_to_fw_logger); + + const char* xml_path_const = "HWLoggerEventsDS5.xml"; + + /*std::string cf = get_current_dir(); + std::string xml_path(xml_path_const); + + if (!xml_path.empty()) + { + std::ifstream f(xml_path); + if (f.good()) + { + int a = 1; + } + else { + + int b = 1; + } + }*/ + + rs2_firmware_logs_parser* parser = rs2_create_firmware_logs_parser(xml_path_const, &e); + REQUIRE(parser); + + bool were_fw_logs_received_once = false; + while (!were_fw_logs_received_once) + { + rs2_firmware_log_message_list* fw_logs_list = rs2_get_firmware_logs_list(dev, &e); + REQUIRE(fw_logs_list); + + if (fw_logs_list->_number_of_messages > 0) + { + were_fw_logs_received_once = true; + for (int i = 0; i < fw_logs_list->_number_of_messages; ++i) + { + rs2_firmware_log_message* msg = &fw_logs_list->_messages[i]; + rs2_raw_data_buffer* parsed_log = rs2_parse_firmware_log(parser, msg->_event_id, msg->_p1, msg->_p2, msg->_p3, + msg->_file_id, msg->_thread_id, &e); + // call as it must be: rs2_parse_firmware_log(parser, &msg); + rs2::error::handle(e); + + int size = rs2_get_raw_data_size(parsed_log, &e); + rs2::error::handle(e); + + if (size > 0) + { + auto start = rs2_get_raw_data(parsed_log, &e); + + unsigned char message_size = *start; + printf("size of message = %d", message_size); + } + + printf("message received: %s\n", rs2_firmware_log_message_to_string(fw_logs_list->_messages[i])); + } + } + rs2_delete_firmware_logs_list(fw_logs_list); + } + + rs2_delete_firmware_logs_parser(parser); + +} From e3b6c97737f19d337fbbe68d7e8ea389d5f7fa05 Mon Sep 17 00:00:00 2001 From: remibettan Date: Mon, 25 May 2020 10:17:55 +0300 Subject: [PATCH 09/61] API change - Getting logs one by one - parser not operable --- examples/firmware-logs/rs-firmware-logs.cpp | 36 ++-- include/librealsense2/h/rs_device.h | 17 +- include/librealsense2/h/rs_types.h | 31 +-- include/librealsense2/hpp/rs_device.hpp | 183 ++++++------------ src/firmware_logger_device.cpp | 71 ++----- src/firmware_logger_device.h | 13 +- src/fw-logs/fw-log-data.cpp | 30 --- src/fw-logs/fw-logs-parser.cpp | 45 ++++- src/fw-logs/fw-logs-parser.h | 5 +- src/realsense.def | 10 +- src/rs.cpp | 101 ++++------ unit-tests/fw-logs/fw-logs-common.h | 11 +- .../fw-logs/test-c-get-fw-logs-not-parsed.cpp | 41 ++-- .../fw-logs/test-c-get-fw-logs-parsed.cpp | 20 +- 14 files changed, 228 insertions(+), 386 deletions(-) diff --git a/examples/firmware-logs/rs-firmware-logs.cpp b/examples/firmware-logs/rs-firmware-logs.cpp index 0db73492af..c3c7568f9d 100644 --- a/examples/firmware-logs/rs-firmware-logs.cpp +++ b/examples/firmware-logs/rs-firmware-logs.cpp @@ -68,20 +68,17 @@ int main(int argc, char * argv[]) while (hub.is_connected(dev)) { - this_thread::sleep_for(chrono::milliseconds(100)); + //this_thread::sleep_for(chrono::milliseconds(100)); auto fw_log = res.get_device().as(); - std::vector fw_log_messages = fw_log.get_firmware_logs(); - - if (fw_log_messages.size() == 0) - continue; + auto fw_log_message = fw_log.get_firmware_log(); std::vector fw_log_lines; - static bool usingParser = true; + static bool usingParser = false; if (usingParser) { - std::string xml_path("HWLoggerEventsDS5.xml"); + /*std::string xml_path("HWLoggerEventsDS5.xml"); if (!xml_path.empty()) { ifstream f(xml_path); @@ -90,27 +87,30 @@ int main(int argc, char * argv[]) unique_ptr parser = unique_ptr(new rs2::firmware_logs_parser(xml_path)); - for each (rs2::firmware_logger_message msg in fw_log_messages) + for (rs2::firmware_logger_message msg : fw_log_messages) { parser->parse_firmware_log(msg); fw_log_lines.push_back(msg.to_string()); } - /*for (auto& elem : fw_log_lines) - elem = datetime_string() + " " + elem;*/ + //for (auto& elem : fw_log_lines) + // elem = datetime_string() + " " + elem; } - } + }*/ } else { - stringstream sstr; - /*sstr << datetime_string() << " FW_Log_Data:";*/ - for (size_t i = 0; i < fw_log_messages.size(); ++i) - sstr << fw_log_messages[i].to_string() << "\n"; - - fw_log_lines.push_back(sstr.str()); + if (fw_log_message.size() > 0) + { + stringstream sstr; + sstr << datetime_string() << " FW_Log_Data:"; + for (int i = 0; i < fw_log_message.size(); ++i) + { + sstr << hexify(fw_log_message[i]) << " "; + } + fw_log_lines.push_back(sstr.str()); + } } - for (auto& line : fw_log_lines) cout << line << endl; } diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index aeafe048e1..fce816f5ef 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -359,14 +359,12 @@ void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_s * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return firmware logs */ -rs2_firmware_log_message_list* rs2_get_firmware_logs_list(rs2_device* dev, rs2_error** error); +rs2_firmware_log_message* rs2_get_firmware_log(rs2_device* dev, rs2_error** error); +void rs2_delete_firmware_log_message(rs2_firmware_log_message* msg); -/** -* \brief Frees the relevant firmware logs messages list object. -* \param[in] firmware logs messages list object that is no longer needed -*/ -void rs2_delete_firmware_logs_list(rs2_firmware_log_message_list* fw_logs_list); +const unsigned char* rs2_firmware_log_message_data(rs2_firmware_log_message* msg, rs2_error** error); +int rs2_firmware_log_message_size(rs2_firmware_log_message* msg, rs2_error** error); /** * \brief Creates RealSense firmware logs parser. @@ -374,13 +372,13 @@ void rs2_delete_firmware_logs_list(rs2_firmware_log_message_list* fw_logs_list); * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return firmware logs parser object */ -rs2_firmware_logs_parser* rs2_create_firmware_logs_parser(const char* xml_path, rs2_error** error); +rs2_firmware_log_parser* rs2_create_firmware_log_parser(const char* xml_path, rs2_error** error); /** * \brief Frees the relevant firmware logs parser object. * \param[in] firmware logs parser object that is no longer needed */ -void rs2_delete_firmware_logs_parser(rs2_firmware_logs_parser* parser); +void rs2_delete_firmware_log_parser(rs2_firmware_log_parser* parser); /** * \brief Parses firmware logs. @@ -394,8 +392,7 @@ void rs2_delete_firmware_logs_parser(rs2_firmware_logs_parser* parser); * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return firmware logs parsed */ -rs2_raw_data_buffer* rs2_parse_firmware_log(rs2_firmware_logs_parser* fw_logs_parser, - int event_id, int p1, int p2, int p3, int file_id, int thread_id, rs2_error** error); +//void rs2_parse_firmware_log(rs2_firmware_log_parser* fw_logs_parser, rs2_firmware_log_message** fw_log_msg, rs2_error** error); #ifdef __cplusplus } diff --git a/include/librealsense2/h/rs_types.h b/include/librealsense2/h/rs_types.h index c709906fce..9ebc1613c0 100644 --- a/include/librealsense2/h/rs_types.h +++ b/include/librealsense2/h/rs_types.h @@ -117,34 +117,6 @@ typedef struct rs2_pose unsigned int mapper_confidence; /**< Pose map confidence 0x0 - Failed, 0x1 - Low, 0x2 - Medium, 0x3 - High */ } rs2_pose; -/** \brief Firmware log message. */ -typedef struct rs2_firmware_log_message -{ - unsigned int _magic_number; /**< magic number at start of the fw log */ - unsigned int _severity; /**< severity of the fw log */ - unsigned int _file_id; /**< id of the file from which the fw log has bee triggered */ - unsigned int _group_id; /**< id of the group from which the fw log has bee triggered */ - unsigned int _event_id; /**< id of the event that the fw log refers to */ - unsigned int _line; /**< line from which the fw log has bee triggered */ - unsigned int _sequence; /**< sequence number from which the fw log has bee triggered */ - unsigned int _p1; /**< parameter for parsing lthe fw log */ - unsigned int _p2; /**< parameter for parsing lthe fw log */ - unsigned int _p3; /**< parameter for parsing lthe fw log */ - unsigned long long _timestamp; /**< timestamp of the fw log */ - double _delta; /**< delta of the timestamp between current and previous fw logs */ - unsigned long long _thread_id; /**< id of the thread from which the fw log has bee triggered */ - - char* _message; /**< fw log message */ - char* _file_name; /**< name of the file from which the fw log has bee triggered */ - char* _thread_name; /**< name of the thread from which the fw log has bee triggered */ -} rs2_firmware_log_message; - -typedef struct rs2_firmware_log_message_list -{ - rs2_firmware_log_message* _messages;/**< pointer to firmware log messages */ - size_t _number_of_messages; /**< number of messages in the member _messages */ -} rs2_firmware_log_message_list; - /** \brief Severity of the librealsense logger. */ typedef enum rs2_log_severity { RS2_LOG_SEVERITY_DEBUG, /**< Detailed information about ordinary operations */ @@ -273,6 +245,8 @@ typedef struct rs2_options_list rs2_options_list; typedef struct rs2_devices_changed_callback rs2_devices_changed_callback; typedef struct rs2_notification rs2_notification; typedef struct rs2_notifications_callback rs2_notifications_callback; +typedef struct rs2_firmware_log_message rs2_firmware_log_message; +typedef struct rs2_firmware_log_parser rs2_firmware_log_parser; typedef struct rs2_terminal_parser rs2_terminal_parser; typedef void (*rs2_log_callback_ptr)(rs2_log_severity, rs2_log_message const *, void * arg); typedef void (*rs2_notification_callback_ptr)(rs2_notification*, void*); @@ -281,7 +255,6 @@ typedef void (*rs2_devices_changed_callback_ptr)(rs2_device_list*, rs2_device_li typedef void (*rs2_frame_callback_ptr)(rs2_frame*, void*); typedef void (*rs2_frame_processor_callback_ptr)(rs2_frame*, rs2_source*, void*); typedef void(*rs2_update_progress_callback_ptr)(const float, void*); -typedef struct rs2_firmware_logs_parser rs2_firmware_logs_parser; typedef double rs2_time_t; /**< Timestamp format. units are milliseconds */ typedef long long rs2_metadata_type; /**< Metadata attribute type is defined as 64 bit signed integer*/ diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index 1fa2bb8483..3cce5a9d57 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -354,105 +354,34 @@ namespace rs2 } }; - class firmware_logger_message + + class firmware_log_message { public: - firmware_logger_message(const std::vector& fw_log_bytes) - { - int i = 0; - _magic_number = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _severity = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _file_id = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _group_id = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _event_id = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _line = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _sequence = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _p1 = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _p2 = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _p3 = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); - i += 4; - _timestamp = firmware_logs_helper::build_uint64_from8_uint8(fw_log_bytes.data() + i); - i += 8; - _delta = firmware_logs_helper::build_double_from8_uint8(fw_log_bytes.data() + i); - i += 8; - _thread_id = firmware_logs_helper::build_uint32_from4_uint8(fw_log_bytes.data() + i); - } + explicit firmware_log_message(std::shared_ptr msg) + {} + rs2_log_severity get_severity() const; + int size() const { return _fw_log_message.size(); } + uint8_t& operator[] (int i) {return _fw_log_message[i]; } - firmware_logger_message(const rs2_firmware_log_message& msg) - { - _magic_number = msg._magic_number; - _severity = msg._severity; - _file_id = msg._file_id; - _group_id = msg._group_id; - _event_id = msg._event_id; - _line = msg._line; - _sequence = msg._sequence; - _p1 = msg._p1; - _p2 = msg._p2; - _p3 = msg._p3; - _timestamp = msg._timestamp; - _delta = msg._delta; - _thread_id = msg._thread_id; - /*_message = std::string(msg._message); - _file_name = std::string(msg._file_name); - _thread_name = std::string(msg._thread_name);*/ - } - - std::string to_string() const + private: + static firmware_log_message create_from_rs2_firmware_log_message(std::shared_ptr msg) { - std::stringstream fmt; - if (_message.size() == 0) - { - fmt << "magic number = " << _magic_number << ",\t" - << "severity = " << _severity << ",\t" - << "file = " << _file_id << ",\t" - << "group = " << _group_id << ",\t" - << "line = " << _line << ",\t" - << "sequ = " << _sequence << ",\t" - << "timestamp = " << _timestamp << ",\t" - << "delta = " << _delta << ",\t" - << "thread = " << _thread_id; - } - else + rs2_error* e = nullptr; + auto size = rs2_firmware_log_message_size(msg.get(), &e); + std::vector result; + if (size > 0) { - fmt << "severity = " << _severity << ",\t" - << "file_name = " << _file_name << ",\t" - << "line = " << _line << ",\t" - << "timestamp = " << _timestamp << ",\t" - << "message = " << _message << ",\t" - << "thread = " << _thread_name; + auto start = rs2_firmware_log_message_data(msg.get(), &e); + result.insert(result.begin(), start, start + size); } - - return fmt.str(); + return firmware_log_message(result); } - - uint32_t _magic_number; - uint32_t _severity; - uint32_t _file_id; - uint32_t _group_id; - uint32_t _event_id; - uint32_t _line; - uint32_t _sequence; - uint32_t _p1; - uint32_t _p2; - uint32_t _p3; - uint64_t _timestamp; - double _delta; - uint32_t _thread_id; - - std::string _message; - std::string _file_name; - std::string _thread_name; + friend class firmware_logger; + explicit firmware_log_message(std::vector msg) : + _fw_log_message(msg) {} + std::vector _fw_log_message; }; class firmware_logger : public device @@ -469,52 +398,52 @@ namespace rs2 error::handle(e); } - std::vector get_firmware_logs() const + rs2::firmware_log_message get_firmware_log() const { - rs2_error* e = nullptr; - - std::shared_ptr msg_list( - rs2_get_firmware_logs_list(_dev.get(), &e), - rs2_delete_firmware_logs_list); + rs2_error* e = nullptr; + std::shared_ptr msg( + rs2_get_firmware_log(_dev.get(), &e), + rs2_delete_firmware_log_message); error::handle(e); - std::vector vec; - - if (msg_list) - { - size_t number_of_messages = msg_list.get()->_number_of_messages > 0; - if (number_of_messages > 0) - { - // for each message: convert rs2_firmware_log_message to rs2::firmware_log_message - for (int i = 0; i < number_of_messages; ++i) - { - rs2::firmware_logger_message message_received(msg_list.get()->_messages[i]); - vec.push_back(message_received); - } - } - } - - return vec; + return firmware_log_message::create_from_rs2_firmware_log_message(msg); } }; - class firmware_logs_parser + + class firmware_log_parser { public: - firmware_logs_parser(std::string xml_path) + firmware_log_parser(std::string xml_path) { rs2_error* e = nullptr; - _firmware_logs_parser = std::shared_ptr( - rs2_create_firmware_logs_parser(xml_path.data(), &e), - rs2_delete_firmware_logs_parser); + _firmware_log_parser = std::shared_ptr( + rs2_create_firmware_log_parser(xml_path.data(), &e), + rs2_delete_firmware_log_parser); error::handle(e); } - void parse_firmware_log(rs2::firmware_logger_message& msg) + void parse_firmware_log(rs2::firmware_log_message& msg) { - rs2_error* e = nullptr; + /*rs2_error* e = nullptr; + + rs2_firmware_log_message* fw_log_msg = new rs2_firmware_log_message{ msg.to_rs2_firmware_log_message() }; + + if (!fw_log_msg) + return; - std::shared_ptr parsed_log( + rs2_parse_firmware_log(_firmware_logs_parser.get(), &fw_log_msg, &e); + rs2::error::handle(e);*/ + + /*msg._message = std::string(fw_log_msg->_message); + msg._file_name = std::string(fw_log_msg->_file_name); + msg._thread_name = std::string(fw_log_msg->_thread_name); + + delete[] fw_log_msg->_message; + delete[] fw_log_msg->_file_name; + delete[] fw_log_msg->_thread_name; + delete fw_log_msg;*/ + /*std::shared_ptr parsed_log( rs2_parse_firmware_log(_firmware_logs_parser.get(), msg._event_id, msg._p1, msg._p2, msg._p3, msg._file_id, msg._thread_id, &e), rs2_delete_raw_data); @@ -551,16 +480,16 @@ namespace rs2 msg._message = message; msg._file_name = file_name; msg._thread_name = thread_name; - } + }*/ } - firmware_logs_parser(std::shared_ptr fw_logs_parser) - : _firmware_logs_parser(fw_logs_parser) {} + firmware_log_parser(std::shared_ptr fw_log_parser) + : _firmware_log_parser(fw_log_parser) {} - explicit operator std::shared_ptr() { return _firmware_logs_parser; }; + explicit operator std::shared_ptr() { return _firmware_log_parser; }; protected: - std::shared_ptr _firmware_logs_parser; + std::shared_ptr _firmware_log_parser; }; class auto_calibrated_device : public calibrated_device diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 4097270443..d9caae25bd 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -10,7 +10,8 @@ namespace librealsense std::string camera_op_code) : _hw_monitor(hardware_monitor), _last_timestamp(0), - _timestamp_factor(0.00001) + _timestamp_factor(0.00001), + _message_queue() { auto op_code = static_cast(std::stoi(camera_op_code.c_str())); _input_code = { 0x14, 0x00, 0xab, 0xcd, op_code, 0x00, 0x00, 0x00, @@ -19,48 +20,22 @@ namespace librealsense } - std::vector firmware_logger_device::get_fw_binary_logs() const - { - auto res = _hw_monitor->send(_input_code); - if (res.empty()) - { - throw std::runtime_error("Getting Firmware logs failed!"); - } - return res; - } - - std::vector firmware_logger_device::get_fw_logs() - { - auto res = _hw_monitor->send(_input_code); - if (res.empty()) - { - throw std::runtime_error("Getting Firmware logs failed!"); - } - - //TODO - REMI - check why this is required - res.erase(res.begin(), res.begin() + 4); - - std::vector vec; - auto beginOfLogIterator = res.begin(); - // convert bytes to fw_log_data - for (int i = 0; i < res.size() / fw_logs::BINARY_DATA_SIZE; ++i) + fw_logs::fw_logs_binary_data firmware_logger_device::get_fw_log() + { + if (_message_queue.empty()) { - auto endOfLogIterator = beginOfLogIterator + fw_logs::BINARY_DATA_SIZE; - std::vector resultsForOneLog; - resultsForOneLog.insert(resultsForOneLog.begin(), beginOfLogIterator, endOfLogIterator); - auto temp_pointer = reinterpret_cast const*>(resultsForOneLog.data()); - auto log = const_cast(reinterpret_cast(temp_pointer)); - - fw_logs::fw_log_data data = fill_log_data(log); - beginOfLogIterator = endOfLogIterator; - - vec.push_back(data); + get_fw_logs_from_hw_monitor(); } + fw_logs::fw_logs_binary_data result; + if (!_message_queue.empty()) + { + result = _message_queue.front(); + _message_queue.pop(); + } + return result; + } - return vec; - } - - std::vector firmware_logger_device::get_fw_logs_msg() + void firmware_logger_device::get_fw_logs_from_hw_monitor() { auto res = _hw_monitor->send(_input_code); if (res.empty()) @@ -68,29 +43,23 @@ namespace librealsense throw std::runtime_error("Getting Firmware logs failed!"); } - //TODO - REMI - check why this is required + //erasing header res.erase(res.begin(), res.begin() + 4); - std::vector vec; auto beginOfLogIterator = res.begin(); - // convert bytes to rs2_firmware_log_message + // convert bytes to fw_logs_binary_data for (int i = 0; i < res.size() / fw_logs::BINARY_DATA_SIZE; ++i) { auto endOfLogIterator = beginOfLogIterator + fw_logs::BINARY_DATA_SIZE; std::vector resultsForOneLog; resultsForOneLog.insert(resultsForOneLog.begin(), beginOfLogIterator, endOfLogIterator); - auto temp_pointer = reinterpret_cast const*>(resultsForOneLog.data()); - auto log = const_cast(reinterpret_cast(temp_pointer)); - - fw_logs::fw_log_data data = fill_log_data(log); - rs2_firmware_log_message msg = data.to_rs2_firmware_log_message(); + fw_logs::fw_logs_binary_data binary_data{ resultsForOneLog }; + _message_queue.push(binary_data); beginOfLogIterator = endOfLogIterator; - - vec.push_back(msg); } - return vec; } + fw_logs::fw_log_data firmware_logger_device::fill_log_data(const char* fw_logs) { fw_logs::fw_log_data log_data; diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index f65db5ef3d..6babb308b3 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -13,9 +13,7 @@ namespace librealsense class firmware_logger_extensions { public: - virtual std::vector get_fw_binary_logs() const = 0; - virtual std::vector get_fw_logs() = 0; - virtual std::vector get_fw_logs_msg() = 0; + virtual fw_logs::fw_logs_binary_data get_fw_log() = 0; virtual ~firmware_logger_extensions() = default; }; MAP_EXTENSION(RS2_EXTENSION_FW_LOGGER, librealsense::firmware_logger_extensions); @@ -27,16 +25,19 @@ namespace librealsense firmware_logger_device(std::shared_ptr hardware_monitor, std::string camera_op_code); - std::vector get_fw_binary_logs() const override; - std::vector get_fw_logs() override; - std::vector get_fw_logs_msg() override; + fw_logs::fw_logs_binary_data get_fw_log() override; + fw_logs::fw_log_data fill_log_data(const char* fw_logs) ; + private: std::vector _input_code; std::shared_ptr _hw_monitor; uint64_t _last_timestamp; const double _timestamp_factor; + + std::queue _message_queue; + void get_fw_logs_from_hw_monitor(); }; } \ No newline at end of file diff --git a/src/fw-logs/fw-log-data.cpp b/src/fw-logs/fw-log-data.cpp index 1f1b6ca5e8..c9c870a9b8 100644 --- a/src/fw-logs/fw-log-data.cpp +++ b/src/fw-logs/fw-log-data.cpp @@ -56,35 +56,5 @@ namespace librealsense auto str = fmt.str(); return str; } - - rs2_firmware_log_message fw_log_data::to_rs2_firmware_log_message() - { - rs2_firmware_log_message msg; - msg._magic_number = this->magic_number; - msg._severity = this->severity; - msg._file_id = this->file_id; - msg._group_id = this->group_id; - msg._event_id = this->event_id; - msg._line = this->line; - msg._sequence = this->sequence; - msg._p1 = this->p1; - msg._p2 = this->p2; - msg._p3 = this->p3; - msg._timestamp = this->timestamp; - msg._thread_id = this->thread_id; - - - //TODO - REMI - check these pointers are deleted in rs2_firmware_log_message destructor - /*msg._message = new char[this->message.size()]; - strcpy(msg._message, this->message.c_str()); - - msg._file_name = new char[this->file_name.size()]; - strcpy(msg._file_name, this->file_name.c_str()); - - msg._thread_name = new char[this->thread_name.size()]; - strcpy(msg._thread_name, this->thread_name.c_str());*/ - - return msg; - } } } diff --git a/src/fw-logs/fw-logs-parser.cpp b/src/fw-logs/fw-logs-parser.cpp index 0f8231e791..348cdde4ef 100644 --- a/src/fw-logs/fw-logs-parser.cpp +++ b/src/fw-logs/fw-logs-parser.cpp @@ -23,22 +23,47 @@ namespace librealsense { } - fw_log_data fw_logs_parser::parse_fw_log(uint32_t event_id, uint32_t p1, uint32_t p2, uint32_t p3, - uint32_t file_id, uint32_t thread_id) + void fw_logs_parser::parse_fw_log(rs2_firmware_log_message** fw_log_msg) { - fw_log_data result; - + /*if (!fw_log_msg || !(*fw_log_msg)) + return; + //message fw_string_formatter reg_exp(_fw_logs_formating_options.get_enums()); fw_log_event log_event_data; + _fw_logs_formating_options.get_event_data((*fw_log_msg)->_event_id, &log_event_data); - _fw_logs_formating_options.get_event_data(event_id, &log_event_data); - uint32_t params[3] = { p1, p2, p3 }; - reg_exp.generate_message(log_event_data.line, log_event_data.num_of_params, params, &result.message); + uint32_t params[3] = { (*fw_log_msg)->_p1, (*fw_log_msg)->_p2, (*fw_log_msg)->_p3 }; + std::string parsed_message; + reg_exp.generate_message(log_event_data.line, log_event_data.num_of_params, params, &parsed_message); + //reallocate char pointer and copy string into it + /*if ((*fw_log_msg)->_message) + { + delete[] (*fw_log_msg)->_message; + }*/ + /*(*fw_log_msg)->_message = new char[parsed_message.size() + 1]; + strncpy_s((*fw_log_msg)->_message, parsed_message.size() + 1, parsed_message.c_str(), parsed_message.size()); - _fw_logs_formating_options.get_file_name(file_id, &result.file_name); - _fw_logs_formating_options.get_thread_name(static_cast(thread_id), &result.thread_name); + //file name + std::string parsed_file_name; + _fw_logs_formating_options.get_file_name((*fw_log_msg)->_file_id, &parsed_file_name); + //reallocate char pointer and copy string into it + /*if ((*fw_log_msg)->_file_name) + { + delete (*fw_log_msg)->_file_name; + }*/ + /*(*fw_log_msg)->_file_name = new char[parsed_file_name.size() + 1]; + strncpy_s((*fw_log_msg)->_file_name, parsed_file_name.size() + 1, parsed_file_name.c_str(), parsed_file_name.size()); - return result; + //thread name + std::string parsed_thread_name; + _fw_logs_formating_options.get_thread_name(static_cast((*fw_log_msg)->_thread_id), &parsed_thread_name); + //reallocate char pointer and copy string into it + /*if ((*fw_log_msg)->_thread_name) + { + delete (*fw_log_msg)->_thread_name; + }*/ + /*(*fw_log_msg)->_thread_name = new char[parsed_thread_name.size() + 1]; + strncpy_s((*fw_log_msg)->_thread_name, parsed_thread_name.size() + 1, parsed_thread_name.c_str(), parsed_thread_name.size());*/ } } } diff --git a/src/fw-logs/fw-logs-parser.h b/src/fw-logs/fw-logs-parser.h index 7715561984..2f29ed10ee 100644 --- a/src/fw-logs/fw-logs-parser.h +++ b/src/fw-logs/fw-logs-parser.h @@ -16,8 +16,9 @@ namespace librealsense public: explicit fw_logs_parser(std::string xml_full_file_path); ~fw_logs_parser(void); - fw_log_data parse_fw_log(uint32_t event_id, uint32_t p1, uint32_t p2, uint32_t p3, - uint32_t file_id, uint32_t thread_id); + /*fw_log_data parse_fw_log(uint32_t event_id, uint32_t p1, uint32_t p2, uint32_t p3, + uint32_t file_id, uint32_t thread_id);*/ + void fw_logs_parser::parse_fw_log(rs2_firmware_log_message** fw_log_msg); private: diff --git a/src/realsense.def b/src/realsense.def index d10da6b2c4..67b2cae8d1 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -356,10 +356,12 @@ EXPORTS rs2_get_calibration_table rs2_set_calibration_table - rs2_get_firmware_logs_list - rs2_delete_firmware_logs_list - rs2_create_firmware_logs_parser - rs2_delete_firmware_logs_parser + rs2_get_firmware_log + rs2_delete_firmware_log_message + rs2_firmware_log_message_data + rs2_firmware_log_message_size + rs2_create_firmware_log_parser + rs2_delete_firmware_log_parser rs2_parse_firmware_log rs2_create_terminal_parser diff --git a/src/rs.cpp b/src/rs.cpp index ec64656763..55e1500a65 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -122,9 +122,14 @@ struct rs2_terminal_parser std::shared_ptr terminal_parser; }; -struct rs2_firmware_logs_parser +struct rs2_firmware_log_message { - std::shared_ptr firmware_logs_parser; + std::shared_ptr firmware_log_binary_data; +}; + +struct rs2_firmware_log_parser +{ + std::shared_ptr firmware_log_parser; }; struct rs2_error @@ -2977,95 +2982,61 @@ void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_s } HANDLE_EXCEPTIONS_AND_RETURN(, dev, json_content, content_size) -rs2_firmware_log_message* rs2_get_firmware_logs(rs2_device* dev, int* number_of_messages, rs2_error** error) BEGIN_API_CALL +rs2_firmware_log_message* rs2_get_firmware_log(rs2_device* dev, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(dev); - VALIDATE_NOT_NULL(number_of_messages); auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); - std::vector logs = fw_loggerable->get_fw_logs(); - *number_of_messages = logs.size(); - - rs2_firmware_log_message* list = new rs2_firmware_log_message[*number_of_messages]; - for(int i = 0; i < *number_of_messages; ++i) - { - list[i] = logs[i].to_rs2_firmware_log_message(); - } - - return list; + fw_logs::fw_logs_binary_data binary_data = fw_loggerable->get_fw_log(); + return new rs2_firmware_log_message{ std::make_shared(binary_data) }; } -HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev, number_of_messages, error) +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev, error) -rs2_firmware_log_message_list* rs2_get_firmware_logs_list(rs2_device* dev, rs2_error** error) BEGIN_API_CALL +void rs2_delete_firmware_log_message(rs2_firmware_log_message* msg) BEGIN_API_CALL { - VALIDATE_NOT_NULL(dev); - auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); - - std::vector logs = fw_loggerable->get_fw_logs(); - size_t numOfLogs = logs.size(); - - rs2_firmware_log_message* messages = new rs2_firmware_log_message[numOfLogs]; - rs2_firmware_log_message_list* list = new rs2_firmware_log_message_list; - list->_messages = messages; - list->_number_of_messages = logs.size(); - for (size_t i = 0; i < numOfLogs; ++i) - { - list->_messages[i] = logs[i].to_rs2_firmware_log_message(); - } - - return list; + VALIDATE_NOT_NULL(msg); + delete msg; } -HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev, error) +NOEXCEPT_RETURN(, msg) -void rs2_delete_firmware_logs(rs2_firmware_log_message* fw_logs_list) BEGIN_API_CALL +const unsigned char* rs2_firmware_log_message_data(rs2_firmware_log_message* msg, rs2_error** error)BEGIN_API_CALL { - VALIDATE_NOT_NULL(fw_logs_list); - - delete[] fw_logs_list[0]._message; - delete[] fw_logs_list[0]._file_name; - delete[] fw_logs_list[0]._thread_name; - - delete[] fw_logs_list; + VALIDATE_NOT_NULL(msg); + return msg->firmware_log_binary_data->logs_buffer.data(); } -NOEXCEPT_RETURN(, fw_logs_list) +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, msg) -void rs2_delete_firmware_logs_list(rs2_firmware_log_message_list* fw_logs_list) BEGIN_API_CALL +int rs2_firmware_log_message_size(rs2_firmware_log_message* msg, rs2_error** error)BEGIN_API_CALL { - VALIDATE_NOT_NULL(fw_logs_list); - - if (fw_logs_list->_messages) - { - /*for (int i = 0; i < fw_logs_list->_number_of_messages; ++i) - { - if (fw_logs_list->_messages[i]._message) - delete fw_logs_list->_messages[i]._message; - if (fw_logs_list->_messages[i]._file_name) - delete fw_logs_list->_messages[i]._file_name; - if (fw_logs_list->_messages[i]._thread_name) - delete fw_logs_list->_messages[i]._thread_name; - }*/ - delete[] fw_logs_list->_messages; - } - delete[] fw_logs_list; + VALIDATE_NOT_NULL(msg); + return msg->firmware_log_binary_data->logs_buffer.size(); } -NOEXCEPT_RETURN(, fw_logs_list) +HANDLE_EXCEPTIONS_AND_RETURN(0, msg) -rs2_firmware_logs_parser* rs2_create_firmware_logs_parser(const char* xml_path, rs2_error** error) BEGIN_API_CALL +rs2_firmware_log_parser* rs2_create_firmware_log_parser(const char* xml_path, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(xml_path); - return new rs2_firmware_logs_parser{ std::make_shared(xml_path)}; + return new rs2_firmware_log_parser{ std::make_shared(xml_path)}; } HANDLE_EXCEPTIONS_AND_RETURN(nullptr, xml_path) -void rs2_delete_firmware_logs_parser(rs2_firmware_logs_parser* parser) BEGIN_API_CALL +void rs2_delete_firmware_log_parser(rs2_firmware_log_parser* parser) BEGIN_API_CALL { VALIDATE_NOT_NULL(parser); delete parser; } NOEXCEPT_RETURN(, parser) -rs2_raw_data_buffer* rs2_parse_firmware_log(rs2_firmware_logs_parser* fw_logs_parser, +void rs2_parse_firmware_log(rs2_firmware_log_parser* fw_log_parser, rs2_firmware_log_message** fw_log_msg, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(fw_log_parser); + VALIDATE_NOT_NULL(fw_log_msg); + + fw_log_parser->firmware_log_parser.get()->parse_fw_log(fw_log_msg); +} +NOEXCEPT_RETURN(, fw_log_msg) +/*rs2_raw_data_buffer* rs2_parse_firmware_log(rs2_firmware_logs_parser* fw_logs_parser, int event_id, int p1, int p2, int p3, int file_id, int thread_id, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(fw_logs_parser); @@ -3094,7 +3065,7 @@ rs2_raw_data_buffer* rs2_parse_firmware_log(rs2_firmware_logs_parser* fw_logs_pa return new rs2_raw_data_buffer { msg_file_thread_bytes }; } -HANDLE_EXCEPTIONS_AND_RETURN(nullptr, fw_logs_parser) +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, fw_logs_parser)*/ rs2_terminal_parser* rs2_create_terminal_parser(const char* xml_content, rs2_error** error) BEGIN_API_CALL { diff --git a/unit-tests/fw-logs/fw-logs-common.h b/unit-tests/fw-logs/fw-logs-common.h index 5609f00be3..af25dced2a 100644 --- a/unit-tests/fw-logs/fw-logs-common.h +++ b/unit-tests/fw-logs/fw-logs-common.h @@ -3,8 +3,15 @@ #pragma once -#include // Include RealSense Cross Platform API - +//#include // Include RealSense Cross Platform API + +#include +#ifdef BUILD_SHARED_LIBS +// With static linkage, ELPP is initialized by librealsense, so doing it here will +// create errors. When we're using the shared .so/.dll, the two are separate and we have +// to initialize ours if we want to use the APIs! +INITIALIZE_EASYLOGGINGPP +#endif // Catch also defines CHECK(), and so we have to undefine it or we get compilation errors! #undef CHECK diff --git a/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp b/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp index 3b3b906e30..3da5c82d73 100644 --- a/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp +++ b/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp @@ -6,17 +6,6 @@ /* Include the librealsense C header files */ #include -#include -#include -#include -#include - -char* rs2_firmware_log_message_to_string(rs2_firmware_log_message msg) -{ - char* buffer = (char*)(malloc(50 * sizeof(char))); - sprintf(buffer, "sev = %d, file = %d, line = %d", msg._severity, msg._file_id, msg._line); - return buffer; -} //get fw logs using c api TEST_CASE( "Getting FW logs in C", "[fw-logs]" ) { @@ -51,20 +40,36 @@ TEST_CASE( "Getting FW logs in C", "[fw-logs]" ) { REQUIRE(device_extendable_to_fw_logger); bool were_fw_logs_received_once = false; - while (!were_fw_logs_received_once) + while (1)//!were_fw_logs_received_once) { - rs2_firmware_log_message_list* fw_logs_list = rs2_get_firmware_logs_list(dev, &e); - REQUIRE(fw_logs_list); + rs2_error* e = nullptr; + rs2_firmware_log_message* fw_log_msg = rs2_get_firmware_log(dev, &e); + + REQUIRE(fw_log_msg); + + int size = rs2_firmware_log_message_size(fw_log_msg, &e); - if (fw_logs_list->_number_of_messages > 0) + auto start = rs2_firmware_log_message_data(fw_log_msg, &e); + + if (size > 0) { were_fw_logs_received_once = true; - for (int i = 0; i < fw_logs_list->_number_of_messages; ++i) + //get time + time_t rawtime; + struct tm* timeinfo; + + time_t mytime = time(NULL); + char* time_str = ctime(&mytime); + time_str[strlen(time_str) - 1] = '\0'; + printf("message received %s - ", time_str); + for (int i = 0; i < size; ++i) { - printf("message received: %s\n", rs2_firmware_log_message_to_string(fw_logs_list->_messages[i])); + printf("%d ", *(start + i)); } + printf("\n"); } - rs2_delete_firmware_logs_list(fw_logs_list); + + rs2_delete_firmware_log_message(fw_log_msg); } } diff --git a/unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp b/unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp index f961c346a5..57e7a2c341 100644 --- a/unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp +++ b/unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp @@ -18,7 +18,7 @@ char* rs2_firmware_log_message_to_string(rs2_firmware_log_message msg) { char* buffer = (char*)(malloc(50 * sizeof(char))); - sprintf(buffer, "sev = %d, file = %d, line = %d", msg._severity, msg._file_id, msg._line); + sprintf(buffer, "message = %s", msg._message); return buffer; } @@ -95,23 +95,15 @@ TEST_CASE( "Getting FW logs in C", "[fw-logs]" ) { for (int i = 0; i < fw_logs_list->_number_of_messages; ++i) { rs2_firmware_log_message* msg = &fw_logs_list->_messages[i]; - rs2_raw_data_buffer* parsed_log = rs2_parse_firmware_log(parser, msg->_event_id, msg->_p1, msg->_p2, msg->_p3, - msg->_file_id, msg->_thread_id, &e); - // call as it must be: rs2_parse_firmware_log(parser, &msg); - rs2::error::handle(e); + /*rs2_raw_data_buffer* parsed_log = rs2_parse_firmware_log(parser, msg->_event_id, msg->_p1, msg->_p2, msg->_p3, + msg->_file_id, msg->_thread_id, &e);*/ - int size = rs2_get_raw_data_size(parsed_log, &e); + rs2_parse_firmware_log(parser, &msg, &e); rs2::error::handle(e); - if (size > 0) - { - auto start = rs2_get_raw_data(parsed_log, &e); - - unsigned char message_size = *start; - printf("size of message = %d", message_size); - } + printf("message received: %s\n", rs2_firmware_log_message_to_string(*msg)); - printf("message received: %s\n", rs2_firmware_log_message_to_string(fw_logs_list->_messages[i])); + } } rs2_delete_firmware_logs_list(fw_logs_list); From f09c831569dcba79382f73593d024c42b73fa26c Mon Sep 17 00:00:00 2001 From: remibettan Date: Mon, 25 May 2020 11:26:05 +0300 Subject: [PATCH 10/61] get_severity added, firmware_log_message struct improved --- examples/firmware-logs/rs-firmware-logs.cpp | 9 +++-- include/librealsense2/h/rs_device.h | 2 ++ include/librealsense2/hpp/rs_device.hpp | 40 +++++++++++++-------- src/fw-logs/fw-log-data.cpp | 29 +++++++++++++++ src/fw-logs/fw-log-data.h | 3 ++ src/realsense.def | 1 + src/rs.cpp | 6 ++++ 7 files changed, 72 insertions(+), 18 deletions(-) diff --git a/examples/firmware-logs/rs-firmware-logs.cpp b/examples/firmware-logs/rs-firmware-logs.cpp index c3c7568f9d..2cfe032a16 100644 --- a/examples/firmware-logs/rs-firmware-logs.cpp +++ b/examples/firmware-logs/rs-firmware-logs.cpp @@ -103,10 +103,13 @@ int main(int argc, char * argv[]) if (fw_log_message.size() > 0) { stringstream sstr; - sstr << datetime_string() << " FW_Log_Data:"; - for (int i = 0; i < fw_log_message.size(); ++i) + sstr << datetime_string(); + sstr << " " << fw_log_message.get_severity_str(); + sstr << " FW_Log_Data:"; + std::vector msg_data = fw_log_message.data(); + for (int i = 0; i < msg_data.size(); ++i) { - sstr << hexify(fw_log_message[i]) << " "; + sstr << hexify(msg_data[i]) << " "; } fw_log_lines.push_back(sstr.str()); } diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index fce816f5ef..c70b7fd140 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -366,6 +366,8 @@ void rs2_delete_firmware_log_message(rs2_firmware_log_message* msg); const unsigned char* rs2_firmware_log_message_data(rs2_firmware_log_message* msg, rs2_error** error); int rs2_firmware_log_message_size(rs2_firmware_log_message* msg, rs2_error** error); +rs2_log_severity rs2_get_fw_log_severity(const rs2_firmware_log_message* msg, rs2_error** error); + /** * \brief Creates RealSense firmware logs parser. * \param[in] xml_path path to xml file needed for parsing diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index 3cce5a9d57..e9f2bb240b 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -358,30 +358,40 @@ namespace rs2 class firmware_log_message { public: - explicit firmware_log_message(std::shared_ptr msg) - {} - rs2_log_severity get_severity() const; - int size() const { return _fw_log_message.size(); } - uint8_t& operator[] (int i) {return _fw_log_message[i]; } + explicit firmware_log_message(std::shared_ptr msg): + _fw_log_message(msg){} + + rs2_log_severity get_severity() const { + rs2_error* e = nullptr; + rs2_log_severity severity = rs2_get_fw_log_severity(_fw_log_message.get(), &e); + error::handle(e); + return severity; + } + std::string get_severity_str() const { + return rs2_log_severity_to_string(get_severity()); + } - private: - static firmware_log_message create_from_rs2_firmware_log_message(std::shared_ptr msg) + int size() const + { + rs2_error* e = nullptr; + return rs2_firmware_log_message_size(_fw_log_message.get(), &e); + } + + std::vector data() const { rs2_error* e = nullptr; - auto size = rs2_firmware_log_message_size(msg.get(), &e); + auto size = rs2_firmware_log_message_size(_fw_log_message.get(), &e); std::vector result; if (size > 0) { - auto start = rs2_firmware_log_message_data(msg.get(), &e); + auto start = rs2_firmware_log_message_data(_fw_log_message.get(), &e); result.insert(result.begin(), start, start + size); } - return firmware_log_message(result); + return result; } - friend class firmware_logger; - explicit firmware_log_message(std::vector msg) : - _fw_log_message(msg) {} - std::vector _fw_log_message; + private: + std::shared_ptr _fw_log_message; }; class firmware_logger : public device @@ -406,7 +416,7 @@ namespace rs2 rs2_delete_firmware_log_message); error::handle(e); - return firmware_log_message::create_from_rs2_firmware_log_message(msg); + return firmware_log_message(msg); } }; diff --git a/src/fw-logs/fw-log-data.cpp b/src/fw-logs/fw-log-data.cpp index c9c870a9b8..0b37356e53 100644 --- a/src/fw-logs/fw-log-data.cpp +++ b/src/fw-logs/fw-log-data.cpp @@ -56,5 +56,34 @@ namespace librealsense auto str = fmt.str(); return str; } + + rs2_log_severity fw_logs_binary_data::get_severity() const + { + const fw_log_binary* log_binary = reinterpret_cast(logs_buffer.data()); + return fw_logs_severity_to_log_severity(static_cast(log_binary->dword1.bits.severity)); + } + + rs2_log_severity fw_logs_severity_to_log_severity(int32_t severity) + { + rs2_log_severity result = RS2_LOG_SEVERITY_NONE; + switch (severity) + { + case 1: + result = RS2_LOG_SEVERITY_DEBUG; + break; + case 2: + result = RS2_LOG_SEVERITY_WARN; + break; + case 3: + result = RS2_LOG_SEVERITY_ERROR; + break; + case 4: + result = RS2_LOG_SEVERITY_FATAL; + break; + default: + break; + } + return result; + } } } diff --git a/src/fw-logs/fw-log-data.h b/src/fw-logs/fw-log-data.h index 585252251e..429f261eae 100644 --- a/src/fw-logs/fw-log-data.h +++ b/src/fw-logs/fw-log-data.h @@ -13,8 +13,11 @@ namespace librealsense struct fw_logs_binary_data { std::vector logs_buffer; + rs2_log_severity get_severity() const; }; + rs2_log_severity fw_logs_severity_to_log_severity(int32_t severity); + static const int BINARY_DATA_SIZE = 20; typedef union diff --git a/src/realsense.def b/src/realsense.def index 67b2cae8d1..dc0edcca1c 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -358,6 +358,7 @@ EXPORTS rs2_get_firmware_log rs2_delete_firmware_log_message + rs2_get_fw_log_severity rs2_firmware_log_message_data rs2_firmware_log_message_size rs2_create_firmware_log_parser diff --git a/src/rs.cpp b/src/rs.cpp index 55e1500a65..e0511220ba 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -3013,6 +3013,12 @@ int rs2_firmware_log_message_size(rs2_firmware_log_message* msg, rs2_error** err } HANDLE_EXCEPTIONS_AND_RETURN(0, msg) +rs2_log_severity rs2_get_fw_log_severity(const rs2_firmware_log_message* msg, rs2_error** error) BEGIN_API_CALL +{ + return msg->firmware_log_binary_data->get_severity(); +} +HANDLE_EXCEPTIONS_AND_RETURN(RS2_LOG_SEVERITY_NONE, msg) + rs2_firmware_log_parser* rs2_create_firmware_log_parser(const char* xml_path, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(xml_path); From 8e1e606caa6c3dbe8d46d521fa8201921b360910 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 27 May 2020 10:34:50 +0300 Subject: [PATCH 11/61] fw logs messages parsed one by one, API added for timestamp, line, severity, message, file name and thread name --- examples/firmware-logs/rs-firmware-logs.cpp | 25 ++-- include/librealsense2/h/rs_device.h | 114 +++++++++++++-- include/librealsense2/h/rs_types.h | 1 + include/librealsense2/hpp/rs_device.hpp | 138 +++++++++++------- src/firmware_logger_device.cpp | 58 +------- src/firmware_logger_device.h | 5 - src/fw-logs/fw-log-data.cpp | 72 +++++---- src/fw-logs/fw-log-data.h | 41 +++--- src/fw-logs/fw-logs-parser.cpp | 97 +++++++----- src/fw-logs/fw-logs-parser.h | 9 +- src/realsense.def | 10 +- src/rs.cpp | 89 +++++++---- .../fw-logs/test-c-get-fw-logs-not-parsed.cpp | 5 + 13 files changed, 402 insertions(+), 262 deletions(-) diff --git a/examples/firmware-logs/rs-firmware-logs.cpp b/examples/firmware-logs/rs-firmware-logs.cpp index 2cfe032a16..15249f1b54 100644 --- a/examples/firmware-logs/rs-firmware-logs.cpp +++ b/examples/firmware-logs/rs-firmware-logs.cpp @@ -75,35 +75,34 @@ int main(int argc, char * argv[]) std::vector fw_log_lines; - static bool usingParser = false; + static bool usingParser = true; if (usingParser) { - /*std::string xml_path("HWLoggerEventsDS5.xml"); + std::string xml_path("HWLoggerEventsDS5.xml"); if (!xml_path.empty()) { ifstream f(xml_path); if (f.good()) { - unique_ptr parser = - unique_ptr(new rs2::firmware_logs_parser(xml_path)); + unique_ptr parser = + unique_ptr(new rs2::firmware_log_parser(xml_path)); - for (rs2::firmware_logger_message msg : fw_log_messages) - { - parser->parse_firmware_log(msg); - fw_log_lines.push_back(msg.to_string()); - } + rs2::firmware_log_parsed_message parsed_log = parser->parse_firmware_log(fw_log_message); + stringstream sstr; + sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() + << " " << parsed_log.thread_name() << " " << parsed_log.file_name() + << " " << parsed_log.line(); - //for (auto& elem : fw_log_lines) - // elem = datetime_string() + " " + elem; + fw_log_lines.push_back(sstr.str()); } - }*/ + } } else { if (fw_log_message.size() > 0) { stringstream sstr; - sstr << datetime_string(); + sstr << fw_log_message.get_timestamp(); sstr << " " << fw_log_message.get_severity_str(); sstr << " FW_Log_Data:"; std::vector msg_data = fw_log_message.data(); diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index c70b7fd140..ce11c16563 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -354,19 +354,51 @@ rs2_raw_data_buffer* rs2_serialize_json(rs2_device* dev, rs2_error** error); void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_size, rs2_error** error); /** -* \brief Gets RealSense firmware logs. -* \param[in] dev Device from which the FW logs should be taken -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return firmware logs +* \brief Gets RealSense firmware log. +* \param[in] dev Device from which the FW log should be taken +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return firmware logs */ rs2_firmware_log_message* rs2_get_firmware_log(rs2_device* dev, rs2_error** error); +/** +* Delete RealSense firmware log message +* \param[in] device Realsense firmware log message to delete +*/ void rs2_delete_firmware_log_message(rs2_firmware_log_message* msg); +/** +* \brief Gets RealSense firmware log message data. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return pointer to start of the firmware log message data +*/ const unsigned char* rs2_firmware_log_message_data(rs2_firmware_log_message* msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log message size. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return size of the firmware log message data +*/ int rs2_firmware_log_message_size(rs2_firmware_log_message* msg, rs2_error** error); -rs2_log_severity rs2_get_fw_log_severity(const rs2_firmware_log_message* msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log message timestamp. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return timestamp of the firmware log message +*/ +unsigned int rs2_firmware_log_message_timestamp(rs2_firmware_log_message* msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log message severity. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return severity of the firmware log message data +*/ +rs2_log_severity rs2_firmware_log_message_severity(const rs2_firmware_log_message* msg, rs2_error** error); /** * \brief Creates RealSense firmware logs parser. @@ -383,18 +415,68 @@ rs2_firmware_log_parser* rs2_create_firmware_log_parser(const char* xml_path, rs void rs2_delete_firmware_log_parser(rs2_firmware_log_parser* parser); /** -* \brief Parses firmware logs. -* \param[in] fw_logs_parser firmware logs parser object -* \param[in] event_id code for event -* \param[in] p1 parameter used to parse the message -* \param[in] p2 parameter used to parse the message -* \param[in] p3 parameter used to parse the message -* \param[in] file_id code for file -* \param[in] thread_id code for the thread -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return firmware logs parsed +* \brief Gets RealSense firmware log parser +* \param[in] fw_logs_parser firmware log parser +* \param[in] fw_log_msg firmware log message to be parsed +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return firmware log parsed message +*/ +rs2_firmware_log_parsed_message* rs2_parse_firmware_log(rs2_firmware_log_parser* fw_logs_parser, + rs2_firmware_log_message* fw_log_msg, rs2_error** error); + +/** +* Delete RealSense firmware log parsed message +* \param[in] device Realsense firmware log parsed message to delete +*/ +void rs2_delete_firmware_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); + +/** +* \brief Gets RealSense firmware log parsed message message. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return message of the firmware log parsed message +*/ +const char* rs2_get_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message file name. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return file name of the firmware log parsed message +*/ +const char* rs2_get_fw_log_parsed_file_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message thread name. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return thread name of the firmware log parsed message +*/ +const char* rs2_get_fw_log_parsed_thread_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message severity. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return severity of the firmware log parsed message +*/ +rs2_log_severity rs2_get_fw_log_parsed_severity(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message relevant line (in the file that is returned by rs2_get_fw_log_parsed_file_name). +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return line number of the firmware log parsed message +*/ +unsigned int rs2_get_fw_log_parsed_line(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message timestamp +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return timestamp of the firmware log parsed message */ -//void rs2_parse_firmware_log(rs2_firmware_log_parser* fw_logs_parser, rs2_firmware_log_message** fw_log_msg, rs2_error** error); +unsigned int rs2_get_fw_log_parsed_timestamp(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); #ifdef __cplusplus } diff --git a/include/librealsense2/h/rs_types.h b/include/librealsense2/h/rs_types.h index 9ebc1613c0..075118cf2f 100644 --- a/include/librealsense2/h/rs_types.h +++ b/include/librealsense2/h/rs_types.h @@ -246,6 +246,7 @@ typedef struct rs2_devices_changed_callback rs2_devices_changed_callback; typedef struct rs2_notification rs2_notification; typedef struct rs2_notifications_callback rs2_notifications_callback; typedef struct rs2_firmware_log_message rs2_firmware_log_message; +typedef struct rs2_firmware_log_parsed_message rs2_firmware_log_parsed_message; typedef struct rs2_firmware_log_parser rs2_firmware_log_parser; typedef struct rs2_terminal_parser rs2_terminal_parser; typedef void (*rs2_log_callback_ptr)(rs2_log_severity, rs2_log_message const *, void * arg); diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index e9f2bb240b..eb9b8eb7bf 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -363,7 +363,7 @@ namespace rs2 rs2_log_severity get_severity() const { rs2_error* e = nullptr; - rs2_log_severity severity = rs2_get_fw_log_severity(_fw_log_message.get(), &e); + rs2_log_severity severity = rs2_firmware_log_message_severity(_fw_log_message.get(), &e); error::handle(e); return severity; } @@ -371,25 +371,39 @@ namespace rs2 return rs2_log_severity_to_string(get_severity()); } + uint32_t get_timestamp() const + { + rs2_error* e = nullptr; + uint32_t timestamp = rs2_firmware_log_message_timestamp(_fw_log_message.get(), &e); + error::handle(e); + return timestamp; + } + int size() const { rs2_error* e = nullptr; - return rs2_firmware_log_message_size(_fw_log_message.get(), &e); + int size = rs2_firmware_log_message_size(_fw_log_message.get(), &e); + error::handle(e); + return size; } std::vector data() const { rs2_error* e = nullptr; auto size = rs2_firmware_log_message_size(_fw_log_message.get(), &e); + error::handle(e); std::vector result; if (size > 0) { auto start = rs2_firmware_log_message_data(_fw_log_message.get(), &e); + error::handle(e); result.insert(result.begin(), start, start + size); } return result; } + const std::shared_ptr get_message() const { return _fw_log_message; } + private: std::shared_ptr _fw_log_message; }; @@ -420,6 +434,59 @@ namespace rs2 } }; + class firmware_log_parsed_message + { + public: + explicit firmware_log_parsed_message(std::shared_ptr msg) : + _parsed_fw_log(msg) {} + + std::string message() const + { + rs2_error* e = nullptr; + std::string msg(rs2_get_fw_log_parsed_message(_parsed_fw_log.get(), &e)); + error::handle(e); + return msg; + } + std::string file_name() const + { + rs2_error* e = nullptr; + std::string file_name(rs2_get_fw_log_parsed_file_name(_parsed_fw_log.get(), &e)); + error::handle(e); + return file_name; + } + std::string thread_name() const + { + rs2_error* e = nullptr; + std::string thread_name(rs2_get_fw_log_parsed_thread_name(_parsed_fw_log.get(), &e)); + error::handle(e); + return thread_name; + } + std::string severity() const + { + rs2_error* e = nullptr; + rs2_log_severity sev = rs2_get_fw_log_parsed_severity(_parsed_fw_log.get(), &e); + error::handle(e); + return std::string(rs2_log_severity_to_string(sev)); + } + uint32_t line() const + { + rs2_error* e = nullptr; + uint32_t line(rs2_get_fw_log_parsed_line(_parsed_fw_log.get(), &e)); + error::handle(e); + return line; + } + uint32_t timestamp() const + { + rs2_error* e = nullptr; + uint32_t timestamp(rs2_get_fw_log_parsed_timestamp(_parsed_fw_log.get(), &e)); + error::handle(e); + return timestamp; + } + + private: + std::shared_ptr _parsed_fw_log; + }; + class firmware_log_parser { @@ -433,64 +500,23 @@ namespace rs2 error::handle(e); } - void parse_firmware_log(rs2::firmware_log_message& msg) + rs2::firmware_log_parsed_message parse_firmware_log(const rs2::firmware_log_message& msg) { - /*rs2_error* e = nullptr; - - rs2_firmware_log_message* fw_log_msg = new rs2_firmware_log_message{ msg.to_rs2_firmware_log_message() }; - - if (!fw_log_msg) - return; - - rs2_parse_firmware_log(_firmware_logs_parser.get(), &fw_log_msg, &e); - rs2::error::handle(e);*/ - - /*msg._message = std::string(fw_log_msg->_message); - msg._file_name = std::string(fw_log_msg->_file_name); - msg._thread_name = std::string(fw_log_msg->_thread_name); + rs2_error* e = nullptr; - delete[] fw_log_msg->_message; - delete[] fw_log_msg->_file_name; - delete[] fw_log_msg->_thread_name; - delete fw_log_msg;*/ - /*std::shared_ptr parsed_log( - rs2_parse_firmware_log(_firmware_logs_parser.get(), - msg._event_id, msg._p1, msg._p2, msg._p3, msg._file_id, msg._thread_id, &e), - rs2_delete_raw_data); - rs2::error::handle(e); + auto size = rs2_firmware_log_message_size(msg.get_message().get(), &e); + error::handle(e); + if (size == 0) + { + // TODO - handle this case, or let the user handle it... + } - auto size = rs2_get_raw_data_size(parsed_log.get(), &e); - rs2::error::handle(e); + std::shared_ptr parsed_msg( + rs2_parse_firmware_log(_firmware_log_parser.get(), msg.get_message().get(), &e), + rs2_delete_firmware_log_parsed_message); + error::handle(e); - - if (size > 0) - { - auto start = rs2_get_raw_data(parsed_log.get(), &e); - - int i = 0; - //retreive message - uint8_t messageSize = *start; - i += 1; - std::string message(firmware_logs_helper::build_string_from_uint8_and_size(start + i, messageSize)); - i += messageSize; - - //retreive file_name - uint8_t fileNameSize = *(start + i); - i += 1; - std::string file_name(firmware_logs_helper::build_string_from_uint8_and_size(start + i, fileNameSize)); - i += fileNameSize; - - //retreive thread_name - uint8_t threadNameSize = *(start + i); - i += 1; - std::string thread_name(firmware_logs_helper::build_string_from_uint8_and_size(start + i, threadNameSize)); - i += threadNameSize; - - //replace in input message - msg._message = message; - msg._file_name = file_name; - msg._thread_name = thread_name; - }*/ + return firmware_log_parsed_message(parsed_msg); } firmware_log_parser(std::shared_ptr fw_log_parser) diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index d9caae25bd..df096041d5 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -9,8 +9,6 @@ namespace librealsense firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor, std::string camera_op_code) : _hw_monitor(hardware_monitor), - _last_timestamp(0), - _timestamp_factor(0.00001), _message_queue() { auto op_code = static_cast(std::stoi(camera_op_code.c_str())); @@ -60,59 +58,5 @@ namespace librealsense } - fw_logs::fw_log_data firmware_logger_device::fill_log_data(const char* fw_logs) - { - fw_logs::fw_log_data log_data; - //fw_string_formatter reg_exp(_fw_logs_formating_options.get_enums()); - //fw_log_event log_event_data; - - auto* log_binary = reinterpret_cast(fw_logs); - - //parse first DWORD - log_data.magic_number = static_cast(log_binary->dword1.bits.magic_number); - log_data.severity = static_cast(log_binary->dword1.bits.severity); - - log_data.file_id = static_cast(log_binary->dword1.bits.file_id); - log_data.group_id = static_cast(log_binary->dword1.bits.group_id); - - //parse second DWORD - log_data.event_id = static_cast(log_binary->dword2.bits.event_id); - log_data.line = static_cast(log_binary->dword2.bits.line_id); - log_data.sequence = static_cast(log_binary->dword2.bits.seq_id); - - //parse third DWORD - log_data.p1 = static_cast(log_binary->dword3.p1); - log_data.p2 = static_cast(log_binary->dword3.p2); - - //parse forth DWORD - log_data.p3 = static_cast(log_binary->dword4.p3); - - //parse fifth DWORD - log_data.timestamp = log_binary->dword5.timestamp; - - //------------------------------------------------------------- - if (_last_timestamp == 0) - { - log_data.delta = 0; - } - else - { - log_data.delta = (log_data.timestamp - _last_timestamp) * _timestamp_factor; - } - - _last_timestamp = log_data.timestamp; - - log_data.thread_id = static_cast(log_binary->dword1.bits.thread_id); - //std::string message; - /* - _fw_logs_formating_options.get_event_data(log_data->event_id, &log_event_data); - uint32_t params[3] = { log_data->p1, log_data->p2, log_data->p3 }; - reg_exp.generate_message(log_event_data.line, log_event_data.num_of_params, params, &log_data->message); - - _fw_logs_formating_options.get_file_name(log_data->file_id, &log_data->file_name); - _fw_logs_formating_options.get_thread_name(static_cast(log_binary->dword1.bits.thread_id), - &log_data->thread_name);*/ - - return log_data; - } + } \ No newline at end of file diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index 6babb308b3..a96dd8fda5 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -27,14 +27,9 @@ namespace librealsense fw_logs::fw_logs_binary_data get_fw_log() override; - fw_logs::fw_log_data fill_log_data(const char* fw_logs) ; - - private: std::vector _input_code; std::shared_ptr _hw_monitor; - uint64_t _last_timestamp; - const double _timestamp_factor; std::queue _message_queue; void get_fw_logs_from_hw_monitor(); diff --git a/src/fw-logs/fw-log-data.cpp b/src/fw-logs/fw-log-data.cpp index 0b37356e53..60560d5abc 100644 --- a/src/fw-logs/fw-log-data.cpp +++ b/src/fw-logs/fw-log-data.cpp @@ -17,20 +17,20 @@ namespace librealsense { fw_log_data::fw_log_data(void) { - magic_number = 0; - severity = 0; - file_id = 0; - group_id = 0; - event_id = 0; - line = 0; - sequence = 0; - p1 = 0; - p2 = 0; - p3 = 0; - timestamp = 0; - delta = 0; - message = ""; - file_name = ""; + _magic_number = 0; + _severity = 0; + _file_id = 0; + _group_id = 0; + _event_id = 0; + _line = 0; + _sequence = 0; + _p1 = 0; + _p2 = 0; + _p3 = 0; + _timestamp = 0; + _delta = 0; + _message = ""; + _file_name = ""; } @@ -39,22 +39,34 @@ namespace librealsense } - string fw_log_data::to_string() + rs2_log_severity fw_log_data::get_severity() const { - stringstream fmt; + return fw_logs_severity_to_log_severity(_severity); + } - fmt << SET_WIDTH_AND_FILL(6, sequence) - << SET_WIDTH_AND_FILL(30, file_name) - << SET_WIDTH_AND_FILL(6, group_id) - << SET_WIDTH_AND_FILL(15, thread_name) - << SET_WIDTH_AND_FILL(6, severity) - << SET_WIDTH_AND_FILL(6, line) - << SET_WIDTH_AND_FILL(15, timestamp) - << SET_WIDTH_AND_FILL(15, delta) - << SET_WIDTH_AND_FILL(30, message); + const std::string& fw_log_data::get_message() const + { + return _message; + } - auto str = fmt.str(); - return str; + const std::string& fw_log_data::get_file_name() const + { + return _file_name; + } + + const std::string& fw_log_data::get_thread_name() const + { + return _thread_name; + } + + uint32_t fw_log_data::get_line() const + { + return _line; + } + + uint32_t fw_log_data::get_timestamp() const + { + return _timestamp; } rs2_log_severity fw_logs_binary_data::get_severity() const @@ -63,6 +75,12 @@ namespace librealsense return fw_logs_severity_to_log_severity(static_cast(log_binary->dword1.bits.severity)); } + uint32_t fw_logs_binary_data::get_timestamp() const + { + const fw_log_binary* log_binary = reinterpret_cast(logs_buffer.data()); + return static_cast(log_binary->dword5.timestamp); + } + rs2_log_severity fw_logs_severity_to_log_severity(int32_t severity) { rs2_log_severity result = RS2_LOG_SEVERITY_NONE; diff --git a/src/fw-logs/fw-log-data.h b/src/fw-logs/fw-log-data.h index 429f261eae..62774dc68c 100644 --- a/src/fw-logs/fw-log-data.h +++ b/src/fw-logs/fw-log-data.h @@ -14,6 +14,7 @@ namespace librealsense { std::vector logs_buffer; rs2_log_severity get_severity() const; + uint32_t get_timestamp() const; }; rs2_log_severity fw_logs_severity_to_log_severity(int32_t severity); @@ -76,27 +77,31 @@ namespace librealsense fw_log_data(void); ~fw_log_data(void); - uint32_t magic_number; - uint32_t severity; - uint32_t file_id; - uint32_t group_id; - uint32_t event_id; - uint32_t line; - uint32_t sequence; - uint32_t p1; - uint32_t p2; - uint32_t p3; - uint64_t timestamp; - double delta; + uint32_t _magic_number; + uint32_t _severity; + uint32_t _file_id; + uint32_t _group_id; + uint32_t _event_id; + uint32_t _line; + uint32_t _sequence; + uint32_t _p1; + uint32_t _p2; + uint32_t _p3; + uint64_t _timestamp; + double _delta; - uint32_t thread_id; + uint32_t _thread_id; - std::string message; - std::string file_name; - std::string thread_name; + std::string _message; + std::string _file_name; + std::string _thread_name; - std::string to_string(); - rs2_firmware_log_message to_rs2_firmware_log_message(); + rs2_log_severity get_severity() const; + const std::string& get_message() const; + const std::string& get_file_name() const; + const std::string& get_thread_name() const; + uint32_t get_line() const; + uint32_t get_timestamp() const; }; } } diff --git a/src/fw-logs/fw-logs-parser.cpp b/src/fw-logs/fw-logs-parser.cpp index 348cdde4ef..7e57f6579f 100644 --- a/src/fw-logs/fw-logs-parser.cpp +++ b/src/fw-logs/fw-logs-parser.cpp @@ -13,7 +13,9 @@ namespace librealsense namespace fw_logs { fw_logs_parser::fw_logs_parser(string xml_full_file_path) - : _fw_logs_formating_options(xml_full_file_path) + : _fw_logs_formating_options(xml_full_file_path), + _last_timestamp(0), + _timestamp_factor(0.00001) { _fw_logs_formating_options.initialize_from_xml(); } @@ -23,47 +25,66 @@ namespace librealsense { } - void fw_logs_parser::parse_fw_log(rs2_firmware_log_message** fw_log_msg) + fw_log_data fw_logs_parser::parse_fw_log(const fw_logs_binary_data* fw_log_msg) { - /*if (!fw_log_msg || !(*fw_log_msg)) - return; + fw_log_data log_data; + + if (!fw_log_msg || fw_log_msg->logs_buffer.size() == 0) + return log_data; + + log_data = fill_log_data(fw_log_msg); + //message fw_string_formatter reg_exp(_fw_logs_formating_options.get_enums()); fw_log_event log_event_data; - _fw_logs_formating_options.get_event_data((*fw_log_msg)->_event_id, &log_event_data); - - uint32_t params[3] = { (*fw_log_msg)->_p1, (*fw_log_msg)->_p2, (*fw_log_msg)->_p3 }; - std::string parsed_message; - reg_exp.generate_message(log_event_data.line, log_event_data.num_of_params, params, &parsed_message); - //reallocate char pointer and copy string into it - /*if ((*fw_log_msg)->_message) - { - delete[] (*fw_log_msg)->_message; - }*/ - /*(*fw_log_msg)->_message = new char[parsed_message.size() + 1]; - strncpy_s((*fw_log_msg)->_message, parsed_message.size() + 1, parsed_message.c_str(), parsed_message.size()); - - //file name - std::string parsed_file_name; - _fw_logs_formating_options.get_file_name((*fw_log_msg)->_file_id, &parsed_file_name); - //reallocate char pointer and copy string into it - /*if ((*fw_log_msg)->_file_name) - { - delete (*fw_log_msg)->_file_name; - }*/ - /*(*fw_log_msg)->_file_name = new char[parsed_file_name.size() + 1]; - strncpy_s((*fw_log_msg)->_file_name, parsed_file_name.size() + 1, parsed_file_name.c_str(), parsed_file_name.size()); - - //thread name - std::string parsed_thread_name; - _fw_logs_formating_options.get_thread_name(static_cast((*fw_log_msg)->_thread_id), &parsed_thread_name); - //reallocate char pointer and copy string into it - /*if ((*fw_log_msg)->_thread_name) - { - delete (*fw_log_msg)->_thread_name; - }*/ - /*(*fw_log_msg)->_thread_name = new char[parsed_thread_name.size() + 1]; - strncpy_s((*fw_log_msg)->_thread_name, parsed_thread_name.size() + 1, parsed_thread_name.c_str(), parsed_thread_name.size());*/ + _fw_logs_formating_options.get_event_data(log_data._event_id, &log_event_data); + + uint32_t params[3] = { log_data._p1, log_data._p2, log_data._p3 }; + reg_exp.generate_message(log_event_data.line, log_event_data.num_of_params, params, &log_data._message); + + //file_name + _fw_logs_formating_options.get_file_name(log_data._file_id, &log_data._file_name); + + //thread_name + _fw_logs_formating_options.get_thread_name(log_data._thread_id, &log_data._thread_name); + + return log_data; + } + + fw_log_data fw_logs_parser::fill_log_data(const fw_logs_binary_data* fw_log_msg) + { + fw_log_data log_data; + + auto* log_binary = reinterpret_cast(fw_log_msg->logs_buffer.data()); + + //parse first DWORD + log_data._magic_number = static_cast(log_binary->dword1.bits.magic_number); + log_data._severity = static_cast(log_binary->dword1.bits.severity); + log_data._thread_id = static_cast(log_binary->dword1.bits.thread_id); + log_data._file_id = static_cast(log_binary->dword1.bits.file_id); + log_data._group_id = static_cast(log_binary->dword1.bits.group_id); + + //parse second DWORD + log_data._event_id = static_cast(log_binary->dword2.bits.event_id); + log_data._line = static_cast(log_binary->dword2.bits.line_id); + log_data._sequence = static_cast(log_binary->dword2.bits.seq_id); + + //parse third DWORD + log_data._p1 = static_cast(log_binary->dword3.p1); + log_data._p2 = static_cast(log_binary->dword3.p2); + + //parse forth DWORD + log_data._p3 = static_cast(log_binary->dword4.p3); + + //parse fifth DWORD + log_data._timestamp = log_binary->dword5.timestamp; + + log_data._delta = (_last_timestamp == 0) ? + 0 :(log_data._timestamp - _last_timestamp) * _timestamp_factor; + + _last_timestamp = log_data._timestamp; + + return log_data; } } } diff --git a/src/fw-logs/fw-logs-parser.h b/src/fw-logs/fw-logs-parser.h index 2f29ed10ee..faeb6c5b26 100644 --- a/src/fw-logs/fw-logs-parser.h +++ b/src/fw-logs/fw-logs-parser.h @@ -16,15 +16,16 @@ namespace librealsense public: explicit fw_logs_parser(std::string xml_full_file_path); ~fw_logs_parser(void); - /*fw_log_data parse_fw_log(uint32_t event_id, uint32_t p1, uint32_t p2, uint32_t p3, - uint32_t file_id, uint32_t thread_id);*/ - void fw_logs_parser::parse_fw_log(rs2_firmware_log_message** fw_log_msg); + + fw_log_data fw_logs_parser::parse_fw_log(const fw_logs_binary_data* fw_log_msg); private: - void fill_log_data(const char* fw_logs, fw_log_data* log_data); + fw_log_data fill_log_data(const fw_logs_binary_data* fw_log_msg); fw_logs_formating_options _fw_logs_formating_options; + uint64_t _last_timestamp; + const double _timestamp_factor; }; } } diff --git a/src/realsense.def b/src/realsense.def index dc0edcca1c..0c14a205df 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -358,12 +358,20 @@ EXPORTS rs2_get_firmware_log rs2_delete_firmware_log_message - rs2_get_fw_log_severity + rs2_firmware_log_message_severity + rs2_firmware_log_message_timestamp rs2_firmware_log_message_data rs2_firmware_log_message_size rs2_create_firmware_log_parser rs2_delete_firmware_log_parser rs2_parse_firmware_log + rs2_delete_firmware_log_parsed_message + rs2_get_fw_log_parsed_message + rs2_get_fw_log_parsed_file_name + rs2_get_fw_log_parsed_thread_name + rs2_get_fw_log_parsed_severity + rs2_get_fw_log_parsed_line + rs2_get_fw_log_parsed_timestamp rs2_create_terminal_parser rs2_delete_terminal_parser diff --git a/src/rs.cpp b/src/rs.cpp index e0511220ba..a22e28ef9c 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -127,6 +127,11 @@ struct rs2_firmware_log_message std::shared_ptr firmware_log_binary_data; }; +struct rs2_firmware_log_parsed_message +{ + std::shared_ptr firmware_log_parsed; +}; + struct rs2_firmware_log_parser { std::shared_ptr firmware_log_parser; @@ -3013,12 +3018,19 @@ int rs2_firmware_log_message_size(rs2_firmware_log_message* msg, rs2_error** err } HANDLE_EXCEPTIONS_AND_RETURN(0, msg) -rs2_log_severity rs2_get_fw_log_severity(const rs2_firmware_log_message* msg, rs2_error** error) BEGIN_API_CALL +rs2_log_severity rs2_firmware_log_message_severity(const rs2_firmware_log_message* msg, rs2_error** error) BEGIN_API_CALL { return msg->firmware_log_binary_data->get_severity(); } HANDLE_EXCEPTIONS_AND_RETURN(RS2_LOG_SEVERITY_NONE, msg) +unsigned int rs2_firmware_log_message_timestamp(rs2_firmware_log_message* msg, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(msg); + return msg->firmware_log_binary_data->get_timestamp(); +} +HANDLE_EXCEPTIONS_AND_RETURN(0, msg) + rs2_firmware_log_parser* rs2_create_firmware_log_parser(const char* xml_path, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(xml_path); @@ -3034,44 +3046,67 @@ void rs2_delete_firmware_log_parser(rs2_firmware_log_parser* parser) BEGIN_API_C } NOEXCEPT_RETURN(, parser) -void rs2_parse_firmware_log(rs2_firmware_log_parser* fw_log_parser, rs2_firmware_log_message** fw_log_msg, rs2_error** error) BEGIN_API_CALL +rs2_firmware_log_parsed_message* rs2_parse_firmware_log(rs2_firmware_log_parser* fw_log_parser, rs2_firmware_log_message* fw_log_msg, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(fw_log_parser); VALIDATE_NOT_NULL(fw_log_msg); - fw_log_parser->firmware_log_parser.get()->parse_fw_log(fw_log_msg); + librealsense::fw_logs::fw_log_data log_data = + fw_log_parser->firmware_log_parser.get()->parse_fw_log(fw_log_msg->firmware_log_binary_data.get()); + + return new rs2_firmware_log_parsed_message{ std::make_shared(log_data) }; } -NOEXCEPT_RETURN(, fw_log_msg) -/*rs2_raw_data_buffer* rs2_parse_firmware_log(rs2_firmware_logs_parser* fw_logs_parser, - int event_id, int p1, int p2, int p3, int file_id, int thread_id, rs2_error** error) BEGIN_API_CALL +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, fw_log_msg) + +void rs2_delete_firmware_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg) BEGIN_API_CALL { - VALIDATE_NOT_NULL(fw_logs_parser); + VALIDATE_NOT_NULL(fw_log_parsed_msg); + delete fw_log_parsed_msg; +} +NOEXCEPT_RETURN(, fw_log_parsed_msg) - librealsense::fw_logs::fw_log_data fw_log = fw_logs_parser->firmware_logs_parser.get()->parse_fw_log(event_id, p1, p2, p3, file_id, thread_id); - - std::vector message_bytes(fw_log.message.begin(), fw_log.message.end()); - message_bytes.push_back('\0'); - uint8_t msg_bytes_size = message_bytes.size(); +const char* rs2_get_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(fw_log_parsed_msg); + return fw_log_parsed_msg->firmware_log_parsed->get_message().c_str(); +} +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, fw_log_parsed_msg) + +const char* rs2_get_fw_log_parsed_file_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(fw_log_parsed_msg); + return fw_log_parsed_msg->firmware_log_parsed->get_file_name().c_str(); +} +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, fw_log_parsed_msg) - std::vector file_name_bytes(fw_log.file_name.begin(), fw_log.file_name.end()); - file_name_bytes.push_back('\0'); - uint8_t file_name_bytes_size = file_name_bytes.size(); +const char* rs2_get_fw_log_parsed_thread_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(fw_log_parsed_msg); + return fw_log_parsed_msg->firmware_log_parsed->get_thread_name().c_str(); +} +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, fw_log_parsed_msg) - std::vector thread_name_bytes(fw_log.thread_name.begin(), fw_log.thread_name.end()); - thread_name_bytes.push_back('\0'); - uint8_t thread_name_bytes_size = thread_name_bytes.size(); +rs2_log_severity rs2_get_fw_log_parsed_severity(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(fw_log_parsed_msg); + return fw_log_parsed_msg->firmware_log_parsed->get_severity(); +} +HANDLE_EXCEPTIONS_AND_RETURN(RS2_LOG_SEVERITY_NONE, fw_log_parsed_msg) - std::vector msg_file_thread_bytes; - msg_file_thread_bytes.push_back(msg_bytes_size); - msg_file_thread_bytes.insert(msg_file_thread_bytes.end(), message_bytes.begin(), message_bytes.end()); - msg_file_thread_bytes.push_back(file_name_bytes_size); - msg_file_thread_bytes.insert(msg_file_thread_bytes.end(), file_name_bytes.begin(), file_name_bytes.end()); - msg_file_thread_bytes.push_back(thread_name_bytes_size); - msg_file_thread_bytes.insert(msg_file_thread_bytes.end(), thread_name_bytes.begin(), thread_name_bytes.end()); +unsigned int rs2_get_fw_log_parsed_line(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(fw_log_parsed_msg); + return fw_log_parsed_msg->firmware_log_parsed->get_line(); +} +HANDLE_EXCEPTIONS_AND_RETURN(0, fw_log_parsed_msg) - return new rs2_raw_data_buffer { msg_file_thread_bytes }; +unsigned int rs2_get_fw_log_parsed_timestamp(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(fw_log_parsed_msg); + return fw_log_parsed_msg->firmware_log_parsed->get_timestamp(); } -HANDLE_EXCEPTIONS_AND_RETURN(nullptr, fw_logs_parser)*/ +HANDLE_EXCEPTIONS_AND_RETURN(0, fw_log_parsed_msg) + rs2_terminal_parser* rs2_create_terminal_parser(const char* xml_content, rs2_error** error) BEGIN_API_CALL { diff --git a/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp b/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp index 3da5c82d73..73cfbc890d 100644 --- a/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp +++ b/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp @@ -62,6 +62,11 @@ TEST_CASE( "Getting FW logs in C", "[fw-logs]" ) { char* time_str = ctime(&mytime); time_str[strlen(time_str) - 1] = '\0'; printf("message received %s - ", time_str); + + rs2_error* e = nullptr; + rs2_log_severity severity = rs2_get_fw_log_severity(fw_log_msg, &e); + printf("%s ", rs2_log_severity_to_string(severity)); + for (int i = 0; i < size; ++i) { printf("%d ", *(start + i)); From 5c651e9c2c0d42cfe83b319b3aea1b891a0be02e Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 27 May 2020 14:09:48 +0300 Subject: [PATCH 12/61] fw log message provided as input to get firmware logs --- examples/firmware-logs/rs-firmware-logs.cpp | 56 ++++++++++----------- include/librealsense2/h/rs_device.h | 18 +++++-- include/librealsense2/hpp/rs_device.hpp | 20 +++++--- src/firmware_logger_device.cpp | 11 ++-- src/firmware_logger_device.h | 4 +- src/realsense.def | 3 +- src/rs.cpp | 23 +++++++-- 7 files changed, 84 insertions(+), 51 deletions(-) diff --git a/examples/firmware-logs/rs-firmware-logs.cpp b/examples/firmware-logs/rs-firmware-logs.cpp index 15249f1b54..bc4cb22c4a 100644 --- a/examples/firmware-logs/rs-firmware-logs.cpp +++ b/examples/firmware-logs/rs-firmware-logs.cpp @@ -67,39 +67,37 @@ int main(int argc, char * argv[]) setvbuf(stdout, NULL, _IONBF, 0); // unbuffering stdout while (hub.is_connected(dev)) - { - //this_thread::sleep_for(chrono::milliseconds(100)); - + { auto fw_log = res.get_device().as(); - auto fw_log_message = fw_log.get_firmware_log(); - - std::vector fw_log_lines; - - static bool usingParser = true; - if (usingParser) + auto fw_log_message = fw_log.create_message(); + bool result = fw_log.get_firmware_log(fw_log_message); + if (result) { - std::string xml_path("HWLoggerEventsDS5.xml"); - if (!xml_path.empty()) + std::vector fw_log_lines; + + static bool usingParser = true; + if (usingParser) { - ifstream f(xml_path); - if (f.good()) + std::string xml_path("HWLoggerEventsDS5.xml"); + if (!xml_path.empty()) { - unique_ptr parser = - unique_ptr(new rs2::firmware_log_parser(xml_path)); - - rs2::firmware_log_parsed_message parsed_log = parser->parse_firmware_log(fw_log_message); - stringstream sstr; - sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() - << " " << parsed_log.thread_name() << " " << parsed_log.file_name() - << " " << parsed_log.line(); - - fw_log_lines.push_back(sstr.str()); + ifstream f(xml_path); + if (f.good()) + { + unique_ptr parser = + unique_ptr(new rs2::firmware_log_parser(xml_path)); + + rs2::firmware_log_parsed_message parsed_log = parser->parse_firmware_log(fw_log_message); + stringstream sstr; + sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() + << " " << parsed_log.thread_name() << " " << parsed_log.file_name() + << " " << parsed_log.line(); + + fw_log_lines.push_back(sstr.str()); + } } } - } - else - { - if (fw_log_message.size() > 0) + else { stringstream sstr; sstr << fw_log_message.get_timestamp(); @@ -112,9 +110,9 @@ int main(int argc, char * argv[]) } fw_log_lines.push_back(sstr.str()); } + for (auto& line : fw_log_lines) + cout << line << endl; } - for (auto& line : fw_log_lines) - cout << line << endl; } } catch (const rs2::error & e) diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index ce11c16563..da03320dd3 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -354,13 +354,21 @@ rs2_raw_data_buffer* rs2_serialize_json(rs2_device* dev, rs2_error** error); void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_size, rs2_error** error); /** -* \brief Gets RealSense firmware log. -* \param[in] dev Device from which the FW log should be taken -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return firmware logs +* \brief Creates RealSense firmware log message. +* \param[in] dev Device from which the FW log will be taken using the created message +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return pointer to created empty firmware log message */ -rs2_firmware_log_message* rs2_get_firmware_log(rs2_device* dev, rs2_error** error); +rs2_firmware_log_message* rs2_create_firmware_log_message(rs2_device* dev, rs2_error** error); +/** +* \brief Gets RealSense firmware log. +* \param[in] dev Device from which the FW log should be taken +* \param[in] fw_log_msg Firmware log message object to be filled +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor +*/ +int rs2_get_firmware_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); /** * Delete RealSense firmware log message * \param[in] device Realsense firmware log message to delete diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index eb9b8eb7bf..91c2273510 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -422,16 +422,28 @@ namespace rs2 error::handle(e); } - rs2::firmware_log_message get_firmware_log() const + rs2::firmware_log_message create_message() { rs2_error* e = nullptr; std::shared_ptr msg( - rs2_get_firmware_log(_dev.get(), &e), + rs2_create_firmware_log_message(_dev.get(), &e), rs2_delete_firmware_log_message); error::handle(e); return firmware_log_message(msg); } + + bool get_firmware_log(rs2::firmware_log_message& msg) const + { + rs2_error* e = nullptr; + rs2_firmware_log_message* m = msg.get_message().get(); + bool fw_log_pulling_status = + rs2_get_firmware_log(_dev.get(), &(m), &e); + + error::handle(e); + + return fw_log_pulling_status; + } }; class firmware_log_parsed_message @@ -506,10 +518,6 @@ namespace rs2 auto size = rs2_firmware_log_message_size(msg.get_message().get(), &e); error::handle(e); - if (size == 0) - { - // TODO - handle this case, or let the user handle it... - } std::shared_ptr parsed_msg( rs2_parse_firmware_log(_firmware_log_parser.get(), msg.get_message().get(), &e), diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index df096041d5..b71e8c4951 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -17,18 +17,21 @@ namespace librealsense 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; } - - fw_logs::fw_logs_binary_data firmware_logger_device::get_fw_log() + bool firmware_logger_device::get_fw_log(fw_logs::fw_logs_binary_data& binary_data) { + bool result = false; if (_message_queue.empty()) { get_fw_logs_from_hw_monitor(); } - fw_logs::fw_logs_binary_data result; + if (!_message_queue.empty()) { - result = _message_queue.front(); + fw_logs::fw_logs_binary_data data; + data = _message_queue.front(); _message_queue.pop(); + binary_data = data; + result = true; } return result; } diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index a96dd8fda5..616c62fc32 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -13,7 +13,7 @@ namespace librealsense class firmware_logger_extensions { public: - virtual fw_logs::fw_logs_binary_data get_fw_log() = 0; + virtual bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) = 0; virtual ~firmware_logger_extensions() = default; }; MAP_EXTENSION(RS2_EXTENSION_FW_LOGGER, librealsense::firmware_logger_extensions); @@ -25,7 +25,7 @@ namespace librealsense firmware_logger_device(std::shared_ptr hardware_monitor, std::string camera_op_code); - fw_logs::fw_logs_binary_data get_fw_log() override; + bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) override; private: std::vector _input_code; diff --git a/src/realsense.def b/src/realsense.def index 0c14a205df..52830ef0cf 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -356,8 +356,9 @@ EXPORTS rs2_get_calibration_table rs2_set_calibration_table - rs2_get_firmware_log + rs2_create_firmware_log_message rs2_delete_firmware_log_message + rs2_get_firmware_log rs2_firmware_log_message_severity rs2_firmware_log_message_timestamp rs2_firmware_log_message_data diff --git a/src/rs.cpp b/src/rs.cpp index a22e28ef9c..9e09c76bdb 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -2987,15 +2987,30 @@ void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_s } HANDLE_EXCEPTIONS_AND_RETURN(, dev, json_content, content_size) -rs2_firmware_log_message* rs2_get_firmware_log(rs2_device* dev, rs2_error** error) BEGIN_API_CALL +rs2_firmware_log_message* rs2_create_firmware_log_message(rs2_device* dev, rs2_error** error)BEGIN_API_CALL { VALIDATE_NOT_NULL(dev); auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + + return new rs2_firmware_log_message{ std::make_shared () }; +} +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev) + +int rs2_get_firmware_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(dev); + VALIDATE_NOT_NULL(fw_log_msg); + auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); - fw_logs::fw_logs_binary_data binary_data = fw_loggerable->get_fw_log(); - return new rs2_firmware_log_message{ std::make_shared(binary_data) }; + fw_logs::fw_logs_binary_data binary_data; + bool result = fw_loggerable->get_fw_log(binary_data); + if (result) + { + (*(*fw_log_msg)->firmware_log_binary_data.get()) = binary_data; + } + return result? 1 : 0; } -HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev, error) +HANDLE_EXCEPTIONS_AND_RETURN(0, dev, fw_log_msg) void rs2_delete_firmware_log_message(rs2_firmware_log_message* msg) BEGIN_API_CALL { From cc747b249b7d74682e707a3137cf2e1d81fb377f Mon Sep 17 00:00:00 2001 From: remibettan Date: Sun, 31 May 2020 16:08:25 +0300 Subject: [PATCH 13/61] Flash logs work - work to do in fw logger device - see comment --- examples/CMakeLists.txt | 1 + examples/flash-logs/CMakeLists.txt | 16 +++ examples/flash-logs/rs-flash-logs.cpp | 126 ++++++++++++++++++++++++ include/librealsense2/h/rs_device.h | 12 +++ include/librealsense2/hpp/rs_device.hpp | 23 +++++ src/firmware_logger_device.cpp | 123 ++++++++++++++++++++--- src/firmware_logger_device.h | 24 ++++- src/fw-logs/fw-logs-parser.h | 2 +- src/realsense.def | 1 + src/rs.cpp | 28 ++++++ 10 files changed, 336 insertions(+), 20 deletions(-) create mode 100644 examples/flash-logs/CMakeLists.txt create mode 100644 examples/flash-logs/rs-flash-logs.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c01d08be23..8f1a688f36 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -48,3 +48,4 @@ add_subdirectory(ar-advanced) add_subdirectory(pose-apriltag) add_subdirectory(tracking-and-depth) add_subdirectory(firmware-logs) +add_subdirectory(flash-logs) diff --git a/examples/flash-logs/CMakeLists.txt b/examples/flash-logs/CMakeLists.txt new file mode 100644 index 0000000000..fac7fe82c8 --- /dev/null +++ b/examples/flash-logs/CMakeLists.txt @@ -0,0 +1,16 @@ +# License: Apache 2.0. See LICENSE file in root directory. +# Copyright(c) 2020 Intel Corporation. All Rights Reserved. +# minimum required cmake version: 3.1.0 +cmake_minimum_required(VERSION 3.1.0) + +project(RealsenseExamplesFirmwareLogs) + +if(BUILD_GRAPHICAL_EXAMPLES) + add_executable(rs-flash-logs rs-flash-logs.cpp ../example.hpp) + set_property(TARGET rs-flash-logs PROPERTY CXX_STANDARD 11) + target_link_libraries(rs-flash-logs ${DEPENDENCIES}) + include_directories(rs-flash-logs ../ ../../third-party/tclap/include) + set_target_properties (rs-flash-logs PROPERTIES FOLDER "Examples") + + install(TARGETS rs-flash-logs RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() diff --git a/examples/flash-logs/rs-flash-logs.cpp b/examples/flash-logs/rs-flash-logs.cpp new file mode 100644 index 0000000000..3658117ad7 --- /dev/null +++ b/examples/flash-logs/rs-flash-logs.cpp @@ -0,0 +1,126 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2017 Intel Corporation. All Rights Reserved. + +#include // Include RealSense Cross Platform API +#include "example.hpp" // Include short list of convenience functions for rendering +#include +#include +#include +#include + +using namespace std; + + +string hexify(unsigned char n) +{ + string res; + + do + { + res += "0123456789ABCDEF"[n % 16]; + n >>= 4; + } while (n); + + reverse(res.begin(), res.end()); + + if (res.size() == 1) + { + res.insert(0, "0"); + } + + return res; +} + +string datetime_string() +{ + auto t = time(nullptr); + char buffer[20] = {}; + const tm* time = localtime(&t); + if (nullptr != time) + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", time); + + return string(buffer); +} + +// Capture Example demonstrates how to +// capture depth and color video streams and render them to the screen +int main(int argc, char * argv[]) +{ + // Declare RealSense pipeline, encapsulating the actual device and sensors + rs2::pipeline pipe; + + // Start streaming with default recommended configuration + // The default video configuration contains Depth and Color streams + // If a device is capable to stream IMU data, both Gyro and Accelerometer are enabled by default + auto res = pipe.start(); + + rs2::context ctx; + rs2::device_hub hub(ctx); + + try + { + cout << "\nWaiting for RealSense device to connect...\n"; + auto dev = hub.wait_for_device(); + cout << "RealSense device was connected...\n"; + + setvbuf(stdout, NULL, _IONBF, 0); // unbuffering stdout + + + auto fw_log = res.get_device().as(); + auto number_of_flash_logs_in_device = fw_log.get_number_of_flash_logs(); + + for (int i = 0; i < number_of_flash_logs_in_device; ++i) + { + auto flash_log_message = fw_log.create_message(); + bool result = fw_log.get_flash_log(flash_log_message); + if (result) + { + std::vector fw_log_lines; + + static bool usingParser = true; + if (usingParser) + { + std::string xml_path("HWLoggerEventsDS5.xml"); + if (!xml_path.empty()) + { + ifstream f(xml_path); + if (f.good()) + { + unique_ptr parser = + unique_ptr(new rs2::firmware_log_parser(xml_path)); + + rs2::firmware_log_parsed_message parsed_log = parser->parse_firmware_log(flash_log_message); + stringstream sstr; + sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() + << " " << parsed_log.thread_name() << " " << parsed_log.file_name() + << " " << parsed_log.line(); + + fw_log_lines.push_back(sstr.str()); + } + } + } + else + { + stringstream sstr; + sstr << flash_log_message.get_timestamp(); + sstr << " " << flash_log_message.get_severity_str(); + sstr << " FW_Log_Data:"; + std::vector msg_data = flash_log_message.data(); + for (int i = 0; i < msg_data.size(); ++i) + { + sstr << hexify(msg_data[i]) << " "; + } + fw_log_lines.push_back(sstr.str()); + } + for (auto& line : fw_log_lines) + cout << line << endl; + } + } + } + catch (const rs2::error & e) + { + cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << endl; + } + + return EXIT_SUCCESS; +} diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index da03320dd3..43f5cd0cfe 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -369,6 +369,18 @@ rs2_firmware_log_message* rs2_create_firmware_log_message(rs2_device* dev, rs2_e * \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor */ int rs2_get_firmware_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); + +int rs2_get_number_of_flash_logs(rs2_device* dev, rs2_error** error); + +/** +* \brief Gets RealSense flash log - this is a fw log that has been written in the device during the previous shutdown of the device +* \param[in] dev Device from which the FW log should be taken +* \param[in] fw_log_msg Firmware log message object to be filled +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor +*/ +int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); + /** * Delete RealSense firmware log message * \param[in] device Realsense firmware log message to delete diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index 91c2273510..103a4fadc7 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -444,6 +444,29 @@ namespace rs2 return fw_log_pulling_status; } + + bool get_flash_log(rs2::firmware_log_message& msg) const + { + rs2_error* e = nullptr; + rs2_firmware_log_message* m = msg.get_message().get(); + bool flash_log_pulling_status = + rs2_get_flash_log(_dev.get(), &(m), &e); + + error::handle(e); + + return flash_log_pulling_status; + } + + int get_number_of_flash_logs() const + { + rs2_error* e = nullptr; + int number_of_flash_logs = + rs2_get_number_of_flash_logs(_dev.get(), &e); + + error::handle(e); + + return number_of_flash_logs; + } }; class firmware_log_parsed_message diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index b71e8c4951..fc37f35259 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -9,57 +9,148 @@ namespace librealsense firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor, std::string camera_op_code) : _hw_monitor(hardware_monitor), - _message_queue() + _fw_logs_queue(), + _flash_logs_queue() { auto op_code = static_cast(std::stoi(camera_op_code.c_str())); - _input_code = { 0x14, 0x00, 0xab, 0xcd, op_code, 0x00, 0x00, 0x00, - 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - } + _input_code_for_fw_logs = { 0x14, 0x00, 0xab, 0xcd, op_code, 0x00, 0x00, 0x00, + 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + //TODO - get the right code for flah logs + auto flash_logs_op_code = static_cast(0x09);// static_cast(std::stoi(camera_op_code.c_str())); + //auto flash_logs_offset = { 0x7a, 0x01, 0x00, 0x00 }; + //auto flash_logs_length = { 0xf8, 0x03, 0x00, 0x00 }; + _input_code_for_flash_logs = { 0x14, 0x00, 0xab, 0xcd, flash_logs_op_code, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x17, 0x00, 0xf8, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + } + bool firmware_logger_device::get_fw_log(fw_logs::fw_logs_binary_data& binary_data) { bool result = false; - if (_message_queue.empty()) + if (_fw_logs_queue.empty()) { - get_fw_logs_from_hw_monitor(); + get_logs_from_hw_monitor(LOG_TYPE_FW_LOG); } - if (!_message_queue.empty()) + if (!_fw_logs_queue.empty()) { fw_logs::fw_logs_binary_data data; - data = _message_queue.front(); - _message_queue.pop(); + data = _fw_logs_queue.front(); + _fw_logs_queue.pop(); binary_data = data; result = true; } return result; } - void firmware_logger_device::get_fw_logs_from_hw_monitor() + bool firmware_logger_device::get_flash_log(fw_logs::fw_logs_binary_data& binary_data) { - auto res = _hw_monitor->send(_input_code); + bool result = false; + if (_flash_logs_queue.empty()) + { + get_logs_from_hw_monitor(LOG_TYPE_FLASH_LOG); + } + + if (!_flash_logs_queue.empty()) + { + fw_logs::fw_logs_binary_data data; + data = _flash_logs_queue.front(); + _flash_logs_queue.pop(); + binary_data = data; + result = true; + } + return result; + } + + bool firmware_logger_device::get_log(fw_logs::fw_logs_binary_data& binary_data, log_type type) + { + std::queue* logs_queue; + logs_queue = (type == LOG_TYPE_FW_LOG) ? &_fw_logs_queue : &_flash_logs_queue; + + bool result = false; + if ((*logs_queue).empty()) + { + get_logs_from_hw_monitor(type); + } + + // if log type is fw log --> pop should be done + // if log type is flash log --> no pop should be done (queue pulled only once) + if (!(*logs_queue).empty()) + { + fw_logs::fw_logs_binary_data data; + data = (*logs_queue).front(); + (*logs_queue).pop(); + binary_data = data; + result = true; + } + return result; + } + + bool firmware_logger_device::get_flash_log(fw_logs::fw_logs_binary_data& binary_data) + { + std::queue* logs_queue; + logs_queue = &_flash_logs_queue; + + bool result = false; + if (_flash_logs_queue.empty()) + { + get_logs_from_hw_monitor(LOG_TYPE_FLASH_LOG); + } + + // if log type is fw log --> pop should be done + // if log type is flash log --> no pop should be done (queue pulled only once) + if (!(*logs_queue).empty()) + { + fw_logs::fw_logs_binary_data data; + data = (*logs_queue).front(); + (*logs_queue).pop(); + binary_data = data; + result = true; + } + return result; + } + + // get number N of flash logs - save in object + // user to call get_flash_log N times + // index of vector (not queue) to be saved in fw logger object + // if user calls get_flash_log N+1 times, index to be reset to 0 (cyclic read) + + void firmware_logger_device::get_logs_from_hw_monitor(log_type type) + { + std::queue& logs_queue = (type == LOG_TYPE_FW_LOG) ? _fw_logs_queue : _flash_logs_queue; + const std::vector & input_code = (type == LOG_TYPE_FW_LOG) ? _input_code_for_fw_logs : _input_code_for_flash_logs; + int size_of_header = (type == LOG_TYPE_FW_LOG) ? 4 : 31; + auto res = _hw_monitor->send(input_code); if (res.empty()) { throw std::runtime_error("Getting Firmware logs failed!"); } + int limit = (type == LOG_TYPE_FW_LOG) ? (res.size() - 4) / fw_logs::BINARY_DATA_SIZE : + static_cast(res[0] + (res[1] << 8) + (res[2] << 16) + (res[3] << 24)); + //erasing header - res.erase(res.begin(), res.begin() + 4); + res.erase(res.begin(), res.begin() + size_of_header); auto beginOfLogIterator = res.begin(); // convert bytes to fw_logs_binary_data - for (int i = 0; i < res.size() / fw_logs::BINARY_DATA_SIZE; ++i) + for (int i = 0; i < limit; ++i) { + if (*beginOfLogIterator == 0) + break; auto endOfLogIterator = beginOfLogIterator + fw_logs::BINARY_DATA_SIZE; std::vector resultsForOneLog; resultsForOneLog.insert(resultsForOneLog.begin(), beginOfLogIterator, endOfLogIterator); fw_logs::fw_logs_binary_data binary_data{ resultsForOneLog }; - _message_queue.push(binary_data); + logs_queue.push(binary_data); beginOfLogIterator = endOfLogIterator; } } + int firmware_logger_device::get_number_of_flash_logs() + { - + } } \ No newline at end of file diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index 616c62fc32..d05862af2f 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -14,6 +14,7 @@ namespace librealsense { public: virtual bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) = 0; + virtual bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) = 0; virtual ~firmware_logger_extensions() = default; }; MAP_EXTENSION(RS2_EXTENSION_FW_LOGGER, librealsense::firmware_logger_extensions); @@ -26,13 +27,30 @@ namespace librealsense std::string camera_op_code); bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) override; + bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) override; + + private: - std::vector _input_code; + enum log_type + { + LOG_TYPE_FW_LOG = 0, + LOG_TYPE_FLASH_LOG = 1, + LOG_TYPE_NUM_OF_TYPES = 2 + }; + + bool get_log(fw_logs::fw_logs_binary_data& binary_data, log_type type); + void get_logs_from_hw_monitor(log_type type); + + std::vector _input_code_for_fw_logs; + std::vector _input_code_for_flash_logs; std::shared_ptr _hw_monitor; - std::queue _message_queue; - void get_fw_logs_from_hw_monitor(); + std::queue _fw_logs_queue; + std::queue _flash_logs_queue; + + + }; } \ No newline at end of file diff --git a/src/fw-logs/fw-logs-parser.h b/src/fw-logs/fw-logs-parser.h index faeb6c5b26..331b35e252 100644 --- a/src/fw-logs/fw-logs-parser.h +++ b/src/fw-logs/fw-logs-parser.h @@ -17,7 +17,7 @@ namespace librealsense explicit fw_logs_parser(std::string xml_full_file_path); ~fw_logs_parser(void); - fw_log_data fw_logs_parser::parse_fw_log(const fw_logs_binary_data* fw_log_msg); + fw_log_data parse_fw_log(const fw_logs_binary_data* fw_log_msg); private: diff --git a/src/realsense.def b/src/realsense.def index 52830ef0cf..617e35d835 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -359,6 +359,7 @@ EXPORTS rs2_create_firmware_log_message rs2_delete_firmware_log_message rs2_get_firmware_log + rs2_get_flash_log rs2_firmware_log_message_severity rs2_firmware_log_message_timestamp rs2_firmware_log_message_data diff --git a/src/rs.cpp b/src/rs.cpp index 9e09c76bdb..068336b985 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -3012,6 +3012,34 @@ int rs2_get_firmware_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, } HANDLE_EXCEPTIONS_AND_RETURN(0, dev, fw_log_msg) + +int rs2_get_number_of_flash_logs(rs2_device* dev, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(dev); + auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + + fw_logs::fw_logs_binary_data binary_data; + int number_of_flash_logs = fw_loggerable->get_number_of_flash_logs(binary_data); + + return number_of_flash_logs; +} +HANDLE_EXCEPTIONS_AND_RETURN(0, dev) + +int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error)BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(dev); + VALIDATE_NOT_NULL(fw_log_msg); + auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + + fw_logs::fw_logs_binary_data binary_data; + bool result = fw_loggerable->get_flash_log(binary_data); + if (result) + { + (*(*fw_log_msg)->firmware_log_binary_data.get()) = binary_data; + } + return result ? 1 : 0; +} +HANDLE_EXCEPTIONS_AND_RETURN(0, dev, fw_log_msg) void rs2_delete_firmware_log_message(rs2_firmware_log_message* msg) BEGIN_API_CALL { VALIDATE_NOT_NULL(msg); From dd69928bd62204d5a08472123cb49065f6cd58c0 Mon Sep 17 00:00:00 2001 From: remibettan Date: Sun, 31 May 2020 21:53:35 +0300 Subject: [PATCH 14/61] fw logs and flash logs implemented --- src/firmware_logger_device.cpp | 164 +++++++++++++++------------------ src/firmware_logger_device.h | 27 +++--- src/realsense.def | 1 + src/rs.cpp | 2 +- 4 files changed, 85 insertions(+), 109 deletions(-) diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index fc37f35259..f28d057f45 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -6,133 +6,88 @@ namespace librealsense { - firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor, - std::string camera_op_code) : - _hw_monitor(hardware_monitor), - _fw_logs_queue(), - _flash_logs_queue() - { - auto op_code = static_cast(std::stoi(camera_op_code.c_str())); + firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor, + std::string camera_op_code) : + _hw_monitor(hardware_monitor), + _fw_logs(), + _flash_logs(), + _flash_logs_initialized(false), + _flash_logs_index(0) + { + auto op_code = static_cast(std::stoi(camera_op_code.c_str())); _input_code_for_fw_logs = { 0x14, 0x00, 0xab, 0xcd, op_code, 0x00, 0x00, 0x00, - 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - //TODO - get the right code for flah logs + //TODO - get the right code for flash logs auto flash_logs_op_code = static_cast(0x09);// static_cast(std::stoi(camera_op_code.c_str())); //auto flash_logs_offset = { 0x7a, 0x01, 0x00, 0x00 }; //auto flash_logs_length = { 0xf8, 0x03, 0x00, 0x00 }; - _input_code_for_flash_logs = { 0x14, 0x00, 0xab, 0xcd, flash_logs_op_code, 0x00, 0x00, 0x00, + _input_code_for_flash_logs = { 0x14, 0x00, 0xab, 0xcd, flash_logs_op_code, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x17, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - } - - bool firmware_logger_device::get_fw_log(fw_logs::fw_logs_binary_data& binary_data) - { - bool result = false; - if (_fw_logs_queue.empty()) - { - get_logs_from_hw_monitor(LOG_TYPE_FW_LOG); - } - - if (!_fw_logs_queue.empty()) - { - fw_logs::fw_logs_binary_data data; - data = _fw_logs_queue.front(); - _fw_logs_queue.pop(); - binary_data = data; - result = true; - } - return result; } - bool firmware_logger_device::get_flash_log(fw_logs::fw_logs_binary_data& binary_data) + bool firmware_logger_device::get_fw_log(fw_logs::fw_logs_binary_data& binary_data) { bool result = false; - if (_flash_logs_queue.empty()) + if (_fw_logs.empty()) { - get_logs_from_hw_monitor(LOG_TYPE_FLASH_LOG); + get_fw_logs_from_hw_monitor(); } - if (!_flash_logs_queue.empty()) + if (!_fw_logs.empty()) { fw_logs::fw_logs_binary_data data; - data = _flash_logs_queue.front(); - _flash_logs_queue.pop(); + data = _fw_logs.front(); + _fw_logs.pop(); binary_data = data; result = true; } return result; } - bool firmware_logger_device::get_log(fw_logs::fw_logs_binary_data& binary_data, log_type type) - { - std::queue* logs_queue; - logs_queue = (type == LOG_TYPE_FW_LOG) ? &_fw_logs_queue : &_flash_logs_queue; - - bool result = false; - if ((*logs_queue).empty()) - { - get_logs_from_hw_monitor(type); - } - // if log type is fw log --> pop should be done - // if log type is flash log --> no pop should be done (queue pulled only once) - if (!(*logs_queue).empty()) - { - fw_logs::fw_logs_binary_data data; - data = (*logs_queue).front(); - (*logs_queue).pop(); - binary_data = data; - result = true; - } - return result; - } - - bool firmware_logger_device::get_flash_log(fw_logs::fw_logs_binary_data& binary_data) + void firmware_logger_device::get_fw_logs_from_hw_monitor() { - std::queue* logs_queue; - logs_queue = &_flash_logs_queue; - - bool result = false; - if (_flash_logs_queue.empty()) + int size_of_fw_logs_header = 4; + auto res = _hw_monitor->send(_input_code_for_fw_logs); + if (res.empty()) { - get_logs_from_hw_monitor(LOG_TYPE_FLASH_LOG); + throw std::runtime_error("Getting Firmware logs failed!"); } - // if log type is fw log --> pop should be done - // if log type is flash log --> no pop should be done (queue pulled only once) - if (!(*logs_queue).empty()) + //erasing header + res.erase(res.begin(), res.begin() + size_of_fw_logs_header); + + auto beginOfLogIterator = res.begin(); + // convert bytes to fw_logs_binary_data + for (int i = 0; i < res.size() / fw_logs::BINARY_DATA_SIZE; ++i) { - fw_logs::fw_logs_binary_data data; - data = (*logs_queue).front(); - (*logs_queue).pop(); - binary_data = data; - result = true; + if (*beginOfLogIterator == 0) + break; + auto endOfLogIterator = beginOfLogIterator + fw_logs::BINARY_DATA_SIZE; + std::vector resultsForOneLog; + resultsForOneLog.insert(resultsForOneLog.begin(), beginOfLogIterator, endOfLogIterator); + fw_logs::fw_logs_binary_data binary_data{ resultsForOneLog }; + _fw_logs.push(binary_data); + beginOfLogIterator = endOfLogIterator; } - return result; } - // get number N of flash logs - save in object - // user to call get_flash_log N times - // index of vector (not queue) to be saved in fw logger object - // if user calls get_flash_log N+1 times, index to be reset to 0 (cyclic read) - - void firmware_logger_device::get_logs_from_hw_monitor(log_type type) + void firmware_logger_device::get_flash_logs_from_hw_monitor() { - std::queue& logs_queue = (type == LOG_TYPE_FW_LOG) ? _fw_logs_queue : _flash_logs_queue; - const std::vector & input_code = (type == LOG_TYPE_FW_LOG) ? _input_code_for_fw_logs : _input_code_for_flash_logs; - int size_of_header = (type == LOG_TYPE_FW_LOG) ? 4 : 31; - auto res = _hw_monitor->send(input_code); + int size_of_flash_logs_header = 31; + auto res = _hw_monitor->send(_input_code_for_flash_logs); if (res.empty()) { - throw std::runtime_error("Getting Firmware logs failed!"); + throw std::runtime_error("Getting Flash logs failed!"); } - int limit = (type == LOG_TYPE_FW_LOG) ? (res.size() - 4) / fw_logs::BINARY_DATA_SIZE : - static_cast(res[0] + (res[1] << 8) + (res[2] << 16) + (res[3] << 24)); - + int limit = static_cast(res[0] + (res[1] << 8) + (res[2] << 16) + (res[3] << 24)); + //erasing header - res.erase(res.begin(), res.begin() + size_of_header); + res.erase(res.begin(), res.begin() + size_of_flash_logs_header); auto beginOfLogIterator = res.begin(); // convert bytes to fw_logs_binary_data @@ -144,13 +99,38 @@ namespace librealsense std::vector resultsForOneLog; resultsForOneLog.insert(resultsForOneLog.begin(), beginOfLogIterator, endOfLogIterator); fw_logs::fw_logs_binary_data binary_data{ resultsForOneLog }; - logs_queue.push(binary_data); + _flash_logs.push_back(binary_data); beginOfLogIterator = endOfLogIterator; } + + _flash_logs_initialized = true; } - int firmware_logger_device::get_number_of_flash_logs() + bool firmware_logger_device::get_flash_log(fw_logs::fw_logs_binary_data& binary_data) { + bool result = false; + if (!_flash_logs_initialized) + { + get_flash_logs_from_hw_monitor(); + } + + if (!_flash_logs.empty()) + { + fw_logs::fw_logs_binary_data data; + data = _flash_logs[_flash_logs_index]; + _flash_logs_index = (_flash_logs_index + 1) % (_flash_logs.size()); + binary_data = data; + result = true; + } + return result; + } + size_t firmware_logger_device::get_number_of_flash_logs() + { + if (!_flash_logs_initialized) + { + get_flash_logs_from_hw_monitor(); + } + return _flash_logs.size(); } } \ No newline at end of file diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index d05862af2f..12f54c7de2 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -15,11 +15,12 @@ namespace librealsense public: virtual bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) = 0; virtual bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) = 0; + virtual size_t get_number_of_flash_logs() = 0; virtual ~firmware_logger_extensions() = default; }; MAP_EXTENSION(RS2_EXTENSION_FW_LOGGER, librealsense::firmware_logger_extensions); - + class firmware_logger_device : public virtual device, public firmware_logger_extensions { public: @@ -29,28 +30,22 @@ namespace librealsense bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) override; bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) override; - + size_t get_number_of_flash_logs() override; private: - enum log_type - { - LOG_TYPE_FW_LOG = 0, - LOG_TYPE_FLASH_LOG = 1, - LOG_TYPE_NUM_OF_TYPES = 2 - }; + void get_fw_logs_from_hw_monitor(); + void get_flash_logs_from_hw_monitor(); - bool get_log(fw_logs::fw_logs_binary_data& binary_data, log_type type); - void get_logs_from_hw_monitor(log_type type); - - std::vector _input_code_for_fw_logs; - std::vector _input_code_for_flash_logs; std::shared_ptr _hw_monitor; - std::queue _fw_logs_queue; - std::queue _flash_logs_queue; - + std::queue _fw_logs; + std::vector _flash_logs; + bool _flash_logs_initialized; + int _flash_logs_index; + std::vector _input_code_for_fw_logs; + std::vector _input_code_for_flash_logs; }; } \ No newline at end of file diff --git a/src/realsense.def b/src/realsense.def index 617e35d835..baa64c8ebb 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -360,6 +360,7 @@ EXPORTS rs2_delete_firmware_log_message rs2_get_firmware_log rs2_get_flash_log + rs2_get_number_of_flash_logs rs2_firmware_log_message_severity rs2_firmware_log_message_timestamp rs2_firmware_log_message_data diff --git a/src/rs.cpp b/src/rs.cpp index 068336b985..5160882761 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -3019,7 +3019,7 @@ int rs2_get_number_of_flash_logs(rs2_device* dev, rs2_error** error) BEGIN_API_C auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); fw_logs::fw_logs_binary_data binary_data; - int number_of_flash_logs = fw_loggerable->get_number_of_flash_logs(binary_data); + int number_of_flash_logs = fw_loggerable->get_number_of_flash_logs(); return number_of_flash_logs; } From 25863282b841f1dd7e6ecbb45d24a1a459269625 Mon Sep 17 00:00:00 2001 From: remibettan Date: Tue, 2 Jun 2020 12:17:54 +0300 Subject: [PATCH 15/61] Parser made member of fw_logger, need to solve case for parsing without init --- examples/firmware-logs/rs-firmware-logs.cpp | 12 +- include/librealsense2/h/rs_device.h | 20 +-- include/librealsense2/hpp/rs_device.hpp | 134 +++++++++----------- src/firmware_logger_device.cpp | 18 ++- src/firmware_logger_device.h | 8 ++ src/realsense.def | 3 +- src/rs.cpp | 29 ++--- 7 files changed, 109 insertions(+), 115 deletions(-) diff --git a/examples/firmware-logs/rs-firmware-logs.cpp b/examples/firmware-logs/rs-firmware-logs.cpp index bc4cb22c4a..1da5678c6d 100644 --- a/examples/firmware-logs/rs-firmware-logs.cpp +++ b/examples/firmware-logs/rs-firmware-logs.cpp @@ -68,9 +68,9 @@ int main(int argc, char * argv[]) while (hub.is_connected(dev)) { - auto fw_log = res.get_device().as(); - auto fw_log_message = fw_log.create_message(); - bool result = fw_log.get_firmware_log(fw_log_message); + auto fw_log_device = res.get_device().as(); + auto fw_log_message = fw_log_device.create_message(); + bool result = fw_log_device.get_firmware_log(fw_log_message); if (result) { std::vector fw_log_lines; @@ -84,10 +84,8 @@ int main(int argc, char * argv[]) ifstream f(xml_path); if (f.good()) { - unique_ptr parser = - unique_ptr(new rs2::firmware_log_parser(xml_path)); - - rs2::firmware_log_parsed_message parsed_log = parser->parse_firmware_log(fw_log_message); + bool parser_initialized = fw_log_device.init_parser(xml_path); + rs2::firmware_log_parsed_message parsed_log = fw_log_device.parse_log(fw_log_message); stringstream sstr; sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() << " " << parsed_log.thread_name() << " " << parsed_log.file_name() diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index 43f5cd0cfe..731120ca86 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -421,28 +421,22 @@ unsigned int rs2_firmware_log_message_timestamp(rs2_firmware_log_message* msg, r rs2_log_severity rs2_firmware_log_message_severity(const rs2_firmware_log_message* msg, rs2_error** error); /** -* \brief Creates RealSense firmware logs parser. +* \brief Initializes RealSense firmware logs parser in device. +* \param[in] dev Device from which the FW log will be taken * \param[in] xml_path path to xml file needed for parsing -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return firmware logs parser object -*/ -rs2_firmware_log_parser* rs2_create_firmware_log_parser(const char* xml_path, rs2_error** error); - -/** -* \brief Frees the relevant firmware logs parser object. -* \param[in] firmware logs parser object that is no longer needed +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return true for success, false for failure - failure happens if opening the xml from the xml_path input fails */ -void rs2_delete_firmware_log_parser(rs2_firmware_log_parser* parser); +int rs2_init_parser(rs2_device* dev, const char* xml_path, rs2_error** error); /** * \brief Gets RealSense firmware log parser -* \param[in] fw_logs_parser firmware log parser +* \param[in] dev Device from which the FW log will be taken * \param[in] fw_log_msg firmware log message to be parsed * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return firmware log parsed message */ -rs2_firmware_log_parsed_message* rs2_parse_firmware_log(rs2_firmware_log_parser* fw_logs_parser, - rs2_firmware_log_message* fw_log_msg, rs2_error** error); +rs2_firmware_log_parsed_message* rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_error** error); /** * Delete RealSense firmware log parsed message diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index 103a4fadc7..e07efbe4d7 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -408,6 +408,59 @@ namespace rs2 std::shared_ptr _fw_log_message; }; + class firmware_log_parsed_message + { + public: + explicit firmware_log_parsed_message(std::shared_ptr msg) : + _parsed_fw_log(msg) {} + + std::string message() const + { + rs2_error* e = nullptr; + std::string msg(rs2_get_fw_log_parsed_message(_parsed_fw_log.get(), &e)); + error::handle(e); + return msg; + } + std::string file_name() const + { + rs2_error* e = nullptr; + std::string file_name(rs2_get_fw_log_parsed_file_name(_parsed_fw_log.get(), &e)); + error::handle(e); + return file_name; + } + std::string thread_name() const + { + rs2_error* e = nullptr; + std::string thread_name(rs2_get_fw_log_parsed_thread_name(_parsed_fw_log.get(), &e)); + error::handle(e); + return thread_name; + } + std::string severity() const + { + rs2_error* e = nullptr; + rs2_log_severity sev = rs2_get_fw_log_parsed_severity(_parsed_fw_log.get(), &e); + error::handle(e); + return std::string(rs2_log_severity_to_string(sev)); + } + uint32_t line() const + { + rs2_error* e = nullptr; + uint32_t line(rs2_get_fw_log_parsed_line(_parsed_fw_log.get(), &e)); + error::handle(e); + return line; + } + uint32_t timestamp() const + { + rs2_error* e = nullptr; + uint32_t timestamp(rs2_get_fw_log_parsed_timestamp(_parsed_fw_log.get(), &e)); + error::handle(e); + return timestamp; + } + + private: + std::shared_ptr _parsed_fw_log; + }; + class firmware_logger : public device { public: @@ -467,98 +520,31 @@ namespace rs2 return number_of_flash_logs; } - }; - class firmware_log_parsed_message - { - public: - explicit firmware_log_parsed_message(std::shared_ptr msg) : - _parsed_fw_log(msg) {} - - std::string message() const - { - rs2_error* e = nullptr; - std::string msg(rs2_get_fw_log_parsed_message(_parsed_fw_log.get(), &e)); - error::handle(e); - return msg; - } - std::string file_name() const - { - rs2_error* e = nullptr; - std::string file_name(rs2_get_fw_log_parsed_file_name(_parsed_fw_log.get(), &e)); - error::handle(e); - return file_name; - } - std::string thread_name() const - { - rs2_error* e = nullptr; - std::string thread_name(rs2_get_fw_log_parsed_thread_name(_parsed_fw_log.get(), &e)); - error::handle(e); - return thread_name; - } - std::string severity() const - { - rs2_error* e = nullptr; - rs2_log_severity sev = rs2_get_fw_log_parsed_severity(_parsed_fw_log.get(), &e); - error::handle(e); - return std::string(rs2_log_severity_to_string(sev)); - } - uint32_t line() const + bool init_parser(const std::string& xml_path) { rs2_error* e = nullptr; - uint32_t line(rs2_get_fw_log_parsed_line(_parsed_fw_log.get(), &e)); - error::handle(e); - return line; - } - uint32_t timestamp() const - { - rs2_error* e = nullptr; - uint32_t timestamp(rs2_get_fw_log_parsed_timestamp(_parsed_fw_log.get(), &e)); - error::handle(e); - return timestamp; - } - - private: - std::shared_ptr _parsed_fw_log; - }; - - class firmware_log_parser - { - public: - firmware_log_parser(std::string xml_path) - { - rs2_error* e = nullptr; - _firmware_log_parser = std::shared_ptr( - rs2_create_firmware_log_parser(xml_path.data(), &e), - rs2_delete_firmware_log_parser); + bool parser_initialized = rs2_init_parser(_dev.get(), xml_path.c_str(), &e); error::handle(e); + + return parser_initialized; } - rs2::firmware_log_parsed_message parse_firmware_log(const rs2::firmware_log_message& msg) + rs2::firmware_log_parsed_message parse_log(const rs2::firmware_log_message& msg) { rs2_error* e = nullptr; - auto size = rs2_firmware_log_message_size(msg.get_message().get(), &e); - error::handle(e); - std::shared_ptr parsed_msg( - rs2_parse_firmware_log(_firmware_log_parser.get(), msg.get_message().get(), &e), + rs2_parse_firmware_log(_dev.get(), msg.get_message().get(), &e), rs2_delete_firmware_log_parsed_message); error::handle(e); return firmware_log_parsed_message(parsed_msg); } - - firmware_log_parser(std::shared_ptr fw_log_parser) - : _firmware_log_parser(fw_log_parser) {} - - explicit operator std::shared_ptr() { return _firmware_log_parser; }; - - protected: - std::shared_ptr _firmware_log_parser; }; + class auto_calibrated_device : public calibrated_device { public: diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index f28d057f45..997b1a9fbf 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -12,7 +12,8 @@ namespace librealsense _fw_logs(), _flash_logs(), _flash_logs_initialized(false), - _flash_logs_index(0) + _flash_logs_index(0), + _parser(nullptr) { auto op_code = static_cast(std::stoi(camera_op_code.c_str())); _input_code_for_fw_logs = { 0x14, 0x00, 0xab, 0xcd, op_code, 0x00, 0x00, 0x00, @@ -133,4 +134,19 @@ namespace librealsense } return _flash_logs.size(); } + + bool firmware_logger_device::init_parser(std::string xml_full_file_path) + { + _parser = new fw_logs::fw_logs_parser(xml_full_file_path); + + return (_parser != nullptr); + } + + fw_logs::fw_log_data firmware_logger_device::parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg) + { + fw_logs::fw_log_data log_data; + if(_parser) + log_data = _parser->parse_fw_log(fw_log_msg); + return log_data; + } } \ No newline at end of file diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index 12f54c7de2..4fb59f33fa 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -7,6 +7,7 @@ #include "device.h" #include #include "fw-logs/fw-log-data.h" +#include "fw-logs/fw-logs-parser.h" namespace librealsense { @@ -15,6 +16,8 @@ namespace librealsense public: virtual bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) = 0; virtual bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) = 0; + virtual bool init_parser(std::string xml_full_file_path) = 0; + virtual fw_logs::fw_log_data parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg) = 0; virtual size_t get_number_of_flash_logs() = 0; virtual ~firmware_logger_extensions() = default; }; @@ -30,6 +33,9 @@ namespace librealsense bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) override; bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) override; + bool init_parser(std::string xml_full_file_path) override; + fw_logs::fw_log_data parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg) override; + size_t get_number_of_flash_logs() override; private: @@ -46,6 +52,8 @@ namespace librealsense std::vector _input_code_for_fw_logs; std::vector _input_code_for_flash_logs; + + fw_logs::fw_logs_parser* _parser; }; } \ No newline at end of file diff --git a/src/realsense.def b/src/realsense.def index baa64c8ebb..bd7ae915a1 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -365,8 +365,7 @@ EXPORTS rs2_firmware_log_message_timestamp rs2_firmware_log_message_data rs2_firmware_log_message_size - rs2_create_firmware_log_parser - rs2_delete_firmware_log_parser + rs2_init_parser rs2_parse_firmware_log rs2_delete_firmware_log_parsed_message rs2_get_fw_log_parsed_message diff --git a/src/rs.cpp b/src/rs.cpp index 5160882761..e37fa7e22a 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -132,10 +132,6 @@ struct rs2_firmware_log_parsed_message std::shared_ptr firmware_log_parsed; }; -struct rs2_firmware_log_parser -{ - std::shared_ptr firmware_log_parser; -}; struct rs2_error { @@ -3074,32 +3070,29 @@ unsigned int rs2_firmware_log_message_timestamp(rs2_firmware_log_message* msg, r } HANDLE_EXCEPTIONS_AND_RETURN(0, msg) -rs2_firmware_log_parser* rs2_create_firmware_log_parser(const char* xml_path, rs2_error** error) BEGIN_API_CALL +int rs2_init_parser(rs2_device* dev, const char* xml_path ,rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(xml_path); + + auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); - return new rs2_firmware_log_parser{ std::make_shared(xml_path)}; -} -HANDLE_EXCEPTIONS_AND_RETURN(nullptr, xml_path) - -void rs2_delete_firmware_log_parser(rs2_firmware_log_parser* parser) BEGIN_API_CALL -{ - VALIDATE_NOT_NULL(parser); - delete parser; + return (fw_loggerable->init_parser(xml_path)) ? 1 : 0; } -NOEXCEPT_RETURN(, parser) +HANDLE_EXCEPTIONS_AND_RETURN(0, xml_path) -rs2_firmware_log_parsed_message* rs2_parse_firmware_log(rs2_firmware_log_parser* fw_log_parser, rs2_firmware_log_message* fw_log_msg, rs2_error** error) BEGIN_API_CALL +rs2_firmware_log_parsed_message* rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_error** error) BEGIN_API_CALL { - VALIDATE_NOT_NULL(fw_log_parser); + VALIDATE_NOT_NULL(dev); VALIDATE_NOT_NULL(fw_log_msg); + auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + librealsense::fw_logs::fw_log_data log_data = - fw_log_parser->firmware_log_parser.get()->parse_fw_log(fw_log_msg->firmware_log_binary_data.get()); + fw_loggerable->parse_log(fw_log_msg->firmware_log_binary_data.get()); return new rs2_firmware_log_parsed_message{ std::make_shared(log_data) }; } -HANDLE_EXCEPTIONS_AND_RETURN(nullptr, fw_log_msg) +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev, fw_log_msg) void rs2_delete_firmware_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg) BEGIN_API_CALL { From c2f47de1b182bbe5080f0b211fed7f03637e5af9 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 3 Jun 2020 09:01:51 +0300 Subject: [PATCH 16/61] rs-fw-logger tool using new API --- examples/CMakeLists.txt | 1 - examples/firmware-logs/rs-firmware-logs.cpp | 43 +++++----- tools/fw-logger/CMakeLists.txt | 11 +-- tools/fw-logger/rs-fw-logger.cpp | 87 ++++++++++----------- 4 files changed, 65 insertions(+), 77 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 8f1a688f36..59e516c697 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -47,5 +47,4 @@ add_subdirectory(ar-basic) add_subdirectory(ar-advanced) add_subdirectory(pose-apriltag) add_subdirectory(tracking-and-depth) -add_subdirectory(firmware-logs) add_subdirectory(flash-logs) diff --git a/examples/firmware-logs/rs-firmware-logs.cpp b/examples/firmware-logs/rs-firmware-logs.cpp index 1da5678c6d..50c2bb6cbe 100644 --- a/examples/firmware-logs/rs-firmware-logs.cpp +++ b/examples/firmware-logs/rs-firmware-logs.cpp @@ -66,34 +66,37 @@ int main(int argc, char * argv[]) setvbuf(stdout, NULL, _IONBF, 0); // unbuffering stdout + auto fw_log_device = res.get_device().as(); + + bool using_parser = false; + std::string xml_path("C:\\Users\\rbettan\\Documents\\Dev\\RefFolder\\HWLoggerEventsDS5.xml"); + if (!xml_path.empty()) + { + ifstream f(xml_path); + if (f.good()) + { + bool parser_initialized = fw_log_device.init_parser(xml_path); + if (parser_initialized) + using_parser = true; + } + } + while (hub.is_connected(dev)) { - auto fw_log_device = res.get_device().as(); auto fw_log_message = fw_log_device.create_message(); bool result = fw_log_device.get_firmware_log(fw_log_message); if (result) { std::vector fw_log_lines; - - static bool usingParser = true; - if (usingParser) + if (using_parser) { - std::string xml_path("HWLoggerEventsDS5.xml"); - if (!xml_path.empty()) - { - ifstream f(xml_path); - if (f.good()) - { - bool parser_initialized = fw_log_device.init_parser(xml_path); - rs2::firmware_log_parsed_message parsed_log = fw_log_device.parse_log(fw_log_message); - stringstream sstr; - sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() - << " " << parsed_log.thread_name() << " " << parsed_log.file_name() - << " " << parsed_log.line(); - - fw_log_lines.push_back(sstr.str()); - } - } + rs2::firmware_log_parsed_message parsed_log = fw_log_device.parse_log(fw_log_message); + stringstream sstr; + sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() + << " " << parsed_log.thread_name() << " " << parsed_log.file_name() + << " " << parsed_log.line(); + + fw_log_lines.push_back(sstr.str()); } else { diff --git a/tools/fw-logger/CMakeLists.txt b/tools/fw-logger/CMakeLists.txt index 77dc526328..094c2645c2 100644 --- a/tools/fw-logger/CMakeLists.txt +++ b/tools/fw-logger/CMakeLists.txt @@ -5,16 +5,7 @@ cmake_minimum_required(VERSION 3.1.0) project(RealsenseToolsFirmwareLogger) -add_executable(rs-fw-logger rs-fw-logger.cpp fw-log-data.cpp - fw-log-data.h - fw-logs-formating-options.cpp - fw-logs-formating-options.h - fw-logs-parser.cpp - fw-logs-parser.h - fw-logs-xml-helper.cpp - fw-logs-xml-helper.h - string-formatter.cpp - string-formatter.h) +add_executable(rs-fw-logger rs-fw-logger.cpp fw-log-data.cpp) set_property(TARGET rs-fw-logger PROPERTY CXX_STANDARD 11) if(WIN32 OR ANDROID) target_link_libraries(rs-fw-logger ${DEPENDENCIES}) diff --git a/tools/fw-logger/rs-fw-logger.cpp b/tools/fw-logger/rs-fw-logger.cpp index 432b26dcd0..ed5afbfa0b 100644 --- a/tools/fw-logger/rs-fw-logger.cpp +++ b/tools/fw-logger/rs-fw-logger.cpp @@ -5,13 +5,11 @@ #include #include #include "tclap/CmdLine.h" -#include "fw-logs-parser.h" using namespace std; using namespace TCLAP; -using namespace fw_logger; using namespace rs2; string char2hex(unsigned char n) @@ -53,20 +51,9 @@ int main(int argc, char* argv[]) cmd.parse(argc, argv); log_to_file(RS2_LOG_SEVERITY_WARN, "librealsense.log"); - // Obtain a list of devices currently present on the system - unique_ptr fw_log_parser; auto use_xml_file = false; auto xml_full_file_path = xml_arg.getValue(); - if (!xml_full_file_path.empty()) - { - ifstream f(xml_full_file_path); - if (f.good()) - { - fw_log_parser = unique_ptr(new fw_logs_parser(xml_full_file_path)); - use_xml_file = true; - } - } context ctx; device_hub hub(ctx); @@ -79,47 +66,55 @@ int main(int argc, char* argv[]) auto dev = hub.wait_for_device(); cout << "RealSense device was connected...\n"; - vector input; - auto str_op_code = dev.get_info(RS2_CAMERA_INFO_DEBUG_OP_CODE); - auto op_code = static_cast(stoi(str_op_code)); - input = {0x14, 0x00, 0xab, 0xcd, op_code, 0x00, 0x00, 0x00, - 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - cout << "Device Name: " << dev.get_info(RS2_CAMERA_INFO_NAME) << endl << - "Device Location: " << dev.get_info(RS2_CAMERA_INFO_PHYSICAL_PORT) << endl << endl; - setvbuf(stdout, NULL, _IONBF, 0); // unbuffering stdout - while (hub.is_connected(dev)) - { - this_thread::sleep_for(chrono::milliseconds(100)); - - auto raw_data = dev.as().send_and_receive_raw_data(input); - vector fw_log_lines = {""}; - if (raw_data.size() <= 4) - continue; + auto fw_log_device = dev.as(); - if (use_xml_file) + bool using_parser = false; + if (!xml_full_file_path.empty()) + { + ifstream f(xml_full_file_path); + if (f.good()) { - fw_logs_binary_data fw_logs_binary_data = {raw_data}; - fw_logs_binary_data.logs_buffer.erase(fw_logs_binary_data.logs_buffer.begin(),fw_logs_binary_data.logs_buffer.begin()+4); - fw_log_lines = fw_log_parser->get_fw_log_lines(fw_logs_binary_data); - for (auto& elem : fw_log_lines) - elem = datetime_string() + " " + elem; + bool parser_initialized = fw_log_device.init_parser(xml_full_file_path); + if (parser_initialized) + using_parser = true; } - else + } + + while (hub.is_connected(dev)) + { + auto fw_log_message = fw_log_device.create_message(); + bool result = fw_log_device.get_firmware_log(fw_log_message); + if (result) { - stringstream sstr; - sstr << datetime_string() << " FW_Log_Data:"; - for (size_t i = 0; i < raw_data.size(); ++i) + std::vector fw_log_lines; + if (using_parser) + { + rs2::firmware_log_parsed_message parsed_log = fw_log_device.parse_log(fw_log_message); + stringstream sstr; + sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() + << " " << parsed_log.thread_name() << " " << parsed_log.file_name() + << " " << parsed_log.line(); + + fw_log_lines.push_back(sstr.str()); + } + else + { + stringstream sstr; + sstr << fw_log_message.get_timestamp(); + sstr << " " << fw_log_message.get_severity_str(); + sstr << " FW_Log_Data:"; + std::vector msg_data = fw_log_message.data(); + for (int i = 0; i < msg_data.size(); ++i) + { sstr << char2hex(raw_data[i]) << " "; - - fw_log_lines.push_back(sstr.str()); + } + fw_log_lines.push_back(sstr.str()); + } + for (auto& line : fw_log_lines) + cout << line << endl; } - - for (auto& line : fw_log_lines) - cout << line << endl; } } catch (const error & e) From 91e53b51e74ca486c27551e9b2c4c7d4f5b41107 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 3 Jun 2020 12:01:11 +0300 Subject: [PATCH 17/61] fw logs api functions moved to dedicated header files --- include/CMakeLists.txt | 6 +- include/librealsense2/h/rs_device.h | 139 ----------- include/librealsense2/h/rs_firmware_logs.h | 160 ++++++++++++ include/librealsense2/hpp/rs_device.hpp | 233 ------------------ .../librealsense2/hpp/rs_firmware_logs.hpp | 204 +++++++++++++++ include/librealsense2/rs.h | 1 + include/librealsense2/rs.hpp | 1 + src/rs.cpp | 1 - tools/fw-logger/CMakeLists.txt | 2 +- 9 files changed, 371 insertions(+), 376 deletions(-) create mode 100644 include/librealsense2/h/rs_firmware_logs.h create mode 100644 include/librealsense2/hpp/rs_firmware_logs.hpp diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 9ace5a5d02..46fcaed190 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -16,7 +16,8 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_internal.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_pipeline.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_config.h" - "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_terminal_parser.h" + "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_firmware_logs.h" + "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_terminal_parser.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_types.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_context.hpp" @@ -30,7 +31,8 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_options.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_internal.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_pipeline.hpp" - "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_terminal_parser.hpp" + "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_firmware_logs.hpp" + "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_terminal_parser.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/rsutil.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/rs_advanced_mode.h" diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index 731120ca86..43ba91b8d3 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -353,145 +353,6 @@ rs2_raw_data_buffer* rs2_serialize_json(rs2_device* dev, rs2_error** error); /* Load JSON and apply advanced-mode controls */ void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_size, rs2_error** error); -/** -* \brief Creates RealSense firmware log message. -* \param[in] dev Device from which the FW log will be taken using the created message -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return pointer to created empty firmware log message -*/ -rs2_firmware_log_message* rs2_create_firmware_log_message(rs2_device* dev, rs2_error** error); - -/** -* \brief Gets RealSense firmware log. -* \param[in] dev Device from which the FW log should be taken -* \param[in] fw_log_msg Firmware log message object to be filled -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor -*/ -int rs2_get_firmware_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); - -int rs2_get_number_of_flash_logs(rs2_device* dev, rs2_error** error); - -/** -* \brief Gets RealSense flash log - this is a fw log that has been written in the device during the previous shutdown of the device -* \param[in] dev Device from which the FW log should be taken -* \param[in] fw_log_msg Firmware log message object to be filled -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor -*/ -int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); - -/** -* Delete RealSense firmware log message -* \param[in] device Realsense firmware log message to delete -*/ -void rs2_delete_firmware_log_message(rs2_firmware_log_message* msg); - -/** -* \brief Gets RealSense firmware log message data. -* \param[in] msg firmware log message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return pointer to start of the firmware log message data -*/ -const unsigned char* rs2_firmware_log_message_data(rs2_firmware_log_message* msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log message size. -* \param[in] msg firmware log message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return size of the firmware log message data -*/ -int rs2_firmware_log_message_size(rs2_firmware_log_message* msg, rs2_error** error); - - -/** -* \brief Gets RealSense firmware log message timestamp. -* \param[in] msg firmware log message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return timestamp of the firmware log message -*/ -unsigned int rs2_firmware_log_message_timestamp(rs2_firmware_log_message* msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log message severity. -* \param[in] msg firmware log message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return severity of the firmware log message data -*/ -rs2_log_severity rs2_firmware_log_message_severity(const rs2_firmware_log_message* msg, rs2_error** error); - -/** -* \brief Initializes RealSense firmware logs parser in device. -* \param[in] dev Device from which the FW log will be taken -* \param[in] xml_path path to xml file needed for parsing -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return true for success, false for failure - failure happens if opening the xml from the xml_path input fails -*/ -int rs2_init_parser(rs2_device* dev, const char* xml_path, rs2_error** error); - -/** -* \brief Gets RealSense firmware log parser -* \param[in] dev Device from which the FW log will be taken -* \param[in] fw_log_msg firmware log message to be parsed -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return firmware log parsed message -*/ -rs2_firmware_log_parsed_message* rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_error** error); - -/** -* Delete RealSense firmware log parsed message -* \param[in] device Realsense firmware log parsed message to delete -*/ -void rs2_delete_firmware_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); - -/** -* \brief Gets RealSense firmware log parsed message message. -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return message of the firmware log parsed message -*/ -const char* rs2_get_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log parsed message file name. -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return file name of the firmware log parsed message -*/ -const char* rs2_get_fw_log_parsed_file_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log parsed message thread name. -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return thread name of the firmware log parsed message -*/ -const char* rs2_get_fw_log_parsed_thread_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log parsed message severity. -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return severity of the firmware log parsed message -*/ -rs2_log_severity rs2_get_fw_log_parsed_severity(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log parsed message relevant line (in the file that is returned by rs2_get_fw_log_parsed_file_name). -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return line number of the firmware log parsed message -*/ -unsigned int rs2_get_fw_log_parsed_line(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log parsed message timestamp -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return timestamp of the firmware log parsed message -*/ -unsigned int rs2_get_fw_log_parsed_timestamp(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - #ifdef __cplusplus } #endif diff --git a/include/librealsense2/h/rs_firmware_logs.h b/include/librealsense2/h/rs_firmware_logs.h new file mode 100644 index 0000000000..79dbe72333 --- /dev/null +++ b/include/librealsense2/h/rs_firmware_logs.h @@ -0,0 +1,160 @@ +/* License: Apache 2.0. See LICENSE file in root directory. + Copyright(c) 2020 Intel Corporation. All Rights Reserved. */ + +/** \file rs_firmware_logs.h +* \brief Exposes RealSense firmware logs functionality for C compilers +*/ + + +#ifndef LIBREALSENSE_RS2_FIRMWARE_LOGS_H +#define LIBREALSENSE_RS2_FIRMWARE_LOGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "rs_types.h" + +/** +* \brief Creates RealSense firmware log message. +* \param[in] dev Device from which the FW log will be taken using the created message +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return pointer to created empty firmware log message +*/ +rs2_firmware_log_message* rs2_create_firmware_log_message(rs2_device* dev, rs2_error** error); + +/** +* \brief Gets RealSense firmware log. +* \param[in] dev Device from which the FW log should be taken +* \param[in] fw_log_msg Firmware log message object to be filled +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor +*/ +int rs2_get_firmware_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); + +int rs2_get_number_of_flash_logs(rs2_device* dev, rs2_error** error); + +/** +* \brief Gets RealSense flash log - this is a fw log that has been written in the device during the previous shutdown of the device +* \param[in] dev Device from which the FW log should be taken +* \param[in] fw_log_msg Firmware log message object to be filled +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor +*/ +int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); + +/** +* Delete RealSense firmware log message +* \param[in] device Realsense firmware log message to delete +*/ +void rs2_delete_firmware_log_message(rs2_firmware_log_message* msg); + +/** +* \brief Gets RealSense firmware log message data. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return pointer to start of the firmware log message data +*/ +const unsigned char* rs2_firmware_log_message_data(rs2_firmware_log_message* msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log message size. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return size of the firmware log message data +*/ +int rs2_firmware_log_message_size(rs2_firmware_log_message* msg, rs2_error** error); + + +/** +* \brief Gets RealSense firmware log message timestamp. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return timestamp of the firmware log message +*/ +unsigned int rs2_firmware_log_message_timestamp(rs2_firmware_log_message* msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log message severity. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return severity of the firmware log message data +*/ +rs2_log_severity rs2_firmware_log_message_severity(const rs2_firmware_log_message* msg, rs2_error** error); + +/** +* \brief Initializes RealSense firmware logs parser in device. +* \param[in] dev Device from which the FW log will be taken +* \param[in] xml_path path to xml file needed for parsing +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return true for success, false for failure - failure happens if opening the xml from the xml_path input fails +*/ +int rs2_init_parser(rs2_device* dev, const char* xml_path, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parser +* \param[in] dev Device from which the FW log will be taken +* \param[in] fw_log_msg firmware log message to be parsed +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return firmware log parsed message +*/ +rs2_firmware_log_parsed_message* rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_error** error); + +/** +* Delete RealSense firmware log parsed message +* \param[in] device Realsense firmware log parsed message to delete +*/ +void rs2_delete_firmware_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); + +/** +* \brief Gets RealSense firmware log parsed message message. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return message of the firmware log parsed message +*/ +const char* rs2_get_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message file name. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return file name of the firmware log parsed message +*/ +const char* rs2_get_fw_log_parsed_file_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message thread name. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return thread name of the firmware log parsed message +*/ +const char* rs2_get_fw_log_parsed_thread_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message severity. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return severity of the firmware log parsed message +*/ +rs2_log_severity rs2_get_fw_log_parsed_severity(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message relevant line (in the file that is returned by rs2_get_fw_log_parsed_file_name). +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return line number of the firmware log parsed message +*/ +unsigned int rs2_get_fw_log_parsed_line(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message timestamp +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return timestamp of the firmware log parsed message +*/ +unsigned int rs2_get_fw_log_parsed_timestamp(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index e07efbe4d7..bab9808827 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -312,239 +312,6 @@ namespace rs2 } }; - class firmware_logs_helper - { - public: - static uint32_t build_uint32_from4_uint8(const uint8_t* start) - { - uint8_t first = *(start); - uint8_t second = (*(start + 1)); - uint8_t third = (*(start + 2)); - uint8_t fourth = (*(start + 3)); - uint32_t res = first; - res += static_cast(second << 8); - res += static_cast(third << 16); - res += static_cast(fourth << 24); - return res; - } - - static double build_double_from8_uint8(const uint8_t* start) - { - uint64_t resInInt = build_uint64_from8_uint8(start); - double res = *reinterpret_cast(&resInInt); - return res; - } - - static uint64_t build_uint64_from8_uint8(const uint8_t* start) - { - uint32_t first = build_uint32_from4_uint8(start); - start += 4; - uint32_t second = build_uint32_from4_uint8(start); - uint64_t res = first; - res += static_cast(second << 32); - - return res; - } - - static std::string build_string_from_uint8_and_size(const uint8_t* start, uint8_t size) - { - std::string res; - res.insert(res.begin(), start, start + size); - return res; - } - }; - - - class firmware_log_message - { - public: - explicit firmware_log_message(std::shared_ptr msg): - _fw_log_message(msg){} - - rs2_log_severity get_severity() const { - rs2_error* e = nullptr; - rs2_log_severity severity = rs2_firmware_log_message_severity(_fw_log_message.get(), &e); - error::handle(e); - return severity; - } - std::string get_severity_str() const { - return rs2_log_severity_to_string(get_severity()); - } - - uint32_t get_timestamp() const - { - rs2_error* e = nullptr; - uint32_t timestamp = rs2_firmware_log_message_timestamp(_fw_log_message.get(), &e); - error::handle(e); - return timestamp; - } - - int size() const - { - rs2_error* e = nullptr; - int size = rs2_firmware_log_message_size(_fw_log_message.get(), &e); - error::handle(e); - return size; - } - - std::vector data() const - { - rs2_error* e = nullptr; - auto size = rs2_firmware_log_message_size(_fw_log_message.get(), &e); - error::handle(e); - std::vector result; - if (size > 0) - { - auto start = rs2_firmware_log_message_data(_fw_log_message.get(), &e); - error::handle(e); - result.insert(result.begin(), start, start + size); - } - return result; - } - - const std::shared_ptr get_message() const { return _fw_log_message; } - - private: - std::shared_ptr _fw_log_message; - }; - - class firmware_log_parsed_message - { - public: - explicit firmware_log_parsed_message(std::shared_ptr msg) : - _parsed_fw_log(msg) {} - - std::string message() const - { - rs2_error* e = nullptr; - std::string msg(rs2_get_fw_log_parsed_message(_parsed_fw_log.get(), &e)); - error::handle(e); - return msg; - } - std::string file_name() const - { - rs2_error* e = nullptr; - std::string file_name(rs2_get_fw_log_parsed_file_name(_parsed_fw_log.get(), &e)); - error::handle(e); - return file_name; - } - std::string thread_name() const - { - rs2_error* e = nullptr; - std::string thread_name(rs2_get_fw_log_parsed_thread_name(_parsed_fw_log.get(), &e)); - error::handle(e); - return thread_name; - } - std::string severity() const - { - rs2_error* e = nullptr; - rs2_log_severity sev = rs2_get_fw_log_parsed_severity(_parsed_fw_log.get(), &e); - error::handle(e); - return std::string(rs2_log_severity_to_string(sev)); - } - uint32_t line() const - { - rs2_error* e = nullptr; - uint32_t line(rs2_get_fw_log_parsed_line(_parsed_fw_log.get(), &e)); - error::handle(e); - return line; - } - uint32_t timestamp() const - { - rs2_error* e = nullptr; - uint32_t timestamp(rs2_get_fw_log_parsed_timestamp(_parsed_fw_log.get(), &e)); - error::handle(e); - return timestamp; - } - - private: - std::shared_ptr _parsed_fw_log; - }; - - class firmware_logger : public device - { - public: - firmware_logger(device d) - : device(d.get()) - { - rs2_error* e = nullptr; - if (rs2_is_device_extendable_to(_dev.get(), RS2_EXTENSION_FW_LOGGER, &e) == 0 && !e) - { - _dev.reset(); - } - error::handle(e); - } - - rs2::firmware_log_message create_message() - { - rs2_error* e = nullptr; - std::shared_ptr msg( - rs2_create_firmware_log_message(_dev.get(), &e), - rs2_delete_firmware_log_message); - error::handle(e); - - return firmware_log_message(msg); - } - - bool get_firmware_log(rs2::firmware_log_message& msg) const - { - rs2_error* e = nullptr; - rs2_firmware_log_message* m = msg.get_message().get(); - bool fw_log_pulling_status = - rs2_get_firmware_log(_dev.get(), &(m), &e); - - error::handle(e); - - return fw_log_pulling_status; - } - - bool get_flash_log(rs2::firmware_log_message& msg) const - { - rs2_error* e = nullptr; - rs2_firmware_log_message* m = msg.get_message().get(); - bool flash_log_pulling_status = - rs2_get_flash_log(_dev.get(), &(m), &e); - - error::handle(e); - - return flash_log_pulling_status; - } - - int get_number_of_flash_logs() const - { - rs2_error* e = nullptr; - int number_of_flash_logs = - rs2_get_number_of_flash_logs(_dev.get(), &e); - - error::handle(e); - - return number_of_flash_logs; - } - - bool init_parser(const std::string& xml_path) - { - rs2_error* e = nullptr; - - bool parser_initialized = rs2_init_parser(_dev.get(), xml_path.c_str(), &e); - error::handle(e); - - return parser_initialized; - } - - rs2::firmware_log_parsed_message parse_log(const rs2::firmware_log_message& msg) - { - rs2_error* e = nullptr; - - std::shared_ptr parsed_msg( - rs2_parse_firmware_log(_dev.get(), msg.get_message().get(), &e), - rs2_delete_firmware_log_parsed_message); - error::handle(e); - - return firmware_log_parsed_message(parsed_msg); - } - }; - - class auto_calibrated_device : public calibrated_device { public: diff --git a/include/librealsense2/hpp/rs_firmware_logs.hpp b/include/librealsense2/hpp/rs_firmware_logs.hpp new file mode 100644 index 0000000000..9e34bd6dbd --- /dev/null +++ b/include/librealsense2/hpp/rs_firmware_logs.hpp @@ -0,0 +1,204 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +#ifndef LIBREALSENSE_RS2_FIRMWARE_LOGS_HPP +#define LIBREALSENSE_RS2_FIRMWARE_LOGS_HPP + +#include "rs_types.hpp" +#include "rs_sensor.hpp" +#include "../h/rs_firmware_logs.h" +#include + +namespace rs2 +{ + class firmware_log_message + { + public: + explicit firmware_log_message(std::shared_ptr msg): + _fw_log_message(msg){} + + rs2_log_severity get_severity() const { + rs2_error* e = nullptr; + rs2_log_severity severity = rs2_firmware_log_message_severity(_fw_log_message.get(), &e); + error::handle(e); + return severity; + } + std::string get_severity_str() const { + return rs2_log_severity_to_string(get_severity()); + } + + uint32_t get_timestamp() const + { + rs2_error* e = nullptr; + uint32_t timestamp = rs2_firmware_log_message_timestamp(_fw_log_message.get(), &e); + error::handle(e); + return timestamp; + } + + int size() const + { + rs2_error* e = nullptr; + int size = rs2_firmware_log_message_size(_fw_log_message.get(), &e); + error::handle(e); + return size; + } + + std::vector data() const + { + rs2_error* e = nullptr; + auto size = rs2_firmware_log_message_size(_fw_log_message.get(), &e); + error::handle(e); + std::vector result; + if (size > 0) + { + auto start = rs2_firmware_log_message_data(_fw_log_message.get(), &e); + error::handle(e); + result.insert(result.begin(), start, start + size); + } + return result; + } + + const std::shared_ptr get_message() const { return _fw_log_message; } + + private: + std::shared_ptr _fw_log_message; + }; + + class firmware_log_parsed_message + { + public: + explicit firmware_log_parsed_message(std::shared_ptr msg) : + _parsed_fw_log(msg) {} + + std::string message() const + { + rs2_error* e = nullptr; + std::string msg(rs2_get_fw_log_parsed_message(_parsed_fw_log.get(), &e)); + error::handle(e); + return msg; + } + std::string file_name() const + { + rs2_error* e = nullptr; + std::string file_name(rs2_get_fw_log_parsed_file_name(_parsed_fw_log.get(), &e)); + error::handle(e); + return file_name; + } + std::string thread_name() const + { + rs2_error* e = nullptr; + std::string thread_name(rs2_get_fw_log_parsed_thread_name(_parsed_fw_log.get(), &e)); + error::handle(e); + return thread_name; + } + std::string severity() const + { + rs2_error* e = nullptr; + rs2_log_severity sev = rs2_get_fw_log_parsed_severity(_parsed_fw_log.get(), &e); + error::handle(e); + return std::string(rs2_log_severity_to_string(sev)); + } + uint32_t line() const + { + rs2_error* e = nullptr; + uint32_t line(rs2_get_fw_log_parsed_line(_parsed_fw_log.get(), &e)); + error::handle(e); + return line; + } + uint32_t timestamp() const + { + rs2_error* e = nullptr; + uint32_t timestamp(rs2_get_fw_log_parsed_timestamp(_parsed_fw_log.get(), &e)); + error::handle(e); + return timestamp; + } + + private: + std::shared_ptr _parsed_fw_log; + }; + + class firmware_logger : public device + { + public: + firmware_logger(device d) + : device(d.get()) + { + rs2_error* e = nullptr; + if (rs2_is_device_extendable_to(_dev.get(), RS2_EXTENSION_FW_LOGGER, &e) == 0 && !e) + { + _dev.reset(); + } + error::handle(e); + } + + rs2::firmware_log_message create_message() + { + rs2_error* e = nullptr; + std::shared_ptr msg( + rs2_create_firmware_log_message(_dev.get(), &e), + rs2_delete_firmware_log_message); + error::handle(e); + + return firmware_log_message(msg); + } + + bool get_firmware_log(rs2::firmware_log_message& msg) const + { + rs2_error* e = nullptr; + rs2_firmware_log_message* m = msg.get_message().get(); + bool fw_log_pulling_status = + rs2_get_firmware_log(_dev.get(), &(m), &e); + + error::handle(e); + + return fw_log_pulling_status; + } + + bool get_flash_log(rs2::firmware_log_message& msg) const + { + rs2_error* e = nullptr; + rs2_firmware_log_message* m = msg.get_message().get(); + bool flash_log_pulling_status = + rs2_get_flash_log(_dev.get(), &(m), &e); + + error::handle(e); + + return flash_log_pulling_status; + } + + int get_number_of_flash_logs() const + { + rs2_error* e = nullptr; + int number_of_flash_logs = + rs2_get_number_of_flash_logs(_dev.get(), &e); + + error::handle(e); + + return number_of_flash_logs; + } + + bool init_parser(const std::string& xml_path) + { + rs2_error* e = nullptr; + + bool parser_initialized = rs2_init_parser(_dev.get(), xml_path.c_str(), &e); + error::handle(e); + + return parser_initialized; + } + + rs2::firmware_log_parsed_message parse_log(const rs2::firmware_log_message& msg) + { + rs2_error* e = nullptr; + + std::shared_ptr parsed_msg( + rs2_parse_firmware_log(_dev.get(), msg.get_message().get(), &e), + rs2_delete_firmware_log_parsed_message); + error::handle(e); + + return firmware_log_parsed_message(parsed_msg); + } + }; + +} +#endif // LIBREALSENSE_RS2_FIRMWARE_LOGS_HPP diff --git a/include/librealsense2/rs.h b/include/librealsense2/rs.h index f43e816461..dfb29974d8 100644 --- a/include/librealsense2/rs.h +++ b/include/librealsense2/rs.h @@ -21,6 +21,7 @@ extern "C" { #include "h/rs_processing.h" #include "h/rs_record_playback.h" #include "h/rs_sensor.h" +#include "h/rs_firmware_logs.h" #include "h/rs_terminal_parser.h" #define RS2_API_MAJOR_VERSION 2 diff --git a/include/librealsense2/rs.hpp b/include/librealsense2/rs.hpp index e23f167b76..b41366102d 100644 --- a/include/librealsense2/rs.hpp +++ b/include/librealsense2/rs.hpp @@ -13,6 +13,7 @@ #include "hpp/rs_record_playback.hpp" #include "hpp/rs_sensor.hpp" #include "hpp/rs_pipeline.hpp" +#include "hpp/rs_firmware_logs.hpp" #include "hpp/rs_terminal_parser.hpp" namespace rs2 diff --git a/src/rs.cpp b/src/rs.cpp index e37fa7e22a..b30aee0aca 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -43,7 +43,6 @@ #include "auto-calibrated-device.h" #include "terminal-parser.h" #include "firmware_logger_device.h" -#include "fw-logs/fw-logs-parser.h" //////////////////////// // API implementation // //////////////////////// diff --git a/tools/fw-logger/CMakeLists.txt b/tools/fw-logger/CMakeLists.txt index 094c2645c2..8a762ca87b 100644 --- a/tools/fw-logger/CMakeLists.txt +++ b/tools/fw-logger/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.1.0) project(RealsenseToolsFirmwareLogger) -add_executable(rs-fw-logger rs-fw-logger.cpp fw-log-data.cpp) +add_executable(rs-fw-logger rs-fw-logger.cpp) set_property(TARGET rs-fw-logger PROPERTY CXX_STANDARD 11) if(WIN32 OR ANDROID) target_link_libraries(rs-fw-logger ${DEPENDENCIES}) From 0a6982740f402d1e098fa38f26332ce25e1fb5d6 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 3 Jun 2020 12:46:36 +0300 Subject: [PATCH 18/61] parse_log api change so that boolean value would be returned --- include/librealsense2/h/rs_firmware_logs.h | 21 +++++++++++++++++-- .../librealsense2/hpp/rs_firmware_logs.hpp | 21 ++++++++++++++----- src/firmware_logger_device.cpp | 15 ++++++++----- src/firmware_logger_device.h | 4 ++-- src/realsense.def | 1 + src/rs.cpp | 21 ++++++++++++++----- tools/fw-logger/rs-fw-logger.cpp | 4 +++- 7 files changed, 67 insertions(+), 20 deletions(-) diff --git a/include/librealsense2/h/rs_firmware_logs.h b/include/librealsense2/h/rs_firmware_logs.h index 79dbe72333..184b81e996 100644 --- a/include/librealsense2/h/rs_firmware_logs.h +++ b/include/librealsense2/h/rs_firmware_logs.h @@ -91,14 +91,31 @@ rs2_log_severity rs2_firmware_log_message_severity(const rs2_firmware_log_messag */ int rs2_init_parser(rs2_device* dev, const char* xml_path, rs2_error** error); + +/** +* \brief Creates RealSense firmware log parsed message. +* \param[in] dev Device from which the FW log will be taken using the created message +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return pointer to created empty firmware log message +*/ +rs2_firmware_log_parsed_message* rs2_create_firmware_log_parsed_message(rs2_device* dev, rs2_error** error); + +/** +* \brief Deletes RealSense firmware log parsed message. +* \param[in] msg message to be deleted +*/ +void rs2_delete_firmware_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); + + /** * \brief Gets RealSense firmware log parser * \param[in] dev Device from which the FW log will be taken * \param[in] fw_log_msg firmware log message to be parsed +* \param[in] parsed_msg firmware log parsed message - place holder for the resulting parsed message * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return firmware log parsed message +* \return true for success, false for failure - failure happens if message could not be parsed */ -rs2_firmware_log_parsed_message* rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_error** error); +int rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_firmware_log_parsed_message* parsed_msg, rs2_error** error); /** * Delete RealSense firmware log parsed message diff --git a/include/librealsense2/hpp/rs_firmware_logs.hpp b/include/librealsense2/hpp/rs_firmware_logs.hpp index 9e34bd6dbd..0e2815b50e 100644 --- a/include/librealsense2/hpp/rs_firmware_logs.hpp +++ b/include/librealsense2/hpp/rs_firmware_logs.hpp @@ -113,6 +113,8 @@ namespace rs2 return timestamp; } + const std::shared_ptr get_message() const { return _parsed_fw_log; } + private: std::shared_ptr _parsed_fw_log; }; @@ -142,6 +144,17 @@ namespace rs2 return firmware_log_message(msg); } + rs2::firmware_log_parsed_message create_parsed_message() + { + rs2_error* e = nullptr; + std::shared_ptr msg( + rs2_create_firmware_log_parsed_message(_dev.get(), &e), + rs2_delete_firmware_log_parsed_message); + error::handle(e); + + return firmware_log_parsed_message(msg); + } + bool get_firmware_log(rs2::firmware_log_message& msg) const { rs2_error* e = nullptr; @@ -187,16 +200,14 @@ namespace rs2 return parser_initialized; } - rs2::firmware_log_parsed_message parse_log(const rs2::firmware_log_message& msg) + bool parse_log(const rs2::firmware_log_message& msg, const rs2::firmware_log_parsed_message& parsed_msg) { rs2_error* e = nullptr; - std::shared_ptr parsed_msg( - rs2_parse_firmware_log(_dev.get(), msg.get_message().get(), &e), - rs2_delete_firmware_log_parsed_message); + bool parsingResult = rs2_parse_firmware_log(_dev.get(), msg.get_message().get(), parsed_msg.get_message().get(), &e); error::handle(e); - return firmware_log_parsed_message(parsed_msg); + return parsingResult; } }; diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 997b1a9fbf..8424ebf0dc 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -142,11 +142,16 @@ namespace librealsense return (_parser != nullptr); } - fw_logs::fw_log_data firmware_logger_device::parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg) + bool firmware_logger_device::parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, + fw_logs::fw_log_data* parsed_msg) { - fw_logs::fw_log_data log_data; - if(_parser) - log_data = _parser->parse_fw_log(fw_log_msg); - return log_data; + bool result = false; + if (_parser && parsed_msg && fw_log_msg) + { + *parsed_msg = _parser->parse_fw_log(fw_log_msg); + result = true; + } + + return result; } } \ No newline at end of file diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index 4fb59f33fa..f2b428bf8e 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -17,7 +17,7 @@ namespace librealsense virtual bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) = 0; virtual bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) = 0; virtual bool init_parser(std::string xml_full_file_path) = 0; - virtual fw_logs::fw_log_data parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg) = 0; + virtual bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) = 0; virtual size_t get_number_of_flash_logs() = 0; virtual ~firmware_logger_extensions() = default; }; @@ -34,7 +34,7 @@ namespace librealsense bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) override; bool init_parser(std::string xml_full_file_path) override; - fw_logs::fw_log_data parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg) override; + bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) override; size_t get_number_of_flash_logs() override; diff --git a/src/realsense.def b/src/realsense.def index bd7ae915a1..83b0a9e939 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -367,6 +367,7 @@ EXPORTS rs2_firmware_log_message_size rs2_init_parser rs2_parse_firmware_log + rs2_create_firmware_log_parsed_message rs2_delete_firmware_log_parsed_message rs2_get_fw_log_parsed_message rs2_get_fw_log_parsed_file_name diff --git a/src/rs.cpp b/src/rs.cpp index b30aee0aca..923e789046 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -3079,19 +3079,30 @@ int rs2_init_parser(rs2_device* dev, const char* xml_path ,rs2_error** error) BE } HANDLE_EXCEPTIONS_AND_RETURN(0, xml_path) -rs2_firmware_log_parsed_message* rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_error** error) BEGIN_API_CALL +rs2_firmware_log_parsed_message* rs2_create_firmware_log_parsed_message(rs2_device* dev, rs2_error** error)BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(dev); + + auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + + return new rs2_firmware_log_parsed_message{ std::make_shared () }; +} +HANDLE_EXCEPTIONS_AND_RETURN(0, dev) + +int rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_firmware_log_parsed_message* parsed_msg, rs2_error** error)BEGIN_API_CALL { VALIDATE_NOT_NULL(dev); VALIDATE_NOT_NULL(fw_log_msg); + VALIDATE_NOT_NULL(parsed_msg); auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); - librealsense::fw_logs::fw_log_data log_data = - fw_loggerable->parse_log(fw_log_msg->firmware_log_binary_data.get()); + bool parsing_result = fw_loggerable->parse_log(fw_log_msg->firmware_log_binary_data.get(), + parsed_msg->firmware_log_parsed.get()); - return new rs2_firmware_log_parsed_message{ std::make_shared(log_data) }; + return parsing_result ? 1 : 0; } -HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev, fw_log_msg) +HANDLE_EXCEPTIONS_AND_RETURN(0, dev, fw_log_msg) void rs2_delete_firmware_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg) BEGIN_API_CALL { diff --git a/tools/fw-logger/rs-fw-logger.cpp b/tools/fw-logger/rs-fw-logger.cpp index ed5afbfa0b..aadf665e52 100644 --- a/tools/fw-logger/rs-fw-logger.cpp +++ b/tools/fw-logger/rs-fw-logger.cpp @@ -91,7 +91,9 @@ int main(int argc, char* argv[]) std::vector fw_log_lines; if (using_parser) { - rs2::firmware_log_parsed_message parsed_log = fw_log_device.parse_log(fw_log_message); + auto parsed_log = fw_log_device.create_parsed_message(); + bool parsing_result = fw_log_device.parse_log(fw_log_message, parsed_log); + stringstream sstr; sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() << " " << parsed_log.thread_name() << " " << parsed_log.file_name() From c8bbb536d4fe234d9f871122b1dbb52ddc9d5db4 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 3 Jun 2020 13:13:05 +0300 Subject: [PATCH 19/61] correct flash log example - to be deleted ater on --- examples/flash-logs/rs-flash-logs.cpp | 50 +++++++++++++++------------ 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/examples/flash-logs/rs-flash-logs.cpp b/examples/flash-logs/rs-flash-logs.cpp index 3658117ad7..e25e44b33e 100644 --- a/examples/flash-logs/rs-flash-logs.cpp +++ b/examples/flash-logs/rs-flash-logs.cpp @@ -66,13 +66,26 @@ int main(int argc, char * argv[]) setvbuf(stdout, NULL, _IONBF, 0); // unbuffering stdout - auto fw_log = res.get_device().as(); - auto number_of_flash_logs_in_device = fw_log.get_number_of_flash_logs(); + auto fw_log_device = res.get_device().as(); + auto number_of_flash_logs_in_device = fw_log_device.get_number_of_flash_logs(); + + bool using_parser = false; + std::string xml_full_file_path("HWLoggerEventsDS5.xml"); + if (!xml_full_file_path.empty()) + { + ifstream f(xml_full_file_path); + if (f.good()) + { + bool parser_initialized = fw_log_device.init_parser(xml_full_file_path); + if (parser_initialized) + using_parser = true; + } + } for (int i = 0; i < number_of_flash_logs_in_device; ++i) { - auto flash_log_message = fw_log.create_message(); - bool result = fw_log.get_flash_log(flash_log_message); + auto flash_log_message = fw_log_device.create_message(); + bool result = fw_log_device.get_flash_log(flash_log_message); if (result) { std::vector fw_log_lines; @@ -80,24 +93,17 @@ int main(int argc, char * argv[]) static bool usingParser = true; if (usingParser) { - std::string xml_path("HWLoggerEventsDS5.xml"); - if (!xml_path.empty()) - { - ifstream f(xml_path); - if (f.good()) - { - unique_ptr parser = - unique_ptr(new rs2::firmware_log_parser(xml_path)); - - rs2::firmware_log_parsed_message parsed_log = parser->parse_firmware_log(flash_log_message); - stringstream sstr; - sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() - << " " << parsed_log.thread_name() << " " << parsed_log.file_name() - << " " << parsed_log.line(); - - fw_log_lines.push_back(sstr.str()); - } - } + + auto parsed_log = fw_log_device.create_parsed_message(); + bool parsing_result = fw_log_device.parse_log(flash_log_message, parsed_log); + + stringstream sstr; + sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() + << " " << parsed_log.thread_name() << " " << parsed_log.file_name() + << " " << parsed_log.line(); + + fw_log_lines.push_back(sstr.str()); + } else { From 85887216e5057a59846157d3ddbc0a248e16421b Mon Sep 17 00:00:00 2001 From: remibettan Date: Tue, 9 Jun 2020 13:03:23 +0300 Subject: [PATCH 20/61] flash logs pulling coorected to be same as fw logs --- examples/flash-logs/rs-flash-logs.cpp | 8 ++++++-- include/librealsense2/h/rs_firmware_logs.h | 2 -- include/librealsense2/hpp/rs_firmware_logs.hpp | 11 ----------- src/firmware_logger_device.cpp | 16 +++------------- src/firmware_logger_device.h | 6 +----- src/realsense.def | 1 - src/rs.cpp | 13 ------------- 7 files changed, 10 insertions(+), 47 deletions(-) diff --git a/examples/flash-logs/rs-flash-logs.cpp b/examples/flash-logs/rs-flash-logs.cpp index e25e44b33e..04b9b2569e 100644 --- a/examples/flash-logs/rs-flash-logs.cpp +++ b/examples/flash-logs/rs-flash-logs.cpp @@ -67,7 +67,6 @@ int main(int argc, char * argv[]) auto fw_log_device = res.get_device().as(); - auto number_of_flash_logs_in_device = fw_log_device.get_number_of_flash_logs(); bool using_parser = false; std::string xml_full_file_path("HWLoggerEventsDS5.xml"); @@ -82,7 +81,8 @@ int main(int argc, char * argv[]) } } - for (int i = 0; i < number_of_flash_logs_in_device; ++i) + bool flash_logs_to_pull = true; + while (hub.is_connected(dev) && flash_logs_to_pull) { auto flash_log_message = fw_log_device.create_message(); bool result = fw_log_device.get_flash_log(flash_log_message); @@ -121,6 +121,10 @@ int main(int argc, char * argv[]) for (auto& line : fw_log_lines) cout << line << endl; } + else + { + flash_logs_to_pull = false; + } } } catch (const rs2::error & e) diff --git a/include/librealsense2/h/rs_firmware_logs.h b/include/librealsense2/h/rs_firmware_logs.h index 184b81e996..3a17c57c6b 100644 --- a/include/librealsense2/h/rs_firmware_logs.h +++ b/include/librealsense2/h/rs_firmware_logs.h @@ -32,8 +32,6 @@ rs2_firmware_log_message* rs2_create_firmware_log_message(rs2_device* dev, rs2_e */ int rs2_get_firmware_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); -int rs2_get_number_of_flash_logs(rs2_device* dev, rs2_error** error); - /** * \brief Gets RealSense flash log - this is a fw log that has been written in the device during the previous shutdown of the device * \param[in] dev Device from which the FW log should be taken diff --git a/include/librealsense2/hpp/rs_firmware_logs.hpp b/include/librealsense2/hpp/rs_firmware_logs.hpp index 0e2815b50e..c9fdadafca 100644 --- a/include/librealsense2/hpp/rs_firmware_logs.hpp +++ b/include/librealsense2/hpp/rs_firmware_logs.hpp @@ -179,17 +179,6 @@ namespace rs2 return flash_log_pulling_status; } - int get_number_of_flash_logs() const - { - rs2_error* e = nullptr; - int number_of_flash_logs = - rs2_get_number_of_flash_logs(_dev.get(), &e); - - error::handle(e); - - return number_of_flash_logs; - } - bool init_parser(const std::string& xml_path) { rs2_error* e = nullptr; diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 8424ebf0dc..1a13c0d91b 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -12,7 +12,6 @@ namespace librealsense _fw_logs(), _flash_logs(), _flash_logs_initialized(false), - _flash_logs_index(0), _parser(nullptr) { auto op_code = static_cast(std::stoi(camera_op_code.c_str())); @@ -100,7 +99,7 @@ namespace librealsense std::vector resultsForOneLog; resultsForOneLog.insert(resultsForOneLog.begin(), beginOfLogIterator, endOfLogIterator); fw_logs::fw_logs_binary_data binary_data{ resultsForOneLog }; - _flash_logs.push_back(binary_data); + _flash_logs.push(binary_data); beginOfLogIterator = endOfLogIterator; } @@ -118,23 +117,14 @@ namespace librealsense if (!_flash_logs.empty()) { fw_logs::fw_logs_binary_data data; - data = _flash_logs[_flash_logs_index]; - _flash_logs_index = (_flash_logs_index + 1) % (_flash_logs.size()); + data = _flash_logs.front(); + _flash_logs.pop(); binary_data = data; result = true; } return result; } - size_t firmware_logger_device::get_number_of_flash_logs() - { - if (!_flash_logs_initialized) - { - get_flash_logs_from_hw_monitor(); - } - return _flash_logs.size(); - } - bool firmware_logger_device::init_parser(std::string xml_full_file_path) { _parser = new fw_logs::fw_logs_parser(xml_full_file_path); diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index f2b428bf8e..a3eaa507ae 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -18,7 +18,6 @@ namespace librealsense virtual bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) = 0; virtual bool init_parser(std::string xml_full_file_path) = 0; virtual bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) = 0; - virtual size_t get_number_of_flash_logs() = 0; virtual ~firmware_logger_extensions() = default; }; MAP_EXTENSION(RS2_EXTENSION_FW_LOGGER, librealsense::firmware_logger_extensions); @@ -36,8 +35,6 @@ namespace librealsense bool init_parser(std::string xml_full_file_path) override; bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) override; - size_t get_number_of_flash_logs() override; - private: void get_fw_logs_from_hw_monitor(); void get_flash_logs_from_hw_monitor(); @@ -45,10 +42,9 @@ namespace librealsense std::shared_ptr _hw_monitor; std::queue _fw_logs; - std::vector _flash_logs; + std::queue _flash_logs; bool _flash_logs_initialized; - int _flash_logs_index; std::vector _input_code_for_fw_logs; std::vector _input_code_for_flash_logs; diff --git a/src/realsense.def b/src/realsense.def index 83b0a9e939..d013030882 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -360,7 +360,6 @@ EXPORTS rs2_delete_firmware_log_message rs2_get_firmware_log rs2_get_flash_log - rs2_get_number_of_flash_logs rs2_firmware_log_message_severity rs2_firmware_log_message_timestamp rs2_firmware_log_message_data diff --git a/src/rs.cpp b/src/rs.cpp index 923e789046..320650286c 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -3007,19 +3007,6 @@ int rs2_get_firmware_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, } HANDLE_EXCEPTIONS_AND_RETURN(0, dev, fw_log_msg) - -int rs2_get_number_of_flash_logs(rs2_device* dev, rs2_error** error) BEGIN_API_CALL -{ - VALIDATE_NOT_NULL(dev); - auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); - - fw_logs::fw_logs_binary_data binary_data; - int number_of_flash_logs = fw_loggerable->get_number_of_flash_logs(); - - return number_of_flash_logs; -} -HANDLE_EXCEPTIONS_AND_RETURN(0, dev) - int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error)BEGIN_API_CALL { VALIDATE_NOT_NULL(dev); From a8b9b7f45528768972a205b3763d98575c2d4afc Mon Sep 17 00:00:00 2001 From: remibettan Date: Mon, 15 Jun 2020 15:19:14 +0300 Subject: [PATCH 21/61] fw logger extension added to the ds5 devices, opcode removed from ctor --- src/ds5/ds5-factory.cpp | 120 ++++++++++++++++++++++----------- src/firmware_logger_device.cpp | 12 +--- src/firmware_logger_device.h | 3 +- 3 files changed, 85 insertions(+), 50 deletions(-) diff --git a/src/ds5/ds5-factory.cpp b/src/ds5/ds5-factory.cpp index 1923da4ede..6d63e88708 100644 --- a/src/ds5/ds5-factory.cpp +++ b/src/ds5/ds5-factory.cpp @@ -27,7 +27,9 @@ namespace librealsense { // PSR - class rs400_device : public ds5_nonmonochrome, public ds5_advanced_mode_base + class rs400_device : public ds5_nonmonochrome, + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs400_device(std::shared_ptr ctx, @@ -36,7 +38,8 @@ namespace librealsense : device(ctx, group, register_device_notifications), ds5_device(ctx, group), ds5_nonmonochrome(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -62,7 +65,8 @@ namespace librealsense // DS5U_S class rs405u_device : public ds5u_device, - public ds5_advanced_mode_base + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs405u_device(std::shared_ptr ctx, @@ -70,7 +74,8 @@ namespace librealsense bool register_device_notifications) : device(ctx, group, register_device_notifications), ds5u_device(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -109,7 +114,9 @@ namespace librealsense // ASR (D460) class rs410_device : public ds5_nonmonochrome, - public ds5_active, public ds5_advanced_mode_base + public ds5_active, + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs410_device(std::shared_ptr ctx, @@ -119,7 +126,8 @@ namespace librealsense ds5_device(ctx, group), ds5_nonmonochrome(ctx, group), ds5_active(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -144,7 +152,8 @@ namespace librealsense class rs415_device : public ds5_nonmonochrome, public ds5_active, public ds5_color, - public ds5_advanced_mode_base + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs415_device(std::shared_ptr ctx, @@ -155,7 +164,8 @@ namespace librealsense ds5_nonmonochrome(ctx, group), ds5_active(ctx, group), ds5_color(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -180,7 +190,9 @@ namespace librealsense }; class rs416_device : public ds5_nonmonochrome, - public ds5_active, public ds5_advanced_mode_base + public ds5_active, + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs416_device(std::shared_ptr ctx, @@ -190,7 +202,8 @@ namespace librealsense ds5_device(ctx, group), ds5_nonmonochrome(ctx, group), ds5_active(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -229,7 +242,8 @@ namespace librealsense public ds5_nonmonochrome, public ds5_active, public ds5_color, - public ds5_advanced_mode_base + public ds5_advanced_mode_base, + public firmware_logger_device { public: @@ -241,7 +255,8 @@ namespace librealsense ds5_nonmonochrome(ctx, group), ds5_active(ctx, group), ds5_color(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -279,7 +294,9 @@ namespace librealsense }; // PWGT - class rs420_mm_device : public ds5_motion, public ds5_advanced_mode_base + class rs420_mm_device : public ds5_motion, + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs420_mm_device(std::shared_ptr ctx, @@ -288,7 +305,8 @@ namespace librealsense : device(ctx, group, register_device_notifications), ds5_device(ctx, group), ds5_motion(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -321,7 +339,9 @@ namespace librealsense }; // PWG - class rs420_device : public ds5_device, public ds5_advanced_mode_base + class rs420_device : public ds5_device, + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs420_device(std::shared_ptr ctx, @@ -329,7 +349,8 @@ namespace librealsense bool register_device_notifications) : device(ctx, group, register_device_notifications), ds5_device(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -354,7 +375,9 @@ namespace librealsense }; // AWG - class rs430_device : public ds5_active, public ds5_advanced_mode_base + class rs430_device : public ds5_active, + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs430_device(std::shared_ptr ctx, @@ -363,7 +386,8 @@ namespace librealsense : device(ctx, group, register_device_notifications), ds5_device(ctx, group), ds5_active(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -387,7 +411,10 @@ namespace librealsense }; }; - class rs430i_device : public ds5_active, public ds5_advanced_mode_base, public ds5_motion + class rs430i_device : public ds5_active, + public ds5_advanced_mode_base, + public ds5_motion, + public firmware_logger_device { public: rs430i_device(std::shared_ptr ctx, @@ -397,7 +424,8 @@ namespace librealsense ds5_device(ctx, group), ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - ds5_motion(ctx, group) + ds5_motion(ctx, group), + firmware_logger_device(ds5_device::_hw_monitor) {} std::vector get_profiles_tags() const override @@ -427,7 +455,8 @@ namespace librealsense // AWGT class rs430_mm_device : public ds5_active, public ds5_motion, - public ds5_advanced_mode_base + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs430_mm_device(std::shared_ptr ctx, @@ -437,7 +466,8 @@ namespace librealsense ds5_device(ctx, group), ds5_active(ctx, group), ds5_motion(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -485,7 +515,7 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor().get_info(RS2_CAMERA_INFO_DEBUG_OP_CODE)) {} + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -513,7 +543,8 @@ namespace librealsense class rs430_rgb_mm_device : public ds5_active, public ds5_color, public ds5_motion, - public ds5_advanced_mode_base + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs430_rgb_mm_device(std::shared_ptr ctx, @@ -524,7 +555,8 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_motion(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -552,7 +584,8 @@ namespace librealsense class rs435i_device : public ds5_active, public ds5_color, public ds5_motion, - public ds5_advanced_mode_base + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs435i_device(std::shared_ptr ctx, @@ -563,7 +596,8 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_motion(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) { check_and_restore_rgb_stream_extrinsic(); } @@ -767,7 +801,8 @@ namespace librealsense public ds5_nonmonochrome, public ds5_color, public ds5_motion, - public ds5_advanced_mode_base + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs465_device(std::shared_ptr ctx, @@ -779,7 +814,8 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_nonmonochrome(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -804,7 +840,8 @@ namespace librealsense }; class rs400_imu_device : public ds5_motion, - public ds5_advanced_mode_base + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs400_imu_device(std::shared_ptr ctx, @@ -813,7 +850,8 @@ namespace librealsense : device(ctx, group, register_device_notifications), ds5_device(ctx, group), ds5_motion(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) {} + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -828,9 +866,10 @@ namespace librealsense }; class rs405_device : public ds5_active, - public ds5_color, - public ds5_motion, - public ds5_advanced_mode_base + public ds5_color, + public ds5_motion, + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs405_device(std::shared_ptr ctx, @@ -841,7 +880,8 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_motion(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -871,9 +911,10 @@ namespace librealsense }; class rs455_device : public ds5_active, - public ds5_color, - public ds5_motion, - public ds5_advanced_mode_base + public ds5_color, + public ds5_motion, + public ds5_advanced_mode_base, + public firmware_logger_device { public: rs455_device(std::shared_ptr ctx, @@ -884,7 +925,8 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_motion(ctx, group), - ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()) + ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(ds5_device::_hw_monitor) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 1a13c0d91b..3be27f70b6 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -6,24 +6,18 @@ namespace librealsense { - firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor, - std::string camera_op_code) : + firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor) : _hw_monitor(hardware_monitor), _fw_logs(), _flash_logs(), _flash_logs_initialized(false), _parser(nullptr) { - auto op_code = static_cast(std::stoi(camera_op_code.c_str())); - _input_code_for_fw_logs = { 0x14, 0x00, 0xab, 0xcd, op_code, 0x00, 0x00, 0x00, + _input_code_for_fw_logs = { 0x14, 0x00, 0xab, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - //TODO - get the right code for flash logs - auto flash_logs_op_code = static_cast(0x09);// static_cast(std::stoi(camera_op_code.c_str())); - //auto flash_logs_offset = { 0x7a, 0x01, 0x00, 0x00 }; - //auto flash_logs_length = { 0xf8, 0x03, 0x00, 0x00 }; - _input_code_for_flash_logs = { 0x14, 0x00, 0xab, 0xcd, flash_logs_op_code, 0x00, 0x00, 0x00, + _input_code_for_flash_logs = { 0x14, 0x00, 0xab, 0xcd, 0x09, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x17, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; } diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index a3eaa507ae..a250a3b933 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -26,8 +26,7 @@ namespace librealsense class firmware_logger_device : public virtual device, public firmware_logger_extensions { public: - firmware_logger_device(std::shared_ptr hardware_monitor, - std::string camera_op_code); + firmware_logger_device(std::shared_ptr hardware_monitor); bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) override; bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) override; From 0b146894bd3e5941134232d729c5943158fb2476 Mon Sep 17 00:00:00 2001 From: remibettan Date: Mon, 15 Jun 2020 15:54:28 +0300 Subject: [PATCH 22/61] xml content sent to api instead of xml path --- examples/flash-logs/rs-flash-logs.cpp | 3 ++- include/librealsense2/h/rs_firmware_logs.h | 10 +++++----- include/librealsense2/hpp/rs_firmware_logs.hpp | 4 ++-- src/firmware_logger_device.cpp | 4 ++-- src/firmware_logger_device.h | 4 ++-- src/fw-logs/fw-logs-formating-options.cpp | 6 +++--- src/fw-logs/fw-logs-formating-options.h | 4 ++-- src/fw-logs/fw-logs-parser.cpp | 4 ++-- src/fw-logs/fw-logs-parser.h | 2 +- src/fw-logs/fw-logs-xml-helper.cpp | 16 +++++++--------- src/fw-logs/fw-logs-xml-helper.h | 4 ++-- src/rs.cpp | 8 ++++---- tools/fw-logger/rs-fw-logger.cpp | 3 ++- 13 files changed, 36 insertions(+), 36 deletions(-) diff --git a/examples/flash-logs/rs-flash-logs.cpp b/examples/flash-logs/rs-flash-logs.cpp index 04b9b2569e..25c5d45aa4 100644 --- a/examples/flash-logs/rs-flash-logs.cpp +++ b/examples/flash-logs/rs-flash-logs.cpp @@ -75,7 +75,8 @@ int main(int argc, char * argv[]) ifstream f(xml_full_file_path); if (f.good()) { - bool parser_initialized = fw_log_device.init_parser(xml_full_file_path); + std::string xml_content((std::istreambuf_iterator(f)), std::istreambuf_iterator()); + bool parser_initialized = fw_log_device.init_parser(xml_content); if (parser_initialized) using_parser = true; } diff --git a/include/librealsense2/h/rs_firmware_logs.h b/include/librealsense2/h/rs_firmware_logs.h index 3a17c57c6b..6d1aa71dee 100644 --- a/include/librealsense2/h/rs_firmware_logs.h +++ b/include/librealsense2/h/rs_firmware_logs.h @@ -82,12 +82,12 @@ rs2_log_severity rs2_firmware_log_message_severity(const rs2_firmware_log_messag /** * \brief Initializes RealSense firmware logs parser in device. -* \param[in] dev Device from which the FW log will be taken -* \param[in] xml_path path to xml file needed for parsing -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return true for success, false for failure - failure happens if opening the xml from the xml_path input fails +* \param[in] dev Device from which the FW log will be taken +* \param[in] xml_content content of the xml file needed for parsing +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return true for success, false for failure - failure happens if opening the xml from the xml_path input fails */ -int rs2_init_parser(rs2_device* dev, const char* xml_path, rs2_error** error); +int rs2_init_parser(rs2_device* dev, const char* xml_content, rs2_error** error); /** diff --git a/include/librealsense2/hpp/rs_firmware_logs.hpp b/include/librealsense2/hpp/rs_firmware_logs.hpp index c9fdadafca..c80f68ee45 100644 --- a/include/librealsense2/hpp/rs_firmware_logs.hpp +++ b/include/librealsense2/hpp/rs_firmware_logs.hpp @@ -179,11 +179,11 @@ namespace rs2 return flash_log_pulling_status; } - bool init_parser(const std::string& xml_path) + bool init_parser(const std::string& xml_content) { rs2_error* e = nullptr; - bool parser_initialized = rs2_init_parser(_dev.get(), xml_path.c_str(), &e); + bool parser_initialized = rs2_init_parser(_dev.get(), xml_content.c_str(), &e); error::handle(e); return parser_initialized; diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 3be27f70b6..05f45d52aa 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -119,9 +119,9 @@ namespace librealsense return result; } - bool firmware_logger_device::init_parser(std::string xml_full_file_path) + bool firmware_logger_device::init_parser(std::string xml_content) { - _parser = new fw_logs::fw_logs_parser(xml_full_file_path); + _parser = new fw_logs::fw_logs_parser(xml_content); return (_parser != nullptr); } diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index a250a3b933..d8b8a4a75f 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -16,7 +16,7 @@ namespace librealsense public: virtual bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) = 0; virtual bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) = 0; - virtual bool init_parser(std::string xml_full_file_path) = 0; + virtual bool init_parser(std::string xml_content) = 0; virtual bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) = 0; virtual ~firmware_logger_extensions() = default; }; @@ -31,7 +31,7 @@ namespace librealsense bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) override; bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) override; - bool init_parser(std::string xml_full_file_path) override; + bool init_parser(std::string xml_content) override; bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) override; private: diff --git a/src/fw-logs/fw-logs-formating-options.cpp b/src/fw-logs/fw-logs-formating-options.cpp index 1bab57c1af..0b8a947ac1 100644 --- a/src/fw-logs/fw-logs-formating-options.cpp +++ b/src/fw-logs/fw-logs-formating-options.cpp @@ -21,8 +21,8 @@ namespace librealsense {} - fw_logs_formating_options::fw_logs_formating_options(const string& xml_full_file_path) - : _xml_full_file_path(xml_full_file_path) + fw_logs_formating_options::fw_logs_formating_options(const string& xml_content) + : _xml_content(xml_content) {} @@ -87,7 +87,7 @@ namespace librealsense bool fw_logs_formating_options::initialize_from_xml() { - fw_logs_xml_helper fw_logs_xml(_xml_full_file_path); + fw_logs_xml_helper fw_logs_xml(_xml_content); return fw_logs_xml.build_log_meta_data(this); } } diff --git a/src/fw-logs/fw-logs-formating-options.h b/src/fw-logs/fw-logs-formating-options.h index 241f92496f..3578fcbee0 100644 --- a/src/fw-logs/fw-logs-formating-options.h +++ b/src/fw-logs/fw-logs-formating-options.h @@ -31,7 +31,7 @@ namespace librealsense class fw_logs_formating_options { public: - fw_logs_formating_options(const std::string& xml_full_file_path); + fw_logs_formating_options(const std::string& xml_content); ~fw_logs_formating_options(void); @@ -48,7 +48,7 @@ namespace librealsense std::unordered_map _fw_logs_thread_names_list; std::unordered_map>> _fw_logs_enum_names_list; - std::string _xml_full_file_path; + std::string _xml_content; }; } } diff --git a/src/fw-logs/fw-logs-parser.cpp b/src/fw-logs/fw-logs-parser.cpp index 7e57f6579f..bd76b1d87e 100644 --- a/src/fw-logs/fw-logs-parser.cpp +++ b/src/fw-logs/fw-logs-parser.cpp @@ -12,8 +12,8 @@ namespace librealsense { namespace fw_logs { - fw_logs_parser::fw_logs_parser(string xml_full_file_path) - : _fw_logs_formating_options(xml_full_file_path), + fw_logs_parser::fw_logs_parser(string xml_content) + : _fw_logs_formating_options(xml_content), _last_timestamp(0), _timestamp_factor(0.00001) { diff --git a/src/fw-logs/fw-logs-parser.h b/src/fw-logs/fw-logs-parser.h index 331b35e252..a06af30718 100644 --- a/src/fw-logs/fw-logs-parser.h +++ b/src/fw-logs/fw-logs-parser.h @@ -14,7 +14,7 @@ namespace librealsense class fw_logs_parser : public std::enable_shared_from_this { public: - explicit fw_logs_parser(std::string xml_full_file_path); + explicit fw_logs_parser(std::string xml_content); ~fw_logs_parser(void); fw_log_data parse_fw_log(const fw_logs_binary_data* fw_log_msg); diff --git a/src/fw-logs/fw-logs-xml-helper.cpp b/src/fw-logs/fw-logs-xml-helper.cpp index 03132f65b1..42adfd501d 100644 --- a/src/fw-logs/fw-logs-xml-helper.cpp +++ b/src/fw-logs/fw-logs-xml-helper.cpp @@ -12,9 +12,9 @@ namespace librealsense { namespace fw_logs { - fw_logs_xml_helper::fw_logs_xml_helper(string xml_full_file_path) + fw_logs_xml_helper::fw_logs_xml_helper(string xml_content) : _init_done(false), - _xml_full_file_path(xml_full_file_path) + _xml_content(xml_content) {} @@ -38,15 +38,13 @@ namespace librealsense { try { - if (_xml_full_file_path.empty()) + if (_xml_content.empty()) return false; - rapidxml::file<> xml_file(_xml_full_file_path.c_str()); - - _document_buffer.resize(xml_file.size() + 2); - memcpy(_document_buffer.data(), xml_file.data(), xml_file.size()); - _document_buffer[xml_file.size()] = '\0'; - _document_buffer[xml_file.size() + 1] = '\0'; + _document_buffer.resize(_xml_content.size() + 2); + memcpy(_document_buffer.data(), _xml_content.data(), _xml_content.size()); + _document_buffer[_xml_content.size()] = '\0'; + _document_buffer[_xml_content.size() + 1] = '\0'; _xml_doc.parse<0>(_document_buffer.data()); return true; diff --git a/src/fw-logs/fw-logs-xml-helper.h b/src/fw-logs/fw-logs-xml-helper.h index c9f5a31226..39b6c963d5 100644 --- a/src/fw-logs/fw-logs-xml-helper.h +++ b/src/fw-logs/fw-logs-xml-helper.h @@ -22,7 +22,7 @@ namespace librealsense none }; - fw_logs_xml_helper(std::string xml_full_file_path); + fw_logs_xml_helper(std::string xml_content); ~fw_logs_xml_helper(void); bool build_log_meta_data(fw_logs_formating_options* logs_formating_options); @@ -40,7 +40,7 @@ namespace librealsense bool try_load_external_xml(); bool _init_done; - std::string _xml_full_file_path; + std::string _xml_content; xml_document<> _xml_doc; std::vector _document_buffer; }; diff --git a/src/rs.cpp b/src/rs.cpp index 320650286c..7cebf0e3fa 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -3056,15 +3056,15 @@ unsigned int rs2_firmware_log_message_timestamp(rs2_firmware_log_message* msg, r } HANDLE_EXCEPTIONS_AND_RETURN(0, msg) -int rs2_init_parser(rs2_device* dev, const char* xml_path ,rs2_error** error) BEGIN_API_CALL +int rs2_init_parser(rs2_device* dev, const char* xml_content,rs2_error** error) BEGIN_API_CALL { - VALIDATE_NOT_NULL(xml_path); + VALIDATE_NOT_NULL(xml_content); auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); - return (fw_loggerable->init_parser(xml_path)) ? 1 : 0; + return (fw_loggerable->init_parser(xml_content)) ? 1 : 0; } -HANDLE_EXCEPTIONS_AND_RETURN(0, xml_path) +HANDLE_EXCEPTIONS_AND_RETURN(0, xml_content) rs2_firmware_log_parsed_message* rs2_create_firmware_log_parsed_message(rs2_device* dev, rs2_error** error)BEGIN_API_CALL { diff --git a/tools/fw-logger/rs-fw-logger.cpp b/tools/fw-logger/rs-fw-logger.cpp index aadf665e52..8188b70d6b 100644 --- a/tools/fw-logger/rs-fw-logger.cpp +++ b/tools/fw-logger/rs-fw-logger.cpp @@ -76,7 +76,8 @@ int main(int argc, char* argv[]) ifstream f(xml_full_file_path); if (f.good()) { - bool parser_initialized = fw_log_device.init_parser(xml_full_file_path); + std::string xml_content((std::istreambuf_iterator(f)), std::istreambuf_iterator()); + bool parser_initialized = fw_log_device.init_parser(xml_content); if (parser_initialized) using_parser = true; } From 0a038223dbef0185e75991cb87ec437035236b71 Mon Sep 17 00:00:00 2001 From: remibettan Date: Tue, 16 Jun 2020 11:54:17 +0300 Subject: [PATCH 23/61] modify fw-logger tool so that it could pull also flash logs --- tools/fw-logger/rs-fw-logger.cpp | 44 ++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/tools/fw-logger/rs-fw-logger.cpp b/tools/fw-logger/rs-fw-logger.cpp index 8188b70d6b..4838cdc524 100644 --- a/tools/fw-logger/rs-fw-logger.cpp +++ b/tools/fw-logger/rs-fw-logger.cpp @@ -47,7 +47,9 @@ int main(int argc, char* argv[]) { CmdLine cmd("librealsense rs-fw-logger example tool", ' ', RS2_API_VERSION_STR); ValueArg xml_arg("l", "load", "Full file path of HW Logger Events XML file", false, "", "Load HW Logger Events XML file"); - cmd.add(xml_arg); + SwitchArg flash_logs_arg("f", "flash", "Flash Logs Request", false); + cmd.add(xml_arg); + cmd.add(flash_logs_arg); cmd.parse(argc, argv); log_to_file(RS2_LOG_SEVERITY_WARN, "librealsense.log"); @@ -55,10 +57,14 @@ int main(int argc, char* argv[]) auto use_xml_file = false; auto xml_full_file_path = xml_arg.getValue(); + bool are_flash_logs_requested = flash_logs_arg.isSet(); + context ctx; device_hub hub(ctx); - while (true) + bool should_loop_end = false; + + while (!should_loop_end) { try { @@ -83,17 +89,32 @@ int main(int argc, char* argv[]) } } + bool are_there_remaining_flash_logs_to_pull = true; + while (hub.is_connected(dev)) { - auto fw_log_message = fw_log_device.create_message(); - bool result = fw_log_device.get_firmware_log(fw_log_message); + if (are_flash_logs_requested && !are_there_remaining_flash_logs_to_pull) + { + should_loop_end = true; + break; + } + auto log_message = fw_log_device.create_message(); + bool result = false; + if (are_flash_logs_requested) + { + result = fw_log_device.get_flash_log(log_message); + } + else + { + result = fw_log_device.get_firmware_log(log_message); + } if (result) { std::vector fw_log_lines; if (using_parser) { auto parsed_log = fw_log_device.create_parsed_message(); - bool parsing_result = fw_log_device.parse_log(fw_log_message, parsed_log); + bool parsing_result = fw_log_device.parse_log(log_message, parsed_log); stringstream sstr; sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() @@ -105,10 +126,10 @@ int main(int argc, char* argv[]) else { stringstream sstr; - sstr << fw_log_message.get_timestamp(); - sstr << " " << fw_log_message.get_severity_str(); + sstr << log_message.get_timestamp(); + sstr << " " << log_message.get_severity_str(); sstr << " FW_Log_Data:"; - std::vector msg_data = fw_log_message.data(); + std::vector msg_data = log_message.data(); for (int i = 0; i < msg_data.size(); ++i) { sstr << char2hex(raw_data[i]) << " "; @@ -118,6 +139,13 @@ int main(int argc, char* argv[]) for (auto& line : fw_log_lines) cout << line << endl; } + else + { + if (are_flash_logs_requested) + { + are_there_remaining_flash_logs_to_pull = false; + } + } } } catch (const error & e) From 6fc4ee727e6d17902acc229a3c91baebf5f82ae0 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 17 Jun 2020 09:38:45 +0300 Subject: [PATCH 24/61] fw logs code corrections --- include/librealsense2/hpp/rs_firmware_logs.hpp | 1 - src/firmware_logger_device.cpp | 16 +++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/include/librealsense2/hpp/rs_firmware_logs.hpp b/include/librealsense2/hpp/rs_firmware_logs.hpp index c80f68ee45..1cb76954f1 100644 --- a/include/librealsense2/hpp/rs_firmware_logs.hpp +++ b/include/librealsense2/hpp/rs_firmware_logs.hpp @@ -7,7 +7,6 @@ #include "rs_types.hpp" #include "rs_sensor.hpp" #include "../h/rs_firmware_logs.h" -#include namespace rs2 { diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 05f45d52aa..bb512e135f 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -48,7 +48,8 @@ namespace librealsense auto res = _hw_monitor->send(_input_code_for_fw_logs); if (res.empty()) { - throw std::runtime_error("Getting Firmware logs failed!"); + LOG_INFO("Getting Firmware logs failed!"); + return; } //erasing header @@ -71,24 +72,21 @@ namespace librealsense void firmware_logger_device::get_flash_logs_from_hw_monitor() { - int size_of_flash_logs_header = 31; + int size_of_flash_logs_header = 27; auto res = _hw_monitor->send(_input_code_for_flash_logs); if (res.empty()) { - throw std::runtime_error("Getting Flash logs failed!"); + LOG_INFO("Getting Flash logs failed!"); + return; } - int limit = static_cast(res[0] + (res[1] << 8) + (res[2] << 16) + (res[3] << 24)); - //erasing header res.erase(res.begin(), res.begin() + size_of_flash_logs_header); auto beginOfLogIterator = res.begin(); - // convert bytes to fw_logs_binary_data - for (int i = 0; i < limit; ++i) + // convert bytes to flash_logs_binary_data + for (int i = 0; i < res.size() / fw_logs::BINARY_DATA_SIZE && *beginOfLogIterator == 160; ++i) { - if (*beginOfLogIterator == 0) - break; auto endOfLogIterator = beginOfLogIterator + fw_logs::BINARY_DATA_SIZE; std::vector resultsForOneLog; resultsForOneLog.insert(resultsForOneLog.begin(), beginOfLogIterator, endOfLogIterator); From 08be3e7cabbdb1cc233aef0247da41971fee14b3 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 17 Jun 2020 10:48:54 +0300 Subject: [PATCH 25/61] pids map added to fw logger, sr300 missing --- src/ds5/ds5-factory.cpp | 36 +++++------ src/firmware_logger_device.cpp | 108 ++++++++++++++++++++++++++++----- src/firmware_logger_device.h | 11 ++-- src/l500/l500-factory.cpp | 13 ++-- 4 files changed, 128 insertions(+), 40 deletions(-) diff --git a/src/ds5/ds5-factory.cpp b/src/ds5/ds5-factory.cpp index 6d63e88708..64b3aa22da 100644 --- a/src/ds5/ds5-factory.cpp +++ b/src/ds5/ds5-factory.cpp @@ -39,7 +39,7 @@ namespace librealsense ds5_device(ctx, group), ds5_nonmonochrome(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -75,7 +75,7 @@ namespace librealsense : device(ctx, group, register_device_notifications), ds5u_device(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -127,7 +127,7 @@ namespace librealsense ds5_nonmonochrome(ctx, group), ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -165,7 +165,7 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -203,7 +203,7 @@ namespace librealsense ds5_nonmonochrome(ctx, group), ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -256,7 +256,7 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -306,7 +306,7 @@ namespace librealsense ds5_device(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -350,7 +350,7 @@ namespace librealsense : device(ctx, group, register_device_notifications), ds5_device(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -387,7 +387,7 @@ namespace librealsense ds5_device(ctx, group), ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -425,7 +425,7 @@ namespace librealsense ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), ds5_motion(ctx, group), - firmware_logger_device(ds5_device::_hw_monitor) + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::vector get_profiles_tags() const override @@ -467,7 +467,7 @@ namespace librealsense ds5_active(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -515,7 +515,7 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -556,7 +556,7 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -597,7 +597,7 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) { check_and_restore_rgb_stream_extrinsic(); } @@ -815,7 +815,7 @@ namespace librealsense ds5_motion(ctx, group), ds5_nonmonochrome(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -851,7 +851,7 @@ namespace librealsense ds5_device(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) {} + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -881,7 +881,7 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -926,7 +926,7 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor) + firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index bb512e135f..2766a7f249 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -2,24 +2,96 @@ // Copyright(c) 2020 Intel Corporation. All Rights Reserved. #include "firmware_logger_device.h" +#include "ds5/ds5-private.h" +#include "l500/l500-private.h" +#include "ivcam/sr300.h" #include namespace librealsense { - firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor) : + std::map firmware_logger_device::fw_logs_commands = + { + {ds::RS400_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS410_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS415_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS430_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS430_MM_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS_USB2_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS_RECOVERY_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS_USB2_RECOVERY_PID, command{ ds::GLD, 0x1f4 }}, + {ds::RS400_IMU_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS420_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS420_MM_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS410_MM_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS400_MM_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS430_MM_RGB_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS460_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS435_RGB_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS405U_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS435I_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS416_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS430I_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS465_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS416_RGB_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS405_PID , command{ ds::GLD, 0x1f4 }}, + {ds::RS455_PID , command{ ds::GLD, 0x1f4 }}, + {L500_RECOVERY_PID , command{ ivcam2::GLD, 0x1f4 }}, + {L500_PID , command{ ivcam2::GLD, 0x1f4 }}, + {L515_PID_PRE_PRQ , command{ ivcam2::GLD, 0x1f4 }}, + {L515_PID , command{ ivcam2::GLD, 0x1f4 }}, + {SR300_PID , command{ ivcam2::GLD, 0x1f4 }}, + {SR300v2_PID , command{ ivcam2::GLD, 0x1f4 }}, + {SR300_RECOVERY , command{ ivcam2::GLD, 0x1f4 }} + }; + + std::map firmware_logger_device::flash_logs_commands = + { + {ds::RS400_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS410_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS415_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS430_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS430_MM_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS_USB2_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS_RECOVERY_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS_USB2_RECOVERY_PID, command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS400_IMU_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS420_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS420_MM_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS410_MM_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS400_MM_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS430_MM_RGB_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS460_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS435_RGB_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS405U_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS435I_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS416_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS430I_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS465_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS416_RGB_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS405_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {ds::RS455_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, + {L500_RECOVERY_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, + {L500_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, + {L515_PID_PRE_PRQ , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, + {L515_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}/*, + {SR300_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, + {SR300v2_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, + {SR300_RECOVERY , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}*/ + }; + + + firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor, + const synthetic_sensor& depth_sensor) : _hw_monitor(hardware_monitor), _fw_logs(), _flash_logs(), _flash_logs_initialized(false), _parser(nullptr) { - _input_code_for_fw_logs = { 0x14, 0x00, 0xab, 0xcd, 0x0f, 0x00, 0x00, 0x00, - 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - _input_code_for_flash_logs = { 0x14, 0x00, 0xab, 0xcd, 0x09, 0x00, 0x00, 0x00, - 0x00, 0xa0, 0x17, 0x00, 0xf8, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + std::string pid_str (depth_sensor.get_info(RS2_CAMERA_INFO_PRODUCT_ID)); + std::stringstream ss; + ss << std::hex << pid_str; + ss >> _device_pid; } bool firmware_logger_device::get_fw_log(fw_logs::fw_logs_binary_data& binary_data) @@ -44,17 +116,19 @@ namespace librealsense void firmware_logger_device::get_fw_logs_from_hw_monitor() { - int size_of_fw_logs_header = 4; - auto res = _hw_monitor->send(_input_code_for_fw_logs); + auto it = fw_logs_commands.find(_device_pid); + if (it == fw_logs_commands.end()) + { + LOG_INFO("Firmware logs not set for this device!"); + return; + } + auto res = _hw_monitor->send(it->second); if (res.empty()) { LOG_INFO("Getting Firmware logs failed!"); return; } - //erasing header - res.erase(res.begin(), res.begin() + size_of_fw_logs_header); - auto beginOfLogIterator = res.begin(); // convert bytes to fw_logs_binary_data for (int i = 0; i < res.size() / fw_logs::BINARY_DATA_SIZE; ++i) @@ -73,7 +147,13 @@ namespace librealsense void firmware_logger_device::get_flash_logs_from_hw_monitor() { int size_of_flash_logs_header = 27; - auto res = _hw_monitor->send(_input_code_for_flash_logs); + auto it = flash_logs_commands.find(_device_pid); + if (it == flash_logs_commands.end()) + { + LOG_INFO("Flash logs not set for this device!"); + return; + } + auto res = _hw_monitor->send(it->second); if (res.empty()) { LOG_INFO("Getting Flash logs failed!"); diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index d8b8a4a75f..77f86939d2 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -26,7 +26,8 @@ namespace librealsense class firmware_logger_device : public virtual device, public firmware_logger_extensions { public: - firmware_logger_device(std::shared_ptr hardware_monitor); + firmware_logger_device(std::shared_ptr hardware_monitor, + const synthetic_sensor& depth_sensor); bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) override; bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) override; @@ -35,6 +36,9 @@ namespace librealsense bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) override; private: + static std::map fw_logs_commands; + static std::map flash_logs_commands; + void get_fw_logs_from_hw_monitor(); void get_flash_logs_from_hw_monitor(); @@ -45,10 +49,9 @@ namespace librealsense bool _flash_logs_initialized; - std::vector _input_code_for_fw_logs; - std::vector _input_code_for_flash_logs; - fw_logs::fw_logs_parser* _parser; + uint16_t _device_pid; + }; } \ No newline at end of file diff --git a/src/l500/l500-factory.cpp b/src/l500/l500-factory.cpp index 4bd7d2be6b..51297c5626 100644 --- a/src/l500/l500-factory.cpp +++ b/src/l500/l500-factory.cpp @@ -11,6 +11,7 @@ #include "context.h" #include "image.h" #include "metadata-parser.h" +#include "../firmware_logger_device.h" #include "l500-factory.h" #include "l500-depth.h" @@ -27,7 +28,8 @@ namespace librealsense public l500_options, public l500_color, public l500_motion, - public l500_serializable + public l500_serializable, + public firmware_logger_device { public: rs515_device(std::shared_ptr ctx, @@ -39,7 +41,8 @@ namespace librealsense l500_options(ctx, group), l500_color(ctx, group), l500_motion(ctx, group), - l500_serializable(_hw_monitor, get_depth_sensor()) + l500_serializable(l500_device::_hw_monitor, get_depth_sensor()), + firmware_logger_device(l500_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -59,7 +62,8 @@ namespace librealsense }; // l500 - class rs500_device : public l500_depth + class rs500_device : public l500_depth, + public firmware_logger_device { public: rs500_device(std::shared_ptr ctx, @@ -67,7 +71,8 @@ namespace librealsense bool register_device_notifications) : device(ctx, group, register_device_notifications), l500_device(ctx, group), - l500_depth(ctx, group) + l500_depth(ctx, group), + firmware_logger_device(l500_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; From 8f037b14d318c0529a8af99cc4a41606ed4807b6 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 17 Jun 2020 11:21:58 +0300 Subject: [PATCH 26/61] removing flash logs example as it is already in rs-fw-logger tool --- examples/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 59e516c697..cf04932166 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -47,4 +47,3 @@ add_subdirectory(ar-basic) add_subdirectory(ar-advanced) add_subdirectory(pose-apriltag) add_subdirectory(tracking-and-depth) -add_subdirectory(flash-logs) From 45ef2ff5d29fa9f34e880966f6aefcdf2905d8e2 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 17 Jun 2020 11:52:19 +0300 Subject: [PATCH 27/61] adding fw logs support for sr300 --- src/firmware_logger_device.cpp | 8 ++++---- src/ivcam/sr300.cpp | 1 + src/ivcam/sr300.h | 8 ++++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 2766a7f249..08cbe87ae1 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -73,10 +73,10 @@ namespace librealsense {L500_RECOVERY_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, {L500_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, {L515_PID_PRE_PRQ , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, - {L515_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}/*, - {SR300_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, - {SR300v2_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, - {SR300_RECOVERY , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}*/ + {L515_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, + {SR300_PID , command{ ivcam::FlashRead, 0x000B6000, 0x3f8 }}, + {SR300v2_PID , command{ ivcam::FlashRead, 0x000B6000, 0x3f8 }}, + {SR300_RECOVERY , command{ ivcam::FlashRead, 0x000B6000, 0x3f8 }} }; diff --git a/src/ivcam/sr300.cpp b/src/ivcam/sr300.cpp index 8329308522..0f52f5a00b 100644 --- a/src/ivcam/sr300.cpp +++ b/src/ivcam/sr300.cpp @@ -422,6 +422,7 @@ namespace librealsense const platform::backend_device_group& group, bool register_device_notifications) : device(ctx, group, register_device_notifications), + firmware_logger_device(_hw_monitor, get_depth_sensor()), _depth_device_idx(add_sensor(create_depth_device(ctx, depth))), _depth_stream(new stream(RS2_STREAM_DEPTH)), _ir_stream(new stream(RS2_STREAM_INFRARED)), diff --git a/src/ivcam/sr300.h b/src/ivcam/sr300.h index 18acb2461d..1db362cd58 100644 --- a/src/ivcam/sr300.h +++ b/src/ivcam/sr300.h @@ -21,6 +21,7 @@ #include "stream.h" #include "fw-update/fw-update-device-interface.h" #include "proc/color-formats-converter.h" +#include "../firmware_logger_device.h" namespace librealsense { @@ -185,7 +186,10 @@ namespace librealsense platform::usb_device_info _hwm; }; - class sr300_camera : public device, public debug_interface, public updatable + class sr300_camera : public device, + public debug_interface, + public updatable, + public firmware_logger_device { public: std::vector get_profiles_tags() const override @@ -386,7 +390,7 @@ namespace librealsense force_hardware_reset(); } - synthetic_sensor& get_depth_sensor() { return dynamic_cast(get_sensor(_depth_device_idx)); } + synthetic_sensor& get_depth_sensor() { return dynamic_cast(device::get_sensor(_depth_device_idx)); } uvc_sensor& get_raw_depth_sensor() { From a8d11e811522df00f8fb41805d8c509c1e8b2e30 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 17 Jun 2020 12:40:44 +0300 Subject: [PATCH 28/61] removing not needed examples --- examples/firmware-logs/CMakeLists.txt | 16 --- examples/firmware-logs/rs-firmware-logs.cpp | 126 ------------------ examples/flash-logs/CMakeLists.txt | 16 --- examples/flash-logs/rs-flash-logs.cpp | 137 -------------------- 4 files changed, 295 deletions(-) delete mode 100644 examples/firmware-logs/CMakeLists.txt delete mode 100644 examples/firmware-logs/rs-firmware-logs.cpp delete mode 100644 examples/flash-logs/CMakeLists.txt delete mode 100644 examples/flash-logs/rs-flash-logs.cpp diff --git a/examples/firmware-logs/CMakeLists.txt b/examples/firmware-logs/CMakeLists.txt deleted file mode 100644 index 929185ad15..0000000000 --- a/examples/firmware-logs/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# License: Apache 2.0. See LICENSE file in root directory. -# Copyright(c) 2020 Intel Corporation. All Rights Reserved. -# minimum required cmake version: 3.1.0 -cmake_minimum_required(VERSION 3.1.0) - -project(RealsenseExamplesFirmwareLogs) - -if(BUILD_GRAPHICAL_EXAMPLES) - add_executable(rs-firmware-logs rs-firmware-logs.cpp ../example.hpp) - set_property(TARGET rs-firmware-logs PROPERTY CXX_STANDARD 11) - target_link_libraries(rs-firmware-logs ${DEPENDENCIES}) - include_directories(rs-firmware-logs ../ ../../third-party/tclap/include) - set_target_properties (rs-firmware-logs PROPERTIES FOLDER "Examples") - - install(TARGETS rs-firmware-logs RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -endif() diff --git a/examples/firmware-logs/rs-firmware-logs.cpp b/examples/firmware-logs/rs-firmware-logs.cpp deleted file mode 100644 index 50c2bb6cbe..0000000000 --- a/examples/firmware-logs/rs-firmware-logs.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2017 Intel Corporation. All Rights Reserved. - -#include // Include RealSense Cross Platform API -#include "example.hpp" // Include short list of convenience functions for rendering -#include -#include -#include -#include - -using namespace std; - - -string hexify(unsigned char n) -{ - string res; - - do - { - res += "0123456789ABCDEF"[n % 16]; - n >>= 4; - } while (n); - - reverse(res.begin(), res.end()); - - if (res.size() == 1) - { - res.insert(0, "0"); - } - - return res; -} - -string datetime_string() -{ - auto t = time(nullptr); - char buffer[20] = {}; - const tm* time = localtime(&t); - if (nullptr != time) - strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", time); - - return string(buffer); -} - -// Capture Example demonstrates how to -// capture depth and color video streams and render them to the screen -int main(int argc, char * argv[]) -{ - // Declare RealSense pipeline, encapsulating the actual device and sensors - rs2::pipeline pipe; - - // Start streaming with default recommended configuration - // The default video configuration contains Depth and Color streams - // If a device is capable to stream IMU data, both Gyro and Accelerometer are enabled by default - auto res = pipe.start(); - - rs2::context ctx; - rs2::device_hub hub(ctx); - while (true) - { - try - { - cout << "\nWaiting for RealSense device to connect...\n"; - auto dev = hub.wait_for_device(); - cout << "RealSense device was connected...\n"; - - setvbuf(stdout, NULL, _IONBF, 0); // unbuffering stdout - - auto fw_log_device = res.get_device().as(); - - bool using_parser = false; - std::string xml_path("C:\\Users\\rbettan\\Documents\\Dev\\RefFolder\\HWLoggerEventsDS5.xml"); - if (!xml_path.empty()) - { - ifstream f(xml_path); - if (f.good()) - { - bool parser_initialized = fw_log_device.init_parser(xml_path); - if (parser_initialized) - using_parser = true; - } - } - - while (hub.is_connected(dev)) - { - auto fw_log_message = fw_log_device.create_message(); - bool result = fw_log_device.get_firmware_log(fw_log_message); - if (result) - { - std::vector fw_log_lines; - if (using_parser) - { - rs2::firmware_log_parsed_message parsed_log = fw_log_device.parse_log(fw_log_message); - stringstream sstr; - sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() - << " " << parsed_log.thread_name() << " " << parsed_log.file_name() - << " " << parsed_log.line(); - - fw_log_lines.push_back(sstr.str()); - } - else - { - stringstream sstr; - sstr << fw_log_message.get_timestamp(); - sstr << " " << fw_log_message.get_severity_str(); - sstr << " FW_Log_Data:"; - std::vector msg_data = fw_log_message.data(); - for (int i = 0; i < msg_data.size(); ++i) - { - sstr << hexify(msg_data[i]) << " "; - } - fw_log_lines.push_back(sstr.str()); - } - for (auto& line : fw_log_lines) - cout << line << endl; - } - } - } - catch (const rs2::error & e) - { - cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << endl; - } - } - - return EXIT_SUCCESS; -} diff --git a/examples/flash-logs/CMakeLists.txt b/examples/flash-logs/CMakeLists.txt deleted file mode 100644 index fac7fe82c8..0000000000 --- a/examples/flash-logs/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# License: Apache 2.0. See LICENSE file in root directory. -# Copyright(c) 2020 Intel Corporation. All Rights Reserved. -# minimum required cmake version: 3.1.0 -cmake_minimum_required(VERSION 3.1.0) - -project(RealsenseExamplesFirmwareLogs) - -if(BUILD_GRAPHICAL_EXAMPLES) - add_executable(rs-flash-logs rs-flash-logs.cpp ../example.hpp) - set_property(TARGET rs-flash-logs PROPERTY CXX_STANDARD 11) - target_link_libraries(rs-flash-logs ${DEPENDENCIES}) - include_directories(rs-flash-logs ../ ../../third-party/tclap/include) - set_target_properties (rs-flash-logs PROPERTIES FOLDER "Examples") - - install(TARGETS rs-flash-logs RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -endif() diff --git a/examples/flash-logs/rs-flash-logs.cpp b/examples/flash-logs/rs-flash-logs.cpp deleted file mode 100644 index 25c5d45aa4..0000000000 --- a/examples/flash-logs/rs-flash-logs.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2017 Intel Corporation. All Rights Reserved. - -#include // Include RealSense Cross Platform API -#include "example.hpp" // Include short list of convenience functions for rendering -#include -#include -#include -#include - -using namespace std; - - -string hexify(unsigned char n) -{ - string res; - - do - { - res += "0123456789ABCDEF"[n % 16]; - n >>= 4; - } while (n); - - reverse(res.begin(), res.end()); - - if (res.size() == 1) - { - res.insert(0, "0"); - } - - return res; -} - -string datetime_string() -{ - auto t = time(nullptr); - char buffer[20] = {}; - const tm* time = localtime(&t); - if (nullptr != time) - strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", time); - - return string(buffer); -} - -// Capture Example demonstrates how to -// capture depth and color video streams and render them to the screen -int main(int argc, char * argv[]) -{ - // Declare RealSense pipeline, encapsulating the actual device and sensors - rs2::pipeline pipe; - - // Start streaming with default recommended configuration - // The default video configuration contains Depth and Color streams - // If a device is capable to stream IMU data, both Gyro and Accelerometer are enabled by default - auto res = pipe.start(); - - rs2::context ctx; - rs2::device_hub hub(ctx); - - try - { - cout << "\nWaiting for RealSense device to connect...\n"; - auto dev = hub.wait_for_device(); - cout << "RealSense device was connected...\n"; - - setvbuf(stdout, NULL, _IONBF, 0); // unbuffering stdout - - - auto fw_log_device = res.get_device().as(); - - bool using_parser = false; - std::string xml_full_file_path("HWLoggerEventsDS5.xml"); - if (!xml_full_file_path.empty()) - { - ifstream f(xml_full_file_path); - if (f.good()) - { - std::string xml_content((std::istreambuf_iterator(f)), std::istreambuf_iterator()); - bool parser_initialized = fw_log_device.init_parser(xml_content); - if (parser_initialized) - using_parser = true; - } - } - - bool flash_logs_to_pull = true; - while (hub.is_connected(dev) && flash_logs_to_pull) - { - auto flash_log_message = fw_log_device.create_message(); - bool result = fw_log_device.get_flash_log(flash_log_message); - if (result) - { - std::vector fw_log_lines; - - static bool usingParser = true; - if (usingParser) - { - - auto parsed_log = fw_log_device.create_parsed_message(); - bool parsing_result = fw_log_device.parse_log(flash_log_message, parsed_log); - - stringstream sstr; - sstr << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() - << " " << parsed_log.thread_name() << " " << parsed_log.file_name() - << " " << parsed_log.line(); - - fw_log_lines.push_back(sstr.str()); - - } - else - { - stringstream sstr; - sstr << flash_log_message.get_timestamp(); - sstr << " " << flash_log_message.get_severity_str(); - sstr << " FW_Log_Data:"; - std::vector msg_data = flash_log_message.data(); - for (int i = 0; i < msg_data.size(); ++i) - { - sstr << hexify(msg_data[i]) << " "; - } - fw_log_lines.push_back(sstr.str()); - } - for (auto& line : fw_log_lines) - cout << line << endl; - } - else - { - flash_logs_to_pull = false; - } - } - } - catch (const rs2::error & e) - { - cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << endl; - } - - return EXIT_SUCCESS; -} From 939d364468b076101efd9ac6d5a25552bd8dd3d8 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 17 Jun 2020 12:46:24 +0300 Subject: [PATCH 29/61] removing not needed unit tests --- unit-tests/fw-logs/fw-logs-common.h | 37 ------ .../fw-logs/test-c-get-fw-logs-not-parsed.cpp | 80 ------------ .../fw-logs/test-c-get-fw-logs-parsed.cpp | 114 ------------------ 3 files changed, 231 deletions(-) delete mode 100644 unit-tests/fw-logs/fw-logs-common.h delete mode 100644 unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp delete mode 100644 unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp diff --git a/unit-tests/fw-logs/fw-logs-common.h b/unit-tests/fw-logs/fw-logs-common.h deleted file mode 100644 index af25dced2a..0000000000 --- a/unit-tests/fw-logs/fw-logs-common.h +++ /dev/null @@ -1,37 +0,0 @@ -// License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2020 Intel Corporation. All Rights Reserved. - -#pragma once - -//#include // Include RealSense Cross Platform API - -#include -#ifdef BUILD_SHARED_LIBS -// With static linkage, ELPP is initialized by librealsense, so doing it here will -// create errors. When we're using the shared .so/.dll, the two are separate and we have -// to initialize ours if we want to use the APIs! -INITIALIZE_EASYLOGGINGPP -#endif - -// Catch also defines CHECK(), and so we have to undefine it or we get compilation errors! -#undef CHECK - -// Let Catch define its own main() function -#define CATCH_CONFIG_MAIN -#include "../catch/catch.hpp" - -// Define our own logging macro for debugging to stdout -// Can possibly turn it on automatically based on the Catch options supplied -// on the command-line, with a custom main(): -// Catch::Session catch_session; -// int main (int argc, char * const argv[]) { -// return catch_session.run( argc, argv ); -// } -// #define TRACE(X) if( catch_session.configData().verbosity == ... ) {} -// With Catch2, we can turn this into SCOPED_INFO. -#define TRACE(X) do { \ - std::cout << X << std::endl; \ - } while(0) - - - diff --git a/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp b/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp deleted file mode 100644 index 73cfbc890d..0000000000 --- a/unit-tests/fw-logs/test-c-get-fw-logs-not-parsed.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2020 Intel Corporation. All Rights Reserved. - -//#cmake:add-file fw-logs-common.h -#include "fw-logs-common.h" - -/* Include the librealsense C header files */ -#include - -//get fw logs using c api -TEST_CASE( "Getting FW logs in C", "[fw-logs]" ) { - - rs2_error* e = 0; - - // Create a context object. This object owns the handles to all connected realsense devices. - // The returned object should be released with rs2_delete_context(...) - rs2_context* ctx = rs2_create_context(RS2_API_VERSION, &e); - REQUIRE(e == 0); - - /* Get a list of all the connected devices. */ - // The returned object should be released with rs2_delete_device_list(...) - rs2_device_list* device_list = rs2_query_devices(ctx, &e); - REQUIRE(e == 0); - - int dev_count = rs2_get_device_count(device_list, &e); - REQUIRE(e == 0); - printf("There are %d connected RealSense devices.\n", dev_count); - REQUIRE(dev_count > 0); - - // Get the first connected device - // The returned object should be released with rs2_delete_device(...) - rs2_device* dev = rs2_create_device(device_list, 0, &e); - REQUIRE(e == 0); - - bool device_extendable_to_fw_logger = false; - if (rs2_is_device_extendable_to(dev, RS2_EXTENSION_FW_LOGGER, &e) != 0 && !e) - { - device_extendable_to_fw_logger = true; - } - REQUIRE(device_extendable_to_fw_logger); - - bool were_fw_logs_received_once = false; - while (1)//!were_fw_logs_received_once) - { - rs2_error* e = nullptr; - rs2_firmware_log_message* fw_log_msg = rs2_get_firmware_log(dev, &e); - - REQUIRE(fw_log_msg); - - int size = rs2_firmware_log_message_size(fw_log_msg, &e); - - auto start = rs2_firmware_log_message_data(fw_log_msg, &e); - - if (size > 0) - { - were_fw_logs_received_once = true; - //get time - time_t rawtime; - struct tm* timeinfo; - - time_t mytime = time(NULL); - char* time_str = ctime(&mytime); - time_str[strlen(time_str) - 1] = '\0'; - printf("message received %s - ", time_str); - - rs2_error* e = nullptr; - rs2_log_severity severity = rs2_get_fw_log_severity(fw_log_msg, &e); - printf("%s ", rs2_log_severity_to_string(severity)); - - for (int i = 0; i < size; ++i) - { - printf("%d ", *(start + i)); - } - printf("\n"); - } - - rs2_delete_firmware_log_message(fw_log_msg); - } - -} diff --git a/unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp b/unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp deleted file mode 100644 index 57e7a2c341..0000000000 --- a/unit-tests/fw-logs/test-c-get-fw-logs-parsed.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2020 Intel Corporation. All Rights Reserved. - -//#cmake:add-file fw-logs-common.h -#include "fw-logs-common.h" - -/* Include the librealsense C header files */ -#include -#include -#include -#include -#include - - -#include -#define GetCurrentDir _getcwd - -char* rs2_firmware_log_message_to_string(rs2_firmware_log_message msg) -{ - char* buffer = (char*)(malloc(50 * sizeof(char))); - sprintf(buffer, "message = %s", msg._message); - return buffer; -} - - -std::string get_current_dir() { - char buff[FILENAME_MAX]; //create string buffer to hold path - GetCurrentDir(buff, FILENAME_MAX); - std::string current_working_dir(buff); - return current_working_dir; -} - -//get fw logs using c api -TEST_CASE( "Getting FW logs in C", "[fw-logs]" ) { - - rs2_error* e = 0; - - // Create a context object. This object owns the handles to all connected realsense devices. - // The returned object should be released with rs2_delete_context(...) - rs2_context* ctx = rs2_create_context(RS2_API_VERSION, &e); - REQUIRE(e == 0); - - /* Get a list of all the connected devices. */ - // The returned object should be released with rs2_delete_device_list(...) - rs2_device_list* device_list = rs2_query_devices(ctx, &e); - REQUIRE(e == 0); - - int dev_count = rs2_get_device_count(device_list, &e); - REQUIRE(e == 0); - printf("There are %d connected RealSense devices.\n", dev_count); - REQUIRE(dev_count > 0); - - // Get the first connected device - // The returned object should be released with rs2_delete_device(...) - rs2_device* dev = rs2_create_device(device_list, 0, &e); - REQUIRE(e == 0); - - bool device_extendable_to_fw_logger = false; - if (rs2_is_device_extendable_to(dev, RS2_EXTENSION_FW_LOGGER, &e) != 0 && !e) - { - device_extendable_to_fw_logger = true; - } - REQUIRE(device_extendable_to_fw_logger); - - const char* xml_path_const = "HWLoggerEventsDS5.xml"; - - /*std::string cf = get_current_dir(); - std::string xml_path(xml_path_const); - - if (!xml_path.empty()) - { - std::ifstream f(xml_path); - if (f.good()) - { - int a = 1; - } - else { - - int b = 1; - } - }*/ - - rs2_firmware_logs_parser* parser = rs2_create_firmware_logs_parser(xml_path_const, &e); - REQUIRE(parser); - - bool were_fw_logs_received_once = false; - while (!were_fw_logs_received_once) - { - rs2_firmware_log_message_list* fw_logs_list = rs2_get_firmware_logs_list(dev, &e); - REQUIRE(fw_logs_list); - - if (fw_logs_list->_number_of_messages > 0) - { - were_fw_logs_received_once = true; - for (int i = 0; i < fw_logs_list->_number_of_messages; ++i) - { - rs2_firmware_log_message* msg = &fw_logs_list->_messages[i]; - /*rs2_raw_data_buffer* parsed_log = rs2_parse_firmware_log(parser, msg->_event_id, msg->_p1, msg->_p2, msg->_p3, - msg->_file_id, msg->_thread_id, &e);*/ - - rs2_parse_firmware_log(parser, &msg, &e); - rs2::error::handle(e); - - printf("message received: %s\n", rs2_firmware_log_message_to_string(*msg)); - - - } - } - rs2_delete_firmware_logs_list(fw_logs_list); - } - - rs2_delete_firmware_logs_parser(parser); - -} From cc9bfa7ef47b6b09cf277a935c264d96a4c325e9 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 17 Jun 2020 13:34:25 +0300 Subject: [PATCH 30/61] api functions names got shorter - fw instead of firmware --- include/librealsense2/h/rs_firmware_logs.h | 20 +++++++++---------- .../librealsense2/hpp/rs_firmware_logs.hpp | 20 +++++++++---------- src/realsense.def | 20 +++++++++---------- src/rs.cpp | 20 +++++++++---------- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/include/librealsense2/h/rs_firmware_logs.h b/include/librealsense2/h/rs_firmware_logs.h index 6d1aa71dee..86dae1f146 100644 --- a/include/librealsense2/h/rs_firmware_logs.h +++ b/include/librealsense2/h/rs_firmware_logs.h @@ -21,7 +21,7 @@ extern "C" { * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return pointer to created empty firmware log message */ -rs2_firmware_log_message* rs2_create_firmware_log_message(rs2_device* dev, rs2_error** error); +rs2_firmware_log_message* rs2_create_fw_log_message(rs2_device* dev, rs2_error** error); /** * \brief Gets RealSense firmware log. @@ -30,7 +30,7 @@ rs2_firmware_log_message* rs2_create_firmware_log_message(rs2_device* dev, rs2_e * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor */ -int rs2_get_firmware_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); +int rs2_get_fw_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); /** * \brief Gets RealSense flash log - this is a fw log that has been written in the device during the previous shutdown of the device @@ -45,7 +45,7 @@ int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs * Delete RealSense firmware log message * \param[in] device Realsense firmware log message to delete */ -void rs2_delete_firmware_log_message(rs2_firmware_log_message* msg); +void rs2_delete_fw_log_message(rs2_firmware_log_message* msg); /** * \brief Gets RealSense firmware log message data. @@ -53,7 +53,7 @@ void rs2_delete_firmware_log_message(rs2_firmware_log_message* msg); * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return pointer to start of the firmware log message data */ -const unsigned char* rs2_firmware_log_message_data(rs2_firmware_log_message* msg, rs2_error** error); +const unsigned char* rs2_fw_log_message_data(rs2_firmware_log_message* msg, rs2_error** error); /** * \brief Gets RealSense firmware log message size. @@ -61,7 +61,7 @@ const unsigned char* rs2_firmware_log_message_data(rs2_firmware_log_message* msg * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return size of the firmware log message data */ -int rs2_firmware_log_message_size(rs2_firmware_log_message* msg, rs2_error** error); +int rs2_fw_log_message_size(rs2_firmware_log_message* msg, rs2_error** error); /** @@ -78,7 +78,7 @@ unsigned int rs2_firmware_log_message_timestamp(rs2_firmware_log_message* msg, r * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return severity of the firmware log message data */ -rs2_log_severity rs2_firmware_log_message_severity(const rs2_firmware_log_message* msg, rs2_error** error); +rs2_log_severity rs2_fw_log_message_timestamp(const rs2_firmware_log_message* msg, rs2_error** error); /** * \brief Initializes RealSense firmware logs parser in device. @@ -87,7 +87,7 @@ rs2_log_severity rs2_firmware_log_message_severity(const rs2_firmware_log_messag * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return true for success, false for failure - failure happens if opening the xml from the xml_path input fails */ -int rs2_init_parser(rs2_device* dev, const char* xml_content, rs2_error** error); +int rs2_init_fw_log_parser(rs2_device* dev, const char* xml_content, rs2_error** error); /** @@ -96,13 +96,13 @@ int rs2_init_parser(rs2_device* dev, const char* xml_content, rs2_error** error) * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return pointer to created empty firmware log message */ -rs2_firmware_log_parsed_message* rs2_create_firmware_log_parsed_message(rs2_device* dev, rs2_error** error); +rs2_firmware_log_parsed_message* rs2_create_fw_log_parsed_message(rs2_device* dev, rs2_error** error); /** * \brief Deletes RealSense firmware log parsed message. * \param[in] msg message to be deleted */ -void rs2_delete_firmware_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); +void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); /** @@ -119,7 +119,7 @@ int rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg * Delete RealSense firmware log parsed message * \param[in] device Realsense firmware log parsed message to delete */ -void rs2_delete_firmware_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); +void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); /** * \brief Gets RealSense firmware log parsed message message. diff --git a/include/librealsense2/hpp/rs_firmware_logs.hpp b/include/librealsense2/hpp/rs_firmware_logs.hpp index 1cb76954f1..f0247d12b0 100644 --- a/include/librealsense2/hpp/rs_firmware_logs.hpp +++ b/include/librealsense2/hpp/rs_firmware_logs.hpp @@ -18,7 +18,7 @@ namespace rs2 rs2_log_severity get_severity() const { rs2_error* e = nullptr; - rs2_log_severity severity = rs2_firmware_log_message_severity(_fw_log_message.get(), &e); + rs2_log_severity severity = rs2_fw_log_message_timestamp(_fw_log_message.get(), &e); error::handle(e); return severity; } @@ -37,7 +37,7 @@ namespace rs2 int size() const { rs2_error* e = nullptr; - int size = rs2_firmware_log_message_size(_fw_log_message.get(), &e); + int size = rs2_fw_log_message_size(_fw_log_message.get(), &e); error::handle(e); return size; } @@ -45,12 +45,12 @@ namespace rs2 std::vector data() const { rs2_error* e = nullptr; - auto size = rs2_firmware_log_message_size(_fw_log_message.get(), &e); + auto size = rs2_fw_log_message_size(_fw_log_message.get(), &e); error::handle(e); std::vector result; if (size > 0) { - auto start = rs2_firmware_log_message_data(_fw_log_message.get(), &e); + auto start = rs2_fw_log_message_data(_fw_log_message.get(), &e); error::handle(e); result.insert(result.begin(), start, start + size); } @@ -136,8 +136,8 @@ namespace rs2 { rs2_error* e = nullptr; std::shared_ptr msg( - rs2_create_firmware_log_message(_dev.get(), &e), - rs2_delete_firmware_log_message); + rs2_create_fw_log_message(_dev.get(), &e), + rs2_delete_fw_log_message); error::handle(e); return firmware_log_message(msg); @@ -147,8 +147,8 @@ namespace rs2 { rs2_error* e = nullptr; std::shared_ptr msg( - rs2_create_firmware_log_parsed_message(_dev.get(), &e), - rs2_delete_firmware_log_parsed_message); + rs2_create_fw_log_parsed_message(_dev.get(), &e), + rs2_delete_fw_log_parsed_message); error::handle(e); return firmware_log_parsed_message(msg); @@ -159,7 +159,7 @@ namespace rs2 rs2_error* e = nullptr; rs2_firmware_log_message* m = msg.get_message().get(); bool fw_log_pulling_status = - rs2_get_firmware_log(_dev.get(), &(m), &e); + rs2_get_fw_log(_dev.get(), &(m), &e); error::handle(e); @@ -182,7 +182,7 @@ namespace rs2 { rs2_error* e = nullptr; - bool parser_initialized = rs2_init_parser(_dev.get(), xml_content.c_str(), &e); + bool parser_initialized = rs2_init_fw_log_parser(_dev.get(), xml_content.c_str(), &e); error::handle(e); return parser_initialized; diff --git a/src/realsense.def b/src/realsense.def index d013030882..ca1fc5ad61 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -356,18 +356,18 @@ EXPORTS rs2_get_calibration_table rs2_set_calibration_table - rs2_create_firmware_log_message - rs2_delete_firmware_log_message - rs2_get_firmware_log + rs2_create_fw_log_message + rs2_delete_fw_log_message + rs2_get_fw_log rs2_get_flash_log - rs2_firmware_log_message_severity - rs2_firmware_log_message_timestamp - rs2_firmware_log_message_data - rs2_firmware_log_message_size - rs2_init_parser + rs2_fw_log_message_severity + rs2_fw_log_message_timestamp + rs2_fw_log_message_data + rs2_fw_log_message_size + rs2_init_fw_log_parser rs2_parse_firmware_log - rs2_create_firmware_log_parsed_message - rs2_delete_firmware_log_parsed_message + rs2_create_fw_log_parsed_message + rs2_delete_fw_log_parsed_message rs2_get_fw_log_parsed_message rs2_get_fw_log_parsed_file_name rs2_get_fw_log_parsed_thread_name diff --git a/src/rs.cpp b/src/rs.cpp index 7cebf0e3fa..3869d5dc1c 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -2982,7 +2982,7 @@ void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_s } HANDLE_EXCEPTIONS_AND_RETURN(, dev, json_content, content_size) -rs2_firmware_log_message* rs2_create_firmware_log_message(rs2_device* dev, rs2_error** error)BEGIN_API_CALL +rs2_firmware_log_message* rs2_create_fw_log_message(rs2_device* dev, rs2_error** error)BEGIN_API_CALL { VALIDATE_NOT_NULL(dev); auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); @@ -2991,7 +2991,7 @@ rs2_firmware_log_message* rs2_create_firmware_log_message(rs2_device* dev, rs2_e } HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev) -int rs2_get_firmware_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error) BEGIN_API_CALL +int rs2_get_fw_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(dev); VALIDATE_NOT_NULL(fw_log_msg); @@ -3022,41 +3022,41 @@ int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs return result ? 1 : 0; } HANDLE_EXCEPTIONS_AND_RETURN(0, dev, fw_log_msg) -void rs2_delete_firmware_log_message(rs2_firmware_log_message* msg) BEGIN_API_CALL +void rs2_delete_fw_log_message(rs2_firmware_log_message* msg) BEGIN_API_CALL { VALIDATE_NOT_NULL(msg); delete msg; } NOEXCEPT_RETURN(, msg) -const unsigned char* rs2_firmware_log_message_data(rs2_firmware_log_message* msg, rs2_error** error)BEGIN_API_CALL +const unsigned char* rs2_fw_log_message_data(rs2_firmware_log_message* msg, rs2_error** error)BEGIN_API_CALL { VALIDATE_NOT_NULL(msg); return msg->firmware_log_binary_data->logs_buffer.data(); } HANDLE_EXCEPTIONS_AND_RETURN(nullptr, msg) -int rs2_firmware_log_message_size(rs2_firmware_log_message* msg, rs2_error** error)BEGIN_API_CALL +int rs2_fw_log_message_size(rs2_firmware_log_message* msg, rs2_error** error)BEGIN_API_CALL { VALIDATE_NOT_NULL(msg); return msg->firmware_log_binary_data->logs_buffer.size(); } HANDLE_EXCEPTIONS_AND_RETURN(0, msg) -rs2_log_severity rs2_firmware_log_message_severity(const rs2_firmware_log_message* msg, rs2_error** error) BEGIN_API_CALL +rs2_log_severity rs2_fw_log_message_severity(const rs2_firmware_log_message* msg, rs2_error** error) BEGIN_API_CALL { return msg->firmware_log_binary_data->get_severity(); } HANDLE_EXCEPTIONS_AND_RETURN(RS2_LOG_SEVERITY_NONE, msg) -unsigned int rs2_firmware_log_message_timestamp(rs2_firmware_log_message* msg, rs2_error** error) BEGIN_API_CALL +unsigned int rs2_fw_log_message_timestamp(rs2_firmware_log_message* msg, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(msg); return msg->firmware_log_binary_data->get_timestamp(); } HANDLE_EXCEPTIONS_AND_RETURN(0, msg) -int rs2_init_parser(rs2_device* dev, const char* xml_content,rs2_error** error) BEGIN_API_CALL +int rs2_init_fw_log_parser(rs2_device* dev, const char* xml_content,rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(xml_content); @@ -3066,7 +3066,7 @@ int rs2_init_parser(rs2_device* dev, const char* xml_content,rs2_error** error) } HANDLE_EXCEPTIONS_AND_RETURN(0, xml_content) -rs2_firmware_log_parsed_message* rs2_create_firmware_log_parsed_message(rs2_device* dev, rs2_error** error)BEGIN_API_CALL +rs2_firmware_log_parsed_message* rs2_create_fw_log_parsed_message(rs2_device* dev, rs2_error** error)BEGIN_API_CALL { VALIDATE_NOT_NULL(dev); @@ -3091,7 +3091,7 @@ int rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg } HANDLE_EXCEPTIONS_AND_RETURN(0, dev, fw_log_msg) -void rs2_delete_firmware_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg) BEGIN_API_CALL +void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg) BEGIN_API_CALL { VALIDATE_NOT_NULL(fw_log_parsed_msg); delete fw_log_parsed_msg; From 8b858ba323962ea2a7fb171bdffd85864013b9e2 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 17 Jun 2020 19:16:18 +0300 Subject: [PATCH 31/61] fw-logger tool readme updated, fw_logger_device improved --- include/librealsense2/h/rs_firmware_logs.h | 4 +- .../librealsense2/hpp/rs_firmware_logs.hpp | 4 +- src/firmware_logger_device.cpp | 146 +++++++++--------- src/firmware_logger_device.h | 19 ++- src/ivcam/sr300.cpp | 1 - src/ivcam/sr300.h | 6 +- tools/fw-logger/readme.md | 8 +- 7 files changed, 102 insertions(+), 86 deletions(-) diff --git a/include/librealsense2/h/rs_firmware_logs.h b/include/librealsense2/h/rs_firmware_logs.h index 86dae1f146..4e0f9c821b 100644 --- a/include/librealsense2/h/rs_firmware_logs.h +++ b/include/librealsense2/h/rs_firmware_logs.h @@ -70,7 +70,7 @@ int rs2_fw_log_message_size(rs2_firmware_log_message* msg, rs2_error** error); * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return timestamp of the firmware log message */ -unsigned int rs2_firmware_log_message_timestamp(rs2_firmware_log_message* msg, rs2_error** error); +unsigned int rs2_fw_log_message_timestamp(rs2_firmware_log_message* msg, rs2_error** error); /** * \brief Gets RealSense firmware log message severity. @@ -78,7 +78,7 @@ unsigned int rs2_firmware_log_message_timestamp(rs2_firmware_log_message* msg, r * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return severity of the firmware log message data */ -rs2_log_severity rs2_fw_log_message_timestamp(const rs2_firmware_log_message* msg, rs2_error** error); +rs2_log_severity rs2_fw_log_message_severity(const rs2_firmware_log_message* msg, rs2_error** error); /** * \brief Initializes RealSense firmware logs parser in device. diff --git a/include/librealsense2/hpp/rs_firmware_logs.hpp b/include/librealsense2/hpp/rs_firmware_logs.hpp index f0247d12b0..1b1d005ba1 100644 --- a/include/librealsense2/hpp/rs_firmware_logs.hpp +++ b/include/librealsense2/hpp/rs_firmware_logs.hpp @@ -18,7 +18,7 @@ namespace rs2 rs2_log_severity get_severity() const { rs2_error* e = nullptr; - rs2_log_severity severity = rs2_fw_log_message_timestamp(_fw_log_message.get(), &e); + rs2_log_severity severity = rs2_fw_log_message_severity(_fw_log_message.get(), &e); error::handle(e); return severity; } @@ -29,7 +29,7 @@ namespace rs2 uint32_t get_timestamp() const { rs2_error* e = nullptr; - uint32_t timestamp = rs2_firmware_log_message_timestamp(_fw_log_message.get(), &e); + uint32_t timestamp = rs2_fw_log_message_timestamp(_fw_log_message.get(), &e); error::handle(e); return timestamp; } diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 08cbe87ae1..61d5697163 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -9,76 +9,62 @@ namespace librealsense { - std::map firmware_logger_device::fw_logs_commands = + std::map + firmware_logger_device::_logs_commands_per_group = { - {ds::RS400_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS410_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS415_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS430_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS430_MM_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS_USB2_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS_RECOVERY_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS_USB2_RECOVERY_PID, command{ ds::GLD, 0x1f4 }}, - {ds::RS400_IMU_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS420_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS420_MM_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS410_MM_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS400_MM_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS430_MM_RGB_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS460_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS435_RGB_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS405U_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS435I_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS416_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS430I_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS465_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS416_RGB_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS405_PID , command{ ds::GLD, 0x1f4 }}, - {ds::RS455_PID , command{ ds::GLD, 0x1f4 }}, - {L500_RECOVERY_PID , command{ ivcam2::GLD, 0x1f4 }}, - {L500_PID , command{ ivcam2::GLD, 0x1f4 }}, - {L515_PID_PRE_PRQ , command{ ivcam2::GLD, 0x1f4 }}, - {L515_PID , command{ ivcam2::GLD, 0x1f4 }}, - {SR300_PID , command{ ivcam2::GLD, 0x1f4 }}, - {SR300v2_PID , command{ ivcam2::GLD, 0x1f4 }}, - {SR300_RECOVERY , command{ ivcam2::GLD, 0x1f4 }} + {LOGS_COMMANDS_GROUP_DS, {command{ds::GLD, 0x1f4}, command{ds::FRB, 0x17a000, 0x3f8}}}, + {LOGS_COMMANDS_GROUP_L5, {command{ivcam2::GLD, 0x1f4}, command{ivcam2::FRB, 0x0011E000, 0x3f8}}}, + {LOGS_COMMANDS_GROUP_SR, {command{ivcam::GLD, 0x1f4}, command{ivcam::FlashRead, 0x000B6000, 0x3f8}}} }; - std::map firmware_logger_device::flash_logs_commands = - { - {ds::RS400_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS410_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS415_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS430_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS430_MM_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS_USB2_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS_RECOVERY_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS_USB2_RECOVERY_PID, command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS400_IMU_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS420_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS420_MM_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS410_MM_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS400_MM_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS430_MM_RGB_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS460_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS435_RGB_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS405U_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS435I_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS416_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS430I_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS465_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS416_RGB_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS405_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {ds::RS455_PID , command{ ds::FRB, 0x17a000, 0x3f8 }}, - {L500_RECOVERY_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, - {L500_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, - {L515_PID_PRE_PRQ , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, - {L515_PID , command{ ivcam2::FRB, 0x0011E000, 0x3f8 }}, - {SR300_PID , command{ ivcam::FlashRead, 0x000B6000, 0x3f8 }}, - {SR300v2_PID , command{ ivcam::FlashRead, 0x000B6000, 0x3f8 }}, - {SR300_RECOVERY , command{ ivcam::FlashRead, 0x000B6000, 0x3f8 }} - }; + firmware_logger_device::logs_commands_group firmware_logger_device::get_logs_commands_group(uint16_t device_pid) + { + logs_commands_group group = LOGS_COMMANDS_GROUP_NONE; + switch (device_pid) + { + case ds::RS400_PID: + case ds::RS410_PID: + case ds::RS415_PID: + case ds::RS430_PID: + case ds::RS430_MM_PID: + case ds::RS_USB2_PID: + case ds::RS_RECOVERY_PID: + case ds::RS_USB2_RECOVERY_PID: + case ds::RS400_IMU_PID: + case ds::RS420_PID: + case ds::RS420_MM_PID: + case ds::RS410_MM_PID: + case ds::RS400_MM_PID: + case ds::RS430_MM_RGB_PID: + case ds::RS460_PID: + case ds::RS435_RGB_PID: + case ds::RS405U_PID: + case ds::RS435I_PID: + case ds::RS416_PID: + case ds::RS430I_PID: + case ds::RS465_PID: + case ds::RS416_RGB_PID: + case ds::RS405_PID: + case ds::RS455_PID: + group = LOGS_COMMANDS_GROUP_DS; + break; + case L500_RECOVERY_PID: + case L500_PID: + case L515_PID_PRE_PRQ: + case L515_PID: + group = LOGS_COMMANDS_GROUP_L5; + break; + case SR300_PID: + case SR300v2_PID: + case SR300_RECOVERY: + group = LOGS_COMMANDS_GROUP_SR; + break; + default: + break; + } + return group; + } firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor, const synthetic_sensor& depth_sensor) : @@ -116,13 +102,19 @@ namespace librealsense void firmware_logger_device::get_fw_logs_from_hw_monitor() { - auto it = fw_logs_commands.find(_device_pid); - if (it == fw_logs_commands.end()) + logs_commands_group group = get_logs_commands_group(_device_pid); + if (group == LOGS_COMMANDS_GROUP_NONE) + { + LOG_INFO("Firmware logs not set for this device!"); + return; + } + auto it = _logs_commands_per_group.find(group); + if (it == _logs_commands_per_group.end()) { LOG_INFO("Firmware logs not set for this device!"); return; } - auto res = _hw_monitor->send(it->second); + auto res = _hw_monitor->send(it->second.fw_logs_command); if (res.empty()) { LOG_INFO("Getting Firmware logs failed!"); @@ -146,14 +138,20 @@ namespace librealsense void firmware_logger_device::get_flash_logs_from_hw_monitor() { - int size_of_flash_logs_header = 27; - auto it = flash_logs_commands.find(_device_pid); - if (it == flash_logs_commands.end()) + logs_commands_group group = get_logs_commands_group(_device_pid); + if (group == LOGS_COMMANDS_GROUP_NONE) { LOG_INFO("Flash logs not set for this device!"); return; } - auto res = _hw_monitor->send(it->second); + auto it = _logs_commands_per_group.find(group); + if (it == _logs_commands_per_group.end()) + { + LOG_INFO("Flash logs not set for this device!"); + return; + } + auto res = _hw_monitor->send(it->second.flash_logs_command); + if (res.empty()) { LOG_INFO("Getting Flash logs failed!"); @@ -161,6 +159,7 @@ namespace librealsense } //erasing header + int size_of_flash_logs_header = 27; res.erase(res.begin(), res.begin() + size_of_flash_logs_header); auto beginOfLogIterator = res.begin(); @@ -216,4 +215,5 @@ namespace librealsense return result; } + } \ No newline at end of file diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index 77f86939d2..f715ada6db 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -22,7 +22,6 @@ namespace librealsense }; MAP_EXTENSION(RS2_EXTENSION_FW_LOGGER, librealsense::firmware_logger_extensions); - class firmware_logger_device : public virtual device, public firmware_logger_extensions { public: @@ -36,8 +35,22 @@ namespace librealsense bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) override; private: - static std::map fw_logs_commands; - static std::map flash_logs_commands; + enum logs_commands_group + { + LOGS_COMMANDS_GROUP_NONE, + LOGS_COMMANDS_GROUP_DS, + LOGS_COMMANDS_GROUP_L5, + LOGS_COMMANDS_GROUP_SR, + LOGS_COMMANDS_GROUP_COUNT + }; + struct logs_commands + { + command fw_logs_command; + command flash_logs_command; + }; + static std::map _logs_commands_per_group; + + logs_commands_group get_logs_commands_group(uint16_t device_pid); void get_fw_logs_from_hw_monitor(); void get_flash_logs_from_hw_monitor(); diff --git a/src/ivcam/sr300.cpp b/src/ivcam/sr300.cpp index 0f52f5a00b..8329308522 100644 --- a/src/ivcam/sr300.cpp +++ b/src/ivcam/sr300.cpp @@ -422,7 +422,6 @@ namespace librealsense const platform::backend_device_group& group, bool register_device_notifications) : device(ctx, group, register_device_notifications), - firmware_logger_device(_hw_monitor, get_depth_sensor()), _depth_device_idx(add_sensor(create_depth_device(ctx, depth))), _depth_stream(new stream(RS2_STREAM_DEPTH)), _ir_stream(new stream(RS2_STREAM_INFRARED)), diff --git a/src/ivcam/sr300.h b/src/ivcam/sr300.h index 1db362cd58..094c47c954 100644 --- a/src/ivcam/sr300.h +++ b/src/ivcam/sr300.h @@ -21,7 +21,6 @@ #include "stream.h" #include "fw-update/fw-update-device-interface.h" #include "proc/color-formats-converter.h" -#include "../firmware_logger_device.h" namespace librealsense { @@ -186,10 +185,9 @@ namespace librealsense platform::usb_device_info _hwm; }; - class sr300_camera : public device, + class sr300_camera : public device, public debug_interface, - public updatable, - public firmware_logger_device + public updatable { public: std::vector get_profiles_tags() const override diff --git a/tools/fw-logger/readme.md b/tools/fw-logger/readme.md index 127b844837..1e3eb55e5c 100644 --- a/tools/fw-logger/readme.md +++ b/tools/fw-logger/readme.md @@ -5,7 +5,13 @@ If you are suspecting that you have an issue that is related to the camera’s firmware, please use this tool and provide the output together with the FW version number when you are creating an issue. In order to run this, ensure that your camera is streaming. This can be done using the [realsense-viewer](https://github.com/IntelRealSense/librealsense/tree/development/tools/realsense-viewer) or [rs-capture Sample](https://github.com/IntelRealSense/librealsense/tree/development/examples/capture) +## Command Line Parameters +|Flag |Description |Default| +|---|---|---| +|`-l `|xml file ful path, used to parse the logs|| +|`-f`|collect flash logs instead of firmware logs|| + ## Usage After installing `librealsense` run `rs-fw-logger` to launch the tool. -rs-fw-logger > filename – will save the FW logs to the filename. + From 7c835f716d852d79c0684b1ad5fbc2a2346a1574 Mon Sep 17 00:00:00 2001 From: remibettan Date: Wed, 17 Jun 2020 19:19:24 +0300 Subject: [PATCH 32/61] new line added at end of files --- src/firmware_logger_device.cpp | 2 +- src/firmware_logger_device.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 61d5697163..aa156ef531 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -216,4 +216,4 @@ namespace librealsense return result; } -} \ No newline at end of file +} diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index f715ada6db..dbe718d532 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -67,4 +67,4 @@ namespace librealsense }; -} \ No newline at end of file +} From fe906ba7d23637e89478d5152971ab226db1ba47 Mon Sep 17 00:00:00 2001 From: remibettan Date: Thu, 18 Jun 2020 11:45:49 +0300 Subject: [PATCH 33/61] tabs and typo corrections --- include/librealsense2/h/rs_firmware_logs.h | 2 +- src/fw-logs/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/librealsense2/h/rs_firmware_logs.h b/include/librealsense2/h/rs_firmware_logs.h index 4e0f9c821b..9ad98a17fd 100644 --- a/include/librealsense2/h/rs_firmware_logs.h +++ b/include/librealsense2/h/rs_firmware_logs.h @@ -122,7 +122,7 @@ int rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); /** -* \brief Gets RealSense firmware log parsed message message. +* \brief Gets RealSense firmware log parsed message. * \param[in] fw_log_parsed_msg firmware log parsed message object * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return message of the firmware log parsed message diff --git a/src/fw-logs/CMakeLists.txt b/src/fw-logs/CMakeLists.txt index 426bc350ad..87b93913e4 100644 --- a/src/fw-logs/CMakeLists.txt +++ b/src/fw-logs/CMakeLists.txt @@ -10,6 +10,6 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/fw-logs-parser.h" "${CMAKE_CURRENT_LIST_DIR}/fw-logs-xml-helper.cpp" "${CMAKE_CURRENT_LIST_DIR}/fw-logs-xml-helper.h" - "${CMAKE_CURRENT_LIST_DIR}/fw-string-formatter.cpp" - "${CMAKE_CURRENT_LIST_DIR}/fw-string-formatter.h" + "${CMAKE_CURRENT_LIST_DIR}/fw-string-formatter.cpp" + "${CMAKE_CURRENT_LIST_DIR}/fw-string-formatter.h" ) From f243dec18c68113e04460bf6050ad079a2894f40 Mon Sep 17 00:00:00 2001 From: remibettan Date: Thu, 18 Jun 2020 12:24:26 +0300 Subject: [PATCH 34/61] add fw and flash logs support for sr300 --- src/ivcam/sr300.cpp | 4 +++- src/ivcam/sr300.h | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ivcam/sr300.cpp b/src/ivcam/sr300.cpp index 8329308522..ae052691f7 100644 --- a/src/ivcam/sr300.cpp +++ b/src/ivcam/sr300.cpp @@ -422,6 +422,7 @@ namespace librealsense const platform::backend_device_group& group, bool register_device_notifications) : device(ctx, group, register_device_notifications), + firmware_logger_device(_hw_monitor, get_depth_sensor()), _depth_device_idx(add_sensor(create_depth_device(ctx, depth))), _depth_stream(new stream(RS2_STREAM_DEPTH)), _ir_stream(new stream(RS2_STREAM_INFRARED)), @@ -492,7 +493,8 @@ namespace librealsense const platform::usb_device_info &hwm_device, const platform::backend_device_group& group, bool register_device_notifications) - : sr300_camera(ctx, color, depth, hwm_device, group, register_device_notifications) { + : sr300_camera(ctx, color, depth, hwm_device, group, register_device_notifications), + device(ctx, group, register_device_notifications) { static auto device_name = "Intel RealSense SR305"; update_info(RS2_CAMERA_INFO_NAME, device_name); diff --git a/src/ivcam/sr300.h b/src/ivcam/sr300.h index 094c47c954..8a88392d7b 100644 --- a/src/ivcam/sr300.h +++ b/src/ivcam/sr300.h @@ -21,6 +21,7 @@ #include "stream.h" #include "fw-update/fw-update-device-interface.h" #include "proc/color-formats-converter.h" +#include "firmware_logger_device.h" namespace librealsense { @@ -185,9 +186,10 @@ namespace librealsense platform::usb_device_info _hwm; }; - class sr300_camera : public device, - public debug_interface, - public updatable + class sr300_camera : public virtual device, + public debug_interface, + public updatable, + public firmware_logger_device { public: std::vector get_profiles_tags() const override From 6228b58a4089c4186c9c9559a303a700354734e7 Mon Sep 17 00:00:00 2001 From: remibettan Date: Thu, 18 Jun 2020 15:09:14 +0300 Subject: [PATCH 35/61] tabs and log removed --- include/CMakeLists.txt | 4 ++-- src/firmware_logger_device.cpp | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 46fcaed190..fff0107534 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -17,7 +17,7 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_pipeline.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_config.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_firmware_logs.h" - "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_terminal_parser.h" + "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_terminal_parser.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_types.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_context.hpp" @@ -32,7 +32,7 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_internal.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_pipeline.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_firmware_logs.hpp" - "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_terminal_parser.hpp" + "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_terminal_parser.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/rsutil.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/rs_advanced_mode.h" diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index aa156ef531..c25a028964 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -117,7 +117,6 @@ namespace librealsense auto res = _hw_monitor->send(it->second.fw_logs_command); if (res.empty()) { - LOG_INFO("Getting Firmware logs failed!"); return; } From b4bda5c186397e9e50fe9f38e1da9a5e98498c55 Mon Sep 17 00:00:00 2001 From: remibettan Date: Thu, 18 Jun 2020 14:58:12 +0300 Subject: [PATCH 36/61] commands sent from each device ctor --- src/ds5/ds5-device.cpp | 10 ++++ src/ds5/ds5-device.h | 3 ++ src/ds5/ds5-factory.cpp | 73 +++++++++++++++++++------- src/firmware_logger_device.cpp | 96 ++-------------------------------- src/firmware_logger_device.h | 21 ++------ src/ivcam/sr300.cpp | 12 ++++- src/ivcam/sr300.h | 3 ++ src/l500/l500-device.cpp | 10 ++++ src/l500/l500-device.h | 3 ++ src/l500/l500-factory.cpp | 8 ++- 10 files changed, 109 insertions(+), 130 deletions(-) diff --git a/src/ds5/ds5-device.cpp b/src/ds5/ds5-device.cpp index bdde330540..756a7c52e3 100644 --- a/src/ds5/ds5-device.cpp +++ b/src/ds5/ds5-device.cpp @@ -945,6 +945,16 @@ namespace librealsense #endif } + command ds5_device::get_firmware_logs_command() const + { + return command{ ds::GLD, 0x1f4 }; + } + + command ds5_device::get_flash_logs_command() const + { + return command{ ds::FRB, 0x17a000, 0x3f8 }; + } + std::shared_ptr ds5u_device::create_ds5u_depth_device(std::shared_ptr ctx, const std::vector& all_device_infos) { diff --git a/src/ds5/ds5-device.h b/src/ds5/ds5-device.h index b4bb61dd35..ec1f8d3c64 100644 --- a/src/ds5/ds5-device.h +++ b/src/ds5/ds5-device.h @@ -75,6 +75,9 @@ namespace librealsense ds::d400_caps parse_device_capabilities(const uint16_t pid) const; + command get_firmware_logs_command() const; + command get_flash_logs_command() const; + void init(std::shared_ptr ctx, const platform::backend_device_group& group); diff --git a/src/ds5/ds5-factory.cpp b/src/ds5/ds5-factory.cpp index 64b3aa22da..e74059b0f5 100644 --- a/src/ds5/ds5-factory.cpp +++ b/src/ds5/ds5-factory.cpp @@ -39,7 +39,9 @@ namespace librealsense ds5_device(ctx, group), ds5_nonmonochrome(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -75,7 +77,9 @@ namespace librealsense : device(ctx, group, register_device_notifications), ds5u_device(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -127,7 +131,9 @@ namespace librealsense ds5_nonmonochrome(ctx, group), ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -165,7 +171,9 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -203,7 +211,9 @@ namespace librealsense ds5_nonmonochrome(ctx, group), ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -256,7 +266,9 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -306,7 +318,9 @@ namespace librealsense ds5_device(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -350,7 +364,9 @@ namespace librealsense : device(ctx, group, register_device_notifications), ds5_device(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -387,7 +403,9 @@ namespace librealsense ds5_device(ctx, group), ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -425,7 +443,9 @@ namespace librealsense ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), ds5_motion(ctx, group), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::vector get_profiles_tags() const override @@ -467,7 +487,9 @@ namespace librealsense ds5_active(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -515,7 +537,9 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -556,7 +580,9 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -597,7 +623,9 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) { check_and_restore_rgb_stream_extrinsic(); } @@ -815,7 +843,9 @@ namespace librealsense ds5_motion(ctx, group), ds5_nonmonochrome(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -851,7 +881,9 @@ namespace librealsense ds5_device(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -881,8 +913,9 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) - {} + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -926,7 +959,9 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, get_depth_sensor()) + firmware_logger_device(ds5_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index c25a028964..0f97d06f09 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -9,76 +9,14 @@ namespace librealsense { - std::map - firmware_logger_device::_logs_commands_per_group = - { - {LOGS_COMMANDS_GROUP_DS, {command{ds::GLD, 0x1f4}, command{ds::FRB, 0x17a000, 0x3f8}}}, - {LOGS_COMMANDS_GROUP_L5, {command{ivcam2::GLD, 0x1f4}, command{ivcam2::FRB, 0x0011E000, 0x3f8}}}, - {LOGS_COMMANDS_GROUP_SR, {command{ivcam::GLD, 0x1f4}, command{ivcam::FlashRead, 0x000B6000, 0x3f8}}} - }; - - - firmware_logger_device::logs_commands_group firmware_logger_device::get_logs_commands_group(uint16_t device_pid) - { - logs_commands_group group = LOGS_COMMANDS_GROUP_NONE; - switch (device_pid) - { - case ds::RS400_PID: - case ds::RS410_PID: - case ds::RS415_PID: - case ds::RS430_PID: - case ds::RS430_MM_PID: - case ds::RS_USB2_PID: - case ds::RS_RECOVERY_PID: - case ds::RS_USB2_RECOVERY_PID: - case ds::RS400_IMU_PID: - case ds::RS420_PID: - case ds::RS420_MM_PID: - case ds::RS410_MM_PID: - case ds::RS400_MM_PID: - case ds::RS430_MM_RGB_PID: - case ds::RS460_PID: - case ds::RS435_RGB_PID: - case ds::RS405U_PID: - case ds::RS435I_PID: - case ds::RS416_PID: - case ds::RS430I_PID: - case ds::RS465_PID: - case ds::RS416_RGB_PID: - case ds::RS405_PID: - case ds::RS455_PID: - group = LOGS_COMMANDS_GROUP_DS; - break; - case L500_RECOVERY_PID: - case L500_PID: - case L515_PID_PRE_PRQ: - case L515_PID: - group = LOGS_COMMANDS_GROUP_L5; - break; - case SR300_PID: - case SR300v2_PID: - case SR300_RECOVERY: - group = LOGS_COMMANDS_GROUP_SR; - break; - default: - break; - } - return group; - } - firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor, - const synthetic_sensor& depth_sensor) : + const command& fw_logs_command, const command& flash_logs_command) : _hw_monitor(hardware_monitor), _fw_logs(), _flash_logs(), _flash_logs_initialized(false), - _parser(nullptr) - { - std::string pid_str (depth_sensor.get_info(RS2_CAMERA_INFO_PRODUCT_ID)); - std::stringstream ss; - ss << std::hex << pid_str; - ss >> _device_pid; - } + _parser(nullptr), _fw_logs_command(fw_logs_command), + _flash_logs_command(flash_logs_command) { } bool firmware_logger_device::get_fw_log(fw_logs::fw_logs_binary_data& binary_data) { @@ -102,19 +40,7 @@ namespace librealsense void firmware_logger_device::get_fw_logs_from_hw_monitor() { - logs_commands_group group = get_logs_commands_group(_device_pid); - if (group == LOGS_COMMANDS_GROUP_NONE) - { - LOG_INFO("Firmware logs not set for this device!"); - return; - } - auto it = _logs_commands_per_group.find(group); - if (it == _logs_commands_per_group.end()) - { - LOG_INFO("Firmware logs not set for this device!"); - return; - } - auto res = _hw_monitor->send(it->second.fw_logs_command); + auto res = _hw_monitor->send(_fw_logs_command); if (res.empty()) { return; @@ -137,19 +63,7 @@ namespace librealsense void firmware_logger_device::get_flash_logs_from_hw_monitor() { - logs_commands_group group = get_logs_commands_group(_device_pid); - if (group == LOGS_COMMANDS_GROUP_NONE) - { - LOG_INFO("Flash logs not set for this device!"); - return; - } - auto it = _logs_commands_per_group.find(group); - if (it == _logs_commands_per_group.end()) - { - LOG_INFO("Flash logs not set for this device!"); - return; - } - auto res = _hw_monitor->send(it->second.flash_logs_command); + auto res = _hw_monitor->send(_flash_logs_command); if (res.empty()) { diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index dbe718d532..5e41ca17df 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -26,7 +26,7 @@ namespace librealsense { public: firmware_logger_device(std::shared_ptr hardware_monitor, - const synthetic_sensor& depth_sensor); + const command& _fw_logs_command, const command& _flash_logs_command); bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) override; bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) override; @@ -35,26 +35,13 @@ namespace librealsense bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) override; private: - enum logs_commands_group - { - LOGS_COMMANDS_GROUP_NONE, - LOGS_COMMANDS_GROUP_DS, - LOGS_COMMANDS_GROUP_L5, - LOGS_COMMANDS_GROUP_SR, - LOGS_COMMANDS_GROUP_COUNT - }; - struct logs_commands - { - command fw_logs_command; - command flash_logs_command; - }; - static std::map _logs_commands_per_group; - - logs_commands_group get_logs_commands_group(uint16_t device_pid); void get_fw_logs_from_hw_monitor(); void get_flash_logs_from_hw_monitor(); + command _fw_logs_command; + command _flash_logs_command; + std::shared_ptr _hw_monitor; std::queue _fw_logs; diff --git a/src/ivcam/sr300.cpp b/src/ivcam/sr300.cpp index ae052691f7..e903b7bce1 100644 --- a/src/ivcam/sr300.cpp +++ b/src/ivcam/sr300.cpp @@ -422,7 +422,7 @@ namespace librealsense const platform::backend_device_group& group, bool register_device_notifications) : device(ctx, group, register_device_notifications), - firmware_logger_device(_hw_monitor, get_depth_sensor()), + firmware_logger_device(_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()), _depth_device_idx(add_sensor(create_depth_device(ctx, depth))), _depth_stream(new stream(RS2_STREAM_DEPTH)), _ir_stream(new stream(RS2_STREAM_INFRARED)), @@ -507,6 +507,16 @@ namespace librealsense } + command sr300_camera::get_firmware_logs_command() const + { + return command{ ivcam::GLD, 0x1f4 }; + } + + command sr300_camera::get_flash_logs_command() const + { + return command{ ivcam::FlashRead, 0x000B6000, 0x3f8 }; + } + void sr300_camera::create_snapshot(std::shared_ptr& snapshot) const { //TODO: implement diff --git a/src/ivcam/sr300.h b/src/ivcam/sr300.h index 8a88392d7b..c6a34bb319 100644 --- a/src/ivcam/sr300.h +++ b/src/ivcam/sr300.h @@ -534,6 +534,9 @@ namespace librealsense lazy _camer_calib_params; protected: + command get_firmware_logs_command() const; + command get_flash_logs_command() const; + const uint8_t _color_device_idx; std::shared_ptr _hw_monitor; }; diff --git a/src/l500/l500-device.cpp b/src/l500/l500-device.cpp index 9a1187f712..5833600580 100644 --- a/src/l500/l500-device.cpp +++ b/src/l500/l500-device.cpp @@ -467,6 +467,16 @@ namespace librealsense }); } + command l500_device::get_firmware_logs_command() const + { + return command{ ivcam2::GLD, 0x1f4 }; + } + + command l500_device::get_flash_logs_command() const + { + return command{ ivcam2::FRB, 0x0011E000, 0x3f8 }; + } + notification l500_notification_decoder::decode(int value) { if (l500_fw_error_report.find(static_cast(value)) != l500_fw_error_report.end()) diff --git a/src/l500/l500-device.h b/src/l500/l500-device.h index 73a62a1ab7..a01bda80a2 100644 --- a/src/l500/l500-device.h +++ b/src/l500/l500-device.h @@ -78,6 +78,9 @@ namespace librealsense void force_hardware_reset() const; bool _is_locked = true; + command get_firmware_logs_command() const; + command get_flash_logs_command() const; + std::vector _advanced_options; }; diff --git a/src/l500/l500-factory.cpp b/src/l500/l500-factory.cpp index 51297c5626..7bf33bd82e 100644 --- a/src/l500/l500-factory.cpp +++ b/src/l500/l500-factory.cpp @@ -42,7 +42,9 @@ namespace librealsense l500_color(ctx, group), l500_motion(ctx, group), l500_serializable(l500_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(l500_device::_hw_monitor, get_depth_sensor()) + firmware_logger_device(l500_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; @@ -72,7 +74,9 @@ namespace librealsense : device(ctx, group, register_device_notifications), l500_device(ctx, group), l500_depth(ctx, group), - firmware_logger_device(l500_device::_hw_monitor, get_depth_sensor()) + firmware_logger_device(l500_device::_hw_monitor, + get_firmware_logs_command(), + get_flash_logs_command()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; From 76470ea37958533cf7961c16c2f07686b42bf191 Mon Sep 17 00:00:00 2001 From: remibettan Date: Thu, 18 Jun 2020 15:13:54 +0300 Subject: [PATCH 37/61] rs-fw-logger code correction --- tools/fw-logger/rs-fw-logger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/fw-logger/rs-fw-logger.cpp b/tools/fw-logger/rs-fw-logger.cpp index 4838cdc524..79ba9b656c 100644 --- a/tools/fw-logger/rs-fw-logger.cpp +++ b/tools/fw-logger/rs-fw-logger.cpp @@ -132,7 +132,7 @@ int main(int argc, char* argv[]) std::vector msg_data = log_message.data(); for (int i = 0; i < msg_data.size(); ++i) { - sstr << char2hex(raw_data[i]) << " "; + sstr << char2hex(msg_data[i]) << " "; } fw_log_lines.push_back(sstr.str()); } From 4d645d6ef9a73d241d5dd93dee1d36d35e756cce Mon Sep 17 00:00:00 2001 From: remibettan Date: Thu, 18 Jun 2020 15:23:52 +0300 Subject: [PATCH 38/61] remove unnecessary includes --- src/firmware_logger_device.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 0f97d06f09..ef53d64c15 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -2,9 +2,6 @@ // Copyright(c) 2020 Intel Corporation. All Rights Reserved. #include "firmware_logger_device.h" -#include "ds5/ds5-private.h" -#include "l500/l500-private.h" -#include "ivcam/sr300.h" #include namespace librealsense From d32d694fb26bdd0fe894b46f620011f9cae4e4ae Mon Sep 17 00:00:00 2001 From: remibettan Date: Thu, 18 Jun 2020 15:56:02 +0300 Subject: [PATCH 39/61] moving api code of fw logs and terminal_parser to rs_internal --- include/CMakeLists.txt | 4 - include/librealsense2/h/rs_firmware_logs.h | 175 ------------- include/librealsense2/h/rs_internal.h | 195 ++++++++++++++ include/librealsense2/h/rs_terminal_parser.h | 63 ----- .../librealsense2/hpp/rs_firmware_logs.hpp | 203 -------------- include/librealsense2/hpp/rs_internal.hpp | 247 ++++++++++++++++++ .../librealsense2/hpp/rs_terminal_parser.hpp | 76 ------ include/librealsense2/rs.h | 2 - include/librealsense2/rs.hpp | 2 - src/ds5/ds5-device.h | 1 + src/ivcam/sr300.h | 2 + src/l500/l500-device.h | 1 + tools/fw-logger/rs-fw-logger.cpp | 3 +- 13 files changed, 448 insertions(+), 526 deletions(-) delete mode 100644 include/librealsense2/h/rs_firmware_logs.h delete mode 100644 include/librealsense2/h/rs_terminal_parser.h delete mode 100644 include/librealsense2/hpp/rs_firmware_logs.hpp delete mode 100644 include/librealsense2/hpp/rs_terminal_parser.hpp diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index fff0107534..81d8cdc93c 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -16,8 +16,6 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_internal.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_pipeline.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_config.h" - "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_firmware_logs.h" - "${CMAKE_CURRENT_LIST_DIR}/librealsense2/h/rs_terminal_parser.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_types.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_context.hpp" @@ -31,8 +29,6 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_options.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_internal.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_pipeline.hpp" - "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_firmware_logs.hpp" - "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_terminal_parser.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/rsutil.h" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/rs_advanced_mode.h" diff --git a/include/librealsense2/h/rs_firmware_logs.h b/include/librealsense2/h/rs_firmware_logs.h deleted file mode 100644 index 9ad98a17fd..0000000000 --- a/include/librealsense2/h/rs_firmware_logs.h +++ /dev/null @@ -1,175 +0,0 @@ -/* License: Apache 2.0. See LICENSE file in root directory. - Copyright(c) 2020 Intel Corporation. All Rights Reserved. */ - -/** \file rs_firmware_logs.h -* \brief Exposes RealSense firmware logs functionality for C compilers -*/ - - -#ifndef LIBREALSENSE_RS2_FIRMWARE_LOGS_H -#define LIBREALSENSE_RS2_FIRMWARE_LOGS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "rs_types.h" - -/** -* \brief Creates RealSense firmware log message. -* \param[in] dev Device from which the FW log will be taken using the created message -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return pointer to created empty firmware log message -*/ -rs2_firmware_log_message* rs2_create_fw_log_message(rs2_device* dev, rs2_error** error); - -/** -* \brief Gets RealSense firmware log. -* \param[in] dev Device from which the FW log should be taken -* \param[in] fw_log_msg Firmware log message object to be filled -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor -*/ -int rs2_get_fw_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); - -/** -* \brief Gets RealSense flash log - this is a fw log that has been written in the device during the previous shutdown of the device -* \param[in] dev Device from which the FW log should be taken -* \param[in] fw_log_msg Firmware log message object to be filled -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor -*/ -int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); - -/** -* Delete RealSense firmware log message -* \param[in] device Realsense firmware log message to delete -*/ -void rs2_delete_fw_log_message(rs2_firmware_log_message* msg); - -/** -* \brief Gets RealSense firmware log message data. -* \param[in] msg firmware log message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return pointer to start of the firmware log message data -*/ -const unsigned char* rs2_fw_log_message_data(rs2_firmware_log_message* msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log message size. -* \param[in] msg firmware log message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return size of the firmware log message data -*/ -int rs2_fw_log_message_size(rs2_firmware_log_message* msg, rs2_error** error); - - -/** -* \brief Gets RealSense firmware log message timestamp. -* \param[in] msg firmware log message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return timestamp of the firmware log message -*/ -unsigned int rs2_fw_log_message_timestamp(rs2_firmware_log_message* msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log message severity. -* \param[in] msg firmware log message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return severity of the firmware log message data -*/ -rs2_log_severity rs2_fw_log_message_severity(const rs2_firmware_log_message* msg, rs2_error** error); - -/** -* \brief Initializes RealSense firmware logs parser in device. -* \param[in] dev Device from which the FW log will be taken -* \param[in] xml_content content of the xml file needed for parsing -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return true for success, false for failure - failure happens if opening the xml from the xml_path input fails -*/ -int rs2_init_fw_log_parser(rs2_device* dev, const char* xml_content, rs2_error** error); - - -/** -* \brief Creates RealSense firmware log parsed message. -* \param[in] dev Device from which the FW log will be taken using the created message -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return pointer to created empty firmware log message -*/ -rs2_firmware_log_parsed_message* rs2_create_fw_log_parsed_message(rs2_device* dev, rs2_error** error); - -/** -* \brief Deletes RealSense firmware log parsed message. -* \param[in] msg message to be deleted -*/ -void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); - - -/** -* \brief Gets RealSense firmware log parser -* \param[in] dev Device from which the FW log will be taken -* \param[in] fw_log_msg firmware log message to be parsed -* \param[in] parsed_msg firmware log parsed message - place holder for the resulting parsed message -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return true for success, false for failure - failure happens if message could not be parsed -*/ -int rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_firmware_log_parsed_message* parsed_msg, rs2_error** error); - -/** -* Delete RealSense firmware log parsed message -* \param[in] device Realsense firmware log parsed message to delete -*/ -void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); - -/** -* \brief Gets RealSense firmware log parsed message. -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return message of the firmware log parsed message -*/ -const char* rs2_get_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log parsed message file name. -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return file name of the firmware log parsed message -*/ -const char* rs2_get_fw_log_parsed_file_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log parsed message thread name. -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return thread name of the firmware log parsed message -*/ -const char* rs2_get_fw_log_parsed_thread_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log parsed message severity. -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return severity of the firmware log parsed message -*/ -rs2_log_severity rs2_get_fw_log_parsed_severity(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log parsed message relevant line (in the file that is returned by rs2_get_fw_log_parsed_file_name). -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return line number of the firmware log parsed message -*/ -unsigned int rs2_get_fw_log_parsed_line(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - -/** -* \brief Gets RealSense firmware log parsed message timestamp -* \param[in] fw_log_parsed_msg firmware log parsed message object -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return timestamp of the firmware log parsed message -*/ -unsigned int rs2_get_fw_log_parsed_timestamp(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/librealsense2/h/rs_internal.h b/include/librealsense2/h/rs_internal.h index 3fe6bdcbb0..b5150507b7 100644 --- a/include/librealsense2/h/rs_internal.h +++ b/include/librealsense2/h/rs_internal.h @@ -347,6 +347,201 @@ void rs2_software_sensor_add_option(rs2_sensor* sensor, rs2_option option, float */ void rs2_software_sensor_detach(rs2_sensor* sensor, rs2_error** error); + +/** +* \brief Creates RealSense firmware log message. +* \param[in] dev Device from which the FW log will be taken using the created message +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return pointer to created empty firmware log message +*/ +rs2_firmware_log_message* rs2_create_fw_log_message(rs2_device* dev, rs2_error** error); + +/** +* \brief Gets RealSense firmware log. +* \param[in] dev Device from which the FW log should be taken +* \param[in] fw_log_msg Firmware log message object to be filled +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor +*/ +int rs2_get_fw_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); + +/** +* \brief Gets RealSense flash log - this is a fw log that has been written in the device during the previous shutdown of the device +* \param[in] dev Device from which the FW log should be taken +* \param[in] fw_log_msg Firmware log message object to be filled +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor +*/ +int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error); + +/** +* Delete RealSense firmware log message +* \param[in] device Realsense firmware log message to delete +*/ +void rs2_delete_fw_log_message(rs2_firmware_log_message* msg); + +/** +* \brief Gets RealSense firmware log message data. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return pointer to start of the firmware log message data +*/ +const unsigned char* rs2_fw_log_message_data(rs2_firmware_log_message* msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log message size. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return size of the firmware log message data +*/ +int rs2_fw_log_message_size(rs2_firmware_log_message* msg, rs2_error** error); + + +/** +* \brief Gets RealSense firmware log message timestamp. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return timestamp of the firmware log message +*/ +unsigned int rs2_fw_log_message_timestamp(rs2_firmware_log_message* msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log message severity. +* \param[in] msg firmware log message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return severity of the firmware log message data +*/ +rs2_log_severity rs2_fw_log_message_severity(const rs2_firmware_log_message* msg, rs2_error** error); + +/** +* \brief Initializes RealSense firmware logs parser in device. +* \param[in] dev Device from which the FW log will be taken +* \param[in] xml_content content of the xml file needed for parsing +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return true for success, false for failure - failure happens if opening the xml from the xml_path input fails +*/ +int rs2_init_fw_log_parser(rs2_device* dev, const char* xml_content, rs2_error** error); + + +/** +* \brief Creates RealSense firmware log parsed message. +* \param[in] dev Device from which the FW log will be taken using the created message +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return pointer to created empty firmware log message +*/ +rs2_firmware_log_parsed_message* rs2_create_fw_log_parsed_message(rs2_device* dev, rs2_error** error); + +/** +* \brief Deletes RealSense firmware log parsed message. +* \param[in] msg message to be deleted +*/ +void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); + + +/** +* \brief Gets RealSense firmware log parser +* \param[in] dev Device from which the FW log will be taken +* \param[in] fw_log_msg firmware log message to be parsed +* \param[in] parsed_msg firmware log parsed message - place holder for the resulting parsed message +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return true for success, false for failure - failure happens if message could not be parsed +*/ +int rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_firmware_log_parsed_message* parsed_msg, rs2_error** error); + +/** +* Delete RealSense firmware log parsed message +* \param[in] device Realsense firmware log parsed message to delete +*/ +void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); + +/** +* \brief Gets RealSense firmware log parsed message. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return message of the firmware log parsed message +*/ +const char* rs2_get_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message file name. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return file name of the firmware log parsed message +*/ +const char* rs2_get_fw_log_parsed_file_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message thread name. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return thread name of the firmware log parsed message +*/ +const char* rs2_get_fw_log_parsed_thread_name(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message severity. +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return severity of the firmware log parsed message +*/ +rs2_log_severity rs2_get_fw_log_parsed_severity(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message relevant line (in the file that is returned by rs2_get_fw_log_parsed_file_name). +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return line number of the firmware log parsed message +*/ +unsigned int rs2_get_fw_log_parsed_line(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Gets RealSense firmware log parsed message timestamp +* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return timestamp of the firmware log parsed message +*/ +unsigned int rs2_get_fw_log_parsed_timestamp(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); + +/** +* \brief Creates RealSense terminal parser. +* \param[in] xml_content content of the xml file needed for parsing +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return pointer to created terminal parser object +*/ +rs2_terminal_parser* rs2_create_terminal_parser(const char* xml_content, rs2_error** error); + +/** +* \brief Deletes RealSense terminal parser. +* \param[in] terminal_parser terminal parser to be deleted +*/ +void rs2_delete_terminal_parser(rs2_terminal_parser* terminal_parser); + +/** +* \brief Parses terminal command via RealSense terminal parser +* \param[in] terminal_parser Terminal parser object +* \param[in] command command to be sent to the hw monitor of the device +* \param[in] size_of_command size of command to be sent to the hw monitor of the device +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return command to hw monitor, in hex +*/ +rs2_raw_data_buffer* rs2_terminal_parse_command(rs2_terminal_parser* terminal_parser, + const char* command, unsigned int size_of_command, rs2_error** error); + +/** +* \brief Parses terminal response via RealSense terminal parser +* \param[in] terminal_parser Terminal parser object +* \param[in] command command sent to the hw monitor of the device +* \param[in] size_of_command size of the command to sent to the hw monitor of the device +* \param[in] response response received by the hw monitor of the device +* \param[in] size_of_response size of the response received by the hw monitor of the device +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return answer parsed +*/ +rs2_raw_data_buffer* rs2_terminal_parse_response(rs2_terminal_parser* terminal_parser, + const char* command, unsigned int size_of_command, + const void* response, unsigned int size_of_response, rs2_error** error); + + #ifdef __cplusplus } #endif diff --git a/include/librealsense2/h/rs_terminal_parser.h b/include/librealsense2/h/rs_terminal_parser.h deleted file mode 100644 index 3bb9239c9e..0000000000 --- a/include/librealsense2/h/rs_terminal_parser.h +++ /dev/null @@ -1,63 +0,0 @@ -/* License: Apache 2.0. See LICENSE file in root directory. - Copyright(c) 2020 Intel Corporation. All Rights Reserved. */ - -/** \file rs_terminal.h -* \brief Exposes RealSense terminal functionality for C compilers -*/ - - -#ifndef LIBREALSENSE_RS2_TERMINAL_H -#define LIBREALSENSE_RS2_TERMINAL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "rs_types.h" - -/** -* \brief Creates RealSense terminal parser. -* \param[in] xml_content content of the xml file needed for parsing -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return pointer to created terminal parser object -*/ -rs2_terminal_parser* rs2_create_terminal_parser(const char* xml_content, rs2_error** error); - -/** -* \brief Deletes RealSense terminal parser. -* \param[in] terminal_parser terminal parser to be deleted -*/ -void rs2_delete_terminal_parser(rs2_terminal_parser* terminal_parser); - -/** -* \brief Parses terminal command via RealSense terminal parser -* \param[in] terminal_parser Terminal parser object -* \param[in] command command to be sent to the hw monitor of the device -* \param[in] size_of_command size of command to be sent to the hw monitor of the device -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return command to hw monitor, in hex -*/ -rs2_raw_data_buffer* rs2_terminal_parse_command(rs2_terminal_parser* terminal_parser, - const char* command, unsigned int size_of_command, rs2_error** error); - -/** -* \brief Parses terminal response via RealSense terminal parser -* \param[in] terminal_parser Terminal parser object -* \param[in] command command sent to the hw monitor of the device -* \param[in] size_of_command size of the command to sent to the hw monitor of the device -* \param[in] response response received by the hw monitor of the device -* \param[in] size_of_response size of the response received by the hw monitor of the device -* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. -* \return answer parsed -*/ -rs2_raw_data_buffer* rs2_terminal_parse_response(rs2_terminal_parser* terminal_parser, - const char* command, unsigned int size_of_command, - const void* response, unsigned int size_of_response, rs2_error** error); - - - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/librealsense2/hpp/rs_firmware_logs.hpp b/include/librealsense2/hpp/rs_firmware_logs.hpp deleted file mode 100644 index 1b1d005ba1..0000000000 --- a/include/librealsense2/hpp/rs_firmware_logs.hpp +++ /dev/null @@ -1,203 +0,0 @@ -// License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2020 Intel Corporation. All Rights Reserved. - -#ifndef LIBREALSENSE_RS2_FIRMWARE_LOGS_HPP -#define LIBREALSENSE_RS2_FIRMWARE_LOGS_HPP - -#include "rs_types.hpp" -#include "rs_sensor.hpp" -#include "../h/rs_firmware_logs.h" - -namespace rs2 -{ - class firmware_log_message - { - public: - explicit firmware_log_message(std::shared_ptr msg): - _fw_log_message(msg){} - - rs2_log_severity get_severity() const { - rs2_error* e = nullptr; - rs2_log_severity severity = rs2_fw_log_message_severity(_fw_log_message.get(), &e); - error::handle(e); - return severity; - } - std::string get_severity_str() const { - return rs2_log_severity_to_string(get_severity()); - } - - uint32_t get_timestamp() const - { - rs2_error* e = nullptr; - uint32_t timestamp = rs2_fw_log_message_timestamp(_fw_log_message.get(), &e); - error::handle(e); - return timestamp; - } - - int size() const - { - rs2_error* e = nullptr; - int size = rs2_fw_log_message_size(_fw_log_message.get(), &e); - error::handle(e); - return size; - } - - std::vector data() const - { - rs2_error* e = nullptr; - auto size = rs2_fw_log_message_size(_fw_log_message.get(), &e); - error::handle(e); - std::vector result; - if (size > 0) - { - auto start = rs2_fw_log_message_data(_fw_log_message.get(), &e); - error::handle(e); - result.insert(result.begin(), start, start + size); - } - return result; - } - - const std::shared_ptr get_message() const { return _fw_log_message; } - - private: - std::shared_ptr _fw_log_message; - }; - - class firmware_log_parsed_message - { - public: - explicit firmware_log_parsed_message(std::shared_ptr msg) : - _parsed_fw_log(msg) {} - - std::string message() const - { - rs2_error* e = nullptr; - std::string msg(rs2_get_fw_log_parsed_message(_parsed_fw_log.get(), &e)); - error::handle(e); - return msg; - } - std::string file_name() const - { - rs2_error* e = nullptr; - std::string file_name(rs2_get_fw_log_parsed_file_name(_parsed_fw_log.get(), &e)); - error::handle(e); - return file_name; - } - std::string thread_name() const - { - rs2_error* e = nullptr; - std::string thread_name(rs2_get_fw_log_parsed_thread_name(_parsed_fw_log.get(), &e)); - error::handle(e); - return thread_name; - } - std::string severity() const - { - rs2_error* e = nullptr; - rs2_log_severity sev = rs2_get_fw_log_parsed_severity(_parsed_fw_log.get(), &e); - error::handle(e); - return std::string(rs2_log_severity_to_string(sev)); - } - uint32_t line() const - { - rs2_error* e = nullptr; - uint32_t line(rs2_get_fw_log_parsed_line(_parsed_fw_log.get(), &e)); - error::handle(e); - return line; - } - uint32_t timestamp() const - { - rs2_error* e = nullptr; - uint32_t timestamp(rs2_get_fw_log_parsed_timestamp(_parsed_fw_log.get(), &e)); - error::handle(e); - return timestamp; - } - - const std::shared_ptr get_message() const { return _parsed_fw_log; } - - private: - std::shared_ptr _parsed_fw_log; - }; - - class firmware_logger : public device - { - public: - firmware_logger(device d) - : device(d.get()) - { - rs2_error* e = nullptr; - if (rs2_is_device_extendable_to(_dev.get(), RS2_EXTENSION_FW_LOGGER, &e) == 0 && !e) - { - _dev.reset(); - } - error::handle(e); - } - - rs2::firmware_log_message create_message() - { - rs2_error* e = nullptr; - std::shared_ptr msg( - rs2_create_fw_log_message(_dev.get(), &e), - rs2_delete_fw_log_message); - error::handle(e); - - return firmware_log_message(msg); - } - - rs2::firmware_log_parsed_message create_parsed_message() - { - rs2_error* e = nullptr; - std::shared_ptr msg( - rs2_create_fw_log_parsed_message(_dev.get(), &e), - rs2_delete_fw_log_parsed_message); - error::handle(e); - - return firmware_log_parsed_message(msg); - } - - bool get_firmware_log(rs2::firmware_log_message& msg) const - { - rs2_error* e = nullptr; - rs2_firmware_log_message* m = msg.get_message().get(); - bool fw_log_pulling_status = - rs2_get_fw_log(_dev.get(), &(m), &e); - - error::handle(e); - - return fw_log_pulling_status; - } - - bool get_flash_log(rs2::firmware_log_message& msg) const - { - rs2_error* e = nullptr; - rs2_firmware_log_message* m = msg.get_message().get(); - bool flash_log_pulling_status = - rs2_get_flash_log(_dev.get(), &(m), &e); - - error::handle(e); - - return flash_log_pulling_status; - } - - bool init_parser(const std::string& xml_content) - { - rs2_error* e = nullptr; - - bool parser_initialized = rs2_init_fw_log_parser(_dev.get(), xml_content.c_str(), &e); - error::handle(e); - - return parser_initialized; - } - - bool parse_log(const rs2::firmware_log_message& msg, const rs2::firmware_log_parsed_message& parsed_msg) - { - rs2_error* e = nullptr; - - bool parsingResult = rs2_parse_firmware_log(_dev.get(), msg.get_message().get(), parsed_msg.get_message().get(), &e); - error::handle(e); - - return parsingResult; - } - }; - -} -#endif // LIBREALSENSE_RS2_FIRMWARE_LOGS_HPP diff --git a/include/librealsense2/hpp/rs_internal.hpp b/include/librealsense2/hpp/rs_internal.hpp index 076a49c6a0..116449b2c9 100644 --- a/include/librealsense2/hpp/rs_internal.hpp +++ b/include/librealsense2/hpp/rs_internal.hpp @@ -363,5 +363,252 @@ namespace rs2 } }; + class firmware_log_message + { + public: + explicit firmware_log_message(std::shared_ptr msg) : + _fw_log_message(msg) {} + + rs2_log_severity get_severity() const { + rs2_error* e = nullptr; + rs2_log_severity severity = rs2_fw_log_message_severity(_fw_log_message.get(), &e); + error::handle(e); + return severity; + } + std::string get_severity_str() const { + return rs2_log_severity_to_string(get_severity()); + } + + uint32_t get_timestamp() const + { + rs2_error* e = nullptr; + uint32_t timestamp = rs2_fw_log_message_timestamp(_fw_log_message.get(), &e); + error::handle(e); + return timestamp; + } + + int size() const + { + rs2_error* e = nullptr; + int size = rs2_fw_log_message_size(_fw_log_message.get(), &e); + error::handle(e); + return size; + } + + std::vector data() const + { + rs2_error* e = nullptr; + auto size = rs2_fw_log_message_size(_fw_log_message.get(), &e); + error::handle(e); + std::vector result; + if (size > 0) + { + auto start = rs2_fw_log_message_data(_fw_log_message.get(), &e); + error::handle(e); + result.insert(result.begin(), start, start + size); + } + return result; + } + + const std::shared_ptr get_message() const { return _fw_log_message; } + + private: + std::shared_ptr _fw_log_message; + }; + + class firmware_log_parsed_message + { + public: + explicit firmware_log_parsed_message(std::shared_ptr msg) : + _parsed_fw_log(msg) {} + + std::string message() const + { + rs2_error* e = nullptr; + std::string msg(rs2_get_fw_log_parsed_message(_parsed_fw_log.get(), &e)); + error::handle(e); + return msg; + } + std::string file_name() const + { + rs2_error* e = nullptr; + std::string file_name(rs2_get_fw_log_parsed_file_name(_parsed_fw_log.get(), &e)); + error::handle(e); + return file_name; + } + std::string thread_name() const + { + rs2_error* e = nullptr; + std::string thread_name(rs2_get_fw_log_parsed_thread_name(_parsed_fw_log.get(), &e)); + error::handle(e); + return thread_name; + } + std::string severity() const + { + rs2_error* e = nullptr; + rs2_log_severity sev = rs2_get_fw_log_parsed_severity(_parsed_fw_log.get(), &e); + error::handle(e); + return std::string(rs2_log_severity_to_string(sev)); + } + uint32_t line() const + { + rs2_error* e = nullptr; + uint32_t line(rs2_get_fw_log_parsed_line(_parsed_fw_log.get(), &e)); + error::handle(e); + return line; + } + uint32_t timestamp() const + { + rs2_error* e = nullptr; + uint32_t timestamp(rs2_get_fw_log_parsed_timestamp(_parsed_fw_log.get(), &e)); + error::handle(e); + return timestamp; + } + + const std::shared_ptr get_message() const { return _parsed_fw_log; } + + private: + std::shared_ptr _parsed_fw_log; + }; + + class firmware_logger : public device + { + public: + firmware_logger(device d) + : device(d.get()) + { + rs2_error* e = nullptr; + if (rs2_is_device_extendable_to(_dev.get(), RS2_EXTENSION_FW_LOGGER, &e) == 0 && !e) + { + _dev.reset(); + } + error::handle(e); + } + + rs2::firmware_log_message create_message() + { + rs2_error* e = nullptr; + std::shared_ptr msg( + rs2_create_fw_log_message(_dev.get(), &e), + rs2_delete_fw_log_message); + error::handle(e); + + return firmware_log_message(msg); + } + + rs2::firmware_log_parsed_message create_parsed_message() + { + rs2_error* e = nullptr; + std::shared_ptr msg( + rs2_create_fw_log_parsed_message(_dev.get(), &e), + rs2_delete_fw_log_parsed_message); + error::handle(e); + + return firmware_log_parsed_message(msg); + } + + bool get_firmware_log(rs2::firmware_log_message& msg) const + { + rs2_error* e = nullptr; + rs2_firmware_log_message* m = msg.get_message().get(); + bool fw_log_pulling_status = + rs2_get_fw_log(_dev.get(), &(m), &e); + + error::handle(e); + + return fw_log_pulling_status; + } + + bool get_flash_log(rs2::firmware_log_message& msg) const + { + rs2_error* e = nullptr; + rs2_firmware_log_message* m = msg.get_message().get(); + bool flash_log_pulling_status = + rs2_get_flash_log(_dev.get(), &(m), &e); + + error::handle(e); + + return flash_log_pulling_status; + } + + bool init_parser(const std::string& xml_content) + { + rs2_error* e = nullptr; + + bool parser_initialized = rs2_init_fw_log_parser(_dev.get(), xml_content.c_str(), &e); + error::handle(e); + + return parser_initialized; + } + + bool parse_log(const rs2::firmware_log_message& msg, const rs2::firmware_log_parsed_message& parsed_msg) + { + rs2_error* e = nullptr; + + bool parsingResult = rs2_parse_firmware_log(_dev.get(), msg.get_message().get(), parsed_msg.get_message().get(), &e); + error::handle(e); + + return parsingResult; + } + }; + + class terminal_parser + { + public: + terminal_parser(const std::string& xml_content) + { + rs2_error* e = nullptr; + + _terminal_parser = std::shared_ptr( + rs2_create_terminal_parser(xml_content.c_str(), &e), + rs2_delete_terminal_parser); + error::handle(e); + } + + std::vector parse_command(const std::string& command) + { + rs2_error* e = nullptr; + + std::shared_ptr list( + rs2_terminal_parse_command(_terminal_parser.get(), command.c_str(), command.size(), &e), + rs2_delete_raw_data); + error::handle(e); + + auto size = rs2_get_raw_data_size(list.get(), &e); + error::handle(e); + + auto start = rs2_get_raw_data(list.get(), &e); + + std::vector results; + results.insert(results.begin(), start, start + size); + + return results; + } + + std::string parse_response(const std::string& command, const std::vector& response) + { + rs2_error* e = nullptr; + + std::shared_ptr list( + rs2_terminal_parse_response(_terminal_parser.get(), command.c_str(), command.size(), + (void*)response.data(), response.size(), &e), + rs2_delete_raw_data); + error::handle(e); + + auto size = rs2_get_raw_data_size(list.get(), &e); + error::handle(e); + + auto start = rs2_get_raw_data(list.get(), &e); + + std::string results; + results.insert(results.begin(), start, start + size); + + return results; + } + + private: + std::shared_ptr _terminal_parser; + }; + } #endif // LIBREALSENSE_RS2_INTERNAL_HPP diff --git a/include/librealsense2/hpp/rs_terminal_parser.hpp b/include/librealsense2/hpp/rs_terminal_parser.hpp deleted file mode 100644 index 45ecf6c608..0000000000 --- a/include/librealsense2/hpp/rs_terminal_parser.hpp +++ /dev/null @@ -1,76 +0,0 @@ -// License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2020 Intel Corporation. All Rights Reserved. - -#ifndef LIBREALSENSE_RS2_TERMINAL_PARSER_HPP -#define LIBREALSENSE_RS2_TERMINAL_PARSER_HPP - -#include "rs_types.hpp" -#include "rs_sensor.hpp" -#include "rs_device.hpp" - -#include -#include - -namespace rs2 -{ - class terminal_parser - { - public: - terminal_parser(const std::string& xml_content) - { - rs2_error* e = nullptr; - - _terminal_parser = std::shared_ptr( - rs2_create_terminal_parser(xml_content.c_str(), &e), - rs2_delete_terminal_parser); - error::handle(e); - } - - std::vector parse_command(const std::string& command) - { - rs2_error* e = nullptr; - - std::shared_ptr list( - rs2_terminal_parse_command(_terminal_parser.get(), command.c_str(), command.size(), &e), - rs2_delete_raw_data); - error::handle(e); - - auto size = rs2_get_raw_data_size(list.get(), &e); - error::handle(e); - - auto start = rs2_get_raw_data(list.get(), &e); - - std::vector results; - results.insert(results.begin(), start, start + size); - - return results; - } - - std::string parse_response(const std::string& command, const std::vector& response) - { - rs2_error* e = nullptr; - - std::shared_ptr list( - rs2_terminal_parse_response(_terminal_parser.get(), command.c_str(), command.size(), - (void*)response.data(), response.size(), &e), - rs2_delete_raw_data); - error::handle(e); - - auto size = rs2_get_raw_data_size(list.get(), &e); - error::handle(e); - - auto start = rs2_get_raw_data(list.get(), &e); - - std::string results; - results.insert(results.begin(), start, start + size); - - return results; - } - - private: - std::shared_ptr _terminal_parser; - }; -} - - -#endif // LIBREALSENSE_RS2_TYPES_HPP diff --git a/include/librealsense2/rs.h b/include/librealsense2/rs.h index dfb29974d8..6976fff839 100644 --- a/include/librealsense2/rs.h +++ b/include/librealsense2/rs.h @@ -21,8 +21,6 @@ extern "C" { #include "h/rs_processing.h" #include "h/rs_record_playback.h" #include "h/rs_sensor.h" -#include "h/rs_firmware_logs.h" -#include "h/rs_terminal_parser.h" #define RS2_API_MAJOR_VERSION 2 #define RS2_API_MINOR_VERSION 35 diff --git a/include/librealsense2/rs.hpp b/include/librealsense2/rs.hpp index b41366102d..2a9ee2e334 100644 --- a/include/librealsense2/rs.hpp +++ b/include/librealsense2/rs.hpp @@ -13,8 +13,6 @@ #include "hpp/rs_record_playback.hpp" #include "hpp/rs_sensor.hpp" #include "hpp/rs_pipeline.hpp" -#include "hpp/rs_firmware_logs.hpp" -#include "hpp/rs_terminal_parser.hpp" namespace rs2 { diff --git a/src/ds5/ds5-device.h b/src/ds5/ds5-device.h index ec1f8d3c64..edb821d1d5 100644 --- a/src/ds5/ds5-device.h +++ b/src/ds5/ds5-device.h @@ -75,6 +75,7 @@ namespace librealsense ds::d400_caps parse_device_capabilities(const uint16_t pid) const; + //TODO - add these to device class as pure virtual methods command get_firmware_logs_command() const; command get_flash_logs_command() const; diff --git a/src/ivcam/sr300.h b/src/ivcam/sr300.h index c6a34bb319..8454baad62 100644 --- a/src/ivcam/sr300.h +++ b/src/ivcam/sr300.h @@ -534,6 +534,8 @@ namespace librealsense lazy _camer_calib_params; protected: + + //TODO - add these to device class as pure virtual methods command get_firmware_logs_command() const; command get_flash_logs_command() const; diff --git a/src/l500/l500-device.h b/src/l500/l500-device.h index a01bda80a2..44f3aa2e90 100644 --- a/src/l500/l500-device.h +++ b/src/l500/l500-device.h @@ -78,6 +78,7 @@ namespace librealsense void force_hardware_reset() const; bool _is_locked = true; + //TODO - add these to device class as pure virtual methods command get_firmware_logs_command() const; command get_flash_logs_command() const; diff --git a/tools/fw-logger/rs-fw-logger.cpp b/tools/fw-logger/rs-fw-logger.cpp index 79ba9b656c..53c29c60df 100644 --- a/tools/fw-logger/rs-fw-logger.cpp +++ b/tools/fw-logger/rs-fw-logger.cpp @@ -1,7 +1,8 @@ // License: Apache 2.0. See LICENSE file in root directory. // Copyright(c) 2015 Intel Corporation. All Rights Reserved. -#include +#include "librealsense2\rs.hpp" +#include "librealsense2\hpp\rs_internal.hpp" #include #include #include "tclap/CmdLine.h" From ac54c4e86afa98ec88a076d88f5e8ebcf3915b95 Mon Sep 17 00:00:00 2001 From: remibettan Date: Thu, 18 Jun 2020 22:35:28 +0300 Subject: [PATCH 40/61] correcting slash directions --- tools/fw-logger/rs-fw-logger.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/fw-logger/rs-fw-logger.cpp b/tools/fw-logger/rs-fw-logger.cpp index 53c29c60df..6085f86ba5 100644 --- a/tools/fw-logger/rs-fw-logger.cpp +++ b/tools/fw-logger/rs-fw-logger.cpp @@ -1,8 +1,8 @@ // License: Apache 2.0. See LICENSE file in root directory. // Copyright(c) 2015 Intel Corporation. All Rights Reserved. -#include "librealsense2\rs.hpp" -#include "librealsense2\hpp\rs_internal.hpp" +#include "librealsense2/rs.hpp" +#include "librealsense2/hpp/rs_internal.hpp" #include #include #include "tclap/CmdLine.h" From 7f044777eeb0ccf95e84599b9e1bb780d9627289 Mon Sep 17 00:00:00 2001 From: ev-mp Date: Fri, 19 Jun 2020 18:08:00 +0300 Subject: [PATCH 41/61] Update script for Ubuntu_18 LTS Kernels. Add support for Kernel 5.4 --- scripts/patch-utils.sh | 21 +- ...lsense-camera-formats-bionic-hwe-5.4.patch | 135 +++++++++ scripts/realsense-hid-bionic-hwe-5.4.patch | 108 +++++++ .../realsense-metadata-bionic-hwe-5.4.patch | 272 ++++++++++++++++++ 4 files changed, 529 insertions(+), 7 deletions(-) create mode 100644 scripts/realsense-camera-formats-bionic-hwe-5.4.patch create mode 100644 scripts/realsense-hid-bionic-hwe-5.4.patch create mode 100644 scripts/realsense-metadata-bionic-hwe-5.4.patch diff --git a/scripts/patch-utils.sh b/scripts/patch-utils.sh index e4e474188d..84dd5469f8 100755 --- a/scripts/patch-utils.sh +++ b/scripts/patch-utils.sh @@ -22,7 +22,7 @@ function require_package { #Based on the current kernel version select the branch name to fetch the kernel source code # The reference name are pulled here : http://kernel.ubuntu.com/git/ubuntu/ubuntu-xenial.git/ -# As of Jun 21, the status is +# As of Jun 19 # Branch Commit message Author Age # hwe UBUNTU: Ubuntu-hwe-4.15.0-24.26~16.04.1 Andy Whitcroft 6 days # hwe-edge UBUNTU: Ubuntu-hwe-4.15.0-23.25~16.04.1 Kleber Sacilotto de Souza 4 weeks @@ -30,11 +30,13 @@ function require_package { # master UBUNTU: Ubuntu-4.4.0-128.154 Stefan Bader 4 weeks # master-next UBUNTU: SAUCE: Redpine: fix soft-ap invisible issue Sanjay Kumar Konduri 2 days -# As of Jan 21, 2020 +# As of Jun 21, 2020 #Ubuntu bionic repo : http://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/ -# hwe UBUNTU: Ubuntu-hwe-5.3.0-28.30~18.04.1 Sultan Alsawaf 6 days -# hwe-edge UBUNTU: Ubuntu-hwe-edge-5.3.0-24.26~18.04.2 Kleber Sacilotto de Souza 8 weeks -# master UBUNTU: Ubuntu-4.15.0-74.84 Khalid Elmously 5 weeks +# hwe UBUNTU: Ubuntu-hwe-5.3.0-56.50~18.04.1 Kleber Sacilotto de Souza 3 weeks +# hwe-5.0 UBUNTU: Ubuntu-hwe-5.0-5.0.0-53.57~18.04.1 Sultan Alsawaf 7 days +# hwe-5.4 UBUNTU: Ubuntu-hwe-5.4-5.4.0-38.42~18.04.1 Stefan Bader 4 days +# hwe-edge UBUNTU: Ubuntu-hwe-edge-5.3.0-24.26~18.04.2 Kleber Sacilotto de Souza 7 months +# master UBUNTU: Ubuntu-4.15.0-106.107 Kleber Sacilotto de Souza 2 weeks # master-current UBUNTU: Ubuntu-4.15.0-66.75 Khalid Elmously 4 months function choose_kernel_branch { @@ -80,10 +82,15 @@ function choose_kernel_branch { echo Ubuntu-hwe-4.18.0-25.26_18.04.1 ;; "5.0") # kernel 5.0 for Ubuntu 18/Bionic Beaver - echo 5 + #echo hwe-5.0 + echo 5 ;; "5.3") # kernel 5.3 - echo 5 + #echo hwe + echo 5 + ;; + "5.4") # kernel 5.4 + echo hwe-5.4 ;; *) #error message shall be redirected to stderr to be printed properly diff --git a/scripts/realsense-camera-formats-bionic-hwe-5.4.patch b/scripts/realsense-camera-formats-bionic-hwe-5.4.patch new file mode 100644 index 0000000000..eabb4f04af --- /dev/null +++ b/scripts/realsense-camera-formats-bionic-hwe-5.4.patch @@ -0,0 +1,135 @@ +Subject: [PATCH] Streaming formats for Ubuntu 18.04 (Bionic Beaver), Kernel 5.4 +From 120e2ef648e5f906555407ff7265ce729fc6d503 Mon Sep 17 00:00:00 2001 +From: Evgeni Raikhel +Signed-off-by: Evgeni Raikhel +Date: Mon, 24 Jun 2019 10:25:39 +0300 + +--- + drivers/media/usb/uvc/uvc_driver.c | 37 ++++++++++++++++++++++++++++ + drivers/media/usb/uvc/uvcvideo.h | 22 +++++++++++++++++ + drivers/media/v4l2-core/v4l2-ioctl.c | 8 ++++++ + include/uapi/linux/videodev2.h | 8 ++++++ + 4 files changed, 75 insertions(+) + +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 99883550375e..443ecea63bd8 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -214,6 +214,43 @@ static struct uvc_format_desc uvc_fmts[] = { + .guid = UVC_GUID_FORMAT_CNF4, + .fcc = V4L2_PIX_FMT_CNF4, + }, ++ { ++ .name = "Depth data 16-bit (D16)", ++ .guid = UVC_GUID_FORMAT_D16, ++ .fcc = V4L2_PIX_FMT_Z16, ++ }, ++ { ++ .name = "Packed raw data 10-bit", ++ .guid = UVC_GUID_FORMAT_W10, ++ .fcc = V4L2_PIX_FMT_W10, ++ }, ++ { ++ .name = "Confidence data (C )", ++ .guid = UVC_GUID_FORMAT_CONFIDENCE_MAP, ++ .fcc = V4L2_PIX_FMT_CONFIDENCE_MAP, ++ }, ++ /* FishEye 8-bit monochrome */ ++ { ++ .name = "Raw data 8-bit (RAW8)", ++ .guid = UVC_GUID_FORMAT_RAW8, ++ .fcc = V4L2_PIX_FMT_GREY, ++ }, ++ /* Legacy formats for backward-compatibility*/ ++ { ++ .name = "Raw data 16-bit (RW16)", ++ .guid = UVC_GUID_FORMAT_RW16, ++ .fcc = V4L2_PIX_FMT_RW16, ++ }, ++ { ++ .name = "16-bit Bayer BGBG/GRGR", ++ .guid = UVC_GUID_FORMAT_BAYER16, ++ .fcc = V4L2_PIX_FMT_SBGGR16, ++ }, ++ { ++ .name = "Z16 Huffman Compression", ++ .guid = UVC_GUID_FORMAT_Z16H, ++ .fcc = V4L2_PIX_FMT_Z16H, ++ }, + }; + + /* ------------------------------------------------------------------------ +diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h +index 24e3d8c647e7..1aa8493a24d1 100644 +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -165,6 +165,28 @@ + {0x32, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} + ++ #define UVC_GUID_FORMAT_D16 \ ++ { 'P', 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ #define UVC_GUID_FORMAT_W10 \ ++ { 'W', '1', '0', ' ', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ #define UVC_GUID_FORMAT_RAW8 \ ++ { 'R', 'A', 'W', '8', 0x66, 0x1a, 0x42, 0xa2, \ ++ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} ++ #define UVC_GUID_FORMAT_CONFIDENCE_MAP \ ++ { 'C', ' ', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ /* Legacy formats */ ++ #define UVC_GUID_FORMAT_RW16 \ ++ { 'R', 'W', '1', '6', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ #define UVC_GUID_FORMAT_BAYER16 \ ++ { 'R', 'W', '1', '6', 0x66, 0x1a, 0x42, 0xa2, \ ++ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} ++ #define UVC_GUID_FORMAT_Z16H \ ++ { 'Z', '1', '6', 'H', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} + + /* ------------------------------------------------------------------------ + * Driver specific constants. +diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c +index 58868d7129eb..c29033b8439c 100644 +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1330,6 +1330,14 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) + case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break; + case V4L2_META_FMT_UVC: descr = "UVC Payload Header Metadata"; break; + case V4L2_META_FMT_D4XX: descr = "Intel D4xx UVC Metadata"; break; ++ /* Librealsense formats*/ ++ case V4L2_PIX_FMT_RW16: descr = "16-bit Raw data"; break; ++ case V4L2_PIX_FMT_W10: descr = "10-bit packed 8888[2222]"; break; ++ case V4L2_PIX_FMT_CONFIDENCE_MAP: descr = "Packed [44] confidence data"; break; ++ case V4L2_PIX_FMT_FG: descr = "Frame Grabber (FG )"; break; ++ case V4L2_PIX_FMT_INZC: descr = "Planar Depth/Confidence (INZC)"; break; ++ case V4L2_PIX_FMT_PAIR: descr = "Relative IR (PAIR)"; break; ++ case V4L2_PIX_FMT_Z16H: descr = "Z16 Huffman Compression"; break; + + default: + /* Compressed formats */ +diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h +index 530638dffd93..d7c85713e32c 100644 +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -727,6 +727,14 @@ struct v4l2_pix_format { + #define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */ + #define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */ + #define V4L2_PIX_FMT_CNF4 v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit packed depth confidence information */ ++#define V4L2_PIX_FMT_RW16 v4l2_fourcc('R', 'W', '1', '6') /* Raw data 16-bit */ ++#define V4L2_PIX_FMT_W10 v4l2_fourcc('W', '1', '0', ' ') /* Packed raw data 10-bit */ ++#define V4L2_PIX_FMT_CONFIDENCE_MAP v4l2_fourcc('C', ' ', ' ', ' ') /* Two pixels in one byte */ ++/* Librealsense development*/ ++#define V4L2_PIX_FMT_FG v4l2_fourcc('F', 'G', ' ', ' ') /* Frame Grabber */ ++#define V4L2_PIX_FMT_INZC v4l2_fourcc('I', 'N', 'Z', 'C') /* Planar Depth/Confidence */ ++#define V4L2_PIX_FMT_PAIR v4l2_fourcc('P', 'A', 'I', 'R') /* Relative IR */ ++#define V4L2_PIX_FMT_Z16H v4l2_fourcc('Z', '1', '6', 'H') /* Depth Z16 custom Huffman Code compression*/ + + /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */ + #define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */ +-- +2.17.1 + diff --git a/scripts/realsense-hid-bionic-hwe-5.4.patch b/scripts/realsense-hid-bionic-hwe-5.4.patch new file mode 100644 index 0000000000..a83a885e1d --- /dev/null +++ b/scripts/realsense-hid-bionic-hwe-5.4.patch @@ -0,0 +1,108 @@ +Signed-off-by: Evgeni +From 001649b143e1a4e0924ac6fc47883a45ba28ff63 Mon Sep 17 00:00:00 2001 +Date: Fri, 19 Jun 2020 12:38:24 +0300 +Subject: [PATCH] Adding missing HID timestamp patch for Gyro sensor. + Ubuntu 18.04 Bionic Beaver with Kernel 5.4 + A symmetric patch for Accelerator was already upstreamed, + this patch was skipped from upstream + The patch was written by Srinivas Pandruvada + Additionally, timestamp conversion is fixed + +--- + drivers/iio/accel/hid-sensor-accel-3d.c | 1 + + drivers/iio/gyro/hid-sensor-gyro-3d.c | 31 ++++++++++++++++++------- + 2 files changed, 24 insertions(+), 8 deletions(-) + +diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c +index 0d9e2def2b25..ad90203c87c1 100644 +--- a/drivers/iio/accel/hid-sensor-accel-3d.c ++++ b/drivers/iio/accel/hid-sensor-accel-3d.c +@@ -276,6 +276,7 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev, + hid_sensor_convert_timestamp( + &accel_state->common_attributes, + *(int64_t *)raw_data); ++ ret = 0; + break; + default: + break; +diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c +index 08cacbbf31e6..f6e88eecd145 100644 +--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c ++++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c +@@ -29,11 +29,13 @@ struct gyro_3d_state { + struct hid_sensor_hub_callbacks callbacks; + struct hid_sensor_common common_attributes; + struct hid_sensor_hub_attribute_info gyro[GYRO_3D_CHANNEL_MAX]; +- u32 gyro_val[GYRO_3D_CHANNEL_MAX]; ++ /* Reserve for 3 channels + padding + timestamp */ ++ u32 gyro_val[GYRO_3D_CHANNEL_MAX + 3]; + int scale_pre_decml; + int scale_post_decml; + int scale_precision; + int value_offset; ++ int64_t timestamp; + }; + + static const u32 gyro_3d_addresses[GYRO_3D_CHANNEL_MAX] = { +@@ -74,7 +76,8 @@ static const struct iio_chan_spec gyro_3d_channels[] = { + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), + .scan_index = CHANNEL_SCAN_INDEX_Z, +- } ++ }, ++ IIO_CHAN_SOFT_TIMESTAMP(3) + }; + + /* Adjust channel real bits based on report descriptor */ +@@ -181,11 +184,11 @@ static const struct iio_info gyro_3d_info = { + }; + + /* Function to push data to buffer */ +-static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data, +- int len) ++static void hid_sensor_push_data(struct iio_dev *indio_dev, void *data, ++ int len, int64_t timestamp) + { + dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); +- iio_push_to_buffers(indio_dev, data); ++ iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp); + } + + /* Callback handler to send event after all samples are received and captured */ +@@ -197,11 +200,16 @@ static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev, + struct gyro_3d_state *gyro_state = iio_priv(indio_dev); + + dev_dbg(&indio_dev->dev, "gyro_3d_proc_event\n"); +- if (atomic_read(&gyro_state->common_attributes.data_ready)) ++ if (atomic_read(&gyro_state->common_attributes.data_ready)) { ++ if (!gyro_state->timestamp) ++ gyro_state->timestamp = iio_get_time_ns(indio_dev); ++ + hid_sensor_push_data(indio_dev, + gyro_state->gyro_val, +- sizeof(gyro_state->gyro_val)); +- ++ sizeof(gyro_state->gyro_val), ++ gyro_state->timestamp); ++ gyro_state->timestamp = 0; ++ } + return 0; + } + +@@ -225,6 +233,13 @@ static int gyro_3d_capture_sample(struct hid_sensor_hub_device *hsdev, + *(u32 *)raw_data; + ret = 0; + break; ++ case HID_USAGE_SENSOR_TIME_TIMESTAMP: ++ gyro_state->timestamp = ++ hid_sensor_convert_timestamp( ++ &gyro_state->common_attributes, ++ *(int64_t *)raw_data); ++ ret = 0; ++ break; + default: + break; + } +-- +2.17.1 + diff --git a/scripts/realsense-metadata-bionic-hwe-5.4.patch b/scripts/realsense-metadata-bionic-hwe-5.4.patch new file mode 100644 index 0000000000..5472adbbf9 --- /dev/null +++ b/scripts/realsense-metadata-bionic-hwe-5.4.patch @@ -0,0 +1,272 @@ +From 91f4e0a84b9754fd98a8b8a086fdc628bf4a6493 Mon Sep 17 00:00:00 2001 +From: ev-mp +Date: Fri, 19 Jun 2020 12:34:08 +0300 +Signed-off-by: Evgeni +Subject: [PATCH] Enabling UVC Metadata attributes with Ubuntu 18.04. Kernel 5.4 + +--- + drivers/media/usb/uvc/uvc_driver.c | 234 +++++++++++++++++++++++++++++ + drivers/media/usb/uvc/uvcvideo.h | 2 +- + 2 files changed, 235 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 443ecea63bd8..d3a5c5f8abb9 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -2945,6 +2945,240 @@ static const struct usb_device_id uvc_ids[] = { + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel SR300 depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0aa5, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D400/PSR depth camera*/ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0ad1, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D410/ASR depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0ad2, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D415/ASRC depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0ad3, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D430/AWG depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0ad4, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D450/AWGT depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0ad5, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* USB2 Descriptor, Depth Sensor */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0ad6, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D400 IMU Module */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0af2, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D420/PWG depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0af6, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D420_MM/PWGT depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0afe, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D410_MM/ASRT depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0aff, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D400_MM/PSRT depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b00, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D430_MM/AWGCT depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b01, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D460/DS5U depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b03, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D435/AWGC depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b07, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D405 S depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b0c, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel L500 depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b0d, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D435i depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b3a, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel L515 Pre-PRQ */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b3d, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel SR305 Depth Camera*/ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b48, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D416 Depth Camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b49, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D430i depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b4b, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D465 */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b4d, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D405 */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b5b, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel D455 */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b5c, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* Intel L515 */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0b64, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, + /* Generic USB Video Class */ + { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) }, + { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) }, +diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h +index 1aa8493a24d1..2b22379756d8 100644 +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -199,7 +199,7 @@ + /* Maximum number of packets per URB. */ + #define UVC_MAX_PACKETS 32 + /* Maximum status buffer size in bytes of interrupt URB. */ +-#define UVC_MAX_STATUS_SIZE 16 ++#define UVC_MAX_STATUS_SIZE 32 + + #define UVC_CTRL_CONTROL_TIMEOUT 500 + #define UVC_CTRL_STREAMING_TIMEOUT 5000 +-- +2.17.1 + From c073c81491beaae8652a1bd80fdab3b7c6990ce4 Mon Sep 17 00:00:00 2001 From: ev-mp Date: Fri, 19 Jun 2020 21:05:36 +0300 Subject: [PATCH 42/61] Fix Ubuntu tag selection for 4-digit kernel version --- scripts/patch-realsense-ubuntu-lts.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/patch-realsense-ubuntu-lts.sh b/scripts/patch-realsense-ubuntu-lts.sh index 6330aa19c8..c849e02bcd 100755 --- a/scripts/patch-realsense-ubuntu-lts.sh +++ b/scripts/patch-realsense-ubuntu-lts.sh @@ -83,7 +83,7 @@ cd ${kernel_name} #then #Search the repository for the tag that matches the mmaj.min.patch-build of Ubuntu kernel kernel_full_num=$(echo $LINUX_BRANCH | cut -d '-' -f 1,2) -kernel_git_tag=$(git ls-remote --tags origin | grep ${kernel_full_num} | grep '[^^{}]$' | tail -n 1 | awk -F/ '{print $NF}') +kernel_git_tag=$(git ls-remote --tags origin | grep "${kernel_full_num}\." | grep '[^^{}]$' | tail -n 1 | awk -F/ '{print $NF}') echo -e "\e[32mFetching Ubuntu LTS tag \e[47m${kernel_git_tag}\e[0m \e[32m to the local kernel sources folder\e[0m" git fetch origin tag ${kernel_git_tag} --no-tags From 96accf5f2fd231558ca2e9693104dfffd0264eba Mon Sep 17 00:00:00 2001 From: ev-mp Date: Fri, 19 Jun 2020 21:08:27 +0300 Subject: [PATCH 43/61] Retrofit FG/INZC/PAIR/Z16H FourCC into patches --- .../realsense-camera-formats-bionic-5.patch | 32 +++++++++++-- ...onic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch | 27 ++++++++++- ...lsense-camera-formats-bionic-hwe-5.4.patch | 28 ++++++++++- ...alsense-camera-formats-bionic-master.patch | 46 ++++++++++++++----- ...nial-Ubuntu-hwe-4.13.0-45.50_16.04.1.patch | 28 +++++++---- ...enial-Ubuntu-hwe-4.8.0-58.63_16.04.1.patch | 46 +++++++++++-------- ...ense-camera-formats-xenial-hwe-zesty.patch | 40 ++++++++++------ .../realsense-camera-formats-xenial-hwe.patch | 28 +++++------ 8 files changed, 200 insertions(+), 75 deletions(-) diff --git a/scripts/realsense-camera-formats-bionic-5.patch b/scripts/realsense-camera-formats-bionic-5.patch index 578557034e..e95d7faa78 100644 --- a/scripts/realsense-camera-formats-bionic-5.patch +++ b/scripts/realsense-camera-formats-bionic-5.patch @@ -15,7 +15,7 @@ diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driv index 33a22c016..a7b76c987 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -219,6 +219,43 @@ static struct uvc_format_desc uvc_fmts[] = { +@@ -219,6 +219,58 @@ static struct uvc_format_desc uvc_fmts[] = { .guid = UVC_GUID_FORMAT_CNF4, .fcc = V4L2_PIX_FMT_CNF4, }, @@ -55,6 +55,21 @@ index 33a22c016..a7b76c987 100644 + .name = "Z16 Huffman Compression", + .guid = UVC_GUID_FORMAT_Z16H, + .fcc = V4L2_PIX_FMT_Z16H, ++ }, ++ { ++ .name = "Frame Grabber (FG )", ++ .guid = UVC_GUID_FORMAT_FG, ++ .fcc = V4L2_PIX_FMT_FG, ++ }, ++ { ++ .name = "SR300 Depth/Confidence (INZC)", ++ .guid = UVC_GUID_FORMAT_INZC, ++ .fcc = V4L2_PIX_FMT_INZC, ++ }, ++ { ++ .name = "Relative IR (PAIR)", ++ .guid = UVC_GUID_FORMAT_PAIR, ++ .fcc = V4L2_PIX_FMT_PAIR, + }, }; @@ -63,7 +78,7 @@ diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 9b41b14ce..4b88f31f5 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h -@@ -165,6 +165,28 @@ +@@ -165,6 +165,37 @@ {0x32, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} @@ -89,6 +104,15 @@ index 9b41b14ce..4b88f31f5 100644 + #define UVC_GUID_FORMAT_Z16H \ + { 'Z', '1', '6', 'H', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ #define UVC_GUID_FORMAT_FG \ ++ { 'F', 'G', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ #define UVC_GUID_FORMAT_INZC \ ++ { 'I', 'N', 'Z', 'C', 0x02, 0xb6, 0x0f, 0x48, \ ++ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} ++ #define UVC_GUID_FORMAT_PAIR \ ++ { 'P', 'A', 'I', 'R', 0x36, 0x85, 0x41, 0x48, \ ++ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} /* ------------------------------------------------------------------------ * Driver specific constants. @@ -103,7 +127,7 @@ index 90aad465f..e2d757e9a 100644 + /* Librealsense formats*/ + case V4L2_PIX_FMT_RW16: descr = "16-bit Raw data"; break; + case V4L2_PIX_FMT_W10: descr = "10-bit packed 8888[2222]"; break; -+ case V4L2_META_FMT_D4XX: descr = "D4XX Payload Header metadata"; break; ++ case V4L2_META_FMT_D4XX: descr = "D4XX Payload Header metadata"; break; + case V4L2_PIX_FMT_CONFIDENCE_MAP: descr = "Packed [44] confidence data"; break; + case V4L2_PIX_FMT_FG: descr = "Frame Grabber (FG )"; break; + case V4L2_PIX_FMT_INZC: descr = "Planar Depth/Confidence (INZC)"; break; @@ -122,7 +146,7 @@ index b5671ce27..8954f78be 100644 #define V4L2_PIX_FMT_CNF4 v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit packed depth confidence information */ +#define V4L2_PIX_FMT_RW16 v4l2_fourcc('R', 'W', '1', '6') /* Raw data 16-bit */ +#define V4L2_PIX_FMT_W10 v4l2_fourcc('W', '1', '0', ' ') /* Packed raw data 10-bit */ -+#define V4L2_PIX_FMT_CONFIDENCE_MAP v4l2_fourcc('C', ' ', ' ', ' ') /* Two pixels in one byte */ ++#define V4L2_PIX_FMT_CONFIDENCE_MAP v4l2_fourcc('C', ' ', ' ', ' ') /* Two pixels in one byte */ +/* Librealsense development*/ +#define V4L2_PIX_FMT_FG v4l2_fourcc('F', 'G', ' ', ' ') /* Frame Grabber */ +#define V4L2_PIX_FMT_INZC v4l2_fourcc('I', 'N', 'Z', 'C') /* Planar Depth/Confidence */ diff --git a/scripts/realsense-camera-formats-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch b/scripts/realsense-camera-formats-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch index e130292c60..a5671dc0d8 100644 --- a/scripts/realsense-camera-formats-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch +++ b/scripts/realsense-camera-formats-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch @@ -15,7 +15,7 @@ diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driv index 8e1382013..6f1dd1a9e 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -209,6 +209,48 @@ static struct uvc_format_desc uvc_fmts[] = { +@@ -209,6 +209,63 @@ static struct uvc_format_desc uvc_fmts[] = { .guid = UVC_GUID_FORMAT_INZI, .fcc = V4L2_PIX_FMT_INZI, }, @@ -60,6 +60,21 @@ index 8e1382013..6f1dd1a9e 100644 + .name = "Z16 Huffman Compression", + .guid = UVC_GUID_FORMAT_Z16H, + .fcc = V4L2_PIX_FMT_Z16H, ++ }, ++ { ++ .name = "Frame Grabber (FG )", ++ .guid = UVC_GUID_FORMAT_FG, ++ .fcc = V4L2_PIX_FMT_FG, ++ }, ++ { ++ .name = "SR300 Depth/Confidence (INZC)", ++ .guid = UVC_GUID_FORMAT_INZC, ++ .fcc = V4L2_PIX_FMT_INZC, ++ }, ++ { ++ .name = "Relative IR (PAIR)", ++ .guid = UVC_GUID_FORMAT_PAIR, ++ .fcc = V4L2_PIX_FMT_PAIR, + }, }; @@ -68,7 +83,7 @@ diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index be5cf1792..f405e5fe6 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h -@@ -158,6 +158,31 @@ +@@ -158,6 +158,40 @@ {0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} @@ -97,6 +112,14 @@ index be5cf1792..f405e5fe6 100644 + #define UVC_GUID_FORMAT_Z16H \ + { 'Z', '1', '6', 'H', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ { 'F', 'G', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ #define UVC_GUID_FORMAT_INZC \ ++ { 'I', 'N', 'Z', 'C', 0x02, 0xb6, 0x0f, 0x48, \ ++ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} ++ #define UVC_GUID_FORMAT_PAIR \ ++ { 'P', 'A', 'I', 'R', 0x36, 0x85, 0x41, 0x48, \ ++ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} /* ------------------------------------------------------------------------ * Driver specific constants. diff --git a/scripts/realsense-camera-formats-bionic-hwe-5.4.patch b/scripts/realsense-camera-formats-bionic-hwe-5.4.patch index eabb4f04af..3ee3ffeced 100644 --- a/scripts/realsense-camera-formats-bionic-hwe-5.4.patch +++ b/scripts/realsense-camera-formats-bionic-hwe-5.4.patch @@ -15,7 +15,7 @@ diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driv index 99883550375e..443ecea63bd8 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -214,6 +214,43 @@ static struct uvc_format_desc uvc_fmts[] = { +@@ -214,6 +214,58 @@ static struct uvc_format_desc uvc_fmts[] = { .guid = UVC_GUID_FORMAT_CNF4, .fcc = V4L2_PIX_FMT_CNF4, }, @@ -55,6 +55,21 @@ index 99883550375e..443ecea63bd8 100644 + .name = "Z16 Huffman Compression", + .guid = UVC_GUID_FORMAT_Z16H, + .fcc = V4L2_PIX_FMT_Z16H, ++ }, ++ { ++ .name = "Frame Grabber (FG )", ++ .guid = UVC_GUID_FORMAT_FG, ++ .fcc = V4L2_PIX_FMT_FG, ++ }, ++ { ++ .name = "SR300 Depth/Confidence (INZC)", ++ .guid = UVC_GUID_FORMAT_INZC, ++ .fcc = V4L2_PIX_FMT_INZC, ++ }, ++ { ++ .name = "Relative IR (PAIR)", ++ .guid = UVC_GUID_FORMAT_PAIR, ++ .fcc = V4L2_PIX_FMT_PAIR, + }, }; @@ -63,7 +78,7 @@ diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 24e3d8c647e7..1aa8493a24d1 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h -@@ -165,6 +165,28 @@ +@@ -165,6 +165,37 @@ {0x32, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} @@ -89,6 +104,15 @@ index 24e3d8c647e7..1aa8493a24d1 100644 + #define UVC_GUID_FORMAT_Z16H \ + { 'Z', '1', '6', 'H', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ #define UVC_GUID_FORMAT_FG \ ++ { 'F', 'G', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ #define UVC_GUID_FORMAT_INZC \ ++ { 'I', 'N', 'Z', 'C', 0x02, 0xb6, 0x0f, 0x48, \ ++ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} ++ #define UVC_GUID_FORMAT_PAIR \ ++ { 'P', 'A', 'I', 'R', 0x36, 0x85, 0x41, 0x48, \ ++ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} /* ------------------------------------------------------------------------ * Driver specific constants. diff --git a/scripts/realsense-camera-formats-bionic-master.patch b/scripts/realsense-camera-formats-bionic-master.patch index 2ac38bf518..e0d81d5a62 100644 --- a/scripts/realsense-camera-formats-bionic-master.patch +++ b/scripts/realsense-camera-formats-bionic-master.patch @@ -27,7 +27,7 @@ diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driv index 28b91b7d7..f50a2b148 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -203,6 +203,48 @@ static struct uvc_format_desc uvc_fmts[] = { +@@ -203,6 +203,63 @@ static struct uvc_format_desc uvc_fmts[] = { .guid = UVC_GUID_FORMAT_INZI, .fcc = V4L2_PIX_FMT_INZI, }, @@ -72,6 +72,21 @@ index 28b91b7d7..f50a2b148 100644 + .name = "Z16 Huffman Compression", + .guid = UVC_GUID_FORMAT_Z16H, + .fcc = V4L2_PIX_FMT_Z16H, ++ }, ++ { ++ .name = "Frame Grabber (FG )", ++ .guid = UVC_GUID_FORMAT_FG, ++ .fcc = V4L2_PIX_FMT_FG, ++ }, ++ { ++ .name = "SR300 Depth/Confidence (INZC)", ++ .guid = UVC_GUID_FORMAT_INZC, ++ .fcc = V4L2_PIX_FMT_INZC, ++ }, ++ { ++ .name = "Relative IR (PAIR)", ++ .guid = UVC_GUID_FORMAT_PAIR, ++ .fcc = V4L2_PIX_FMT_PAIR, + }, }; @@ -80,35 +95,44 @@ diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 05398784d..8c99aabef 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h -@@ -153,6 +153,31 @@ +@@ -153,6 +153,40 @@ #define UVC_GUID_FORMAT_INVI \ { 'I', 'N', 'V', 'I', 0xdb, 0x57, 0x49, 0x5e, \ 0x8e, 0x3f, 0xf4, 0x79, 0x53, 0x2b, 0x94, 0x6f} -+#define UVC_GUID_FORMAT_L8 \ ++ #define UVC_GUID_FORMAT_L8 \ + { '2', 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -+#define UVC_GUID_FORMAT_D16 \ ++ #define UVC_GUID_FORMAT_D16 \ + { 'P', 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -+#define UVC_GUID_FORMAT_W10 \ ++ #define UVC_GUID_FORMAT_W10 \ + { 'W', '1', '0', ' ', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -+#define UVC_GUID_FORMAT_RAW8 \ ++ #define UVC_GUID_FORMAT_RAW8 \ + { 'R', 'A', 'W', '8', 0x66, 0x1a, 0x42, 0xa2, \ + 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} -+#define UVC_GUID_FORMAT_CONFIDENCE_MAP \ ++ #define UVC_GUID_FORMAT_CONFIDENCE_MAP \ + { 'C', ' ', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -+/* Legacy formats */ -+#define UVC_GUID_FORMAT_RW16 \ ++ /* Legacy formats */ ++ #define UVC_GUID_FORMAT_RW16 \ + { 'R', 'W', '1', '6', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -+#define UVC_GUID_FORMAT_BAYER16 \ ++ #define UVC_GUID_FORMAT_BAYER16 \ + { 'R', 'W', '1', '6', 0x66, 0x1a, 0x42, 0xa2, \ + 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} -+#define UVC_GUID_FORMAT_Z16H \ ++ #define UVC_GUID_FORMAT_Z16H \ + { 'Z', '1', '6', 'H', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ #define UVC_GUID_FORMAT_FG \ ++ { 'F', 'G', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ #define UVC_GUID_FORMAT_INZC \ ++ { 'I', 'N', 'Z', 'C', 0x02, 0xb6, 0x0f, 0x48, \ ++ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} ++ #define UVC_GUID_FORMAT_PAIR \ ++ { 'P', 'A', 'I', 'R', 0x36, 0x85, 0x41, 0x48, \ ++ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} /* ------------------------------------------------------------------------ * Driver specific constants. diff --git a/scripts/realsense-camera-formats-xenial-Ubuntu-hwe-4.13.0-45.50_16.04.1.patch b/scripts/realsense-camera-formats-xenial-Ubuntu-hwe-4.13.0-45.50_16.04.1.patch index 5de9acc02a..c9dba919b4 100644 --- a/scripts/realsense-camera-formats-xenial-Ubuntu-hwe-4.13.0-45.50_16.04.1.patch +++ b/scripts/realsense-camera-formats-xenial-Ubuntu-hwe-4.13.0-45.50_16.04.1.patch @@ -16,7 +16,7 @@ diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driv index 70842c5..2c92aa0 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -203,6 +203,58 @@ static struct uvc_format_desc uvc_fmts[] = { +@@ -203,6 +203,63 @@ static struct uvc_format_desc uvc_fmts[] = { .guid = UVC_GUID_FORMAT_INZI, .fcc = V4L2_PIX_FMT_INZI, }, @@ -71,6 +71,11 @@ index 70842c5..2c92aa0 100644 + .name = "Relative IR (PAIR)", + .guid = UVC_GUID_FORMAT_PAIR, + .fcc = V4L2_PIX_FMT_PAIR, ++ }, ++ { ++ .name = "Z16 Huffman Compression", ++ .guid = UVC_GUID_FORMAT_Z16H, ++ .fcc = V4L2_PIX_FMT_Z16H, + }, }; @@ -79,7 +84,7 @@ diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 15e415e..1ade6ee 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h -@@ -152,6 +152,40 @@ +@@ -152,6 +155,40 @@ #define UVC_GUID_FORMAT_INVI \ { 'I', 'N', 'V', 'I', 0xdb, 0x57, 0x49, 0x5e, \ 0x8e, 0x3f, 0xf4, 0x79, 0x53, 0x2b, 0x94, 0x6f} @@ -117,6 +122,9 @@ index 15e415e..1ade6ee 100644 +#define UVC_GUID_FORMAT_PAIR \ + { 'P', 'A', 'I', 'R', 0x36, 0x85, 0x41, 0x48, \ + 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} ++ #define UVC_GUID_FORMAT_Z16H \ ++ { 'Z', '1', '6', 'H', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} /* ------------------------------------------------------------------------ * Driver specific constants. @@ -124,7 +132,7 @@ diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2 index cab63bb..f9fcf13 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c -@@ -1239,7 +1239,13 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) +@@ -1239,7 +1239,14 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_TCH_FMT_TU08: descr = "8-bit unsigned touch data"; break; case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break; case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break; @@ -136,6 +144,7 @@ index cab63bb..f9fcf13 100644 + case V4L2_PIX_FMT_FG: descr = "Frame Grabber (FG )"; break; + case V4L2_PIX_FMT_INZC: descr = "Planar Depth/Confidence (INZC)"; break; + case V4L2_PIX_FMT_PAIR: descr = "Relative IR (PAIR)"; break; ++ case V4L2_PIX_FMT_Z16H: descr = "Z16 Huffman Compression"; break; default: /* Compressed formats */ flags = V4L2_FMT_FLAG_COMPRESSED; @@ -143,18 +152,19 @@ diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 45cf735..6944a02 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h -@@ -662,6 +662,14 @@ struct v4l2_pix_format { +@@ -662,6 +662,15 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */ #define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode */ #define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */ -+#define V4L2_PIX_FMT_RW16 v4l2_fourcc('R', 'W', '1', '6') /* Raw data 16-bit */ -+#define V4L2_PIX_FMT_W10 v4l2_fourcc('W', '1', '0', ' ') /* Packed raw data 10-bit */ ++#define V4L2_PIX_FMT_RW16 v4l2_fourcc('R', 'W', '1', '6') /* Raw data 16-bit */ ++#define V4L2_PIX_FMT_W10 v4l2_fourcc('W', '1', '0', ' ') /* Packed raw data 10-bit */ +#define V4L2_PIX_FMT_CONFIDENCE_MAP v4l2_fourcc('C', ' ', ' ', ' ') /* Two pixels in one byte */ + +/* Librealsense development*/ -+#define V4L2_PIX_FMT_FG v4l2_fourcc('F', 'G', ' ', ' ') /* Frame Grabber */ -+#define V4L2_PIX_FMT_INZC v4l2_fourcc('I', 'N', 'Z', 'C') /* Planar Depth/Confidence */ -+#define V4L2_PIX_FMT_PAIR v4l2_fourcc('P', 'A', 'I', 'R') /* Relative IR */ ++#define V4L2_PIX_FMT_FG v4l2_fourcc('F', 'G', ' ', ' ') /* Frame Grabber */ ++#define V4L2_PIX_FMT_INZC v4l2_fourcc('I', 'N', 'Z', 'C') /* Planar Depth/Confidence */ ++#define V4L2_PIX_FMT_PAIR v4l2_fourcc('P', 'A', 'I', 'R') /* Relative IR */ ++#define V4L2_PIX_FMT_Z16H v4l2_fourcc('Z', '1', '6', 'H') /* Depth Z16 custom Huffman Code compression*/ /* SDR formats - used only for Software Defined Radio devices */ #define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */ diff --git a/scripts/realsense-camera-formats-xenial-Ubuntu-hwe-4.8.0-58.63_16.04.1.patch b/scripts/realsense-camera-formats-xenial-Ubuntu-hwe-4.8.0-58.63_16.04.1.patch index b4d7918541..45d1a84229 100644 --- a/scripts/realsense-camera-formats-xenial-Ubuntu-hwe-4.8.0-58.63_16.04.1.patch +++ b/scripts/realsense-camera-formats-xenial-Ubuntu-hwe-4.8.0-58.63_16.04.1.patch @@ -28,7 +28,7 @@ diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driv index cde43b6..54bd175 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -168,6 +168,103 @@ static struct uvc_format_desc uvc_fmts[] = { +@@ -168,6 +168,108 @@ static struct uvc_format_desc uvc_fmts[] = { .guid = UVC_GUID_FORMAT_RW10, .fcc = V4L2_PIX_FMT_SRGGB10P, }, @@ -128,6 +128,11 @@ index cde43b6..54bd175 100644 + .name = "Relative IR (PAIR)", + .guid = UVC_GUID_FORMAT_PAIR, + .fcc = V4L2_PIX_FMT_PAIR, ++ }, ++ { ++ .name = "Z16 Huffman Compression", ++ .guid = UVC_GUID_FORMAT_Z16H, ++ .fcc = V4L2_PIX_FMT_Z16H, + }, }; @@ -136,16 +141,16 @@ diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 7e4d3ee..e517d8f 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h -@@ -131,6 +131,57 @@ +@@ -131,6 +131,60 @@ #define UVC_GUID_FORMAT_RW10 \ { 'R', 'W', '1', '0', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_RAW8 \ -+ { 'R', 'A', 'W', '8', 0x66, 0x1a, 0x42, 0xa2, \ -+ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} ++ { 'R', 'A', 'W', '8', 0x66, 0x1a, 0x42, 0xa2, \ ++ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} +#define UVC_GUID_FORMAT_RW16 \ -+ { 'R', 'W', '1', '6', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ { 'R', 'W', '1', '6', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_INVZ \ + { 'I', 'N', 'V', 'Z', 0x90, 0x2d, 0x58, 0x4a, \ + 0x92, 0x0b, 0x77, 0x3f, 0x1f, 0x2c, 0x55, 0x6b} @@ -174,23 +179,26 @@ index 7e4d3ee..e517d8f 100644 + { 'P', 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_BAYER16 \ -+ { 'R', 'W', '1', '6', 0x66, 0x1a, 0x42, 0xa2, \ -+ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} ++ { 'R', 'W', '1', '6', 0x66, 0x1a, 0x42, 0xa2, \ ++ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} +#define UVC_GUID_FORMAT_W10 \ -+ { 'W', '1', '0', ' ', 0x00, 0x00, 0x10, 0x00, \ ++ { 'W', '1', '0', ' ', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_CONFIDENCE_MAP \ + { 'C', ' ', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_FG \ + { 'F', 'G', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_INZC \ + { 'I', 'N', 'Z', 'C', 0x02, 0xb6, 0x0f, 0x48, \ -+ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} ++ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} +#define UVC_GUID_FORMAT_PAIR \ + { 'P', 'A', 'I', 'R', 0x36, 0x85, 0x41, 0x48, \ -+ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} ++ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} ++#define UVC_GUID_FORMAT_Z16H \ ++ { 'Z', '1', '6', 'H', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} /* ------------------------------------------------------------------------ * Driver specific constants. @@ -198,7 +206,7 @@ diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2 index 51a0fa1..391c2b3 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c -@@ -1243,6 +1243,16 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) +@@ -1243,6 +1243,17 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_SDR_FMT_CS8: descr = "Complex S8"; break; case V4L2_SDR_FMT_CS14LE: descr = "Complex S14LE"; break; case V4L2_SDR_FMT_RU12LE: descr = "Real U12LE"; break; @@ -212,6 +220,7 @@ index 51a0fa1..391c2b3 100644 + case V4L2_PIX_FMT_FG: descr = "Frame Grabber (FG )"; break; + case V4L2_PIX_FMT_INZC: descr = "Planar Depth/Confidence (INZC)"; break; + case V4L2_PIX_FMT_PAIR: descr = "Relative IR (PAIR)"; break; ++ case V4L2_PIX_FMT_Z16H: descr = "Z16 Huffman Compression"; break; default: /* Compressed formats */ @@ -219,7 +228,7 @@ diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 724f43e..29bcba5 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h -@@ -627,6 +627,18 @@ struct v4l2_pix_format { +@@ -627,6 +627,19 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Y8I v4l2_fourcc('Y', '8', 'I', ' ') /* Greyscale 8-bit L/R interleaved */ #define V4L2_PIX_FMT_Y12I v4l2_fourcc('Y', '1', '2', 'I') /* Greyscale 12-bit L/R interleaved */ #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */ @@ -232,9 +241,10 @@ index 724f43e..29bcba5 100644 +#define V4L2_PIX_FMT_W10 v4l2_fourcc('W', '1', '0', ' ') /* Packed raw data 10-bit */ +#define V4L2_PIX_FMT_CONFIDENCE_MAP v4l2_fourcc('C', ' ', ' ', ' ') /* Two pixels in one byte */ +/* Librealsense development*/ -+#define V4L2_PIX_FMT_FG v4l2_fourcc('F', 'G', ' ', ' ') /* Frame Grabber */ -+#define V4L2_PIX_FMT_INZC v4l2_fourcc('I', 'N', 'Z', 'C') /* Planar Depth/Confidence */ -+#define V4L2_PIX_FMT_PAIR v4l2_fourcc('P', 'A', 'I', 'R') /* Relative IR */ ++#define V4L2_PIX_FMT_FG v4l2_fourcc('F', 'G', ' ', ' ') /* Frame Grabber */ ++#define V4L2_PIX_FMT_INZC v4l2_fourcc('I', 'N', 'Z', 'C') /* Planar Depth/Confidence */ ++#define V4L2_PIX_FMT_PAIR v4l2_fourcc('P', 'A', 'I', 'R') /* Relative IR */ ++#define V4L2_PIX_FMT_Z16H v4l2_fourcc('Z', '1', '6', 'H') /* Depth Z16 custom Huffman Code compression*/ /* SDR formats - used only for Software Defined Radio devices */ #define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */ diff --git a/scripts/realsense-camera-formats-xenial-hwe-zesty.patch b/scripts/realsense-camera-formats-xenial-hwe-zesty.patch index 4c6307cd3b..2ad52d861e 100644 --- a/scripts/realsense-camera-formats-xenial-hwe-zesty.patch +++ b/scripts/realsense-camera-formats-xenial-hwe-zesty.patch @@ -16,7 +16,7 @@ diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driv index 04bf350..bb8fefb 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -188,6 +188,88 @@ static struct uvc_format_desc uvc_fmts[] = { +@@ -188,6 +188,93 @@ static struct uvc_format_desc uvc_fmts[] = { .guid = UVC_GUID_FORMAT_GR16, .fcc = V4L2_PIX_FMT_SGRBG16, }, @@ -101,6 +101,11 @@ index 04bf350..bb8fefb 100644 + .name = "Relative IR (PAIR)", + .guid = UVC_GUID_FORMAT_PAIR, + .fcc = V4L2_PIX_FMT_PAIR, ++ }, ++ { ++ .name = "Z16 Huffman Compression", ++ .guid = UVC_GUID_FORMAT_Z16H, ++ .fcc = V4L2_PIX_FMT_Z16H, + }, }; @@ -109,16 +114,16 @@ diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 3d6cc62..6ffdc0e 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h -@@ -143,6 +143,48 @@ +@@ -143,6 +143,51 @@ #define UVC_GUID_FORMAT_RW10 \ { 'R', 'W', '1', '0', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_RAW8 \ -+ { 'R', 'A', 'W', '8', 0x66, 0x1a, 0x42, 0xa2, \ -+ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} ++ { 'R', 'A', 'W', '8', 0x66, 0x1a, 0x42, 0xa2, \ ++ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} +#define UVC_GUID_FORMAT_RW16 \ -+ { 'R', 'W', '1', '6', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ { 'R', 'W', '1', '6', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_INVZ \ + { 'I', 'N', 'V', 'Z', 0x90, 0x2d, 0x58, 0x4a, \ + 0x92, 0x0b, 0x77, 0x3f, 0x1f, 0x2c, 0x55, 0x6b} @@ -138,23 +143,26 @@ index 3d6cc62..6ffdc0e 100644 + { 'P', 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_BAYER16 \ -+ { 'R', 'W', '1', '6', 0x66, 0x1a, 0x42, 0xa2, \ -+ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} ++ { 'R', 'W', '1', '6', 0x66, 0x1a, 0x42, 0xa2, \ ++ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} +#define UVC_GUID_FORMAT_W10 \ -+ { 'W', '1', '0', ' ', 0x00, 0x00, 0x10, 0x00, \ ++ { 'W', '1', '0', ' ', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_CONFIDENCE_MAP \ + { 'C', ' ', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_FG \ + { 'F', 'G', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_INZC \ + { 'I', 'N', 'Z', 'C', 0x02, 0xb6, 0x0f, 0x48, \ -+ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} ++ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} +#define UVC_GUID_FORMAT_PAIR \ + { 'P', 'A', 'I', 'R', 0x36, 0x85, 0x41, 0x48, \ -+ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} ++ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} ++#define UVC_GUID_FORMAT_Z16H \ ++ { 'Z', '1', '6', 'H', 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} /* ------------------------------------------------------------------------ * Driver specific constants. @@ -162,7 +170,7 @@ diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2 index 0c3f238..5347286 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c -@@ -1217,7 +1217,13 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) +@@ -1217,7 +1217,14 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_TCH_FMT_DELTA_TD08: descr = "8-bit signed deltas"; break; case V4L2_TCH_FMT_TU16: descr = "16-bit unsigned touch data"; break; case V4L2_TCH_FMT_TU08: descr = "8-bit unsigned touch data"; break; @@ -174,6 +182,7 @@ index 0c3f238..5347286 100644 + case V4L2_PIX_FMT_FG: descr = "Frame Grabber (FG )"; break; + case V4L2_PIX_FMT_INZC: descr = "Planar Depth/Confidence (INZC)"; break; + case V4L2_PIX_FMT_PAIR: descr = "Relative IR (PAIR)"; break; ++ case V4L2_PIX_FMT_Z16H: descr = "Z16 Huffman Compression"; break; default: /* Compressed formats */ flags = V4L2_FMT_FLAG_COMPRESSED; @@ -181,7 +190,7 @@ diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 45184a2..e7f6029 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h -@@ -661,7 +661,16 @@ struct v4l2_pix_format { +@@ -661,7 +661,17 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Y12I v4l2_fourcc('Y', '1', '2', 'I') /* Greyscale 12-bit L/R interleaved */ #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */ #define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode */ @@ -196,6 +205,7 @@ index 45184a2..e7f6029 100644 +#define V4L2_PIX_FMT_FG v4l2_fourcc('F', 'G', ' ', ' ') /* Frame Grabber */ +#define V4L2_PIX_FMT_INZC v4l2_fourcc('I', 'N', 'Z', 'C') /* Planar Depth/Confidence */ +#define V4L2_PIX_FMT_PAIR v4l2_fourcc('P', 'A', 'I', 'R') /* Relative IR */ ++#define V4L2_PIX_FMT_Z16H v4l2_fourcc('Z', '1', '6', 'H') /* Depth Z16 custom Huffman Code compression*/ /* SDR formats - used only for Software Defined Radio devices */ #define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */ #define V4L2_SDR_FMT_CU16LE v4l2_fourcc('C', 'U', '1', '6') /* IQ u16le */ diff --git a/scripts/realsense-camera-formats-xenial-hwe.patch b/scripts/realsense-camera-formats-xenial-hwe.patch index 684af469a3..40b1f0d844 100644 --- a/scripts/realsense-camera-formats-xenial-hwe.patch +++ b/scripts/realsense-camera-formats-xenial-hwe.patch @@ -110,29 +110,29 @@ index 0539878..401882d 100644 + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_RAW8 \ + { 'R', 'A', 'W', '8', 0x66, 0x1a, 0x42, 0xa2, \ -+ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} ++ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} +#define UVC_GUID_FORMAT_CONFIDENCE_MAP \ + { 'C', ' ', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +/* Legacy/Development formats */ +#define UVC_GUID_FORMAT_RW16 \ + { 'R', 'W', '1', '6', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_BAYER16 \ + { 'R', 'W', '1', '6', 0x66, 0x1a, 0x42, 0xa2, \ -+ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} ++ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} +#define UVC_GUID_FORMAT_BAYER16 \ + { 'R', 'W', '1', '6', 0x66, 0x1a, 0x42, 0xa2, \ -+ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} ++ 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} +#define UVC_GUID_FORMAT_FG \ + { 'F', 'G', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_INZC \ + { 'I', 'N', 'Z', 'C', 0x02, 0xb6, 0x0f, 0x48, \ -+ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} ++ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} +#define UVC_GUID_FORMAT_PAIR \ + { 'P', 'A', 'I', 'R', 0x36, 0x85, 0x41, 0x48, \ -+ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} ++ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} +#define UVC_GUID_FORMAT_Z16H \ + { 'Z', '1', '6', 'H', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} @@ -167,15 +167,15 @@ index 1c095b5..959bf0b 100644 #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */ #define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode */ #define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */ -+#define V4L2_PIX_FMT_RW16 v4l2_fourcc('R', 'W', '1', '6') /* Raw data 16-bit */ -+#define V4L2_PIX_FMT_W10 v4l2_fourcc('W', '1', '0', ' ') /* Packed raw data 10-bit */ ++#define V4L2_PIX_FMT_RW16 v4l2_fourcc('R', 'W', '1', '6') /* Raw data 16-bit */ ++#define V4L2_PIX_FMT_W10 v4l2_fourcc('W', '1', '0', ' ') /* Packed raw data 10-bit */ +#define V4L2_PIX_FMT_CONFIDENCE_MAP v4l2_fourcc('C', ' ', ' ', ' ') /* Two pixels in one byte */ + +/* Librealsense development*/ -+#define V4L2_PIX_FMT_FG v4l2_fourcc('F', 'G', ' ', ' ') /* Frame Grabber */ -+#define V4L2_PIX_FMT_INZC v4l2_fourcc('I', 'N', 'Z', 'C') /* Planar Depth/Confidence */ -+#define V4L2_PIX_FMT_PAIR v4l2_fourcc('P', 'A', 'I', 'R') /* Relative IR */ -+#define V4L2_PIX_FMT_Z16H v4l2_fourcc('Z', '1', '6', 'H') /* Depth Z16 custom Huffman Code compression*/ ++#define V4L2_PIX_FMT_FG v4l2_fourcc('F', 'G', ' ', ' ') /* Frame Grabber */ ++#define V4L2_PIX_FMT_INZC v4l2_fourcc('I', 'N', 'Z', 'C') /* Planar Depth/Confidence */ ++#define V4L2_PIX_FMT_PAIR v4l2_fourcc('P', 'A', 'I', 'R') /* Relative IR */ ++#define V4L2_PIX_FMT_Z16H v4l2_fourcc('Z', '1', '6', 'H') /* Depth Z16 custom Huffman Code compression*/ /* SDR formats - used only for Software Defined Radio devices */ #define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */ From c0e228251da6bdde6a64234bce46c44e354c4785 Mon Sep 17 00:00:00 2001 From: ev-mp Date: Sat, 20 Jun 2020 10:53:56 +0300 Subject: [PATCH 44/61] Fix Confidence stream FourCC for kernel v4.18+ --- src/l500/l500-device.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/l500/l500-device.cpp b/src/l500/l500-device.cpp index 9a1187f712..cc87e5caf6 100644 --- a/src/l500/l500-device.cpp +++ b/src/l500/l500-device.cpp @@ -30,12 +30,14 @@ namespace librealsense { rs_fourcc('G','R','E','Y'), RS2_FORMAT_Y8 }, { rs_fourcc('Z','1','6',' '), RS2_FORMAT_Z16 }, { rs_fourcc('C',' ',' ',' '), RS2_FORMAT_RAW8 }, + { rs_fourcc('C','N','F','4'), RS2_FORMAT_RAW8 }, }; std::map l500_depth_fourcc_to_rs2_stream = { { rs_fourcc('G','R','E','Y'), RS2_STREAM_INFRARED }, { rs_fourcc('Z','1','6',' '), RS2_STREAM_DEPTH }, - { rs_fourcc('C',' ',' ',' '), RS2_STREAM_CONFIDENCE } + { rs_fourcc('C',' ',' ',' '), RS2_STREAM_CONFIDENCE }, + { rs_fourcc('C','N','F','4'), RS2_STREAM_CONFIDENCE }, }; using namespace ivcam2; From 98565e2dc52b27764e4a82200b1d295e19482d57 Mon Sep 17 00:00:00 2001 From: Yu Meng Date: Fri, 19 Jun 2020 15:22:34 +0800 Subject: [PATCH 45/61] Fix the value of RS2_OPTION_FILTER_MAGNITUDE option for PointCloud processing block. --- .../RealSenseSDK2.0/ProcessingPipe/PointCloudDepth.asset | 2 +- .../ProcessingPipe/PointCloudDepthAndColor.asset | 2 +- .../ProcessingPipe/PointCloudProcessingBlocks.asset | 2 +- .../RealSenseSDK2.0/Scripts/ProcessingBlocks/RsPointCloud.cs | 5 ++--- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudDepth.asset b/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudDepth.asset index ced8a27fca..905ab2fb2b 100644 --- a/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudDepth.asset +++ b/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudDepth.asset @@ -45,4 +45,4 @@ MonoBehaviour: enabled: 1 TextureStream: 1 TextureFormat: 1 - _occlusionRemoval: 0 + _occlusionRemoval: 1 diff --git a/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudDepthAndColor.asset b/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudDepthAndColor.asset index 10405f03a4..79ef06fa93 100644 --- a/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudDepthAndColor.asset +++ b/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudDepthAndColor.asset @@ -27,4 +27,4 @@ MonoBehaviour: enabled: 1 TextureStream: 2 TextureFormat: 5 - _occlusionRemoval: 0 + _occlusionRemoval: 1 diff --git a/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudProcessingBlocks.asset b/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudProcessingBlocks.asset index c28970e927..a53e2b8499 100644 --- a/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudProcessingBlocks.asset +++ b/wrappers/unity/Assets/RealSenseSDK2.0/ProcessingPipe/PointCloudProcessingBlocks.asset @@ -138,7 +138,7 @@ MonoBehaviour: enabled: 1 TextureStream: 1 TextureFormat: 5 - _occlusionRemoval: 0 + _occlusionRemoval: 1 --- !u!114 &114947088938950326 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/wrappers/unity/Assets/RealSenseSDK2.0/Scripts/ProcessingBlocks/RsPointCloud.cs b/wrappers/unity/Assets/RealSenseSDK2.0/Scripts/ProcessingBlocks/RsPointCloud.cs index ba2fe28de4..60328f0b43 100644 --- a/wrappers/unity/Assets/RealSenseSDK2.0/Scripts/ProcessingBlocks/RsPointCloud.cs +++ b/wrappers/unity/Assets/RealSenseSDK2.0/Scripts/ProcessingBlocks/RsPointCloud.cs @@ -5,9 +5,8 @@ public class RsPointCloud : RsProcessingBlock { public enum OcclusionRemoval { - Off = 0, - Heuristic = 1, - Exhaustive = 2 + Off = 1, + On = 2 } public Stream TextureStream = Stream.Color; From eade95ca3d240672f3e4dd9381a6f3332eba3055 Mon Sep 17 00:00:00 2001 From: ev-mp Date: Sat, 20 Jun 2020 15:21:39 +0300 Subject: [PATCH 46/61] Fix Bionic 4.18 build --- ...onic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch | 9 ++-- ...onic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch | 45 +++++++++---------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/scripts/realsense-camera-formats-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch b/scripts/realsense-camera-formats-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch index a5671dc0d8..bd6c7556c2 100644 --- a/scripts/realsense-camera-formats-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch +++ b/scripts/realsense-camera-formats-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch @@ -111,15 +111,16 @@ index be5cf1792..f405e5fe6 100644 + 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a} + #define UVC_GUID_FORMAT_Z16H \ + { 'Z', '1', '6', 'H', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ #define UVC_GUID_FORMAT_FG \ + { 'F', 'G', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} + #define UVC_GUID_FORMAT_INZC \ + { 'I', 'N', 'Z', 'C', 0x02, 0xb6, 0x0f, 0x48, \ -+ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} ++ 0x97, 0x8c, 0xe4, 0xe8, 0x8a, 0xe8, 0x9b, 0x89} + #define UVC_GUID_FORMAT_PAIR \ + { 'P', 'A', 'I', 'R', 0x36, 0x85, 0x41, 0x48, \ -+ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} ++ 0xb6, 0xbf, 0x8f, 0xc6, 0xff, 0xb0, 0x83, 0xa8} /* ------------------------------------------------------------------------ * Driver specific constants. diff --git a/scripts/realsense-metadata-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch b/scripts/realsense-metadata-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch index 39736d5524..3a0b0cd1f5 100644 --- a/scripts/realsense-metadata-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch +++ b/scripts/realsense-metadata-bionic-Ubuntu-hwe-4.18.0-25.26_18.04.1.patch @@ -1,20 +1,19 @@ -From 2be737f3c795751dcab548e0d8dbd7b1c2c89a49 Mon Sep 17 00:00:00 2001 -From: Evgeni -Date: Mon, 1 Apr 2019 15:54:03 +0300 -Subject: [PATCH] Enabling UVC Metadata attributes with Ubuntu 18.04. Kernel 4.18 - Signed-off-by: Evgeni +From 90588aff339a66dde0462042729692b8fa44373e Mon Sep 17 00:00:00 2001 +From: Evgeni Raikhel +Date: Sat, 20 Jun 2020 14:55:57 +0300 +Subject: [PATCH] Enabling UVC Metadata attributes with Ubuntu 18.04. Kernel 5.18 --- - drivers/media/usb/uvc/uvc_driver.c | 172 +++++++++++++++++++++++++++++ + drivers/media/usb/uvc/uvc_driver.c | 236 +++++++++++++++++++++++++++++ drivers/media/usb/uvc/uvcvideo.h | 2 +- include/uapi/linux/videodev2.h | 1 + - 3 files changed, 174 insertions(+), 1 deletion(-) + 3 files changed, 238 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c -index 8e1382013..880765a5e 100644 +index d74c9a2d3b0b..ae9f847c061d 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -2340,6 +2340,8 @@ static const struct uvc_device_info uvc_quirk_force_y8 = { +@@ -2397,6 +2397,8 @@ static const struct uvc_device_info uvc_quirk_force_y8 = { }; #define UVC_QUIRK_INFO(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q} @@ -23,10 +22,19 @@ index 8e1382013..880765a5e 100644 /* * The Logitech cameras listed below have their interface class set to -@@ -2813,6 +2815,240 @@ static const struct usb_device_id uvc_ids[] = { +@@ -2870,6 +2872,240 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_quirk_force_y8 }, ++ /* Intel SR300 depth camera */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x8086, ++ .idProduct = 0x0aa5, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_QUIRK_META(V4L2_META_FMT_D4XX) }, + /* Intel D400/PSR depth camera*/ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, @@ -153,15 +161,6 @@ index 8e1382013..880765a5e 100644 + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_META(V4L2_META_FMT_D4XX) }, -+ /* Intel SR300 depth camera */ -+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE -+ | USB_DEVICE_ID_MATCH_INT_INFO, -+ .idVendor = 0x8086, -+ .idProduct = 0x0aa5, -+ .bInterfaceClass = USB_CLASS_VIDEO, -+ .bInterfaceSubClass = 1, -+ .bInterfaceProtocol = 0, -+ .driver_info = UVC_QUIRK_META(V4L2_META_FMT_D4XX) }, + /* Intel D405 S depth camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, @@ -265,10 +264,10 @@ index 8e1382013..880765a5e 100644 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) }, { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) }, diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h -index be5cf1792..42c82f3d3 100644 +index 3edb18288ab9..c86e44543b62 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h -@@ -170,7 +170,7 @@ +@@ -204,7 +204,7 @@ /* Maximum number of packets per URB. */ #define UVC_MAX_PACKETS 32 /* Maximum status buffer size in bytes of interrupt URB. */ @@ -278,10 +277,10 @@ index be5cf1792..42c82f3d3 100644 #define UVC_CTRL_CONTROL_TIMEOUT 500 #define UVC_CTRL_STREAMING_TIMEOUT 5000 diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h -index 082dc1439..fab1e7a37 100644 +index 3a6656d8abc1..bc2b184eee8a 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h -@@ -707,6 +707,7 @@ struct v4l2_pix_format { +@@ -715,6 +715,7 @@ struct v4l2_pix_format { #define V4L2_META_FMT_VSP1_HGO v4l2_fourcc('V', 'S', 'P', 'H') /* R-Car VSP1 1-D Histogram */ #define V4L2_META_FMT_VSP1_HGT v4l2_fourcc('V', 'S', 'P', 'T') /* R-Car VSP1 2-D Histogram */ #define V4L2_META_FMT_UVC v4l2_fourcc('U', 'V', 'C', 'H') /* UVC Payload Header metadata */ From ea05d7f8464a272c6e5da379555c6ef7d54ce861 Mon Sep 17 00:00:00 2001 From: remibettan Date: Sun, 21 Jun 2020 09:13:27 +0300 Subject: [PATCH 47/61] fix linux build --- src/ds5/ds5-factory.cpp | 36 +++++++++++++++++----------------- src/firmware_logger_device.cpp | 8 ++++++-- src/firmware_logger_device.h | 5 +++-- src/ivcam/sr300.cpp | 2 +- src/l500/l500-factory.cpp | 4 ++-- 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/ds5/ds5-factory.cpp b/src/ds5/ds5-factory.cpp index e74059b0f5..90d84d934e 100644 --- a/src/ds5/ds5-factory.cpp +++ b/src/ds5/ds5-factory.cpp @@ -39,7 +39,7 @@ namespace librealsense ds5_device(ctx, group), ds5_nonmonochrome(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -77,7 +77,7 @@ namespace librealsense : device(ctx, group, register_device_notifications), ds5u_device(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -131,7 +131,7 @@ namespace librealsense ds5_nonmonochrome(ctx, group), ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -171,7 +171,7 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -211,7 +211,7 @@ namespace librealsense ds5_nonmonochrome(ctx, group), ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -266,7 +266,7 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -318,7 +318,7 @@ namespace librealsense ds5_device(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -364,7 +364,7 @@ namespace librealsense : device(ctx, group, register_device_notifications), ds5_device(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -403,7 +403,7 @@ namespace librealsense ds5_device(ctx, group), ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -443,7 +443,7 @@ namespace librealsense ds5_active(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), ds5_motion(ctx, group), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -487,7 +487,7 @@ namespace librealsense ds5_active(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -537,7 +537,7 @@ namespace librealsense ds5_active(ctx, group), ds5_color(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -580,7 +580,7 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -623,7 +623,7 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) { @@ -843,7 +843,7 @@ namespace librealsense ds5_motion(ctx, group), ds5_nonmonochrome(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -881,7 +881,7 @@ namespace librealsense ds5_device(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -913,7 +913,7 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -959,7 +959,7 @@ namespace librealsense ds5_color(ctx, group), ds5_motion(ctx, group), ds5_advanced_mode_base(ds5_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(ds5_device::_hw_monitor, + firmware_logger_device(ctx, group, ds5_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index ef53d64c15..647c699c67 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -6,13 +6,17 @@ namespace librealsense { - firmware_logger_device::firmware_logger_device(std::shared_ptr hardware_monitor, + firmware_logger_device::firmware_logger_device(std::shared_ptr ctx, + const platform::backend_device_group group, + std::shared_ptr hardware_monitor, const command& fw_logs_command, const command& flash_logs_command) : + device(ctx, group), _hw_monitor(hardware_monitor), _fw_logs(), _flash_logs(), _flash_logs_initialized(false), - _parser(nullptr), _fw_logs_command(fw_logs_command), + _parser(nullptr), + _fw_logs_command(fw_logs_command), _flash_logs_command(flash_logs_command) { } bool firmware_logger_device::get_fw_log(fw_logs::fw_logs_binary_data& binary_data) diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index 5e41ca17df..7634a12f9c 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -25,8 +25,9 @@ namespace librealsense class firmware_logger_device : public virtual device, public firmware_logger_extensions { public: - firmware_logger_device(std::shared_ptr hardware_monitor, - const command& _fw_logs_command, const command& _flash_logs_command); + firmware_logger_device(std::shared_ptr ctx, const platform::backend_device_group group, + std::shared_ptr hardware_monitor, + const command& fw_logs_command, const command& flash_logs_command); bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) override; bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) override; diff --git a/src/ivcam/sr300.cpp b/src/ivcam/sr300.cpp index e903b7bce1..867174bbf3 100644 --- a/src/ivcam/sr300.cpp +++ b/src/ivcam/sr300.cpp @@ -422,7 +422,7 @@ namespace librealsense const platform::backend_device_group& group, bool register_device_notifications) : device(ctx, group, register_device_notifications), - firmware_logger_device(_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()), + firmware_logger_device(ctx, group, _hw_monitor, get_firmware_logs_command(), get_flash_logs_command()), _depth_device_idx(add_sensor(create_depth_device(ctx, depth))), _depth_stream(new stream(RS2_STREAM_DEPTH)), _ir_stream(new stream(RS2_STREAM_INFRARED)), diff --git a/src/l500/l500-factory.cpp b/src/l500/l500-factory.cpp index 7bf33bd82e..c1ae01a722 100644 --- a/src/l500/l500-factory.cpp +++ b/src/l500/l500-factory.cpp @@ -42,7 +42,7 @@ namespace librealsense l500_color(ctx, group), l500_motion(ctx, group), l500_serializable(l500_device::_hw_monitor, get_depth_sensor()), - firmware_logger_device(l500_device::_hw_monitor, + firmware_logger_device(ctx, group, l500_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} @@ -74,7 +74,7 @@ namespace librealsense : device(ctx, group, register_device_notifications), l500_device(ctx, group), l500_depth(ctx, group), - firmware_logger_device(l500_device::_hw_monitor, + firmware_logger_device(ctx, group,l500_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command()) {} From 7b08009303ce385922e56629e882fe5220444bf5 Mon Sep 17 00:00:00 2001 From: remibettan Date: Mon, 22 Jun 2020 11:49:55 +0300 Subject: [PATCH 48/61] tabs to spaces --- include/librealsense2/h/rs_internal.h | 64 +++++++++++++-------------- src/firmware_logger_device.cpp | 4 +- src/firmware_logger_device.h | 64 +++++++++++++-------------- 3 files changed, 66 insertions(+), 66 deletions(-) diff --git a/include/librealsense2/h/rs_internal.h b/include/librealsense2/h/rs_internal.h index b5150507b7..5691c63727 100644 --- a/include/librealsense2/h/rs_internal.h +++ b/include/librealsense2/h/rs_internal.h @@ -350,7 +350,7 @@ void rs2_software_sensor_detach(rs2_sensor* sensor, rs2_error** error); /** * \brief Creates RealSense firmware log message. -* \param[in] dev Device from which the FW log will be taken using the created message +* \param[in] dev Device from which the FW log will be taken using the created message * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return pointer to created empty firmware log message */ @@ -358,8 +358,8 @@ rs2_firmware_log_message* rs2_create_fw_log_message(rs2_device* dev, rs2_error** /** * \brief Gets RealSense firmware log. -* \param[in] dev Device from which the FW log should be taken -* \param[in] fw_log_msg Firmware log message object to be filled +* \param[in] dev Device from which the FW log should be taken +* \param[in] fw_log_msg Firmware log message object to be filled * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor */ @@ -367,8 +367,8 @@ int rs2_get_fw_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_e /** * \brief Gets RealSense flash log - this is a fw log that has been written in the device during the previous shutdown of the device -* \param[in] dev Device from which the FW log should be taken -* \param[in] fw_log_msg Firmware log message object to be filled +* \param[in] dev Device from which the FW log should be taken +* \param[in] fw_log_msg Firmware log message object to be filled * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor */ @@ -382,7 +382,7 @@ void rs2_delete_fw_log_message(rs2_firmware_log_message* msg); /** * \brief Gets RealSense firmware log message data. -* \param[in] msg firmware log message object +* \param[in] msg firmware log message object * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return pointer to start of the firmware log message data */ @@ -390,7 +390,7 @@ const unsigned char* rs2_fw_log_message_data(rs2_firmware_log_message* msg, rs2_ /** * \brief Gets RealSense firmware log message size. -* \param[in] msg firmware log message object +* \param[in] msg firmware log message object * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return size of the firmware log message data */ @@ -399,7 +399,7 @@ int rs2_fw_log_message_size(rs2_firmware_log_message* msg, rs2_error** error); /** * \brief Gets RealSense firmware log message timestamp. -* \param[in] msg firmware log message object +* \param[in] msg firmware log message object * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return timestamp of the firmware log message */ @@ -407,7 +407,7 @@ unsigned int rs2_fw_log_message_timestamp(rs2_firmware_log_message* msg, rs2_err /** * \brief Gets RealSense firmware log message severity. -* \param[in] msg firmware log message object +* \param[in] msg firmware log message object * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return severity of the firmware log message data */ @@ -415,8 +415,8 @@ rs2_log_severity rs2_fw_log_message_severity(const rs2_firmware_log_message* msg /** * \brief Initializes RealSense firmware logs parser in device. -* \param[in] dev Device from which the FW log will be taken -* \param[in] xml_content content of the xml file needed for parsing +* \param[in] dev Device from which the FW log will be taken +* \param[in] xml_content content of the xml file needed for parsing * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return true for success, false for failure - failure happens if opening the xml from the xml_path input fails */ @@ -425,7 +425,7 @@ int rs2_init_fw_log_parser(rs2_device* dev, const char* xml_content, rs2_error** /** * \brief Creates RealSense firmware log parsed message. -* \param[in] dev Device from which the FW log will be taken using the created message +* \param[in] dev Device from which the FW log will be taken using the created message * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return pointer to created empty firmware log message */ @@ -433,16 +433,16 @@ rs2_firmware_log_parsed_message* rs2_create_fw_log_parsed_message(rs2_device* de /** * \brief Deletes RealSense firmware log parsed message. -* \param[in] msg message to be deleted +* \param[in] msg message to be deleted */ void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg); /** * \brief Gets RealSense firmware log parser -* \param[in] dev Device from which the FW log will be taken -* \param[in] fw_log_msg firmware log message to be parsed -* \param[in] parsed_msg firmware log parsed message - place holder for the resulting parsed message +* \param[in] dev Device from which the FW log will be taken +* \param[in] fw_log_msg firmware log message to be parsed +* \param[in] parsed_msg firmware log parsed message - place holder for the resulting parsed message * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return true for success, false for failure - failure happens if message could not be parsed */ @@ -456,7 +456,7 @@ void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_pa /** * \brief Gets RealSense firmware log parsed message. -* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[in] fw_log_parsed_msg firmware log parsed message object * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return message of the firmware log parsed message */ @@ -464,7 +464,7 @@ const char* rs2_get_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_lo /** * \brief Gets RealSense firmware log parsed message file name. -* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[in] fw_log_parsed_msg firmware log parsed message object * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return file name of the firmware log parsed message */ @@ -472,7 +472,7 @@ const char* rs2_get_fw_log_parsed_file_name(rs2_firmware_log_parsed_message* fw_ /** * \brief Gets RealSense firmware log parsed message thread name. -* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[in] fw_log_parsed_msg firmware log parsed message object * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return thread name of the firmware log parsed message */ @@ -480,7 +480,7 @@ const char* rs2_get_fw_log_parsed_thread_name(rs2_firmware_log_parsed_message* f /** * \brief Gets RealSense firmware log parsed message severity. -* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[in] fw_log_parsed_msg firmware log parsed message object * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return severity of the firmware log parsed message */ @@ -488,7 +488,7 @@ rs2_log_severity rs2_get_fw_log_parsed_severity(rs2_firmware_log_parsed_message* /** * \brief Gets RealSense firmware log parsed message relevant line (in the file that is returned by rs2_get_fw_log_parsed_file_name). -* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[in] fw_log_parsed_msg firmware log parsed message object * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return line number of the firmware log parsed message */ @@ -496,7 +496,7 @@ unsigned int rs2_get_fw_log_parsed_line(rs2_firmware_log_parsed_message* fw_log_ /** * \brief Gets RealSense firmware log parsed message timestamp -* \param[in] fw_log_parsed_msg firmware log parsed message object +* \param[in] fw_log_parsed_msg firmware log parsed message object * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return timestamp of the firmware log parsed message */ @@ -504,7 +504,7 @@ unsigned int rs2_get_fw_log_parsed_timestamp(rs2_firmware_log_parsed_message* fw /** * \brief Creates RealSense terminal parser. -* \param[in] xml_content content of the xml file needed for parsing +* \param[in] xml_content content of the xml file needed for parsing * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return pointer to created terminal parser object */ @@ -512,15 +512,15 @@ rs2_terminal_parser* rs2_create_terminal_parser(const char* xml_content, rs2_err /** * \brief Deletes RealSense terminal parser. -* \param[in] terminal_parser terminal parser to be deleted +* \param[in] terminal_parser terminal parser to be deleted */ void rs2_delete_terminal_parser(rs2_terminal_parser* terminal_parser); /** * \brief Parses terminal command via RealSense terminal parser -* \param[in] terminal_parser Terminal parser object -* \param[in] command command to be sent to the hw monitor of the device -* \param[in] size_of_command size of command to be sent to the hw monitor of the device +* \param[in] terminal_parser Terminal parser object +* \param[in] command command to be sent to the hw monitor of the device +* \param[in] size_of_command size of command to be sent to the hw monitor of the device * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return command to hw monitor, in hex */ @@ -529,11 +529,11 @@ rs2_raw_data_buffer* rs2_terminal_parse_command(rs2_terminal_parser* terminal_pa /** * \brief Parses terminal response via RealSense terminal parser -* \param[in] terminal_parser Terminal parser object -* \param[in] command command sent to the hw monitor of the device -* \param[in] size_of_command size of the command to sent to the hw monitor of the device -* \param[in] response response received by the hw monitor of the device -* \param[in] size_of_response size of the response received by the hw monitor of the device +* \param[in] terminal_parser Terminal parser object +* \param[in] command command sent to the hw monitor of the device +* \param[in] size_of_command size of the command to sent to the hw monitor of the device +* \param[in] response response received by the hw monitor of the device +* \param[in] size_of_response size of the response received by the hw monitor of the device * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return answer parsed */ diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index 647c699c67..63564c52cd 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -119,7 +119,7 @@ namespace librealsense bool firmware_logger_device::parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) - { + { bool result = false; if (_parser && parsed_msg && fw_log_msg) { @@ -128,6 +128,6 @@ namespace librealsense } return result; - } + } } diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index 7634a12f9c..2eb6ae1ac1 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -11,48 +11,48 @@ namespace librealsense { - class firmware_logger_extensions - { - public: - virtual bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) = 0; - virtual bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) = 0; - virtual bool init_parser(std::string xml_content) = 0; - virtual bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) = 0; - virtual ~firmware_logger_extensions() = default; - }; - MAP_EXTENSION(RS2_EXTENSION_FW_LOGGER, librealsense::firmware_logger_extensions); + class firmware_logger_extensions + { + public: + virtual bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) = 0; + virtual bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) = 0; + virtual bool init_parser(std::string xml_content) = 0; + virtual bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) = 0; + virtual ~firmware_logger_extensions() = default; + }; + MAP_EXTENSION(RS2_EXTENSION_FW_LOGGER, librealsense::firmware_logger_extensions); - class firmware_logger_device : public virtual device, public firmware_logger_extensions - { - public: - firmware_logger_device(std::shared_ptr ctx, const platform::backend_device_group group, - std::shared_ptr hardware_monitor, - const command& fw_logs_command, const command& flash_logs_command); + class firmware_logger_device : public virtual device, public firmware_logger_extensions + { + public: + firmware_logger_device(std::shared_ptr ctx, const platform::backend_device_group group, + std::shared_ptr hardware_monitor, + const command& fw_logs_command, const command& flash_logs_command); - bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) override; - bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) override; + bool get_fw_log(fw_logs::fw_logs_binary_data& binary_data) override; + bool get_flash_log(fw_logs::fw_logs_binary_data& binary_data) override; - bool init_parser(std::string xml_content) override; - bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) override; + bool init_parser(std::string xml_content) override; + bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) override; - private: + private: - void get_fw_logs_from_hw_monitor(); - void get_flash_logs_from_hw_monitor(); + void get_fw_logs_from_hw_monitor(); + void get_flash_logs_from_hw_monitor(); - command _fw_logs_command; - command _flash_logs_command; + command _fw_logs_command; + command _flash_logs_command; - std::shared_ptr _hw_monitor; + std::shared_ptr _hw_monitor; - std::queue _fw_logs; - std::queue _flash_logs; + std::queue _fw_logs; + std::queue _flash_logs; - bool _flash_logs_initialized; + bool _flash_logs_initialized; - fw_logs::fw_logs_parser* _parser; - uint16_t _device_pid; + fw_logs::fw_logs_parser* _parser; + uint16_t _device_pid; - }; + }; } From 408f2e10989c48ff259f25752166d5bcd8d67b1e Mon Sep 17 00:00:00 2001 From: remibettan Date: Mon, 22 Jun 2020 12:28:29 +0300 Subject: [PATCH 49/61] correct stoi call for linux build --- src/fw-logs/fw-logs-xml-helper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fw-logs/fw-logs-xml-helper.cpp b/src/fw-logs/fw-logs-xml-helper.cpp index 42adfd501d..e5f19f1b37 100644 --- a/src/fw-logs/fw-logs-xml-helper.cpp +++ b/src/fw-logs/fw-logs-xml-helper.cpp @@ -145,7 +145,7 @@ namespace librealsense try { auto key_str = std::string(attribute->value()); - key = std::stoi(key_str, nullptr); + key = std::stoi(key_str); } catch (...) {} } From 428130708d141aac8e49d1f82a5a719883743c30 Mon Sep 17 00:00:00 2001 From: ev-mp Date: Mon, 22 Jun 2020 23:27:59 +0300 Subject: [PATCH 50/61] relax unit-tests criteria for specific pipeline cases --- unit-tests/unit-tests-live.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/unit-tests/unit-tests-live.cpp b/unit-tests/unit-tests-live.cpp index fbf811d847..8ba70c49f0 100644 --- a/unit-tests/unit-tests-live.cpp +++ b/unit-tests/unit-tests-live.cpp @@ -2980,7 +2980,7 @@ static const std::map< dev_type, device_profiles> pipeline_default_configuration /* SR300*/ { { "0AA5", true } ,{ { { RS2_STREAM_DEPTH, RS2_FORMAT_Z16, 640, 480, 0 },{ RS2_STREAM_COLOR, RS2_FORMAT_RGB8, 1920, 1080, 0 } }, 30, true } }, }; -TEST_CASE("Pipeline wait_for_frames", "[live][pipeline][using_pipeline]") { +TEST_CASE("Pipeline wait_for_frames", "[live][pipeline][using_pipeline][!mayfail]") { rs2::context ctx; @@ -3046,7 +3046,7 @@ TEST_CASE("Pipeline wait_for_frames", "[live][pipeline][using_pipeline]") { } } -TEST_CASE("Pipeline poll_for_frames", "[live][pipeline][using_pipeline]") +TEST_CASE("Pipeline poll_for_frames", "[live][pipeline][using_pipeline][!mayfail]") { rs2::context ctx; @@ -3311,7 +3311,7 @@ TEST_CASE("Pipeline enable stream auto complete", "[live][pipeline][using_pipeli } } -TEST_CASE("Pipeline disable_all", "[live][pipeline][using_pipeline]") { +TEST_CASE("Pipeline disable_all", "[live][pipeline][using_pipeline][!mayfail]") { auto not_default_configurations = pipeline_custom_configurations; auto default_configurations = pipeline_default_configurations; @@ -4730,7 +4730,7 @@ TEST_CASE("Pipeline stream enable hierarchy", "[pipeline]") } } -TEST_CASE("Pipeline stream with callback", "[live][pipeline][using_pipeline]") +TEST_CASE("Pipeline stream with callback", "[live][pipeline][using_pipeline][!mayfail]") { rs2::context ctx; @@ -5830,7 +5830,7 @@ TEST_CASE("Wheel_Odometry_API", "[live]") } -TEST_CASE("get_sensor_from_frame", "[live][using_pipeline]") +TEST_CASE("get_sensor_from_frame", "[live][using_pipeline][!mayfail]") { // Require at least one device to be plugged in rs2::context ctx; From 0119aa8bf8e4ef8e9484b3de9fa5f9bb34de98a7 Mon Sep 17 00:00:00 2001 From: gwen2018 Date: Mon, 22 Jun 2020 19:16:03 -0700 Subject: [PATCH 51/61] temporary fix invoke_and_wait - revert back wait_for to sleep equivalent --- src/concurrency.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/concurrency.h b/src/concurrency.h index 7dbf55d2a8..49873f4533 100644 --- a/src/concurrency.h +++ b/src/concurrency.h @@ -273,7 +273,7 @@ class dispatcher //wait std::unique_lock lk(_blocking_invoke_mutex); - _blocking_invoke_cv.wait(lk, [&](){ return done || exit_condition(); }); + while(_blocking_invoke_cv.wait_for(lk, std::chrono::milliseconds(10), [&](){ return !done && !exit_condition(); })); } void start() @@ -443,4 +443,4 @@ class watchdog bool _blocker = true; std::function _operation; std::shared_ptr> _watcher; -}; \ No newline at end of file +}; From 5c275658643b5d1391fecfa05c91e31526bee5aa Mon Sep 17 00:00:00 2001 From: Evgeni Raikhel Date: Tue, 23 Jun 2020 12:29:52 +0300 Subject: [PATCH 52/61] Temporal work-around for HW Monitor injection for SR300 Change-Id: I427e31accda8f88bd17b0da5fbd130998dce8133 --- src/firmware_logger_device.h | 4 ++++ src/ivcam/sr300.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index 2eb6ae1ac1..2d948b3f36 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -35,6 +35,10 @@ namespace librealsense bool init_parser(std::string xml_content) override; bool parse_log(const fw_logs::fw_logs_binary_data* fw_log_msg, fw_logs::fw_log_data* parsed_msg) override; + // Temporal solution for HW_Monitor injection + void assign_hw_monitor(std::shared_ptr hardware_monitor) + { _hw_monitor = hardware_monitor; } + private: void get_fw_logs_from_hw_monitor(); diff --git a/src/ivcam/sr300.cpp b/src/ivcam/sr300.cpp index 867174bbf3..ebbb564fd8 100644 --- a/src/ivcam/sr300.cpp +++ b/src/ivcam/sr300.cpp @@ -381,7 +381,7 @@ namespace librealsense return flash; } - void sr300_camera::update_flash(const std::vector& image, update_progress_callback_ptr callback, int update_mode) + void sr300_camera::update_flash(const std::vector&, update_progress_callback_ptr, int) { throw std::runtime_error("update_flash is not supported by SR300"); } @@ -422,7 +422,7 @@ namespace librealsense const platform::backend_device_group& group, bool register_device_notifications) : device(ctx, group, register_device_notifications), - firmware_logger_device(ctx, group, _hw_monitor, get_firmware_logs_command(), get_flash_logs_command()), + firmware_logger_device(ctx, group, nullptr, get_firmware_logs_command(), get_flash_logs_command()), _depth_device_idx(add_sensor(create_depth_device(ctx, depth))), _depth_stream(new stream(RS2_STREAM_DEPTH)), _ir_stream(new stream(RS2_STREAM_INFRARED)), @@ -433,6 +433,8 @@ namespace librealsense using namespace ivcam; static auto device_name = "Intel RealSense SR300"; + // Temporal solution for HW Monitor injection - to be refactored + this->assign_hw_monitor(_hw_monitor); std::vector gvd_buff(HW_MONITOR_BUFFER_SIZE); _hw_monitor->get_gvd(gvd_buff.size(), gvd_buff.data(), GVD); // fooling tests recordings - don't remove From 81cffa839148fa620ebace13292ebc54c4cf5c6c Mon Sep 17 00:00:00 2001 From: NirAz Date: Thu, 18 Jun 2020 21:20:29 +0300 Subject: [PATCH 53/61] Add QVGA sensor mode --- common/model-views.cpp | 6 ++++-- include/librealsense2/h/rs_option.h | 1 + src/l500/l500-depth.cpp | 4 +++- src/l500/l500-options.cpp | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/common/model-views.cpp b/common/model-views.cpp index 33258c871b..44500d908b 100644 --- a/common/model-views.cpp +++ b/common/model-views.cpp @@ -43,7 +43,9 @@ using namespace rs2::sw_update; static rs2_sensor_mode resolution_from_width_height(int width, int height) { - if ((width == 640 && height == 480) || (height == 640 && width == 480)) + if ((width == 240 && height == 320) || (width == 320 && height == 240)) + return RS2_SENSOR_MODE_QVGA; + else if ((width == 640 && height == 480) || (height == 640 && width == 480)) return RS2_SENSOR_MODE_VGA; else if ((width == 1024 && height == 768) || (height == 768 && width == 1024)) return RS2_SENSOR_MODE_XGA; @@ -1237,7 +1239,7 @@ namespace rs2 auto width = res_values[ui.selected_res_id].first; auto height = res_values[ui.selected_res_id].second; auto res = resolution_from_width_height(width, height); - if (res >= RS2_SENSOR_MODE_XGA && res < RS2_SENSOR_MODE_COUNT) + if (res >= RS2_SENSOR_MODE_QVGA && res < RS2_SENSOR_MODE_COUNT) s->set_option(RS2_OPTION_SENSOR_MODE, res); } } diff --git a/include/librealsense2/h/rs_option.h b/include/librealsense2/h/rs_option.h index d0694f7d2d..5ad8d8f65c 100644 --- a/include/librealsense2/h/rs_option.h +++ b/include/librealsense2/h/rs_option.h @@ -148,6 +148,7 @@ extern "C" { /** \brief For setting the camera_mode option */ typedef enum rs2_sensor_mode { + RS2_SENSOR_MODE_QVGA, RS2_SENSOR_MODE_VGA, RS2_SENSOR_MODE_XGA, RS2_SENSOR_MODE_COUNT /**< Number of enumeration values. Not a valid input: intended to be used in for-loops. */ diff --git a/src/l500/l500-depth.cpp b/src/l500/l500-depth.cpp index 63cc9d3a0a..efb033a8a1 100644 --- a/src/l500/l500-depth.cpp +++ b/src/l500/l500-depth.cpp @@ -266,7 +266,9 @@ namespace librealsense rs2_sensor_mode get_resolution_from_width_height(int width, int height) { - if ((width == 640 && height == 480) || (width == 480 && height == 640)) + if ((width == 240 && height == 320) || (width == 320 && height == 240)) + return RS2_SENSOR_MODE_QVGA; + else if ((width == 640 && height == 480) || (width == 480 && height == 640)) return RS2_SENSOR_MODE_VGA; else if ((width == 1024 && height == 768) || (width == 768 && height == 1024)) return RS2_SENSOR_MODE_XGA; diff --git a/src/l500/l500-options.cpp b/src/l500/l500-options.cpp index 2a70be7e31..c5f162d186 100644 --- a/src/l500/l500-options.cpp +++ b/src/l500/l500-options.cpp @@ -94,7 +94,7 @@ namespace librealsense } else { - auto resolution_option = std::make_shared>(option_range{ RS2_SENSOR_MODE_VGA,RS2_SENSOR_MODE_XGA,1, RS2_SENSOR_MODE_XGA }, "Notify the sensor about the intended streaming mode. Required for preset "); + auto resolution_option = std::make_shared>(option_range{ RS2_SENSOR_MODE_QVGA,RS2_SENSOR_MODE_XGA,1, RS2_SENSOR_MODE_XGA }, "Notify the sensor about the intended streaming mode. Required for preset "); depth_sensor.register_option(RS2_OPTION_SENSOR_MODE, resolution_option); From 10e402a09d62f3368af2ba289887e0b47828c220 Mon Sep 17 00:00:00 2001 From: NirAz Date: Tue, 23 Jun 2020 11:16:34 +0300 Subject: [PATCH 54/61] change enum order for backward compatibility --- common/model-views.cpp | 2 +- include/librealsense2/h/rs_option.h | 2 +- src/l500/l500-options.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/model-views.cpp b/common/model-views.cpp index 44500d908b..680ff56d5c 100644 --- a/common/model-views.cpp +++ b/common/model-views.cpp @@ -1239,7 +1239,7 @@ namespace rs2 auto width = res_values[ui.selected_res_id].first; auto height = res_values[ui.selected_res_id].second; auto res = resolution_from_width_height(width, height); - if (res >= RS2_SENSOR_MODE_QVGA && res < RS2_SENSOR_MODE_COUNT) + if (res >= RS2_SENSOR_MODE_VGA && res < RS2_SENSOR_MODE_COUNT) s->set_option(RS2_OPTION_SENSOR_MODE, res); } } diff --git a/include/librealsense2/h/rs_option.h b/include/librealsense2/h/rs_option.h index 5ad8d8f65c..8a092b5fd4 100644 --- a/include/librealsense2/h/rs_option.h +++ b/include/librealsense2/h/rs_option.h @@ -148,9 +148,9 @@ extern "C" { /** \brief For setting the camera_mode option */ typedef enum rs2_sensor_mode { - RS2_SENSOR_MODE_QVGA, RS2_SENSOR_MODE_VGA, RS2_SENSOR_MODE_XGA, + RS2_SENSOR_MODE_QVGA, RS2_SENSOR_MODE_COUNT /**< Number of enumeration values. Not a valid input: intended to be used in for-loops. */ } rs2_sensor_mode; const char* rs2_sensor_mode_to_string(rs2_sensor_mode preset); diff --git a/src/l500/l500-options.cpp b/src/l500/l500-options.cpp index c5f162d186..5c726d6ad8 100644 --- a/src/l500/l500-options.cpp +++ b/src/l500/l500-options.cpp @@ -94,7 +94,7 @@ namespace librealsense } else { - auto resolution_option = std::make_shared>(option_range{ RS2_SENSOR_MODE_QVGA,RS2_SENSOR_MODE_XGA,1, RS2_SENSOR_MODE_XGA }, "Notify the sensor about the intended streaming mode. Required for preset "); + auto resolution_option = std::make_shared>(option_range{ RS2_SENSOR_MODE_VGA,RS2_SENSOR_MODE_COUNT - 1,1, RS2_SENSOR_MODE_XGA }, "Notify the sensor about the intended streaming mode. Required for preset "); depth_sensor.register_option(RS2_OPTION_SENSOR_MODE, resolution_option); From dc1ae29e2feb80b771754c8bdec7f2ece626d8dc Mon Sep 17 00:00:00 2001 From: Andrei Costinescu Date: Tue, 23 Jun 2020 11:18:58 +0200 Subject: [PATCH 55/61] Fixed "depth" typo depht -> depth --- wrappers/opencv/dnn/rs-dnn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/opencv/dnn/rs-dnn.cpp b/wrappers/opencv/dnn/rs-dnn.cpp index e9cdd76341..c14028a537 100644 --- a/wrappers/opencv/dnn/rs-dnn.cpp +++ b/wrappers/opencv/dnn/rs-dnn.cpp @@ -107,7 +107,7 @@ int main(int argc, char** argv) try // Calculate mean depth inside the detection region // This is a very naive way to estimate objects depth // but it is intended to demonstrate how one might - // use depht data in general + // use depth data in general Scalar m = mean(depth_mat(object)); std::ostringstream ss; From 51dc600c9902f60214cb8f0b0a5318f08b0eac4d Mon Sep 17 00:00:00 2001 From: Sergey Dorodnicov Date: Tue, 23 Jun 2020 13:57:50 +0300 Subject: [PATCH 56/61] Changes in librealsense --- src/ds5/ds5-private.h | 2 +- src/l500/l500-factory.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ds5/ds5-private.h b/src/ds5/ds5-private.h index 38f0e09881..9f51c2967d 100644 --- a/src/ds5/ds5-private.h +++ b/src/ds5/ds5-private.h @@ -333,7 +333,6 @@ namespace librealsense uint32_t param; // This field content is defined ny table type uint32_t crc32; // crc of all the actual table data excluding header/CRC }; -#pragma pack(pop) enum ds5_rect_resolutions : unsigned short { @@ -380,6 +379,7 @@ namespace librealsense float ppx; float ppy; }; +#pragma pack(pop) template const T* check_calib(const std::vector& raw_data) diff --git a/src/l500/l500-factory.cpp b/src/l500/l500-factory.cpp index c1ae01a722..265c272b4b 100644 --- a/src/l500/l500-factory.cpp +++ b/src/l500/l500-factory.cpp @@ -19,6 +19,8 @@ #include "l500-color.h" #include "l500-serializable.h" +#include "../firmware_logger_device.h" + namespace librealsense { using namespace ivcam2; From dd94bab8f44f925e59f6f46a92d6bd2f96d3d5ce Mon Sep 17 00:00:00 2001 From: Sergey Dorodnicov Date: Tue, 23 Jun 2020 13:58:19 +0300 Subject: [PATCH 57/61] Changes in IMGUI --- third-party/imgui/imgui-fonts-monofont.hpp | 1368 ++++++++++++++++++++ third-party/imgui/imgui_impl_glfw.cpp | 3 + 2 files changed, 1371 insertions(+) create mode 100644 third-party/imgui/imgui-fonts-monofont.hpp diff --git a/third-party/imgui/imgui-fonts-monofont.hpp b/third-party/imgui/imgui-fonts-monofont.hpp new file mode 100644 index 0000000000..f47ab242b5 --- /dev/null +++ b/third-party/imgui/imgui-fonts-monofont.hpp @@ -0,0 +1,1368 @@ +// File: 'AnonymousPro-Regular.ttf' (112072 bytes) +// Exported using binary_to_compressed_c.cpp +static const unsigned int monospace_compressed_size = 65326; +static const unsigned int monospace_compressed_data[65328/4] = +{ + 0x0000bc57, 0x00000000, 0xc8b50100, 0x00000400, 0x00010025, 0x82100000, 0x00042e04, 0x2f534f00, 0xbe624a32, 0x52010084, 0x28158240, 0x4d445660, + 0x72a56a58, 0x080f823c, 0x0000a020, 0x6d63e005, 0x12927061, 0x01009217, 0x00005862, 0x7663e203, 0x8a042074, 0x01009e0a, 0x2f824c68, 0x70662e3c, + 0x41926d67, 0x0100fada, 0x00003c66, 0x61676101, 0x15007073, 0x01000800, 0x1f82b8b5, 0x6c671028, 0x73bc6679, 0x1b82bfec, 0x01000c3f, 0x6468f046, + 0x6479786d, 0x0100b44d, 0x00008058, 0x6568d809, 0x2bff6461, 0x0100c49a, 0x222e824d, 0x82683600, 0x670a2310, 0x7f82ce02, 0x10821c20, 0x6d682428, + 0x6a347874, 0x1f82d035, 0x0000382f, 0x6f6ce204, 0x05b16163, 0x0100a762, 0x2d1f8248, 0x616de204, 0x88047078, 0x01006103, 0x2f82fc47, 0x616e2028, + 0x6704656d, 0x9f82685c, 0x00007c3b, 0x6f706a3b, 0xaae67473, 0x0100d736, 0x0000e8a3, 0x7270ce11, 0xf7307065, 0x211f82d4, 0x2f82a067, 0x00ab3b08, + 0x00310002, 0x05730300, 0x00030019, 0xb0450007, 0x09b02f08, 0xdc00b02f, 0xb01008b0, 0x01b0d001, 0x0c04b12f, 0x1000b0f4, 0xf40805b1, 0x4500b000, + 0x2f02b058, 0x1502b11b, 0x0c84593e, 0x0c820020, 0x3e0f0035, 0x0604b159, 0x1002b0f4, 0xf40606b1, 0x21213130, 0x82012111, 0x73033203, 0x4203befc, + 0x2f0247fd, 0x1905d1fd, 0x2f045cfb, 0x086f8200, 0x01000024, 0xa503a403, 0x1f001b00, 0x20b0bd00, 0x2f21b02f, 0xb1dc02b0, 0xb0f40d03, 0x07b01020, + 0x2f07b0d0, 0x0c8206b1, 0xb0100723, 0x2f0c820b, 0xd00fb010, 0xb01006b0, 0x03b0d011, 0xd013b010, 0xb0216582, 0x20058415, 0x20118419, 0x211d841c, + 0x9c85d01e, 0x8f821020, 0x86131021, 0x8214209c, 0x8714200c, 0x82b6840c, 0x20b684a9, 0x20198206, 0x2b0c8206, 0x00011bb3, 0x0fb32b04, 0x2b040c01, + 0xb022e482, 0x0583d004, 0xb0d0082c, 0x0ab0101b, 0x100fb0d0, 0x058412b0, 0xb0d01626, 0x18b0100c, 0x70821784, 0x1d290b82, 0x253130d0, 0x35231523, + 0x23038221, 0x11333523, 0x35230382, 0x82211533, 0x15332403, 0x82331123, 0x031128fe, 0xff75dda4, 0x82dd7500, 0x01752100, 0xfe240784, 0xde00ffae, + 0xdd250e82, 0x6d08016e, 0x3d0082e4, 0x01f8fe6d, 0x00f8fe08, 0x00000300, 0x830346ff, 0x2b00d305, 0x3b003200, 0x33b3af00, 0x9a820f08, 0x2c082422, + 0x29210582, 0x83a68208, 0x8409209a, 0xd0142ba0, 0xb01029b0, 0x24b0d016, 0x8e82b010, 0x2f1c2f08, 0xea2cdab4, 0x405d022c, 0x192c091b, 0x392c292c, + 0x592c492c, 0x792c692c, 0x992c892c, 0xb92ca92c, 0x0d2cc92c, 0x102cb05d, 0xb0d01db0, 0x3c832f1d, 0x42842020, 0xd02f2608, 0x33061b40, 0x33263316, + 0x33463336, 0x33663356, 0x33863376, 0x33a63396, 0x33c633b6, 0xd5b45d0d, 0x0233e533, 0x2079835d, 0x316d8436, 0xb000dc3d, 0x2ab02f15, 0x2a2fb22f, + 0x39121115, 0x068436b2, 0x31302708, 0x27032e05, 0x17161637, 0x35032e11, 0x37023e34, 0x1e153335, 0x26071703, 0x16112726, 0x0e141516, 0x23150702, + 0x0d823401, 0x01363623, 0x08268214, 0x01030e94, 0x6489548d, 0x17810c40, 0x83547481, 0x5a312f5c, 0x4b8a5483, 0x06385c7f, 0x60680d8f, 0x5e31b6b6, + 0x018a5687, 0x746a6d61, 0x73ccfd61, 0x33523762, 0x3f0a1019, 0x21447a5f, 0x02159565, 0x54411f0f, 0x7040496d, 0xa40a395b, 0x62440aa4, 0x58193d77, + 0x29fe1492, 0x4493af43, 0x08415f78, 0x560202aa, 0x22fe2f79, 0xed027d11, 0x0127674d, 0x392b08aa, 0x05000042, 0xe5ffecff, 0x3705c103, 0x17001300, + 0x37002b00, 0x45014300, 0x0a0a32b3, 0x00b32b04, 0x05822c09, 0x09187908, 0x402b0438, 0x1600061b, 0x36002600, 0x56004600, 0x76006600, 0x96008600, + 0xb600a600, 0x0d00c600, 0x00d5b45d, 0x5d0200e5, 0x002c22b2, 0xb0391211, 0xdab42f22, 0x0222ea22, 0x091b405d, 0x29221922, 0x49223922, 0x69225922, + 0x89227922, 0xa9229922, 0xc922b922, 0x405d0d22, 0x7632660f, 0x96328632, 0xb632a632, 0x0732c632, 0x060d405d, 0x26321632, 0x46323632, 0x06325632, + 0x32295782, 0x5d0232e5, 0xea38dab4, 0x084d8438, 0x38193835, 0x38393829, 0x38593849, 0x38793869, 0x38993889, 0x38b938a9, 0x5d0d38c9, 0xf4093eb1, + 0xb01018b0, 0xb000dc45, 0x17b02f0f, 0x4500b02f, 0x2f15b058, 0x4215b11b, 0x1d2007e3, 0x1d200c82, 0xb3230c82, 0x823b0227, 0x013530d8, 0xb02b0405, + 0x2fb1100f, 0xd9b4f401, 0x832fe92f, 0x085e0862, 0x282f182f, 0x482f382f, 0x682f582f, 0x882f782f, 0xa82f982f, 0xc82fb82f, 0xb05d0d2f, 0x41b1101d, + 0x1b40f401, 0x41174107, 0x41374127, 0x41574147, 0x41774167, 0x41974187, 0x41b741a7, 0x5d0d41c7, 0xe641d6b4, 0x305d0241, 0x0e140131, 0x2e222302, + 0x3e343502, 0x1e323302, 0x27012502, 0x138e1301, 0x2634012b, 0x15062223, 0x32331614, 0x3b0b8c36, 0x5c4527e1, 0x445c3334, 0x5c442626, 0x455c3433, + 0xfcc30127, 0x46035ebc, 0x5e442979, 0x43230f82, 0x83432929, 0x29462e1f, 0x4056bafd, 0x3f56563f, 0xdf015640, 0x82058258, 0x0458220d, 0x21398231, + 0x39822929, 0x835f3321, 0x5f240829, 0x3cedfa94, 0xaefb1605, 0x27465a35, 0x355c4427, 0x27435c34, 0x035c4327, 0x58584018, 0x58583f40, 0x5640f3fc, + 0x3b083883, 0x03000058, 0xe5ffe7ff, 0x2f05bc03, 0x32002700, 0xe3004200, 0x0e0830b3, 0x1eb32b04, 0x2b043b08, 0x30061b40, 0x30263016, 0x30463036, + 0x30663056, 0x30863076, 0x30a63096, 0x30c630b6, 0x3808f982, 0x30e530d5, 0x16b25d02, 0x1211300e, 0x2f16b039, 0xf40833b1, 0xea3bdab4, 0x405d023b, + 0x193b091b, 0x393b293b, 0x593b493b, 0x793b693b, 0x993b893b, 0xb93ba93b, 0x0d3bc93b, 0x05a9445d, 0x1b2f1924, 0x464519b1, 0x82052007, 0x4105200c, + 0x092007b8, 0x09200c82, 0xb13f0c82, 0x40f40728, 0x1728071b, 0x37282728, 0x57284728, 0x77286728, 0x97288728, 0xb728a728, 0x8228c728, 0x28d63183, + 0x5d0228e6, 0xb11019b0, 0xb4f4043e, 0x3ee93ed9, 0x26087c83, 0x3e183e08, 0x3e383e28, 0x3e583e48, 0x3e783e68, 0x3e983e88, 0x3eb83ea8, 0x5d0d3ec8, + 0x06013130, 0x07170706, 0x41060627, 0x373407ae, 0x34352626, 0x1e323336, 0x0e141502, 0x36010702, 0x32013736, 0x22820382, 0x14159d08, 0x16140316, + 0x35033e17, 0x22232634, 0xbc03020e, 0x9d3b5012, 0xb44a9d5e, 0x64874c69, 0x402f1b3c, 0xb3443e25, 0x58774495, 0x775e3e31, 0x30680139, 0x21fe103d, + 0xfe35874e, 0x3f341ea8, 0x3923567d, 0x2f4d6533, 0x452b4e68, 0x35021832, 0x934eae56, 0x54429a6b, 0x4c816038, 0x4354693f, 0x4e994e1d, 0x4c29b69a, + 0x6e4e466c, 0xfe254454, 0x469142ae, 0x313b17fe, 0x2d1d5001, 0x81605675, 0x772f7203, 0x413a1e4b, 0x5a4e3550, 0x004e3b23, 0x03750101, 0x052f0244, + 0x00030019, 0x01b00013, 0x2705f442, 0xb11b2f00, 0x593e1500, 0x4908d982, 0x02032303, 0x29662b2f, 0x2bfe1905, 0x0100d501, 0x8dfebc00, 0xdf05c102, + 0x3e001500, 0x050d10b3, 0x1b402b04, 0x10161006, 0x10361026, 0x10561046, 0x10761066, 0x10961086, 0x10b610a6, 0x5d0d10c6, 0xe510d5b4, 0x005d0210, + 0x5a8a0ab0, 0x5a841120, 0x022e3c08, 0x12343502, 0x17373636, 0x1415030e, 0x0217021e, 0x70a66b79, 0xa6703c3c, 0x955f486b, 0x67353567, 0x8dfe6193, + 0x01f2d554, 0x01878708, 0x54d5f107, 0xdbc04c5a, 0xed7b79ee, 0x824cc3d9, 0x82e52089, 0x86ec2089, 0x00280889, 0x2b040b0d, 0xea0bdab4, 0x405d020b, + 0x190b091b, 0x390b290b, 0x590b490b, 0x790b690b, 0x990b890b, 0xb90ba90b, 0x0d0bc90b, 0x11208982, 0x05208985, 0x0520e482, 0x14358985, 0x07060602, + 0x35033e27, 0x27022e34, 0x12021e37, 0x733cec02, 0x308583a5, 0x69353569, 0x6b485f95, 0x023c73a5, 0xfafe8735, 0x2f8483f2, 0x79eddbc1, 0xc0dbf079, + 0xd5545a4c, 0x00f7fef1, 0x232a8b82, 0x81030100, 0x1100a503, 0x8b424700, 0x820e2005, 0x470e205d, 0x6a840728, 0x593e0f2b, 0x0e0501b2, 0xb2391211, + 0x20068504, 0x20068507, 0x2006850a, 0x2006850d, 0x08068410, 0x01313029, 0x25070505, 0x05132313, 0x37252527, 0x03330305, 0xfe810325, 0x375601aa, + 0x740eb4fe, 0x37b4fe0e, 0xaafe5601, 0x824c0137, 0x4c01360c, 0xbdb88c02, 0x7dfecb5e, 0x5ecb8301, 0xcd60b8bd, 0x7afe8601, 0x3f9783cd, 0x030d0000, + 0x00b003a4, 0xb337000b, 0x04030d02, 0x1003b02b, 0xb0d007b0, 0x09b01002, 0x02b000d0, 0x20050a41, 0x20ac8208, 0x22ac8208, 0x47060bb3, 0x04270614, + 0x100bb0d0, 0x82d006b0, 0x21210887, 0x21112311, 0x33112135, 0xa4032111, 0xfe7468fe, 0x74980168, 0xa4019801, 0x970169fe, 0xfe970175, 0x26ff8269, + 0x028bfef0, 0x42ba0062, 0x00200545, 0x01205585, 0x01345582, 0x30593e11, 0x23012531, 0xfe620213, 0xbaba60ee, 0x2f02d1fd, 0x00262f82, 0xa403a401, + 0x2f821902, 0xb3000923, 0x83758303, 0x82352069, 0x5cfc2e61, 0xa401a403, 0x01010075, 0x02000075, 0x8653872f, 0x490020a9, 0x302a061c, 0x35232131, + 0xba2f0233, 0x4d82baba, 0x10ff2926, 0x4a058903, 0xb0254d84, 0x03b02f01, 0x084d822f, 0x01270136, 0x02fd8903, 0x05fe0262, 0x34f9f917, 0x00000606, + 0xffdfff03, 0x05c703e9, 0x0008002f, 0x00250011, 0x2f26b0f8, 0xb02f27b0, 0x12b01026, 0x2f12b0d0, 0xf40c00b1, 0x0824a846, 0x1027b037, 0xb2dc1cb0, + 0x111c1202, 0x0eb13912, 0xdab4f408, 0x020eea0e, 0x091b405d, 0x290e190e, 0x490e390e, 0x690e590e, 0x890e790e, 0xa90e990e, 0xc90eb90e, 0xb25d0d0e, + 0x422f8411, 0x17200520, 0x1720c982, 0x2007ac44, 0x270c8221, 0x593e0f21, 0x172102b2, 0xb02b5182, 0x06b11017, 0xd9b4f406, 0x8306e906, 0x08210854, + 0x28061806, 0x48063806, 0x68065806, 0x88067806, 0xa8069806, 0xc806b806, 0xb05d0d06, 0x0bb11021, 0x08b68206, 0x170b0721, 0x370b270b, 0x570b470b, + 0x770b670b, 0x970b870b, 0xb70ba70b, 0x0d0bc70b, 0x0bd6b45d, 0x82020be6, 0x345e8480, 0x14133130, 0x26260117, 0x13022223, 0x12323316, 0x27263411, + 0x06644601, 0x60461520, 0x68460806, 0x30630223, 0xbbb05e8d, 0xacb66352, 0xfc1012be, 0xbf7638c4, 0x78bf8787, 0xbf763636, 0x77bf8989, 0x918b0235, + 0x5a85027f, 0xfdd5fe60, 0x2b01b07d, 0x81480401, 0x83fcfe3b, 0x7171bcf4, 0x8383f4bc, 0x7171baf4, 0x8342f4ba, 0x02002b05, 0x001905e9, 0xb33a0012, + 0x83420811, 0x4a0f2006, 0x0f20065d, 0x0f20f982, 0x3d10fa4a, 0xb2f40602, 0x110f0004, 0x11b03912, 0xd012b0d0, 0x21213130, 0x0e113335, 0x32352303, + 0x0982023e, 0x02334408, 0xd3d1fde9, 0x7f6a4e12, 0x768c3d44, 0x75d28a4e, 0x5d297b03, 0x4c8e344d, 0xfb4a9676, 0x0001005c, 0x0300000a, 0x002f0577, + 0xb0720020, 0x18b32f05, 0x2b04190b, 0x120809b3, 0x09b02b04, 0xd000b010, 0x822f00b0, 0x07b12308, 0x0682f40d, 0xdc22b022, 0x20059541, 0x208e821c, + 0x208e871c, 0x080c820a, 0x3e0f0a32, 0x0606b159, 0x101cb0f4, 0xf40615b1, 0xe915d9b4, 0x405d0215, 0x1815081b, 0x38152815, 0x58154815, 0x78156815, + 0x98158815, 0xb815a815, 0x0d15c815, 0x2806ba47, 0x11210107, 0x35211133, 0x06ea4501, 0x23150622, 0x08051246, 0x1373033c, 0xfe3d5031, 0x75270239, + 0xfc01b0fc, 0x20384727, 0xa8a4759f, 0x54dfec7f, 0x03427395, 0x585636c7, 0x33fe3f62, 0x8bfe0001, 0x27040279, 0x2f56504e, 0xacb67b78, 0x5c31fadd, + 0xd9820085, 0xe9ff1b24, 0xd9829803, 0xd4003626, 0x250b24b3, 0x2f22d682, 0xd6821e0c, 0xb1102f37, 0xb1f40913, 0xb0f40800, 0x0bb01024, 0x2f0bb0d0, + 0xea1edab4, 0x08ae831e, 0x191e0927, 0x391e291e, 0x591e491e, 0x791e691e, 0x991e891e, 0xb91ea91e, 0x0d1ec91e, 0x2532b25d, 0x39121100, 0xb0102fb0, + 0x06064138, 0xf9822a20, 0x49472a20, 0x19b3230f, 0x66821806, 0x10053608, 0xf4060eb1, 0x0e071b40, 0x0e270e17, 0x0e470e37, 0x0e670e57, 0x0e870e77, + 0x0ea70e97, 0x0ec70eb7, 0xd6b45d0d, 0x020ee60e, 0x102ab05d, 0xf40621b1, 0xe921d9b4, 0x39858321, 0x21182108, 0x21382128, 0x21582148, 0x21782168, + 0x21982188, 0x21b821a8, 0x858321c8, 0x82191821, 0x09f64885, 0x1637272b, 0x3e323316, 0x2e343502, 0x05f64102, 0x2005eb48, 0x08a94223, 0x07066208, + 0x9803031e, 0x54997546, 0x4e7da35f, 0xba0c8508, 0x4e683b8a, 0x8d60332d, 0x647f445d, 0x9274923e, 0x764281b0, 0x915465a6, 0x7b853d6d, 0x25466846, + 0x8d566801, 0x64343864, 0x97126298, 0x60482798, 0x3965503b, 0x35177514, 0x856e4458, 0xa266a499, 0x5c313b6f, 0x936f5685, 0x5b3b0a13, 0x0200006e, + 0x39008200, 0x1905a403, 0x11000e00, 0x0db35100, 0x2b04030c, 0xb0100db0, 0x03b0d008, 0xc342b010, 0x2f072407, 0x4207b11b, 0xb3230fc3, 0x8204030f, + 0x1000392c, 0xf40602b1, 0xb0100fb0, 0x04b0d009, 0xd00bb010, 0xb01002b0, 0x0eb0d00d, 0x0807d442, 0x01352137, 0x15331133, 0x01331123, 0xa4030111, + 0xfdd3d1fd, 0xae2302b8, 0xfed3d3d3, 0x7549fea4, 0x03770001, 0x77d3fc2d, 0x770100ff, 0x75fd8b02, 0x00010000, 0x03e9ff04, 0x089582aa, 0xa6002a4b, + 0xb02f2bb0, 0x00b02f2c, 0x0c15b1dc, 0x15dab4f4, 0x5d0215ea, 0x15091b40, 0x15291519, 0x15491539, 0x15691559, 0x15891579, 0x15a91599, 0x15c915b9, + 0x2bb05d0d, 0xd01eb010, 0xb12f1eb0, 0xb0f40c1d, 0x23b2d022, 0x1211001e, 0x05ff4239, 0xca821f20, 0xf8411f20, 0x06262210, 0x05f8411a, 0x06103208, + 0x071b40f4, 0x27101710, 0x47103710, 0x67105710, 0x87107710, 0xa7109710, 0xc710b710, 0xb45d0d10, 0x10e610d6, 0x1fb05d02, 0x0621b110, 0x0523b2f4, + 0x0ed3411f, 0x41031e21, 0x920808d3, 0x23070622, 0x21152111, 0x33363611, 0x03021e32, 0xb07d48aa, 0x79a05e68, 0x0685084a, 0x44725434, 0x2f587d50, + 0x4c7d562f, 0x89369350, 0x58fd3103, 0x6550993c, 0x01447aa8, 0x7da860b6, 0x98683848, 0x75441562, 0x5f352f52, 0x7f4a477d, 0x4043355c, 0xfe758c02, + 0x413f3a68, 0x0000ac77, 0xfff8ff02, 0x05be03e9, 0x0022002f, 0xb3df0036, 0x040a0b19, 0x0c00b32b, 0x402b0423, 0x1619061b, 0x36192619, 0x56194619, + 0x76196619, 0x96198619, 0xb619a619, 0x8219c619, 0xd52f08c0, 0x0219e519, 0x23dab45d, 0x5d0223ea, 0x23091b40, 0x23292319, 0x23492339, 0x23692359, + 0x23892379, 0x23a92399, 0x23c923b9, 0x0ab05d0d, 0x4f2db110, 0xc84407c3, 0x2f052b0c, 0x0f05b11b, 0x1eb3593e, 0x224c2806, 0x06142705, 0x14d9b4f4, + 0x538314e9, 0x14084508, 0x14281418, 0x14481438, 0x14681458, 0x14881478, 0x14a81498, 0x14c814b8, 0x19b25d0d, 0x12110f05, 0x1005b039, 0xf40632b1, + 0x32071b40, 0x32273217, 0x32473237, 0x32673257, 0x32873277, 0x32a73297, 0x32c732b7, 0xd623ab82, 0x4c32e632, 0x17311129, 0x22232607, 0x3e15020e, + 0x1e323303, 0x2e340702, 0x080e8402, 0x021e148a, 0x023e3233, 0x7f47be03, 0xbc8b65ae, 0x8a453373, 0x81c28bcf, 0x698f5a5a, 0x0e356ba1, 0x3c77664e, + 0x457bac66, 0x7b542d89, 0x5a7f4c4d, 0x7d542831, 0x5a7b4a56, 0x6cbc0131, 0x714279ac, 0x8583f4ba, 0x876ebdf4, 0x8f506250, 0x5a3378c9, 0x7b452741, + 0x814a67ac, 0x5a32365e, 0x834a4b7b, 0x5a313a64, 0x00010084, 0x03000031, 0x00190598, 0xb04b0010, 0x12b02f11, 0xdc05b02f, 0xf40806b1, 0xb01011b0, + 0x0eb0d00e, 0x0d0db12f, 0x2406f650, 0xb11b2f0d, 0x0723490d, 0x08143f41, 0x100fb091, 0xf4060bb1, 0x06013130, 0x2307020a, 0x37021a36, 0x11231121, + 0x7b980321, 0x021c5094, 0x58230290, 0x92fd7498, 0x04670375, 0xfefe85a0, 0xc1fee7fe, 0x4201b6c1, 0x0a012501, 0x0100ff7d, 0xff030075, 0x03e9fff8, + 0x002f05ae, 0x00330027, 0xb3310147, 0x040a0c3e, 0x0c1eb32b, 0xb42b0428, 0x28ea28da, 0x1b405d02, 0x28192809, 0x28392829, 0x28592849, 0x28792869, + 0x28992889, 0x28b928a9, 0x5d0d28c9, 0x1e2834b2, 0xb0391211, 0xdab42f34, 0x8434ea34, 0x3422082e, 0x34293419, 0x34493439, 0x34693459, 0x34893479, + 0x34a93499, 0x34c934b9, 0x00b15d0d, 0x0fb2f40c, 0x3282000a, 0x1b402808, 0x3e163e06, 0x3e363e26, 0x3e563e46, 0x3e763e66, 0x3e963e86, 0x3eb63ea6, + 0x5d0d3ec6, 0xe53ed5b4, 0xb25d023e, 0x823e0a14, 0x14b0242b, 0x8423b22f, 0x2eb12235, 0x061e410c, 0x2914ce4c, 0x390631b3, 0x0fb22b04, 0x35823139, + 0x8423b221, 0x19b02b06, 0x062bb110, 0x2bd9b4f4, 0x9f822be9, 0x2b28173c, 0x2b482b38, 0x2b682b58, 0x2b882b78, 0x2ba82b98, 0x2bc82bb8, 0x08b45d0b, + 0x2082182b, 0x05b02208, 0x0643b110, 0x071b40f4, 0x27431743, 0x47433743, 0x67435743, 0x87437743, 0xa7439743, 0xc743b743, 0x239e8243, 0x43e643d6, + 0x200f5b42, 0x05895037, 0x2208d74c, 0x4503031e, 0x14250593, 0x36323316, 0x0f694213, 0x4aae3208, 0x6462ae81, 0x274a81ac, 0x373f6949, 0x46213b56, + 0x54549c76, 0x2146769c, 0x4038583b, 0xb8294a68, 0x9c87879c, 0x948f8f94, 0x785f372f, 0x5f784444, 0x38078737, 0x91676f01, 0x602e2e60, 0x6c356791, + 0x06083d5d, 0x2b5e503c, 0x2d588558, 0x0804822d, 0x505e2b44, 0x3d08063c, 0x29026c5d, 0x6e7f7f6e, 0xfe7a7a67, 0x3f654709, 0x653f1d1d, 0x44664647, + 0x66442121, 0xe9ff0200, 0xb003e9ff, 0x23002f05, 0xe5003700, 0x000824b3, 0x0ab32b04, 0x2b042e08, 0xb1100ab0, 0xfe820b1a, 0x24064708, 0x24262416, + 0x24462436, 0x24662456, 0x24862476, 0x24a62496, 0x24c624b6, 0xd5b45d0d, 0x0224e524, 0x2edab45d, 0x5d022eea, 0x2e091b40, 0x2e292e19, 0x2e492e39, + 0x2e692e59, 0x2e892e79, 0x2ea92e99, 0x2ec92eb9, 0x50825d0d, 0x4739b021, 0x05240638, 0x05b11b2f, 0x20073f45, 0x270c820f, 0x593e0f0f, 0x1f0629b3, + 0x21050544, 0x77820615, 0x17150739, 0x37152715, 0x57154715, 0x77156715, 0x97158715, 0xb715a715, 0x8215c715, 0x15d62977, 0x5d0215e6, 0x050f1ab2, + 0x27060544, 0xb4f40633, 0x33e933d9, 0x083e8583, 0x28331833, 0x48333833, 0x68335833, 0x88337833, 0xa8339833, 0xc833b833, 0x305d0d33, 0xc2490331, + 0x083e470c, 0x23030e26, 0x37022e22, 0x2006fe43, 0x06a44135, 0x48172008, 0x8965ae7f, 0x463373be, 0xc289d189, 0x772d5a81, 0x6d9f6945, 0x664c1035, + 0xac663a79, 0x448a467b, 0x29210706, 0x05064453, 0x5c032e08, 0x4179ac6d, 0x83f2bc71, 0x6fbcf485, 0x31325088, 0x79c98f50, 0x27425a33, 0x66ac7b46, + 0x355e814a, 0x4c7d5831, 0x3964834a, 0x00835a31, 0x05bd4b02, 0x00a4032b, 0x00070003, 0x0800b32f, 0x080e5401, 0xb0100123, 0x06fd4905, 0x1b2f0224, + 0x014402b1, 0x82042007, 0x0f04260c, 0x3130593e, 0x06fd5301, 0xba2f0222, 0x022e0082, 0x5cfcbbe9, 0x020000ba, 0x8bfef000, 0x53866202, 0x53852a20, + 0x4d0a4055, 0x11260c6d, 0x04b2593e, 0x7d460205, 0x234e8205, 0x13230113, 0x33244e83, 0xba60eefe, 0xfd215182, 0x06894c16, 0xdeffc72c, 0xde031403, + 0x09000500, 0x3b4cb000, 0x07252906, 0x01170101, 0xfe4d1403, 0x4d257482, 0x4f2d50fe, 0x22088202, 0x8250fe50, 0x00002605, 0x02a403c7, 0x2dd784f6, + 0x07b3000f, 0x2b040406, 0x000303b3, 0xc14c2b04, 0x21112105, 0x2107c54c, 0x28825cfc, 0xfd777f2d, 0x000075d1, 0xff8f0001, 0x8add02de, 0x4c052067, + 0x013606a3, 0xfedd0237, 0xb0014e00, 0x014e50fe, 0x4f00fede, 0xb001b101, 0x69820050, 0x0000a826, 0x2f058d03, 0x21266982, 0x0bb39000, 0x68820c08, + 0x13080426, 0x0cb02b04, 0x82064856, 0xb12d0808, 0xb4f40803, 0x13ea13da, 0x1b405d02, 0x13191309, 0x13391329, 0x13591349, 0x13791369, 0x13991389, + 0x13b913a9, 0x5d0d13c9, 0xb01004b0, 0x06a54223, 0x4d0ce547, 0xb02b0752, 0x16b1101f, 0xd9b4f406, 0x8316e916, 0x16083b4c, 0x16281618, 0x16481638, + 0x16681658, 0x16881678, 0x16a81698, 0x16c816b8, 0x7e4d5d0d, 0x14012805, 0x2315040e, 0x50043e34, 0x410806ca, 0x36362707, 0x02163233, 0x01baba2f, + 0x6656395e, 0x3b913a56, 0x3b566956, 0x5f3f676c, 0x7b062741, 0xa6b0c312, 0x4403baba, 0x5662754e, 0x4e456d5c, 0x5c5e6b7a, 0x64583963, 0x3a604529, + 0xaac2a813, 0x9f4d0200, 0x004f2808, 0xb3400160, 0x82440932, 0x0c5821f3, 0xb323f382, 0x820b0c1e, 0x0900220b, 0x32ff8226, 0x1bb0100b, 0x26a9b6d0, + 0x26c926b9, 0xdab45d03, 0x8226ea26, 0x490d3eb1, 0x69265926, 0x89267926, 0x06269926, 0x0909405d, 0x29261926, 0x04263926, 0x5611405d, 0x0d2b5432, + 0x405d0823, 0x092b540b, 0xb45d0529, 0x32e532d5, 0x82b05d02, 0xd050335a, 0x58061140, 0x58265816, 0x58465836, 0x58665856, 0x2e835876, 0x96588629, + 0xb658a658, 0x8358c658, 0xe558232e, 0x77520258, 0x2f4b2406, 0x434bb11b, 0x3d2007f4, 0x3d270c82, 0xb3593e0f, 0x820e035b, 0x011822b0, 0x2fb08253, + 0x05b0100e, 0x3d0bb2d0, 0x3912114b, 0x18531bb2, 0xb0340682, 0x21b0105b, 0x2f21b0d0, 0xb1104bb0, 0xb4f4022d, 0x2de92dd9, 0x4608c582, 0x182d081b, + 0x382d282d, 0x582d482d, 0x782d682d, 0x982d882d, 0xb82da82d, 0x0d2dc82d, 0x103db05d, 0xf40237b1, 0x37071b40, 0x37273717, 0x37473737, 0x37673757, + 0x37873777, 0x37a73797, 0x37c737b7, 0xd6b45d0d, 0x4537e637, 0x35200cba, 0x27099952, 0x17163233, 0x14113335, 0x20075a4b, 0x091b4804, 0x17373631, + 0x2e222306, 0x3e343504, 0x1e323304, 0x48262502, 0x2b860547, 0xc703af08, 0x435a3616, 0x192a361d, 0x423e5e16, 0x22163558, 0x23436544, 0x1883184e, + 0x18281c17, 0x3e27110b, 0x714a7559, 0x28285d98, 0x5270995d, 0x803b3582, 0x6f915cc4, 0x1817324f, 0x90704f32, 0x78bf875b, 0x1781fe36, 0x3726263f, + 0x34391124, 0x162a3c25, 0x8c44ac02, 0x26144871, 0x4b1c2033, 0x7a603a5e, 0x67874a40, 0x3525233d, 0x1c20f3fd, 0x2f645336, 0x697b8945, 0xa2602b4d, + 0xd37375d4, 0x313a60a2, 0x5c338144, 0x57a8967e, 0x7e96a959, 0xb66f335b, 0x273104e6, 0x315f4b2d, 0x492d6e6d, 0x02002d5b, 0x0000c5ff, 0x1905e303, + 0x0a000700, 0x19443000, 0x2f062405, 0x4b06b11b, 0xb0240f9b, 0xb0584500, 0x08076e44, 0x0308b32c, 0x302b0402, 0x03232131, 0x01230321, 0x03031333, + 0x7b93e303, 0x9379fcfd, 0x7dbab201, 0x7501dbdb, 0x19058bfe, 0xa102d5fc, 0x60825ffd, 0x82310021, 0x82a22004, 0x0e4f0865, 0x24001b00, 0x21b38700, + 0x2b04040c, 0x0f0c0bb3, 0x0bb02b04, 0x0a1cb110, 0x0c00b1f4, 0x040db2f4, 0x39121100, 0xea0fdab4, 0x405d020f, 0x190f091b, 0x390f290f, 0x590f490f, + 0x790f690f, 0x990f890f, 0xb90fa90f, 0x0d0fc90f, 0x1021b05d, 0x82d015b0, 0x26b0213c, 0x20134746, 0x2dc38203, 0x593e0f03, 0x1f0117b3, 0x0db22b04, + 0x1b46171f, 0x06143d06, 0x1003b0f4, 0xf40621b1, 0x14013130, 0x11212306, 0x021e3221, 0x16071415, 0x022e3403, 0x3e240e84, 0x26341302, 0x51080984, + 0xf2a20336, 0x0160fedf, 0x7d9e5289, 0xb6f8cb4e, 0x326c5a3a, 0x000100ff, 0x38566c38, 0xfe99af2d, 0x991701e9, 0xbb7501af, 0x1b1905ba, 0xcb6a834a, + 0x61014c4a, 0x112f5845, 0x311145fe, 0x87f4fd56, 0x81fefd7b, 0xecff0100, 0xac03e9ff, 0x25002f05, 0x3d51e300, 0xdc122106, 0x30064e4f, 0x08b01026, + 0x2f08b0d0, 0xb11012b0, 0xb0f40d11, 0x080c8214, 0x1eb11032, 0x1b40f40c, 0x1e161e06, 0x1e361e26, 0x1e561e46, 0x1e761e66, 0x1e961e86, 0x1eb61ea6, + 0x5d0d1ec6, 0xe51ed5b4, 0xb05d021e, 0x25b01011, 0x2f25b0d0, 0x2005b841, 0x20f48211, 0x07b84111, 0x0c820d20, 0x0c870d20, 0x08070e41, 0x0310b23b, + 0x3912110d, 0xb1100db0, 0xb4f40619, 0x19e919d9, 0x08b65d02, 0x28191819, 0x405d0319, 0x48193815, 0x68195819, 0x88197819, 0xa8199819, 0xc819b819, + 0xb05d0a19, 0x23b11003, 0x39928206, 0x23172307, 0x23372327, 0x23572347, 0x23772367, 0x23972387, 0x23b723a7, 0x928223c7, 0xe623d628, 0x305d0223, + 0x39430131, 0x48232010, 0x52080ce5, 0x33ac0313, 0xbe89b0e8, 0x79353579, 0xac7989be, 0x35757529, 0x6a447b5a, 0x2323548b, 0xf46a8b54, 0xa8560160, + 0xf4ba71c5, 0xbcf48383, 0x98585671, 0x7b4554fe, 0xa264335a, 0xc76263c6, 0x2701659f, 0x00020000, 0x03000031, 0x001905cf, 0x0015000c, 0x5816b070, + 0x3a08057a, 0x1016b0dc, 0xb0d006b0, 0x00b02f06, 0x0c0db110, 0x0ddab4f4, 0x5d020dea, 0x0d091b40, 0x0d290d19, 0x0d490d39, 0x0d690d59, 0x0d890d79, + 0x0da90d99, 0x0dc90db9, 0x06b05d0d, 0x4a12b110, 0x964e073f, 0x080e570c, 0xb1100727, 0xb0f40610, 0x42288205, 0x0e200536, 0x23052842, 0x1007021e, + 0x2c080985, 0x37cf0312, 0xfe87bf79, 0x85a80158, 0x893979bf, 0xe1feacc1, 0xc1ac1f01, 0xed838b02, 0x190568b3, 0x83ecb46b, 0x19010001, 0x1601d1fb, + 0x06f14b00, 0xbf827320, 0x3d000b2a, 0x010c0ab3, 0x0ab02b04, 0x430ee147, 0xb3230f7f, 0x82080607, 0x10022326, 0x8a8204b1, 0xb1100023, 0x07e35c0a, + 0x11211523, 0x5c038321, 0x022c08e7, 0xb902fefd, 0xfe751905, 0x19fe752d, 0x09266d8b, 0x06b33600, 0x4682070c, 0xb0100623, 0x064f4801, 0x1b2f0824, + 0x6d8708b1, 0x915c0620, 0x06032207, 0x23268204, 0x00b11008, 0x6285f184, 0x21112327, 0x47fd7303, 0x24608202, 0x04420389, 0x216082a4, 0xc582a4fd, + 0x3005e142, 0x002f05d7, 0xb3d3002b, 0x040a0c20, 0x0d14b32b, 0x08408213, 0xb0101335, 0x1b40d016, 0x20162006, 0x20362026, 0x20562046, 0x20762066, + 0x20962086, 0x20b620a6, 0x5d0d20c6, 0xe520d5b4, 0xb05d0220, 0x2bb11013, 0x14b0f408, 0x432db010, 0x132006d0, 0x13208c82, 0x4f0c184a, 0x2b261065, + 0x2b042806, 0xff4d12b2, 0x0f4d0805, 0x061bb110, 0x1bd9b4f4, 0x5d021be9, 0x1b081b40, 0x1b281b18, 0x1b481b38, 0x1b681b58, 0x1b881b78, 0x1ba81b98, + 0x1bc81bb8, 0x05b05d0d, 0x0625b110, 0x071b40f4, 0x27251725, 0x47253725, 0x67255725, 0x87257725, 0xa7259725, 0xc725b725, 0x23998225, 0x25e625d6, + 0x220c1446, 0x46023e34, 0xd242060c, 0x37362a0d, 0x03213521, 0xbf7937d7, 0x18d74287, 0x11b69e2c, 0xb201dffe, 0xf2858902, 0xde426fba, 0x7b47220c, + 0x08de4258, 0x75ddf422, 0x350d1f42, 0x2f0cb060, 0xb02f0db0, 0x01b1dc00, 0x0cb0f408, 0xd005b010, 0x0f5f05b0, 0xd0072605, 0xb01001b0, 0x06c84109, + 0x240cb645, 0xb11b2f0a, 0x0f43420a, 0x210dc345, 0xc3450609, 0x21112506, 0x33112311, 0x333c0582, 0xfd8a7303, 0x028989d1, 0x5c028a2f, 0x1905a4fd, + 0x4802b8fd, 0xba000100, 0xe9020000, 0x2307ad42, 0x2b040308, 0x8c056e44, 0x07124970, 0x0602b125, 0x4206b0f4, 0x082105a5, 0x299c82d0, 0xb01002b0, + 0x0bb0d00a, 0x905430d0, 0x35232305, 0x6e821521, 0xfde90238, 0x02d3d3d1, 0x75d2d22f, 0x75752f04, 0x0100d1fb, 0xe9fffeff, 0x67827303, 0x4c001126, + 0x0f0800b3, 0x10206787, 0x1020cb82, 0x080fc944, 0x060ab126, 0x071b40f4, 0x270a170a, 0x470a370a, 0x670a570a, 0x870a770a, 0xa70a970a, 0xc70ab70a, + 0xb45d0d0a, 0x0ae60ad6, 0x2305be41, 0x26222302, 0x2008dc4b, 0x3de68211, 0xecaed9d3, 0xaa2b772f, 0x3d735c7d, 0xf2018a16, 0xb7effef8, 0x83a22db6, + 0x488f734a, 0x81412703, 0x849e2007, 0xb34a2bf3, 0x04050c04, 0x1004b02b, 0x6a4107b0, 0x82092013, 0x4109209e, 0xb22d1c6a, 0x11060008, 0x31303912, + 0x07012321, 0x3dfc8211, 0x01330111, 0xfea89e03, 0x89898a4e, 0xfeb52f02, 0x9a7f0200, 0x19051bfe, 0x7b0285fd, 0x1f44c6fd, 0x0005220a, 0x207d8227, + 0x07094101, 0x8218f460, 0x11212f5a, 0x03211133, 0x89befc73, 0x1905b902, 0x458a5cfb, 0x6d000c27, 0xb02f0db0, 0x0845420e, 0xe1600d20, 0xf40c2508, + 0x00070ab2, 0x4408cb52, 0x0b200c0c, 0x0b20d882, 0x0620d894, 0x23062644, 0x080002b2, 0xb2213b82, 0x20068505, 0x8206840a, 0x1123248b, 0x83032303, + 0x131335e8, 0x8a730333, 0x89e662e7, 0xb2f0eeb2, 0x5ffd3f04, 0xc1fba102, 0x5622e882, 0x9944aa02, 0xb062250d, 0x0bb02f0a, 0xb02aa183, 0x04b0100a, + 0x2f04b0d0, 0xf36103b1, 0x52072005, 0x294e072f, 0x4baa8c0c, 0x00230890, 0x46b05845, 0x022208ec, 0x9d830500, 0x06840720, 0x01209683, 0x01219383, + 0x31938211, 0x89f1fdaa, 0x8af701c1, 0xb0fb5004, 0xe3fb1905, 0x494b1d04, 0x0013290a, 0xb0e20027, 0x29b02f28, 0x28248f84, 0xd00ab010, 0x2a089e83, + 0x14b11000, 0xdab4f408, 0x0214ea14, 0x091b405d, 0x29141914, 0x49143914, 0x69145914, 0x89147914, 0xa9149914, 0xc914b914, 0x825d0d14, 0x1eb125c4, + 0x1740f40c, 0x2715c547, 0xb6b45d0b, 0x021ec61e, 0x4307c847, 0x0f200550, 0x460bd857, 0x0f20087d, 0x210bab47, 0xac471b40, 0x13a84705, 0x05207582, + 0x5f2ca847, 0xf6520e18, 0x36c72110, 0x3b06b758, 0x87bf7935, 0x3876bf87, 0x875c318a, 0x548b6b56, 0x8b542121, 0x548c6a6b, 0x838b0220, 0x2105b458, + 0xc4588383, 0xcf812306, 0xab474d92, 0x9f652207, 0x06ab47c7, 0x1905a233, 0x13000a00, 0x14b07200, 0x2f15b02f, 0xb0dc00b0, 0x06ab4714, 0x4105b121, + 0x0b2205e5, 0x8c5cf40c, 0x05b02124, 0x54164556, 0x11290840, 0x2b040306, 0xb11007b0, 0x09e4490e, 0x21112325, 0x49071632, 0x360809d6, 0xd9fed5ec, + 0xd7ae0189, 0x8eaa89ec, 0x2701d9fe, 0xa403aa8e, 0xd1fdb8bd, 0xbabb1905, 0x00fe7987, 0x02000079, 0x8dfedfff, 0x2f05c703, 0x30002000, 0x31b01c01, + 0x8332b02f, 0x21b122b9, 0x08a98208, 0x21ea2123, 0x1b405d02, 0x21192109, 0x21392129, 0x21592149, 0x21792169, 0x21992189, 0x21b921a9, 0x5d0d21c9, + 0x05d949b0, 0xaf832120, 0x0fb03208, 0x1031b02f, 0xb0d017b0, 0x2bb12f17, 0x1b40f40c, 0x2b162b06, 0x2b362b26, 0x2b562b46, 0x2b762b66, 0x2b962b86, + 0x2bb62ba6, 0x5d0d2bc6, 0xe52bd5b4, 0x072a4d2b, 0x250c5f59, 0xb11b2f0c, 0x5964110c, 0x820f2006, 0x870f200c, 0x8212200c, 0x5f12200c, 0x3c4207bc, + 0x0608210b, 0x07396d82, 0x27081708, 0x47083708, 0x67085708, 0x87087708, 0xa7089708, 0xc708b708, 0x376d8208, 0x08e608d6, 0x0bb05d02, 0x2f0bb0d0, + 0xb1101cb0, 0xb4f40626, 0x26e926d9, 0x0839e083, 0x28261826, 0x48263826, 0x68265826, 0x88267826, 0xa8269826, 0xc826b826, 0x25e08226, 0x2eb11012, + 0x7f58f401, 0x16072d05, 0x36323316, 0x06061537, 0x27262223, 0x4209f552, 0x103a0855, 0x12323312, 0x692fc703, 0x8b1777a8, 0x17312387, 0xcc19351d, + 0xa26e17cf, 0x5f423167, 0x22200808, 0x6b688e52, 0xbd21548b, 0x02beacae, 0xb6e77d8b, 0x66860c77, 0x02750202, 0x0eb5ae02, 0x81e7b273, 0x2d076642, + 0x64a2c663, 0x63c6a264, 0xd7fefcfe, 0x65422901, 0x05b03006, 0x000f0019, 0xb08e0018, 0x1ab02f19, 0x4b0ab02f, 0x19200765, 0x2a0b3547, 0x10b1100a, + 0xdab4f408, 0x8310ea10, 0x100939e0, 0x10291019, 0x10491039, 0x10691059, 0x10891079, 0x10a91099, 0x10c910b9, 0x20050050, 0x13f34514, 0x4d0c6f44, + 0x163f0815, 0x2b040f01, 0xb0100fb0, 0x02b0d002, 0x1006b02f, 0xf40613b1, 0x23213130, 0x23112301, 0x64322111, 0x5c4c0581, 0xaeb03809, 0x89cb83fe, + 0xecd7ae01, 0x528b643a, 0xfe90a5ed, 0x902501db, 0x422f02a5, 0x23080587, 0x385c8352, 0x856f0106, 0x7900fe7b, 0x19000100, 0x8303e9ff, 0x3f002f05, + 0x0cb3dc00, 0x2b04200a, 0x290b2ab3, 0x293d6f82, 0x0800b110, 0x100cb0f4, 0xb0d008b0, 0x2cb01029, 0x1020b0d0, 0xf40c36b1, 0xb0102ab0, 0x064b4941, + 0x1b2f2924, 0xcb4529b1, 0x822b2007, 0x132b210c, 0x20064442, 0x200c8225, 0x20198725, 0x06f46109, 0x4500b024, 0x5043b058, 0x043b2808, 0xb22b041b, + 0x4d250508, 0x29080643, 0x40f40611, 0x1711071b, 0x37112711, 0x57114711, 0x77116711, 0x97118711, 0xb711a711, 0x0d11c711, 0x11d6b45d, 0x5d0211e6, + 0x328528b2, 0x10252908, 0xf40631b1, 0xe931d9b4, 0x405d0231, 0x1831081b, 0x38312831, 0x58314831, 0x78316831, 0x98318831, 0xb831a831, 0x0d31c831, + 0x2508c263, 0x23152726, 0x80533311, 0x0851420a, 0x35171624, 0x7e491133, 0x1771080b, 0x8303031e, 0x50947244, 0x7436b86e, 0x7d603e74, 0x4a623a41, + 0x745d372b, 0x708e473c, 0x926e4446, 0x2da15f4d, 0x54317979, 0x60353c6c, 0x56332b48, 0x924a3b71, 0x54014a74, 0x34608552, 0x018b5052, 0x506f438d, + 0x583d212d, 0x405a3f38, 0x3719162d, 0x505a7954, 0x4e2d567d, 0x8bfe8850, 0x2b49673b, 0x3a543518, 0x2d374833, 0x5a401a17, 0x01000083, 0x07e15a00, + 0x6b000f35, 0xb02f10b0, 0x0db0d00d, 0xdc09b02f, 0x010940b2, 0x8201b05d, 0x01013207, 0x0d00b15d, 0x1009b0f4, 0xf40804b1, 0xb1100db0, 0x230d820c, + 0x11b01000, 0x24068e41, 0xb11b2f0e, 0x0f744b0e, 0x5a0eb021, 0x3d4905f8, 0x23012716, 0x33112111, 0xfe822115, 0x3a05d057, 0xe8fe75a4, 0xd3d1fdd2, + 0x0375e8fe, 0x016003a4, 0x75d1fb44, 0xfe2f0475, 0x83b901bc, 0x493120a5, 0x192d064d, 0x1ab07000, 0x2f1bb02f, 0xb0dc00b0, 0x06cb461a, 0x450db121, + 0x17200575, 0x47075b47, 0x18200cec, 0x18209e82, 0x080f6c4b, 0x0612b126, 0x071b40f4, 0x27121712, 0x47123712, 0x67125712, 0x87127712, 0xa7129712, + 0xc712b712, 0xb45d0d12, 0x12e612d6, 0x220c304b, 0x41113311, 0x300807c3, 0x73033311, 0x6c9e6731, 0x31659d6d, 0x6d3d1589, 0x3d6f5858, 0xd1018a14, + 0x467fb46f, 0x6fb67f46, 0xb8fc4603, 0x486c843b, 0x3b846c48, 0x01004803, 0x079950ff, 0x31000622, 0x20051e47, 0x20958200, 0x0c074a00, 0x01200c87, + 0x29081982, 0x593e0f01, 0x000105b2, 0x30391211, 0x23010131, 0x01013301, 0x4cfee303, 0x9150feba, 0x7b017d01, 0xe7fa1905, 0x72fb1905, 0x5b828e04, + 0x5000c121, 0x0c2205f5, 0x5b925900, 0x200cd84a, 0x205b8209, 0x072c4309, 0x494b6887, 0x03b2210c, 0xb2217584, 0x20068508, 0x8206840b, 0x23032283, + 0x22028203, 0x82131333, 0xe3032d02, 0x8785a2eb, 0xb891e9a0, 0xb8848783, 0x02238b83, 0x8283fd7d, 0x02ce268f, 0x0443fdbd, 0x20938232, 0x269382e9, + 0x001905ba, 0x637a001b, 0xe2870a0f, 0x86821520, 0x8c491520, 0x82072014, 0x82072019, 0x02b13efc, 0x03b0f406, 0x0004b2d0, 0x3912110e, 0xb0d005b0, + 0x09b0d006, 0xd00ab0d0, 0xb1100eb0, 0x261c820c, 0x11b0d010, 0x8512b2d0, 0xd013291f, 0xb0d014b0, 0x18b0d017, 0x10252282, 0xb0d01ab0, 0x06a24b1b, + 0x3303032f, 0x33352115, 0x35230101, 0x13231521, 0x08068413, 0x33010138, 0x8efeba03, 0x58cfcd58, 0x017f8dfe, 0x6deafe1b, 0xcb6d7501, 0x750169c5, + 0x01f0fe71, 0x01757f18, 0x7554feac, 0x021c0275, 0xfe757513, 0x75a2015e, 0xfdedfd75, 0xd98200e4, 0xd982ec20, 0xd982b820, 0x6700142c, 0x080803b3, + 0x10b22b04, 0x734a0308, 0x820c2008, 0x870c20bf, 0x0cf34dd9, 0x2308c546, 0x00b11013, 0x0523bf82, 0x8203b110, 0xd0072706, 0xb0d008b0, 0xd9831000, + 0xdc820b20, 0x0fb0d027, 0x0510b2d0, 0x8251820c, 0x12b021df, 0x0122c682, 0x2a430123, 0x3fc48a06, 0xfe6ab803, 0xd1fdd2c9, 0x6ac9fed3, 0xe36c7001, + 0x70016ce1, 0x8ffda404, 0x757542fe, 0x7102be01, 0x1423b682, 0x8275ec01, 0x310021b1, 0x7720b182, 0x0d2db182, 0x0eb05500, 0x2f0fb02f, 0xb0dc00b0, + 0x06b1480e, 0xd001b026, 0x000603b2, 0x06256e83, 0x0d05b110, 0x218b82f4, 0xa15b0bb1, 0x0c425007, 0x20082746, 0x20ba8507, 0x08b74f00, 0x21013527, + 0x21112311, 0x3c068215, 0xfc770333, 0xfd9002ba, 0x310375e5, 0x290277fd, 0x2f047575, 0xb501c0fe, 0x01d1fb75, 0x3a8d8245, 0x8bfe7501, 0xd305e902, + 0x2d000700, 0x010906b3, 0x01b02b04, 0x0e00b110, 0x4603b0f4, 0x6684069b, 0x593e1125, 0x5f0103b3, 0x06240640, 0x3130f401, 0x213d5b82, 0x21112115, + 0x8cfee902, 0xfafe7401, 0x8bfe0601, 0xf96f4807, 0x00010098, 0x0310ff85, 0x0eff63e5, 0x0107052e, 0x62e50337, 0xbc6202fd, 0x33070634, 0xba202582, + 0x2f207982, 0x30237984, 0x580e00b3, 0xb123058f, 0x82f40903, 0x08905880, 0x07207c88, 0x02207c87, 0x35207c85, 0x35297a82, 0xfe2f0221, 0xfe07018b, + 0x23c583f9, 0x6f680671, 0x02315582, 0xa6032f02, 0x06001905, 0xb0001d00, 0x03b02f00, 0x096f462f, 0x593e1523, 0x05b74bb2, 0x2339bf82, 0x01230101, + 0x98a60333, 0xc7fec5fe, 0xb8750198, 0x65022f02, 0xea029bfd, 0x26458200, 0x0346ff00, 0x65bbffa4, 0x05200c0f, 0x21084958, 0x238375ba, 0xf403e526, + 0x5405bc02, 0x2f0de564, 0x02372507, 0x52fe29bc, 0x41350442, 0x02006df3, 0x3305774e, 0x2600ba03, 0xed003700, 0xb02f38b0, 0x38b02f39, 0xd000b010, + 0x39379c83, 0xdc1cb010, 0xf4080bb1, 0xb2d01eb0, 0x111c001f, 0x0bb03912, 0x822cb010, 0x1028081c, 0xf40c35b1, 0x35061b40, 0x35263516, 0x35463536, + 0x35663556, 0x35863576, 0x35a63596, 0x35c635b6, 0xd5b45d0d, 0x0235e535, 0x2506f456, 0xb11b2f17, 0x77471317, 0x821d2006, 0x491d200c, 0x242007af, + 0x24200c82, 0x35080c82, 0x300605b3, 0x17b02b04, 0x0610b110, 0x10d9b4f4, 0x5d0210e9, 0x10081b40, 0x10281018, 0x10481038, 0x10681058, 0x10881078, + 0x10a81098, 0x10c810b8, 0x1fb25d0d, 0x92831724, 0xb1102424, 0x8c820627, 0x17270739, 0x37272727, 0x57274727, 0x77276727, 0x97278727, 0xb727a727, + 0x8227c727, 0x27d6328c, 0x5d0227e6, 0xb01030b0, 0x2db0d02d, 0x2731302f, 0x05276b34, 0x34351727, 0x2223022e, 0x058e5806, 0x15021e30, 0x0e352311, + 0x26222303, 0x023e3205, 0xd5563535, 0x02780808, 0x60b98f58, 0x36353b25, 0x5e563b20, 0x4cb06821, 0x7dd1543e, 0x4675934c, 0x645b248a, 0xbeb92d64, + 0x89567701, 0x7b433560, 0x66894a2d, 0x58fc733e, 0x021f4577, 0x43040604, 0x15335844, 0x33672f38, 0x84512741, 0x9c9efd5c, 0x172b442d, 0x4c33198e, + 0x0a582356, 0x482d1402, 0x00633b35, 0x31000200, 0xa403e9ff, 0x14001905, 0xec002400, 0xb02f25b0, 0x00b02f26, 0x1025b0dc, 0x2a05814d, 0xf40c09b1, + 0xb2d00cb0, 0x83000a0d, 0x100024f3, 0x610815b1, 0x092326c1, 0x431cb010, 0xea46062d, 0x0caa6f0c, 0x0814fe48, 0x0620b12c, 0x071b40f4, 0x27201720, + 0x47203720, 0x67205720, 0x87207720, 0xa7209720, 0xc720b720, 0xb45d0d20, 0x20e620d6, 0x08b25d02, 0x96832005, 0x10102e08, 0xf4061ab1, 0xe91ad9b4, + 0x405d021a, 0x181a081b, 0x381a281a, 0x581a481a, 0x781a681a, 0x981a881a, 0xb81aa81a, 0x0d1ac81a, 0x100db25d, 0x05b0461a, 0x020e1424, 0xf5482223, + 0x36112305, 0x85603336, 0x075c0808, 0x33161611, 0x03023e32, 0xae7b42a4, 0x3c8b4c6c, 0x8b3c8989, 0x7bae6c4c, 0x54298b42, 0x759e527d, 0x524e893c, + 0x012b547b, 0x81b46bd1, 0x54353648, 0x35fe1905, 0x81493933, 0x87506ab5, 0xfe7d3a64, 0x3a38410e, 0x01008764, 0xe9ff0000, 0xba038103, 0xd7002800, + 0xb02f29b0, 0x14b02f2a, 0x21071f4b, 0xab4c1029, 0x10142e06, 0xf40b13b1, 0xb0d016b0, 0x20b11008, 0x53f7820c, 0xad4622ba, 0x2f132405, 0x4213b11b, + 0x0d2007dc, 0xa6600c82, 0x088f4f08, 0x7c561220, 0x28a75308, 0xa7530320, 0x5625202b, 0x1e210b79, 0x0f284a02, 0x32334708, 0x81033736, 0x6d8dcd3b, + 0x424881b6, 0x2b6cb17a, 0x1040505a, 0x4e2d7b7b, 0x7d543e6c, 0x5d312b54, 0xa2685283, 0x6d5cb22b, 0x6db28148, 0x4981b56a, 0x27392914, 0x3e8bfe87, + 0x3a294a66, 0x50508764, 0x523a6287, 0x31440044, 0x19052e07, 0x26001600, 0x27b0e800, 0x2f28b02f, 0x06a153b0, 0xab422720, 0x01b02506, 0xd012b010, + 0x2b080583, 0x0ab0d017, 0x0c1fb110, 0x061b40f4, 0x261f161f, 0x461f361f, 0x661f561f, 0x861f761f, 0xa61f961f, 0xc61fb61f, 0xb45d0d1f, 0x1fe51fd5, + 0x24072a44, 0xb11b2f0f, 0x074d410f, 0x2019fb47, 0x06346305, 0x0624b122, 0x07395d82, 0x27241724, 0x47243724, 0x67245724, 0x87247724, 0xa7249724, + 0xc724b724, 0x355d8224, 0x24e624d6, 0x02b25d02, 0x12112405, 0x1015b039, 0xf40613b1, 0xaa420fb0, 0x31302329, 0x145b2321, 0x2311240e, 0x44032135, + 0x3a08071b, 0x3233021e, 0x8a730337, 0x6f4a8d3b, 0x414179b0, 0x4a6fb079, 0x01ba3b8d, 0x8b3b8a44, 0x547d524e, 0x7d542b2b, 0x56769e52, 0x81483835, + 0xb56a6bb4, 0x35354981, 0xfd755401, 0x413a41b2, 0x6432055b, 0x02007d3a, 0xe9fffcff, 0xba03ae03, 0x22001900, 0x59427b00, 0x0c407305, 0xf1820a20, + 0x3e0f0a2e, 0x0622b359, 0xb02b0400, 0x03b1100a, 0x0338fa84, 0x03270317, 0x03470337, 0x03670357, 0x03870377, 0x03a70397, 0x03c703b7, 0x3308fa83, + 0x0203e603, 0x1014b05d, 0xf4061db1, 0xe91dd9b4, 0x405d021d, 0x181d081b, 0x381d281d, 0x581d481d, 0x781d681d, 0x981d881d, 0xb81da81d, 0x0d1dc81d, + 0x1331305d, 0x2005ce4e, 0x0d524217, 0x85271521, 0x074e08ee, 0x95ba0f89, 0x6029a469, 0x6c8ec246, 0x414883b4, 0x776db07b, 0x913977b2, 0x4281b017, + 0x083a5670, 0xb094a201, 0x62424056, 0xb2814867, 0x83b36a6d, 0xc48d5049, 0x96997577, 0x4371502b, 0xba000100, 0xa4030000, 0x19002f05, 0x02b39f00, + 0xc8820708, 0x23056774, 0x18b01002, 0x4c06a544, 0xd9590c22, 0x2f0a240c, 0x420ab11b, 0x1820071b, 0x18200c82, 0x210f0e60, 0x304918b0, 0x4c042005, + 0xd0230650, 0x74d007b0, 0x09230652, 0x690eb0d0, 0x734c2c96, 0x23850807, 0x36343335, 0x17163233, 0x23262615, 0x21150622, 0x73fea403, 0xd3d1fdd2, + 0xc9c7d3d3, 0x1d17412f, 0x83832b3f, 0x2f038d01, 0x757546fd, 0xc075ba02, 0x750406cb, 0x91850604, 0xff020000, 0x0375fefe, 0x00ba0373, 0x012e001f, + 0x2f2fb001, 0xb02f30b0, 0x2fb0dc00, 0xd015b010, 0xb12f15b0, 0x40f40c28, 0x1628061b, 0x36282628, 0x56284628, 0x76286628, 0x96288628, 0xb628a628, + 0x0d28c628, 0x28d5b45d, 0x5d0228e5, 0x20be82b0, 0x2c3a8209, 0x080fb110, 0xd01db0f4, 0xb0100fb0, 0x06304120, 0x1b2f1e24, 0x09411eb1, 0x821a2007, + 0x871a200c, 0x0cad4f0c, 0x19820f20, 0x77470f20, 0x07345107, 0x040cb32b, 0xb02b0405, 0x2bb11012, 0x39898206, 0x2b172b07, 0x2b372b27, 0x2b572b47, + 0x2b772b67, 0x2b972b87, 0x2bb72ba7, 0x89822bc7, 0x2bd63c08, 0x5d022be6, 0x2b1210b2, 0xb0391211, 0x23b1101a, 0xd9b4f406, 0x0223e923, 0x081b405d, + 0x28231823, 0x48233823, 0x68235823, 0x88237823, 0xa8239823, 0xc823b823, 0xb25d0d23, 0x82231a1d, 0x31302232, 0x06ec4525, 0x1616372c, 0x35363233, + 0x22230635, 0x5b583526, 0x47072008, 0x1c82086d, 0x03374a08, 0xa1774273, 0x47c38b63, 0x68a22b60, 0x9c7aa58e, 0x7941fadb, 0x8f4c6dae, 0x3b8a8a3b, + 0x7d524e8d, 0xa6a62b52, 0x0a3b8d4e, 0x37689660, 0x414a6268, 0x64878f58, 0x6ad9fa6c, 0x354983b3, 0x41d95435, 0x89643a3a, 0x3bbea04e, 0x0b6f5542, + 0x8e001322, 0x36088953, 0xf40801b1, 0xb01014b0, 0x0cb0d00c, 0x0c0bb12f, 0xd00eb0f4, 0x560c0fb2, 0x495c0914, 0x2f11240c, 0x4111b11b, 0x0b201458, + 0x34081982, 0x593e0f0b, 0xb11011b0, 0xb4f40605, 0x05e905d9, 0x1b405d02, 0x05180508, 0x05380528, 0x05580548, 0x05780568, 0x05980588, 0x05b805a8, + 0x5d0d05c8, 0x0d000fb2, 0x05195711, 0xdb711120, 0x152c0805, 0x33112311, 0x20331211, 0x8a730311, 0x7b4c796c, 0x89892d56, 0x5801fe63, 0x8a7d3f02, + 0x52977546, 0x19055efe, 0x0001a1fd, 0x020085fe, 0x2e089958, 0x000d0003, 0x0e0cb35f, 0xb22b0406, 0x820c0601, 0x01b02252, 0x0616512f, 0x8207b121, + 0x590620df, 0x44570927, 0x0c4b430c, 0x2807c851, 0xf40606b1, 0xb1100ab0, 0x82068208, 0xd00c2438, 0x63d00db0, 0x13280561, 0x11333521, 0x11213523, + 0x3105476f, 0xd3d3d1fd, 0x04d25d01, 0xe7fabb5e, 0x75ba0275, 0x9382d1fc, 0x75fe0430, 0x1905e902, 0x16000300, 0x00b33e00, 0x93820108, 0x00010f22, + 0x0f239383, 0x5c14b12f, 0x868c076a, 0x1b2f122b, 0x3e1312b1, 0x060ab359, 0x05874204, 0xf4061022, 0x01217285, 0x09b95822, 0x14357983, 0xbae90206, + 0xf673feba, 0x75246962, 0x355c4456, 0x5c01d317, 0x338282bd, 0x48ca5cf9, 0x4827524c, 0x2f034266, 0xb45cfc75, 0x000100d7, 0x2207775f, 0x5851000b, + 0xd74123c5, 0x07154114, 0x2106c558, 0xcc580ab2, 0xc3a23913, 0x89a883fe, 0xc4130289, 0xa2012dfe, 0x05f8fe9a, 0x0195fc19, 0x0054fef6, 0x260a3f5a, + 0xb3440009, 0x5c020e08, 0x03240558, 0x02b0f408, 0x4f09f45c, 0xb0430c73, 0x0b4c5a07, 0x08232b82, 0x4e09b0d0, 0x844106a3, 0x41e92006, 0x75250681, + 0xfb752f04, 0x089b515c, 0x00ba0328, 0xb0da0021, 0x5e442f22, 0x0ab02905, 0x0aefb2dc, 0x40b25d01, 0xb0210482, 0x200c8201, 0x820c8301, 0x00b12804, + 0x0ab0f40c, 0x8209b110, 0x1015238c, 0x0d8214b1, 0xb2d0172c, 0x110a1518, 0x1cb23912, 0x654a010a, 0x08046405, 0x1b2f1624, 0x624416b1, 0x0c7c4414, + 0x4a0c6f44, 0x14200c53, 0x14254082, 0xb0593e0f, 0x2923431e, 0x820eb021, 0x1a002191, 0x06849184, 0x2131302b, 0x26341123, 0x15062223, 0x21088511, + 0x0983020e, 0x36153325, 0x82173233, 0x16210803, 0x89a40315, 0x494e3538, 0x3135398a, 0x890a213a, 0x89902b89, 0x777c4431, 0x509e026f, 0xfd94a458, + 0x2d0783f2, 0x366e5a3a, 0xa403f2fd, 0x89899d87, 0x1d448f8d, 0xba032208, 0x311d4400, 0x44071341, 0x1120501d, 0x20121d44, 0x1c1d4415, 0xeaa4032f, + 0x85fe0001, 0xff020000, 0x03e9ffec, 0x59cf84bc, 0x0c2019cf, 0x415fcf59, 0xcc50071a, 0x79cf5908, 0x8145bc28, 0xb46d6fb4, 0x07824581, 0x826f6d21, + 0x2f892a07, 0x5252835c, 0x2f2f5a83, 0x0807835a, 0x012f5c2e, 0x7fb26dcf, 0xb27f4848, 0x81b76a6d, 0xb7814949, 0x6687506a, 0x87663a3a, 0x62875050, + 0x87623838, 0x31000200, 0xa4038bfe, 0x1300ba03, 0x2027a34d, 0x27634114, 0x6c0fa34d, 0x0c870ce7, 0x1b2f0924, 0xf45809b1, 0x08ff4a07, 0x412fa34d, + 0xb2222a84, 0x65710f0d, 0x2726260b, 0x33112311, 0x0aa24d15, 0xa34d0620, 0x44370809, 0x4a6cae7b, 0x89893c8b, 0xae6c927f, 0x2b89447b, 0x4e527d56, + 0x873c3c87, 0x567d524e, 0x6dd1012b, 0x364881b2, 0x0537fe35, 0x476c5619, 0x4e6ab583, 0x3a3a6489, 0x4d0cfe41, 0x022605a3, 0x8bfe0000, 0x5b417303, + 0x4ef22006, 0x252006ff, 0x2f078950, 0x09b01026, 0x0808b1dc, 0xd00bb0f4, 0x09000cb2, 0x08059c44, 0x0c14b12a, 0x061b40f4, 0x26141614, 0x46143614, + 0x66145614, 0x86147614, 0xa6149614, 0xc614b614, 0xb45d0d14, 0x14e514d5, 0x08b05d02, 0x2409024f, 0xb11b2f08, 0x0c994208, 0x0a200c87, 0x0a201982, + 0x080c605a, 0x593e0f30, 0xb11005b0, 0xb4f40620, 0x20e920d9, 0x1b405d02, 0x20182008, 0x20382028, 0x20582048, 0x20782068, 0x20982088, 0x20b820a8, + 0x5d0d20c8, 0x054f07b2, 0x05614105, 0x071b403b, 0x27191719, 0x47193719, 0x67195719, 0x87197719, 0xa7199719, 0xc719b719, 0x27998219, 0x19e619d6, + 0x0cb25d02, 0x2b066141, 0x023e3411, 0x35173233, 0x11231133, 0x6b05784b, 0x36220583, 0x14491137, 0x7a442d05, 0x7f916caf, 0x8b3b8a8a, 0x7aaf6c4a, + 0x21075f41, 0x5f413b3b, 0xb56a3c07, 0x566c4783, 0xc901e7fa, 0x81483635, 0x874e6db2, 0x41383a64, 0x3a41f401, 0x5789643a, 0x9e2a06b9, 0x1700ba03, + 0x08b38300, 0x89460c0e, 0x0c0d2d05, 0x100cb0f4, 0xb0d00fb0, 0x11b01008, 0x2020c27f, 0x06814c0a, 0x14b02b08, 0x0602b110, 0x02d9b4f4, 0x5d0202e9, + 0x02081b40, 0x02280218, 0x02480238, 0x02680258, 0x02880278, 0x02a80298, 0x02c802b8, 0x4d485d0d, 0xd00c3407, 0xb2d00db0, 0x11140a12, 0x31303912, + 0x22232601, 0x5415020e, 0x380806a9, 0x15213523, 0x16322112, 0x4a710317, 0x5c845466, 0xd1fdd331, 0x5c01d3d3, 0x4707015e, 0x21032d69, 0x97754825, + 0x75d3fe50, 0x75ba0275, 0x120001ea, 0xff010017, 0x03e9fff6, 0x2ecf828b, 0xb0df0032, 0x34b02f33, 0xdc00b02f, 0x770c0eb1, 0x2f08255b, 0xb01033b0, + 0x18b0d018, 0x0c29b12f, 0x061b40f4, 0x26291629, 0x46293629, 0x66295629, 0x86297629, 0xa6299629, 0xc629b629, 0xb45d0d29, 0x29e529d5, 0x24079b4e, + 0xb11b2f1d, 0x0c3c421d, 0x593e0f26, 0x13052eb3, 0x2105f072, 0x4c82060c, 0x170c0739, 0x370c270c, 0x570c470c, 0x770c670c, 0x970c870c, 0xb70ca70c, + 0x820cc70c, 0xd62f084c, 0x020ce60c, 0x101db05d, 0xf40624b1, 0xe924d9b4, 0x405d0224, 0x1824081b, 0x38242824, 0x58244824, 0x78246824, 0x98248824, + 0xb824a824, 0x5a24c824, 0x37280b16, 0x20331616, 0x022e3435, 0x4b0a105a, 0x2a080831, 0x1e17021e, 0x528b0303, 0x7f4c9f81, 0x673d5cfc, 0x35016bc8, + 0x3d6f5633, 0x4d7f9a4e, 0x56a07747, 0x374ec27b, 0x2b60a450, 0x833d5a69, 0x4c280816, 0x014e7f9b, 0x406c5202, 0x763c4a1b, 0x27a04641, 0x08121f31, + 0x643c1e0b, 0x44664652, 0x6b353920, 0x250f2d38, 0x2f272d3b, 0x3a221684, 0x45510064, 0x05ae2a06, 0x001b0019, 0x0c13b385, 0x29f28208, 0x0cb01008, + 0x1013b0d0, 0x3a420eb0, 0x0c2f4b06, 0x1b2f0b24, 0xc8440bb1, 0x07165114, 0x0fb03a08, 0x0609b110, 0xd00ab0f4, 0xb0d011b0, 0x03b0d012, 0x0618b110, + 0x071b40f4, 0x27181718, 0x47183718, 0x67185718, 0x87187718, 0xa7189718, 0xc718b718, 0xb45d0d18, 0x18e618d6, 0x0a6d6702, 0x35231129, 0x11331133, + 0x59211521, 0x30080571, 0xae033736, 0x5295c710, 0xd3356088, 0x8d0189d3, 0x3b2173fe, 0x89663654, 0x9329010a, 0x876036ad, 0x75d90150, 0x8bfe7501, + 0x3327fe75, 0x7f27445a, 0x26db8265, 0x03e9ff31, 0x47a40373, 0x14200aff, 0x25067b44, 0xf40c01b1, 0xe88215b0, 0x25050955, 0x0fb2d00e, 0xc1570c00, + 0x82002008, 0x870020e3, 0x20f08ce3, 0x2019820d, 0x076c4d0d, 0x0c821120, 0x0c821120, 0x8405b121, 0x170538dd, 0x37052705, 0x57054705, 0x77056705, + 0x97058705, 0xb705a705, 0x8305c705, 0xe60527dd, 0xb25d0205, 0xce59110f, 0x6b132005, 0x1121087d, 0x08e88233, 0x2023022c, 0x6d893111, 0x567a4c79, + 0x628a8a2d, 0x03a8fefe, 0x7dc0fda4, 0x97754689, 0xfca20152, 0x00ffe95c, 0x01007b01, 0x0000e1ff, 0xcf82c303, 0x870d415a, 0x820320a8, 0x5903208e, + 0x415a0fd8, 0xfec32e10, 0x6afeb86c, 0x014e01a4, 0xfca4034c, 0x2203825c, 0x823103cf, 0x86e5205b, 0x0d415a5b, 0x06204e87, 0x06205b82, 0x8f0cb146, + 0x31415a68, 0xa0bdc32c, 0xbfa08d95, 0x88918792, 0x87828795, 0xac025c24, 0xf88254fd, 0xea021623, 0x590382fd, 0xba200667, 0x1b22ef82, 0x415a7700, + 0x0c45520a, 0x2014e14b, 0x08415a07, 0x5af40321, 0x0422173e, 0x3e5ab0f4, 0x2303272e, 0x23152135, 0x06843717, 0x01032d08, 0xfeba0333, 0xb6b8527f, + 0x9184fe4b, 0x87f60001, 0xaa567f01, 0x83015eac, 0x0001f683, 0x0e01798f, 0x7979f2fe, 0x50016001, 0xfefe7b7b, 0xb0220382, 0xd182a0fe, 0x75fee124, + 0xd182c103, 0x23001222, 0x430aa75b, 0x354d0f4e, 0x31302605, 0x06060101, 0x062e4d23, 0x37363508, 0x01330137, 0xfec10301, 0x568e2708, 0x2f1b6060, + 0x33441c5a, 0x60fe3913, 0x015001a2, 0xfba4034a, 0x233d6270, 0x42111476, 0xbf038d2d, 0x2f03d1fc, 0x00010000, 0x03210482, 0x226f8277, 0x5958000d, + 0xb02414f7, 0x03b22f01, 0x5905cb4d, 0x614117fa, 0x1ffa5910, 0x7b02b837, 0x0375fcfd, 0x0285fd2f, 0x0275751d, 0x0100ffba, 0x46fd7575, 0x318f8301, + 0x028bfeba, 0x00d305e7, 0xb3460026, 0x04060923, 0x8f4eb02b, 0x2a7c8205, 0xb0f40e26, 0x23b0d013, 0x5a17b010, 0x132e0f05, 0x2b041401, 0x09010ab3, + 0x1db22b04, 0x27480a09, 0x01252f06, 0x013130f4, 0x022e2223, 0x23341135, 0x05823235, 0x33023e2e, 0x22231533, 0x0e141115, 0x031e0702, 0x45080782, + 0xe7023333, 0x49673d5c, 0x29bbbb29, 0x5c3d6749, 0x2d1aaa5c, 0x3e252540, 0x5caa1a2f, 0x4a2b8bfe, 0xa8013e68, 0x01a870a8, 0x4a663eae, 0xfea86f29, + 0x404a2252, 0x2d06062f, 0xfe234940, 0x0100aa58, 0x46ff8d01, 0xb1821702, 0x0f000322, 0x7f05fb4e, 0x2f2d0531, 0x23053130, 0x17023311, 0x06ba8a8a, + 0x06595a8d, 0x0322d987, 0xd9820a0e, 0xb1100325, 0x5cf4090d, 0x1c26068e, 0x1003b0d0, 0xd98623b0, 0x1b2f082b, 0x3e1108b1, 0x011eb359, 0x22d9821b, + 0x82000126, 0x1008292f, 0xf4010ab1, 0x260013b2, 0x85054c47, 0x232323c6, 0xda853335, 0x032e3722, 0x0f84e282, 0x83021e21, 0xe7022bda, 0x664c29b8, + 0xa75d5d3d, 0xd3822f1b, 0x1b2d4230, 0x3d5d5da7, 0xb8294c66, 0xfea8f601, 0x09823e56, 0xa8715208, 0x4b23aa01, 0x08062b40, 0x224a402d, 0x6fa8ae01, + 0x3c664a2b, 0x00a852fe, 0x00fcff01, 0x02a803f6, 0x002300b0, 0x3e320100, 0x0e173702, 0x2e222303, 0x0e222304, 0x3e270702, 0x1e323303, 0x258b0204, + 0x08152133, 0x462b0687, 0x543d4066, 0x32292b39, 0x08118822, 0x3d426428, 0x292b3b54, 0x2f75012f, 0x0e417352, 0x42709a5a, 0x4550462f, 0x70522f2f, + 0x9b580f42, 0x452f4171, 0x002f4652, 0xf95effff, 0x8c062b05, 0x22002602, 0x07000000, 0x71828c00, 0x03007322, 0x37081786, 0x0016008b, 0x00250019, + 0x0a0ab368, 0xb42b0420, 0x20ea20da, 0x1b405d02, 0x20192009, 0x20392029, 0x20592049, 0x20792069, 0x20992089, 0x20b920a9, 0x5d0d20c9, 0x0a2017b2, + 0x2408ae45, 0xb11b2f1d, 0x07705d1d, 0x0c820e20, 0x0e530e20, 0x02052e10, 0xb32b0423, 0x04100317, 0x1331302b, 0x05245a34, 0x0614153f, 0x03230107, + 0x01230321, 0x03012626, 0x16141303, 0x35363233, 0x22232634, 0x3e22f206, 0x25c98252, 0x333f233d, 0x0970a101, 0x339f2b06, 0xdbbc013f, 0x375054db, + 0x03835037, 0x2faa053e, 0x23233d52, 0x422f523d, 0x1bfb1d66, 0x8bfe7501, 0x681de304, 0xa10286fc, 0xbc035ffd, 0x50322485, 0xecff0100, 0xac038dfe, + 0x2e002f05, 0x27b3ea00, 0x8982110c, 0x0b0d0422, 0x34080582, 0x041a0d1b, 0x101ab02b, 0x40d01db0, 0x1627061b, 0x36272627, 0x56274627, 0x76276627, + 0x96278627, 0xb627a627, 0x0d27c627, 0x27d5b45d, 0x5d0227e5, 0xb0101bb0, 0x06716130, 0xe7821a20, 0xf4871a20, 0x0c821620, 0x0c871620, 0x20075c42, + 0x0b3b68b0, 0x0c200c84, 0x5d082682, 0x593e0f0c, 0xf40509b1, 0x160819b2, 0xb0391211, 0x22b11016, 0xd9b4f406, 0x0222e922, 0x081b405d, 0x28221822, + 0x48223822, 0x68225822, 0x88227822, 0xa8229822, 0xc822b822, 0xb05d0d22, 0x2cb1100c, 0x1b40f401, 0x2c172c07, 0x2c372c27, 0x2c572c47, 0x2c772c67, + 0x2c972c87, 0x2cb72ca7, 0xaa822cc7, 0xe62cd623, 0x06c8472c, 0x1415072b, 0x35230607, 0x2e353532, 0x090f5403, 0x2f0cec62, 0x03133233, 0x8fc12dac, + 0xca935852, 0x316eb27f, 0x2e18426f, 0x1914bd95, 0x755f5893, 0x740815d5, 0x6f7febb9, 0xff37174b, 0x003100ff, 0x06730300, 0x002602c7, 0x00000026, + 0x008b0007, 0x88730100, 0x02732417, 0x842f0026, 0x85d72017, 0x056f7417, 0x828c0621, 0x42302017, 0x2f83099d, 0x82e9ff21, 0x20178347, 0x20178c36, + 0x22178200, 0x82530575, 0x0242242f, 0x82060000, 0x82ff205f, 0x2015852d, 0x22158854, 0x88000041, 0x88572015, 0x82d62015, 0x82ff2014, 0x03e92419, + 0x88190575, 0x898c2015, 0xff04212b, 0xd7201588, 0xca202b8a, 0xdb2c1588, 0x0100ff00, 0x8dfe0000, 0xba038103, 0xea22eb82, 0x514229b3, 0x0b1d2a0a, + 0xb02b041c, 0x1fb0101c, 0x24004bd0, 0x101db024, 0x514233b0, 0x2f1c2406, 0x451cb11b, 0x195207ed, 0x2651420c, 0x51421b20, 0x27064b08, 0x0cb03008, + 0x012eb110, 0x071b40f4, 0x272e172e, 0x472e372e, 0x672e572e, 0x872e772e, 0xa72e972e, 0xc72eb72e, 0xb45d0d2e, 0x2ee62ed6, 0x31305d02, 0x42060625, + 0x165b1151, 0xaa352a17, 0x93585273, 0x75a464ca, 0x1a1a5b3f, 0x0c665223, 0x06554217, 0xac7f4b23, 0x19235b67, 0x59ffff21, 0x052605c9, 0x00260253, + 0xf7410046, 0x20158608, 0x22158854, 0x88000041, 0x8857202b, 0x83d62015, 0x202b8614, 0x41158819, 0x8d6e05f7, 0x20578305, 0x565789d5, 0x57830609, + 0x57841585, 0x00aa0026, 0x05fc0200, 0x15855783, 0x2b865784, 0x15855783, 0x31265785, 0x73030000, 0x6d82ff04, 0x57844f20, 0x8384d720, 0xe9ffec24, + 0xc584bc03, 0x6d895020, 0x1585ff20, 0x15856d83, 0x15866d84, 0x15856d83, 0x15866d84, 0x15856d83, 0x15856d84, 0x15856d84, 0x00216d84, 0x216d8231, + 0x57830573, 0x6d865620, 0x15868482, 0x99825620, 0x41221585, 0x6f430200, 0x58052107, 0xd6211588, 0x832b8900, 0x822b856d, 0x0100246d, 0x5601ba00, + 0x0b220593, 0x8f471300, 0x452d0805, 0x2f08b058, 0x1508b11b, 0x3130593e, 0x23132701, 0x17350713, 0x37073327, 0x0cede902, 0xeeee0e6e, 0xed0c6e0e, + 0xfd0ec903, 0x0e62029e, 0x290f8370, 0x00000200, 0xe902e902, 0x4382d305, 0x7c00272a, 0xb02f28b0, 0x28b02f29, 0x2b06214c, 0xb01029b0, 0x00b0dc0a, + 0x0a14b110, 0x25268f50, 0x1eb1100a, 0x4318f40a, 0x002f246f, 0x0f0219b3, 0x05b32b04, 0x2b042302, 0x46113130, 0x0e210891, 0x13a97b02, 0x653b2808, + 0x894c4e87, 0x643b3b64, 0x874e4c89, 0x2b5c3b65, 0x393c644e, 0x2b2b4e66, 0x3c39664e, 0x042b4e64, 0x65894c5e, 0x83653b3b, 0x3c642e1e, 0x4e87643c, + 0x2b4d653b, 0x3b654d2b, 0x8225853a, 0x082208ed, 0x89030000, 0x1c001905, 0x8d002300, 0xb02f24b0, 0x1ab02f25, 0x0800b1dc, 0x1024b0f4, 0xb0d003b0, + 0xee822f03, 0xd008b022, 0x21065467, 0xbc4d101a, 0x1d270806, 0x1b40f40c, 0x1d161d06, 0x1d361d26, 0x1d561d46, 0x1d761d66, 0x1d961d86, 0x1db61da6, + 0x5d0d1dc6, 0xe51dd5b4, 0x835d021d, 0x07bc5a3d, 0x2f0c4470, 0xb11b2f1b, 0x593e0f1b, 0x12060bb3, 0x0bb02b04, 0x2b069d5f, 0x091b20b2, 0x30391211, + 0x02262531, 0x07dd4e18, 0x16165b08, 0x26260717, 0x36361127, 0x06061737, 0x03231507, 0x11171614, 0x8d010606, 0x6737d3b2, 0x7f8a588f, 0x296039ba, + 0x8d5c5c8d, 0xba396029, 0x83fc8a7f, 0xaa837979, 0xc0000121, 0x527da25e, 0x06a6af10, 0x3e42566b, 0x19fd0650, 0x423f4e08, 0xa2086a56, 0xc2858b02, + 0x1fcf0221, 0x3f5800c3, 0x05d32a06, 0x002c002f, 0x0c14b381, 0x288c8201, 0x17b01014, 0x011bb2d0, 0x24898214, 0xb01001b0, 0x06a2492a, 0x200cf664, + 0x20c08222, 0x22c08322, 0x82160615, 0x10152633, 0xb0d000b0, 0x29d46207, 0x1022b036, 0xf4061bb1, 0xb0d024b0, 0x16b0d025, 0xd02bb010, 0x33133130, + 0x8307f641, 0x22232df2, 0x33111506, 0x14112315, 0x20330706, 0x6d08fc82, 0x35212304, 0x023e3233, 0x31231135, 0x78542dbb, 0x4b5f334e, 0x167d0c38, + 0x5c623c52, 0x2933baba, 0x700f01ce, 0xfcfe426d, 0x3e4afea6, 0x0d1e3022, 0x01c702bb, 0x5c834c08, 0x5e3f2335, 0x495a1c3c, 0xf8fe707b, 0x50f2fe75, + 0x3bdf1669, 0x21758b8e, 0x01173931, 0x0200003b, 0x46ff1400, 0x8b069a03, 0x4f003f00, 0x50b0a000, 0x2f51b02f, 0xd18450b0, 0x2f002a08, 0xf40c40b1, + 0x40061b40, 0x40264016, 0x40464036, 0x40664056, 0x40864076, 0x40a64096, 0x40c640b6, 0xd5b45d0d, 0x0240e540, 0x092f425d, 0xd0064208, 0xb01051b0, + 0x10b0dc20, 0x2f10b0d0, 0xb11020b0, 0xb4f40848, 0x48ea48da, 0x1b405d02, 0x48194809, 0x48394829, 0x48594849, 0x48794869, 0x48994889, 0x48b948a9, + 0x5d0d48c9, 0xb0d011b0, 0x19b01040, 0x333482d0, 0xb0d026b0, 0x39b01048, 0x34b300d0, 0x2b042b06, 0x14060bb3, 0x2205ab49, 0x5c263736, 0x1e21064c, + 0x05284102, 0x15020e2d, 0x15041e14, 0x16070614, 0x43141516, 0x535a0531, 0x2e342408, 0x82143704, 0x36380829, 0x2e343536, 0x06062702, 0x3c483f44, + 0x916d3f4b, 0x7b955052, 0x16810c52, 0x5e2d87a0, 0xa06a2f4c, 0x386ba0b8, 0x4240333b, 0x56529571, 0x1560839e, 0x96ba1d7f, 0x2b496537, 0x63081983, + 0x8f5e896a, 0x312950ac, 0x4c9f8154, 0x3d033d46, 0x2836834c, 0x7b505c79, 0x582b2d54, 0x84155c85, 0x52331781, 0x465a493c, 0x73916042, 0x2b358548, + 0x8750587b, 0x582b355e, 0x8b216089, 0x563b1f8e, 0x4a6c583a, 0x7087583e, 0x39425c49, 0x33582127, 0x3948664e, 0x005e2321, 0xba000100, 0xa403ba00, + 0x1300a403, 0xb0210182, 0x0a28660f, 0x593e1322, 0x850b9a4a, 0x3cba2ad6, 0x4c4e8764, 0x3c3c6489, 0x05da4364, 0x8b2f0221, 0x241d820d, 0x00030000, + 0x3404821f, 0x0019058b, 0x000f000b, 0xb3920015, 0x04080813, 0x0804b32b, 0x21058205, 0x5f670c00, 0xb0310805, 0x04b0d00c, 0xd00eb010, 0xb01005b0, + 0x1b40d010, 0x13161306, 0x13361326, 0x13561346, 0x13761366, 0x13961386, 0x13b613a6, 0x5d0d13c6, 0xe513d5b4, 0x071e5313, 0x26227a75, 0x0402040c, + 0x6802b02b, 0x0a27074f, 0x060db110, 0x5f0cb0f4, 0x3024060d, 0x11232131, 0x24250183, 0x21211011, 0x300a8203, 0x15060603, 0x8b031714, 0xfe8aeb89, + 0x01f30192, 0x08088279, 0xe371722d, 0xd1fd2f02, 0x01273702, 0xfd750146, 0xfefa0191, 0x13f00106, 0x27c9667d, 0x00010000, 0x03e9ff31, 0x002f05a4, + 0xb306013b, 0x82250c24, 0x083522d9, 0x22058216, 0x821b0c30, 0x08002405, 0x7b2b040f, 0x23082467, 0xea1bdab4, 0x405d021b, 0x191b091b, 0x391b291b, + 0x591b491b, 0x791b691b, 0x991b891b, 0xb91ba91b, 0x0d1bc91b, 0x03671d82, 0x2f2b2c28, 0x152bb11b, 0x00b0593e, 0x66b05845, 0x6e6e07f6, 0x54b1200c, + 0x2b2a2840, 0x061eb110, 0x1ed9b4f4, 0xa1831ee9, 0x181e0839, 0x381e281e, 0x581e481e, 0x781e681e, 0x981e881e, 0xb81ea81e, 0x541ec81e, 0x322a0f40, + 0x2e343536, 0x3e343504, 0x755e3502, 0x0a534609, 0x14156f08, 0xa403041e, 0x4b815f35, 0x4e428f63, 0x5c446d35, 0x68563c79, 0x50423c56, 0x4a645241, + 0x8913355e, 0x7b955019, 0x2b51774c, 0x3b415041, 0x3c586658, 0x6b3d0c01, 0x35382e4d, 0x562f3168, 0x384b385a, 0x394e3931, 0x4a3f4c44, 0x3b64463d, + 0xfc488366, 0x4c4c03b2, 0x2d5e8faa, 0x523e684c, 0x22344162, 0x392f2b1b, 0x04006f50, 0x75010000, 0x53475e04, 0x00372e06, 0xb3bd0040, 0x040a0a1e, + 0x082cb32b, 0x2205822d, 0x82380834, 0x0a002405, 0x742b0414, 0x40202476, 0x2823357c, 0x000a28b2, 0xb2391211, 0x21068437, 0x5318dab4, 0xb02422e8, + 0x3cb0102c, 0x2b06e945, 0xb11b2f3d, 0x593e133d, 0x050223b3, 0x0f229c82, 0x05821902, 0x3b012f24, 0x4a182b04, 0xbd4c0988, 0x181e2005, 0x26104947, + 0x23272307, 0x7d112315, 0x58080572, 0x34370706, 0x15232326, 0x04363233, 0xcd93545e, 0x9ccb6c79, 0xcc98585e, 0x9ac87175, 0x854c415a, 0xb46667b4, + 0x854d4d88, 0xb46568b5, 0xbabb4e85, 0x018f23ae, 0x485e330c, 0x335e6229, 0x7d7d3b3a, 0xa4033e37, 0x5c99cb6f, 0x7fcd9350, 0x5898cc73, 0x77cc9854, + 0x4f88b264, 0x2331824b, 0x4c85b469, 0x26084182, 0x02f2f2e7, 0x50371ba4, 0x0a795037, 0xd73f2dd3, 0x0003003c, 0x04b80002, 0x00190562, 0x002d0019, + 0xb3d50041, 0x82240a38, 0x081422c0, 0x24058207, 0x042e0a1a, 0x244d592b, 0x24e64418, 0x26084982, 0x26381638, 0x46383638, 0x66385638, 0x86387638, + 0xa6389638, 0xc638b638, 0xb45d0d38, 0x38e538d5, 0x1ab05d02, 0x7143b010, 0xb3230ea6, 0x821f023d, 0x0317228e, 0x2a058202, 0x0411030c, 0x1029b02b, + 0x180233b1, 0x2527d744, 0x22230601, 0x8541022e, 0x07172205, 0xef541826, 0x25372107, 0x391ff275, 0x50cd6062, 0x33356085, 0xcd54855e, 0x8c376a60, + 0x6a717566, 0x6a01378c, 0x9e419554, 0x99cb240a, 0x414e415a, 0x2a08079e, 0x6568b486, 0x024e87b4, 0x60359312, 0x834c4f86, 0x48933963, 0x64698b64, + 0x6e8d648f, 0x505c9acb, 0x737fcc94, 0x56589acd, 0x8277cf96, 0x82502027, 0x68692137, 0x4a059c41, 0x042d0551, 0x0019055e, 0x0014000c, 0x090fb36e, + 0x22ee8210, 0x82070906, 0x09002705, 0xb22b0401, 0x8662100a, 0xb02f2206, 0x05866d06, 0x210ab84a, 0x0c8200b0, 0x200ccc69, 0x06317c13, 0x26149778, + 0xb11008b0, 0x6ef4010d, 0xa4780922, 0x2305220a, 0x08018211, 0x04213532, 0x4e816e5e, 0x799e6f81, 0x73fd9d79, 0x01b071b0, 0x01e902d1, 0x01b2fe8a, + 0x0276fe4e, 0x01b8fe30, 0x41fe7148, 0x0071bf01, 0xf2000100, 0xc702f403, 0x2f0f5b6c, 0x02012705, 0x2550fec7, 0xe7049301, 0x1f0141f3, 0xba22e382, + 0x0f625e04, 0x00072206, 0x07135330, 0x10c25a18, 0xba820620, 0x3e15062f, 0x1002b059, 0xf40500b1, 0xb0d004b0, 0x06746205, 0x35230530, 0xbae90233, + 0xbb8cfeba, 0xbb5e04bb, 0xe760bbbb, 0x00a42409, 0x55410013, 0x0c200519, 0x0c204082, 0x20078e4e, 0x320c8202, 0x593e0f02, 0x000113b3, 0x0bb32b04, + 0x2b040801, 0x831000b0, 0x10132f55, 0xb0d006b0, 0x0eb0100b, 0x1008b0d0, 0x648210b0, 0x07212528, 0x35213723, 0x03821321, 0x33372108, 0x21152107, + 0xa4032103, 0x6f5adffd, 0x01ecfe5a, 0x14fea24a, 0x6e5a2102, 0xfe15015a, 0xec01a2b6, 0x703d8082, 0xba6f5001, 0xb0fe6fba, 0xff020000, 0x030000c1, + 0x001905a4, 0x0012000f, 0x080eb356, 0x266a8201, 0x09b0100e, 0x8301b0d0, 0x1a2b7c5e, 0x230c0357, 0x020310b3, 0x0321aa83, 0x253f820c, 0x08b11006, + 0xb182f403, 0x040eb12c, 0x213130f4, 0x03231121, 0x98820123, 0x03841120, 0x0311012f, 0x06fea403, 0x01916fe9, 0xfe58028b, 0x37998291, 0xfe6f01eb, + 0x7501c506, 0x19058bfe, 0x7937fe79, 0x73011dfe, 0x6dfd9302, 0xff2f9c82, 0x03e9ffd3, 0x002f05d3, 0x0026001b, 0x5b1b0132, 0x58080629, 0x04b01033, + 0x2f04b0d0, 0xb0d000b0, 0x34b02f00, 0xdc12b010, 0xb0d00db0, 0x12b02f0d, 0x081cb110, 0x1cdab4f4, 0x5d021cea, 0x1c091b40, 0x1c291c19, 0x1c491c39, + 0x1c691c59, 0x1c891c79, 0x1ca91c99, 0x1cc91cb9, 0x1eb25d0d, 0x12110d00, 0x1004b039, 0xf40c27b1, 0xc627b6b4, 0x20328227, 0x159d5217, 0x99520b20, + 0x2ab22107, 0x1b413584, 0x0cfb4b05, 0x1b2f1733, 0x3e0f17b1, 0x1009b059, 0xf4062eb1, 0xe92ed9b4, 0x3a50822e, 0x182e081b, 0x382e282e, 0x582e482e, + 0x782e682e, 0x982e882e, 0xb82ea82e, 0x822ec82e, 0x090d2283, 0x0883832e, 0xb110172e, 0x40f40622, 0x1722071b, 0x37222722, 0x57224722, 0x77226722, + 0x97228722, 0xb722a722, 0x0d22c722, 0x22d6b45d, 0x5d0222e6, 0x22171bb2, 0xb2233282, 0x8309171e, 0x842a2006, 0x31302206, 0x083c4a27, 0x37171623, + 0x082f4a15, 0x07272631, 0x01273401, 0x32331616, 0x1425023e, 0x5d011716, 0x2d3c058e, 0x351f234e, 0x8387bf79, 0x52873cba, 0x76362323, 0xb98789bf, + 0x6a03853b, 0x2999fd22, 0x0805217a, 0x0f2bfd6e, 0x30650212, 0x8b6b5e8d, 0x54bc2154, 0x8368bf54, 0x6a71bcf4, 0x56a0925b, 0x8369be54, 0x6771baf4, + 0x6e028d5a, 0x72fd7996, 0x9f65604e, 0x8a4562c7, 0x568b023f, 0xc6a2645c, 0xf8ff0300, 0xb603dc00, 0x1f00c502, 0x33002900, 0x2fb35200, 0x2b04100a, + 0x2f061b40, 0x2f262f16, 0x2f462f36, 0x2f662f56, 0x2f862f76, 0x2fa62f96, 0x2fc62fb6, 0x2a08e082, 0x2fe52fd5, 0xb3005d02, 0x04050227, 0x021bb32b, + 0xb02b0423, 0x0bb01005, 0x101bb0d0, 0xb0d015b0, 0x2cb01023, 0x1027b0d0, 0x46d032b0, 0x262107b0, 0xb3421827, 0x5f36200d, 0x262306dd, 0x82072223, + 0x253621f3, 0x39084145, 0x3f23b603, 0x75483358, 0x4e6f3535, 0x25415631, 0x33563f25, 0x35356f4e, 0x0d834875, 0x565a4b08, 0x4a4a7f3b, 0xfe543b7f, + 0x3b834652, 0x813f5256, 0x5a33d101, 0x5a432642, 0x42264558, 0x5b33335a, 0x5a462541, 0x4125465a, 0x5448335b, 0x415e9f9c, 0x4144589c, 0x0200005e, + 0x46ff0000, 0xb003a403, 0x0f000b00, 0x02b32d00, 0xb5820309, 0x0b775618, 0x010fb323, 0x22ce820c, 0x4300010b, 0x561808c9, 0x2108126d, 0x21352111, + 0x66fea403, 0x0166fe70, 0x9a01709a, 0xa4035cfc, 0x5afea601, 0x0171a601, 0xfd67fe99, 0x6b83712f, 0x6b84ba20, 0x0500de39, 0x0c000900, 0x2f03b000, + 0x060109b3, 0x31302b04, 0x01010725, 0x83010117, 0xc8491844, 0x40023108, 0xea0216fd, 0xfe014d2d, 0xfe4e0002, 0x7168fd4e, 0x418ead82, 0x41880520, + 0x27010125, 0x84370101, 0x18982041, 0x2107a249, 0x41830c02, 0xfede012a, 0xb1014d02, 0xfb4eb201, 0x8b5f4282, 0x05a42906, 0x00190019, 0x0c02b36e, + 0xb228ef88, 0x11020310, 0x02b03912, 0x5d09d858, 0x11200c50, 0x0be44418, 0x2808e744, 0x04000319, 0x030cb32b, 0x081d4109, 0xb0101928, 0x10b2d006, + 0x4c830d02, 0xb0100c2a, 0x09b0d013, 0xd015b010, 0x099e5718, 0x21273527, 0x33033335, 0x08018201, 0x15330338, 0x21150721, 0x73fea403, 0x0171fe88, + 0xddfe6c8f, 0x0199cce5, 0x21010221, 0xfee1cc99, 0x8d016ee1, 0x68fe9801, 0x23789801, 0x960179d7, 0x5402acfd, 0xd7796afe, 0xc7820023, 0x8bfe312a, + 0xa4037303, 0x9e001500, 0x08894418, 0x0801b125, 0x4f16b0f4, 0xb12806b7, 0xb0f40c07, 0x01b0d00a, 0xf2438483, 0x2060180a, 0x82072014, 0x110721de, + 0x66061f4b, 0x04200c48, 0x04271982, 0xb2593e0f, 0x82090702, 0x515418d3, 0x06b22328, 0x2f820e04, 0x2131302b, 0x21023523, 0x23112722, 0x0a4e5d11, + 0x8a730328, 0x7b00ff60, 0x4f5d8954, 0xfeec2b07, 0x6afe38fd, 0xc2fd1905, 0x505d8b7d, 0x06496505, 0x2f05b622, 0x2523e382, 0x18b0be00, 0x45080158, + 0x27270539, 0xdc0eb010, 0x830005b2, 0xb12a0865, 0xb4f40c16, 0x16ea16da, 0x1b405d02, 0x16191609, 0x16391629, 0x16591649, 0x16791669, 0x16991689, + 0x16b916a9, 0x5d0d16c9, 0x461800b0, 0x264529e6, 0x2f132b12, 0x0f13b11b, 0x05b2593e, 0xdc820913, 0x21b13608, 0x1b40f406, 0x21172107, 0x21372127, + 0x21572147, 0x21772167, 0x21972187, 0x21b721a7, 0x5d0d21c7, 0xe621d6b4, 0x305d0221, 0x36340331, 0x26372436, 0x1e372724, 0x050d4f03, 0x34012625, + 0x820e2726, 0x165e080c, 0x023e3233, 0x01cb7414, 0xfe4e9c10, 0x872da6f8, 0x4770bdfa, 0xcd79c088, 0x104103f5, 0xb0f49111, 0x5c91a862, 0x0133628e, + 0x7aa26962, 0xae7d1954, 0x8935753b, 0x81a3f8bd, 0xc14e92cf, 0x64376f01, 0x6246102f, 0x90744c7d, 0x00a47440, 0x2b000100, 0x73030000, 0x0f001905, + 0x07b34300, 0xe56d080b, 0xd0002905, 0xb01008b0, 0x07b0d00d, 0x18090e7a, 0x410cd840, 0x052008f4, 0x08051760, 0xb110003b, 0x30f4060c, 0x35212131, + 0x21350101, 0x21112311, 0x11210101, 0xfc730333, 0xfe4801b8, 0x794803b8, 0x4501d5fd, 0x2b02bbfe, 0x18027579, 0xfe751702, 0xfd440147, 0x01e8fde9, + 0x08294845, 0x0b2d8582, 0x0cb05700, 0x2f0db02f, 0xb1dc02b0, 0x05f36203, 0x86820720, 0x06b12f22, 0x4e07047a, 0x62180cba, 0xb02514aa, 0x00b1100a, + 0x069e4806, 0x9069b020, 0x23012106, 0x41499483, 0xa4032d05, 0xe4fe89bb, 0xa403ba8a, 0x5cfba404, 0x75210385, 0x057d7200, 0xa403b22c, 0x94001b00, + 0xb02f1cb0, 0xa9622f1d, 0x1cb02a06, 0xd016b010, 0xb12f16b0, 0x07196b10, 0x200cd26e, 0x069b5e07, 0x4500b025, 0x7e12b058, 0x09200be3, 0x2606ab7c, + 0xf40303b1, 0x70071b40, 0xb22d2100, 0x11180906, 0x18b03912, 0x040fb110, 0x227583f4, 0x78b0d017, 0x252706f7, 0x32331614, 0x4b173736, 0x3b080537, + 0x03102311, 0x35123623, 0x15213523, 0x46d10223, 0x0f231c33, 0x2d52291a, 0xec294356, 0x17168b2b, 0xd3a403d3, 0x083835cf, 0x1f197109, 0x0237563a, + 0xfe73fe5a, 0x9301c964, 0x007b7bcd, 0x2008eb82, 0x0375fe04, 0x00a206a4, 0xb3270019, 0x04130807, 0x10b3002b, 0x2b040906, 0x030616b3, 0x09b02b04, + 0x056b6d10, 0x1016b02b, 0xb0d019b0, 0x31302f19, 0x05536f01, 0x21101127, 0x35272622, 0x208b8316, 0x080c8235, 0x17163249, 0x3f1da403, 0xfe878129, + 0x23431f72, 0x7f2d3b1d, 0x1e920185, 0x27062344, 0x8f790204, 0x85fecbfa, 0x04730404, 0x058e7903, 0x067d0135, 0xff030004, 0x020001f8, 0x002b05bc, + 0x00340025, 0xb0c40038, 0x3ab02f39, 0x5239b02f, 0xb02106af, 0x15cd763a, 0xb0d02b2a, 0x32b11000, 0x1b40f408, 0x09e14d18, 0x0fff4d18, 0x185d0d21, + 0x2307f14d, 0x35b0101c, 0xb0253183, 0x36b0d036, 0x059e432f, 0x1b2f172b, 0x3e1517b1, 0x0638b359, 0x22ea8235, 0x82210626, 0x01052205, 0x057d472f, + 0xb0d00a24, 0xd7762f0a, 0x2fb0282b, 0xd02cb010, 0x182f2cb0, 0x2207a451, 0x76161632, 0x062413a5, 0x022e2223, 0x0809a576, 0x14150685, 0x35210116, + 0x75450821, 0x251f4d92, 0x271b201f, 0x561a4237, 0x3d374085, 0x753d73a2, 0x758d395c, 0x4c663da8, 0x441a012b, 0x3527476b, 0x96762544, 0xfdef0148, + 0x02bc0244, 0x3d6345f8, 0x0404041b, 0x1d31254b, 0x6d2d230c, 0x3b1b2f29, 0xf8fd425c, 0x3a1c816f, 0x2f213250, 0x08501636, 0x2d4c4302, 0x756ffe3a, + 0xff030000, 0x020001ee, 0x002d05fe, 0x00250013, 0xb0b20029, 0x2bb02f2a, 0xdc00b02f, 0x76102ab0, 0xb02305ad, 0x68b11000, 0x0a2028fb, 0x342f0e45, + 0xb11b2f0f, 0x593e150f, 0x260629b3, 0x21b32b04, 0x2b040506, 0x2ad668b0, 0x081bac4f, 0x32331663, 0x2113023e, 0xfe022135, 0x5291693d, 0x3b6a8e54, + 0x548e6a3b, 0x3d699152, 0x5c462989, 0x455c3635, 0x376f8f27, 0x7427465c, 0xe90217fd, 0x9256a403, 0x66373966, 0x91585a90, 0x69373769, 0x673d5891, + 0x49272749, 0x967d3d67, 0xfd664827, 0x0000759a, 0x00ecff01, 0x05bc0300, 0x002d002f, 0x0c17b3c7, 0x25b38224, 0x040d0c00, 0x4b18b42b, 0x2f0823a4, + 0x17660f40, 0x17861776, 0x17a61796, 0x17c617b6, 0x0d405d07, 0x17161706, 0x17361726, 0x17561746, 0xd5b45d06, 0x0217e517, 0x1024b05d, 0xf40e1cb1, + 0x18059242, 0x250cf440, 0xb11b2f06, 0x7c790f06, 0x066b7f0f, 0x10294008, 0xf40112b1, 0xe912d9b4, 0x405d0212, 0x1812081b, 0x38122812, 0x58124812, + 0x78126812, 0x98128812, 0xb812a812, 0x0d12c812, 0x1004b05d, 0xb0d01fb0, 0x3130d020, 0x07021401, 0x21153315, 0x79033e11, 0x0e2b053f, 0x1e141502, + 0x21111702, 0x57353335, 0x7b0805a3, 0x021e3233, 0x7d6ebc03, 0x43a4fed3, 0x2716385a, 0x5a5e8556, 0x16295685, 0xfe435836, 0x6e79d3a4, 0x77b67b3f, + 0x3f7db677, 0xfe91e502, 0x75725df0, 0x671a2301, 0x523f877b, 0x565689a8, 0x3f52a889, 0x1a677b87, 0x7275ddfe, 0x95130156, 0x62a2d571, 0x00d5a262, + 0xdbff0300, 0xba03e9ff, 0x3500ba03, 0x4b003c00, 0x4cb01b01, 0x2f4db02f, 0xb1dc3cb0, 0xb2f40c10, 0x11103c00, 0x4cb03912, 0x85083658, 0x3c34080f, + 0xd029b010, 0xb01010b0, 0x08b0d03d, 0x0c43b110, 0x061b40f4, 0x26431643, 0x46433643, 0x66435643, 0x86437643, 0xa6439643, 0xc643b643, 0xb45d0d43, + 0x43e543d5, 0x2414f367, 0xb11b2f23, 0x0f006823, 0x4500b025, 0x8233b058, 0x0f332d19, 0x0db3593e, 0x2b042905, 0x1d0500b2, 0x0d218983, 0x06ec5610, + 0xb1101d26, 0xb4f40114, 0x24d45918, 0x3b852020, 0xb1103324, 0x435f042c, 0x14b03725, 0xd039b010, 0xb1100db0, 0xb0f40640, 0x46b0102c, 0x253130d0, + 0x5d73030e, 0x2634240b, 0x61062223, 0x162105ae, 0x05e64b17, 0x14211522, 0x2006fb45, 0x20298206, 0x21218401, 0x90450715, 0x08198305, 0x35023e98, + 0x2b0dc101, 0x75314e3d, 0x785d397d, 0x16301640, 0x5e294746, 0x461a5623, 0x4e194146, 0x841c1770, 0x336b5c45, 0x4e54fe0e, 0x12482f4e, 0x667d2375, + 0x50017f4c, 0x50424740, 0x172d0c89, 0x3b3c7b56, 0x1d2f3d21, 0x384323aa, 0x50779e23, 0x02234975, 0x734c6004, 0x2b543b48, 0x4512273d, 0x70454e4e, + 0xa64abaa4, 0x25413a94, 0x0165696c, 0x858aa3cd, 0x020265a8, 0x56366660, 0x2948351f, 0xd5ff0300, 0xd103e9ff, 0x1900ba03, 0x2f002400, 0x30b0fc00, + 0x2f31b02f, 0x845a30b0, 0x315f0807, 0xdc10b010, 0xf40c1ab1, 0xea1adab4, 0x405d021a, 0x191a091b, 0x391a291a, 0x591a491a, 0x791a691a, 0x991a891a, + 0xb91aa91a, 0x0d1ac91a, 0xd00bb05d, 0xb02f0bb0, 0x25b11003, 0x1740f40c, 0x25162506, 0x25362526, 0x25562546, 0x25762566, 0x25962586, 0x5d0b25a6, + 0xc625b6b4, 0xb45d0225, 0x82e525d5, 0x05276a06, 0x6c055543, 0x152d0c3b, 0x15b11b2f, 0xb0593e0f, 0x2bb11008, 0x4f591806, 0x081b2408, 0x182b182b, + 0x25155359, 0x0cb25d0d, 0x83782b08, 0x28b66d06, 0x20151922, 0x30233282, 0x58372731, 0x9f4e06dc, 0x06c04905, 0x4e0d9e4e, 0x2b2c079d, 0x8145455c, + 0xb4716db4, 0x495e9841, 0x62080982, 0x42b6716f, 0x2b5e0395, 0x7f2fc9fd, 0x5c835254, 0x2742fd2f, 0x812f3902, 0x5a835252, 0x744a772f, 0x81b76a9a, + 0x79444b49, 0x99794c77, 0x487fb26d, 0x0177444a, 0xfe546acf, 0x383a313c, 0x6b508762, 0x31c4014d, 0x87663a3a, 0xd1000200, 0xb603e9ff, 0x03001905, + 0x94001f00, 0x040813b3, 0x0cb32b04, 0x18040308, 0x220d6756, 0x58f4080b, 0x00202a37, 0x0bde4218, 0x366a0b20, 0x821d200b, 0x0f1d260c, 0x16b1593e, + 0x08508206, 0x17160732, 0x37162716, 0x57164716, 0x77166716, 0x97168716, 0xb716a716, 0x0d16c716, 0x16d6b45d, 0x5d0216e6, 0x33013130, 0x34012315, + 0x3335043e, 0x15040e14, 0x080be042, 0xba2f023b, 0x39a2feba, 0x39566756, 0x68563b91, 0x666d3c56, 0x7b0e7f7f, 0xa6b0c312, 0xbb1905ba, 0x754dbdfc, + 0x6c5c5762, 0x6a7b4e46, 0x39625c5f, 0x72966558, 0xaac3a812, 0x02020000, 0x2004822f, 0x24f584e9, 0xb33f0007, 0x21f58305, 0x594804b0, 0x10052207, + 0x8e4018b0, 0x82042007, 0x180420af, 0x670c9b43, 0x30260f14, 0x33132131, 0xa4820313, 0x3331022b, 0xbaba3352, 0xfcaa03ba, 0x4e7e8256, 0x6b820717, + 0x0f00052c, 0x010900b3, 0xb3002b04, 0x4e180105, 0x352c08aa, 0x71a40321, 0xa403cdfc, 0x0070bf01, 0x172a2d82, 0xa4030000, 0x08005e04, 0x9e421600, + 0x08124e05, 0x0001082e, 0x31302b04, 0x23012101, 0x01133703, 0xfe363782, 0x68d3fee3, 0x01a66adb, 0x036f010e, 0x0210fcf0, 0xaefd21d5, 0x4582ba03, + 0x75fe043a, 0x2b05a403, 0x97002000, 0x0f0803b3, 0x0fb02b04, 0xd013b010, 0xb01003b0, 0x6407a15d, 0x5c180c33, 0x00200c67, 0x200bfe6a, 0x200c8212, + 0x23ee8212, 0x05060cb3, 0x002a4682, 0x0601b110, 0xd002b0f4, 0x8e4505b0, 0x02b02206, 0x05496910, 0x7a16b021, 0x01222b8f, 0x1d4a2115, 0x0f8f790d, + 0xfea40323, 0x09254a73, 0x240b9479, 0xfc75a403, 0x08294ac1, 0x3f032e08, 0x06c7c075, 0x06047504, 0x02009181, 0x9000ecff, 0x0f03b803, 0x27001300, + 0x06010000, 0x022e2223, 0x27072223, 0x1e323336, 0x37323302, 0x2b119013, 0xc572b803, 0x4445584a, 0x64528133, 0x5a230982, 0x85314445, 0x2e138f09, + 0x2dc8cf02, 0x3b892d37, 0x2d382fc5, 0x874dfe90, 0x2e37230c, 0x77820090, 0x0000c52c, 0x1905e303, 0x06000300, 0xb9412100, 0xe244180a, 0x04b1210f, + 0x0805fb4c, 0x13330135, 0xe3030101, 0xb201e2fb, 0xaafef8ba, 0x1905aafe, 0x18045cfb, 0x0200e8fb, 0x96000e00, 0x27031403, 0x0b000500, 0xb0000f00, + 0x09b02f03, 0x2f01b02f, 0x502f07b0, 0x0f3f06d2, 0x17010102, 0x4d140307, 0x4601bafe, 0x507df54d, 0x4401bcfe, 0x4fe5f850, 0x4a014701, 0x86f8fa50, + 0x21978207, 0x4b828d00, 0x25039822, 0x05234b87, 0x880bb02f, 0x0101264b, 0x37273727, 0x37058503, 0x4eb8fe98, 0x2f4ef8f8, 0xf850bcfe, 0xdd0150f8, + 0xfa4db9fe, 0xb8fe4efa, 0xd7820785, 0xe1820020, 0xba00a422, 0x07200982, 0x40209782, 0xd14fe385, 0x00b02114, 0x3f07d556, 0xb0593e0f, 0x02b11004, + 0x03b0f405, 0xd006b0d0, 0xb0d007b0, 0x0bb0d00a, 0x213130d0, 0x05333523, 0x03270386, 0xfebbbba4, 0x83baba8b, 0x83ba2003, 0x68002000, 0xc9220835, + 0x35682602, 0x00412406, 0x88750100, 0x88732017, 0x0dc76517, 0xc7651783, 0x23178405, 0xf2ff0200, 0x0806395c, 0x2a00133c, 0x0ab3a000, 0x2b04160c, + 0x000c23b3, 0x1b402b04, 0x0a160a06, 0x0a360a26, 0x0a560a46, 0x0a760a66, 0x0a960a86, 0x0ab60aa6, 0x5d0d0ac6, 0xe50ad5b4, 0xb05d020a, 0x1bb11023, + 0x0682f409, 0xd01fb02f, 0xb0101bb0, 0x28b2d027, 0x12112300, 0x05004139, 0x1b2f1823, 0x5a4818b1, 0x821c2008, 0x3a66180c, 0x081b7708, 0x58450024, + 0x198226b0, 0x3e0f2635, 0x0621b359, 0xb02b0422, 0x1eb1101c, 0x14b0f406, 0x8224b110, 0x82252006, 0x18142152, 0x30235282, 0x18340131, 0x200eaa61, + 0x05364d20, 0x2b563520, 0x15500808, 0x06063521, 0x210aa601, 0x3b2f3039, 0x210c0c21, 0x39302f3b, 0xfe940a21, 0x4a2001e0, 0xe3011d48, 0x1b018bfe, + 0x7501e5fe, 0x481d1dfe, 0xcf7b8b02, 0x93525293, 0xcc7b7bcf, 0x94525294, 0x02d9fdcc, 0x4ca402a2, 0xfe758650, 0x19fe752d, 0x4c508575, 0x350b7f49, + 0x0022001b, 0xb0fc002a, 0x2cb02f2b, 0xdc00b02f, 0xf40823b1, 0xee840bb2, 0x102bb02a, 0xb0d00fb0, 0x13b22f0f, 0x00230f85, 0x8222b010, 0xb110250f, + 0x40f40c27, 0x4123be68, 0x11200530, 0x660b707b, 0x59780c66, 0x6f0d200c, 0xb32e0669, 0x04000322, 0x090bb22b, 0x39121111, 0x068413b2, 0x16b03408, + 0x011fb110, 0x1fd9b4f4, 0x5d021fe9, 0x1f081b40, 0x1f281f18, 0x1f481f38, 0x1f681f58, 0x1f881f78, 0x1fa81f98, 0x1fc81fb8, 0x25b05d0d, 0x100db0d0, + 0x820129b1, 0x072508a3, 0x27291729, 0x47293729, 0x67295729, 0x87297729, 0xa7299729, 0xc729b729, 0xb45d0d29, 0x29e629d6, 0x31305d02, 0x09394f01, + 0x23062727, 0x21101120, 0x07584932, 0x34275808, 0x06222326, 0x23100707, 0x33101122, 0x4e0e0232, 0x0e422f4e, 0xb2ba447f, 0xfeaa2b31, 0xa41701e9, + 0x546f162f, 0x0e397164, 0x52523793, 0x8d8f043a, 0x018d8e8e, 0x3894a6a2, 0xc9d52947, 0x01e801c9, 0x6062c2e9, 0x54bca068, 0x9e969779, 0x77014a8f, + 0x87fe89fe, 0x82010000, 0x03a82b02, 0x001402a4, 0x00090003, 0xe84501b3, 0x35112905, 0xa4031521, 0x6c6ca801, 0xff201e82, 0x04210882, 0x20218702, + 0x29218503, 0x21352101, 0xa2fb0204, 0x25825e04, 0x00020038, 0x03e90237, 0x001705a4, 0x0019000c, 0x0d18b374, 0xb32b040f, 0x9a5f0d0b, 0x00b12b05, + 0x07b0f40e, 0x100fb0d0, 0x09820db1, 0xfc5c1420, 0x0c974706, 0x4411a850, 0x142407bd, 0x14b11b2f, 0x0b240c83, 0x0500b110, 0x102a4882, 0xf40608b1, + 0xb01000b0, 0x7859d00d, 0x05895406, 0x3e34352b, 0x22153302, 0x05331515, 0x2e0b8921, 0xc0fea403, 0x50775029, 0xd1fdcbcb, 0x8227c2fe, 0xc9c92c09, + 0x45dae902, 0x75385c7b, 0x87bb1fdf, 0x82002008, 0x020026c3, 0x056d03ec, 0x24c38419, 0x0e01b36b, 0x24c38200, 0x040d0e0e, 0x826c832b, 0x10012abf, + 0xf40d0ab1, 0xb0100db0, 0x22798214, 0x8217b110, 0x100e240c, 0x18dc1bb0, 0x2012f74a, 0x20b5820d, 0x23b5820d, 0x070608b3, 0xb1214084, 0x83bb840b, + 0x10083c3a, 0xb0d015b0, 0x18b0100b, 0xd019b0d0, 0x21113130, 0x020e1415, 0x35323523, 0x8a252335, 0x3f01220b, 0x23b88428, 0x3e012f02, 0x0521b885, + 0x21af8319, 0xb8867437, 0x002d0883, 0x02aa0101, 0x05e902e9, 0x000c0017, 0x0f73413b, 0x69419985, 0x8207200c, 0x41072099, 0x3022104f, 0x34410131, + 0xe902290a, 0x5029c1fe, 0xcaca4f77, 0x2a092a41, 0x00010000, 0x01ec02ba, 0x821905fa, 0x41302069, 0x1941051f, 0x0d06410c, 0x3022f98c, 0xd88a1331, + 0x4001ba22, 0x89059241, 0x00002acf, 0x00000003, 0x03a4030d, 0x06e545b0, 0xdf5b3520, 0x23618305, 0x01b0d004, 0x0ed35918, 0x593e132a, 0x050506b3, + 0x0bb32b04, 0x07cc5918, 0xf4050022, 0x2a05e67d, 0x33352311, 0x21352125, 0x82ba2f02, 0x75013800, 0xa4035cfc, 0xfcbaf602, 0x75ddba5d, 0xff020000, + 0x03f0ffee, 0x84b803b6, 0x851d2067, 0x14c072b4, 0x09313035, 0xfeb60307, 0x011dfe1b, 0xfe6201e3, 0x019efe9e, 0x84d30162, 0xfee5220d, 0x2e11851b, + 0xffffff00, 0x0375fee1, 0x021905c1, 0x825a0022, 0x000223c3, 0x1583008c, 0xd282ec20, 0x8c06b822, 0x3a201582, 0x03201582, 0x2006796e, 0x2b7f8201, + 0x05a403e5, 0x00030037, 0x03b00013, 0x0aab6e18, 0x593e0f22, 0x0131bf82, 0xa4030127, 0x035ebcfc, 0xfaf80446, 0x16053ced, 0x06f15300, 0x2f05ac26, + 0x99003500, 0xe25caf85, 0x0ce04508, 0x011a8308, 0xb32b041b, 0x04120111, 0x1011b02b, 0xb0d000b0, 0x0db11006, 0xd9b4f406, 0x020de90d, 0x081b405d, + 0x280d180d, 0x480d380d, 0x680d580d, 0x880d780d, 0xa80d980d, 0xc80db80d, 0xb05d0d0d, 0x1fb11026, 0x1b40f406, 0x1f171f07, 0x1f371f27, 0x1f571f47, + 0x1f771f67, 0x1f971f87, 0x1fb71fa7, 0x5d0d1fc7, 0xe61fd6b4, 0xb05d021f, 0x2bb0101b, 0x101ab0d0, 0xb0d02db0, 0x34b01012, 0x113130d0, 0x33033e33, + 0x27651632, 0x07062a05, 0x06211521, 0x14141514, 0x20088217, 0x09144e16, 0x022e7608, 0x33352327, 0x34353426, 0xa6233734, 0x89603c0e, 0x33bb8b5a, + 0x5c841c79, 0x011b8964, 0x02f4fe00, 0xff0c0102, 0x648b1900, 0x791c845c, 0x5a8bbb33, 0x0e3e6089, 0x02029aa4, 0x625a039a, 0xb04a7faa, 0x9b7b1fbc, + 0x1671b0b0, 0x2d18192f, 0xaeb27117, 0xbc217b9e, 0xac7d4ab1, 0x2f177162, 0x16311716, 0x00010000, 0x029600c7, 0x0027035c, 0x00090005, 0xb02f03b0, + 0x07bd4801, 0x5c020728, 0x01b9fe4e, 0xb0484e47, 0x01002308, 0x2d824801, 0x2503dd22, 0x05202d85, 0x9f482d85, 0xdd022605, 0xf750bbfe, 0x089248f7, + 0x02000023, 0x2a008200, 0x2b055e04, 0x1b001700, 0x55b0bf00, 0x1c20057f, 0x34073f4e, 0x03b0d007, 0x0c1bb110, 0xd014b0f4, 0xb0101db0, 0x18b1dc16, + 0x0642510c, 0x590c1156, 0x06200c87, 0x200be274, 0xe3781814, 0x0cbd7f0b, 0x10143608, 0xf40604b1, 0xb0d005b0, 0x11b1100a, 0xd9b4f406, 0x0211e911, + 0x081b405d, 0x28111811, 0x48113811, 0x68115811, 0x88117811, 0xa8119811, 0xc811b811, 0xb05d0d11, 0x2e858202, 0xd017b0d0, 0xb0d018b0, 0x19b01005, + 0x821ab0d0, 0x1810200b, 0x2008a24e, 0x0ffd4a11, 0x11212108, 0x21112133, 0xfb5e0411, 0xd3d3d3a2, 0x422fc8c7, 0x2b401c16, 0x2f028383, 0xfea4fed3, + 0xba02755a, 0x2509f54a, 0xba02d1fc, 0x154146fd, 0x000f240a, 0x41b2001b, 0x1d281215, 0xdc0eb010, 0xf40c10b1, 0x73071f41, 0x15410769, 0x0c08410c, + 0x1b2f1722, 0x09e24b18, 0x200c0841, 0x08084117, 0x0e2cdc82, 0xd00fb0d0, 0xb0d010b0, 0x14b1100a, 0x26e66a18, 0x20090841, 0x13084110, 0x21331123, + 0x05b45011, 0x23153322, 0x2c090841, 0xd33b8767, 0x4c16a4fe, 0xd383833e, 0x050641d3, 0xfb11122d, 0x0433046d, 0x7591810a, 0x670046fd, 0x022f0563, + 0x001905e9, 0xb34b0013, 0x04050e01, 0x8201b02b, 0xf40a2bac, 0xf40e00b1, 0xb01004b0, 0x7b83d007, 0x83d00921, 0xd00b240b, 0x5f1001b0, 0x00210626, + 0x82c58310, 0xd011210e, 0x2408556c, 0xb11b2f0c, 0x06556c0c, 0x37231726, 0x11173507, 0x2206596c, 0x6c112715, 0x5f6c085d, 0xeded2b05, 0xf00e9c01, + 0x0c6e0ef0, 0x646cd901, 0x0e703905, 0x000c27fe, 0x01750101, 0x022f0281, 0x0003003b, 0x00b00009, 0x2f02b02f, 0x34052545, 0xbaba2f02, 0x00ba8101, + 0xfe2e0201, 0x006e038e, 0x000c00bb, 0x12d54541, 0x0e20a383, 0x5b06e246, 0x0b200c51, 0x0b239e82, 0x47593e0f, 0x30210a95, 0x0bbf4631, 0x452e0221, + 0xbb2007e7, 0x2707b646, 0x00000200, 0x6d038efe, 0x19226d84, 0x65477900, 0x085e4721, 0x14207b8c, 0x14217b82, 0x06815411, 0xb0258887, 0xb0584500, + 0x20198218, 0x20958218, 0x1d2e48b0, 0x73473520, 0x88bb8828, 0x00240808, 0xecff0700, 0x5c04dbff, 0x03002f05, 0x1b000f00, 0x33002700, 0x4b003f00, + 0x0ab38501, 0x2b04100a, 0x280a22b3, 0x2e220582, 0x05821c09, 0x400a3a22, 0x46220582, 0xf54b3409, 0xb4240826, 0x22c622b6, 0x17405d02, 0x22162206, + 0x22362226, 0x22562246, 0x22762266, 0x22962286, 0x5d0b22a6, 0xe522d5b4, 0xb0282082, 0x16b01022, 0x2f16b0d0, 0x18245b61, 0x24243d6c, 0xea40dab4, + 0x087a8240, 0x40091b2b, 0x40294019, 0x40494039, 0x40694059, 0x40894079, 0x40a94099, 0x40c940b9, 0x46b05d0d, 0xdc4db010, 0x2f01b000, 0xb02f31b0, + 0x05c04649, 0x2d641320, 0x09f87306, 0x593e1526, 0x1f012bb3, 0x0d30fa82, 0x2b041901, 0xb11013b0, 0xb4f40107, 0x07e907d9, 0x08396183, 0x28071807, + 0x48073807, 0x68075807, 0x88077807, 0xa8079807, 0xc807b807, 0x24618207, 0x25b11031, 0x51601801, 0x1fb03125, 0xd037b010, 0xb01025b0, 0x2bb0d03d, + 0xd043b010, 0x21054347, 0x67603405, 0x25362808, 0x32333634, 0x54141516, 0x14230a93, 0x8c323316, 0x96252017, 0x98022b2f, 0x0266c8fd, 0x2fddfe3d, + 0x00823133, 0xfe2f3333, 0x676662d8, 0x66676262, 0x2f620262, 0x31313233, 0x20138232, 0x830f83d7, 0xcf022317, 0x2682342f, 0x2f343124, 0x2787d7fe, + 0xfafc0438, 0x230529df, 0x565640f4, 0x56563f40, 0x9393693f, 0x94946869, 0x108e1afd, 0x0f8e6820, 0x20086f4e, 0x086f4ecb, 0x4f74d620, 0x7417830c, + 0x17860567, 0x00c5ff27, 0x06e30300, 0x742f88c7, 0x8c200d7f, 0x2f851782, 0x478c8c20, 0x1788c920, 0x2506e74e, 0x0000ba00, 0x4784e902, 0x74002a21, + 0xaa200bc7, 0xfc221782, 0x2f82cb06, 0x77861785, 0x5f832f86, 0x5f871785, 0xc9204785, 0x474f2f88, 0xffdf2407, 0x84c703e9, 0x052f4f5f, 0xff20a786, + 0xcb201785, 0x84080f75, 0x0200215f, 0x002d0182, 0x3f056804, 0x30000400, 0xb0002000, 0x05744200, 0x083d4018, 0x58450028, 0x1b2f14b0, 0x424914b1, + 0x06142805, 0x0e011207, 0x4e222303, 0xbe6705cf, 0x021e2409, 0x823e3233, 0x175d0803, 0x1e141506, 0x93330302, 0x3b020275, 0x6450390e, 0x393a1e38, + 0x391f1e3c, 0x441a3536, 0x273d6783, 0x2454794e, 0x1d393e46, 0x403f3e20, 0x926d9323, 0x05452f19, 0x0aa6953f, 0x66fc0a01, 0x52717a2b, 0x10101510, + 0xba7b1017, 0x964a5cd7, 0x130e4c76, 0x1014110e, 0x2b8b7b85, 0xff3b4e58, 0x20c586ff, 0x86c588c9, 0x310021f5, 0x1d76f582, 0x41362005, 0x17850c55, + 0x2f82cb20, 0xe5411785, 0x202f8408, 0x841788c9, 0x01002147, 0x22056d41, 0x1800a403, 0x54200348, 0xb12b0f2a, 0xb0f40602, 0x04b11006, 0x18b0f403, + 0x251d0348, 0xfc79b602, 0x6b8200d1, 0x03aa2c08, 0x05fc02f4, 0x00050058, 0x01b0000c, 0x2f03b02f, 0x302f05b0, 0x27070131, 0x02012707, 0xf6f235fc, + 0x04290135, 0xcfcd4339, 0x82230141, 0x044e372f, 0x054e032f, 0x00130000, 0x11b3000f, 0x2b040202, 0x07020cb3, 0x32822b04, 0x2c11fe52, 0x399c5a4e, + 0x26363748, 0x5c503f67, 0x2c09829a, 0x40662735, 0x259ecd04, 0x2f6f252b, 0x2005829c, 0x28818371, 0x025204ba, 0x00c304e9, 0x20ef8203, 0x0a7d4eb3, + 0xfde90228, 0x042f02d1, 0x75827152, 0x4604b626, 0x0605f002, 0x0f212182, 0x249f8200, 0xb32f09b0, 0x857b8307, 0x37273775, 0x37323316, 0xa875f002, + 0x5e4e75a8, 0x045e7171, 0x4c7474ba, 0x5d825e5e, 0x04750127, 0x052f025e, 0x205d8219, 0x084f6819, 0x27055d42, 0xb11b2f02, 0x593e1502, 0x2c092d47, + 0x00bb5e04, 0x04f20002, 0x05b40208, 0x28e182cb, 0xb33a001f, 0x041a0a0a, 0x242c582b, 0x17b3002a, 0x2b040f02, 0x1d0205b3, 0x7a055d70, 0x0e270709, + 0x2e222302, 0x7a143702, 0x232a1201, 0x2f2f523d, 0x5a223e52, 0xd2793750, 0xe9042b05, 0x233e5130, 0x30513e23, 0xff79522f, 0x22178305, 0x82505038, + 0xf20031cb, 0x2f028dfe, 0x09000000, 0x00b32300, 0x2b04070d, 0x20052b4c, 0x20c88204, 0x072b4704, 0x0c820820, 0x830f0821, 0x790520d5, 0x332f0720, + 0x58522f02, 0x2973ca93, 0x755f5893, 0x820029d5, 0x04aa3fe3, 0x05640300, 0x00030077, 0x000f0007, 0xb02f02b0, 0x00b02f06, 0x2f04b02f, 0x23013130, + 0x03833313, 0x8daa0231, 0xd1fdba8d, 0x04bb8b8b, 0xfe770100, 0x82770189, 0x02360883, 0x0385fef0, 0x002700fc, 0xb334000c, 0x04030a09, 0x061b402b, + 0x26091609, 0x46093609, 0x66095609, 0x86097609, 0xa6099609, 0xc609b609, 0xb45d0d09, 0x09e509d5, 0xa8825d02, 0x5c826283, 0x26222108, 0x37363435, + 0x14150617, 0xfc033316, 0x27358f7d, 0x506d3225, 0x667d85fe, 0x27235c40, 0x60484c2d, 0x3b1a9542, 0x17370209, 0xfefc0237, 0x35d7fed7, 0x1005f2f6, + 0x2001e4fe, 0x00cbcf44, 0x75010200, 0xe7410482, 0x00072205, 0x0da84e1d, 0x820c3a69, 0x23032882, 0x35231303, 0x572d0233, 0x052e054d, 0x0356fc19, + 0xbae7faaa, 0xba000200, 0x7f6a4803, 0x00232608, 0xb02f01b0, 0x052c4205, 0x200c7058, 0x06b35704, 0x23204b85, 0x022e4f82, 0x2b6728e9, 0x2b652bba, + 0x2ffe1905, 0x0383d101, 0x0101002d, 0x028bfe37, 0x0098ff62, 0x44130003, 0x7c1808d3, 0x052d09b5, 0x02132303, 0x547fac62, 0x01f3fe68, 0x38be820d, + 0x9100d9ff, 0x8504cd03, 0x35002100, 0x36b08500, 0x2f37b02f, 0xb0dc04b0, 0x06074836, 0x1004b027, 0xf40822b1, 0xbb8218b4, 0xb0440823, 0x2cb11016, + 0x1b40f40c, 0x2c162c06, 0x2c362c26, 0x2c562c46, 0x2c762c66, 0x2c962c86, 0x2cb62ca6, 0x5d0d2cc6, 0xe52cd5b4, 0x005d022c, 0xb02f09b0, 0x1ab02f11, + 0x2f21b02f, 0x0d0331b3, 0x1db32b04, 0x2b042706, 0x2108df82, 0x15161607, 0x17070614, 0x06062707, 0x27262223, 0x26372707, 0x37343526, 0x36173727, + 0x17163233, 0x54540337, 0x75cd3e0f, 0x2f353531, 0x3d735073, 0x9e5e5c9e, 0x734e733d, 0x7562312f, 0xb87f754e, 0x753b9e5c, 0x4549184a, 0x3704260f, + 0x5ca03e74, 0x2428835c, 0x35312f71, 0x3f29822f, 0xb95c9c3d, 0x774e767f, 0x752f3667, 0x875004fe, 0x67393967, 0x87505087, 0x62373762, 0x02000087, + 0x220a377f, 0x501b0007, 0x06231345, 0x7f00b02f, 0x35260645, 0x02331123, 0x00828a17, 0xe902ba28, 0x00ea02ba, 0x02820100, 0x1803a421, 0x351e1d7e, + 0xe9021b00, 0x2505c101, 0x60001b00, 0x04090ab3, 0x0ab02b04, 0xc365b010, 0x10042805, 0xb0d008b0, 0x82b02f08, 0x52102008, 0x182006eb, 0x2306aa55, + 0x0b0208b3, 0x73082b82, 0x13b11018, 0xd9b4f402, 0x0213e913, 0x081b405d, 0x28131813, 0x48133813, 0x68135813, 0x88137813, 0xa8139813, 0xc813b813, + 0x305d0d13, 0x07140131, 0x06060706, 0x33353307, 0x37352115, 0x26343536, 0x23152223, 0x17323334, 0x21c10116, 0x45193b11, 0xfe62932d, 0x372ffc6b, + 0xd9667329, 0x04423754, 0x1d2d377f, 0x2f3f1735, 0xf04ea449, 0x2523292f, 0x3129e88a, 0xff2fd682, 0x01dd02fe, 0x002305b2, 0xb3930021, 0x8212091e, + 0x861e2089, 0xdab424b5, 0x8312ea12, 0x12093e8b, 0x12291219, 0x12491239, 0x12691259, 0x12891279, 0x12a91299, 0x12c912b9, 0x12b05d0d, 0x05f25c10, + 0x1220b223, 0x0886561e, 0xdb821b20, 0x3e151b34, 0x0310b259, 0x03b02b03, 0x0208b110, 0x101bb0f4, 0xe18314b1, 0x78181420, 0x20222273, 0x80561003, + 0x06142505, 0x37272223, 0x26050745, 0x35232627, 0x84343532, 0x493720e9, 0x440805bf, 0xb2011607, 0x19cc5c73, 0x296c0f6a, 0x4311213a, 0x6970586a, + 0x5c5a3f40, 0x034c4269, 0xcb6b458d, 0x20327b0e, 0x640a0a38, 0x6a7b4a42, 0x485c3338, 0x0035234c, 0x02000001, 0x058501e9, 0x00100019, 0x090fb328, + 0x050b6a03, 0x97410d20, 0x07864f06, 0x0210b323, 0x2d198200, 0x02b01010, 0x013130d0, 0x11333521, 0x80820606, 0x82023e21, 0x33210809, 0xdffe8501, + 0x4a60145a, 0x2438431f, 0xe9025a6d, 0x3322015b, 0x361c634a, 0x2bfe304b, 0x00000400, 0x07d151ff, 0x00142008, 0x00260023, 0x2f27b0ab, 0xb02f28b0, + 0x03b0dc22, 0x2f03b0d0, 0xb01027b0, 0x07b0d007, 0x8211b02f, 0xb1102905, 0xb0f40913, 0x18b11022, 0x1c230682, 0x821cb0d0, 0xb0103228, 0x18b0d01d, + 0xd024b010, 0x220725b2, 0xb2391211, 0x52068426, 0xa9690820, 0x395f180c, 0x07355e0c, 0x0224b329, 0xb32b0419, 0x78040214, 0x06250559, 0x0108b2d0, + 0x061b5e03, 0xf4021736, 0xb01024b0, 0x19b0d01e, 0xd020b010, 0xb01017b0, 0x23b0d022, 0x90062b4b, 0x2dfe82ee, 0x13352335, 0x15331133, 0x27331523, + 0x91520735, 0x3dfe2106, 0x2c0c0741, 0x5ce1fe1f, 0x5a6ff4fa, 0x77c35a5a, 0x05ac5204, 0x41b2fd21, 0xfc370b1b, 0x4b3c5abc, 0xc3fe4e01, 0x9f983c5c, + 0x0003009f, 0x03e5ff00, 0x823705a6, 0x001f3409, 0xb0880030, 0x32b02f31, 0xdc0eb02f, 0xb0d000b0, 0x6eb0100e, 0x0e250543, 0x0908b110, 0x06d765f4, + 0xb0100827, 0x31b0d014, 0x24ac8210, 0xb02f23b0, 0x24b5822d, 0x092fb110, 0x081941f4, 0x1b2f2d25, 0x4e152db1, 0x19410609, 0x820f200c, 0x0f200819, + 0xb3593e0f, 0x0417021c, 0x0230b32b, 0xb02b0420, 0x0bb1100f, 0x30b0f402, 0xd022b010, 0x030124b2, 0x23057842, 0x13012701, 0x421b6543, 0x0e410e0f, + 0x215e2a06, 0x46183c10, 0xfe62942d, 0x097b436a, 0x41dffd21, 0x16410b23, 0x5ffc3606, 0x351d2d38, 0x4a2f4016, 0x30ef4ea4, 0x89252229, 0x013129e7, + 0x0d474208, 0x42feff21, 0x21290647, 0x34002500, 0x0f013700, 0x3f5d18b0, 0xd0122808, 0xb12f12b0, 0x74f4091e, 0x88442495, 0x0ead4306, 0x1039b037, + 0xb0dc33b0, 0x25b0d025, 0x1033b02f, 0xf40929b1, 0xb0d02db0, 0x310c832d, 0xb0d02eb0, 0x35b01029, 0x1236b2d0, 0x39121133, 0x068437b2, 0x2a830020, + 0x58450023, 0x07e343b0, 0x0c83b020, 0x1b2f2325, 0x410f23b1, 0x5d5a0672, 0x02352708, 0xb32b042a, 0x61430208, 0xdc102106, 0x34320344, 0xb11026b0, + 0xb0f40228, 0x2fb01035, 0x102ab0d0, 0xb0d031b0, 0x26b58228, 0xd034b0d0, 0x44013130, 0x0123211f, 0x42130127, 0x354410bd, 0xf2012718, 0x035ebcfc, + 0xc7425c46, 0x1748440a, 0xfa1d0128, 0x16053ced, 0xd142c9fa, 0xff02390c, 0x0300008b, 0x001905cf, 0x001d0010, 0x2f1eb088, 0xb02f1fb0, 0x1eb0dc00, + 0x08088f78, 0x00b0d035, 0x0c11b110, 0x11dab4f4, 0x5d0211ea, 0x11091b40, 0x11291119, 0x11491139, 0x11691159, 0x11891179, 0x11a91199, 0x11c911b9, + 0x06b05d0d, 0x0c1ab110, 0x5915b0f4, 0xdc420b22, 0x2f053d07, 0x0f05b11b, 0x0ab3593e, 0x2b040706, 0xb1100bb0, 0xb0f40614, 0x16b0100a, 0x1007b0d0, + 0x2305de53, 0xf4061ab1, 0x27068d66, 0x35231121, 0x32211133, 0x07597118, 0x23153322, 0x4a080d82, 0x3ccf0312, 0xfe81bf7a, 0x01a6a658, 0x79bf89a8, + 0xacc18935, 0xfefee1fe, 0xc1ac1f01, 0xed878d02, 0x5e0266b3, 0x6b460275, 0x0181ecb4, 0xfe170100, 0x17fe752f, 0x00001801, 0x00620001, 0x0344036d, + 0x000b004e, 0x09b0000f, 0x4c0bb02f, 0x2308080c, 0x01070209, 0x01012701, 0x03010137, 0x01ddfe44, 0xdffe5023, 0x014eddfe, 0x4edffe21, 0x21012301, + 0xdefe0003, 0x23200f83, 0x01220484, 0x23834e22, 0xffffff22, 0x24052157, 0x002602c7, 0x090f4d3a, 0x0002003a, 0x03000031, 0x001905a2, 0x0012000a, + 0x2f13b074, 0xb02f14b0, 0x13b0dc00, 0x0eaf6f18, 0xb1100024, 0x6a18080b, 0x042026e8, 0x09524c18, 0x080c3a57, 0x1b2f0422, 0x3e0f04b1, 0x0610b359, + 0xb32b0402, 0x040d0609, 0x0131302b, 0x11232110, 0x11331123, 0x34032033, 0x33080a82, 0x03363233, 0xf40cfea2, 0x01f48989, 0x97fe8bf4, 0xb5b4f4f4, + 0x8bfe9802, 0x1905ddfe, 0x8cfef3fe, 0x8300fefe, 0xecff0200, 0xb603e9ff, 0x20005c05, 0xc2003000, 0x1806db44, 0x2e07a86a, 0xb01032b0, 0x01b2dc0f, + 0x12110f17, 0x841cb239, 0x21b12206, 0xfd6a180c, 0x10172126, 0x2a574e18, 0x924a0820, 0x07104f05, 0x1401b223, 0x84738408, 0x2cb12206, 0x25016606, + 0x1331302c, 0x27262637, 0x37171637, 0xde6d0717, 0x34352408, 0x83243636, 0x6d072017, 0xe92e0ce8, 0x2f5629a0, 0x9066752d, 0x8750794e, 0xe86d3760, + 0xcb742b05, 0x299c1001, 0x01b74779, 0xf16d10f6, 0x0321080a, 0x2316a0d1, 0x352d7510, 0x337b508f, 0x70bb9b7f, 0x4e92cf81, 0xa269b8c1, 0x4619547a, + 0xfeb62f6e, 0x0cfc6d98, 0x2a085f59, 0x00260254, 0x0000005a, 0x828b0006, 0x00023305, 0x038bfe31, 0x001905a6, 0x00210012, 0x2f22b0ec, 0xf78223b0, + 0x22b0dc34, 0xd009b010, 0xb12f09b0, 0xb0f40c08, 0x0cb2d00b, 0xfd820009, 0x1000b025, 0x180813b1, 0x2326aa7a, 0x1ab01008, 0x56068043, 0x0e240c9d, + 0x0eb11b2f, 0x2007534f, 0x200c8208, 0x3b531808, 0x1d290810, 0x1b40f401, 0x1d171d07, 0x1d371d27, 0x1d571d47, 0x1d771d67, 0x1d971d87, 0x1db71da7, + 0x5d0d1dc7, 0xe61dd6b4, 0xb25d021d, 0x05926707, 0x100e2e08, 0xf40118b1, 0xe918d9b4, 0x405d0218, 0x1818081b, 0x38182818, 0x58184818, 0x78186818, + 0x98188818, 0xb818a818, 0x0d18c818, 0x0e0cb25d, 0x05ad4618, 0x020e1423, 0x067b7023, 0x0a3a5318, 0x1611073f, 0x023e3233, 0x7842a603, 0x7d966eb1, + 0x967d8989, 0x447bb06a, 0x7f522b8b, 0x77779c52, 0x3d06829c, 0x6dd1012b, 0x634883b2, 0x8e0641fe, 0x45623ffe, 0x5271b47f, 0x7f3a6489, 0x39810cfe, + 0x6f528b67, 0x52362008, 0xd82e083f, 0x73010000, 0x0000ffff, 0x7503e9ff, 0x4618c204, 0xd8210809, 0x522c8200, 0x7920066d, 0xd9202d88, 0x05212d8b, + 0x3d2d8805, 0x00ff00d9, 0xfec5ff02, 0x056f0485, 0x00130019, 0xb37f0016, 0x04030a10, 0x03dab42b, 0xf78303ea, 0x19030939, 0x39032903, 0x59034903, + 0x79036903, 0x99038903, 0xb903a903, 0x8203c903, 0x030622f7, 0x25f78210, 0xb01010b0, 0x274ddc18, 0x071b5708, 0x0cfc9118, 0x0a250c84, 0x0ab11b2f, + 0x069d460f, 0x0c820e20, 0x0c820e20, 0x0314b329, 0xb22b0408, 0x410c000b, 0x664e0542, 0x23410805, 0x23032103, 0x06013301, 0x33161415, 0x04030301, + 0x1f907d6f, 0xfd7b4817, 0x019379fc, 0xb201bab2, 0xfe506d31, 0xfedbdb3f, 0x30667d85, 0x75011d4b, 0x19058bfe, 0x4c2de7fa, 0x0f036048, 0x5ffda102, + 0x3fd78200, 0x0385fefe, 0x00ba03fc, 0x00440033, 0x0c42b3f5, 0xb32b0417, 0x040e0a03, 0x100eb02b, 0xf40800b1, 0xc36c0682, 0x100e2406, 0x83d021b0, + 0x3929080e, 0x061b40d0, 0x26421642, 0x46423642, 0x66425642, 0x86427642, 0xa6429642, 0xc642b642, 0xb45d0d42, 0x42e542d5, 0xb0005d02, 0x05ca4307, + 0xc5822e20, 0xcc512e20, 0x20ec840f, 0x06aa600d, 0xf1430c84, 0x1cb32307, 0xec823d06, 0x2e070f22, 0x4e08ec82, 0xb1102eb0, 0xb4f40627, 0x27e927d9, + 0x1b405d02, 0x27182708, 0x27382728, 0x27582748, 0x27782768, 0x27982788, 0x27b827a8, 0x5d0d27c8, 0xb11014b0, 0x40f40634, 0x1734071b, 0x37342734, + 0x57344734, 0x77346734, 0x97348734, 0xb734a734, 0x8234c734, 0x34d6389c, 0x5d0234e6, 0xb0103db0, 0x3ab0d03a, 0x2131302f, 0x14150606, 0x41153316, + 0x35200654, 0x220a266a, 0x1817021e, 0x2b0f0e65, 0x023e3201, 0x26263535, 0x020e2223, 0x03333682, 0x6d1d1773, 0x1e8f7d50, 0x5b243c17, 0xb92d6464, + 0x188f58be, 0x22151765, 0x185602fe, 0x320a0f65, 0x48233f17, 0x667d5a60, 0x9c1d4b30, 0x172b442d, 0x1858858e, 0x20152065, 0x196518fc, 0xffff2d0d, + 0xe9ffecff, 0xc706ac03, 0x24002602, 0x42097746, 0x812206e5, 0x17825305, 0x46184420, 0xac220e9f, 0x2d88cb06, 0x20079d53, 0x22458200, 0x88570581, + 0x00d6212d, 0x5b865a82, 0x2d888c20, 0x1343da20, 0x0581220a, 0x822d8819, 0x89898817, 0x8cdf205b, 0x205b892d, 0x275b83df, 0x00003100, 0xcf06cf03, + 0x25204382, 0x2d83b784, 0x03007723, 0x2b898200, 0x19052904, 0x26001600, 0xd9002a00, 0x24094163, 0xb0f40c01, 0x07416f2b, 0xb0100125, 0x82b0d012, + 0x43631805, 0x2f12262f, 0xb02f1ab0, 0x058a4228, 0x0c3f6318, 0x1b2f2724, 0x781827b1, 0xa4420c55, 0x59631814, 0x06292542, 0x213130f4, 0x21346318, + 0x03012a08, 0xe9021123, 0x3b752f89, 0x35638f5a, 0x5a8f6335, 0xba2f753b, 0x2f894301, 0x603d3c6c, 0x42232342, 0x5c7b3d60, 0x6554c901, 0x3c631856, + 0x3f04281b, 0xd1012ffe, 0x49ffff00, 0x250807df, 0xec000602, 0x02000000, 0xe9fffeff, 0x19052d04, 0x2c001c00, 0x2db00901, 0x2f2eb02f, 0xb1dc02b0, + 0xb0f40803, 0xb34c102d, 0x10032506, 0xb0d014b0, 0x18260582, 0x1002b0d0, 0x0b841ab0, 0xb0d01d2a, 0x25b1100c, 0x1b40f40c, 0x2415276c, 0x25c625b6, + 0x07246c0d, 0x6905a152, 0xbc640c1a, 0x0c50740c, 0x1b2f0733, 0x3e0f07b1, 0x061cb359, 0xb02b0400, 0x2ab11007, 0x39668206, 0x2a172a07, 0x2a372a27, + 0x2a572a47, 0x2a772a67, 0x2a972a87, 0x2ab72aa7, 0x66822ac7, 0xe62ad62e, 0xb25d022a, 0x112a0704, 0x11b03912, 0x2a935818, 0x20111422, 0x2d055047, + 0xb0d015b0, 0x17b0101c, 0x013130d0, 0x9b411123, 0x2335280f, 0x33353335, 0x18013315, 0x230cd464, 0x8aba2d04, 0x0ed56418, 0xba8aba26, 0x8b3bbcfe, + 0x0ad76418, 0xfce90323, 0x0c9e4117, 0xbb759927, 0x416dfebb, 0xdc64183a, 0x534d1809, 0x02362908, 0x00260026, 0x00070000, 0x2806ab46, 0xe9fffcff, + 0xc204ae03, 0x2b4b1802, 0x43d82007, 0x7322083b, 0x2d887906, 0x8506ab46, 0x0505212d, 0xd9202d88, 0x2f592d8a, 0x06c54309, 0x4b182d86, 0x17820945, + 0x00010035, 0x0485fe31, 0x00190500, 0xb37b0018, 0x04070c10, 0x4615b32b, 0xb02528dd, 0x0bb01010, 0x08d646d0, 0x1b2f0824, 0x514308b1, 0x0c667107, + 0x085e6318, 0x0e060d30, 0x08b02b04, 0x060ab110, 0x1006b0f4, 0x068210b1, 0x55d01121, 0x2120083a, 0x2005d67d, 0x55078315, 0x04350546, 0x1e8f7d00, + 0x0308fd17, 0x0247fd42, 0x02fefd02, 0x6c3102b9, 0x06d34650, 0x67190521, 0x7321058d, 0x055b5502, 0xff024008, 0x0385fefc, 0x00ba03ae, 0x00300027, + 0x0a03b3bd, 0xb42b040a, 0x0aea0ada, 0x1b405d02, 0x0a190a09, 0x0a390a29, 0x0a590a49, 0x0a790a69, 0x0a990a89, 0x0ab90aa9, 0x5d0d0ac9, 0x030a0db2, + 0x46391211, 0x192008b4, 0x1920ca82, 0x0cc46818, 0x4f079447, 0x28220898, 0x924f1e06, 0x276a7d05, 0x8818b020, 0x1a6f0d6a, 0x3130221c, 0x0c974625, + 0x0ac64118, 0x15021e23, 0x07936221, 0x9f420320, 0x02072c05, 0x6d191693, 0x17907d50, 0x182b2b12, 0x2a0b8666, 0xba0fdbfc, 0x29a46995, 0x18025e60, + 0x22079066, 0x46421602, 0x2923057b, 0x18071d42, 0x2d0b9466, 0x4056b094, 0xe8018342, 0x502b9699, 0xa3424371, 0x42cb2008, 0xdf450875, 0x06474206, + 0x09a34d18, 0x3b46df20, 0x06d72108, 0x28252d83, 0x07000000, 0x06694600, 0xfefeff26, 0x05730375, 0x48202d83, 0x06201782, 0x69461782, 0x06d72207, + 0x855b8279, 0x07d1422d, 0x05202d85, 0x2d851782, 0x5b8ad920, 0x2d888c20, 0x8507d142, 0x8819202d, 0x0697462d, 0x038bfe25, 0x862f05d7, 0x0006222d, + 0x207782e2, 0x24878603, 0x000300d3, 0x0dfb7f23, 0xb0d01933, 0x34b02f19, 0xdc04b010, 0x041900b2, 0xb2391211, 0x21068402, 0x665619b0, 0x06086129, + 0xb1100434, 0xb0f40813, 0x13b0d021, 0xd024b010, 0x2f01b000, 0x7b4600b0, 0x2f222405, 0x4222b11b, 0x1e200751, 0x1e200c82, 0xc64d0c87, 0x00b02507, + 0x13b05845, 0x8406cf7a, 0x8216200c, 0x1639080c, 0xb3593e0f, 0x04090410, 0x1016b02b, 0xf4062fb1, 0x2f071b40, 0x2f272f17, 0x2f472f37, 0x2f672f57, + 0x2f872f77, 0x2fa72f97, 0x2fc72fb7, 0xd6b45d0d, 0x022fe62f, 0x1614b25d, 0x21c9822f, 0x3f491eb0, 0x21b22329, 0x5f4a271e, 0x33012b05, 0x0e140103, + 0x26222302, 0x66183727, 0x01282299, 0x6012011b, 0x42a001ba, 0x249f6618, 0x015e0428, 0xfb8bfe75, 0x661860ac, 0x81421fa6, 0x4229200c, 0x002b0b53, + 0x03000031, 0x02cd0673, 0x88490026, 0x75250817, 0x77ff0200, 0x2f040000, 0x13001905, 0x99001700, 0xb02f18b0, 0x04b02f19, 0xd000b0dc, 0xb11004b0, + 0xb0f40805, 0x0b5f4d18, 0xb010092f, 0x08b0d00d, 0xd00fb010, 0xb01005b0, 0x20058411, 0x20118414, 0x7b691816, 0x2f122413, 0x4412b11b, 0xb44107de, + 0x5a08200c, 0xb32f0697, 0x04020101, 0x0614b32b, 0xb02b0406, 0x7db01002, 0x0c2705eb, 0x1001b0d0, 0x83d010b0, 0xd0152611, 0x33013130, 0x09277b15, + 0x33353338, 0x33352115, 0x11211103, 0xbcbc7303, 0x89d1fd8a, 0x0289baba, 0x09828a2f, 0x71480437, 0x5c0229fc, 0xd703a4fd, 0xd1d1d171, 0x0601b8fd, + 0x0000fafe, 0x21e78301, 0xe7827303, 0xaf001b23, 0x08437bb0, 0xdf820120, 0xc5471c20, 0x0bb12506, 0x0cb0f40c, 0x0b257484, 0xd012b010, 0x250582b0, + 0x17b2d016, 0xf856000c, 0x0c945508, 0x6e0cee44, 0x9e620c9a, 0x10b32307, 0xd4820d01, 0xb1101922, 0x27d26718, 0x1010b02a, 0xb0d013b0, 0x15b0100d, + 0x00207982, 0x12c06318, 0x21066447, 0x67182315, 0xba260ee6, 0xbbbb89ba, 0x6718fe63, 0x03360bea, 0xbbbb70ee, 0x01ccfe70, 0x0085fe00, 0x4e00ffff, + 0x4e030000, 0x9b5f7306, 0x4ad72008, 0x1784067b, 0x82ff0421, 0x00d52617, 0x00060000, 0x202c82d7, 0x05735eff, 0x88360621, 0x066d472d, 0x04211785, + 0x472d88c2, 0xb626056d, 0xf0020000, 0x2d887906, 0x20069b44, 0x21178400, 0x2d880505, 0xff00d938, 0xba000100, 0x750385fe, 0x17001905, 0x10b38200, + 0x2b040908, 0x3f4714b3, 0x06b22328, 0x90411403, 0x05234405, 0x3019174e, 0xb11b2f12, 0x593e0f12, 0xb11006b0, 0xb0f40608, 0x0541470c, 0xb0d00e2b, + 0x08b0d00f, 0xd010b010, 0x0b4647b0, 0x1133353e, 0x15213523, 0x15331123, 0x16141506, 0x7d750333, 0xfe171f90, 0x02d3d31c, 0x31d2d22f, 0x3005935c, + 0x751d4b30, 0x75752f04, 0x2d75d1fb, 0x0060484c, 0x28cb8802, 0x00190015, 0x0e0eb3a4, 0x20cd8208, 0x20cdab12, 0x26cd8212, 0xb1100eb0, 0x83f40809, + 0xd00b2595, 0x0e0817b2, 0x17251383, 0x0816b12f, 0x082948f4, 0x180cfc6f, 0x480cb046, 0x10200c36, 0x1020f582, 0xef82f591, 0x3648f884, 0x87ef8509, + 0x230122ed, 0x21f18a35, 0xf0845d01, 0xbababa22, 0x24063548, 0x75ba0275, 0x24f385fc, 0x00bb7f05, 0x071f42ff, 0x08090162, 0x0000da2c, 0x02007301, + 0x75fe0000, 0x1905a403, 0x1c001000, 0x1db06700, 0x2f1eb02f, 0xb1dc0bb0, 0xb0f40c08, 0x14b0101d, 0x2f14b0d0, 0xd6841bb1, 0xb0584522, 0x11bd4518, + 0x20072b44, 0x20c68211, 0x31c68211, 0x0e0603b3, 0x11b02b04, 0x0613b110, 0x1017b0f4, 0x068215b1, 0x3b05d268, 0x1bb01013, 0xd01cb0d0, 0x16053130, + 0x3e323316, 0x33113502, 0x23021411, 0x21012722, 0x3109cc41, 0x7f310001, 0x3d735c48, 0xd9d38917, 0x85017bd3, 0xd041d1fd, 0x39aa3005, 0x8f734a34, + 0xfb9c0448, 0xf0fef864, 0x410a0181, 0x002206d7, 0xc3880400, 0x0d000332, 0x24001100, 0x0cb3b300, 0x2b04060e, 0x1d0c22b3, 0x0c238b82, 0x8207b110, + 0x10062acd, 0xb0d009b0, 0x26b01022, 0x05bc4bdc, 0xb2820220, 0xbf870220, 0x0c821020, 0x0c871020, 0x0c286b18, 0x19822020, 0xc7462020, 0x07aa7614, + 0x4500b025, 0x1822b058, 0x22070652, 0x82120618, 0x10022974, 0xf40500b1, 0xb11004b0, 0x125f6b18, 0x1000b023, 0x08d642b0, 0xb0d01e24, 0x6b18d01f, + 0x01250f71, 0x01333523, 0x0c6b1822, 0x75012b0f, 0xfdbabbbb, 0x01d3d3d1, 0x0b83d35c, 0xf673fe2b, 0x75256963, 0x365c4356, 0x25138216, 0xbb5e04bc, + 0xfa41e7fa, 0xe9032205, 0x236b18bb, 0xffff2d10, 0xe9fffeff, 0xcb067303, 0x2b002602, 0x3f085546, 0x00020073, 0x0375fe04, 0x00580558, 0x00180012, + 0x0c10b32c, 0x002b040b, 0xb02f18b0, 0x16b02f14, 0x2005b743, 0x065b530e, 0x0606b323, 0x053a5100, 0xf4060c22, 0xa491b682, 0x07270727, 0x5c010127, + 0xb36b18f6, 0x4401210c, 0x23058962, 0x48ca75fe, 0x0cb86b18, 0x62c40521, 0xff29069a, 0xfe3100ff, 0x059e038b, 0x209d8219, 0x249d822c, 0x00e20006, + 0x20158600, 0x201584a2, 0x2f15874c, 0x31000100, 0xa2030000, 0x0b00a403, 0x04b34a00, 0x14b38418, 0x2007b341, 0x20b98209, 0x14f74e09, 0x1807e046, + 0x2815b384, 0x83fec3a2, 0x028989a8, 0xe66b1813, 0xa4032707, 0xf6010afe, 0x5a1854fe, 0x2d200c47, 0x650ca150, 0x4d20094f, 0x75201788, 0x7320c386, + 0x2f83c384, 0xba24d987, 0xe9028bfe, 0x2d831584, 0xd982ef88, 0x07262b89, 0xd5007701, 0xc143eafe, 0x41032005, 0x5b840507, 0x01770123, 0x2017845c, + 0x252f8d31, 0xba00c100, 0x2f85ba00, 0x885e0421, 0x0007245d, 0x822f02c1, 0xff012293, 0x312f855e, 0x4f000d00, 0x010c0cb3, 0x01b02b04, 0xd005b010, + 0x85180cb0, 0x2b4716f3, 0x02b22807, 0x12110600, 0x8503b239, 0x85082006, 0x84092006, 0xb12c0806, 0x30f4030c, 0x11212131, 0x11373507, 0x15371133, + 0x03211107, 0xd3befc73, 0xd3d389d3, 0x3302b902, 0x02457f45, 0x46c8fd67, 0x15fe467f, 0x29072165, 0x11001905, 0x04b38900, 0x8382030e, 0x10042108, + 0xf40800b1, 0xf40e07b1, 0xb01004b0, 0x05b0d008, 0xd009b010, 0xb01007b0, 0x03b0d00a, 0xd00cb010, 0x23053543, 0x04030fb2, 0x12838582, 0x2407bb5f, + 0xb11b2f03, 0x07bb4303, 0x29086b6a, 0x01b11003, 0x05b2f403, 0x2e82030b, 0x8406b221, 0x0bb02606, 0x0309b110, 0x059872f4, 0x840fb221, 0x10b22113, + 0x30260684, 0x23110131, 0xba842135, 0x21153324, 0xca823335, 0xd38d0129, 0xd2d25d01, 0x82d1fdd2, 0x01b223c4, 0xc08677f0, 0x01777726, 0x007f45bc, + 0x200c0742, 0x0c07422f, 0x24059341, 0x00260253, 0x09a9524f, 0xfe310024, 0xd941038b, 0x412d8305, 0x158308ef, 0x88ba0321, 0x06f5422b, 0x43000021, + 0x598506a9, 0xfd47df20, 0x20598506, 0x202d8857, 0x228682df, 0x840100ff, 0x862f202d, 0x01072415, 0x8274fe77, 0x82012077, 0x83752071, 0x00210871, + 0xb05e0016, 0x18b02f17, 0xdc00b02f, 0xf40814b1, 0xb0d00eb0, 0x17b02f0e, 0xd011b010, 0xb12f11b0, 0x07036f10, 0x520c004a, 0x10200c4b, 0x2e06a846, + 0x030609b3, 0x0fb22b04, 0x12111210, 0x8414b239, 0x31302506, 0x23021425, 0x08080a44, 0x11013735, 0x01331123, 0x73033311, 0x7bd3d9d3, 0x487f3156, + 0x29425e41, 0x89dffd0a, 0x8af701c1, 0xf0fef87d, 0x34396081, 0x31584227, 0xb0fb7504, 0xe3fb1905, 0x86001d04, 0xba0330ad, 0xa1002000, 0xb02f21b0, + 0x1bb02f22, 0x8208b1dc, 0x102132ad, 0xb0d013b0, 0x12b12f13, 0x15b0f40c, 0x1316b2d0, 0x08e4491b, 0x200c8e6f, 0x18a48218, 0x4a082174, 0xb02007b2, + 0x104e4518, 0x26821b20, 0xad461b20, 0x611e2005, 0x2a0805ed, 0xb4f4060c, 0x0ce90cd9, 0x1b405d02, 0x0c180c08, 0x0c380c28, 0x0c580c48, 0x0c780c68, + 0x0c980c88, 0x0cb80ca8, 0x5d0d0cc8, 0x570816b2, 0xc34605e4, 0x55342008, 0xf1830528, 0x33121534, 0x14111120, 0x27222306, 0x43198301, 0x355c441f, + 0x71186c16, 0xbd2a0ad6, 0xfa445ab8, 0x48270f0e, 0x71184266, 0x032c09e1, 0x0001eaa4, 0xc1fd85fe, 0xff1ad7b4, 0x20079b68, 0x089b6836, 0xf741d820, + 0xecff2705, 0xbc03e9ff, 0x1782c204, 0x00005025, 0x57000600, 0x8f6905e1, 0x88792005, 0x06c7492d, 0x05212d85, 0x4e2d8805, 0x2d850563, 0x2d88ea20, + 0x5b8bdd20, 0x88760521, 0x51dd202d, 0xb0220863, 0x1582c706, 0xdb423320, 0x230c820c, 0x54059e03, 0x53201782, 0x06220a82, 0xa5458b00, 0x05b02208, + 0x422d8619, 0x002607db, 0x9e038bfe, 0x2b88ba03, 0x2209db42, 0x88cb06b0, 0x08555559, 0x03000025, 0x8858059e, 0x2317822d, 0x1900ffff, 0x8320f982, + 0x34208784, 0xff21878b, 0x201782f6, 0x2087848b, 0x85878a54, 0x855b832d, 0x86d6202d, 0x832d85e3, 0x822d855b, 0x01003717, 0x8dfe1900, 0x2f058303, + 0xb0004800, 0x290a15b3, 0x06b32b04, 0x05820d0d, 0x320b3331, 0x32b02b04, 0x0800b110, 0x1015b0f4, 0x82d011b0, 0x35b02e0c, 0x1029b0d0, 0xf40c3fb1, + 0xb01033b0, 0x0646484a, 0x1b2f3224, 0x7d4432b1, 0x82342007, 0x4634200c, 0x2e20076b, 0x2e200c82, 0x200c5348, 0x06f55811, 0x19821220, 0x3e0f122c, + 0x0a11b259, 0x3912112e, 0x068431b2, 0x2eb02908, 0x063ab110, 0x3ad9b4f4, 0x5d023ae9, 0x3a081b40, 0x3a283a18, 0x3a483a38, 0x3a683a58, 0x3a883a78, + 0x3aa83a98, 0x3ac83ab8, 0x23057564, 0x1507020e, 0x21072368, 0x84182626, 0x372a2e44, 0x52467b5c, 0x60ca9358, 0x84182fa0, 0x4a242c48, 0x0a3b5c79, + 0x076d6118, 0x8b475022, 0x30518418, 0xfef6ff2f, 0x038b038d, 0x003b00ba, 0x0c32b3a5, 0x08734121, 0x170c0029, 0xdab42b04, 0x8317ea17, 0x17093bfc, + 0x17291719, 0x17491739, 0x17691759, 0x17891779, 0x17a91799, 0x17c917b9, 0x47185d0d, 0xe44924b8, 0x2f262405, 0x4126b11b, 0x0a200790, 0x0a290c82, + 0xb0593e11, 0x2db11026, 0x52951806, 0x05ac5f25, 0x200c6841, 0x966b1837, 0x623b2b22, 0x5852427d, 0xf27aca93, 0x6b183d5a, 0x4424259a, 0x06254162, + 0x23055841, 0x3c450512, 0x24a36b18, 0x42081d43, 0x4b4309ef, 0x061d4306, 0x4309ef42, 0x002d054b, 0xa4038bfe, 0x26021905, 0x00003500, 0x0ba54300, + 0x1584ae20, 0x158b5520, 0x03000024, 0x598306a4, 0x07212b83, 0x08a54300, 0x03e9ff25, 0x82d405ae, 0x282d8343, 0x01770107, 0x00a5ff5c, 0x82398201, + 0x19053f2f, 0x86001700, 0xb02f18b0, 0x0fb0d00f, 0xdc07b02f, 0x010740b2, 0x0802b15d, 0x1007b0f4, 0x14820bb0, 0x0eb11023, 0x200c840d, 0x201b8213, + 0x201b8213, 0x290e8212, 0x15b01002, 0x1012b0d0, 0x564319b0, 0x0c904b06, 0x22080560, 0x48000117, 0x0223052b, 0x7eb0f406, 0x002f0532, 0xd008b010, + 0xb01017b0, 0x10b0d00a, 0x820cb110, 0xd0142118, 0x30244c82, 0x11230131, 0x2605c947, 0x11333523, 0x86231121, 0x02332203, 0x05d247e9, 0xe8fed33f, + 0x75a40375, 0x02d2e8fe, 0x7515fe60, 0x71eb0175, 0xbcfed301, 0x47feb901, 0x2dfe4401, 0x016d1800, 0x0023260a, 0x0c02b3a3, 0x257b8213, 0x17b01013, + 0xcb4cb0d0, 0x10022505, 0xb0d01db0, 0x21200582, 0x7d064b51, 0x1a240ce3, 0x1ab11b2f, 0x5c140d53, 0x232008f4, 0x2e08ce84, 0x07b1100e, 0x1b40f406, + 0x07170707, 0x07370727, 0x07570747, 0x07770767, 0x07970787, 0x07b707a7, 0x5d0d07c7, 0xe607d6b4, 0xb05d0207, 0x82b01000, 0x102329dd, 0xb0d016b0, + 0x18b1101e, 0x1927ed82, 0xd020b0d0, 0x83d021b0, 0x141529f0, 0x3233021e, 0x06173736, 0x20054d55, 0x83fa8335, 0x11333903, 0x11211521, 0xd32f0233, + 0x36543b21, 0x730a8966, 0x5295c710, 0xd3356088, 0x22080082, 0xfe8d0189, 0xbe01d373, 0x445a3368, 0x19657f27, 0x6036ad93, 0x71685087, 0x01750001, + 0x758bfe75, 0x180000ff, 0x2c078361, 0x26027306, 0x00003600, 0xd7000700, 0x057b5e00, 0xe9ff3126, 0x00057303, 0x56201782, 0x06201782, 0x2d881783, + 0x2d883620, 0x6f06c746, 0x04210563, 0x822d88c3, 0x202d8817, 0x462d8879, 0x2d8506c7, 0x88060521, 0x8717822d, 0x3e07212d, 0xdb202d88, 0xcb20898c, + 0x17822d88, 0xea205b88, 0xf5462d88, 0x205b8606, 0x822d8877, 0x01002517, 0x85fe3100, 0x192ecd82, 0xa7002600, 0x0e0c11b3, 0x23b32b04, 0x0582030a, + 0x1b081e22, 0x20290f5f, 0x05975423, 0x5f28b021, 0x0f24090f, 0x0fb11b2f, 0x42070c46, 0x0e500c27, 0x1809200c, 0x1807e84d, 0x5d2afe44, 0xf14105d6, + 0x33112306, 0x46711411, 0x83352005, 0x0706300a, 0x16141506, 0x7df80233, 0x1012148f, 0x186d1021, 0x210c9188, 0xbb6d877f, 0x40292606, 0x4603021d, + 0x9988187f, 0xb8fc290f, 0x2d2bf2b4, 0x0060484c, 0x34061941, 0x00a403fe, 0xb399001f, 0x040c0c0f, 0x0a1cb32b, 0xb02b0407, 0x085b7907, 0x17b01023, + 0x210e82d0, 0x06511ab1, 0x180d200a, 0x490b1d81, 0xf78c0c9e, 0x26821a20, 0x7f581a20, 0x600a2007, 0xb2290621, 0x110d0008, 0x12b13912, 0x8c891806, + 0x050b4128, 0x02352325, 0x83112023, 0x086850ff, 0x1415062f, 0xfe033316, 0x171e8f7d, 0xfefe623e, 0x025218a8, 0x09695907, 0x00ffe926, 0x40027b01, + 0x0b5c6f18, 0xff2dfa83, 0x00c1ffff, 0x06e30300, 0x002602cb, 0x0cf75738, 0x1782e520, 0x5805c322, 0x58201782, 0x06231782, 0x7c00d600, 0x2d830957, + 0x2d8c3a20, 0x75fee124, 0x2d84c103, 0x84052563, 0x3100212d, 0x77224382, 0x4382c906, 0x314e3b20, 0x832f200c, 0x53052117, 0x5b201782, 0x840b414c, + 0x888e202d, 0x00da272d, 0xff750100, 0x2d8500ff, 0x2d881920, 0x9d4c1782, 0x06772206, 0x202d88cd, 0x202d8cdf, 0x202d8857, 0x05e553df, 0xa42a5b82, + 0x16002f05, 0x00b39d00, 0x147f040e, 0x08052105, 0x470c1579, 0xc3530554, 0x0cd8420c, 0x182f0821, 0x180a6b75, 0x200cc041, 0x24198202, 0x593e0f02, + 0x515118b1, 0x51162009, 0x0727051c, 0x100cb0d0, 0x6d0613b1, 0x2520276e, 0x2108d445, 0x7f183634, 0x02250aa3, 0xd1fdd217, 0x0b4618d3, 0x7575220b, + 0x9b7f1875, 0x06c9410c, 0xcb06a422, 0x8e20f982, 0x20086d41, 0x26178277, 0x03e9ffdb, 0x825605ba, 0x419e2017, 0x0220066d, 0xd3201582, 0xd3201582, + 0x8f202d84, 0xd5202d8c, 0xd1201782, 0x9f202d84, 0x00272d89, 0x038bfe19, 0x822f0583, 0x47342043, 0xff210945, 0x221582f6, 0x82ba038b, 0x47542015, + 0x87470e71, 0x01002924, 0x5e048d01, 0x2f064602, 0x32081f7a, 0x31302f01, 0x11230301, 0x65544602, 0x2ffe2f06, 0x8200d101, 0x0400241b, 0x84a4035e, + 0x00072a25, 0xb339000b, 0x04090808, 0x088c542b, 0x250c5367, 0xb11b2f0a, 0x6855150a, 0x18012005, 0x25077e5b, 0xb0d008b0, 0x5985d009, 0x35230124, + 0x03820533, 0x02276183, 0xfdbbbb17, 0x85baba16, 0x2ffe2669, 0xffbbbbbb, 0x065964ff, 0x22022f24, 0xd5828101, 0x7701032a, 0x00008cfe, 0x5fffffff, + 0x2206874e, 0x85850122, 0xd2fd2117, 0x2322178c, 0x11837701, 0x01020023, 0x28178387, 0x00001700, 0x2f06e902, 0x21178202, 0x31828afe, 0x89010222, + 0x5b242f84, 0xc703e9ff, 0x22221782, 0x47868f01, 0x1785ce20, 0xb8205f82, 0x94201784, 0xbc201790, 0x00211783, 0x82178b9d, 0x03e92233, 0x221782a4, + 0x82a70126, 0x01062217, 0x20058278, 0x079e1002, 0x00226301, 0x0d4a0031, 0x00052805, 0x0c03b32a, 0x732b0400, 0xb03a1ad3, 0x02b11000, 0x3130f406, + 0x21152113, 0x03312311, 0x8916fd73, 0xfb751905, 0x4918005c, 0x01204c3d, 0x9c189584, 0x77206d8b, 0x87598d18, 0x6024fb8a, 0xb02f0cb0, 0x7c679b18, + 0xdfff033c, 0xc703e9ff, 0x03002f05, 0x2b001700, 0x2cb0e900, 0x2f2db02f, 0xb0dc04b0, 0x9c52102c, 0x04330806, 0x0818b110, 0x18dab4f4, 0x5d0218ea, + 0x18091b40, 0x18291819, 0x18491839, 0x18691859, 0x18891879, 0x18a91899, 0x18c918b9, 0x0eb05d0d, 0x0c22b110, 0x7d1340f4, 0x092d1192, 0x9609405d, + 0xb622a622, 0x0422c622, 0x069a7d5d, 0x20058b42, 0x0b137d13, 0x31077849, 0x020601b3, 0x13b02b04, 0x061db110, 0x1dd9b4f4, 0x7c831de9, 0x87180820, + 0xb0251a3f, 0x27b11009, 0x8e8c1806, 0x05e24225, 0x1f996218, 0xd701e52e, 0xe20229fe, 0x89bf7636, 0x3577bf89, 0x08319618, 0x875c3137, 0x548b6b56, + 0x8b542121, 0x548c6a6b, 0x75c70220, 0xbaf48339, 0x619d1871, 0xbc712707, 0xcf8183f4, 0x98184d92, 0x8d7a0b93, 0xd19c1806, 0x31002561, 0x9e030000, + 0x91576784, 0x07fe4a17, 0x5d0c465a, 0x91570c8a, 0x459c181d, 0x08d3451a, 0x87820620, 0x18093078, 0x840f614d, 0x078a4819, 0x0001b235, 0x39121104, + 0x01213130, 0x33012301, 0xfe500301, 0x6a85fe83, 0x04280558, 0x0573fb8d, 0x00e7fa19, 0x22093344, 0x106d000c, 0x2201599c, 0x82000321, 0xa4033300, + 0x07001905, 0x13000f00, 0x14b07e00, 0x2f15b02f, 0xc77614b0, 0x01b12b06, 0x15b0f40b, 0xdc06b010, 0x098203b1, 0xb0d00831, 0x09b01001, 0x1000b0d0, + 0xb0d00bb0, 0x75b01006, 0x644a07f9, 0x2f062d0c, 0x0f06b11b, 0x11b3593e, 0x2b041206, 0x00212683, 0x230582dc, 0xf40602b1, 0x04213983, 0x05c058d0, + 0x2206375e, 0x5bdc0ab0, 0x3021055f, 0x06015031, 0x01213208, 0x11231521, 0x01231121, 0x79211521, 0xfc79b202, 0xfd2b035c, 0xa403794e, 0x01bafd79, + 0x0129fed7, 0xfeb8b82d, 0xbba404d3, 0xd0fe3001, 0x0075defe, 0x08a14402, 0x01219d10, 0x094d434b, 0x4b00073a, 0xb02f08b0, 0x00b02f09, 0x0801b1dc, + 0x1008b0f4, 0xb0d005b0, 0x04b12f05, 0x4a078b58, 0x26440cb4, 0x06024214, 0x21313026, 0x11211123, 0x032e0382, 0xd1fd8a73, 0x04420389, 0x055cfba4, + 0xab720019, 0x919d180c, 0x515f18ad, 0x180f208f, 0x749bff99, 0x052305a9, 0x18140019, 0x20a67597, 0x20b18403, 0x30b182bc, 0x00220019, 0xb391002b, + 0x040d0c23, 0x0806b32b, 0x22058207, 0x511a0c00, 0x12270557, 0x1006b0d0, 0x18d014b0, 0x8324bf40, 0x1f2b082a, 0x061b40d0, 0x26231623, 0x46233623, + 0x66235623, 0x86237623, 0xa6239623, 0xc623b623, 0xb45d0d23, 0x23e523d5, 0x07b05d02, 0x5426b010, 0x054906b3, 0x4506200c, 0xf5560667, 0x232a0807, + 0x35032e35, 0x37023e34, 0x1e153335, 0x2e340703, 0x36112702, 0x16142536, 0x030e1117, 0x6f3dbc03, 0x5e8a5e9b, 0x3b3b6f99, 0x0882996f, 0x6f9b4108, + 0x4727893d, 0x9587436b, 0x879142fd, 0x25476943, 0xa8628f02, 0xac0a507f, 0x7d500aae, 0xa86362a8, 0xa20d4f81, 0x7f520aa2, 0x7d4663aa, 0xfd0c4062, + 0x8dc71625, 0x0216c78d, 0x60420cdb, 0xff01007d, 0xd8179a18, 0x27087d4b, 0xb355001b, 0x04090c0c, 0x08837118, 0x04190823, 0x069b672b, 0x65180420, + 0xd7740934, 0x0c945d0c, 0x1b2f1a23, 0xdc7b18b1, 0x072f4908, 0x0131302b, 0x11070214, 0x02261123, 0x05015435, 0x06821720, 0x82033e21, 0x0333080c, + 0x8ab4a873, 0x1189a6b6, 0x8a43522d, 0x102f5241, 0xcd27038a, 0xfe1600ff, 0x164401bc, 0x01cd0201, 0x350efef0, 0x0f4e6675, 0xa1fc5f03, 0x75664e0f, + 0x64f20135, 0x8e2a082f, 0x89012202, 0x03000000, 0x3b528c00, 0xecff2105, 0xb8240c82, 0x23028e06, 0x002f1185, 0x00940102, 0x00ffff00, 0x03e9ff02, + 0x822f06aa, 0x829f202f, 0x0102222f, 0x20158477, 0x20158200, 0x22158281, 0x82a30126, 0x86062015, 0xfe0c2415, 0x8473038b, 0x8aa52015, 0xffba2415, + 0x4fe902e9, 0x41890aab, 0x2005c14f, 0x09c14fb2, 0x032d6d85, 0x001300ba, 0xb3cc0029, 0x04140c00, 0x98bd182b, 0x05f84b24, 0x1b2f1d24, 0x99571db1, + 0x0c176807, 0x19822020, 0x86542020, 0x82252007, 0x1825200c, 0x082bc383, 0x1019b036, 0xf4060fb1, 0xe90fd9b4, 0x405d020f, 0x180f081b, 0x380f280f, + 0x580f480f, 0x780f680f, 0x980f880f, 0xb80fa80f, 0x0d0fc80f, 0x251cb25d, 0x39121119, 0x0f191eb2, 0x22200683, 0x30220d84, 0xbc551331, 0x2e373406, + 0x0e222303, 0x3e340702, 0x16323302, 0x03331317, 0x55032313, 0x340805e2, 0x613b1b8b, 0x475c3c43, 0x34141434, 0x433c5c47, 0x891b3b61, 0x6492602d, + 0x3829b67b, 0x93838393, 0x7bb62938, 0x2d609264, 0x8340d301, 0x6a46466c, 0x843f4085, 0x3507826a, 0xb05e3f84, 0x899b5287, 0x2ffe0e01, 0x0e012dfe, + 0x8a529c89, 0xa77700b0, 0x05a82805, 0x001a002f, 0x630d0134, 0xb32a054b, 0x04270810, 0x27dab42b, 0xc78327ea, 0x19270939, 0x39272927, 0x59274927, + 0x79276927, 0x99278927, 0xb927a927, 0x8227c927, 0x271e22c7, 0x21c08210, 0xbc181eb0, 0xb127254c, 0xb2f40c16, 0x83160513, 0x10042932, 0xb0d031b0, + 0x36b01016, 0x1806f359, 0x180cdf6e, 0x470c1545, 0xb32307fd, 0x54210624, 0x2b080598, 0x40f4061b, 0x171b071b, 0x371b271b, 0x571b471b, 0x771b671b, + 0x971b871b, 0xb71ba71b, 0x0d1bc71b, 0x1bd6b45d, 0x5d021be6, 0x1b0003b2, 0xb2236c82, 0x82242113, 0x0bb02b06, 0x062cb110, 0x2cd9b4f4, 0xd9832ce9, + 0x2c083f08, 0x2c282c18, 0x2c482c38, 0x2c682c58, 0x2c882c78, 0x2ca82c98, 0x2cc82cb8, 0x31305d0d, 0x27262205, 0x34112311, 0x3233023e, 0x1415021e, + 0x16160706, 0x020e1415, 0x35363227, 0x23232634, 0x08833335, 0x022e6c08, 0x020e2223, 0x16161115, 0x9163ee01, 0x70428940, 0x98605a9c, 0x6d753868, + 0x74429485, 0xa28f62a2, 0x5a5aa6aa, 0x401e8791, 0x67354a66, 0x933c3251, 0xfe313017, 0x541f0541, 0x3b39698f, 0x68407d5e, 0xa62925a0, 0x6489527b, + 0x7490753a, 0x8e759375, 0x4150256c, 0x6644202b, 0x412dfd46, 0x00010038, 0x038bfe00, 0x00a4037b, 0x463e000e, 0xb2230521, 0x6106070b, 0x00240800, + 0x00b11b2f, 0x2014ec64, 0x27198206, 0x593e1106, 0x00060bb2, 0x30252e82, 0x030e0131, 0x08d08207, 0x01330142, 0x03371236, 0x5639117b, 0xfe8a4d77, + 0x3d019e73, 0x03138b77, 0xfcfe77a4, 0xb4fe6bf1, 0xcf034a01, 0x01c7b4fc, 0x0200d9ac, 0xe9ff2700, 0x2f057903, 0x37002700, 0x2eb31101, 0x2b04110c, + 0x190c00b3, 0x07220582, 0x7543280c, 0x14b22326, 0x7f820711, 0x244fb918, 0x1b402208, 0x2e162e06, 0x2e362e26, 0x2e562e46, 0x2e762e66, 0x2e962e86, + 0x2eb62ea6, 0x5d0d2ec6, 0xe52ed5b4, 0x05bf462e, 0x34423920, 0x821e2006, 0x4d1e20e4, 0x0c2007e7, 0x0c210c82, 0x22f1820f, 0x821e0c14, 0xb0340871, + 0x25b1101e, 0xd9b4f406, 0x0225e925, 0x0813405d, 0x28251825, 0x48253825, 0x68255825, 0x88257825, 0x405d0925, 0xa8259809, 0xc825b825, 0xb05d0425, + 0x33b1100c, 0x07232f82, 0x82331733, 0x27173c2f, 0x47333733, 0x67335733, 0x87337733, 0xa7339733, 0xc733b733, 0xb45d0b33, 0x82e633d6, 0x31303120, + 0x041e1401, 0x020e1415, 0x022e2223, 0x37363435, 0x18052d47, 0x25096553, 0x27263401, 0x955b0606, 0x3e7a0805, 0x524e0102, 0x527b917b, 0x629e6e3c, + 0x3b6f9e60, 0x4025a8a6, 0x4b271c2f, 0x8454456d, 0x6a303d3d, 0x0158433e, 0x858594a2, 0x6f431fa2, 0x466e4e4e, 0x2944041f, 0x7f62524c, 0x9b6166a0, + 0x733e3e73, 0xee76619b, 0x3733195c, 0x542b2942, 0x29212943, 0x3b162162, 0xbd7217fd, 0x75bd4747, 0x35596e39, 0x006e5838, 0x00000100, 0x8103e9ff, + 0x3000ba03, 0x1cb3bf00, 0x2b042b0c, 0x7b4d2bb0, 0x40270806, 0x161c061b, 0x361c261c, 0x561c461c, 0x761c661c, 0x961c861c, 0xb61ca61c, 0x0d1cc61c, + 0x1cd5b45d, 0x5d021ce5, 0x5d101cb0, 0x2b4505bb, 0x2f052405, 0x4205b11b, 0x4018075d, 0x1522084b, 0x8b181606, 0x37630800, 0x18b02024, 0x2a2abc54, + 0x15162eb2, 0x30391211, 0x44341331, 0x072405fd, 0x22232626, 0x27054541, 0x22231533, 0x1415020e, 0x0bb05418, 0x34355908, 0x26263736, 0xa177420c, + 0x3dc99961, 0x769a2966, 0x401ea38e, 0xcece4262, 0x23446444, 0xa47b94b6, 0xcf3f602f, 0x7daa64a0, 0x635c7148, 0x3fa4025e, 0x64274769, 0x54464664, + 0x33194a58, 0x1b741b29, 0x501b372b, 0x42484c5a, 0x4a276364, 0x7748436b, 0x00771012, 0x02000100, 0x08061b6b, 0x82002841, 0xb02f29b0, 0x22b02f2a, + 0x0c00b1dc, 0x00dab4f4, 0x5d0200ea, 0x00091b40, 0x00290019, 0x00490039, 0x00690059, 0x00890079, 0x00a90099, 0x00c900b9, 0x29b05d0d, 0xd00ab010, + 0xb22f0ab0, 0x82220a0f, 0xb12808ce, 0x40f40c18, 0x1618061b, 0x36182618, 0x56184618, 0x76186618, 0x96188618, 0xb618a618, 0x0d18c618, 0x18d5b45d, + 0x5d0218e5, 0x08d34118, 0x1b2f1132, 0x3e1511b1, 0x060fb159, 0x053130f4, 0x27022e34, 0x26055f42, 0x21352137, 0x42040615, 0x48080558, 0x15031e17, + 0x27070614, 0x02033636, 0x37583b21, 0x669ebd54, 0x83e8ae64, 0xea023bfe, 0xcdd9feb8, 0x9373486d, 0x6284474a, 0x3c75743b, 0x25734458, 0x040c192b, + 0xbd642306, 0xb4cb68a0, 0x75753598, 0xcbbca031, 0x508d715c, 0x284e821f, 0x564a5833, 0x21682999, 0x20fd8360, 0x0597660c, 0x001d002b, 0x2f1eb091, + 0xb02f1fb0, 0x082e661e, 0xb2f40825, 0x82101100, 0x1fb029d5, 0xdc07b010, 0xf40808b1, 0x18052e42, 0x200ca757, 0x20c0821b, 0x073b421b, 0x6d180720, + 0x10200bec, 0x23064c66, 0x030700b2, 0x2005cd67, 0x278165b1, 0x2905da5f, 0x32333636, 0x23111516, 0x94183411, 0x07210b1b, 0x08178427, 0x1f2f0142, + 0xa09a6883, 0x685a568a, 0x232d8a8d, 0x151b2122, 0x6d471d39, 0x664e0603, 0x49fcc0b8, 0x9074b703, 0xecfd92a0, 0x2f2bec02, 0x0e0a6b0f, 0x03000058, + 0xe9ff2900, 0x2f057f03, 0x1e001300, 0xa4002900, 0x15e16818, 0xf4081927, 0xb1100ab0, 0x2606821a, 0x19b0d024, 0x4b25b010, 0x045b0644, 0x0742180c, + 0x06252108, 0x0805db49, 0x0614b12e, 0x071b40f4, 0x27141714, 0x47143714, 0x67145714, 0x87147714, 0xa7149714, 0xc714b714, 0xb45d0d14, 0x14e614d6, + 0x0fb05d02, 0x061fb110, 0x25bc5c18, 0x11d36818, 0x32013708, 0x2137023e, 0x2213031e, 0x2107020e, 0x7f03032e, 0x71a36731, 0x2f699f73, 0x739f692f, + 0x2f69a173, 0x6c4e54fe, 0xfd041f44, 0x442102c0, 0x6a4e4e6a, 0x02022144, 0x0b820440, 0x8b023608, 0x63b2f895, 0x95f8b263, 0x64b4f894, 0xfdfab264, + 0xbd894e3f, 0x89bd6c6c, 0x495c044e, 0x6868b383, 0x004983b3, 0xffba0001, 0x03e902e9, 0x001100a4, 0x080db35d, 0x07d55708, 0x0cbf5a18, 0x1b2f0327, + 0x3e0f03b1, 0x076c6959, 0xb1100323, 0x38ff840f, 0x270f170f, 0x470f370f, 0x670f570f, 0x870f770f, 0xa70f970f, 0xc70fb70f, 0x2eff830f, 0x020fe60f, + 0x0311b25d, 0x3912110b, 0x48253130, 0x270805ea, 0x35231135, 0x33141121, 0xe9023732, 0x2d2b3916, 0xd3253e52, 0x316a5d01, 0x0d0c021b, 0x37563a1f, + 0xfd795c02, 0x0011712b, 0x2d7d0f6c, 0xe1ff0100, 0xc1030000, 0x12002f05, 0x07435d00, 0x2f0e2205, 0xf4a8181b, 0x0cbb5009, 0x200a7d54, 0x08eb820e, + 0x100eb02b, 0xf40608b1, 0xe908d9b4, 0x405d0208, 0x1808081b, 0x38082808, 0x58084808, 0x78086808, 0x98088808, 0xb808a808, 0x0d08c808, 0x06a9545d, + 0x26275608, 0x06222326, 0x33362707, 0x01171632, 0xb6fe1d03, 0x01a2b0fe, 0x331339a0, 0x2f5a1c44, 0x5660601b, 0xf801278e, 0xd1fc2f03, 0x2d8ebe03, + 0x76141041, 0xfb633d23, 0x01000071, 0x8bfe3100, 0xa4039803, 0xac002100, 0xb02f22b0, 0x16b02f23, 0x0813b1dc, 0x1600b2f4, 0x2d8c8313, 0x08b01022, + 0x2f08b0d0, 0xf40c07b1, 0xdc420ab0, 0x0c406d06, 0x430c6e69, 0xf7410cd3, 0x45002408, 0x821fb058, 0x0f1f27ff, 0x00b2593e, 0x58820907, 0x8406b221, + 0x03b02e06, 0x060eb110, 0x071b40f4, 0x270e170e, 0x1cc6180e, 0xd019231d, 0x35841bb2, 0x20060e42, 0xcd711826, 0x1411240e, 0x62323316, 0x370805e9, + 0x15750226, 0x683c6289, 0x6d898917, 0x41542f4e, 0x1d298b25, 0x151b1d31, 0x6c482531, 0x3e694c9e, 0x052bfe39, 0x6a9bfd19, 0x734e2977, 0xfd150247, + 0x112f2d16, 0x590d0c6d, 0x2406b564, 0x00a4037b, 0x0737560a, 0x4e490020, 0x0cfd460b, 0xb222e087, 0x4e490307, 0x02062306, 0x4c492307, 0xb2233907, + 0x83fe8b9e, 0x772f01a4, 0xa403127f, 0xd521fef0, 0xe1fca403, 0xd98101c5, 0x3b064946, 0x002f058b, 0xb3c3003a, 0x04380c1d, 0x0c27b32b, 0xb22b042e, + 0x11273800, 0x1b403912, 0x22418318, 0x3803b223, 0x262b821d, 0xb12f03b0, 0x18f40812, 0x2924927b, 0xb01027b0, 0xb000dc3c, 0x63182f2a, 0x15260975, + 0x22b3593e, 0x81823303, 0x17061622, 0x17218183, 0x20558316, 0x29b94c08, 0x01313025, 0x47352626, 0x16210e9a, 0x07994733, 0x46021e21, 0x35200991, + 0x3d07b346, 0x6f1b0136, 0x93714473, 0x3fa44e50, 0x467a462b, 0x8d8b9975, 0x7d4cf6f6, 0x73462f58, 0x9d464c93, 0x21230808, 0x7537583b, 0x94508dc3, + 0xa623b002, 0x587f4e60, 0x6a232331, 0x647d1823, 0x27747f71, 0x4e375e48, 0x4613315c, 0x2f2d0ba6, 0x0c192b25, 0x50230a04, 0xa66c6d85, 0x05991000, + 0x262d6201, 0x27b0ce00, 0x2f28b02f, 0xb0dc00b0, 0x0b697827, 0x2bff6f18, 0xb0100823, 0x0b38471e, 0x1db24518, 0x26277b7c, 0x220507b2, 0x18391211, + 0x4d331770, 0x07210ae5, 0x06cf4d34, 0xa6181520, 0x3f08088b, 0x966eb079, 0x6931897b, 0xaa696f9f, 0x29894078, 0x3d4e7952, 0x3c2b4c6b, 0x7d544e87, + 0xd1012b54, 0x4881b26d, 0x0341fe61, 0x89b05c46, 0xb5834754, 0x6487506a, 0x8e5a293a, 0x3841fa64, 0x0087623a, 0x2507ff43, 0x2b00ba03, 0xe95caf00, + 0x4b2c2006, 0xb0250693, 0x1bb0102d, 0x057545dc, 0x00b03108, 0x0c11b110, 0x061b40f4, 0x26111611, 0x46113611, 0x66115611, 0x86117611, 0xa6119611, + 0xc611b611, 0xb45d0d11, 0x11e511d5, 0x1bb05d02, 0x0c22b110, 0x254c5218, 0x1eb00022, 0x44050144, 0x6c4907ce, 0x0e834b28, 0x15020e23, 0x12df4314, + 0x8148022f, 0xcd8d6db4, 0xa22b603b, 0x5b835268, 0x0c714a31, 0x583b213a, 0x91c16f37, 0x6cd10154, 0x6c4781b5, 0x5244425c, 0x5087643a, 0x254e7d5e, + 0x2211ca43, 0x436a3808, 0xfa2808c7, 0x1600a403, 0xcd002900, 0x20068b49, 0x06974c2a, 0x102bb029, 0xb2dc05b0, 0x41050f00, 0x520806ed, 0x40f40c1a, + 0x161a061b, 0x361a261a, 0x561a461a, 0x761a661a, 0x961a861a, 0xb61aa61a, 0x0d1ac61a, 0x1ad5b45d, 0x5d021ae5, 0xb11005b0, 0xb4f40c24, 0x24ea24da, + 0x1b405d02, 0x24192409, 0x24392429, 0x24592449, 0x24792469, 0x24992489, 0x24b924a9, 0x470d24c9, 0xec4606c5, 0xb746180c, 0x10142b08, 0xf40600b1, + 0xb0d017b0, 0x6118100a, 0x17292991, 0xd029b010, 0x1e013130, 0x09304e03, 0x33023e25, 0x4c211521, 0x4e0806da, 0x35023e32, 0x27022e34, 0x542b8902, + 0x79422944, 0xa66664a6, 0x83494177, 0x23026ab5, 0xb6aadbfd, 0x4a72522b, 0x2b54754a, 0x395a4223, 0x4e122f03, 0x663e7869, 0x484279a6, 0x6a6db27f, + 0x75427bae, 0x874ea0c0, 0x58333a62, 0x763c4a7d, 0x4e145069, 0xa4290609, 0x1300a403, 0x05b35c00, 0x08836108, 0x1b2f0224, 0x734302b1, 0x820e2007, + 0x0f0e250c, 0x02b0593e, 0x0bec7618, 0x24059448, 0x08071b40, 0x4ab51817, 0x21d2821f, 0xc5823521, 0x18141121, 0x080a5476, 0xfe8d0122, 0xfea40373, + 0x231d6a73, 0x52281a0e, 0x253e522d, 0x75752f03, 0x0871a0fd, 0x1f196b07, 0x0037563a, 0x312a9f82, 0xa403e9ff, 0x1d00b603, 0x614c9500, 0x05045a09, + 0xf40c082c, 0xb0101fb0, 0x12b1dc19, 0x5218f40c, 0x774924fb, 0x0c736605, 0x0cad6018, 0xe8820020, 0xe8820020, 0x030db123, 0x08d882f4, 0x0d170d26, + 0x0d370d27, 0x0d570d47, 0x0d770d67, 0x0d970d87, 0x0db70da7, 0x5d0d0dc7, 0xe60dd6b4, 0x305d020d, 0x2e220531, 0x28074e55, 0x023e3233, 0x27263435, + 0x05015237, 0xd3014c08, 0x3c6e9a5e, 0x674c2d89, 0x4c7d5c39, 0x852b2523, 0x71352b29, 0x603017b0, 0x3e02608d, 0x623dc2fd, 0x7b4e2344, 0xbd684493, + 0xdb60355c, 0x99bf5e7b, 0xff020061, 0x038bfeec, 0x00ba03be, 0x002d0021, 0x0c19b3b7, 0xb32b0412, 0x820c080b, 0x0c052805, 0x402b0425, 0x1819061b, + 0x082079cc, 0x100cb035, 0xb0d01cb0, 0x22b0100b, 0x25dab4d0, 0x5d0225ea, 0x25091b40, 0x25292519, 0x25492539, 0x25692559, 0x25892579, 0x25a92599, + 0x25c925b9, 0x05b05d0d, 0x512fb010, 0xdb48062b, 0x2f0b330c, 0x110bb11b, 0x00b0593e, 0x062ab110, 0x2ad9b4f4, 0x4c832ae9, 0x2a08a408, 0x2a282a18, + 0x2a482a38, 0x2a682a58, 0x2a882a78, 0x2aa82a98, 0x2ac82ab8, 0x31305d0d, 0x021e3201, 0x020e1415, 0x11231107, 0x3435032e, 0x06173736, 0x16141506, + 0x3e341117, 0x36360302, 0x022e3435, 0x15062223, 0x85525402, 0x6f3d355e, 0x5e8a609b, 0x643b6f99, 0x4742525c, 0x2d138791, 0x9787024c, 0x27523f29, + 0xba031a23, 0x6cb58147, 0x507daa62, 0x019dfe0a, 0x7f500a63, 0xe58362a8, 0xaf355e46, 0x17c98d6c, 0x4e2b8302, 0xaafc203a, 0x508dc917, 0x2d3a6487, + 0xff010032, 0x0375fef8, 0x00bc03a4, 0x663c000b, 0x40460dd9, 0x210c820c, 0xaa7601b2, 0x8507200c, 0x8409200d, 0x30340806, 0x23020931, 0x01370101, + 0x01013301, 0xc9fe0c03, 0x01a4c7fe, 0x798dfe8d, 0x2d014a01, 0x0181fea2, 0x0275fe5e, 0x02ebfd2b, 0x45690283, 0x2702c1fd, 0xaefd6afd, 0x08fb7c18, + 0x005e0425, 0x574b001b, 0x12201fc1, 0x23056e45, 0xb11b2f0a, 0x08bca818, 0x200c0e6e, 0x23198204, 0x593e1104, 0x312cb757, 0xffcdd101, 0x9dfe1600, + 0x01166301, 0xd101cd02, 0xb7572dfe, 0xfcfa2205, 0x05b75706, 0x0100d338, 0xe9fff2ff, 0xb603b603, 0xd6003400, 0x080c13b3, 0x1cb32b04, 0x05821908, + 0x220c2d2b, 0x00b22b04, 0x12111c19, 0xa8711839, 0xa6581824, 0x552d2025, 0xe96b09bd, 0x8228200c, 0x412820e0, 0x194c0796, 0x8232200c, 0x0f322719, + 0x00b2593e, 0x8b820d03, 0x1003b023, 0x27eb6cb1, 0xd01fb022, 0x29060b4c, 0x3435022e, 0x1737023e, 0x0a52030e, 0x11352605, 0x16141133, 0x058e5533, + 0x0bed7c18, 0x17d35908, 0x64485072, 0x160a1c40, 0x1787151f, 0x3908151e, 0x8a563d46, 0x3b463d58, 0x171e150a, 0x14211587, 0x64401c0c, 0xa273504a, + 0x77446752, 0x8d3e64a8, 0x352f818b, 0x7d7f752d, 0xa4a6ac33, 0xfe510194, 0xa6a494af, 0x7f7d33ac, 0x2f352d75, 0x3e8d8b81, 0x4477a864, 0xffff0067, + 0x22050b4f, 0x68021905, 0x0022065b, 0x256f008c, 0x84a42007, 0x00b22415, 0x85060000, 0x058f7515, 0x022f0625, 0x59ad0122, 0x31210a1d, 0x079d68ff, + 0x1d592b84, 0x05c14105, 0x26222b82, 0x2b82b601, 0x26073359, 0x03000031, 0x828e0673, 0x82cf206d, 0x83072015, 0x75012557, 0x77ff0100, 0x2b084382, + 0x00190573, 0xb0e80023, 0x25b02f24, 0x1024b02f, 0xb0d021b0, 0x20b12f21, 0x03b0f40c, 0x1025b0d0, 0xb2dc09b0, 0x11092104, 0x11b23912, 0xa87e0684, + 0x58452206, 0x175b18b0, 0x0c2f450c, 0x2107a251, 0x268200b0, 0x1b2f2023, 0x081759b1, 0x67083246, 0xb22305b6, 0x84000e04, 0x2206845a, 0x50100eb0, + 0x062129ee, 0x3db01810, 0x02b02128, 0x08125718, 0x15210324, 0x6a771123, 0x020e2205, 0x06757823, 0x77113521, 0x23330988, 0xbbfe0189, 0x5801fe63, + 0x2d523e25, 0x0e1a2654, 0x776a1d23, 0x21080687, 0x751905ba, 0x000116fe, 0x90fe85fe, 0x1f3a5637, 0x08096d19, 0x7d700171, 0x9775468a, 0x045efe52, + 0x376d00a4, 0xa4350806, 0x2602c906, 0x0000cd01, 0x8b000700, 0x75010000, 0xecff0100, 0xac03e9ff, 0x2e002f05, 0x2fb0b700, 0x2f30b02f, 0xb0dc15b0, + 0x00b0d000, 0x102fb02f, 0xb0d00bb0, 0x8211820b, 0xf40d23fe, 0x0c8217b0, 0x24b11030, 0x21b0f408, 0x1014b0d0, 0xb0d02eb0, 0xa2462f2e, 0x15d97205, + 0x06223a08, 0xb22b0423, 0x11100413, 0x10b03912, 0x061cb110, 0x1cd9b4f4, 0x5d021ce9, 0x1c081b40, 0x1c281c18, 0x1c481c38, 0x1c681c58, 0x1c881c78, + 0x1ca81c98, 0x1cc81cb8, 0x04b05d0d, 0x32521810, 0x0601272a, 0x22230607, 0xbe4d042e, 0x33352407, 0x4a342311, 0x420805f0, 0x21152107, 0x1e171616, + 0x13323303, 0x7433ac03, 0x915bb074, 0x17334f70, 0x89bf7736, 0x752aab79, 0x7a5a3575, 0x55866045, 0x4602052b, 0x2303bafd, 0x47371526, 0x60f43557, + 0x64a75601, 0x7e5b3462, 0x1858a796, 0x33087897, 0x335a7a46, 0x5bb08a54, 0x47ab5875, 0x1b304227, 0x01002701, 0x2505c777, 0x3f002f05, 0xbb18d300, + 0xb2296dd3, 0x11250508, 0x11b13912, 0xcabb1806, 0x660768fa, 0x12694218, 0x00008c28, 0x01007301, 0xa944feff, 0x00112206, 0xf1c4184c, 0xff02227e, + 0x328b8275, 0x0019059c, 0x00240008, 0x0c15b3ba, 0xb32b0423, 0x82120c05, 0x080e2405, 0x572b0400, 0x052625e0, 0xd009b010, 0x42180eb0, 0x09240951, + 0x09b11b2f, 0x0f114318, 0x4500b024, 0x4218b058, 0x1a200c2a, 0x1a3c2682, 0xb3593e0f, 0x0403060b, 0x1009b02b, 0xf40613b1, 0x091a1eb2, 0xb0391211, + 0x21b1101a, 0x28df8318, 0x26340129, 0x33112323, 0x82013632, 0x15162304, 0x0d820614, 0x18112321, 0x080bd748, 0x03113544, 0x4c5c6c12, 0xfe6c5c4c, + 0xb3a14aec, 0xbbd1a3b3, 0x2b4c3a20, 0x18163628, 0x5e19200d, 0x857f7101, 0x047f00fe, 0xbcd0fd25, 0x04b6bbbc, 0x372bfca4, 0x091f3a56, 0x0809730a, + 0x004a0471, 0x00310002, 0x29410300, 0x001b2c05, 0x0c1bb39f, 0xb32b0409, 0x820d0c10, 0x41142005, 0x10352929, 0xd004b010, 0xb0101bb0, 0x0db0d00b, + 0xd018b010, 0xb01014b0, 0x06944a1d, 0x550cea60, 0x09200c37, 0x25060c75, 0x584500b0, 0x0c8217b0, 0x02681720, 0x04033705, 0x1017b02b, 0xf40605b1, + 0xb01011b0, 0x03b0d00c, 0xd019b010, 0x0e413130, 0x11052208, 0x20018533, 0x08144132, 0x24070641, 0xbb891ffd, 0x06094189, 0xf426fd86, 0xd0fd1905, + 0x02413002, 0x75022305, 0x48188bfd, 0x17330b7f, 0x18b0a100, 0x2f19b02f, 0xb01018b0, 0x15b0d015, 0x4714b12f, 0x19200557, 0x26055747, 0x12110915, + 0x590ab139, 0x50470700, 0x18cd8c19, 0x28090076, 0x0602b110, 0x0904b2f4, 0x08468200, 0x1006b033, 0xf4060eb1, 0xe90ed9b4, 0x405d020e, 0x180e081b, + 0x380e280e, 0x580e480e, 0x780e680e, 0x980e880e, 0xb80ea80e, 0x0d0ec80e, 0x1002b05d, 0xb0d016b0, 0x47f78217, 0x23200910, 0x18130547, 0x46075ab0, + 0xfd2309fb, 0x463f02c1, 0xf14609f2, 0x069e2606, 0x012602c9, 0x09f146d4, 0xffffff29, 0x03e9ffe1, 0x827b06c1, 0x84dd2017, 0x00d93c17, 0x00750100, + 0xfe310001, 0x057303c1, 0x000b0019, 0x0c08b353, 0xb32b0405, 0x82030802, 0x72002005, 0x02200575, 0x6705ff4a, 0xe6410cc0, 0x0c11570c, 0x088ab018, + 0xf4060824, 0xcf8209b0, 0x11212127, 0x11211123, 0x35038333, 0xa4fe7303, 0x89a4fe8a, 0xfe8a2f02, 0x053f01c1, 0x045cfb19, 0xc37100a4, 0x05fd4265, + 0xe782a220, 0x1500082c, 0x16b07300, 0x2f17b02f, 0x035c0db0, 0x5b16202a, 0x05210731, 0x48da830c, 0xce630500, 0x5641180c, 0x060a2608, 0xb02b0403, + 0x05d64210, 0xb1101225, 0x42f40614, 0x212605d1, 0x36322111, 0xca422101, 0x230c8205, 0x19032115, 0x07c8c518, 0x01a1fd2d, 0xececd527, 0x0352fed7, + 0x4247fd42, 0x012b06cf, 0xbbbcbcf5, 0x751905b6, 0x18030000, 0x2108ab5b, 0xd018000e, 0x8572f28d, 0x00003749, 0xa403c1fe, 0x0f001905, 0x52001800, + 0x000b0db3, 0x10b32b04, 0x0582050c, 0x160c0822, 0x0a300582, 0x2b040b0b, 0xb0100ab0, 0xb000dc1a, 0x0eb02f0a, 0x60120243, 0xb13d079d, 0xb0f40608, + 0x16b0d015, 0x1006b0d0, 0xf40617b1, 0x3e353130, 0x11351202, 0x11331121, 0x08058223, 0x14012339, 0x07060602, 0x39231121, 0x011f3c58, 0xfd7bbbfd, + 0x75017b52, 0x39503117, 0x75ebbc01, 0x01bc7131, 0x4201e123, 0x4cfe5cfb, 0xc1fe3f01, 0xfeb01605, 0x399ad1f2, 0x18002f04, 0x3a6f6fcf, 0x0000c1ff, + 0x1905e303, 0x7f001300, 0x000813b3, 0x00b02b04, 0xd008b010, 0x5a1013b0, 0x0644083f, 0x0c23470c, 0x440ce36d, 0x324e0c13, 0x2f0f300c, 0x0f0fb11b, + 0x02b2593e, 0x12110600, 0x8508b239, 0x850b2006, 0x84112006, 0x31302d06, 0x01271121, 0x33010123, 0x11331101, 0x0b820582, 0x11072708, 0xfe378d01, + 0x3f018ffa, 0x0195c1fe, 0x37018a37, 0x01c1fe95, 0xfafe8f3f, 0x64060237, 0xe10296fd, 0xbcfd3802, 0x03844402, 0x1ffdc83f, 0xfd646a02, 0x000100fa, + 0x03e9ff1b, 0x002f0598, 0xb3e4003e, 0x042b0d2d, 0x0c37b32b, 0x08d9821f, 0xb1103737, 0xb1f40914, 0xb0f40800, 0x0bb0102d, 0x2f0bb0d0, 0xea1fdab4, + 0x405d021f, 0x191f091b, 0x391f291f, 0x591f491f, 0x791f691f, 0x991f891f, 0xb91fa91f, 0x0d1fc91f, 0x282d835d, 0x29b0d029, 0x2b3ab22f, 0x24c08200, + 0xb01037b0, 0x3e421840, 0x08395e13, 0x395e1a20, 0x27395d07, 0x1032b027, 0xf40623b1, 0x9bb718b4, 0x052d2224, 0x23858232, 0x1a193ab2, 0x475e0682, + 0x37272409, 0x52161716, 0x2e3905e8, 0x32352302, 0x3435023e, 0x22232627, 0x06060706, 0x33112315, 0x33033e15, 0x05076532, 0x031e6b08, 0x75469803, + 0xa45e5499, 0x85084e7d, 0x8b5c5d0c, 0x2d4e683b, 0x5c8e6132, 0x3e648043, 0x41744949, 0x36282a79, 0x4a18757d, 0x54306058, 0x843e6b92, 0x4769457c, + 0x56680124, 0x3338648d, 0x12639666, 0x284c4d96, 0x503a6246, 0x75143965, 0x43593616, 0x3243426e, 0x4c702629, 0x31989c01, 0x31122942, 0x7055865c, + 0x3c0a1392, 0xd3426f59, 0x0009280b, 0x2f0ab062, 0x182f0bb0, 0x2a08cd67, 0xf40c01b1, 0xb0100bb0, 0x18b1dc05, 0x4708da8b, 0x03200c83, 0x0b1d4818, + 0x18076041, 0x280c857e, 0x000502b2, 0xb2391211, 0x08068407, 0x13313020, 0x33011133, 0x01112311, 0x01893123, 0xfd8ac1f8, 0x1905aaf2, 0x1d04e3fb, + 0x5004e7fa, 0x214eb0fb, 0x06732607, 0x01260279, 0x081747d2, 0x7b437320, 0x739e2006, 0xe7207803, 0x2206614b, 0x718b0013, 0x01300675, 0x0802b1dc, + 0x1014b0f4, 0xb0d012b0, 0x05b12f12, 0x1814a648, 0x240c9565, 0xb11b2f0c, 0x0f897d0c, 0x1000b03a, 0xf40603b1, 0x000a0db2, 0xb0391211, 0x10b1100a, + 0x1b40f406, 0x10171007, 0x1eeae118, 0x01313026, 0x21112311, 0x3b05944a, 0x16163727, 0x11353233, 0xfe8a7303, 0x523e255b, 0x1b27542d, 0x6a1d230e, + 0xe7fa1905, 0x21077b4a, 0x7a4a6d19, 0xac797305, 0x77000b21, 0x32108153, 0x338002b1, 0xecffecff, 0x2f05ac03, 0xe3002500, 0xb02f26b0, 0x12b02f27, + 0x21071f53, 0xe25c1026, 0xfbd91006, 0xc2240d01, 0x83f4ba6e, 0x23083653, 0x335a7b45, 0x2405bb79, 0x2501659d, 0x069d6200, 0x1805754a, 0x4e9a7dcd, + 0x05250525, 0x00120019, 0x12e57d5a, 0x4d0c1b67, 0x0a2508eb, 0x1b40f406, 0xd2d61807, 0x11b22221, 0x066c6304, 0x06060122, 0x1807ec55, 0x331ef0b0, + 0x70fb1905, 0x77233e62, 0x2d421114, 0xfcbf038d, 0x003003d0, 0x01713310, 0xc1fe33f2, 0x19051f04, 0x4f000b00, 0x040c07b3, 0x0bb32b04, 0x05820808, + 0x020b012d, 0x01b02b04, 0xdc0db010, 0x6101b000, 0x15240a18, 0x00b0593e, 0x0fe55618, 0xcd680320, 0x00b12c06, 0x07b0f406, 0xd008b0d0, 0x50253130, + 0x112c099e, 0xfc7b1f04, 0x2f02898d, 0x4cfe758a, 0x21079e50, 0xb34a5cfb, 0x0013220b, 0x10037b5e, 0xb0f40c32, 0x0cb01015, 0x080bb1dc, 0xd00eb0f4, + 0x0c000fb2, 0x180dcf6f, 0x180cce52, 0x2b0ce6de, 0xb3593e0f, 0x04110605, 0x0d0fb22b, 0x20051943, 0x05fb5a13, 0x35023e24, 0x99823311, 0x20230223, + 0x31b61811, 0x1905330d, 0x897dc0fd, 0x52987446, 0xe7faa201, 0x00ff5e02, 0x5d447b01, 0x000b250b, 0x2f0cb07c, 0x072bdd83, 0xdc00b02f, 0x0100efb2, + 0x8240b25d, 0x01b12104, 0x00239e82, 0x8203b010, 0x83032013, 0x21048213, 0xbc8206b1, 0xb1100723, 0x2006820a, 0x05444106, 0x485a0020, 0x148d180f, + 0x3261180c, 0x02b12e14, 0x0ab0f406, 0xd00bb0d0, 0x33013130, 0x06ec5111, 0x0121112c, 0x04018a8d, 0x895cfc89, 0xea510401, 0xe7fa2105, 0xad840783, + 0x2c06cf41, 0xb36f000f, 0x04000c03, 0x0807b32b, 0x2b058204, 0x04080c0b, 0x100bb02b, 0xf40b0cb1, 0xb0210682, 0x2655820e, 0xdc11b010, 0x180db000, + 0x410abc83, 0x98180743, 0x8c4e0c7e, 0x0820600c, 0xe9410320, 0x219d8207, 0xa0820cb0, 0x8a523120, 0x23a58405, 0x11231133, 0xa5839c82, 0x857b7b21, + 0x5cfb23a2, 0x8a4fa404, 0x02002205, 0x29008200, 0x1905a203, 0x15000c00, 0x31527600, 0x10162106, 0x3705096e, 0xf40c12b1, 0xb0d001b0, 0x06b01017, + 0x0c0db1dc, 0x0ddab4f4, 0x5d020dea, 0x1db4df18, 0x18125245, 0x2208ac40, 0x82100603, 0x100023fb, 0xb3820bb1, 0xb1100927, 0x30f40612, 0x52a78331, + 0x2320072d, 0x33081355, 0xb4b27501, 0xfeb6c7c7, 0x1903ecc7, 0xb4b46f81, 0x1905816f, 0x2708f555, 0xfe857fcd, 0x00007f00, 0x3009bd7d, 0x0013000a, + 0xb3870017, 0x04000c01, 0x0c06b32b, 0x2405820b, 0x04140c15, 0xb8d8182b, 0x10012625, 0xb0d00fb0, 0xcf4d1815, 0x0c934d09, 0x1b2f1424, 0x6e4314b1, + 0x07704c0c, 0x19821620, 0x0c821620, 0x0603b323, 0x051b570e, 0xd2841020, 0xe0563320, 0x89212007, 0x113336d0, 0xa2878923, 0xfea4b2b2, 0x6cdb01f2, + 0x5d89895d, 0x8940016c, 0x56d68789, 0xfa2108db, 0x06c756e7, 0x2205c953, 0x436c0013, 0xc953068f, 0x5314202b, 0xc25335c9, 0x53332014, 0x892013c0, + 0x2d0ebd53, 0xf8ff0100, 0xb803e9ff, 0x2e002f05, 0x6f5cbe00, 0x102f2b06, 0xb0d018b0, 0x17b12f18, 0x795cf40d, 0x10303006, 0xb1dc23b0, 0xb0f4080a, + 0x17b0d00d, 0x821ab010, 0x5c10201f, 0xb222056f, 0x8c182e1b, 0x2773098c, 0x2a40080c, 0x2ab11b2f, 0xb3593e0f, 0x040a060d, 0x102ab02b, 0xf40602b1, + 0x02071b40, 0x02270217, 0x02470237, 0x02670257, 0x02870277, 0x02a70297, 0x02c702b7, 0xd6b45d0d, 0x0202e602, 0x101eb05d, 0xf40612b1, 0x243e9618, + 0x2a1bb235, 0x3912111e, 0x12133130, 0x023e3233, 0x37363637, 0x76213521, 0x152605d9, 0x15331123, 0x50503636, 0x0e670805, 0x27222304, 0x606f2726, + 0x475735f4, 0x23261537, 0x02bafd03, 0x552b0546, 0x7a456086, 0x7575355a, 0x8979ab2a, 0x173677bf, 0x91704f33, 0x7474b05b, 0xfe850133, 0x42301bd9, + 0x58ab4727, 0x8ab05b75, 0x7a5a3354, 0x98ac0146, 0xbc715658, 0xa75883f4, 0x345b7e96, 0x00a76462, 0xff310002, 0x05a803e9, 0x000e002f, 0x42de0022, + 0x1e2806cd, 0x2b040b08, 0x140c07b3, 0x0b2afa82, 0xd003b010, 0xb01001b0, 0xa818d00c, 0xb0242475, 0x24b01007, 0x13508a18, 0x200c5844, 0xf66b180d, + 0x0aad430b, 0xb0217782, 0x290f6f09, 0x1005b036, 0xf40619b1, 0xe919d9b4, 0x405d0219, 0x1819081b, 0x38192819, 0x12b8e418, 0x305d0d34, 0x11331331, + 0x20211233, 0x20211011, 0x23112303, 0x50663225, 0x05307305, 0x021e3508, 0x0dac8931, 0x21011401, 0xecfedffe, 0x0289ac0d, 0x203c2f56, 0x3c200d0d, + 0x213b2f2f, 0x3b210c0c, 0xaefd1905, 0x5cfd6802, 0x69025efd, 0x525eaefd, 0x7b7bcc94, 0x0a208e18, 0xff020027, 0x030000f4, 0x06035573, 0x19b09427, + 0x2f1ab02f, 0x6eda18b0, 0x1ab02407, 0x460ab010, 0x052105cf, 0x05407410, 0x1023bd83, 0x1840f408, 0x232300fa, 0xb0100bb0, 0x07778c18, 0x670c3046, + 0x00240875, 0x0eb05845, 0x0806ac66, 0x0113b328, 0xb02b0400, 0x0cb01000, 0x2f0cb0d0, 0xb11008b0, 0x30f40615, 0x032e0131, 0x33363435, 0x11231121, + 0x13230123, 0x0a821614, 0x22213108, 0x527d0106, 0xec39658b, 0x8aae01d7, 0xae83feca, 0x0190a69b, 0x90dcfe24, 0x063502a6, 0x52835c38, 0xe7fabbba, + 0xd1fd2f02, 0x7987a403, 0x007b0002, 0xfe28e982, 0x7303e9ff, 0x2600ba03, 0x0125d310, 0xff003f80, 0x05a403e9, 0x000d002f, 0xb00a013a, 0x3cb02f3b, + 0x103bb02f, 0xb0d00eb0, 0x29b12f0e, 0xb618f408, 0xa46125ca, 0x3c320805, 0xdc33b010, 0xf40c08b1, 0xea08dab4, 0x405d0208, 0x1908091b, 0x39082908, + 0x59084908, 0x79086908, 0x99088908, 0xb908a908, 0x0d08c908, 0xd01bb05d, 0xb3611bb0, 0x0c247f06, 0x1b2f1b24, 0xbd461bb1, 0x82382007, 0x0f382c0c, + 0x2eb3593e, 0x2b040b06, 0x181038b0, 0x2029a3cf, 0x13c21813, 0x18b12b29, 0x1fb1f402, 0x29b2f406, 0x51451338, 0x55142005, 0x262506a9, 0x27062223, + 0x05a17a34, 0x0af95318, 0x0ae1f318, 0x08056e6a, 0xac96024c, 0x56774697, 0xa69aa82f, 0x733f969d, 0x3e2d609e, 0x291f2d31, 0x2b472939, 0x3a273374, + 0x3d233331, 0x192d506b, 0x31645848, 0x467ba862, 0x62a87b46, 0xbc01eeeb, 0x5d31bf9f, 0xbfa04f81, 0xf8962fbf, 0x191264b2, 0x52211c12, 0x07823729, + 0xb47f4331, 0x31462d71, 0xae753b18, 0x7dac6275, 0x5a480148, 0x032b086d, 0x001000a4, 0x0026001d, 0x4b23b3a9, 0x0c250577, 0xb42b0411, 0x5f7718da, + 0x1eb22322, 0x4d7c0b11, 0x0c00262b, 0x040eb2f4, 0x18328300, 0x710a1cbe, 0xb32914b5, 0x04210619, 0x210eb22b, 0x352d8319, 0x16b11005, 0x03b0f406, + 0x0623b110, 0x013130f4, 0x21230614, 0xe57b2111, 0x34032308, 0x1084022e, 0x13023e24, 0x09842634, 0x03364708, 0xfebac7a2, 0x44d10110, 0x46426885, + 0xb65c7d66, 0x2752432e, 0x4801b8fe, 0x29445429, 0xfe74862d, 0x7465019b, 0x870a0186, 0x15a40383, 0x484c5e35, 0x711d1a62, 0x352b4a01, 0xf4fe0a1d, + 0xfe331f0a, 0xfe4c5291, 0xd7544ec7, 0x03a42306, 0x4d1800a4, 0x3367131b, 0x2f042707, 0x0f04b11b, 0x4d18593e, 0x032c141b, 0xd1fc75a4, 0x00020000, + 0x03c1fe00, 0x955a4983, 0x5a698733, 0x03221c95, 0x945a3535, 0x020e290a, 0x23112107, 0x2740562f, 0x2f08935a, 0x21443521, 0x75eba601, 0xdf9c580a, + 0xd1fcc191, 0x2905915a, 0xcb742204, 0x021c73a0, 0xd21800ba, 0xff39e6e5, 0x030000f0, 0x00a403b4, 0xb37f0013, 0x04030806, 0x1006b02b, 0xb0d00db0, + 0xc1e31803, 0x2f012409, 0x4101b11b, 0x1b790cdf, 0xa55a180c, 0x180f200c, 0x180e1f75, 0x280cc35e, 0x010a03b2, 0xb2391211, 0x20068506, 0x2006850c, + 0x21068411, 0x025b3130, 0x0325080b, 0x11231107, 0x01230327, 0x99e2fe0e, 0x018a0401, 0xe2fe9904, 0xd9931e01, 0xd9318a31, 0x010c0293, 0x0177fe98, + 0x2d038489, 0x01f4fd68, 0xa6fe48a2, 0xfe485a01, 0xaf63005e, 0x037f2606, 0x002e00ba, 0x20d182c5, 0x27d18520, 0x00b0d000, 0x20dab42f, 0x2186bf18, + 0x6120b021, 0xb024062f, 0x30b01006, 0x24063149, 0xb11b2f2a, 0x20e8872a, 0x200c820b, 0x29e8820b, 0x1a061db3, 0x03b22b04, 0xa17f1d1a, 0xef551806, + 0x2ab02127, 0x2329f45a, 0x14013130, 0x1807bf7f, 0x230af56b, 0x23022e34, 0x2506c77f, 0x06222326, 0x924a2707, 0x034b0805, 0x5c625f73, 0xaa7d4871, + 0x3fcfa064, 0x7ba42f60, 0x4423b793, 0x9c9c4464, 0x8ea37f83, 0x66299a76, 0x6199c93d, 0x024277a1, 0x107744a4, 0x43487712, 0x63274a6b, 0x4c484264, + 0x371b505a, 0x5d741b2b, 0x54584a33, 0x64644646, 0x50694727, 0x0322080b, 0xbf5a00a4, 0x0c3c6b2a, 0xbf5a0c87, 0xa4032b37, 0xf00210fd, 0x12035cfc, + 0xbf5aeefc, 0x06052b08, 0xf2012602, 0x06000000, 0x0582d900, 0x7c536518, 0xff01002a, 0x03e9ffe7, 0x00a40373, 0x4127bd5a, 0xbd5a0713, 0xa4032780, + 0x2f035cfc, 0x4f6aa0fd, 0xd5022108, 0x180bf341, 0x432e374e, 0x0c870c1d, 0x240c1b5f, 0xb11b2f06, 0x050e5f06, 0x12110826, 0x0005b239, 0x0a200684, + 0xea180684, 0xe5351191, 0xb289e862, 0x02b2eef0, 0x011dfee3, 0x031dfde3, 0x011afea4, 0x5aa18be6, 0xaa4430bd, 0x20a3940c, 0x06be4604, 0x0609b325, + 0x842b0402, 0x11212294, 0x05475123, 0x8a73032d, 0x8989d1fd, 0x018a2f02, 0x825efea2, 0x0173228e, 0xbb37108d, 0xd3435601, 0x03732305, 0x4d1800a4, + 0xcd41276f, 0x6f4d181c, 0x2f032318, 0x6482d1fc, 0x10020021, 0x5a0131d1, 0x09d94318, 0xd7002823, 0xd5de10b0, 0xb0231b01, 0x18486b5c, 0x2219d5de, + 0x5b004450, 0x03220759, 0x4e1800a4, 0x2e433ed7, 0x07934507, 0x100eb024, 0xf21802b1, 0xe8181915, 0x012d1dd7, 0xfd4301ec, 0x02757546, 0x01bdfeba, + 0x25a582b8, 0x75fee1ff, 0xa582c103, 0x6513cc18, 0xff032308, 0x038bfee3, 0x001905c1, 0x0024000a, 0xb032012f, 0x10b02f30, 0x2f10b0d0, 0xb2dc00b0, + 0x5d010080, 0x0483d0b2, 0x04823020, 0x1010b02c, 0xf40805b1, 0xb01000b0, 0x0583d00b, 0x05831520, 0x822fb121, 0x83172012, 0x2ab02109, 0x2a203182, + 0x04833183, 0x04833020, 0x2a001827, 0xb1391211, 0x2922821d, 0x22b0102f, 0x101db0d0, 0x184a31b0, 0x18162006, 0x200ba5c8, 0x200c8213, 0x07594113, + 0x200c3775, 0x21198223, 0x1b4b1123, 0x0c645306, 0x2608a172, 0x02b11013, 0x18b4f406, 0x2524a9d2, 0x08b1100d, 0xe678f406, 0x0bb22324, 0xbd82080d, + 0x1315b223, 0x20068302, 0x20068518, 0x08148422, 0xd027b023, 0xb01002b0, 0x3130d02d, 0x22232601, 0x16141506, 0x15373233, 0x26222306, 0x33363435, + 0x33111732, 0x22068211, 0x82141516, 0x11272312, 0x90181323, 0x07330849, 0x54398d01, 0x4a49494a, 0x58353954, 0x8f8e8e8f, 0x888a3558, 0x878a2008, + 0x022e081a, 0xc9ac5fe7, 0x7d5eaac9, 0xebecfc56, 0xb50156fe, 0xfe564bfe, 0x56fceceb, 0x31024cfe, 0xc9c9aa5e, 0x01005fac, 0x0000ecff, 0xa403ba03, + 0xcf181b00, 0x0025c711, 0x04c1fe31, 0x5bd1821f, 0x4b1828c1, 0xc15b1405, 0xfe792b28, 0x033f0148, 0x03d1fca4, 0xc149fc2f, 0x34c15b0c, 0x4214c749, + 0xc15b07b2, 0x5b352018, 0x033215c1, 0x7dd7fea4, 0x98754589, 0x5cfc8b52, 0x00ff0002, 0xc3447b01, 0x48bf5b0a, 0x18149c4e, 0x440cd361, 0xbf5b07e7, + 0x06494122, 0x07835c20, 0xad830020, 0x2206cd41, 0x5b75000f, 0x014d32bf, 0x14e7410c, 0x2115bf5b, 0x23562f0b, 0x31302105, 0x8618c55b, 0x03d129a8, + 0xfed5fc2f, 0x003f0148, 0x2106c55b, 0xc55ba403, 0x5abd8c55, 0xc55b05eb, 0xdd20082a, 0xa0aeaea2, 0x03ec98fe, 0xdf5c6919, 0x03695cdf, 0x858bfea4, + 0x03879291, 0x4deafd2f, 0x56bbfe54, 0x8208c55b, 0x000330bf, 0x0017000e, 0x0c14b387, 0xb32b040c, 0x820f0c08, 0x0c012a05, 0xb02b0400, 0x04b01014, + 0x15c318d0, 0x01b02124, 0x870ec55b, 0x0cf079bf, 0x1b2f0224, 0xb55002b1, 0x08d94f07, 0x12060522, 0x08098b18, 0x01313027, 0x01231133, 0x079a5c33, + 0xc95b3320, 0x1b033b08, 0x6efd8989, 0xa1a19aa0, 0x89d5fe98, 0x545c5201, 0x5c54a2a2, 0x5cfca403, 0xda842f02, 0x75fda422, 0x916fda85, 0x24d98206, + 0x0013000a, 0x09575f6f, 0xb0d0082d, 0x10b12f08, 0x00b0f40c, 0x8215b0d0, 0xb1dc23db, 0x8a180c0b, 0x5f5d257b, 0xe4461805, 0x8207200c, 0x820720cc, + 0x01b323cc, 0xbf820e06, 0xb1100728, 0x30f40610, 0x846f1331, 0x30bb8408, 0x32211121, 0x6501ba36, 0xbac7c9ba, 0x028910fe, 0x0703545f, 0x012cb58f, + 0xe9ff2300, 0xba03a403, 0x7b002000, 0x0b206e85, 0x0b206182, 0x20074841, 0x200c8215, 0x206e8515, 0x052e411f, 0x06042708, 0x04d9b4f4, 0x5d0204e9, + 0x04081b40, 0x04280418, 0x04480438, 0x04680458, 0x04880478, 0x04a80498, 0x04c804b8, 0xea825d0d, 0x1cb12d08, 0x1b40f406, 0x1c171c07, 0x1c371c27, + 0x1c571c47, 0x1c771c67, 0x1c971c87, 0x1cb71ca7, 0x5d0d1cc7, 0xe61cd6b4, 0x305d021c, 0x26210131, 0x560be450, 0x26200518, 0x37059469, 0x01213736, + 0x14fd0117, 0xa26894b4, 0xcd3b602b, 0x81b66d8d, 0xb6814848, 0x07d74118, 0x0fb89a3d, 0x1702fefd, 0x4452aa85, 0x476c5c42, 0x6d6cb581, 0x6b4881b2, + 0x5044425c, 0x5b008eb6, 0xe1830567, 0x16000e22, 0x2108675b, 0x675b0c15, 0x5b112005, 0x09560f67, 0x07b02422, 0x7e18b010, 0xdc5513b6, 0x0c02480c, + 0x2412675b, 0x1b40f401, 0x774a1807, 0x05b02521, 0x0113b110, 0x27806618, 0x0810675b, 0x23101130, 0x31101122, 0x0112bd89, 0xfe170104, 0x0ef8fee9, + 0x5c0289bd, 0x038d8e8e, 0x0168fea4, 0xfe17feae, 0xfeaf0118, 0x79015868, 0x89fe7701, 0x4b5b87fe, 0xa4033507, 0x16000d00, 0x17b09100, 0x2f18b02f, + 0xb01017b0, 0x03b0d003, 0x10300b82, 0xb1dc08b0, 0xb0f40809, 0x0db01003, 0x2f0db0d0, 0xb1220882, 0xcd820c0e, 0x0e062808, 0x0e260e16, 0x0e460e36, + 0x0e660e56, 0x0e860e76, 0x0ea60e96, 0x0ec60eb6, 0xd5b45d0d, 0x020ee50e, 0x1009b05d, 0x42d012b0, 0xd27b0567, 0x1073180c, 0x07f6550c, 0x0611b323, + 0x054b5b00, 0xb0d00a2d, 0x13b11006, 0x3130f406, 0x5b262601, 0x3c081448, 0xc7b2a65a, 0x8af001ba, 0xc2acfedf, 0x01758597, 0x759cfe64, 0x08750185, + 0x87928985, 0x75015cfc, 0x8b028bfe, 0x4601544e, 0xffffff56, 0x03e9fffc, 0x021905ae, 0x00ef0126, 0x00060000, 0x0805828c, 0x8fff0124, 0x730375fe, + 0x27001905, 0x28b0af00, 0x2f29b02f, 0xb01028b0, 0x01b0d001, 0x0c04b12f, 0xd007b0f4, 0xf28229b0, 0x08b2dc29, 0x12110d01, 0x8415b239, 0x1ab12806, + 0x04b0f408, 0x8223b010, 0x744d1827, 0xc0791809, 0x0c6b7f0c, 0x1b2f2431, 0x3e0f24b1, 0x0618b359, 0xb32b0412, 0x82060605, 0x100528e1, 0xb2d000b0, + 0x6c022408, 0x1e2106c1, 0x4ec71806, 0x06b02d25, 0xd026b010, 0x33033130, 0x33153335, 0x231f7a7c, 0xbb89a271, 0x38167b7c, 0xbb5e04a2, 0xd1fe75bb, + 0x85fe0001, 0x56371bfd, 0x6d181e3a, 0x02710908, 0x078a75e5, 0x53e90321, 0xa42c079b, 0x26025405, 0x0000ed01, 0x8b000600, 0xfb4d0582, 0x08414409, + 0x149b4418, 0x061eb323, 0x20ea8200, 0x2a855a0a, 0xb1101426, 0xb4f4061b, 0x23490019, 0x13313023, 0x78511816, 0x9f51180d, 0x2107260b, 0xb80f8b15, + 0x153e449a, 0x15b6942b, 0xa2010602, 0x4450b68e, 0x059d4d42, 0x080d4618, 0x7585aa22, 0x0cdddd18, 0x33b0d925, 0x1834b02f, 0x083adddd, 0x29061721, + 0x29262916, 0x29462936, 0x29662956, 0x29862976, 0x29a62996, 0xb6b45d0b, 0x0229c629, 0x18d5b45d, 0x201fe0dd, 0x96c918b1, 0xd7dd1828, 0x00022fb2, + 0x020000ba, 0x001905e9, 0x000d0003, 0xe818b35f, 0x357c8249, 0x19052107, 0x08798018, 0x82008c21, 0x040023a4, 0xa98675fe, 0x3e001625, 0x180800b3, + 0x7c795fe8, 0xb0320533, 0x1b00a403, 0x95002400, 0x0f0c01b3, 0x21b32b04, 0x05821a0c, 0x1c0c1632, 0x21b02b04, 0xd011b010, 0xea1cdab4, 0x405d021c, + 0x1c47c518, 0x7c16b021, 0x10240933, 0x10b11b2f, 0x68104550, 0x51490886, 0x82192007, 0x82192026, 0x13b3230c, 0x6b821f06, 0xb1101036, 0xb0f40600, + 0x21b11019, 0x0ab2f406, 0x12112119, 0x13313039, 0x200efa7b, 0x08346521, 0x6b491120, 0x7bba2008, 0xcd2e0cfe, 0xa2a29977, 0x01fefe97, 0x79545cb2, + 0xc6565479, 0x05007c08, 0x4ad50221, 0x7f490f5a, 0x03b02c05, 0x001200a4, 0xb39f001b, 0x82000c12, 0x065d69ff, 0x82130c21, 0x10123499, 0xb0d002b0, + 0x0fb01004, 0x13dab4d0, 0x5d0213ea, 0x19091b40, 0x261b770c, 0x17b01007, 0x7c0bb0d0, 0x265b090f, 0x0ced470c, 0x620c0557, 0x0422080b, 0x77821006, + 0x07307182, 0x1010b0d0, 0xb0d016b0, 0x18b1100e, 0x3130f406, 0x4106047c, 0x23200905, 0x23090741, 0x89bb8931, 0xbb22fc86, 0xfd866d02, 0x8bfea424, + 0xf3857501, 0xfeba0125, 0x4a190146, 0x01230575, 0x62008fff, 0x841805f9, 0x1c20098d, 0x200eb546, 0x0ab5461d, 0x460eb121, 0xd78205ae, 0xb0100123, + 0xcc0e1919, 0x0736600b, 0x480cae46, 0x18240cc5, 0x18b11b2f, 0x4605e469, 0x0d200ab5, 0x6507b546, 0xb024277b, 0x1ab01006, 0x7c10b546, 0xaa460c1f, + 0x07207c08, 0x7c0ca046, 0x97460a22, 0x05a22709, 0x01260254, 0x974600f4, 0xffff2106, 0x2105a152, 0x15820605, 0x495afd20, 0xc1fe250b, 0xa4037303, + 0x58231f7c, 0xb120294b, 0x25221f7c, 0xd1fca403, 0x635f2f03, 0xd3053307, 0x41000700, 0xb02f08b0, 0x01b02f09, 0x0d00b1dc, 0x6418b0f4, 0xa6790e67, + 0x087a5f12, 0xb1100626, 0x30f40602, 0x3305a06a, 0x03211123, 0x16fd752f, 0x05fe0289, 0xfbd1fed3, 0x0019055c, 0x04216787, 0x4f67ab5e, 0x0f220c65, + 0x5557593e, 0x33012408, 0x8a112111, 0x5e042367, 0xce82d1fe, 0x08934418, 0x8e06a22c, 0x23002602, 0x07000000, 0x7c82da00, 0xffff7528, 0xe9ff3100, + 0x1784a403, 0x178d4320, 0x03000023, 0x201784cf, 0x21178b25, 0x2f82feff, 0x17847320, 0x2f904520, 0x27201785, 0xba20178c, 0x5f854782, 0x178c4720, + 0x17823120, 0x2e202f85, 0x0c82178c, 0x05a40323, 0x20a78219, 0x200a824e, 0x7ea78306, 0xbd85065f, 0xbd8b3782, 0x088f7818, 0x2d8a5120, 0xa3821920, + 0xa3848320, 0xbb8c3420, 0x1782f620, 0x5b848b20, 0x2d8a5420, 0x2d847184, 0x898d3520, 0xae202d82, 0x55201784, 0xc120458c, 0xe322b982, 0xa182cd06, + 0x17843820, 0x00004127, 0xffff7901, 0xcd7318ff, 0x0041220f, 0x85158204, 0x88c9202d, 0x418b202d, 0x2d860577, 0x17825420, 0x0d435820, 0x202d850a, + 0x182d888e, 0x85073561, 0x8819205b, 0x8217822d, 0x82ec205b, 0x84b82089, 0x8c3a2089, 0x29741889, 0x1889820f, 0x2024f5a0, 0x38458204, 0x05460400, + 0x00090019, 0x00190011, 0xb312011d, 0x04040c03, 0x0c00b32b, 0x22058207, 0x82140c10, 0x18290805, 0x2b040c08, 0xea0cdab4, 0x405d020c, 0x190c091b, + 0x390c290c, 0x590c490c, 0x790c690c, 0x990c890c, 0xb90ca90c, 0x0d0cc90c, 0x2510695d, 0xb010142d, 0x1ab0d01a, 0x1018b02f, 0x83d01bb0, 0x4d1f2005, + 0x052406b7, 0x05b11b2f, 0x6707f144, 0x4d180cd5, 0xd6450ca6, 0x0cf87b0c, 0x40821c20, 0x3e0f1c34, 0x010ab359, 0xb22b0412, 0x11050002, 0x07b23912, + 0x06820a12, 0x1016b025, 0x18010eb1, 0x25262b41, 0x1ab11000, 0x9e82f406, 0x21313038, 0x23110323, 0x11133311, 0x35320133, 0x15222334, 0x11201714, + 0x03822110, 0x15210534, 0xaafe0121, 0xb4c189cb, 0x744a0189, 0xff777974, 0x01820100, 0x02fe2108, 0x02fefe01, 0x02fcfe03, 0x54fc1905, 0xb2fcac03, + 0xc0bfbfc0, 0x012f016f, 0xfed1fe2f, 0x0075e7d1, 0x2d249d41, 0x00d3ff01, 0x02d10302, 0x00050050, 0xa4180020, 0xbd5e0798, 0x37fc870c, 0x07253130, + 0x01270101, 0xfe50d103, 0x4e4efe52, 0x4e500002, 0x50feb001, 0x22080882, 0x00060000, 0x04460044, 0x00190419, 0x003a002f, 0x00490045, 0x015f0054, + 0x0a59b322, 0xb32b0418, 0x82460a3f, 0x0a492205, 0x3b058213, 0x04300a27, 0x1027b02b, 0xb0d000b0, 0x06b01046, 0x2f06b0d0, 0xb01049b0, 0x18b0d008, + 0x8207a369, 0x841e200e, 0x202f081d, 0x103fb0d0, 0xb0d02bb0, 0xdab42f2b, 0x0230ea30, 0x091b405d, 0x29301930, 0x49303930, 0x69305930, 0x89307930, + 0xa9309930, 0xc930b930, 0x835d0d30, 0x363e082d, 0x2f36b0d0, 0xb01030b0, 0x13b0d03b, 0xd04ab010, 0x59061b40, 0x59265916, 0x59465936, 0x59665956, + 0x59865976, 0x59a65996, 0x59c659b6, 0xd5b45d0d, 0x0259e559, 0x1059b05d, 0xb0d050b0, 0x33832f50, 0x83d05521, 0xdc6126a0, 0x0243b300, 0x22b38203, + 0x82330224, 0x02462205, 0x22058207, 0x82140254, 0x100323bf, 0xa1840cb0, 0xb0d01232, 0x1bb01024, 0x1054b0d0, 0xb0d01fb0, 0x2ab01014, 0x2c201784, + 0x37261184, 0x1007b0d0, 0x17843eb0, 0xb0d04726, 0x4db01033, 0x60821184, 0xb0104323, 0x9e9e185c, 0x35262507, 0x14152335, 0x22079a57, 0x57233533, + 0x162506a3, 0x35331515, 0x07a55734, 0x3315232a, 0x34031632, 0x06222326, 0x32221782, 0x0a821136, 0x16243682, 0x25363233, 0x19863f82, 0x33161424, + 0xef571133, 0x35363007, 0x4e6f1904, 0x6ee86a4e, 0x6e6e4e4e, 0x8360624e, 0x4e200805, 0x4e6ce66c, 0x4e6f6f4e, 0x6f4e6060, 0x2929395b, 0x39296037, + 0x355e2939, 0xfe392929, 0x375ae6e4, 0x39230782, 0x83626029, 0x39292314, 0x33830201, 0x3f822a82, 0x5782398c, 0x02214882, 0x2326830c, 0xcffd3760, + 0xe3244685, 0xa001e6e6, 0x37223984, 0x498566fe, 0x03000022, 0x27066542, 0x000300c7, 0x000d0007, 0x1806c068, 0x530c7c44, 0x0321089e, 0x06fa4f01, + 0xb0d0042e, 0x06b01003, 0x013130d0, 0x05213521, 0x01200382, 0x26058042, 0x01d5fea2, 0x838bfd2b, 0xa4022105, 0x26078c42, 0x71715602, 0x4289fd71, + 0x02310892, 0x25000000, 0xc7025c04, 0x15001100, 0xb3001b00, 0x23578311, 0x060109b3, 0x26053464, 0x09b0d012, 0x8214b010, 0x2325325d, 0x26032722, + 0x33352323, 0x16161732, 0x33331617, 0x086b8211, 0xa25c0423, 0x66aa7bd7, 0xd9a4a4b4, 0x2b56297b, 0xfea2b464, 0x25700190, 0x910f0191, 0x88439471, + 0xc5019443, 0x2bd98271, 0x00004a00, 0x19055604, 0x09000400, 0x31266782, 0x020908b3, 0xe7502b04, 0x0ce57d05, 0x2c085343, 0x06b11003, 0x01b0f401, + 0x0108b110, 0x08db82f4, 0x11210128, 0x23010121, 0x07013311, 0x37270727, 0x37173727, 0x56040717, 0x81fe73fd, 0xef017f01, 0xe4e4e4fd, 0x7d500201, + 0x02844e7d, 0x027d5035, 0x0575fd8b, 0x0272fd19, 0x01c5fb1f, 0x7e7e4d9f, 0x827d7d4d, 0x7d50221e, 0x057d5700, 0x015c043c, 0x000b002f, 0x2f0cb046, + 0xb02f0db0, 0x0cb0dc01, 0xd004b010, 0xb12f04b0, 0x77840908, 0xf4090922, 0x0eaabf18, 0x73410b20, 0x100b260a, 0xb0d006b0, 0x269e8602, 0x21152125, + 0x83352335, 0x21240805, 0x00ff5c04, 0x01fea2fd, 0x0181016d, 0xc1c1c16e, 0x00c0c06e, 0xbc000200, 0x6204feff, 0x1f00a203, 0x9a002800, 0x2e06035e, + 0x15b1dc00, 0xdab4f40a, 0x0215ea15, 0x191b405d, 0x321cdb1f, 0x24b01029, 0x2f24b0d0, 0xf40923b1, 0x002428b2, 0x85391211, 0x2f25249e, 0x5725b11b, + 0x0f250c63, 0x10b1593e, 0x25e47d02, 0x0522b223, 0x264a8225, 0xb11025b0, 0x18f40127, 0x210b5140, 0x4018031e, 0x7b080750, 0x031e3727, 0x15010705, + 0x15211123, 0x49620423, 0x5063ac7f, 0x1656758f, 0x63431349, 0x90524579, 0x4c283d6a, 0x4a163f69, 0xfe335c7b, 0x8ffe508a, 0xdd9c016f, 0xac62d301, + 0x58314a7d, 0x3b144c7d, 0x3d2b4c68, 0x3f548f69, 0x13476579, 0x75561449, 0x014e6091, 0xa001e370, 0x0100006f, 0xd9ffe3ff, 0x7d035404, 0x1e001500, + 0x120900b3, 0xb0002b04, 0x15b32f08, 0x2b040001, 0x05010db3, 0x2105df52, 0x9986d012, 0x17213a08, 0x17010107, 0x3e322107, 0x35213502, 0x54540421, + 0xfe75ca96, 0xfe4ebf8b, 0x4e4401bc, 0x5c7501bf, 0xfe4579a0, 0x0325024a, 0x98c9700e, 0x014cc058, 0x4e450142, 0xa07846be, 0x2b6d835c, 0x00004800, + 0x2f015c03, 0x40000700, 0xb0276682, 0x00b02f09, 0x4c08b0dc, 0x09260810, 0x1000b0f4, 0xf94105b1, 0x08de4607, 0x83dc0221, 0x01042a17, 0x1002b0f4, + 0xb0d006b0, 0x088f8207, 0x11212125, 0x35211533, 0xfc5c0333, 0x36026eec, 0xc02f0170, 0x000100c0, 0x04480200, 0x00d1025e, 0x00090003, 0x820701b3, + 0x313025c6, 0x15213511, 0x48221482, 0xf1828989, 0xfe8d0127, 0x0617028b, 0x2321828b, 0x0801b319, 0x53182082, 0x02270811, 0x02b11b2f, 0x82593e11, + 0x11332aec, 0x8a8d0123, 0xf88b068a, 0x84338600, 0x00052455, 0x1803b31c, 0x20090f56, 0x20308204, 0x82308204, 0x04022268, 0x2236822b, 0x83211521, + 0xd1022938, 0x028ab9fd, 0x43fc89d1, 0x6f839183, 0x3b859182, 0x77430420, 0x873b850c, 0x231130a4, 0x8a170211, 0xfb894802, 0x00bd03ba, 0x838d0101, + 0x22a982cb, 0x89120005, 0x03b322a9, 0x84438207, 0x826d82a2, 0x470228a4, 0x8b062ffd, 0x858946fc, 0x83db84fd, 0x08052231, 0x216b8302, 0x06412f03, + 0x3311220a, 0x24318311, 0xba038948, 0x236184fb, 0x5e048bfe, 0x07226182, 0x61852500, 0x1001b025, 0x41d005b0, 0x06200811, 0x0620e082, 0x748ca483, + 0x8a20e283, 0xb9217682, 0x8977848a, 0x224986e5, 0x78010800, 0x49830527, 0x274c0620, 0x82002005, 0x83002049, 0x07052149, 0x26052a41, 0x35211123, + 0x82331121, 0x73fe21f0, 0xfe239382, 0x82bd038b, 0x052f4195, 0x025e042b, 0x000700d1, 0x0805b322, 0x072f4106, 0x40820520, 0x2f410520, 0x00b02508, + 0xd003b010, 0x3105da41, 0x11231121, 0xb9fd5e04, 0x8948028a, 0x0343fc89, 0x094100bd, 0x20d98605, 0x41458218, 0xe3850c09, 0x11243b84, 0x15211133, + 0x02217d82, 0x243b8247, 0x46fcba03, 0x413b8489, 0x0b220615, 0x3b853700, 0x1005b02e, 0xb0d008b0, 0x0ab01002, 0x03b000d0, 0x0920d185, 0x09209082, + 0x01249089, 0xd005b010, 0x07209683, 0x5a849685, 0x5e849a83, 0x61849d85, 0x0220a185, 0x8d266882, 0x8b035e04, 0xe9820300, 0xb3000f33, 0x04050504, + 0x0700b32b, 0x302b0401, 0x21150131, 0x23038335, 0xa2fb5e04, 0x03310383, 0xfe89898b, 0x008a8a8c, 0xd3000200, 0xd1028bfe, 0x43378506, 0x42430745, + 0x0c002408, 0x8209b0f4, 0xb1dc2a89, 0x00f40c04, 0xb02f02b0, 0x0d7f4104, 0x4500b024, 0xd641b058, 0x2a688207, 0x023b1123, 0x5c012311, 0x82ec8989, + 0x088b2362, 0xef42f800, 0x259b8208, 0xb33e000b, 0x2b780803, 0x05924605, 0x0e00b128, 0xd008b0f4, 0xc0780bb0, 0x2f032b09, 0x1103b11b, 0x08b3593e, + 0xc2830907, 0xc2820520, 0x8200b021, 0x84d02084, 0x23113dc8, 0x21112111, 0x04152315, 0x8ab9fd5e, 0x5c017501, 0x8a1702d3, 0x8c03fefc, 0xeb897401, + 0xd1836d82, 0x025e0427, 0x000b00d1, 0x060f4649, 0xbf840320, 0x100cb022, 0x08276a83, 0x0c07b12f, 0x1804b0f4, 0x87091747, 0x20cc8471, 0x207e8207, + 0x217e8307, 0x78820700, 0x070ab323, 0x06414105, 0x23207882, 0x04237c84, 0x8273fe5e, 0x75012ede, 0xfc89d102, 0xfd480243, 0x01d102b8, 0x064b4175, + 0x825e0421, 0x460520e7, 0x74820a8b, 0xb0d00226, 0x01b12f02, 0x0d277482, 0xdc09b010, 0x460c0ab1, 0x0120068b, 0x01206b82, 0x42074561, 0x03220800, + 0xf7820007, 0x07050622, 0x72837884, 0x21021d22, 0x01240682, 0x8b03895c, 0x03277a82, 0x0589fb02, 0x84eb8900, 0x05e142f4, 0x82170221, 0x000b2575, + 0x0e07b33b, 0x0922b483, 0x2d5b0a08, 0x82022005, 0x10012373, 0xf95004b0, 0x22628806, 0x82030706, 0x05012162, 0xb0206882, 0x63421f82, 0x35332205, + 0x06636e23, 0x01d3d330, 0x018abb5c, 0x89eb8a8d, 0x74fc8cfe, 0x65860203, 0x5541d120, 0x0c4e410c, 0xb0d00022, 0x6841dc82, 0x0a094805, 0x5541dc87, + 0x8209200a, 0x41022079, 0x11200655, 0x2320d783, 0x233edb82, 0x015c0135, 0x89ec8975, 0xfed102d3, 0x022ffd8b, 0x03b8fd48, 0x020089bd, 0x8bfe0000, + 0x5341d102, 0xb3422406, 0x820b0e06, 0x0c03213e, 0x0b29b883, 0xd001b010, 0xb11006b0, 0x074f4108, 0x0caa6c18, 0x4f417288, 0x04092207, 0x0556492b, + 0x03231122, 0xba417284, 0x25748305, 0xfb890203, 0xea840300, 0x01008a2e, 0x8d018d01, 0x8b065e04, 0x34000b00, 0x2105b143, 0x718409b3, 0xb110002a, + 0xb0f40e0b, 0x09b0d006, 0x2405af42, 0x09b32f03, 0x2b8b8205, 0x020705b3, 0x02b02b04, 0xd007b010, 0xd6826382, 0x21113330, 0x33152315, 0xfe020315, + 0x47028a8b, 0x5482d3d3, 0x8903752b, 0xe98900fd, 0x0001008c, 0x068b45d3, 0x35000b22, 0x2606a342, 0x00b1dc09, 0x42b0f40c, 0x0520082e, 0x00210c82, + 0x256b8210, 0x2f03b000, 0x688707b0, 0x01050622, 0x6284c684, 0x83113321, 0x48022366, 0xc4828bfe, 0x028d0132, 0x02740148, 0x02bbfdcf, 0x8b48fc45, + 0x00020000, 0xc7847482, 0xc9820520, 0x67863220, 0x00266082, 0x2f00b0d0, 0x8f4203b1, 0x0c062508, 0x01b000f4, 0x03206484, 0x0922cd84, 0x64830607, + 0x5e841320, 0x05840120, 0x0389d326, 0x89eafd02, 0x8d26c582, 0x8cfbfe04, 0xcc85018a, 0xcb820020, 0x79820020, 0x8b061722, 0x2e246382, 0x020808b3, + 0x22070f7c, 0x841008b0, 0x06e644d1, 0xb02f0926, 0x03b32f05, 0x200b2741, 0x06704213, 0x23112136, 0x01191935, 0x8bfe8a8d, 0xe91902a2, 0xfc000389, + 0x8c8bfe77, 0x02235b84, 0x84d10248, 0x0727415b, 0x20082041, 0x22bf820b, 0x43b0d004, 0xc2840552, 0x20052741, 0x063e4301, 0xc2830920, 0x54351121, + 0x2136077b, 0xec89d311, 0x028bfe89, 0xba038948, 0x4502bbfd, 0x8cfe31fd, 0x64820200, 0x61848d20, 0xbf840520, 0x000e0522, 0x0921bf82, 0x05f1530c, + 0x4102b121, 0xa6450584, 0x2f072406, 0x820506b3, 0x09014756, 0x17255c83, 0x21113311, 0x235c8335, 0x02032ffd, 0xeb2abc84, 0x02fb7404, 0x0200008a, + 0xfb458d01, 0x235d8306, 0x0803b331, 0xb0275d82, 0x08b01003, 0x4400b0d0, 0x0120057f, 0x220efd45, 0x82070506, 0x48032080, 0x01200569, 0xfc435a83, + 0x478d2006, 0x03240522, 0xfd890302, 0x4508fc43, 0x042505bf, 0x008b065e, 0x20bf8203, 0x09e3414c, 0xb0d00126, 0x00b12f01, 0x2005e341, 0x05ff4405, + 0xb0100524, 0xc545d009, 0x2f0a2d18, 0x110ab11b, 0x07b3593e, 0x2b040807, 0x4807cb45, 0x5c240582, 0x89ec8989, 0x732bcc82, 0x088bfe89, 0x8946fc00, + 0x820043fc, 0x86d32071, 0x000330dd, 0x000f0009, 0x2f10b058, 0xb02f11b0, 0x89b01010, 0x1011237d, 0x7d8507b0, 0xb0100729, 0x04b0d00c, 0x850eb010, + 0x46052083, 0x0d201249, 0x0d208382, 0x0a248383, 0x2b040b05, 0x04208982, 0x33218986, 0x0a0a4113, 0x77208d8e, 0x200e1141, 0x06914900, 0x22057341, + 0x5c020805, 0x06260573, 0x1002b0d0, 0x714708b0, 0x08204409, 0x200ed441, 0x2b6a8221, 0x11231115, 0x8d013521, 0x73fe8a8a, 0x2407d441, 0x020374fc, + 0x0791448a, 0x008b0623, 0x17714107, 0x4205bb47, 0x08280598, 0xb000f40c, 0x08b02f06, 0x7141ed92, 0x09c44808, 0x33352322, 0x21074147, 0x4347d3d3, + 0xbd032a05, 0xf8ba0389, 0x03000000, 0x20d98300, 0x207982d1, 0x23798205, 0xb354000f, 0x2205ad42, 0x840c0c0d, 0x02b126e1, 0x05b0f40c, 0x05c94c10, + 0x230a6242, 0x0cb02f03, 0x68187d85, 0x0e270c26, 0x0eb11b2f, 0x42593e11, 0xfe8313d3, 0x0135232d, 0xd3231133, 0x02d38989, 0x41898948, 0x04210c04, + 0x208f8374, 0x228f8302, 0x41035e04, 0x28200509, 0x47145d49, 0x012105c3, 0x06de4e05, 0x480b6349, 0xfd330590, 0xd1028ab9, 0x8d01a2fb, 0xfefc8a8a, + 0xfe010203, 0x41008989, 0x04240563, 0x00d1025e, 0xd542e983, 0x2e49470a, 0x03070022, 0x2305714c, 0x03b0d006, 0x25079b45, 0x35231123, 0x50471521, + 0x04d32506, 0x8973fe5e, 0xba288182, 0x8989bd03, 0x460443fc, 0x84066741, 0x000530d7, 0x000f0009, 0x0e00b34e, 0xb32b0405, 0x840e0c0d, 0x0767414d, + 0x55470820, 0x0cc54706, 0x2208c142, 0x82070706, 0x05002133, 0x0a208186, 0x0b268184, 0x013130d0, 0x81822311, 0x47069249, 0x858205d6, 0x85a2fb21, + 0xfc172b89, 0x8a020374, 0x89897401, 0xe0478cfe, 0x05a34405, 0x574b0420, 0x000b2205, 0x0591461e, 0x03b00025, 0x4408b32f, 0x854a098d, 0x021d330e, + 0x8d013521, 0xfb47028a, 0x890203a2, 0x00fd0003, 0xef49eb89, 0x4c002005, 0x0b220805, 0x2f443800, 0x05594109, 0x13460520, 0x0a50450d, 0x1000b025, + 0x83d006b0, 0x82092065, 0x0a5645c3, 0x89d31536, 0x8d0189ec, 0x03894802, 0x04bdfbba, 0x8946fc43, 0x00000300, 0x26064147, 0x000b0005, 0x423a000f, + 0x574506a9, 0xd00e210f, 0xb028c683, 0x0cb32f07, 0x2b040d05, 0x98055745, 0x85d38369, 0x20d4866c, 0x07f943fc, 0x41069543, 0x0f220623, 0x674b3d00, + 0xd00a2609, 0xb01002b0, 0x09f5430c, 0x1b2f0b27, 0x3e110bb1, 0x113c4159, 0x1009b024, 0xdc840db0, 0x6c442120, 0x06464109, 0x44b9fd21, 0xfd200708, + 0x21067c45, 0xa7428a02, 0x8b062308, 0xe5820700, 0xff445b20, 0x44032006, 0x032805ef, 0xd006b010, 0xb01010b0, 0x0a278282, 0x0c09b12f, 0x440ab0f4, + 0x052005fc, 0x4a080e44, 0x9d490c79, 0x07002108, 0x6b06f04c, 0x938305d0, 0x21150124, 0x95822311, 0x08053c42, 0x04113320, 0x8973fe5e, 0x898bfe89, + 0xd102d3d3, 0x0843fc89, 0x0346fc00, 0x0300f8ba, 0xba0389bd, 0x99430400, 0x06294405, 0x17001124, 0x81417800, 0x440f2006, 0xb02a1c2b, 0x14b0100f, + 0x100cb0d0, 0x304116b0, 0x440d2005, 0x15241237, 0x15b11b2f, 0x2f0e3744, 0xb01000b0, 0x01b0d00c, 0xd00fb010, 0xb01006b0, 0x20056852, 0x08294213, + 0x20054f44, 0x09564125, 0x8989d32a, 0x894602d3, 0x71fe8f01, 0x200d5a44, 0x0bcc45eb, 0xeeff012c, 0xb603eeff, 0x0300b803, 0x554a1d00, 0x0f71740a, + 0x0931302d, 0xfeb60303, 0x011bfe1d, 0x84d301e5, 0x00e53605, 0x08000100, 0x5604cfff, 0x0500ec02, 0xb0000900, 0x01b02f05, 0x0829822f, 0x01370229, + 0xfc560401, 0x5eb6fefc, 0xa4020201, 0x35fd9a02, 0xfe3bfe01, 0x00730271, 0x00f2ff02, 0x03b40300, 0x000800aa, 0x4153000f, 0xb02208cf, 0x4d521010, + 0x090d2706, 0x1003b0f4, 0x53500eb1, 0x0c936907, 0x1b2f032a, 0x3e0f03b1, 0x0209b359, 0x27060d4a, 0x09b0d005, 0xd00bb010, 0x0d2f3383, 0x3130f401, + 0x11231501, 0x35231121, 0x82330309, 0x03240807, 0x10feebb4, 0x01e101e7, 0xfea0fe60, 0x1001d99e, 0xfe6bc701, 0x6b5c01a4, 0x00fee301, 0x9efe6201, + 0x3b01c5fe, 0x0c20958c, 0x20070741, 0x206b8207, 0x79e51807, 0x855f820f, 0x0101225e, 0x265e8b05, 0xfea4fee1, 0x875c01f4, 0x1f1d3b5a, 0xf4fe0c01, + 0x00000300, 0x1404d9ff, 0x0c008103, 0x14001000, 0x00b33000, 0xe34f0809, 0x010c2a06, 0xb32b0409, 0x04000108, 0x0516432b, 0x100cb034, 0xb0d00fb0, + 0x11b01000, 0x1008b0d0, 0x30d013b0, 0xbf512531, 0x08d08207, 0x21052123, 0x23032135, 0x14043335, 0x4fbe17fe, 0x4401bcfe, 0x7901be4f, 0xfd2b01bb, + 0x018dfe5f, 0xbabab973, 0x07bf51e5, 0x6dc00131, 0x64fd6d6d, 0x0004006f, 0x04000048, 0x82140514, 0x00072a09, 0x0019000d, 0x090db367, 0x22798201, + 0x82110910, 0x0a072205, 0x8405820a, 0x11b02895, 0xd015b010, 0x181010b0, 0x640879fa, 0x002b0c75, 0x00b11b2f, 0xb3593e0f, 0x820e0119, 0x02052132, + 0xac82be82, 0x0108b128, 0x1002b0f4, 0x06820bb1, 0xb0100e29, 0x19b0d012, 0x5114b010, 0x212705ee, 0x15272301, 0x82211101, 0x23012401, 0x82352315, + 0x333522bb, 0x08bf8215, 0x0234fc3d, 0x9d950137, 0xfe2501f8, 0x0291fe81, 0xb36cb200, 0x05b26cb3, 0xfa6dfe14, 0x02eefcfa, 0xfb7f01b8, 0xb12b01c9, + 0xb2b26eb1, 0x4a000200, 0x5e04d3ff, 0x0800d103, 0x22000c00, 0x820909b3, 0xb00022b1, 0xefbc1803, 0x080b6708, 0xd4180820, 0x07240819, 0x01170101, + 0x11297d82, 0xfd5e0433, 0x4e7901d1, 0x084682fe, 0x87fe4e35, 0x5afc2f02, 0x9a016e6e, 0x024e87fe, 0x4efe0100, 0xf8fd85fe, 0x0000a203, 0xff0a0001, + 0x037b04d9, 0x0015007d, 0x0903b318, 0x002b0415, 0xb32f0db0, 0x82020101, 0x094808ea, 0x2b040f01, 0x21133130, 0x1e142115, 0x27213302, 0x27010137, + 0x2e222137, 0x020a3502, 0x454afe25, 0x015ca079, 0x014ebf75, 0x4ebcfe44, 0x758bfebf, 0x035496ca, 0xa05c6f7d, 0x4ebe4678, 0xbefebbfe, 0x9858c04c, + 0x030070c9, 0xd924c982, 0x81035c04, 0x07280982, 0x30001400, 0x0c0911b3, 0x09236983, 0x8303b32f, 0x07b323bb, 0xdf5f0401, 0xd00b3205, 0xb01003b0, + 0x00b0d00d, 0xd00fb010, 0xb01007b0, 0x06b05611, 0x35231124, 0x7e830533, 0x15211124, 0x8b821123, 0xfe5c043d, 0xb8700190, 0xfeacfeb8, 0xfebe4ebb, + 0xbd2b0117, 0x4ebe7b01, 0xfd6d1403, 0x83396f64, 0x9c02307c, 0xbe40fe6d, 0x0002004e, 0x04d3ff00, 0x82d10314, 0x000c267f, 0x0900b322, 0x207d8301, + 0x0849410c, 0x2208e241, 0x8307010a, 0x232123f1, 0xea823311, 0x21012408, 0x37012135, 0x6e6e1404, 0x02fef0fe, 0xfd7b0150, 0xfe3102cf, 0xa2035085, + 0x00fe31fe, 0x6e79014e, 0x824e7b01, 0x00023753, 0x05680404, 0x00240044, 0x00540048, 0x2f55b0c1, 0xb02f56b0, 0x57711055, 0x10562906, 0xb1dc21b0, + 0xb4f40a27, 0x236c7b18, 0x21b03408, 0xd02db010, 0xb02f2db0, 0x39b11010, 0x1b40f40a, 0x39163906, 0x39363926, 0x39563946, 0x39763966, 0x39963986, + 0x39b639a6, 0x5d0d39c6, 0xe539d5b4, 0x835d0239, 0xd0472734, 0x002f47b0, 0x574552b0, 0x2f2f2405, 0x432fb11b, 0x352007c4, 0x35200c82, 0xb3250c82, + 0x040c0245, 0x08c0562b, 0x35b02108, 0x021db110, 0xd014b0f4, 0xb02f14b0, 0x3db01045, 0x2f3db0d0, 0x06013130, 0x22230607, 0x22232627, 0x352a0785, + 0x33363734, 0x16161732, 0x08843233, 0x14150626, 0x26071617, 0x36221683, 0x26833737, 0x2c850720, 0x23861783, 0x03222b84, 0x4a820714, 0x07069608, + 0x16162512, 0x4e246804, 0x472d5e63, 0x48292d4a, 0x777b224a, 0x9a5a4e79, 0x372b5639, 0x5656220d, 0x926d9332, 0x9a263331, 0x070a0431, 0x115c2024, + 0x6888915e, 0x333e730e, 0x14465c6b, 0x3f3c5c31, 0x331a385a, 0x378e0f4e, 0x2b0c4c35, 0x0601021d, 0x6f010202, 0x1b876d75, 0xd11d1a1a, 0x73a5c5d3, + 0x0a0d1889, 0x7b851c19, 0x56505a8b, 0x67cb7641, 0x0a0e045a, 0x21142927, 0x5b6c121d, 0xa2b6b37c, 0x151f2313, 0x31041975, 0x19585256, 0x01040404, + 0x0e093c0a, 0x054d7100, 0x2f05bc22, 0x01c1dd10, 0x00012d42, 0x00700200, 0x00070061, 0x00040058, 0x00290d82, 0x000a0000, 0x02000200, 0x830482a6, + 0x0038210f, 0x4a090185, 0x027701c4, 0x0356037f, 0x03b3036e, 0x044504f9, 0x04910479, 0x04b804a3, 0x058705cd, 0x062f06c2, 0x073007e5, 0x087e08c2, + 0x0ac209c6, 0x0aac0a82, 0x0bee0ad6, 0x0b230b0a, 0x0cbc0c9d, 0x0e6e0def, 0x0e770e17, 0x0fdf0eae, 0x10ce0f87, 0x10481002, 0x10aa1087, 0x114211fb, + 0x134a12ed, 0x14911320, 0x15a91456, 0x15371509, 0x16ee1581, 0x168e1647, 0x16cb16b8, 0x171917f6, 0x183e172b, 0x19b11803, 0x1a041a57, 0x1bef1a77, + 0x1c1b1cb3, 0x1cab1c65, 0x1d241dee, 0x1e2a1ec2, 0x20831fd5, 0x219b2033, 0x22c22154, 0x2258222a, 0x230b23a2, 0x238b2343, 0x24f823e4, 0x24862451, + 0x25062592, 0x25c925bd, 0x25e125d5, 0x26f825ed, 0x260e2603, 0x26242619, 0x26e9262f, 0x27ff26f4, 0x2715270a, 0x272b2720, 0x27412736, 0x2757274c, + 0x276d2762, 0x27832778, 0x2799278e, 0x27af27a4, 0x284928d2, 0x2a4d29cb, 0x2a362a0c, 0x2c7c2ba8, 0x2dfb2c35, 0x2d6d2d59, 0x2edd2d98, 0x2f0b2f2e, + 0x2fb62f80, 0x30f92fd7, 0x31cf305d, 0x31ad316a, 0x326632f0, 0x335933a4, 0x359734f1, 0x3657368e, 0x370537d2, 0x373f371c, 0x38f837bc, 0x3844381e, + 0x82a13869, 0xad8c0b01, 0xc538b938, 0x173a5739, 0x3a3a283a, 0xf83a9c3a, 0x5c3b2d3b, 0xb83b903b, 0xcf3bc33b, 0x813ce93b, 0xaf3c983c, 0xbe3d3a3d, + 0x183e073e, 0xb23e4f3e, 0xf13fe53f, 0x0940fd3f, 0x21401540, 0x39402d40, 0x51404540, 0x69405d40, 0xcc40c040, 0xe440d840, 0x2641f040, 0x67413e41, + 0x96417941, 0xfc41af41, 0x3e422142, 0x8a427142, 0xd442ad42, 0x8043ec42, 0xb243a043, 0x87440d44, 0x4d45b844, 0xb646dc45, 0x54472b47, 0xbc476047, + 0x73486848, 0x29491d49, 0x40493449, 0xb7494b49, 0x9c4a904a, 0xb34aa74a, 0xca4abe4a, 0xe14ad54a, 0xf84aec4a, 0xae4ba64b, 0x7f4c734c, 0x964c8a4c, + 0xad4ca14c, 0x1f4db84c, 0xd14dc54d, 0xe84ddc4d, 0xff4df34d, 0x164e0a4e, 0x2c4e214e, 0x124f064f, 0x924f1e4f, 0x1f501350, 0x36502a50, 0x4d504150, + 0xbe505850, 0x46513a51, 0x3d52a851, 0x8c524952, 0xa2529752, 0xed52e152, 0x0453f952, 0x1b530f53, 0x33532753, 0x81533f53, 0xf153e553, 0x0754fc53, + 0x1e541254, 0x35542954, 0x0e558c54, 0x25551a55, 0x3c553155, 0x53554855, 0x6a555f55, 0x80557555, 0x97558c55, 0xae55a355, 0xc555ba55, 0x26577f56, + 0x3d573257, 0x53574857, 0x6b575f57, 0x5b58d557, 0x72586758, 0x89587e58, 0xa0589558, 0xb758ac58, 0xce58c358, 0xd8595b59, 0xef59e459, 0x065afb59, + 0x1d5a125a, 0x345a295a, 0x4b5a405a, 0xc95abd5a, 0xe05ad45a, 0xf65aeb5a, 0x0c5b015b, 0x2a5b175b, 0x6d5b615b, 0x855b795b, 0x9d5b915b, 0xb55ba95b, + 0xf35bc05b, 0x975c725c, 0xf45cbd5c, 0x825d3b5d, 0x6b5e375e, 0xd75eaa5e, 0x6f5f285f, 0x7e60d35f, 0x1361b660, 0xa9615661, 0x8d620262, 0x5263fa62, + 0x6a635e63, 0x80637563, 0x96638b63, 0x4764a163, 0x56651865, 0xd4662f66, 0xca675367, 0xaa685d68, 0x3d69e968, 0xf969c669, 0x586bad6a, 0x916cf96b, + 0x846d346d, 0x9c6efc6d, 0x2e6fdb6e, 0xee6fe36f, 0x0470f96f, 0x1a700f70, 0xd0702670, 0x7b71dc70, 0x6f723b72, 0xc1727b72, 0xd2735673, 0x55744974, + 0xa2746174, 0x3675d574, 0xda75b575, 0x66762f76, 0x9977d076, 0xed77e177, 0x94782c78, 0x2c79e578, 0x0f7ad779, 0x157b6c7a, 0xbb7b687b, 0xb37c467c, + 0x447df37c, 0xee7d9b7d, 0xba7e4e7e, 0xb67f147f, 0xd1805c80, 0x6d829681, 0x25830083, 0xea837783, 0xf9845384, 0x4c854185, 0xf3858b85, 0x8b864486, + 0x6e873687, 0xc2881c88, 0x4d891589, 0x948a2b8a, 0x248bd48a, 0xd18b7b8b, 0x9e8c318c, 0x6a8df98c, 0x738e028e, 0x0f8f7e8e, 0x8a8f1a8f, 0x8a904090, + 0xdb909590, 0xd9915e91, 0x66925b92, 0xb2927192, 0x1a93e692, 0x32932693, 0x4a933e93, 0x62935693, 0x79936e93, 0x90938593, 0xa7939c93, 0xbf93b393, + 0xd693cb93, 0xed93e293, 0x0494f993, 0x1b941094, 0xea942d94, 0x2095fc94, 0x69962f96, 0xe3969c96, 0xa9971d97, 0x1198e097, 0x3c982298, 0x77985a98, + 0xa8989098, 0xf298cd98, 0x33991599, 0x82996699, 0xeb99b499, 0x639a289a, 0xd29a969a, 0x3d9b0c9b, 0xa39b709b, 0x029cd19b, 0x629c319c, 0xeb9ca09c, + 0x589d1b9d, 0xcd9da09d, 0x549e0c9e, 0xad9e7a9e, 0x219fe69e, 0xd19f6d9f, 0x09a0f09f, 0x80a054a0, 0x22a1c1a0, 0x87a154a1, 0xf6a1c7a1, 0x78a3d2a2, + 0x01000000, 0xc52c0384, 0x84a049fe, 0xf53c0f5f, 0x00081b00, 0xc6230083, 0x83d045f5, 0x31d52b07, 0x5bff7e09, 0x7b0475fe, 0x0f823e07, 0x02000923, + 0x23008400, 0x31005e04, 0x04840884, 0xffecff2b, 0x007501e7, 0x00e500bc, 0x28108223, 0x010000f0, 0xff290075, 0x220b82df, 0x821b000a, 0xff042805, + 0xff3100f8, 0x82e9fff8, 0x00f02217, 0x261182c7, 0xffa8008f, 0x82c5ffdf, 0x82ec2015, 0x86312049, 0xffba2207, 0x820d85fe, 0x85df200f, 0x19002103, + 0x31272d82, 0xc1ffc5ff, 0x82ffe9ff, 0x2241822b, 0x84ba0085, 0x84e52087, 0xff00252d, 0x00fcfffe, 0xba223985, 0x3f820400, 0x3184ba20, 0x07822b82, + 0xf6ff0022, 0xe1220d84, 0xa582e5ff, 0x2f00e126, 0x8d01ba00, 0xfc202d82, 0xc5205182, 0x65864f83, 0x02892482, 0x85fcff21, 0x22678201, 0x82aa00ba, + 0x82312005, 0x85ec203b, 0x829f8703, 0x00002215, 0x200d8208, 0x20098214, 0x2007821f, 0x20938400, 0x200d82f2, 0x20ab8200, 0x20f182d3, 0x203f8400, + 0x21db8400, 0x0083002b, 0xf8ff0424, 0x4782eeff, 0xd5ffdb26, 0x2f02d100, 0x17221282, 0x0f820400, 0x0e00c524, 0xad848d00, 0x9782c520, 0xf2ffdf2d, + 0x0000dbff, 0x3700a4ff, 0x83010000, 0x8200207f, 0x82e12035, 0x000226ad, 0x01c70000, 0x82058248, 0x7501235b, 0x25822e02, 0xc5ffec22, 0x03826182, + 0x2d83f984, 0xdfffba26, 0x0200dfff, 0x31200382, 0xc383ad84, 0x8b824e20, 0x7501b624, 0x0182f200, 0xf002aa24, 0x0b82aa00, 0x3701ba25, 0x8301d9ff, + 0xff1b2277, 0x265384fe, 0xfffeff00, 0x8262008b, 0xff312469, 0x84e1ffec, 0x82002057, 0x8203825f, 0x83ec2019, 0x8203896d, 0xff00225b, 0x2239828b, + 0x82fcff31, 0x82038c29, 0x8bfe203d, 0x262b8203, 0xff77ff31, 0x824e0077, 0x83ba2001, 0xb600218b, 0x09830582, 0x43827882, 0x57410420, 0x8231200a, + 0x21038619, 0x0b845eff, 0x0583c785, 0x49840120, 0x5b82df20, 0x0f820386, 0x03880020, 0xf6ff1923, 0x82038b00, 0x8902885b, 0x21098c43, 0x1942c1ff, + 0x00312206, 0x8547822f, 0x82ba2003, 0xffdb2415, 0x84d5ffd3, 0x2142824d, 0xf7828d01, 0x5fffc528, 0x17005fff, 0x01835bff, 0x8b840f83, 0x22057941, + 0x83dfff31, 0x85ff20a9, 0x4100200d, 0x2b20067b, 0xec242582, 0xe9ffecff, 0xba202982, 0x2006bf41, 0x2227820c, 0x84020000, 0x822720b3, 0x0002245a, + 0x8429000c, 0x84e1203b, 0x82022013, 0x00312127, 0x00220583, 0x3b823100, 0x0582f820, 0x1f84f220, 0x0984ec20, 0x77ff3122, 0xec220782, 0x13821900, + 0xfeffba24, 0x0d8275ff, 0x03827720, 0x8505ad41, 0x223983db, 0x821b00c1, 0x210f824f, 0xa784e7ff, 0x0584df20, 0x9182ec20, 0x5582e120, 0xc1439183, + 0xff312109, 0xf4226583, 0x8f82feff, 0x23823182, 0xf0fffc22, 0x4d840d82, 0x7d823f86, 0x00249f84, 0xe3ffe1ff, 0x3f8aa384, 0x82230021, 0xfff42481, + 0x838ffffc, 0xf6ff2123, 0x00219b83, 0x829b8404, 0x82ff2011, 0x08df419b, 0x57843120, 0x4b84ba20, 0x19205f83, 0x76822d82, 0xffc1ff23, 0x200388e5, + 0x823182ec, 0x24878213, 0xff4400d3, 0x200a82d3, 0x2a03824a, 0x00e3ffbc, 0x01000048, 0x838d018d, 0x82038505, 0x24028517, 0x008d01d3, 0x840182d3, + 0x840b970d, 0x27048c1c, 0x0800eeff, 0xf2fff2ff, 0x48241482, 0x0a004a00, 0x00200382, 0x31067d41, 0x06000001, 0x008bfe8b, 0xff5e0400, 0x04e3ff5e, + 0x1182007b, 0x02892782, 0x0300012e, 0x90015e04, 0x00000500, 0x33059a05, 0x25209182, 0x03390785, 0x017b00a0, 0x020105d1, 0x03090606, 0x05000202, + 0x0200a004, 0xa90070af, 0x293c87ca, 0x73736c6d, 0x00004000, 0x638502fb, 0x018b0627, 0x00002075, 0x231f839f, 0x1905a403, 0x0e820782, 0x01220582, + 0x00830100, 0x000c002d, 0x00ff08f8, 0xff070008, 0x820900fe, 0x82fe20b3, 0x820920ab, 0x000b240b, 0x82fdff09, 0x820a201d, 0x000d2205, 0x2205820b, + 0x820c000e, 0x000f2205, 0x2205820d, 0x820e0010, 0x82112005, 0x00fc2a05, 0xff0f0012, 0x001300fc, 0x22058210, 0x82110014, 0x00152205, 0x20058212, + 0x2a058216, 0x001700fb, 0x00fbff13, 0x82140018, 0x00192205, 0x22058215, 0x8216001a, 0x001b2205, 0x20058217, 0x2a05821c, 0x001d00fa, 0x00faff18, + 0x8219001e, 0x001f2205, 0x2205821a, 0x821b0020, 0x82212005, 0x00f92a05, 0xff1c0022, 0x002300f9, 0x2205821d, 0x821e0024, 0x00252205, 0x2205821f, + 0x82200026, 0x82272005, 0x00f82a05, 0xff210028, 0x002900f8, 0x22058222, 0x8223002a, 0x002b2205, 0x20058224, 0x2a05822c, 0x002d00f7, 0x00f7ff25, + 0x8226002e, 0x002f2205, 0x22058227, 0x82280030, 0x00312205, 0x20058229, 0x2a058232, 0x003300f6, 0x00f6ff2a, 0x822b0034, 0x00352205, 0x2205822c, + 0x822d0036, 0x82372005, 0x00f52a05, 0xff2e0038, 0x003900f5, 0x2205822f, 0x8230003a, 0x003b2205, 0x22058231, 0x8232003c, 0x823d2005, 0x00f42a05, + 0xff33003e, 0x003f00f4, 0x22058234, 0x82350040, 0x00412205, 0x20058236, 0x2a058242, 0x004300f3, 0x00f3ff37, 0x82380044, 0x00452205, 0x22058239, + 0x823a0046, 0x00472205, 0x2005823b, 0x2a058248, 0x004900f2, 0x00f2ff3c, 0x823d004a, 0x004b2205, 0x2205823e, 0x823f004c, 0x824d2005, 0x00f12a05, + 0xff40004e, 0x004f00f1, 0x22058241, 0x82420050, 0x00512205, 0x22058243, 0x82440052, 0x82532005, 0x00f02a05, 0xff450054, 0x005500f0, 0x22058246, + 0x82470056, 0x00572205, 0x20058248, 0x2a058258, 0x005900ef, 0x00efff49, 0x824a005a, 0x005b2205, 0x2205824b, 0x824c005c, 0x005d2205, 0x2005824d, + 0x2a05825e, 0x005f00ee, 0x00eeff4e, 0x824f0060, 0x00612205, 0x22058250, 0x82510062, 0x82632005, 0x00ed2a05, 0xff520064, 0x006500ed, 0x22058253, + 0x82540066, 0x00672205, 0x22058255, 0x82560068, 0x82692005, 0x00ec2a05, 0xff57006a, 0x006b00ec, 0x22058258, 0x8259006c, 0x006d2205, 0x2005825a, + 0x2a05826e, 0x006f00eb, 0x00ebff5b, 0x825c0070, 0x00712205, 0x2205825d, 0x825e0072, 0x00732205, 0x2005825f, 0x2a058274, 0x007500ea, 0x00eaff60, + 0x82610076, 0x00772205, 0x22058262, 0x82630078, 0x82792005, 0x00e92a05, 0xff64007a, 0x007b00e9, 0x22058265, 0x8266007c, 0x007d2205, 0x22058267, + 0x8268007e, 0x827f2005, 0x00e82a05, 0xff690080, 0x008100e8, 0x2205826a, 0x826b0082, 0x00832205, 0x2005826c, 0x2a058284, 0x008500e7, 0x00e7ff6d, + 0x826e0086, 0x00872205, 0x2205826f, 0x82700088, 0x00892205, 0x20058271, 0x2a05828a, 0x008b00e6, 0x00e6ff72, 0x8273008c, 0x008d2205, 0x22058274, + 0x8275008e, 0x828f2005, 0x00e52a05, 0xff760090, 0x009100e5, 0x22058277, 0x82780092, 0x00932205, 0x22058279, 0x827a0094, 0x82952005, 0x00e42a05, + 0xff7b0096, 0x009700e4, 0x2205827c, 0x827d0098, 0x00992205, 0x2005827e, 0x2a05829a, 0x009b00e3, 0x00e3ff7f, 0x8280009c, 0x009d2205, 0x22058281, + 0x8282009e, 0x009f2205, 0x20058283, 0x2a0582a0, 0x00a100e2, 0x00e2ff84, 0x828500a2, 0x00a32205, 0x22058286, 0x828700a4, 0x82a52005, 0x00e12a05, + 0xff8800a6, 0x00a700e1, 0x22058289, 0x828a00a8, 0x00a92205, 0x2205828b, 0x828c00aa, 0x82ab2005, 0x00e02a05, 0xff8d00ac, 0x00ad00e0, 0x2205828e, + 0x828f00ae, 0x00af2205, 0x20058290, 0x2a0582b0, 0x00b100df, 0x00dfff91, 0x829200b2, 0x00b32205, 0x22058293, 0x829400b4, 0x00b52205, 0x20058295, + 0x2a0582b6, 0x00b700de, 0x00deff96, 0x829700b8, 0x00b92205, 0x22058298, 0x829900ba, 0x82bb2005, 0x00dd2a05, 0xff9a00bc, 0x00bd00dd, 0x2205829b, + 0x829c00be, 0x00bf2205, 0x2205829d, 0x829e00c0, 0x82c12005, 0x00dc2a05, 0xff9f00c2, 0x00c300dc, 0x220582a0, 0x82a100c4, 0x00c52205, 0x200582a2, + 0x2a0582c6, 0x00c700db, 0x00dbffa3, 0x82a400c8, 0x00c92205, 0x220582a5, 0x82a600ca, 0x00cb2205, 0x200582a7, 0x2a0582cc, 0x00cd00da, 0x00daffa8, + 0x82a900ce, 0x00cf2205, 0x220582aa, 0x82ab00d0, 0x82d12005, 0x00d92a05, 0xffac00d2, 0x00d300d9, 0x220582ad, 0x82ae00d4, 0x00d52205, 0x220582af, + 0x82b000d6, 0x82d72005, 0x00d82a05, 0xffb100d8, 0x00d900d8, 0x220582b2, 0x82b300da, 0x00db2205, 0x200582b4, 0x2a0582dc, 0x00dd00d7, 0x00d7ffb5, + 0x82b600de, 0x00df2205, 0x220582b7, 0x82b800e0, 0x00e12205, 0x200582b9, 0x2a0582e2, 0x00e300d6, 0x00d6ffba, 0x82bb00e4, 0x00e52205, 0x220582bc, + 0x82bd00e6, 0x82e72005, 0x00d52a05, 0xffbe00e8, 0x00e900d5, 0x220582bf, 0x82c000ea, 0x00eb2205, 0x220582c1, 0x82c200ec, 0x82ed2005, 0x00d42a05, + 0xffc300ee, 0x00ef00d4, 0x220582c4, 0x82c500f0, 0x00f12205, 0x200582c6, 0x2a0582f2, 0x00f300d3, 0x00d3ffc7, 0x82c800f4, 0x00f52205, 0x220582c9, + 0x82ca00f6, 0x00f72205, 0x200582cb, 0x2a0582f8, 0x00f900d2, 0x00d2ffcc, 0x82cd00fa, 0x00fb2205, 0x220582ce, 0x82cf00fc, 0x82fd2005, 0x00d12a05, + 0xffd000fe, 0x00ff00d1, 0x280582d1, 0x00040000, 0x0a740200, 0x00001005, 0x00236f02, 0x10060b00, 0x6f020000, 0x0c000023, 0x00001007, 0x00226f02, + 0x02100d00, 0x216f0272, 0x00830007, 0x00000224, 0x03820300, 0x03001424, 0x07840100, 0xce030422, 0xb2260782, 0x06008000, 0x09823200, 0x000dae08, + 0x007e0022, 0x013001ff, 0x01510131, 0x01770153, 0x017f0178, 0x02ff0192, 0x02c7021b, 0x038603dd, 0x038c038a, 0x03a803a1, 0x03bf03a9, 0x04ce03c0, + 0x044f040c, 0x045f045c, 0x1e031e91, 0x1e1f1e0b, 0x1e571e41, 0x1e6b1e61, 0x20f31e85, 0x201a2015, 0x2022201e, 0x20302026, 0x2044203a, 0x211621ac, + 0x22262122, 0x22062202, 0x2212220f, 0x221e221a, 0x2248222b, 0x23652260, 0x23182303, 0x237d2326, 0x24ce2388, 0x25002523, 0x250c2502, 0x25142510, + 0x251c2518, 0x252c2524, 0x253c2534, 0x25c6256c, 0xe01327ca, 0xf9c3f607, 0xff02fb00, 0x2ab182ff, 0x000d0000, 0x00230020, 0x820001a0, 0x013224b3, + 0x82540152, 0x827920b3, 0x02fc2ab3, 0x02c60218, 0x038403d8, 0x22b38288, 0x82a3038e, 0x82aa20b3, 0xc12408b3, 0x0e040104, 0x5e045104, 0x021e9004, + 0x1e1e0a1e, 0x561e401e, 0x6a1e601e, 0xf21e801e, 0x18201320, 0x20201c20, 0x3920b384, 0x1120b390, 0x6420b38a, 0x2420b384, 0x5020b39e, 0x0026b386, + 0xfff8c3f6, 0xb38201fb, 0xf5ff0126, 0xe1ff0000, 0xf3320382, 0xf2ffa4ff, 0xf0ff5cff, 0xefff41ff, 0x73ff12ff, 0xd1835bff, 0xf3fd2d08, 0xf1fdf2fd, + 0xeffdf0fd, 0xeefdc6fe, 0xedfdd9fc, 0xbafdbbfd, 0xb8fdb9fd, 0x18e488fd, 0x00e412e4, 0xcce3e0e3, 0xbce3c4e3, 0x3ce3a8e3, 0x03833183, 0xe083e023, + 0x08038294, 0x0fe07652, 0x68df1be1, 0x94de77df, 0x89dea0de, 0x89de0000, 0x6fde72de, 0x2dde5dde, 0x30df2ede, 0x11df1cdf, 0xb1debbde, 0x18de6cde, + 0x3bdd3cdd, 0x2fdd32dd, 0x29dd2cdd, 0x1fdd26dd, 0x11dd18dd, 0xf7dc0add, 0xedda9edc, 0x662252db, 0x00001f0a, 0x0100bd05, 0x00215d83, 0x200582ae, + 0x900382b0, 0x5a012302, 0x14905c01, 0x0127109c, 0x013c0138, 0x95440140, 0x32012124, 0x15a61795, 0x2784f820, 0x0003f508, 0x00e100e0, 0x00a100aa, + 0x00830082, 0x009400e3, 0x008400e4, 0x0089008c, 0x00a7009b, 0x00e500a2, 0x00d80088, 0x00910081, 0x00e700e6, 0x0095008b, 0x00c10086, 0x00e800dc, + 0x00a8009c, 0x00ea00e9, 0x00a000eb, 0x00c700ab, 0x00ac00c5, 0x00610060, 0x0062008e, 0x006300c9, 0x00c800c6, 0x00ca00cd, 0x00cc00cb, 0x006400ec, + 0x00ce00d1, 0x00ad00cf, 0x00ed0065, 0x00d4008f, 0x00d300d2, 0x00ee0066, 0x008700ef, 0x00670068, 0x006b0069, 0x006c006a, 0x006d009e, 0x006e006f, + 0x00710070, 0x00720073, 0x00750074, 0x007600f0, 0x00770078, 0x007b0079, 0x00b6007a, 0x007d009f, 0x007e007c, 0x00f1007f, 0x00b800f2, 0x00df00d6, + 0x00da00d9, 0x00de00db, 0x00dd00d7, 0x02b100b0, 0x00b40030, 0x00c200b5, 0x00b300b2, 0x008000c3, 0x008500c0, 0x00320297, 0x006e02d0, 0x48082082, + 0x09b04b2c, 0x01b15850, 0xb8598e01, 0xb085ff01, 0x09b11d44, 0x2d5e5f03, 0x202c01b0, 0x44694520, 0x2d6001b0, 0xb02c02b0, 0x2d212a01, 0x202c03b0, + 0x2503b046, 0x23585246, 0x208a2059, 0x8a64498a, 0x68204620, 0x04b06461, 0x82078425, 0x8a652918, 0xb0202f59, 0x69585300, 0x54260582, 0x40b02158, + 0x0a881b59, 0x59596526, 0x04b02d3a, 0x31824683, 0x8a212d82, 0x20408259, 0x8240866a, 0x08128407, 0x2dfd2f29, 0x4b2c05b0, 0x2603b020, 0x58515850, + 0x1b4480b0, 0x594440b0, 0x2021211b, 0x50c0b045, 0x44c0b058, 0x5959211b, 0x8806b02d, 0x22ab82a3, 0x8518697d, 0x2c0727ad, 0x2d2a06b0, 0x418508b0, + 0xb0585329, 0x00b01b40, 0x838a8a59, 0x5853294f, 0x80b02123, 0x8a1b8a8a, 0x5f82c182, 0xc0200f84, 0xb8220f8d, 0x108f0001, 0x108b4020, 0x2503b027, + 0x8001b845, 0x824a8250, 0x21232206, 0x2310831b, 0x21232123, 0x5929a182, 0x09b02d44, 0x58534b2c, 0x31a28245, 0x002d5921, 0x00b00000, 0x01b2002b, + 0x012b0207, 0x058308b2, 0x4208b72e, 0x1825303f, 0xb72b0800, 0x3d3f5309, 0x0a240985, 0x2f3d5267, 0x0b211384, 0x211d874c, 0x0987530c, 0x52610d22, + 0x0e252786, 0x0f151b21, 0x223b8209, 0x8801b700, 0x8802203c, 0x4d03213c, 0x04203287, 0x05204688, 0x06206e88, 0x07204688, 0x003e5a87, 0x07040fb2, + 0x2000b02b, 0x18697d45, 0x2a000044, 0x5a006f00, 0x7b007900, 0x75008b00, 0x05828900, 0x7b200f83, 0x75220982, 0xcc825c01, 0x8dfe192c, 0xa2030000, + 0x14051900, 0x0f821900, 0x0c00002a, 0x03009600, 0x09040100, 0x76200d82, 0x0b850382, 0x1a000124, 0x17867600, 0x0e000224, 0x0b869000, 0x3e000324, + 0x0b869e00, 0x6d820420, 0x0b86dc20, 0x1a000524, 0x0b860601, 0x28000624, 0x0b862001, 0x5c000724, 0x0b864801, 0x23820920, 0x0b86a420, 0x30000b24, + 0x0b86be01, 0x0b8a0c20, 0xe6380d26, 0x4300ee01, 0x7020c582, 0x7230c582, 0x67006900, 0x74006800, 0x28002000, 0x29006300, 0x4d260782, 0x72006100, + 0x09826b00, 0x1d825320, 0x29826d20, 0x73006e22, 0x20240584, 0x30003200, 0x39220182, 0x09842d00, 0x0b823120, 0x27822e20, 0x6c004122, 0x20200182, + 0x4d873582, 0x15827320, 0x65007222, 0x65203782, 0x76201582, 0x64260982, 0x41002e00, 0x47846e00, 0x83007921, 0x82752055, 0x0020221d, 0x221f8250, + 0x8252006f, 0x00672221, 0x20458275, 0x200f8261, 0x832b8231, 0x00332a67, 0x0055003b, 0x0057004b, 0x9109824e, 0x203b853d, 0x913d8e2d, 0x20658727, + 0x20298e20, 0x20758256, 0x20858272, 0x21958469, 0x77890020, 0x6bb14391, 0xdf846920, 0x20006124, 0xd3827400, 0x64006122, 0x6d206d82, 0x22085b41, + 0x4166006f, 0x2e211c6b, 0x19874100, 0x51826820, 0x70007426, 0x2f003a00, 0x77210182, 0x22018300, 0x826d002e, 0x822d206f, 0x00742203, 0x836b8275, + 0x002e22d3, 0x20d98263, 0x1ced416d, 0x2007d141, 0x238d9c2c, 0x00280020, 0x518375af, 0x4020ef87, 0x55429d82, 0x42732005, 0xa3870e53, 0x83002921, + 0x8277202f, 0x8274201d, 0x05a94169, 0x42007321, 0x2022093d, 0xcb824600, 0xf9826e20, 0x4e002024, 0x4f826100, 0xb1826520, 0x2011a741, 0x06514220, + 0x0d002e22, 0x54200182, 0x87414b82, 0x203d8905, 0x20478253, 0x20478266, 0x20458277, 0x20618272, 0x20738220, 0x204b8273, 0x2007826c, 0x210f8263, + 0x7783006e, 0x11826420, 0x6e007524, 0x83846400, 0x83002021, 0x24718395, 0x00490053, 0x221b824c, 0x8470004f, 0x20978b2b, 0x83418c4c, 0x136142cf, + 0x83003121, 0x1b81439b, 0x01930110, 0x00202175, 0x42092d42, 0x21420d0b, 0x00632e07, 0x0070006f, 0x00650069, 0x00200064, 0x20078262, 0x2211826c, + 0x822c0077, 0x0061220d, 0x4215846e, 0x6124056d, 0x73006c00, 0x20241b82, 0x76006100, 0x69200382, 0x61200f82, 0x6c203182, 0x20213382, 0x09e54200, + 0x39826120, 0x41004624, 0x41845100, 0x3a007422, 0x67430782, 0x00732a0d, 0x00720063, 0x00700069, 0x20518274, 0x2003822e, 0x204b8269, 0x2c5b822e, + 0x00670072, 0x004f002f, 0x004c0046, 0x2101840d, 0x01f3002d, 0x43002021, 0x50260913, 0x4e004500, 0x93822000, 0x4e004f24, 0x09825400, 0x49004c24, + 0x15844300, 0x05825320, 0x43002021, 0x20201511, 0x2024b982, 0x36003200, 0x46243182, 0x62006500, 0x7522f382, 0x05826100, 0x11827920, 0x20050f43, + 0xf3098237, 0x002d22df, 0x2201820d, 0x82520050, 0x004126bf, 0x0042004d, 0x22c9844c, 0x82680054, 0x002024a9, 0x826f0067, 0x006c22a9, 0x459f8273, + 0x742005d5, 0x23441986, 0x00202221, 0x06c14128, 0x3d822920, 0xef826120, 0x07826520, 0x51827420, 0x4f822020, 0x69007424, 0x15476d00, 0x84742006, + 0x8277206b, 0x00722619, 0x0064006c, 0x201b8277, 0x83138464, 0x42762005, 0x7020068b, 0x65212f82, 0x05254500, 0x63208b85, 0x6c203182, 0x61223182, + 0x3b846200, 0x83006121, 0x222f8355, 0x45660020, 0x70200851, 0x6f227982, 0x45826a00, 0x1f826320, 0x2c007322, 0x7522858a, 0x01827000, 0x21826f20, + 0x15847420, 0x3b89f585, 0xb5846320, 0x6f225785, 0x23826e00, 0x59826520, 0x72201f83, 0x20204b84, 0x66206582, 0x61241582, 0x61006300, 0x6520b982, + 0x6920d382, 0x20200b82, 0x33430d82, 0x006c2205, 0x20378269, 0x20e98267, 0x20f58669, 0x832f8263, 0x846d20b9, 0x826e20ff, 0x20b5831f, 0x431d8265, + 0x27410b6b, 0x84702005, 0x417620bb, 0x6120080f, 0x66203b82, 0x65209384, 0x200a9743, 0x08af456f, 0x61201b83, 0x65215782, 0x054d4100, 0x25826b20, + 0xb7846920, 0x68007723, 0x20998300, 0x87118268, 0x827320df, 0x826d200b, 0x827920a9, 0x00622107, 0x73205183, 0xa9412582, 0x43642005, 0x6d200cf7, + 0x72206182, 0xed48eb82, 0x84202005, 0x822020d3, 0x82612013, 0x0074228b, 0x203b826e, 0x83bf8272, 0x82702061, 0x09034437, 0x42006f21, 0x1d83052f, + 0x8309b546, 0x05db4369, 0x7d822020, 0x44006c21, 0x8d830569, 0x20202d85, 0xab831182, 0x59826520, 0x8b07af46, 0x051b41b3, 0x7520b185, 0x65247782, + 0x2c006400, 0x73207782, 0x1f486d82, 0x20118705, 0x20b3826d, 0x20ad8264, 0x08d94466, 0x53826120, 0x7220db83, 0x6420b382, 0x33831582, 0x07827220, + 0x75006222, 0xfd443d82, 0x07614105, 0x79006c22, 0x61205582, 0x91836182, 0x39826f20, 0x0f886720, 0x68007422, 0x1f854182, 0x20056947, 0x206b826e, + 0x20858474, 0x45bf826f, 0x1f830545, 0x6d202985, 0x6c22a784, 0x35827600, 0x2e007322, 0x54202782, 0xa9424184, 0x05994209, 0x65826920, 0x3f826320, + 0x6e21c785, 0x20718500, 0x2089846e, 0x223b8264, 0x82690072, 0x0be94243, 0x8507e941, 0x0063223f, 0x21418261, 0x1d410020, 0x22d58305, 0x8264006e, + 0x0711414f, 0x6d006522, 0x64201b84, 0x13871582, 0x411b0b41, 0x2f20052f, 0x7220db82, 0xe341db8c, 0x82612009, 0x20e7836f, 0x107b4873, 0x200dbd42, + 0x06614364, 0x74006122, 0x35870982, 0x200f494b, 0x204d8220, 0x22a38261, 0x44730065, 0x5b410a35, 0x07ed4107, 0x7383df83, 0x411f1141, 0x9d431567, + 0x413f9309, 0x68200547, 0x7724cd82, 0x76006500, 0x72220382, 0x8b822c00, 0x87055941, 0x055f4189, 0x6c20bd83, 0x61202182, 0x87145749, 0x090543e3, + 0xfb822020, 0x70007922, 0x39443182, 0x0d8d4707, 0x7220af8b, 0x71252582, 0x69007500, 0x20098300, 0x440d826d, 0x662005fb, 0x43068b41, 0x27851111, + 0x9d436120, 0x0fe14906, 0xa3826920, 0x220f5943, 0x82640020, 0x056b414d, 0x6120d987, 0x70219f82, 0x05fb4200, 0x87056943, 0x826420c7, 0x8263202b, + 0x458b8991, 0x3943091f, 0x82752005, 0x00692163, 0x2005b542, 0x10df4274, 0x7220f383, 0x20086745, 0x83d78269, 0x8265207f, 0x0dd34207, 0x44007321, + 0x4428052b, 0x46004500, 0x4e004900, 0x54200382, 0x4f200382, 0x53200982, 0x22203f82, 0x6f201582, 0x4a060946, 0x22200ff1, 0x21069d4d, 0x57830066, + 0x20055344, 0x2073886f, 0x229f8220, 0x46740065, 0x662208cd, 0xe9826900, 0x15826520, 0x85822020, 0x0b846520, 0x2109cb41, 0xbf430062, 0x4c202009, + 0x48211469, 0x05eb4300, 0x3d826520, 0x45822820, 0x594b2920, 0x15774112, 0x22055743, 0x86630020, 0x41722073, 0x554c0671, 0x054f4107, 0x99846120, + 0x75007322, 0x68202782, 0x85083544, 0x07b94551, 0x450b3144, 0x6f2005c3, 0x72202f82, 0x0d833182, 0x2c20e189, 0x62209b82, 0x69201982, 0x64206982, + 0x7d490b82, 0x0b13430d, 0x3b826f20, 0x6d477520, 0x09fd4608, 0x22059541, 0x4e520022, 0xbf4c0efd, 0x17874113, 0x21074b42, 0xe543006e, 0x00732209, + 0x20518270, 0x0ea74563, 0xa3847320, 0xf9847520, 0x66229d83, 0xaf4c7400, 0x4f63200e, 0x732012e9, 0x61202582, 0xa5422984, 0x05974107, 0x4f22bb87, + 0x67827200, 0x03826720, 0x6c208183, 0x56206382, 0x970c294f, 0x427420b7, 0x734806cd, 0x82652007, 0x82742097, 0x05154845, 0x4d058f48, 0xf1471b87, + 0x82702005, 0x436e20b1, 0xdf4406c9, 0x46058305, 0x7f421787, 0x20e78733, 0x10f9464d, 0xeb43e7a5, 0x11974309, 0x6d002025, 0x49006100, 0x9b850599, + 0xbd830d83, 0x2307f143, 0x002c006f, 0x2005d343, 0x23e5826c, 0x00690074, 0x13831983, 0x72006f22, 0x2006cf41, 0x06074962, 0x75007423, 0x22218700, + 0x822d0020, 0x0f574801, 0x48072f44, 0x6f2109c1, 0x87578300, 0x095f452d, 0xe1436620, 0x1569410a, 0x420fbd4a, 0x2b431d05, 0x82792005, 0x00632255, + 0x83f38268, 0x47cb85c5, 0x722205af, 0x15826d00, 0xc9827420, 0x0f41a387, 0x00702105, 0xd589e783, 0x35427420, 0x1b194206, 0x26076345, 0x006e0020, + 0x82770065, 0x82652073, 0x00762409, 0x82720069, 0x436e204d, 0xd9410887, 0x00412307, 0x57830075, 0xad426983, 0x0bc54117, 0x49827320, 0x5b846720, + 0x2005c746, 0x420b8265, 0x652005ff, 0x2008db46, 0x206b8470, 0x20058267, 0x206f8261, 0x2017886d, 0x20098274, 0x20c38263, 0x2043826e, 0x20f18263, + 0x209d826c, 0x20258277, 0x088b4369, 0x4605d741, 0x70200be1, 0x73203d84, 0x2020bb84, 0x6820cf82, 0x20220982, 0x0f846300, 0x3b847420, 0x850b6b49, + 0x212741fd, 0x502afd85, 0x52004500, 0x49004d00, 0x01825300, 0x4f004924, 0x91824e00, 0x03822620, 0x0b844320, 0x29464420, 0x8450200e, 0x826d208b, + 0x537320bd, 0x3f450a0b, 0x84682005, 0x0065211b, 0x8505b941, 0x846e20fb, 0x054d4ad7, 0x4209674b, 0x0942053b, 0x00722205, 0x4c378267, 0x69410943, + 0x20f58d07, 0x2255826f, 0x82610074, 0x846e2077, 0x05c54903, 0x22050541, 0x4d790070, 0x1f42104d, 0x20698919, 0x20c18275, 0x0ce74a65, 0x0d847920, + 0x83070545, 0x05b94129, 0xeb49a187, 0x221b8509, 0x8264006f, 0x8266208d, 0x490f837f, 0x854c17f5, 0x8273200b, 0x006c22eb, 0x4baf826c, 0x75231949, + 0x91006e00, 0x094f501d, 0x9d113b4e, 0x007324ed, 0x4d620075, 0x202108af, 0x0d214200, 0x6f006622, 0x6c208f82, 0x77200582, 0x42085941, 0x6420055b, + 0x2006494d, 0x248f826f, 0x003a0073, 0x2201820d, 0x82290031, 0x824e20bb, 0x4c6920c5, 0xef520889, 0x20879909, 0x42438220, 0x634405d9, 0x8345830d, + 0x826920cf, 0x206f831f, 0x20738276, 0x20af8264, 0x41938261, 0x6d2105dd, 0x0de34500, 0x814d2c20, 0x11794608, 0xa9456185, 0x058f4a1f, 0x4c0fa74d, + 0x97850d63, 0x85826520, 0x3b496620, 0x84322006, 0x2173b9f9, 0x31450020, 0x1b2b410d, 0x734c9b8d, 0x17694211, 0x4c09634e, 0x2c22335f, 0x954e2000, + 0x00692308, 0x31490064, 0x00742605, 0x00610068, 0x201b8274, 0x20078265, 0x430d8263, 0x29420b75, 0x43742005, 0x714e0699, 0x0061220b, 0x06df4e62, + 0x41582f89, 0x051d4b0b, 0x55496920, 0x00612206, 0x4271826e, 0xdf490549, 0x09c74b13, 0x97827320, 0x954d5183, 0x0db1490b, 0xab846420, 0x210b9f42, + 0xfb480061, 0x83a78305, 0x822d2067, 0x826c20af, 0x846e209d, 0x8274204b, 0x84782005, 0x0ddb49e1, 0x75006824, 0x29826d00, 0x2d006e24, 0x23827200, + 0xa1826120, 0x3147d583, 0x86682005, 0x82652011, 0x425d831b, 0x8983057b, 0x22090f43, 0x41700061, 0x70200651, 0x69202582, 0x99514b82, 0x416d2005, + 0x69200649, 0x6520f582, 0x6d205d94, 0xad835d82, 0x33846420, 0x2005a550, 0x20138269, 0x8383826c, 0x0077216d, 0x6f87df85, 0x85006521, 0x208585c1, + 0x201d8262, 0x0811536e, 0x2020d589, 0xbd561382, 0x117b4f05, 0x41006f21, 0x2d830559, 0x87006521, 0x0dfd4e67, 0x3f846520, 0x594b6920, 0x82762006, + 0x00652265, 0x08e15477, 0x200bdb4b, 0x204d8475, 0x063b4372, 0x44003321, 0x6f230535, 0x43002000, 0x27431f9d, 0x416d8533, 0x4f4b0977, 0x0b5d4c23, + 0xc3826c20, 0xb1827320, 0x07822020, 0x70007822, 0x22062d51, 0x47740069, 0x74200a9d, 0x6e201b82, 0x70200f82, 0x461a0147, 0x20200df3, 0x4a060947, + 0x72210be9, 0x059f4f00, 0x6f007025, 0x49006e00, 0xe15709e9, 0x4d482013, 0xff420a0b, 0x4d692007, 0x73200859, 0x72229d82, 0x354b6900, 0x416e200e, + 0x7942069b, 0x826c2005, 0x058b4d1f, 0x200df345, 0x21858270, 0x194d0069, 0x52792005, 0x2b500abf, 0x07294209, 0x41832983, 0x6e006522, 0x11446f82, + 0x0bff4d07, 0x52057b41, 0x3422098f, 0x8b512900, 0x07954c0a, 0x45076d41, 0xf59f0d03, 0xe54e3589, 0x00202109, 0x950baf49, 0x1b5b4557, 0x68007325, + 0x47006100, 0x7b500583, 0x20c9850d, 0x08cd5464, 0x6f24fb83, 0x6f006d00, 0x2c20f984, 0x65241782, 0x64006e00, 0xed830f82, 0x0f826520, 0x20056d43, + 0x50138261, 0x742305d5, 0x43006900, 0x61200545, 0x4206c351, 0x55851fed, 0x63007826, 0x70006500, 0x20206782, 0x6f200382, 0x61205982, 0x6b201182, + 0x6f224382, 0xab827700, 0x61826520, 0xab446720, 0x84682006, 0x11fd4907, 0x97826920, 0x41006e21, 0x6741150f, 0x0b854527, 0x4b05315b, 0x8b410919, + 0x077f440d, 0x9183af83, 0x72006922, 0x6521b582, 0x333d4300, 0x2005894a, 0x0c374235, 0x4919c141, 0x69210d79, 0x05934200, 0x49058941, 0x2f481339, + 0x00702209, 0x20a58261, 0x08b74174, 0x850f054d, 0x00752359, 0x23830073, 0x4e058f52, 0x65221749, 0x25826e00, 0x6520f583, 0x52067143, 0x094a231d, + 0x006d210b, 0x85426987, 0x8b71970d, 0x1307535f, 0x42e1f752, 0x41421913, 0x4c542005, 0x4e2308cb, 0x52004100, 0xa95b07df, 0x0062231b, 0xdd4e0065, + 0x00652805, 0x00200073, 0x4475006e, 0x09430619, 0x00762607, 0x0069006f, 0x211b8264, 0x97580069, 0x4c6e2005, 0xeb48126d, 0x826e200f, 0x00692231, + 0x4b398274, 0x2023053b, 0x56006100, 0xdf470dd3, 0x28b78505, 0x00490044, 0x00430053, 0x22b5824c, 0x844d0049, 0x20b583c5, 0x5b098248, 0x53280b1d, + 0x46004f00, 0x57005400, 0x52202782, 0x37831b84, 0x50002024, 0x19825200, 0x45825620, 0x15824420, 0xab824420, 0x21822220, 0x07825320, 0x22221f83, + 0x09822c00, 0x1d825720, 0x48005422, 0x55202782, 0x20204182, 0x52204386, 0x4e202782, 0x59200f82, 0x5b832182, 0x0f842020, 0x4b200d83, 0x4e222f82, + 0x3b844400, 0x58004522, 0x45206384, 0x5583a582, 0x6f824f20, 0x1f822020, 0x15824d20, 0x07824c20, 0x27864520, 0x4e004922, 0x5520c584, 0x0b830f82, + 0x55824720, 0x85004221, 0x824e206f, 0x82542079, 0x202f830f, 0x838b844d, 0x00202235, 0x89178254, 0x87d98575, 0x82492095, 0x206f85cd, 0x41398246, + 0x43200517, 0x4120c382, 0x54206782, 0x4220a982, 0x4c204782, 0x59204b84, 0x4620a784, 0x4e200b84, 0x37833584, 0x5b824620, 0x39825220, 0x03824120, + 0x2f825020, 0x6d825220, 0xa1824920, 0x4c005522, 0x20240d84, 0x55005000, 0x5020cb82, 0x6f5c2782, 0x20598305, 0x832d8244, 0x004e22ad, 0x20678249, + 0x851f8246, 0x004522cb, 0x5c59824d, 0x2b4105a7, 0x82432005, 0x00502237, 0x20218459, 0x20978247, 0x83858454, 0x86542069, 0x822c2029, 0x8254204b, + 0x0041221f, 0x20118244, 0x2075844d, 0x4125844b, 0x4f220543, 0x37825400, 0x21824520, 0x458a2020, 0x35822e20, 0x20207383, 0x4f207f82, 0x45220b82, + 0x79885600, 0xff845320, 0xc1824c20, 0x91092142, 0x82202087, 0x824f2025, 0x82442023, 0x82522037, 0x82422041, 0x82202007, 0x8249200f, 0x07915c81, + 0x20091d41, 0x21c3824e, 0x7f420020, 0x822c2009, 0x82442031, 0x20af8329, 0x08834147, 0xaf8b4783, 0x85004c21, 0x8449204d, 0x82542057, 0x42378343, + 0x41201303, 0x5920c782, 0x4b835382, 0x91844e20, 0x33824120, 0x53222d83, 0x0f825000, 0x49844320, 0x87004c21, 0x8244203f, 0x8452200f, 0x05514117, + 0x49215385, 0x22cd8300, 0x8254004e, 0x412b8599, 0xa7500543, 0x82532005, 0x0051222f, 0x06274155, 0x23844920, 0x31822020, 0x89004121, 0x225f83c5, + 0x82480057, 0x09754123, 0x83056741, 0x822020a1, 0x44432033, 0xe3410a35, 0x20738309, 0x831d8652, 0x00542143, 0x54207983, 0xc541d182, 0x8257200f, + 0x825320b9, 0x2225835f, 0x84520041, 0x053d420d, 0x46002022, 0x4f200f82, 0x1b838d82, 0x15434f20, 0x20638506, 0x20938454, 0x42138220, 0x55850585, + 0x4e004922, 0x200ee342, 0x062d4320, 0x85005521, 0x20378727, 0x428f8246, 0x21440597, 0x874b8511, 0x8220207b, 0x20fb8929, 0x22a98244, 0x824c0041, + 0x004e22a5, 0x20538247, 0x44098420, 0x2e222379, 0xfd820d00, 0x541f4f47, 0x0d203f55, 0x6f4f6582, 0x0d755511, 0x83735754, 0x23595497, 0x22202783, + 0x540cad4a, 0x8383715d, 0x617b5f54, 0x6354050d, 0x2331852b, 0x00720065, 0x83836554, 0x0061218d, 0x838b6754, 0x17ff5191, 0x83696954, 0x0f295c85, + 0x6b547d83, 0x876f544b, 0x2b4c8783, 0x118d4405, 0x835b7154, 0x89755477, 0x541b7742, 0x8b836f77, 0x42837954, 0x63240719, 0x75006c00, 0x20083155, + 0x069b5365, 0x72006522, 0x5d08dd62, 0x7b540545, 0x09a5425b, 0x50007421, 0x7d540523, 0x54878375, 0x93838f7f, 0x83898354, 0x07956c8d, 0x838b8554, + 0x1f295297, 0x83758754, 0x31895499, 0x8d543583, 0x1333478b, 0x54002021, 0x81836b8f, 0x42839154, 0x19432369, 0x5f935407, 0x4a055b42, 0x9b51116f, + 0x541d8305, 0x87838399, 0x54093154, 0x8383759b, 0x48819d54, 0x6d210787, 0x79976700, 0x99678383, 0x1fa15413, 0x4d056572, 0xa554070d, 0x0d7f720b, + 0x210dcb55, 0xa7540020, 0x568d836f, 0xa9540795, 0x5417830b, 0xbd8513ad, 0x8385af54, 0x83b1548b, 0x23056b45, 0x00520045, 0x5183b354, 0x4620054b, + 0x5406d763, 0x014681b5, 0x004f2105, 0xb754898d, 0x548d8377, 0x67438bb9, 0x87bb5405, 0xbd548d83, 0x05c34283, 0x2345bf54, 0x00020000, 0xff230084, + 0x827b0045, 0x82012008, 0x21028c03, 0x15847002, 0x0002dd08, 0x00060003, 0x00080007, 0x000a0009, 0x000c000b, 0x000e000d, 0x0010000f, 0x00120011, + 0x00140013, 0x00160015, 0x00180017, 0x001a0019, 0x001c001b, 0x001e001d, 0x0020001f, 0x00220021, 0x00240023, 0x00260025, 0x00280027, 0x002a0029, + 0x002c002b, 0x002e002d, 0x0030002f, 0x00320031, 0x00340033, 0x00360035, 0x00380037, 0x003a0039, 0x003c003b, 0x003e003d, 0x0040003f, 0x00420041, + 0x00440043, 0x00460045, 0x00480047, 0x004a0049, 0x004c004b, 0x004e004d, 0x0050004f, 0x00520051, 0x00540053, 0x00560055, 0x00580057, 0x005a0059, + 0x005c005b, 0x005e005d, 0x0060005f, 0x00620061, 0x00640063, 0x00660065, 0x00680067, 0x006a0069, 0x006c006b, 0x006e006d, 0x0070006f, 0x00720071, + 0x0805df71, 0x770076a6, 0x79007800, 0x7b007a00, 0x7d007c00, 0x7f007e00, 0x81008000, 0x83008200, 0x85008400, 0x87008600, 0x89008800, 0x8b008a00, + 0x8d008c00, 0x8f008e00, 0x91009000, 0x93009200, 0x95009400, 0x97009600, 0x99009800, 0x9b009a00, 0x9d009c00, 0x9f009e00, 0xa100a000, 0xa300a200, + 0xa500a400, 0xa700a600, 0xa900a800, 0xab00aa00, 0xad000201, 0xaf00ae00, 0xb100b000, 0xb300b200, 0xb500b400, 0xb700b600, 0xb900b800, 0xbb00ba00, + 0x0301bc00, 0xbf00be00, 0xc100c000, 0xc300c200, 0xc500c400, 0xc700c600, 0xc900c800, 0x3606f57f, 0x00ce00cd, 0x00d000cf, 0x00d200d1, 0x00d400d3, + 0x00d600d5, 0x7fd800d7, 0x430b06a9, 0x00dd00dc, 0x00df00de, 0x00e100e0, 0x01050004, 0x00bd0004, 0x000501e8, 0x00f300f2, 0x00f500f1, 0x00f600f4, + 0x00f000e9, 0x00ed00eb, 0x00ec00ea, 0x010601ee, 0x01080107, 0x010a0109, 0x00fd000b, 0x010c01fe, 0x010e010d, 0x01ff000f, 0x01100100, 0x01120111, + 0x01130101, 0x01150114, 0x01170116, 0x01190118, 0x011b011a, 0x011d011c, 0x00f8001e, 0x011f01f9, 0x01210120, 0x01230122, 0x01250124, 0x01270126, + 0x01290128, 0x012b012a, 0x012d012c, 0x01fa002e, 0x0130012f, 0x01320131, 0x01340133, 0x01360135, 0x01380137, 0x013a0139, 0x013c013b, 0x00e2003d, + 0x013e01e3, 0x0140013f, 0x01420141, 0x01440143, 0x01460145, 0x01480147, 0x014a0149, 0x014c014b, 0x014e014d, 0x0150014f, 0x01520151, 0x01540153, + 0x00560155, 0x00fc00fb, 0x01e500e4, 0x01580157, 0x015a0159, 0x015c015b, 0x015e015d, 0x0160015f, 0x01620161, 0x01640163, 0x01660165, 0x01680167, + 0x016a0169, 0x016c016b, 0x016e016d, 0x0070016f, 0x01e700e6, 0x01720171, 0x01740173, 0x01760175, 0x01780177, 0x017a0179, 0x017c017b, 0x017e017d, + 0x0180017f, 0x01820181, 0x01840183, 0x01860185, 0x01880187, 0x018a0189, 0x018c018b, 0x018e018d, 0x0190018f, 0x01920191, 0x01940193, 0x01960195, + 0x01980197, 0x019a0199, 0x019c019b, 0x019e019d, 0x01a0019f, 0x01a201a1, 0x01a401a3, 0x01a601a5, 0x01a801a7, 0x01aa01a9, 0x01ac01ab, 0x01ae01ad, + 0x01b001af, 0x01b201b1, 0x01b401b3, 0x01b601b5, 0x01b801b7, 0x01ba01b9, 0x01bc01bb, 0x01be01bd, 0x01c001bf, 0x01c201c1, 0x01c401c3, 0x01c601c5, + 0x01c801c7, 0x01ca01c9, 0x01cc01cb, 0x01ce01cd, 0x01d001cf, 0x01d201d1, 0x01d401d3, 0x01d601d5, 0x01d801d7, 0x01da01d9, 0x01dc01db, 0x01de01dd, + 0x01e001df, 0x01e201e1, 0x01e401e3, 0x01e601e5, 0x01e801e7, 0x01ea01e9, 0x01ec01eb, 0x01ee01ed, 0x01f001ef, 0x01f201f1, 0x01f401f3, 0x01f601f5, + 0x01f801f7, 0x01fa01f9, 0x01fc01fb, 0x01fe01fd, 0x020002ff, 0x02020201, 0x02040203, 0x02060205, 0x02080207, 0x020a0209, 0x020c020b, 0x020e020d, + 0x0210020f, 0x02120211, 0x02140213, 0x02160215, 0x02180217, 0x021a0219, 0x021c021b, 0x021e021d, 0x0220021f, 0x02220221, 0x02240223, 0x02260225, + 0x02280227, 0x022a0229, 0x022c022b, 0x022e022d, 0x0230022f, 0x02320231, 0x00340233, 0x023502ef, 0x02370236, 0x02390238, 0x023b023a, 0x023d023c, + 0x023f023e, 0x02410240, 0x02430242, 0x02450244, 0x02470246, 0x02490248, 0x024b024a, 0x024d024c, 0x024f024e, 0x02510250, 0x02530252, 0x02550254, + 0x02570256, 0x02590258, 0x025b025a, 0x025d025c, 0x025f025e, 0x02610260, 0x02630262, 0x02650264, 0x02670266, 0x02690268, 0x026b026a, 0x026d026c, + 0x026f026e, 0x07710270, 0x30696e75, 0x04304130, 0x6f727545, 0x6d6f630b, 0x6361616d, 0x746e6563, 0x442a1886, 0x616d4107, 0x6e6f7263, 0x07856107, + 0x62410628, 0x65766572, 0x06846106, 0x6f410729, 0x656e6f67, 0x8561076b, 0x430b2d07, 0x63726963, 0x6c666d75, 0x630b7865, 0x0a240b89, 0x746f6443, + 0x0a215885, 0x230a8863, 0x61634406, 0x06215a82, 0x27068564, 0x6f726344, 0x45077461, 0x07216885, 0x21078565, 0x69844506, 0x84650621, 0x450a2106, + 0x0a213d88, 0x210a8865, 0x7e854507, 0x85650721, 0x45062107, 0x65205185, 0x0b210684, 0x21888947, 0x0b89670b, 0x89470a21, 0x8867204b, 0x470c210a, + 0x210a0541, 0x0c8a670c, 0x89480b21, 0x680b213b, 0x04260b89, 0x72616248, 0x04826804, 0x74490628, 0x65646c69, 0x06846906, 0x85490721, 0x690721c1, + 0x06210785, 0x21c28449, 0x06846906, 0x85490721, 0x690721ab, 0x02270785, 0x69024a49, 0x894a0b6a, 0x6a0b2157, 0x0c210b89, 0x21888a4b, 0x0c8c6b0c, + 0x65726733, 0x616c6e65, 0x6369646e, 0x63614c06, 0x06657475, 0x2106846c, 0x278b4c0c, 0x0c8a6c20, 0x634c0628, 0x6e6f7261, 0x06846c06, 0x824c0421, + 0x6c0421fd, 0x06210482, 0x203f854e, 0x203f856e, 0x21328a4e, 0x0c8a6e0c, 0x844e0621, 0x6e062138, 0x0b350684, 0x6f70616e, 0x6f727473, 0x03656870, + 0x03676e45, 0x07676e65, 0x21f4854f, 0x07856f07, 0x844f0621, 0x6f0621f5, 0x0d2f0684, 0x6e75684f, 0x75726167, 0x75616c6d, 0x8b6f0d74, 0x5206210d, + 0x06217c84, 0x21068472, 0x768a520c, 0x8a720c21, 0x5206210c, 0x06217c84, 0x20068572, 0x212e8453, 0x06847306, 0x41530b21, 0x0b21093a, 0x210b8973, + 0x408a540c, 0x8a740c21, 0x5406210c, 0x74204685, 0x04260684, 0x72616254, 0x04827404, 0x74550628, 0x65646c69, 0x06847506, 0x85550721, 0x750721cd, + 0x06210785, 0x21ce8455, 0x06847506, 0x72550527, 0x05676e69, 0x21058375, 0xe18c550d, 0x0d8b7520, 0x41550721, 0x072105f2, 0x21078575, 0xa189570b, + 0x8a770b21, 0x8a59200b, 0x8979200b, 0x5a06210b, 0x0621e484, 0x2106847a, 0xbb425a0a, 0x7a0a2108, 0x05280a88, 0x676e6f6c, 0x45410773, 0x07222384, + 0x07846561, 0x734f0b26, 0x6873616c, 0x6f200b85, 0x0c210b89, 0x0a0a4153, 0x44730c21, 0x32390f07, 0x75074131, 0x3230696e, 0x74054231, 0x736f6e6f, + 0x6569640d, 0x69736572, 0x250d8473, 0x706c410a, 0x0a846168, 0x70450c24, 0x7a826973, 0x08220c84, 0x15857445, 0x6f490922, 0x0c270986, 0x63696d4f, + 0x846e6f72, 0x550c211f, 0x0a242c8a, 0x67656d4f, 0x11212e85, 0x8c2e8269, 0x84052061, 0x42042a61, 0x05617465, 0x6d6d6147, 0x238e8461, 0x07343933, + 0x04216f86, 0x201a825a, 0x226f8203, 0x82685405, 0x83042009, 0x4b053670, 0x61707061, 0x6d614c06, 0x02616462, 0x4e02754d, 0x69580275, 0x31818607, + 0x03695002, 0x056f6852, 0x6d676953, 0x61540361, 0x8d860775, 0x68500325, 0x82430369, 0x73502303, 0x47830c69, 0x0f208987, 0x0f872086, 0x89610a21, + 0x8a6520f6, 0x820820c9, 0x20df8480, 0x84c78309, 0x75142109, 0xd48d1f85, 0x04213f84, 0x212e8262, 0xd4836705, 0x65640526, 0x0761746c, 0x04214b86, + 0x2018827a, 0x21038203, 0xd2847405, 0x05214c83, 0x20d2846b, 0x41d2846c, 0x42290503, 0x756e0243, 0x07697802, 0x0559416f, 0x68720325, 0x8373066f, + 0x053121d4, 0x03210684, 0x86db8274, 0x7003217f, 0x6320d782, 0x8e820382, 0x6d6f0526, 0x0c616765, 0x200b6b41, 0x20a68e0f, 0x8453860c, 0x860c20c3, + 0x200c841c, 0x843c840a, 0x6109290a, 0x31696966, 0x33323030, 0x35210987, 0x20098831, 0x89098832, 0x8834201d, 0x88352013, 0x88362009, 0x88372009, + 0x88382009, 0x87392009, 0x30362109, 0x63880988, 0x63873620, 0x88343121, 0x8831204f, 0x88312045, 0x88312045, 0x88322045, 0x88322045, 0x88322045, + 0x883220a9, 0x8832209f, 0x8832204f, 0x8832209f, 0x88322059, 0x88322059, 0x88332059, 0x88332059, 0x88332059, 0x41332059, 0x33200803, 0x33206388, + 0x33206388, 0x33206388, 0x33206388, 0x33206388, 0x34206388, 0x34206388, 0x34206388, 0x34206388, 0x34206388, 0x17416388, 0x88342009, 0x88342063, + 0x88342063, 0x88342063, 0x88362063, 0x88362095, 0x88362031, 0x88362031, 0x88362031, 0x88372031, 0x88372095, 0x8837208b, 0x8837208b, 0x8837208b, + 0x88372059, 0x88372059, 0x88372059, 0x88372059, 0x88382059, 0x88382059, 0x883820ef, 0x88382063, 0x88382063, 0x88382063, 0x88382063, 0x88382063, + 0x88382063, 0x88382063, 0x88392063, 0x88392063, 0x88392063, 0x88392063, 0x88392063, 0x88392063, 0x88392063, 0x88392063, 0x89372063, 0x21638745, + 0x63873031, 0x87303121, 0x3031211d, 0x2008bb42, 0x21638730, 0x63873031, 0x87303121, 0x30312163, 0x31216387, 0x21638730, 0xc7873031, 0x88303121, + 0x88312063, 0x20b38963, 0x28db8935, 0x6e750738, 0x30453169, 0x20078632, 0x20078633, 0x20078641, 0x21078542, 0x07864531, 0x07854620, 0x86303421, + 0x85312007, 0x36352107, 0x37200786, 0x36200785, 0x36201f86, 0x36201f86, 0x362a4f86, 0x67570642, 0x65766172, 0x06857706, 0x63615724, 0x0d827475, + 0x09210684, 0x070d4557, 0x87770921, 0x59062109, 0x79202885, 0x09270684, 0x69696661, 0x86323030, 0x313623e9, 0xb9843533, 0x30333222, 0x3222b984, + 0xd1843133, 0x3233323d, 0x706f0934, 0x6e6f6974, 0x0f79656b, 0x73617265, 0x746f7465, 0x69726568, 0x83746867, 0x333223a3, 0x07856437, 0x31863820, + 0x84656321, 0x3234270f, 0x46530833, 0x00833031, 0x09840883, 0x30200882, 0x33200888, 0x86821a86, 0x1a830982, 0x11873420, 0x08873820, 0x08873920, + 0x08873620, 0x08873720, 0x08863520, 0x47873420, 0x3e873220, 0x86313521, 0x3235211a, 0x33200886, 0x32204787, 0x32201187, 0x32202387, 0x07844787, + 0x86823020, 0x2c873420, 0x86873320, 0x08883220, 0x32207d87, 0x33208f87, 0x1a870888, 0x62873420, 0x74883120, 0x86863020, 0xaa873220, 0x2c883420, + 0x34215987, 0x20238631, 0x87d78834, 0x83d68459, 0x88352098, 0x844788e0, 0x620c3d11, 0x6b63616c, 0x6d616964, 0x09646e6f, 0x63656863, 0x72616d6b, + 0x6873056b, 0x09746669, 0x6c360584, 0x0b6b636f, 0x74726576, 0x6c616369, 0x04626174, 0x79706f63, 0x36826204, 0x6e650623, 0x23108264, 0x736e6906, + 0x03201e82, 0x09290a82, 0x6c707061, 0x65706f65, 0x0507476e, 0x00394122, 0x032c0083, 0x02000900, 0x01000d00, 0x0200ffff, 0x4a7afa05, 0x00008ed9, +}; + diff --git a/third-party/imgui/imgui_impl_glfw.cpp b/third-party/imgui/imgui_impl_glfw.cpp index ca0b45bbbe..cddf0b905c 100644 --- a/third-party/imgui/imgui_impl_glfw.cpp +++ b/third-party/imgui/imgui_impl_glfw.cpp @@ -139,6 +139,9 @@ void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) if (action == GLFW_RELEASE) io.KeysDown[key] = false; + if (mods && GLFW_MOD_CONTROL) io.KeysDown[GLFW_KEY_LEFT_CONTROL] = true; + else io.KeysDown[GLFW_KEY_LEFT_CONTROL] = false; + (void)mods; // Modifiers are not reliable across systems io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; From accd2b8edb430211b2bfac49cbf1f89dcb4f6810 Mon Sep 17 00:00:00 2001 From: Sergey Dorodnicov Date: Tue, 23 Jun 2020 13:59:45 +0300 Subject: [PATCH 58/61] Changes in GUI --- common/CMakeLists.txt | 4 + common/calibration-model.cpp | 438 ++++++++ common/calibration-model.h | 37 + common/model-views.cpp | 100 +- common/model-views.h | 53 +- common/notifications.cpp | 100 +- common/notifications.h | 18 +- common/output-model.cpp | 1101 +++++++++++++++++++ common/output-model.h | 190 ++++ common/rendering.h | 37 + common/ux-window.cpp | 8 +- common/ux-window.h | 7 +- common/viewer.cpp | 88 +- common/viewer.h | 6 +- tools/realsense-viewer/realsense-viewer.cpp | 56 +- 15 files changed, 1997 insertions(+), 246 deletions(-) create mode 100644 common/calibration-model.cpp create mode 100644 common/calibration-model.h create mode 100644 common/output-model.cpp create mode 100644 common/output-model.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index e9c2d987b6..8e7d0bc024 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -7,6 +7,8 @@ set(COMMON_SRC "${CMAKE_CURRENT_LIST_DIR}/model-views.cpp" "${CMAKE_CURRENT_LIST_DIR}/notifications.h" "${CMAKE_CURRENT_LIST_DIR}/notifications.cpp" + "${CMAKE_CURRENT_LIST_DIR}/calibration-model.h" + "${CMAKE_CURRENT_LIST_DIR}/calibration-model.cpp" "${CMAKE_CURRENT_LIST_DIR}/viewer.h" "${CMAKE_CURRENT_LIST_DIR}/viewer.cpp" "${CMAKE_CURRENT_LIST_DIR}/ux-window.h" @@ -23,6 +25,8 @@ set(COMMON_SRC "${CMAKE_CURRENT_LIST_DIR}/fw-update-helper.cpp" "${CMAKE_CURRENT_LIST_DIR}/metadata-helper.h" "${CMAKE_CURRENT_LIST_DIR}/metadata-helper.cpp" + "${CMAKE_CURRENT_LIST_DIR}/output-model.h" + "${CMAKE_CURRENT_LIST_DIR}/output-model.cpp" "${CMAKE_CURRENT_LIST_DIR}/skybox.h" "${CMAKE_CURRENT_LIST_DIR}/skybox.cpp" "${CMAKE_CURRENT_LIST_DIR}/measurement.h" diff --git a/common/calibration-model.cpp b/common/calibration-model.cpp new file mode 100644 index 0000000000..e48a051637 --- /dev/null +++ b/common/calibration-model.cpp @@ -0,0 +1,438 @@ +#include +#include "calibration-model.h" +#include "model-views.h" +#include "os.h" + +#include "../src/ds5/ds5-private.h" + +using namespace rs2; + +bool calibration_model::supports() +{ + bool is_d400 = dev.supports(RS2_CAMERA_INFO_PRODUCT_LINE) ? + std::string(dev.get_info(RS2_CAMERA_INFO_PRODUCT_LINE)) == "D400" : false; + + return dev.is() && is_d400; +} + +calibration_model::calibration_model(rs2::device dev) : dev(dev) +{ + _accept = config_file::instance().get_or_default(configurations::calibration::enable_writing, false); +} + +void calibration_model::draw_float(std::string name, float& x, const float& orig, bool& changed) +{ + if (abs(x - orig) > 0.00001) ImGui::PushStyleColor(ImGuiCol_FrameBg, regular_blue); + else ImGui::PushStyleColor(ImGuiCol_FrameBg, black); + if (ImGui::DragFloat(std::string(to_string() << "##" << name).c_str(), &x, 0.001f)) + { + changed = true; + } + ImGui::PopStyleColor(); +} + +void calibration_model::draw_float4x4(std::string name, librealsense::float3x3& feild, + const librealsense::float3x3& original, bool& changed) +{ + ImGui::SetCursorPosX(10); + ImGui::Text("%s:", name.c_str()); ImGui::SameLine(); + ImGui::SetCursorPosX(200); + + ImGui::PushItemWidth(120); + ImGui::SetCursorPosX(200); + draw_float(name + "_XX", feild.x.x, original.x.x, changed); + ImGui::SameLine(); + draw_float(name + "_XY", feild.x.y, original.x.y, changed); + ImGui::SameLine(); + draw_float(name + "_XZ", feild.x.z, original.x.z, changed); + + ImGui::SetCursorPosX(200); + draw_float(name + "_YX", feild.y.x, original.y.x, changed); + ImGui::SameLine(); + draw_float(name + "_YY", feild.y.y, original.y.y, changed); + ImGui::SameLine(); + draw_float(name + "_YZ", feild.y.z, original.y.z, changed); + + ImGui::SetCursorPosX(200); + draw_float(name + "_ZX", feild.z.x, original.z.x, changed); + ImGui::SameLine(); + draw_float(name + "_ZY", feild.z.y, original.z.y, changed); + ImGui::SameLine(); + draw_float(name + "_ZZ", feild.z.z, original.z.z, changed); + + ImGui::PopItemWidth(); + + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); +} + +void calibration_model::update(ux_window& window, std::string& error_message) +{ + const auto window_name = "Calibration Window"; + + if (to_open) + { + try + { + _calibration = dev.as().get_calibration_table(); + _original = _calibration; + ImGui::OpenPopup(window_name); + } + catch(std::exception e) + { + error_message = e.what(); + } + to_open = false; + } + + auto table = (librealsense::ds::coefficients_table*)_calibration.data(); + auto orig_table = (librealsense::ds::coefficients_table*)_original.data(); + bool changed = false; + + const float w = 620; + const float h = 500; + const float x0 = std::max(window.width() - w, 0.f) / 2; + const float y0 = std::max(window.height() - h, 0.f) / 2; + ImGui::SetNextWindowPos({ x0, y0 }); + ImGui::SetNextWindowSize({ w, h }); + + auto flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings; + + ImGui::PushStyleColor(ImGuiCol_PopupBg, sensor_bg); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white); + ImGui::PushStyleColor(ImGuiCol_Text, light_grey); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(5, 5)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 1); + + if (ImGui::BeginPopupModal(window_name, nullptr, flags)) + { + if (error_message != "") ImGui::CloseCurrentPopup(); + + std::string title_message = "CAMERA CALIBRATION"; + auto title_size = ImGui::CalcTextSize(title_message.c_str()); + ImGui::SetCursorPosX(w / 2 - title_size.x / 2); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); + ImGui::PushFont(window.get_large_font()); + ImGui::PushStyleColor(ImGuiCol_Text, white); + ImGui::Text("%s", title_message.c_str()); + ImGui::PopStyleColor(); + ImGui::PopFont(); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); + + ImGui::SetCursorPosX(w / 2 - 260 / 2); + if (ImGui::Button(u8"\uF07C Load...", ImVec2(70, 30))) + { + try + { + if (auto fn = file_dialog_open(file_dialog_mode::open_file, "Calibration JSON\0*.json\0", nullptr, nullptr)) + { + config_file cf(fn); + table->baseline = cf.get("baseline"); + + auto load_float3x4 = [&](std::string name, librealsense::float3x3& m){ + m.x.x = cf.get(std::string(to_string() << name << ".x.x").c_str()); + m.x.y = cf.get(std::string(to_string() << name << ".x.y").c_str()); + m.x.z = cf.get(std::string(to_string() << name << ".x.z").c_str()); + + m.y.x = cf.get(std::string(to_string() << name << ".y.x").c_str()); + m.y.y = cf.get(std::string(to_string() << name << ".y.y").c_str()); + m.y.z = cf.get(std::string(to_string() << name << ".y.z").c_str()); + + m.z.x = cf.get(std::string(to_string() << name << ".z.x").c_str()); + m.z.y = cf.get(std::string(to_string() << name << ".z.y").c_str()); + m.z.z = cf.get(std::string(to_string() << name << ".z.z").c_str()); + }; + + load_float3x4("intrinsic_left", table->intrinsic_left); + load_float3x4("intrinsic_right", table->intrinsic_right); + load_float3x4("world2left_rot", table->world2left_rot); + load_float3x4("world2right_rot", table->world2right_rot); + + for (int i = 0; i < librealsense::ds::max_ds5_rect_resolutions; i++) + { + auto xy = librealsense::ds::resolutions_list[(librealsense::ds::ds5_rect_resolutions)i]; + int w = xy.x; int h = xy.y; + + table->rect_params[i].x = cf.get(std::string(to_string() << "rectified." << i << ".fx").c_str()); + table->rect_params[i].y = cf.get(std::string(to_string() << "rectified." << i << ".fy").c_str()); + + table->rect_params[i].z = cf.get(std::string(to_string() << "rectified." << i << ".ppx").c_str()); + table->rect_params[i].w = cf.get(std::string(to_string() << "rectified." << i << ".ppy").c_str()); + } + } + + changed = true; + } + catch (const std::exception& ex) + { + error_message = ex.what(); + ImGui::CloseCurrentPopup(); + } + } + if (ImGui::IsItemHovered()) + { + window.link_hovered(); + ImGui::SetTooltip("%s", "Load calibration from file"); + } + ImGui::SameLine(); + if (ImGui::Button(u8"\uF0C7 Save As...", ImVec2(100, 30))) + { + try + { + if (auto fn = file_dialog_open(file_dialog_mode::save_file, "Calibration JSON\0*.json\0", nullptr, nullptr)) + { + config_file cf(fn); + cf.set("baseline", table->baseline); + + auto save_float3x4 = [&](std::string name, librealsense::float3x3& m){ + cf.set(std::string(to_string() << name << ".x.x").c_str(), m.x.x); + cf.set(std::string(to_string() << name << ".x.y").c_str(), m.x.y); + cf.set(std::string(to_string() << name << ".x.z").c_str(), m.x.z); + + cf.set(std::string(to_string() << name << ".y.x").c_str(), m.y.x); + cf.set(std::string(to_string() << name << ".y.y").c_str(), m.y.y); + cf.set(std::string(to_string() << name << ".y.z").c_str(), m.y.z); + + cf.set(std::string(to_string() << name << ".z.x").c_str(), m.z.x); + cf.set(std::string(to_string() << name << ".z.y").c_str(), m.z.y); + cf.set(std::string(to_string() << name << ".z.z").c_str(), m.z.z); + }; + + save_float3x4("intrinsic_left", table->intrinsic_left); + save_float3x4("intrinsic_right", table->intrinsic_right); + save_float3x4("world2left_rot", table->world2left_rot); + save_float3x4("world2right_rot", table->world2right_rot); + + for (int i = 0; i < librealsense::ds::max_ds5_rect_resolutions; i++) + { + auto xy = librealsense::ds::resolutions_list[(librealsense::ds::ds5_rect_resolutions)i]; + int w = xy.x; int h = xy.y; + + cf.set(std::string(to_string() << "rectified." << i << ".width").c_str(), w); + cf.set(std::string(to_string() << "rectified." << i << ".height").c_str(), h); + + cf.set(std::string(to_string() << "rectified." << i << ".fx").c_str(), table->rect_params[i].x); + cf.set(std::string(to_string() << "rectified." << i << ".fy").c_str(), table->rect_params[i].y); + + cf.set(std::string(to_string() << "rectified." << i << ".ppx").c_str(), table->rect_params[i].z); + cf.set(std::string(to_string() << "rectified." << i << ".ppy").c_str(), table->rect_params[i].w); + } + } + } + catch (const std::exception& ex) + { + error_message = ex.what(); + ImGui::CloseCurrentPopup(); + } + } + if (ImGui::IsItemHovered()) + { + window.link_hovered(); + ImGui::SetTooltip("%s", "Save calibration image to file"); + } + ImGui::SameLine(); + if (_accept) + { + if (ImGui::Button(u8"\uF275 Restore Factory", ImVec2(115, 30))) + { + try + { + dev.as().reset_to_factory_calibration(); + _calibration = dev.as().get_calibration_table(); + _original = _calibration; + changed = true; + } + catch(const std::exception& ex) + { + error_message = ex.what(); + ImGui::CloseCurrentPopup(); + } + } + if (ImGui::IsItemHovered()) + { + window.link_hovered(); + ImGui::SetTooltip("%s", "Restore calibration in flash to factory settings"); + } + } + else + { + ImGui::PushStyleColor(ImGuiCol_Text, grey); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, grey); + + ImGui::Button(u8"\uF275 Restore Factory", ImVec2(115, 30)); + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("%s", "Write selected calibration table to the device. For advanced users"); + } + + ImGui::PopStyleColor(2); + } + + ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, dark_sensor_bg); + + ImGui::BeginChild("##CalibData",ImVec2(w - 15, h - 110), true); + + ImGui::SetCursorPosX(10); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); + + ImGui::Text("Stereo Baseline(mm):"); ImGui::SameLine(); + ImGui::SetCursorPosX(200); + + ImGui::PushItemWidth(120); + draw_float("Baseline", table->baseline, orig_table->baseline, changed); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); + ImGui::PopItemWidth(); + + draw_float4x4("Left Intrinsics", table->intrinsic_left, orig_table->intrinsic_left, changed); + draw_float4x4("Right Intrinsics", table->intrinsic_right, orig_table->intrinsic_right, changed); + draw_float4x4("World to Left Rotation", table->world2left_rot, orig_table->world2left_rot, changed); + draw_float4x4("World to Right Rotation", table->world2right_rot, orig_table->world2right_rot, changed); + + ImGui::SetCursorPosX(10); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); + + ImGui::Text("Rectified Resolution:"); ImGui::SameLine(); + ImGui::SetCursorPosX(200); + + std::vector resolution_names; + std::vector resolution_names_char; + std::vector resolution_offset; + for (int i = 0; i < librealsense::ds::max_ds5_rect_resolutions; i++) + { + auto xy = librealsense::ds::resolutions_list[(librealsense::ds::ds5_rect_resolutions)i]; + int w = xy.x; int h = xy.y; + if (w != 0) { + resolution_offset.push_back(i); + std::string name = to_string() << w <<" x "<rect_params[selected_resolution].x, orig_table->rect_params[selected_resolution].x, changed); + ImGui::SameLine(); + draw_float("FocalY", table->rect_params[selected_resolution].y, orig_table->rect_params[selected_resolution].y, changed); + + ImGui::SetCursorPosX(10); + ImGui::Text("Principal Point:"); ImGui::SameLine(); + ImGui::SetCursorPosX(200); + + draw_float("PPX", table->rect_params[selected_resolution].z, orig_table->rect_params[selected_resolution].z, changed); + ImGui::SameLine(); + draw_float("PPY", table->rect_params[selected_resolution].w, orig_table->rect_params[selected_resolution].w, changed); + + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); + + ImGui::PopItemWidth(); + + if (ImGui::IsWindowHovered()) window.set_hovered_over_input(); + + ImGui::EndChild(); + ImGui::PopStyleColor(); + + ImGui::SetCursorScreenPos({ (float)(x0 + 10), (float)(y0 + h - 30) }); + if (ImGui::Checkbox("I know what I'm doing", &_accept)) + { + config_file::instance().set(configurations::calibration::enable_writing, _accept); + } + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("%s", "Changing calibration will affect depth quality. Changes are persistent.\nThere is an option to get back to factory calibration, but it maybe worse than current calibration\nBefore writing to flash, we strongly recommend to make a file backup"); + } + + ImGui::SetCursorScreenPos({ (float)(x0 + w - 230), (float)(y0 + h - 30) }); + + if (ImGui::Button("Cancel", ImVec2(100, 25))) + { + ImGui::CloseCurrentPopup(); + } + if (ImGui::IsItemHovered()) + { + window.link_hovered(); + ImGui::SetTooltip("%s", "Close without saving any changes"); + } + ImGui::SameLine(); + + auto streams = dev.query_sensors()[0].get_active_streams(); + if (_accept && streams.size()) + { + if (ImGui::Button(u8"\uF2DB Write Table", ImVec2(120, 25))) + { + try + { + auto actual_data = _calibration.data() + sizeof(librealsense::ds::table_header); + auto actual_data_size = _calibration.size() - sizeof(librealsense::ds::table_header); + auto crc = librealsense::calc_crc32(actual_data, actual_data_size); + table->header.crc32 = crc; + dev.as().set_calibration_table(_calibration); + dev.as().write_calibration(); + _original = _calibration; + ImGui::CloseCurrentPopup(); + } + catch (const std::exception& ex) + { + error_message = ex.what(); + ImGui::CloseCurrentPopup(); + } + } + if (ImGui::IsItemHovered()) + { + window.link_hovered(); + ImGui::SetTooltip("%s", "Write selected calibration table to the device"); + } + } + else + { + ImGui::PushStyleColor(ImGuiCol_Text, grey); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, grey); + + ImGui::Button(u8"\uF2DB Write Table", ImVec2(120, 25)); + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("%s", "Write selected calibration table to the device. For advanced users"); + } + + ImGui::PopStyleColor(2); + } + + if (changed && streams.size()) + { + try + { + dev.as().set_calibration_table(_calibration); + } + catch (const std::exception& ex) + { + try + { + dev.query_sensors()[0].close(); + dev.query_sensors()[0].open(streams); + dev.as().set_calibration_table(_calibration); + } + catch (const std::exception& ex) + { + error_message = ex.what(); + ImGui::CloseCurrentPopup(); + } + } + } + + if (ImGui::IsWindowHovered()) window.set_hovered_over_input(); + + ImGui::EndPopup(); + } + ImGui::PopStyleColor(3); + ImGui::PopStyleVar(2); +} \ No newline at end of file diff --git a/common/calibration-model.h b/common/calibration-model.h new file mode 100644 index 0000000000..d322f31a5c --- /dev/null +++ b/common/calibration-model.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include "ux-window.h" + +namespace librealsense +{ + struct float3x3; +} + +namespace rs2 +{ + class calibration_model + { + public: + calibration_model(rs2::device dev); + + bool supports(); + + void update(ux_window& window, std::string& error_message); + + void open() { to_open = true; } + + private: + void draw_float4x4(std::string name, librealsense::float3x3& feild, const librealsense::float3x3& original, bool& changed); + void draw_float(std::string name, float& x, const float& orig, bool& changed); + + rs2::device dev; + bool to_open = false; + bool _accept = false; + + std::vector _calibration; + std::vector _original; + + int selected_resolution = 0; + }; +} \ No newline at end of file diff --git a/common/model-views.cpp b/common/model-views.cpp index 33258c871b..748f72a743 100644 --- a/common/model-views.cpp +++ b/common/model-views.cpp @@ -31,11 +31,12 @@ #include "imgui-fonts-karla.hpp" #include "imgui-fonts-fontawesome.hpp" +#include "imgui-fonts-monofont.hpp" #include "os.h" #include "metadata-helper.h" - +#include "calibration-model.h" using namespace rs400; using namespace nlohmann; @@ -137,7 +138,7 @@ namespace rs2 file.write((char*)bytes.data(), bytes.size()); } - void imgui_easy_theming(ImFont*& font_14, ImFont*& font_18) + void imgui_easy_theming(ImFont*& font_14, ImFont*& font_18, ImFont*& monofont) { ImGuiStyle& style = ImGui::GetStyle(); @@ -178,6 +179,21 @@ namespace rs2 } + // Load monofont + { + ImFontConfig config_words; + config_words.OversampleV = OVERSAMPLE; + config_words.OversampleH = OVERSAMPLE; + monofont = io.Fonts->AddFontFromMemoryCompressedTTF(monospace_compressed_data, monospace_compressed_size, 15.f); + + ImFontConfig config_glyphs; + config_glyphs.MergeMode = true; + config_glyphs.OversampleV = OVERSAMPLE; + config_glyphs.OversampleH = OVERSAMPLE; + monofont = io.Fonts->AddFontFromMemoryCompressedTTF(font_awesome_compressed_data, + font_awesome_compressed_size, 14.f, &config_glyphs, icons_ranges); + } + style.WindowRounding = 0.0f; style.ScrollbarRounding = 0.0f; @@ -3356,6 +3372,7 @@ namespace rs2 device_model::device_model(device& dev, std::string& error_message, viewer_model& viewer) : dev(dev), + _calib_model(dev), syncer(viewer.syncer), _update_readonly_options_timer(std::chrono::seconds(6)) , _detected_objects(std::make_shared< atomic_objects_in_frame >()), @@ -4505,6 +4522,7 @@ namespace rs2 ImGui::PopFont(); ImGui::PushFont(window.get_font()); static bool keep_showing_advanced_mode_modal = false; + bool open_calibration_ui = false; if (ImGui::BeginPopup(label.c_str())) { bool something_to_show = false; @@ -4738,6 +4756,80 @@ namespace rs2 ImGui::SetTooltip("Tare calibration is used to adjust camera absolute distance to flat target.\n" "User needs to enter the known ground truth"); + + if (_calib_model.supports()) + { + if (ImGui::Selectable("Calibration Data")) + { + _calib_model.open(); + } + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Access low level camera calibration parameters"); + } + + if (auto fwlogger = dev.as()) + { + if (ImGui::Selectable("Recover Logs from Flash")) + { + try + { + bool has_parser = false; + std::string hwlogger_xml = config_file::instance().get(configurations::viewer::hwlogger_xml); + std::ifstream f(hwlogger_xml.c_str()); + if (f.good()) + { + try + { + std::string str((std::istreambuf_iterator(f)), + std::istreambuf_iterator()); + fwlogger.init_parser(str); + has_parser = true; + } + catch (const std::exception& ex) + { + viewer.not_model->output.add_log(RS2_LOG_SEVERITY_WARN, __FILE__, __LINE__, + to_string() << "Invalid Hardware Logger XML at '" << hwlogger_xml << "': " << ex.what() << "\nEither configure valid XML or remove it"); + } + } + + auto message = fwlogger.create_message(); + + while (fwlogger.get_flash_log(message)) + { + auto parsed = fwlogger.create_parsed_message(); + auto parsed_ok = false; + + if (has_parser) + { + if (fwlogger.parse_log(message, parsed)) + { + parsed_ok = true; + + viewer.not_model->output.add_log(message.get_severity(), + parsed.file_name(), parsed.line(), to_string() + << "FW-LOG [" << parsed.thread_name() << "] " << parsed.message()); + } + } + + if (!parsed_ok) + { + std::stringstream ss; + for (auto& elem : message.data()) + ss << std::setfill('0') << std::setw(2) << std::hex << static_cast(elem) << " "; + viewer.not_model->output.add_log(message.get_severity(), __FILE__, 0, ss.str()); + } + } + } + catch(const std::exception& ex) + { + viewer.not_model->output.add_log(RS2_LOG_SEVERITY_WARN, __FILE__, __LINE__, + to_string() << "Failed to fetch firmware logs: " << ex.what()); + } + } + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Recovers last set of firmware logs prior to camera shutdown / disconnect"); + } + has_autocalib = true; } } @@ -4764,6 +4856,10 @@ namespace rs2 std::string msg = to_string() << "\t\tAre you sure you want to " << (is_advanced_mode_enabled ? "turn off Advanced mode" : "turn on Advanced mode") << "\t\t"; keep_showing_advanced_mode_modal = prompt_toggle_advanced_mode(!is_advanced_mode_enabled, msg, restarting_device_info, viewer, window); } + + _calib_model.update(window, error_message); + + //////////////////////////////////////// // Draw icons names //////////////////////////////////////// diff --git a/common/model-views.h b/common/model-views.h index 3ade00fb50..e79f6e9c60 100644 --- a/common/model-views.h +++ b/common/model-views.h @@ -26,6 +26,7 @@ #include "realsense-ui-advanced-mode.h" #include "fw-update-helper.h" #include "updates-model.h" +#include "calibration-model.h" ImVec4 from_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a, bool consistent_color = false); ImVec4 operator+(const ImVec4& c, float v); @@ -57,7 +58,8 @@ static const ImVec4 yellowish = from_rgba(255, 253, 191, 255, true); static const ImVec4 green = from_rgba(0x20, 0xe0, 0x20, 0xff, true); static const ImVec4 dark_sensor_bg = from_rgba(0x1b, 0x21, 0x25, 170); static const ImVec4 red = from_rgba(233, 0, 0, 255, true); -static const ImVec4 greenish = from_rgba(33, 104, 0, 255); +static const ImVec4 greenish = from_rgba(67, 163, 97, 255); +static const ImVec4 orange = from_rgba(255, 157, 0, 255, true); inline ImVec4 operator*(const ImVec4& color, float t) { @@ -68,44 +70,6 @@ inline ImVec4 operator+(const ImVec4& a, const ImVec4& b) return ImVec4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); } -// Helper class that lets smoothly animate between its values -template -class animated -{ -private: - T _old, _new; - std::chrono::system_clock::time_point _last_update; - std::chrono::system_clock::duration _duration; -public: - animated(T def, std::chrono::system_clock::duration duration = std::chrono::milliseconds(200)) - : _duration(duration) - { - _last_update = std::chrono::system_clock::now(); - } - animated& operator=(const T& other) - { - if (other != _new) - { - _old = get(); - _new = other; - _last_update = std::chrono::system_clock::now(); - } - return *this; - } - T get() const - { - auto now = std::chrono::system_clock::now(); - auto ms = std::chrono::duration_cast(now - _last_update).count(); - auto duration_ms = std::chrono::duration_cast(_duration).count(); - auto t = (float)ms / duration_ms; - t = std::max(0.f, std::min(rs2::smoothstep(t, 0.f, 1.f), 1.f)); - return _old * (1.f - t) + _new * t; - } - operator T() const { return get(); } - T value() const { return _new; } -}; - - inline ImVec4 blend(const ImVec4& c, float a) { return{ c.x, c.y, c.z, a * c.w }; @@ -166,6 +130,10 @@ namespace rs2 static const char* sw_updates_url { "update.sw_update_url" }; static const char* sw_updates_official_server { "update.sw_update_official_server" }; } + namespace calibration + { + static const char* enable_writing { "calibration.enable_writing" }; + } namespace viewer { static const char* is_3d_view { "viewer_model.is_3d_view" }; @@ -176,6 +144,8 @@ namespace rs2 static const char* sdk_version { "viewer_model.sdk_version" }; static const char* last_calib_notice { "viewer_model.last_calib_notice" }; static const char* is_measuring { "viewer_model.is_measuring" }; + static const char* output_open { "viewer_model.output_open" }; + static const char* search_term { "viewer_model.search_term" }; static const char* log_to_console { "viewer_model.log_to_console" }; static const char* log_to_file { "viewer_model.log_to_file" }; @@ -186,6 +156,8 @@ namespace rs2 static const char* show_stream_details { "viewer_model.show_stream_details" }; static const char* metric_system { "viewer_model.metric_system" }; static const char* shading_mode { "viewer_model.shading_mode" }; + static const char* commands_xml { "viewer_model.commands_xml" }; + static const char* hwlogger_xml { "viewer_model.hwlogger_xml" }; static const char* last_ip { "viewer_model.last_ip" }; } @@ -284,7 +256,7 @@ namespace rs2 class subdevice_model; struct notifications_model; - void imgui_easy_theming(ImFont*& font_14, ImFont*& font_18); + void imgui_easy_theming(ImFont*& font_14, ImFont*& font_18, ImFont*& monofont); // avoid display the following options bool static skip_option(rs2_option opt) @@ -860,6 +832,7 @@ namespace rs2 std::shared_ptr< atomic_objects_in_frame > _detected_objects; std::shared_ptr _updates; sw_update::dev_updates_profile::update_profile _updates_profile; + calibration_model _calib_model; }; class viewer_model; diff --git a/common/notifications.cpp b/common/notifications.cpp index 8e0e3a8136..82539156d8 100644 --- a/common/notifications.cpp +++ b/common/notifications.cpp @@ -511,7 +511,7 @@ namespace rs2 } } - add_log(n.get_description()); + output.add_log(n.get_severity(), __FILE__, __LINE__, n.get_description()); return result; } @@ -538,55 +538,7 @@ namespace rs2 } } - add_log(model->get_title()); - } - - void notifications_model::draw_snoozed_button() - { - auto has_snoozed = snoozed_notifications.size(); - ImGui::PushStyleColor(ImGuiCol_Text, !has_snoozed ? sensor_bg : light_grey); - ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, !has_snoozed ? sensor_bg : light_blue); - - const auto width = 50.f; - - using namespace std; - using namespace chrono; - - if (!has_snoozed) - { - ImGui::ButtonEx(textual_icons::mail, { width, width }, ImGuiButtonFlags_Disabled); - - if (ImGui::IsItemActive()) - ImGui::SetTooltip("No pending notifications at this point"); - } - else - { - auto k = duration_cast(system_clock::now() - last_snoozed).count() / 500.f; - if (k <= 1.f) - { - auto size = 50.f; - - ImGui::PopStyleColor(); - ImGui::PushStyleColor(ImGuiCol_Text, saturate(white, smoothstep(static_cast(k), 0.f, 1.f))); - } - - if (ImGui::Button(textual_icons::mail, { width, width })) - { - for (auto&& n : snoozed_notifications) - { - n->forced = true; - n->snoozed = false; - n->last_y -= 500; - pending_notifications.push_back(n); - } - snoozed_notifications.clear(); - } - - if (ImGui::IsItemActive()) - ImGui::SetTooltip("Pending notifications available. Click to review"); - } - - ImGui::PopStyleColor(2); + output.add_log(model->severity, __FILE__, __LINE__, model->get_title()); } void notifications_model::draw(ux_window& win, int w, int h, std::string& error_message) @@ -600,13 +552,6 @@ namespace rs2 std::lock_guard lock(m); if (pending_notifications.size() > 0) { - snoozed_notifications.erase(std::remove_if(std::begin(snoozed_notifications), - std::end(snoozed_notifications), - [&](std::shared_ptr& n) - { - return n->dismissed; - }), end(snoozed_notifications)); - // loop over all notifications, remove "old" ones pending_notifications.erase(std::remove_if(std::begin(pending_notifications), std::end(pending_notifications), @@ -616,8 +561,6 @@ namespace rs2 { n->dismissed = false; n->to_close = false; - snoozed_notifications.push_back(n); - last_snoozed = std::chrono::system_clock::now(); return true; } return ((n->get_age_in_ms() > n->get_max_lifetime_ms() && @@ -727,45 +670,6 @@ namespace rs2 ImGui::PopFont(); } - void notifications_model::foreach_log(std::function action) - { - std::lock_guard lock(m); - - // Process only the messages that are available upon invocation - std::string log_entry; - for (size_t len = 0; len < incoming_log_queue.size(); len++) - { - if (incoming_log_queue.try_dequeue(&log_entry)) - notification_logs.push_back(log_entry); - } - - // Limit the notification window - while (notification_logs.size() > 200) - notification_logs.pop_front(); - - for (auto&& l : notification_logs) - action(l); - - auto rc = ImGui::GetCursorPos(); - ImGui::SetCursorPos({ rc.x, rc.y + 5 }); - - if (new_log) - { - ImGui::SetScrollPosHere(); - new_log = false; - } - } - - // Callback function must not include mutex - void notifications_model::add_log(std::string line) - { - if (!line.size()) return; - - if (line[line.size() - 1] != '\n') line += "\n"; - incoming_log_queue.enqueue(std::move(line)); - new_log = true; - } - version_upgrade_model::version_upgrade_model(int version) : process_notification_model(nullptr), _version(version) { diff --git a/common/notifications.h b/common/notifications.h index 4482747485..2aa1e5574e 100644 --- a/common/notifications.h +++ b/common/notifications.h @@ -9,7 +9,8 @@ #include #include "ux-window.h" -#include "../src/concurrency.h" + +#include "output-model.h" namespace rs2 { @@ -195,25 +196,22 @@ namespace rs2 void add_notification(std::shared_ptr model); void draw(ux_window& win, int w, int h, std::string& error_message); - void foreach_log(std::function action); - void add_log(std::string line); + notifications_model() {} - void draw_snoozed_button(); + void add_log(std::string message) + { + output.add_log(RS2_LOG_SEVERITY_INFO, "", 0, message); + } - notifications_model() : last_snoozed(std::chrono::system_clock::now()) {} + output_model output; private: std::vector> pending_notifications; - std::vector> snoozed_notifications; int index = 1; const int MAX_SIZE = 6; std::recursive_mutex m; - bool new_log = false; - single_consumer_queue incoming_log_queue; - std::deque notification_logs; std::shared_ptr selected; - std::chrono::system_clock::time_point last_snoozed; }; inline ImVec4 saturate(const ImVec4& a, float f) diff --git a/common/output-model.cpp b/common/output-model.cpp new file mode 100644 index 0000000000..63c120d2b6 --- /dev/null +++ b/common/output-model.cpp @@ -0,0 +1,1101 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +#include +#include "output-model.h" + +#include "model-views.h" +#include "os.h" + +#include +#include + +using namespace rs2; + +void output_model::thread_loop() +{ + while (!to_stop) + { + std::vector dev_copy; + { + std::lock_guard lock(devices_mutex); + dev_copy = devices; + } + if (enable_firmware_logs) + for (auto&& dev : devices) + { + try + { + if (auto fwlogger = dev.as()) + { + bool has_parser = false; + std::string hwlogger_xml = config_file::instance().get(configurations::viewer::hwlogger_xml); + std::ifstream f(hwlogger_xml.c_str()); + if (f.good()) + { + try + { + std::string str((std::istreambuf_iterator(f)), + std::istreambuf_iterator()); + fwlogger.init_parser(str); + has_parser = true; + } + catch (const std::exception& ex) + { + add_log(RS2_LOG_SEVERITY_WARN, __FILE__, __LINE__, + to_string() << "Invalid Hardware Logger XML at '" << hwlogger_xml << "': " << ex.what() << "\nEither configure valid XML or remove it"); + } + } + + auto message = fwlogger.create_message(); + while (fwlogger.get_firmware_log(message)) + { + auto parsed = fwlogger.create_parsed_message(); + auto parsed_ok = false; + + if (has_parser) + { + if (fwlogger.parse_log(message, parsed)) + { + parsed_ok = true; + + add_log(message.get_severity(), + parsed.file_name(), parsed.line(), to_string() + << "FW-LOG [" << parsed.thread_name() << "] " << parsed.message()); + } + } + + if (!parsed_ok) + { + std::stringstream ss; + for (auto& elem : message.data()) + ss << std::setfill('0') << std::setw(2) << std::hex << static_cast(elem) << " "; + add_log(message.get_severity(), __FILE__, 0, ss.str()); + } + } + } + } + catch(const std::exception& ex) + { + add_log(RS2_LOG_SEVERITY_WARN, __FILE__, __LINE__, + to_string() << "Failed to fetch firmware logs: " << ex.what()); + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } +} + +output_model::~output_model() +{ + to_stop = 1; + fw_logger.join(); +} + +output_model::output_model() : fw_logger([this](){ thread_loop(); }) +{ + is_output_open = config_file::instance().get_or_default( + configurations::viewer::output_open, false); + search_line = config_file::instance().get_or_default( + configurations::viewer::search_term, std::string("")); + if (search_line != "") search_open = true; + + available_dashboards["Frame Drops per Second"] = [&](std::string name){ + return std::make_shared(name, &number_of_drops, &total_frames); + }; + + auto front = available_dashboards.begin(); + dashboards.push_back(front->second(front->first)); +} + +bool output_model::round_indicator(ux_window& win, std::string icon, + int count, ImVec4 color, std::string tooltip, bool& highlighted, std::string suffix) +{ + std::stringstream ss; + ss << icon; + if (count > 0) ss << " " << count << suffix; + auto size = ImGui::CalcTextSize(ss.str().c_str()); + + if (count == 0 || (!is_output_open && !highlighted)) { + color = dark_sensor_bg; + ImGui::PushStyleColor(ImGuiCol_Text, header_color); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, header_color); + } + else + { + if (!highlighted) + { + color = saturate(color, 0.3f); + ImGui::PushStyleColor(ImGuiCol_Text, white); + } + else + ImGui::PushStyleColor(ImGuiCol_Text, light_grey); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white); + } + + auto pos = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled({ pos.x, pos.y + 3 }, + { pos.x + size.x + 15, pos.y + 27 }, ImColor(color), 12, 15); + + auto res = ImGui::Button(ss.str().c_str(), ImVec2(size.x + 15, 28)); + if (count > 0 && ImGui::IsItemHovered()) + { + highlighted = true; + win.link_hovered(); + ImGui::SetTooltip("%s", tooltip.c_str()); + } + else highlighted = false; + + ImGui::PopStyleColor(2); + + return res; +} + +void output_model::open(ux_window& win) +{ + is_output_open = true; + config_file::instance().set(configurations::viewer::output_open, true); + default_log_h = (win.height() - 100) / 2; + new_log = true; +} + +void output_model::draw(ux_window& win, rect view_rect, std::vector devices) +{ + ImGui::PushStyleColor(ImGuiCol_FrameBg, scrollbar_bg); + + auto x = view_rect.x; + auto y = view_rect.y; + auto w = view_rect.w; + auto h = view_rect.h; + + auto flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings; + + ImGui::PushStyleColor(ImGuiCol_WindowBg, sensor_bg); + ImGui::PushStyleColor(ImGuiCol_Button, transparent); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, transparent); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, transparent); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white); + ImGui::PushStyleColor(ImGuiCol_Text, light_grey); + + ImGui::PushFont(win.get_font()); + ImGui::SetNextWindowPos({ x, y }); + ImGui::SetNextWindowSize({ w, h }); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(3, 3)); + + ImGui::Begin("Output", nullptr, flags); + + ImGui::SetCursorPosX(w - 31); + if (!is_output_open) + { + if (ImGui::Button(u8"\uF139", ImVec2(28, 28))) + { + open(win); + } + if (ImGui::IsItemHovered()) + { + win.link_hovered(); + ImGui::SetTooltip("%s", "Open Debug Console Window"); + } + + if (default_log_h.value() != 36) + default_log_h = 36; + } + else + { + if (ImGui::Button(u8"\uF13A", ImVec2(28, 28))) + { + is_output_open = false; + config_file::instance().set(configurations::viewer::output_open, false); + default_log_h = 36; + search_open = false; + } + if (ImGui::IsItemHovered()) + { + win.link_hovered(); + ImGui::SetTooltip("%s", "Collapse Debug Console Window"); + } + + if (default_log_h.value() != (win.height() - 100) / 2) + default_log_h = (win.height() - 100) / 2; + } + + ImGui::SameLine(); + ImGui::SetCursorPosX(5); + + if (errors_selected) errors_highlighted = true; + if (round_indicator(win, u8"\uF057", number_of_errors, redish, "Instances of logged errors", errors_highlighted)) + { + errors_selected = !errors_selected; + open(win); + } + ImGui::SameLine(); + + if (warnings_selected) warnings_highlighted = true; + if (round_indicator(win, u8"\uF071", number_of_warnings, orange, "Instances of logged warnings", warnings_highlighted)) + { + warnings_selected = !warnings_selected; + open(win); + } + ImGui::SameLine(); + + if (info_selected) info_highlighted = true; + if (round_indicator(win, u8"\uF05A", number_of_info, greenish, "Instances of logged info messages", info_highlighted)) + { + info_selected = !info_selected; + open(win); + } + ImGui::SameLine(); + + if (!is_output_open || search_open) + { + ImGui::PushStyleColor(ImGuiCol_Text, header_color); + } + else + { + ImGui::PushStyleColor(ImGuiCol_Text, light_grey); + } + bool focus_search = false; + if (ImGui::Button(u8"\uF002", ImVec2(28, 28))) + { + focus_search = true; + search_open = true; + open(win); + } + if (ImGui::IsItemHovered()) + { + win.link_hovered(); + ImGui::SetTooltip("%s", "Search through logs"); + } + ImGui::PopStyleColor(1); + ImGui::SameLine(); + + auto curr_x = ImGui::GetCursorPosX(); + ImGui::SetCursorPosX(curr_x - 5); + + + int percent = total_frames ? 100 * ((double)number_of_drops / (total_frames)) : 0; + + std::stringstream ss; + ss << u8"\uF043"; + if (percent) ss << " " << percent << "%"; + auto size = ImGui::CalcTextSize(ss.str().c_str()); + + char buff[1024]; + memcpy(buff, search_line.c_str(), search_line.size()); + buff[search_line.size()] = 0; + + auto actual_search_width = w - size.x - 100 - curr_x; + if (focus_search) search_width = actual_search_width; + + if (search_open && search_width.value() != actual_search_width) + search_width = actual_search_width; + + // if (is_output_open && search_width < 1) + // { + // search_open = true; + // } + + if (search_open) + { + ImGui::PushFont(win.get_monofont()); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 4); + ImGui::PushItemWidth(search_width); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, regular_blue); + if (ImGui::InputText("##SearchInLogs",buff, 1023)) + { + search_line = buff; + config_file::instance().set(configurations::viewer::search_term, search_line); + } + if (focus_search) ImGui::SetKeyboardFocusHere(); + ImGui::PopItemWidth(); + ImGui::SameLine(); + ImGui::PopStyleColor(); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 4); + ImGui::PopFont(); + } + + ImGui::SetCursorPosX(w - size.x - 3 * 30); + + if (enable_firmware_logs) + { + ImGui::PushStyleColor(ImGuiCol_Text, light_blue); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, light_blue); + } + else + { + if (is_output_open) + ImGui::PushStyleColor(ImGuiCol_Text, light_grey); + else + ImGui::PushStyleColor(ImGuiCol_Text, header_color); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white); + } + + if (ImGui::Button(u8"\uF2DB", ImVec2(28, 28))) + { + enable_firmware_logs = !enable_firmware_logs; + } + ImGui::PopStyleColor(2); + if (ImGui::IsItemHovered()) + { + win.link_hovered(); + if (enable_firmware_logs) ImGui::SetTooltip("%s", "Disable Firmware Logs"); + else ImGui::SetTooltip("%s", "Enable Firmware Logs"); + } + ImGui::SameLine(); + + + if (round_indicator(win, u8"\uF043", percent, regular_blue, "Frame drops", drops_highlighted, "%")) + { + open(win); + } + + if (is_output_open) + { + ImGui::SetCursorPos(ImVec2(3, 35)); + + + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0)); + ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, dark_sensor_bg); + + ImGui::BeginChild("##LogArea", + ImVec2(0.7f * w - 4, h - 38 - ImGui::GetTextLineHeightWithSpacing() - 1), true, + ImGuiWindowFlags_AlwaysVerticalScrollbar); + + const auto log_area_width = 0.7f * w - 4; + + bool copy_all = false; + bool save_all = false; + std::vector output_strings; + + auto time_now = glfwGetTime(); + + int i = 0; + foreach_log([&](log_entry& log) + { + auto line = log.line; + if (log.line_number) + { + line = log.filename.substr(log.filename.find_last_of("/\\") + 1) + ":"; + line += std::string(to_string() << log.line_number) + " - "; + line += log.line; + } + + bool ok = false; + if (info_selected || warnings_selected || errors_selected) + { + if (info_selected && log.severity <= RS2_LOG_SEVERITY_INFO) ok = true; + if (warnings_selected && log.severity == RS2_LOG_SEVERITY_WARN) ok = true; + if (errors_selected && log.severity >= RS2_LOG_SEVERITY_ERROR) ok = true; + } + else ok = true; + + if (search_line != "" && to_lower(line).find(to_lower(search_line)) == std::string::npos) ok = false; + + if (!ok) return; + + std::stringstream ss; ss << log.timestamp << " [" << rs2_log_severity_to_string(log.severity) << "] "; + if (log.line_number) ss << log.filename << ":" << log.line_number; + ss << " - " << log.line; + std::string full = ss.str(); + + ImGui::PushFont(win.get_monofont()); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, regular_blue); + ImGui::PushStyleColor(ImGuiCol_Text, light_grey); + ImGui::PushStyleColor(ImGuiCol_FrameBg, transparent); + + ImVec4 color = redish; + if (log.severity >= RS2_LOG_SEVERITY_ERROR) + { + color = redish; + } + else if (log.severity >= RS2_LOG_SEVERITY_WARN) + { + color = orange; + } + else + { + color = greenish; + } + + auto margin = ImGui::GetTextLineHeightWithSpacing() - ImGui::GetTextLineHeight(); + auto size = ImGui::CalcTextSize(line.c_str()); + + auto t = single_wave(time_now - log.time_added + 0.3f) * 0.2f; + if (log.selected) t = 0.2f; + + auto pos = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled({ pos.x, pos.y }, + { pos.x + log_area_width, pos.y + size.y + 2 * margin }, + ImColor(alpha(saturate(color, 0.3f + t), 0.7f + t))); + ImGui::GetWindowDrawList()->AddLine({ pos.x, pos.y + size.y + 2 * margin }, + { pos.x + log_area_width, pos.y + size.y + 2 * margin }, ImColor(alpha(color, 0.5f))); + + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 4); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 4); + ImGui::Text("%s", log.timestamp.c_str()); ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 4); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 4); + + std::string label = to_string() << "##log_entry" << i++; + ImGui::InputTextEx(label.c_str(), + (char*)line.data(), + static_cast(line.size() + 1), + ImVec2(-1, size.y + margin), + ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_ReadOnly); + + ImGui::PushStyleColor(ImGuiCol_PopupBg, almost_white_bg); + ImGui::PushStyleColor(ImGuiCol_Text, black); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, light_blue); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(5,5)); + label = to_string() << "##log_entry" << i << "_context_menu"; + if (ImGui::BeginPopupContextItem(label.c_str())) + { + log.selected = true; + ImGui::PushFont(win.get_font()); + if (ImGui::Selectable("Copy Line")) { + glfwSetClipboardString(win, full.c_str()); + } + if (ImGui::Selectable("Copy All")) { + copy_all = true; + } + if (ImGui::Selectable("Save As...")) { + save_all = true; + } + ImGui::PopFont(); + ImGui::EndPopup(); + } + else log.selected = false; + ImGui::PopStyleVar(); + ImGui::PopStyleColor(4); + + ImGui::PopStyleColor(3); + ImGui::PopFont(); + + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 1); + + output_strings.push_back(full); + }); + + std::stringstream ss; + for (auto&& s : output_strings) ss << s << "\n"; + if (copy_all) + glfwSetClipboardString(win, ss.str().c_str()); + + if (save_all) + { + if (auto fn = file_dialog_open(file_dialog_mode::save_file, "Log File\0*.log\0", nullptr, nullptr)) + { + std::ofstream out(fn); + if (out.good()) + { + out << ss.str(); + } + out.close(); + } + } + + ImGui::EndChild(); + ImGui::PopStyleVar(); + + + ImGui::SetCursorPos(ImVec2(7, h - ImGui::GetTextLineHeightWithSpacing() - 2)); + ImGui::Text("%s", u8"\uF120"); ImGui::SameLine(); + ImGui::SetCursorPos(ImVec2(30, h - ImGui::GetTextLineHeightWithSpacing() - 4)); + + + ImGui::PushFont(win.get_monofont()); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, regular_blue); + ImGui::PushItemWidth(0.7f * w - 32); + + bool force_refresh = false; + + if (ImGui::IsKeyPressed(GLFW_KEY_UP) || ImGui::IsKeyPressed(GLFW_KEY_DOWN)) + { + if (commands_histroy.size()) + { + if (ImGui::IsKeyPressed(GLFW_KEY_UP)) history_offset = (history_offset + 1) % commands_histroy.size(); + if (ImGui::IsKeyPressed(GLFW_KEY_DOWN)) history_offset = (history_offset - 1 + commands_histroy.size()) % commands_histroy.size(); + command_line = commands_histroy[history_offset]; + + force_refresh = true; + } + } + + if (ImGui::IsKeyPressed(GLFW_KEY_TAB)) + { + if (!autocomplete.size() || !starts_with(to_lower(autocomplete.front()), to_lower(command_line))) + { + std::string commands_xml = config_file::instance().get(configurations::viewer::commands_xml); + std::ifstream f(commands_xml.c_str()); + if (f.good()) + { + std::string str((std::istreambuf_iterator(f)), + std::istreambuf_iterator()); + + autocomplete.clear(); + std::regex exp("Command Name=\"(\\w+)\""); + std::smatch res; + std::string::const_iterator searchStart(str.cbegin()); + while (regex_search(searchStart, str.cend(), res, exp)) + { + if (starts_with(to_lower(res[1]), to_lower(command_line))) + autocomplete.push_back(res[1]); + searchStart = res.suffix().first; + } + } + } + if (autocomplete.size()) + { + auto temp = autocomplete.front(); + autocomplete.pop_front(); + autocomplete.push_back(temp); + + if (starts_with(to_lower(temp), command_line)) + command_line = to_lower(autocomplete.front()); + else + command_line = autocomplete.front(); + force_refresh = true; + } + } + + memcpy(buff, command_line.c_str(), command_line.size()); + buff[command_line.size()] = 0; + + int flags = ImGuiInputTextFlags_EnterReturnsTrue; + if (force_refresh) + { + flags = ImGuiInputTextFlags_ReadOnly; + } + + ImGui::PushStyleColor(ImGuiCol_FrameBg, scrollbar_bg); + if (ImGui::InputText("##TerminalCommand", buff, 1023, flags)) + { + + } + if (!command_focus && !new_log) command_line = buff; + ImGui::PopStyleColor(); + if (command_focus || new_log) ImGui::SetKeyboardFocusHere(); + ImGui::PopFont(); + ImGui::PopStyleColor(); + + if (ImGui::IsKeyPressed(GLFW_KEY_ENTER) || ImGui::IsKeyPressed(GLFW_KEY_KP_ENTER)) + { + if (commands_histroy.size() > 100) commands_histroy.pop_back(); + commands_histroy.push_front(command_line); + run_command(command_line, devices); + command_line = ""; + command_focus = true; + } + else command_focus = false; + + if (ImGui::IsKeyPressed(GLFW_KEY_ESCAPE)) + { + command_line = ""; + } + + ImGui::SetCursorPos(ImVec2(0.7f * w - 2, 35)); + ImGui::BeginChild("##StatsArea",ImVec2(0.3f * w - 2, h - 38), true); + + auto top = 0; + for(auto&& dash : dashboards) + { + auto h = dash->get_height(); + auto r = rect { 0.f, top, 0.3f * w - 2, h }; + dash->draw(win, r); + top += h; + } + + dashboards.erase(std::remove_if(dashboards.begin(), dashboards.end(), + [](std::shared_ptr p){ + return p->closing(); + }), dashboards.end()); + + bool can_add = false; + for (auto&& kvp : available_dashboards) + { + auto name = kvp.first; + auto it = std::find_if(dashboards.begin(), dashboards.end(), + [name](std::shared_ptr p){ + return p->get_name() == name; + }); + if (it == dashboards.end()) can_add = true; + } + + if (can_add) + { + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); + const auto new_dashboard_name = "new_dashaborad"; + if (ImGui::Button(u8"\uF0D0 Add Dashboard", ImVec2(-1, 25))) + { + ImGui::OpenPopup(new_dashboard_name); + } + + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("Add one of the available stream dashboards to view"); + win.link_hovered(); + } + + ImGui::PushStyleColor(ImGuiCol_PopupBg, almost_white_bg); + ImGui::PushStyleColor(ImGuiCol_Text, black); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, light_blue); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(5,5)); + if (ImGui::BeginPopup(new_dashboard_name)) + { + for (auto&& kvp : available_dashboards) + { + auto name = kvp.first; + auto it = std::find_if(dashboards.begin(), dashboards.end(), + [name](std::shared_ptr p){ + return p->get_name() == name; + }); + if (it == dashboards.end()) + { + name = name + "##New"; + bool selected = false; + if (ImGui::Selectable(name.c_str(), &selected)) + { + dashboards.push_back(kvp.second(kvp.first)); + } + } + } + + ImGui::EndPopup(); + } + + ImGui::PopStyleColor(4); + ImGui::PopStyleVar(); + } + + + ImGui::EndChild(); + + + ImGui::PopStyleColor(); + } + else foreach_log([&](log_entry& log) {}); + + + ImGui::End(); + ImGui::PopStyleColor(7); + ImGui::PopStyleVar(); + ImGui::PopFont(); + + { + std::lock_guard lock(devices_mutex); + this->devices = devices; + } +} + +void output_model::foreach_log(std::function action) +{ + std::lock_guard lock(m); + + // Process only the messages that are available upon invocation + log_entry le; + for (size_t len = 0; len < incoming_log_queue.size(); len++) + { + if (incoming_log_queue.try_dequeue(&le)) + { + if (le.severity >= RS2_LOG_SEVERITY_ERROR) number_of_errors++; + else if (le.severity >= RS2_LOG_SEVERITY_WARN) number_of_warnings++; + else number_of_info++; + + notification_logs.push_back(le); + } + } + + // Limit the notification window + while (notification_logs.size() > 1000) + { + auto&& le = notification_logs.front(); + if (le.severity >= RS2_LOG_SEVERITY_ERROR) number_of_errors--; + else if (le.severity >= RS2_LOG_SEVERITY_WARN) number_of_warnings--; + else number_of_info--; + notification_logs.pop_front(); + } + + for (auto&& l : notification_logs) + action(l); + + if (new_log) + { + ImGui::SetScrollPosHere(); + new_log = false; + } +} + +// Callback function must not include mutex +void output_model::add_log(rs2_log_severity severity, std::string filename, int line_number, std::string line) +{ + if (!line.size()) return; + + time_t rawtime; + struct tm * timeinfo; + char buffer[80]; + time (&rawtime); + timeinfo = localtime(&rawtime); + strftime(buffer,sizeof(buffer),"%H:%M:%S",timeinfo); + + log_entry e; + e.line = line; + e.line_number = line_number; + e.filename = filename; + e.severity = severity; + e.timestamp = buffer; + e.time_added = glfwGetTime(); + + incoming_log_queue.enqueue(std::move(e)); + new_log = true; +} + +void output_model::run_command(std::string command, std::vector devices) +{ + try + { + if (to_lower(command) == "clear") + { + while (notification_logs.size() > 0) + { + auto&& le = notification_logs.front(); + if (le.severity >= RS2_LOG_SEVERITY_ERROR) number_of_errors--; + else if (le.severity >= RS2_LOG_SEVERITY_WARN) number_of_warnings--; + else number_of_info--; + notification_logs.pop_front(); + for (auto& d : dashboards) + d->clear(true); + } + + return; + } + + std::regex e("([0-9A-Fa-f]{2}\\s)+"); + + if (std::regex_match(command, e)) + { + add_log(RS2_LOG_SEVERITY_INFO, __FILE__, 0, to_string() << "Trying to send " << command << "..."); + + std::vector raw_data; + std::stringstream ss(command); + std::string word; + while (ss >> word) + { + std::stringstream converter; + int temp; + converter << std::hex << word; + converter >> temp; + raw_data.push_back(temp); + } + if (raw_data.empty()) + throw std::runtime_error("Invalid input!"); + + bool found = false; + for (auto&& dev : devices) + { + if (auto dbg = dev.as()) + { + found = true; + auto res = dbg.send_and_receive_raw_data(raw_data); + + std::stringstream ss; + int i = 0; + for (auto& elem : res) + { + ss << std::setfill('0') << std::setw(2) << std::hex << static_cast(elem) << " "; + i++; + if (i > 80) + { + ss << "\n"; + i = 0; + } + } + add_log(RS2_LOG_SEVERITY_INFO, __FILE__, 0, ss.str()); + + return; + } + } + + if (!found) + { + add_log(RS2_LOG_SEVERITY_WARN, __FILE__, __LINE__, "No device is available to receive the command"); + return; + } + } + + std::string commands_xml = config_file::instance().get(configurations::viewer::commands_xml); + std::ifstream f(commands_xml.c_str()); + if (f.good()) + { + std::string str((std::istreambuf_iterator(f)), + std::istreambuf_iterator()); + auto terminal_parser = rs2::terminal_parser(str); + + auto buffer = terminal_parser.parse_command(to_lower(command)); + + std::stringstream ss; ss << command << " = "; + for (auto& elem : buffer) + ss << std::setfill('0') << std::setw(2) << std::hex << static_cast(elem) << " "; + + add_log(RS2_LOG_SEVERITY_INFO, __FILE__, 0, ss.str()); + + bool found = false; + for (auto&& dev : devices) + { + if (auto dbg = dev.as()) + { + found = true; + auto res = dbg.send_and_receive_raw_data(buffer); + + std::string response = to_string() << "\n" << terminal_parser.parse_response(to_lower(command), res); + add_log(RS2_LOG_SEVERITY_INFO, __FILE__, 0, response); + } + } + + if (!found) + add_log(RS2_LOG_SEVERITY_WARN, __FILE__, __LINE__, "No device is available to receive the command"); + + return; + } + + add_log(RS2_LOG_SEVERITY_WARN, __FILE__, __LINE__, to_string() << "Unrecognized command '" << command << "'"); + } + catch(const std::exception& ex) + { + add_log(RS2_LOG_SEVERITY_ERROR, __FILE__, __LINE__, ex.what()); + } +} + +void output_model::update_dashboards(rs2::frame f) +{ + for (auto&& d : dashboards) + d->add_frame(f); +} + +void stream_dashboard::draw_dashboard(ux_window& win, rect& r) +{ + auto min_x = 0.f; + auto max_x = 1.f; + auto min_y = 0.f; + auto max_y = 1.f; + + if (xy.size()) + { + min_x = xy[0].first; + max_x = xy[0].first; + min_y = xy[0].second; + max_y = xy[0].second; + for (auto&& p : xy) + { + min_x = std::min(min_x, p.first); + min_y = std::min(min_y, p.second); + max_x = std::max(max_x, p.first); + max_y = std::max(max_y, p.second); + } + } + + auto gap_y = max_y - min_y; + auto gap_x = max_x - min_x; + auto height_y = r.h - 2 * ImGui::GetTextLineHeight() - 10; + auto ticks_y = ceil(height_y / ImGui::GetTextLineHeight()); + + auto max_y_label_width = 0.f; + for (int i = 0; i <= ticks_y; i++) + { + auto y = max_y - i * (gap_y / ticks_y); + std::string y_label = to_string() << std::fixed << std::setprecision(2) << y; + auto size = ImGui::CalcTextSize(y_label.c_str()); + max_y_label_width = std::max(max_y_label_width, + size.x); + } + + auto pos = ImGui::GetCursorScreenPos(); + + ImGui::PushStyleColor(ImGuiCol_Text, white); + + ImGui::GetWindowDrawList()->AddRectFilled({ pos.x, pos.y }, + { pos.x + r.w - 1, pos.y + get_height() - 1 }, ImColor(header_color)); + ImGui::GetWindowDrawList()->AddRect({ pos.x, pos.y }, + { pos.x + r.w, pos.y + get_height() }, ImColor(dark_sensor_bg)); + + auto size = ImGui::CalcTextSize(name.c_str()); + ImGui::SetCursorPos(ImVec2( r.w / 2 - size.x / 2, 5 )); + ImGui::Text("%s", name.c_str()); + ImGui::SameLine(); + + ImGui::PushStyleColor(ImGuiCol_Text, grey); + ImGui::SetCursorPosX(r.w - 25); + ImGui::SetCursorPosY(3); + std::string id = to_string() << u8"\uF00D##Close_" << name; + if (ImGui::Button(id.c_str(),ImVec2(22,22))) + { + close(); + } + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("Remove Dashboard from View"); + win.link_hovered(); + } + ImGui::PopStyleColor(); + + ImGui::GetWindowDrawList()->AddRectFilled({ pos.x + max_y_label_width + 15, pos.y + ImGui::GetTextLineHeight() + 5 }, + { pos.x + r.w - 10, pos.y + r.h - ImGui::GetTextLineHeight() - 5 }, ImColor(almost_white_bg)); + + //ImGui::PushFont(win.get_monofont()); + for (int i = 0; i <= ticks_y; i++) + { + auto y = max_y - i * (gap_y / ticks_y); + std::string y_label = to_string() << std::fixed << std::setprecision(2) << y; + auto y_pixel = ImGui::GetTextLineHeight() + i * (height_y / ticks_y); + ImGui::SetCursorPos(ImVec2( 10, y_pixel )); + ImGui::Text("%s", y_label.c_str()); + + ImGui::GetWindowDrawList()->AddLine({ pos.x + max_y_label_width + 15, pos.y + y_pixel + 5 }, + { pos.x + r.w - 10, pos.y + y_pixel + 5 }, ImColor(light_grey)); + } + + auto graph_width = r.w - max_y_label_width - 25; + + int ticks_x = 2; + bool has_room = true; + while (has_room) + { + auto total = 0; + for (int i = 0; i <= ticks_x; i++) + { + auto x = min_x + i * (gap_x / ticks_x); + std::string x_label = to_string() << std::fixed << std::setprecision(2) << x; + auto size = ImGui::CalcTextSize(x_label.c_str()); + total += size.x; + } + if (total < graph_width) ticks_x++; + else has_room = false; + } + ticks_x -= 3; + + auto total = 0; + for (int i = 0; i < ticks_x; i++) + { + auto x = min_x + i * (gap_x / ticks_x); + std::string x_label = to_string() << std::fixed << std::setprecision(2) << x; + auto y_pixel = ImGui::GetTextLineHeight() + i * (height_y / ticks_y); + ImGui::SetCursorPos(ImVec2( 15 + max_y_label_width+ i * (graph_width / ticks_x), r.h - ImGui::GetTextLineHeight() )); + ImGui::Text("%s", x_label.c_str()); + + ImGui::GetWindowDrawList()->AddLine({ pos.x + 15 + max_y_label_width + i * (graph_width / ticks_x), pos.y + ImGui::GetTextLineHeight() + 5 }, + { pos.x + max_y_label_width + 15 + i * (graph_width / ticks_x), pos.y + ImGui::GetTextLineHeight() + 5 + height_y }, ImColor(light_grey)); + } + + std::sort(xy.begin(), xy.end(), [](const std::pair& a, const std::pair& b) { return a.first < b.first; }); + + for (int i = 0; i + 1 < xy.size(); i++) + { + auto x0 = xy[i].first; + auto y0 = xy[i].second; + + auto x1 = xy[i+1].first; + auto y1 = xy[i+1].second; + + x0 = (x0 - min_x) / (max_x - min_x); + x1 = (x1 - min_x) / (max_x - min_x); + + y0 = (y0 - min_y) / (max_y - min_y); + y1 = (y1 - min_y) / (max_y - min_y); + + ImGui::GetWindowDrawList()->AddLine({ pos.x + 15 + max_y_label_width + x0 * graph_width, pos.y + ImGui::GetTextLineHeight() + 5 + height_y * (1.f - y0) }, + { pos.x + 15 + max_y_label_width + x1 * graph_width, pos.y + ImGui::GetTextLineHeight() + 5 + height_y * (1.f - y1) }, ImColor(black)); + } + + //ImGui::PopFont(); + ImGui::PopStyleColor(); + + xy.clear(); +} + +void frame_drops_dashboard::process_frame(rs2::frame f) +{ + write_shared_data([&](){ + double ts = glfwGetTime(); + if (method == 1) ts = f.get_timestamp() / 1000.f; + auto it = stream_to_time.find(f.get_profile().unique_id()); + if (it != stream_to_time.end()) + { + auto last = stream_to_time[f.get_profile().unique_id()]; + + auto fps = f.get_profile().fps(); + + if (f.supports_frame_metadata(RS2_FRAME_METADATA_ACTUAL_FPS)) + fps = f.get_frame_metadata(RS2_FRAME_METADATA_ACTUAL_FPS); + + if (1000.f * (ts - last) > 1.5f * (1000.f / fps)) { + drops++; + } + } + + counter++; + + if (ts - last_time > 1.f) + { + if (drops_history.size() > 100) drops_history.pop_front(); + drops_history.push_back(drops); + *total = counter; + *frame_drop_count = drops; + drops = 0; + last_time = ts; + counter = 0; + } + + stream_to_time[f.get_profile().unique_id()] = ts; + }); +} + +void frame_drops_dashboard::draw(ux_window& win, rect r) +{ + auto hist = read_shared_data>([&](){ return drops_history; }); + for (int i = 0; i < hist.size(); i++) + { + add_point(i, hist[i]); + } + r.h -= ImGui::GetTextLineHeightWithSpacing() + 10; + draw_dashboard(win, r); + + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 40); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 3); + ImGui::Text("%s", "Measurement Metric:"); ImGui::SameLine(); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 3); + + ImGui::SetCursorPosX(200); + + std::vector methods; + methods.push_back("Viewer Processing Rate"); + methods.push_back("Camera Timestamp Rate"); + + ImGui::PushItemWidth(r.w - 207); + if (ImGui::Combo("##fps_method", &method, methods.data(), methods.size())) + { + clear(false); + } + ImGui::PopItemWidth(); +} + +int frame_drops_dashboard::get_height() const +{ + return 160.f + ImGui::GetTextLineHeightWithSpacing(); +} + +void frame_drops_dashboard::clear(bool full) +{ + write_shared_data([&](){ + stream_to_time.clear(); + last_time = 0; + *total = 0; + *frame_drop_count = 0; + if (full) + { + drops_history.clear(); + for (int i = 0; i < 100; i++) + drops_history.push_back(0); + } + }); +} \ No newline at end of file diff --git a/common/output-model.h b/common/output-model.h new file mode 100644 index 0000000000..345c95b9ab --- /dev/null +++ b/common/output-model.h @@ -0,0 +1,190 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +#pragma once + +#include +#include + +#include "ux-window.h" +#include "rendering.h" + +#include "../src/concurrency.h" + +namespace rs2 +{ + class stream_dashboard + { + public: + stream_dashboard(std::string name, int size) : q(size), name(name), t([this](){ thread_function(); }) {} + virtual ~stream_dashboard() + { + stop = true; + t.join(); + } + + std::string get_name() const { return name; } + + void add_frame(rs2::frame f) { q.enqueue(f); } + + virtual void draw(ux_window& win, rect r) = 0; + + virtual int get_height() const { return 150.f; } + + virtual void clear(bool full = false) {} + + void close() { to_close = true; } + bool closing() const { return to_close; } + + protected: + virtual void process_frame(rs2::frame f) = 0; + + void write_shared_data(std::function action) + { + std::lock_guard lock(m); + action(); + } + + template + T read_shared_data(std::function action) + { + std::lock_guard lock(m); + T res = action(); + return res; + } + + void add_point(float x, float y) { xy.push_back(std::make_pair(x, y)); } + + void draw_dashboard(ux_window& win, rect& r); + + private: + void thread_function() + { + while(!stop) + { + rs2::frame f; + if (q.try_wait_for_frame(&f, 100)) + process_frame(f); + } + } + std::string name; + rs2::frame_queue q; + std::mutex m; + std::atomic stop { false }; + std::thread t; + std::vector> xy; + bool to_close = false; + }; + + class frame_drops_dashboard : public stream_dashboard + { + public: + frame_drops_dashboard(std::string name, int* frame_drop_count, int* total) + : stream_dashboard(name, 30), + last_time(glfwGetTime()), frame_drop_count(frame_drop_count), total(total) + { + clear(true); + } + + void process_frame(rs2::frame f) override; + void draw(ux_window& win, rect r) override; + int get_height() const override; + + void clear(bool full) override; + + private: + std::map stream_to_time; + int drops = 0; + double last_time; + std::deque drops_history; + int *frame_drop_count, *total; + int counter = 0; + int method = 0; + }; + + class output_model + { + public: + struct log_entry + { + std::string line = ""; + std::string filename = ""; + rs2_log_severity severity = RS2_LOG_SEVERITY_FATAL; + int line_number = 0; + double time_added = 0.0; + std::string timestamp = ""; + bool selected = false; + }; + + void update_dashboards(rs2::frame f); + + output_model(); + ~output_model(); + + void add_log(rs2_log_severity severity, std::string filename, int line_number, std::string line); + + void draw(ux_window& win, rect view_rect, std::vector devices); + + int get_output_height() const { return default_log_h; } + + void run_command(std::string command, std::vector devices); + + private: + void open(ux_window& win); + + void foreach_log(std::function action); + bool round_indicator(ux_window& win, std::string icon, int count, + ImVec4 color, std::string tooltip, bool& highlighted, std::string suffix = ""); + + bool new_log = false; + std::recursive_mutex m; + + single_consumer_queue incoming_log_queue; + std::deque notification_logs; + + animated default_log_h { 36 }; + bool is_output_open = true; + + bool enable_firmware_logs = false; + + bool errors_selected = false; + bool warnings_selected = false; + bool info_selected = false; + + bool errors_highlighted = false; + bool warnings_highlighted = false; + bool info_highlighted = false; + bool drops_highlighted = false; + + rs2_log_severity min_severity = RS2_LOG_SEVERITY_DEBUG; + rs2_log_severity max_severity = RS2_LOG_SEVERITY_FATAL; + + int number_of_errors = 0; + int number_of_warnings = 0; + int number_of_info = 0; + int number_of_drops = 0; + int total_frames = 0; + + animated search_width { 0, std::chrono::milliseconds(400) }; + bool search_open = false; + + std::deque autocomplete; + + std::mutex devices_mutex; + std::vector devices; + + std::string search_line { "" }; + std::string command_line { "" }; + std::deque commands_histroy; + int history_offset = 0; + bool command_focus = true; + + std::vector> dashboards; + std::map(std::string)>> available_dashboards; + + std::atomic to_stop { 0 }; + std::thread fw_logger; + + void thread_loop(); + }; +} \ No newline at end of file diff --git a/common/rendering.h b/common/rendering.h index 59d5bedad4..61646505ea 100644 --- a/common/rendering.h +++ b/common/rendering.h @@ -1581,6 +1581,43 @@ namespace rs2 } }; + // Helper class that lets smoothly animate between its values + template + class animated + { + private: + T _old, _new; + std::chrono::system_clock::time_point _last_update; + std::chrono::system_clock::duration _duration; + public: + animated(T def, std::chrono::system_clock::duration duration = std::chrono::milliseconds(200)) + : _duration(duration), _old(def), _new(def) + { + _last_update = std::chrono::system_clock::now(); + } + animated& operator=(const T& other) + { + if (other != _new) + { + _old = get(); + _new = other; + _last_update = std::chrono::system_clock::now(); + } + return *this; + } + T get() const + { + auto now = std::chrono::system_clock::now(); + auto ms = std::chrono::duration_cast(now - _last_update).count(); + auto duration_ms = std::chrono::duration_cast(_duration).count(); + auto t = (float)ms / duration_ms; + t = std::max(0.f, std::min(rs2::smoothstep(t, 0.f, 1.f), 1.f)); + return _old * (1.f - t) + _new * t; + } + operator T() const { return get(); } + T value() const { return _new; } + }; + inline bool is_integer(float f) { return (fabs(fmod(f, 1)) < std::numeric_limits::min()); diff --git a/common/ux-window.cpp b/common/ux-window.cpp index 295373bbd7..4c0dfbf0e2 100644 --- a/common/ux-window.cpp +++ b/common/ux-window.cpp @@ -71,6 +71,9 @@ namespace rs2 config_file::instance().set_default(configurations::ply::use_normals, false); config_file::instance().set_default(configurations::ply::encoding, configurations::ply::binary); + config_file::instance().set_default(configurations::viewer::commands_xml, "./Commands.xml"); + config_file::instance().set_default(configurations::viewer::hwlogger_xml, "./HWLoggerEvents.xml"); + #ifdef __APPLE__ config_file::instance().set_default(configurations::performance::font_oversample, 8); config_file::instance().set_default(configurations::performance::enable_msaa, true); @@ -342,7 +345,7 @@ namespace rs2 _2d_vis = std::make_shared(std::make_shared()); // Load fonts to be used with the ImGui - TODO move to RAII - imgui_easy_theming(_font_14, _font_18); + imgui_easy_theming(_font_14, _font_18, _monofont); // Register for UI-controller events glfwSetWindowUserPointer(_win, this); @@ -397,7 +400,7 @@ namespace rs2 ux_window::ux_window(const char* title, context &ctx) : _win(nullptr), _width(0), _height(0), _output_height(0), - _font_14(nullptr), _font_18(nullptr), _app_ready(false), + _font_14(nullptr), _font_18(nullptr), _monofont(nullptr), _app_ready(false), _first_frame(true), _query_devices(true), _missing_device(false), _hourglass_index(0), _dev_stat_message{}, _keep_alive(true), _title(title), _ctx(ctx) { @@ -597,6 +600,7 @@ namespace rs2 glfwSetCursor(_win, nullptr); _cross_hovered = false; _link_hovered = false; + _hovers_any_input_window = false; return res; } diff --git a/common/ux-window.h b/common/ux-window.h index 1ad2394911..9244e58e3a 100644 --- a/common/ux-window.h +++ b/common/ux-window.h @@ -60,6 +60,7 @@ namespace rs2 void reset(); ImFont* get_large_font() const { return _font_18; } + ImFont* get_monofont() const { return _monofont; } ImFont* get_font() const { return _font_14; } rs2::mouse_info& get_mouse() { return _mouse; } @@ -78,6 +79,9 @@ namespace rs2 void link_hovered(); void cross_hovered(); + void set_hovered_over_input() { _hovers_any_input_window = true; } + bool get_hovered_over_input() const { return _hovers_any_input_window; } + double time() const { return glfwGetTime(); } private: void open_window(); @@ -93,7 +97,7 @@ namespace rs2 int _fb_height = 0; rs2::rect _viewer_rect; - ImFont *_font_14, *_font_18; + ImFont *_font_14, *_font_18, *_monofont; rs2::mouse_info _mouse{}; std::string _error_message; float _scale_factor; @@ -108,6 +112,7 @@ namespace rs2 std::vector _on_load_message; std::mutex _on_load_message_mtx; + bool _hovers_any_input_window = false; bool _query_devices = true; bool _missing_device = false; int _hourglass_index = 0; diff --git a/common/viewer.cpp b/common/viewer.cpp index 49497171da..d20bf84ca3 100644 --- a/common/viewer.cpp +++ b/common/viewer.cpp @@ -328,8 +328,8 @@ namespace rs2 } else { - ImGui::PushStyleColor(ImGuiCol_Text, grey); - ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, grey); + ImGui::PushStyleColor(ImGuiCol_Text, header_color); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, header_color); } ImGui::SetCursorPos({float(x), float(y)}); @@ -979,52 +979,6 @@ namespace rs2 } } - void viewer_model::show_event_log(ImFont* font_14, float x, float y, float w, float h) - { - auto flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | - ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | - ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysVerticalScrollbar; - - ImGui::PushFont(font_14); - ImGui::SetNextWindowPos({ x, y }); - ImGui::SetNextWindowSize({ w, h }); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); - - is_output_collapsed = ImGui::Begin("Output", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | - ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ShowBorders); - - int i = 0; - not_model->foreach_log([&](const std::string& line) { - ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, light_blue); - ImGui::PushStyleColor(ImGuiCol_Text, light_grey); - - auto rc = ImGui::GetCursorPos(); - ImGui::SetCursorPos({ rc.x + 10, rc.y + 4 }); - - ImGui::PushStyleColor(ImGuiCol_Text, light_grey); - ImGui::Icon(textual_icons::minus); ImGui::SameLine(); - ImGui::PopStyleColor(); - - rc = ImGui::GetCursorPos(); - ImGui::SetCursorPos({ rc.x, rc.y - 4 }); - - std::string label = to_string() << "##log_entry" << i++; - ImGui::InputTextEx(label.c_str(), - (char*)line.data(), - static_cast(line.size() + 1), - ImVec2(-1, ImGui::GetTextLineHeight() * 1.5f * float(std::max(1,(int)std::count(line.begin(),line.end(), '\n')))), - ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_ReadOnly); - ImGui::PopStyleColor(2); - - rc = ImGui::GetCursorPos(); - ImGui::SetCursorPos({ rc.x, rc.y - 6 }); - }); - - ImGui::End(); - ImGui::PopStyleVar(); - ImGui::PopFont(); - } - void rs2::viewer_model::show_popup(const ux_window& window, const popup& p) { auto flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | @@ -1345,6 +1299,9 @@ namespace rs2 last_frames[f.get_profile().unique_id()] = f; } + for(auto&& f : last_frames) + not_model->output.update_dashboards(f.second); + for(auto&& frame : last_frames) { auto f = frame.second; @@ -2464,6 +2421,8 @@ namespace rs2 if (ImGui::BeginPopupModal(settings, nullptr, flags)) { + if (ImGui::IsWindowHovered()) window.set_hovered_over_input(); + ImGui::SetCursorScreenPos({ (float)(x0 + w / 2 - 280), (float)(y0 + 27) }); ImGui::PushStyleColor(ImGuiCol_Button, sensor_bg); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, sensor_bg); @@ -2739,6 +2698,38 @@ namespace rs2 } + ImGui::Separator(); + + { + ImGui::Text("Commands.xml Path:"); + ImGui::SameLine(); + static char logpath[256]; + memset(logpath, 0, 256); + std::string path_str = temp_cfg.get(configurations::viewer::commands_xml); + memcpy(logpath, path_str.c_str(), std::min(255, (int)path_str.size())); + + if (ImGui::InputText("##commands_xml_path", logpath, 255)) + { + path_str = logpath; + temp_cfg.set(configurations::viewer::commands_xml, path_str); + } + } + + { + ImGui::Text("HWLoggerEvents.xml Path:"); + ImGui::SameLine(); + static char logpath[256]; + memset(logpath, 0, 256); + std::string path_str = temp_cfg.get(configurations::viewer::hwlogger_xml); + memcpy(logpath, path_str.c_str(), std::min(255, (int)path_str.size())); + + if (ImGui::InputText("##fw_log_xml_path", logpath, 255)) + { + path_str = logpath; + temp_cfg.set(configurations::viewer::hwlogger_xml, path_str); + } + } + ImGui::Separator(); ImGui::Text("RealSense tools settings capture the state of UI, and not of the hardware:"); @@ -3003,6 +2994,7 @@ namespace rs2 const rect& viewer_rect, bool force) { if (_measurements.manipulating()) return; + if (win.get_hovered_over_input()) return; mouse_info& mouse = win.get_mouse(); auto now = std::chrono::high_resolution_clock::now(); diff --git a/common/viewer.h b/common/viewer.h index c8c392d01b..de10a18dbf 100644 --- a/common/viewer.h +++ b/common/viewer.h @@ -62,9 +62,8 @@ namespace rs2 const float panel_width = 340.f; const float panel_y = 50.f; - const float default_log_h = 110.f; - float get_output_height() const { return (is_output_collapsed ? default_log_h : 15); } + float get_output_height() const { return not_model->output.get_output_height(); } rs2::frame handle_ready_frames(const rect& viewer_rect, ux_window& window, int devices, std::string& error_message); @@ -103,8 +102,6 @@ namespace rs2 void popup_firmware_update_progress(const ux_window& window, const float progress); - void show_event_log(ImFont* font_14, float x, float y, float w, float h); - void render_pose(rs2::rect stream_rect, float buttons_heights); void try_select_pointcloud(ux_window& win); @@ -132,7 +129,6 @@ namespace rs2 context &ctx; std::shared_ptr not_model = std::make_shared(); - bool is_output_collapsed = false; bool is_3d_view = false; bool paused = false; bool metric_system = true; diff --git a/tools/realsense-viewer/realsense-viewer.cpp b/tools/realsense-viewer/realsense-viewer.cpp index 6553d579b7..94fb3bce5f 100644 --- a/tools/realsense-viewer/realsense-viewer.cpp +++ b/tools/realsense-viewer/realsense-viewer.cpp @@ -299,49 +299,18 @@ int main(int argc, const char** argv) try std::vector connected_devs; std::mutex m; -#ifdef BUILD_SHARED_LIBS - // Configure the logger - el::Configurations conf; - conf.set(el::Level::Global, el::ConfigurationType::Format, "[%level] %msg"); - conf.set(el::Level::Info, el::ConfigurationType::Format, "%msg"); - conf.set(el::Level::Debug, el::ConfigurationType::Enabled, "false"); - el::Loggers::reconfigureLogger("default", conf); - // Create a dispatch sink which will get any messages logged to EasyLogging, which will then - // post the messages on the viewer's notification window. - class viewer_model_dispatcher : public el::LogDispatchCallback - { - public: - std::weak_ptr notifications; // only the default ctor is available to us...! - protected: - void handle(const el::LogDispatchData* data) noexcept override - { - // TODO align LRS and Easyloging severity levels. W/A for easylogging on Linux - if (data->logMessage()->level() > el::Level::Debug) - { - if (auto not_model = notifications.lock()) - not_model->add_log( - data->logMessage()->logger()->logBuilder()->build( - data->logMessage(), - data->dispatchAction() == el::base::DispatchAction::NormalLog)); - } - } - }; - el::Helpers::installLogDispatchCallback< viewer_model_dispatcher >("viewer_model_dispatcher"); - auto dispatcher = el::Helpers::logDispatchCallback< viewer_model_dispatcher >("viewer_model_dispatcher"); - dispatcher->notifications = viewer_model.not_model; - el::Helpers::uninstallLogDispatchCallback< el::base::DefaultLogDispatchCallback >("DefaultLogDispatchCallback"); -#else std::weak_ptr notifications = viewer_model.not_model; rs2::log_to_callback( RS2_LOG_SEVERITY_INFO, [notifications]( rs2_log_severity severity, rs2::log_message const& msg ) - { + { if (auto not_model = notifications.lock()) - not_model->add_log( msg.raw() ); - } ); -#endif + { + not_model->output.add_log(severity, msg.filename(), msg.line_number(), msg.raw()); + } + }); + window.on_file_drop = [&](std::string filename) { - add_playback_device(ctx, *device_models, error_message, viewer_model, filename); if (!error_message.empty()) { @@ -638,9 +607,16 @@ int main(int argc, const char** argv) try viewer_model.show_top_bar(window, viewer_rect, *device_models); - viewer_model.show_event_log(window.get_font(), viewer_model.panel_width, - window.height() - (viewer_model.is_output_collapsed ? viewer_model.default_log_h : 20), - window.width() - viewer_model.panel_width, viewer_model.default_log_h); + auto output_rect = rect{ viewer_model.panel_width, + window.height() - viewer_model.get_output_height(), + window.width() - viewer_model.panel_width, viewer_model.get_output_height() }; + + std::vector devices; + for (auto&& dev_model : *device_models) + { + devices.push_back(dev_model->dev); + } + viewer_model.not_model->output.draw(window, output_rect, devices); // Set window position and size ImGui::SetNextWindowPos({ 0, viewer_model.panel_y }); From 8c6d7253bba89cf0c4420bbae1f4dcb14367a682 Mon Sep 17 00:00:00 2001 From: Sergey Dorodnicov Date: Tue, 23 Jun 2020 14:07:35 +0300 Subject: [PATCH 59/61] Fix warnings --- common/output-model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/output-model.cpp b/common/output-model.cpp index 63c120d2b6..13199aa320 100644 --- a/common/output-model.cpp +++ b/common/output-model.cpp @@ -601,7 +601,7 @@ void output_model::draw(ux_window& win, rect view_rect, std::vector for(auto&& dash : dashboards) { auto h = dash->get_height(); - auto r = rect { 0.f, top, 0.3f * w - 2, h }; + auto r = rect { 0.f, (float)top, 0.3f * w - 2, (float)h }; dash->draw(win, r); top += h; } From d325faa95e7155ac537bb95668b2c701d1ad341e Mon Sep 17 00:00:00 2001 From: dorodnic Date: Tue, 23 Jun 2020 17:44:31 +0300 Subject: [PATCH 60/61] Adding CRC calculation to UI module --- common/calibration-model.cpp | 62 +++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/common/calibration-model.cpp b/common/calibration-model.cpp index e48a051637..385cd2b4f3 100644 --- a/common/calibration-model.cpp +++ b/common/calibration-model.cpp @@ -65,6 +65,66 @@ void calibration_model::draw_float4x4(std::string name, librealsense::float3x3& ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5); } +namespace helpers +{ + #define UPDC32(octet, crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8)) + + static const uint32_t crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d + }; + + /// Calculate CRC code for arbitrary characters buffer + uint32_t calc_crc32(const uint8_t *buf, size_t bufsize) + { + uint32_t oldcrc32 = 0xFFFFFFFF; + for (; bufsize; --bufsize, ++buf) + oldcrc32 = UPDC32(*buf, oldcrc32); + return ~oldcrc32; + } +}; + void calibration_model::update(ux_window& window, std::string& error_message) { const auto window_name = "Calibration Window"; @@ -374,7 +434,7 @@ void calibration_model::update(ux_window& window, std::string& error_message) { auto actual_data = _calibration.data() + sizeof(librealsense::ds::table_header); auto actual_data_size = _calibration.size() - sizeof(librealsense::ds::table_header); - auto crc = librealsense::calc_crc32(actual_data, actual_data_size); + auto crc = helpers::calc_crc32(actual_data, actual_data_size); table->header.crc32 = crc; dev.as().set_calibration_table(_calibration); dev.as().write_calibration(); From 7e85829b251ca976b7a5554158e25cc1cd0892ef Mon Sep 17 00:00:00 2001 From: Evgeni Raikhel Date: Wed, 17 Jun 2020 14:28:02 +0300 Subject: [PATCH 61/61] Handle MSVC warnings: casting/unused var/ #ifdefs --- common/fw-update-helper.cpp | 12 ++++---- common/measurement.cpp | 22 +++++++-------- common/measurement.h | 4 +-- common/metadata-helper.cpp | 8 ++++-- common/model-views.cpp | 4 +-- common/notifications.cpp | 24 ++++++++-------- common/on-chip-calib.cpp | 26 +++++++++--------- common/on-chip-calib.h | 2 +- common/rendering.h | 6 ++-- common/viewer.cpp | 2 +- include/librealsense2/hpp/rs_device.hpp | 8 +++--- include/librealsense2/hpp/rs_export.hpp | 2 +- src/ds5/advanced_mode/presets.h | 32 +++++++++++----------- src/ds5/ds5-auto-calibration.cpp | 6 ++-- src/gl/align-gl.cpp | 32 ++++++++++++---------- src/gl/colorizer-gl.cpp | 4 ++- src/gl/pc-shader.cpp | 7 ++--- src/gl/synthetic-stream-gl.cpp | 2 ++ src/gl/upload.cpp | 2 ++ src/l500/l500-depth.cpp | 2 +- src/l500/l500-device.cpp | 8 +++--- src/l500/l500-options.cpp | 10 +++---- src/proc/rates-printer.cpp | 12 ++++---- src/proc/rates-printer.h | 6 ++-- src/proc/sse/sse-pointcloud.cpp | 4 +-- src/proc/synthetic-stream.cpp | 4 +-- tools/convert/converters/converter-bin.hpp | 4 +-- 27 files changed, 132 insertions(+), 123 deletions(-) diff --git a/common/fw-update-helper.cpp b/common/fw-update-helper.cpp index a5b08ac83d..5671f5beb7 100644 --- a/common/fw-update-helper.cpp +++ b/common/fw-update-helper.cpp @@ -196,7 +196,7 @@ namespace rs2 auto flash = upd.create_flash_backup([&](const float progress) { - _progress = ((ceil(progress * 5) / 5) * (30 - next_progress)) + next_progress; + _progress = int((ceil(progress * 5) / 5) * (30 - next_progress)) + next_progress; }); auto temp = get_folder_path(special_folder::app_data); @@ -221,7 +221,7 @@ namespace rs2 if (!check_for([this, serial, &dfu]() { auto devs = _ctx.query_devices(); - for (int j = 0; j < devs.size(); j++) + for (uint32_t j = 0; j < devs.size(); j++) { try { @@ -267,7 +267,7 @@ namespace rs2 dfu.update(_fw, [&](const float progress) { - _progress = (ceil(progress * 10) / 10 * (90 - next_progress)) + next_progress; + _progress = int((ceil(progress * 10) / 10 * (90 - next_progress)) + next_progress); }); log("Firmware Download completed, await DFU transition event"); @@ -279,7 +279,7 @@ namespace rs2 auto upd = _dev.as(); upd.update_unsigned(_fw, [&](const float progress) { - _progress = (ceil(progress * 10) / 10 * (90 - next_progress)) + next_progress; + _progress = int((ceil(progress * 10) / 10 * (90 - next_progress)) + next_progress); }); log("Firmware Update completed, waiting for device to reconnect"); } @@ -287,7 +287,7 @@ namespace rs2 if (!check_for([this, serial, &dfu]() { auto devs = _ctx.query_devices(); - for (int j = 0; j < devs.size(); j++) + for (uint32_t j = 0; j < devs.size(); j++) { try { @@ -341,7 +341,7 @@ namespace rs2 ImGui::SetCursorScreenPos({ float(x + 9), float(y + height - 67) }); - ImGui::PushStyleColor(ImGuiCol_Text, alpha(light_grey, 1. - t)); + ImGui::PushStyleColor(ImGuiCol_Text, alpha(light_grey, 1.f - t)); if (update_state == RS2_FWU_STATE_INITIAL_PROMPT) ImGui::Text("Firmware updates offer critical bug fixes and\nunlock new camera capabilities."); diff --git a/common/measurement.cpp b/common/measurement.cpp index 6c1cfd7724..99d097b4fc 100644 --- a/common/measurement.cpp +++ b/common/measurement.cpp @@ -85,8 +85,8 @@ void measurement::add_point(interest_point p) state.polygons.clear(); } - int last = state.points.size(); - if (current_hovered_point == -1 || + int last = int(state.points.size()); + if (current_hovered_point == -1 || current_hovered_point >= state.points.size()) { state.points.push_back(p); @@ -122,7 +122,7 @@ void measurement::add_point(interest_point p) log_function(to_string() << "Measured distance of " << length_to_string(dist.length())); } - last_hovered_point = state.points.size() - 1; + last_hovered_point = int(state.points.size() - 1); commit_state(); } @@ -186,18 +186,18 @@ void draw_sphere(const float3& pos, float r, int lats, int longs) { for(int i = 0; i <= lats; i++) { - float lat0 = M_PI * (-0.5 + (float) (i - 1) / lats); + float lat0 = float(M_PI) * (-0.5f + (float) (i - 1) / lats); float z0 = sin(lat0); float zr0 = cos(lat0); - float lat1 = M_PI * (-0.5 + (float) i / lats); + float lat1 = float(M_PI) * (-0.5f + (float) i / lats); float z1 = sin(lat1); float zr1 = cos(lat1); glBegin(GL_QUAD_STRIP); for(int j = 0; j <= longs; j++) { - float lng = 2 * M_PI * (float) (j - 1) / longs; + float lng = 2.f * float(M_PI) * (float) (j - 1) / longs; float x = cos(lng); float y = sin(lng); @@ -305,7 +305,7 @@ void measurement::draw_ruler(ux_window& win, float3 from, float3 to, float heigh // calculate center of the ruler line float3 ctr = from + (to - from) / 2; float distance = (to - from).length(); - draw_label(win, ctr, distance, height); + draw_label(win, ctr, distance, int(height)); } } @@ -352,7 +352,7 @@ void measurement::update_input(ux_window& win, const rs2::rect& viewer_rect) if (rect_copy.contains(win.get_mouse().cursor)) { input_ctrl.click = true; - input_ctrl.click_time = glfwGetTime(); + input_ctrl.click_time = float(glfwGetTime()); } } } @@ -478,8 +478,8 @@ void measurement::draw(ux_window& win) const int segments = 50; for (int i = 0; i < segments; i++) { - auto t1 = 2 * M_PI * ((float)i / segments); - auto t2 = 2 * M_PI * ((float)(i+1) / segments); + auto t1 = 2.f * float(M_PI) * ((float)i / segments); + auto t2 = 2.f * float(M_PI) * ((float)(i+1) / segments); float4 xy1 { cosf(t1) * size, sinf(t1) * size, 0.f, 1.f }; xy1 = basis * xy1; xy1 = float4 { _picked.x + xy1.x, _picked.y + xy1.y, _picked.z + xy1.z, 1.f }; @@ -556,7 +556,7 @@ void measurement::draw(ux_window& win) auto area = calculate_area(points); - draw_label(win, mid, area, win.framebuf_height(), true); + draw_label(win, mid, area, int(win.framebuf_height()), true); } for (int i = 0; i < state.edges.size(); i++) diff --git a/common/measurement.h b/common/measurement.h index 2a5e208586..ff1b39130d 100644 --- a/common/measurement.h +++ b/common/measurement.h @@ -96,8 +96,8 @@ namespace rs2 double selection_started = 0.0; float2 down_pos { 0.f, 0.f }; int mouse_wheel = 0; - double click_time = 0.0; - float click_period() { return clamp((glfwGetTime() - click_time) * 10, 0.f, 1.f); } + float click_time = 0.f; + float click_period() { return clamp(float(glfwGetTime() - click_time) * 10, 0.f, 1.f); } }; mouse_control input_ctrl; int id = 0; diff --git a/common/metadata-helper.cpp b/common/metadata-helper.cpp index 1f160ab542..7182b271be 100644 --- a/common/metadata-helper.cpp +++ b/common/metadata-helper.cpp @@ -118,7 +118,7 @@ namespace rs2 &cbSecurityDescriptor, // security descriptor &ftLastWriteTime); // last write time - for (int i = 0; i < cSubKeys; i++) + for (auto i = 0ul; i < cSubKeys; i++) { TCHAR achKey[MAX_KEY_LENGTH]; DWORD cbName = MAX_KEY_LENGTH; @@ -133,7 +133,8 @@ namespace rs2 { std::wstring suffix = achKey; device_id rdid; - if (parse_device_id(std::string(suffix.begin(), suffix.end()), &rdid)) + auto a = std::string(suffix.begin(), suffix.end()); + if (parse_device_id(a, &rdid)) { for (auto&& did : kvp.second) { @@ -223,6 +224,7 @@ namespace rs2 CloseHandle(sei.hProcess); if (exitCode) throw std::runtime_error("Failed to set metadata registry keys!"); + return true; } } else @@ -287,7 +289,7 @@ namespace rs2 rs2::context ctx; auto list = ctx.query_devices(); - for (int i = 0; i < list.size(); i++) + for (uint32_t i = 0; i < list.size(); i++) { try { diff --git a/common/model-views.cpp b/common/model-views.cpp index 680ff56d5c..6b8573b878 100644 --- a/common/model-views.cpp +++ b/common/model-views.cpp @@ -1131,7 +1131,7 @@ namespace rs2 { s->set_option( RS2_OPTION_SENSOR_MODE, resolution_from_width_height( res_values[ui.selected_res_id].first, res_values[ui.selected_res_id].second ) ); } - catch( not_implemented_error const & e ) + catch( not_implemented_error const &) { // Just ignore for now: need to figure out a way to write to playback sensors... } @@ -1240,7 +1240,7 @@ namespace rs2 auto height = res_values[ui.selected_res_id].second; auto res = resolution_from_width_height(width, height); if (res >= RS2_SENSOR_MODE_VGA && res < RS2_SENSOR_MODE_COUNT) - s->set_option(RS2_OPTION_SENSOR_MODE, res); + s->set_option(RS2_OPTION_SENSOR_MODE, float(res)); } } ImGui::PopStyleColor(); diff --git a/common/notifications.cpp b/common/notifications.cpp index 8e0e3a8136..cf0f2d4e52 100644 --- a/common/notifications.cpp +++ b/common/notifications.cpp @@ -135,7 +135,7 @@ namespace rs2 auto a = curr_progress_value / 100.f; ImGui::GetWindowDrawList()->AddRectFilled({ float(pos.x + 3 - i), float(pos.y + 3 - i) }, { float(pos.x + filled_w + i), float(pos.y + 17 + i) }, - ImColor(alpha(light_blue, sqrt(a) * 0.02f)), i); + ImColor(alpha(light_blue, sqrt(a) * 0.02f)), float(i)); } ImGui::GetWindowDrawList()->AddRectFilled({ float(pos.x + 3), float(pos.y + 3) }, @@ -170,9 +170,9 @@ namespace rs2 { ImVec4 c; - ImGui::PushStyleColor(ImGuiCol_Button, saturate(c, 1.3)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, saturate(c, 0.9)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, saturate(c, 1.5)); + ImGui::PushStyleColor(ImGuiCol_Button, saturate(c, 1.3f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, saturate(c, 0.9f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, saturate(c, 1.5f)); ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white); c = alpha(white, 1 - t); ImGui::PushStyleColor(ImGuiCol_Text, c); @@ -198,7 +198,7 @@ namespace rs2 void notification_model::draw_text(const char* msg, int x, int y, int h) { std::string text_name = to_string() << "##notification_text_" << index; - ImGui::PushTextWrapPos(x + width - 100); + ImGui::PushTextWrapPos(x + width - 100.f); ImGui::PushStyleColor(ImGuiCol_FrameBg, transparent); ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, transparent); ImGui::PushStyleColor(ImGuiCol_ScrollbarGrab, transparent); @@ -232,7 +232,7 @@ namespace rs2 { auto title = get_title(); auto lines = static_cast(std::count(title.begin(), title.end(), '\n') + 1); - return (lines + 1) * ImGui::GetTextLineHeight() + 5; + return int((lines + 1) * ImGui::GetTextLineHeight() + 5); } void process_notification_model::draw_pre_effect(int x, int y) @@ -333,8 +333,8 @@ namespace rs2 { if (last_x > 100000) { - last_x = x + 500; - last_y = y; + last_x = x + 500.f; + last_y = float(y); } last_moved = system_clock::now(); animating = true; @@ -345,12 +345,12 @@ namespace rs2 if (s < 1.f) { - x = s * x + (1 - s) * last_x; - y = s * y + (1 - s) * last_y; + x = int(s * x + (1 - s) * last_x); + y = int(s * y + (1 - s) * last_y); } else { - last_x = x; last_y = y; + last_x = float(x); last_y = float(y); animating = false; if (dismissed && !expanded) to_close = true; } @@ -939,7 +939,7 @@ namespace rs2 ImGui::SetCursorScreenPos({ float(x + 10), float(y + 35) }); - ImGui::PushStyleColor(ImGuiCol_Text, alpha(light_grey, 1. - t)); + ImGui::PushStyleColor(ImGuiCol_Text, alpha(light_grey, 1.f - t)); std::string s = to_string() << "Saving 3D view to " << get_file_name(get_manager().get_filename()); diff --git a/common/on-chip-calib.cpp b/common/on-chip-calib.cpp index 63a1c8d192..b97979b97d 100644 --- a/common/on-chip-calib.cpp +++ b/common/on-chip-calib.cpp @@ -320,9 +320,9 @@ namespace rs2 auto calib_dev = _dev.as(); if (tare) - _new_calib = calib_dev.run_tare_calibration(ground_truth, json, [&](const float progress) {_progress = progress;}, 5000); + _new_calib = calib_dev.run_tare_calibration(ground_truth, json, [&](const float progress) {_progress = int(progress);}, 5000); else - _new_calib = calib_dev.run_on_chip_calibration(json, &_health, [&](const float progress) {_progress = progress;}, 5000); + _new_calib = calib_dev.run_on_chip_calibration(json, &_health, [&](const float progress) {_progress = int(progress);}, 5000); } void on_chip_calib_manager::process_flow(std::function cleanup, @@ -393,7 +393,7 @@ namespace rs2 _viewer.is_3d_view = _in_3d_view; - _viewer.ground_truth_r = ground_truth; + _viewer.ground_truth_r = uint32_t(ground_truth); config_file::instance().set(configurations::viewer::ground_truth_r, ground_truth); _viewer.synchronization_enable = _synchronized; @@ -516,7 +516,7 @@ namespace rs2 else ImGui::SetCursorScreenPos({ float(x + 9), float(y + 27) }); - ImGui::PushStyleColor(ImGuiCol_Text, alpha(light_grey, 1. - t)); + ImGui::PushStyleColor(ImGuiCol_Text, alpha(light_grey, 1.f - t)); if (update_state == RS2_CALIB_STATE_INITIAL_PROMPT) { @@ -570,7 +570,7 @@ namespace rs2 ImGui::SetCursorScreenPos({ float(x + 135), float(y + 30) }); std::string id = to_string() << "##avg_step_count_" << index; - ImGui::PushItemWidth(width - 145); + ImGui::PushItemWidth(width - 145.f); ImGui::SliderInt(id.c_str(), &get_manager().average_step_count, 1, 30); ImGui::PopItemWidth(); @@ -586,7 +586,7 @@ namespace rs2 id = to_string() << "##step_count_" << index; - ImGui::PushItemWidth(width - 145); + ImGui::PushItemWidth(width - 145.f); ImGui::SliderInt(id.c_str(), &get_manager().step_count, 1, 30); ImGui::PopItemWidth(); @@ -607,14 +607,14 @@ namespace rs2 std::vector vals_cstr; for (auto&& s : vals) vals_cstr.push_back(s.c_str()); - ImGui::PushItemWidth(width - 145); - ImGui::Combo(id.c_str(), &get_manager().accuracy, vals_cstr.data(), vals.size()); - + ImGui::PushItemWidth(width - 145.f); + ImGui::Combo(id.c_str(), &get_manager().accuracy, vals_cstr.data(), int(vals.size())); + ImGui::SetCursorScreenPos({ float(x + 135), float(y + 35 + ImGui::GetTextLineHeightWithSpacing()) }); ImGui::PopItemWidth(); - draw_intrinsic_extrinsic(x, y + 3 * ImGui::GetTextLineHeightWithSpacing() - 10); + draw_intrinsic_extrinsic(x, y + 3 * int(ImGui::GetTextLineHeightWithSpacing()) - 10); ImGui::SetCursorScreenPos({ float(x + 9), float(y + 52 + 4 * ImGui::GetTextLineHeightWithSpacing()) }); id = to_string() << "Apply High-Accuracy Preset##apply_preset_" << index; @@ -651,7 +651,7 @@ namespace rs2 char buff[MAX_SIZE]; memcpy(buff, gt.c_str(), gt.size() + 1); - ImGui::PushItemWidth(width - 145); + ImGui::PushItemWidth(width - 145.f); if (ImGui::InputText(id.c_str(), buff, std::max((int)gt.size() + 1, 10))) { std::stringstream ss; @@ -704,9 +704,9 @@ namespace rs2 std::vector vals_cstr; for (auto&& s : vals) vals_cstr.push_back(s.c_str()); - ImGui::PushItemWidth(width - 145); + ImGui::PushItemWidth(width - 145.f); - ImGui::Combo(id.c_str(), &get_manager().speed, vals_cstr.data(), vals.size()); + ImGui::Combo(id.c_str(), &get_manager().speed, vals_cstr.data(), int(vals.size())); ImGui::PopItemWidth(); draw_intrinsic_extrinsic(x, y); diff --git a/common/on-chip-calib.h b/common/on-chip-calib.h index 41ab6de8a9..c2e24e27b3 100644 --- a/common/on-chip-calib.h +++ b/common/on-chip-calib.h @@ -49,7 +49,7 @@ namespace rs2 void update_last_used(); - uint32_t ground_truth = 2500; + float ground_truth = 2500; int average_step_count = 20; int step_count = 20; int accuracy = 2; diff --git a/common/rendering.h b/common/rendering.h index 59d5bedad4..2f6493ecb1 100644 --- a/common/rendering.h +++ b/common/rendering.h @@ -1656,7 +1656,7 @@ namespace rs2 inline float single_wave(float x) { auto c = clamp(x, 0.f, 1.f); - return 0.5f * (sinf(2.f * M_PI * c - M_PI_2) + 1.f); + return 0.5f * (sinf(2.f * float(M_PI) * c - float(M_PI_2)) + 1.f); } // convert 3d points into 2d viewport coordinates @@ -1737,8 +1737,8 @@ namespace rs2 p2d.z = clamp(p2d.z, -1.0, 1.0); // viewport coordinates - float x_vp = round((p2d.x + 1.0) / 2.0 * vp[2]) + vp[0]; - float y_vp = round((p2d.y + 1.0) / 2.0 * vp[3]) + vp[1]; + float x_vp = round((p2d.x + 1.f) / 2.f * vp[2]) + vp[0]; + float y_vp = round((p2d.y + 1.f) / 2.f * vp[3]) + vp[1]; float2 p_w; p_w.x = x_vp; diff --git a/common/viewer.cpp b/common/viewer.cpp index 49497171da..a086fe75fd 100644 --- a/common/viewer.cpp +++ b/common/viewer.cpp @@ -611,7 +611,7 @@ namespace rs2 // ------------ Texture Selection -------------- - auto t = single_wave((glfwGetTime() - texture_update_time) * 2.f); + auto t = single_wave(float(glfwGetTime() - texture_update_time) * 2); ImVec4 text_color = light_grey * (1.f - t) + light_blue * t; const auto tex_selection_popup = "Tex Selection"; diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index bab9808827..930cb28c58 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -242,7 +242,7 @@ namespace rs2 void update_unsigned(const std::vector& image, T callback, int update_mode = RS2_UNSIGNED_UPDATE_MODE_UPDATE) const { rs2_error* e = nullptr; - rs2_update_firmware_unsigned_cpp(_dev.get(), image.data(), image.size(), new update_progress_callback(std::move(callback)), update_mode, &e); + rs2_update_firmware_unsigned_cpp(_dev.get(), image.data(), int(image.size()), new update_progress_callback(std::move(callback)), update_mode, &e); error::handle(e); } }; @@ -277,7 +277,7 @@ namespace rs2 void update(const std::vector& fw_image, T callback) const { rs2_error* e = nullptr; - rs2_update_firmware_cpp(_dev.get(), fw_image.data(), fw_image.size(), new update_progress_callback(std::move(callback)), &e); + rs2_update_firmware_cpp(_dev.get(), fw_image.data(), int(fw_image.size()), new update_progress_callback(std::move(callback)), &e); error::handle(e); } }; @@ -353,7 +353,7 @@ namespace rs2 rs2_error* e = nullptr; std::shared_ptr list( - rs2_run_on_chip_calibration_cpp(_dev.get(), json_content.data(), json_content.size(), health, new update_progress_callback(std::move(callback)), timeout_ms, &e), + rs2_run_on_chip_calibration_cpp(_dev.get(), json_content.data(), int(json_content.size()), health, new update_progress_callback(std::move(callback)), timeout_ms, &e), rs2_delete_raw_data); error::handle(e); @@ -434,7 +434,7 @@ namespace rs2 rs2_error* e = nullptr; std::shared_ptr list( - rs2_run_tare_calibration_cpp(_dev.get(), ground_truth_mm, json_content.data(), json_content.size(), new update_progress_callback(std::move(callback)), timeout_ms, &e), + rs2_run_tare_calibration_cpp(_dev.get(), ground_truth_mm, json_content.data(), int(json_content.size()), new update_progress_callback(std::move(callback)), timeout_ms, &e), rs2_delete_raw_data); error::handle(e); diff --git a/include/librealsense2/hpp/rs_export.hpp b/include/librealsense2/hpp/rs_export.hpp index 19eff98110..55f52f0257 100644 --- a/include/librealsense2/hpp/rs_export.hpp +++ b/include/librealsense2/hpp/rs_export.hpp @@ -99,7 +99,7 @@ namespace rs2 if (fabs(verts[i].x) >= min_distance || fabs(verts[i].y) >= min_distance || fabs(verts[i].z) >= min_distance) { - idx_map[i] = new_verts.size(); + idx_map[int(i)] = int(new_verts.size()); new_verts.push_back({ verts[i].x, -1 * verts[i].y, -1 * verts[i].z }); if (use_texcoords) { diff --git a/src/ds5/advanced_mode/presets.h b/src/ds5/advanced_mode/presets.h index eed2cbe062..63d3ae9338 100644 --- a/src/ds5/advanced_mode/presets.h +++ b/src/ds5/advanced_mode/presets.h @@ -6,91 +6,91 @@ namespace librealsense { - typedef struct + typedef struct laser_power_control { float laser_power; bool was_set = false; }laser_power_control; - typedef struct + typedef struct laser_state_control { int laser_state; bool was_set = false; }laser_state_control; - typedef struct + typedef struct exposure_control { float exposure; bool was_set = false; }exposure_control; - typedef struct + typedef struct auto_exposure_control { int auto_exposure; bool was_set = false; }auto_exposure_control; - - typedef struct + + typedef struct gain_control { float gain; bool was_set = false; }gain_control; - typedef struct + typedef struct backlight_compensation_control { int backlight_compensation; bool was_set = false; }backlight_compensation_control; - typedef struct + typedef struct brightness_control { float brightness; bool was_set = false; }brightness_control; - typedef struct + typedef struct contrast_control { float contrast; bool was_set = false; }contrast_control; - typedef struct + typedef struct gamma_control { float gamma; bool was_set = false; }gamma_control; - typedef struct + typedef struct hue_control { float hue; bool was_set = false; }hue_control; - typedef struct + typedef struct saturation_control { float saturation; bool was_set = false; }saturation_control; - typedef struct + typedef struct sharpness_control { float sharpness; bool was_set = false; }sharpness_control; - typedef struct + typedef struct white_balance_control { float white_balance; bool was_set = false; }white_balance_control; - typedef struct + typedef struct auto_white_balance_control { int auto_white_balance; bool was_set = false; }auto_white_balance_control; - typedef struct + typedef struct power_line_frequency_control { int power_line_frequency; bool was_set = false; diff --git a/src/ds5/ds5-auto-calibration.cpp b/src/ds5/ds5-auto-calibration.cpp index de0acd0d5d..9598baf4bf 100644 --- a/src/ds5/ds5-auto-calibration.cpp +++ b/src/ds5/ds5-auto-calibration.cpp @@ -213,7 +213,7 @@ namespace librealsense LOG_WARNING(ex.what()); } if (progress_callback) - progress_callback->on_update_progress(count++ * (2 * speed)); //curently this number does not reflect the actual progress + progress_callback->on_update_progress(count++ * (2.f * speed)); //curently this number does not reflect the actual progress now = std::chrono::high_resolution_clock::now(); @@ -310,7 +310,7 @@ namespace librealsense } if (progress_callback) - progress_callback->on_update_progress(count++ * (2 * speed)); //curently this number does not reflect the actual progress + progress_callback->on_update_progress(count++ * (2.f * speed)); //curently this number does not reflect the actual progress now = std::chrono::high_resolution_clock::now(); @@ -356,7 +356,7 @@ namespace librealsense adv->set_all(old_preset_values); } else - advanced_mode->_preset_opt->set(old_preset); + advanced_mode->_preset_opt->set(static_cast(old_preset)); }); return recover_preset; diff --git a/src/gl/align-gl.cpp b/src/gl/align-gl.cpp index c6c32875ad..32aed31ca4 100644 --- a/src/gl/align-gl.cpp +++ b/src/gl/align-gl.cpp @@ -9,7 +9,9 @@ #include "align-gl.h" #include "option.h" +#ifndef NOMINMAX #define NOMINMAX +#endif // NOMINMAX #include @@ -96,10 +98,10 @@ void build_opengl_projection_for_intrinsics(matrix4& frustum, // These parameters define the final viewport that is rendered into by // the camera. - double L = 0; - double R = img_width; - double B = 0; - double T = img_height; + int L = 0; + int R = img_width; + int B = 0; + int T = img_height; // near and far clipping planes, these only matter for the mapping from // world-space z-coordinate into the depth coordinate for OpenGL @@ -117,21 +119,21 @@ void build_opengl_projection_for_intrinsics(matrix4& frustum, // [-1, 1]. OpenGL then maps coordinates in NDC to the current // viewport matrix4 ortho; - ortho(0,0) = 2.0/(R-L); ortho(0,3) = -(R+L)/(R-L); - ortho(1,1) = 2.0/(T-B); ortho(1,3) = -(T+B)/(T-B); - ortho(2,2) = -2.0/(F-N); ortho(2,3) = -(F+N)/(F-N); - ortho(3,3) = 1.0; - + ortho(0,0) = 2.f/(R-L); ortho(0,3) = float(-(R+L)/(R-L)); + ortho(1,1) = 2.f/(T-B); ortho(1,3) = float(-(T+B)/(T-B)); + ortho(2,2) = -2.f/float(F-N); ortho(2,3) = float(-(F+N)/(F-N)); + ortho(3,3) = 1.f; + // construct a projection matrix, this is identical to the // projection matrix computed for the intrinsicx, except an // additional row is inserted to map the z-coordinate to - // OpenGL. + // OpenGL. matrix4 tproj; - tproj(0,0) = alpha; tproj(0,1) = skew; tproj(0,2) = u0; - tproj(1,1) = beta; tproj(1,2) = v0; - tproj(2,2) = -(N+F); tproj(2,3) = -N*F; - tproj(3,2) = 1.0; - + tproj(0,0) = float(alpha); tproj(0,1) = float(skew); tproj(0,2) = 0.f; + tproj(1,1) = float(beta); tproj(1,2) = float(v0); + tproj(2,2) = float(-(N+F)); tproj(2,3) = float(-N*F); + tproj(3,2) = 1.f; + // resulting OpenGL frustum is the product of the orthographic // mapping to normalized device coordinates and the augmented // camera intrinsic matrix diff --git a/src/gl/colorizer-gl.cpp b/src/gl/colorizer-gl.cpp index 4f571c94e9..cc5892c227 100644 --- a/src/gl/colorizer-gl.cpp +++ b/src/gl/colorizer-gl.cpp @@ -11,7 +11,9 @@ #include "colorizer-gl.h" #include "option.h" +#ifndef NOMINMAX #define NOMINMAX +#endif // NOMINMAX #include @@ -181,7 +183,7 @@ namespace librealsense void colorizer::populate_floating_histogram(float* f, int* hist) { - float total = hist[MAX_DEPTH-1]; + float total = float(hist[MAX_DEPTH-1]); for (int i = 0; i < MAX_DEPTH; i++) f[i] = hist[i] / total; } diff --git a/src/gl/pc-shader.cpp b/src/gl/pc-shader.cpp index 9c7223dff6..219af381f9 100644 --- a/src/gl/pc-shader.cpp +++ b/src/gl/pc-shader.cpp @@ -552,9 +552,9 @@ namespace librealsense ox = (xy.x / wh.x) * 2 - 1; oy = (xy.y / wh.y) * 2 - 1; - auto p = frustum(left/(0.5*wh.x), right/(0.5*wh.x), - bottom/(0.5*wh.y), top/(0.5*wh.y), near_plane, far_plae, - ox * (0.5*wh.x), oy * (0.5*wh.y)); + auto p = frustum(left/(0.5f*wh.x), right/(0.5f*wh.x), + bottom / (0.5f * wh.y), top / (0.5f * wh.y), near_plane, far_plae, + ox * (0.5f * wh.x), oy * (0.5f * wh.y)); auto fbo_width = 3; auto fbo_height = 3; @@ -621,7 +621,6 @@ namespace librealsense if (rgba.a > 0) { std::vector pos_floats(size); - rs2::float2 w_pos; for (int i = 0; i < size; i++) { auto pos = pos_halfs[i]; diff --git a/src/gl/synthetic-stream-gl.cpp b/src/gl/synthetic-stream-gl.cpp index 3b4e9dc7d6..e6442f39b7 100644 --- a/src/gl/synthetic-stream-gl.cpp +++ b/src/gl/synthetic-stream-gl.cpp @@ -8,7 +8,9 @@ #include +#ifndef NOMINMAX #define NOMINMAX +#endif // NOMINMAX #include diff --git a/src/gl/upload.cpp b/src/gl/upload.cpp index c8dcdf53fe..f2b1f16c57 100644 --- a/src/gl/upload.cpp +++ b/src/gl/upload.cpp @@ -12,7 +12,9 @@ #include "option.h" #include "context.h" +#ifndef NOMINMAX #define NOMINMAX +#endif // NOMINMAX #include diff --git a/src/l500/l500-depth.cpp b/src/l500/l500-depth.cpp index efb033a8a1..b5a8ad955f 100644 --- a/src/l500/l500-depth.cpp +++ b/src/l500/l500-depth.cpp @@ -351,7 +351,7 @@ namespace librealsense } } - sensor_mode_option.set(get_resolution_from_width_height(vs->get_width(), vs->get_height())); + sensor_mode_option.set(float(get_resolution_from_width_height(vs->get_width(), vs->get_height()))); } diff --git a/src/l500/l500-device.cpp b/src/l500/l500-device.cpp index 7d9f884cf5..5269fb339b 100644 --- a/src/l500/l500-device.cpp +++ b/src/l500/l500-device.cpp @@ -378,7 +378,7 @@ namespace librealsense { command cmdFES(ivcam2::FES); cmdFES.require_response = false; - cmdFES.param1 = sector_index; + cmdFES.param1 = int(sector_index); cmdFES.param2 = 1; auto res = hwm->send(cmdFES); @@ -390,7 +390,7 @@ namespace librealsense int packet_size = std::min((int)(HW_MONITOR_COMMAND_SIZE - (i % HW_MONITOR_COMMAND_SIZE)), (int)(ivcam2::FLASH_SECTOR_SIZE - i)); command cmdFWB(ivcam2::FWB); cmdFWB.require_response = false; - cmdFWB.param1 = index; + cmdFWB.param1 = int(index); cmdFWB.param2 = packet_size; cmdFWB.data.assign(image.data() + index, image.data() + index + packet_size); res = hwm->send(cmdFWB); @@ -406,7 +406,7 @@ namespace librealsense update_progress_callback_ptr callback, float continue_from, float ratio) { auto first_table_offset = fs.tables.front().offset; - float total_size = fs.app_size + tables_size; + float total_size = float(fs.app_size + tables_size); float app_ratio = fs.app_size / total_size * ratio; float tables_ratio = tables_size / total_size * ratio; @@ -424,7 +424,7 @@ namespace librealsense // update read-write section auto first_table_offset = flash_image_info.read_write_section.tables.front().offset; auto tables_size = flash_image_info.header.read_write_start_address + flash_image_info.header.read_write_size - first_table_offset; - update_section(hwm, merged_image, flash_image_info.read_write_section, tables_size, callback, 0, update_mode == RS2_UNSIGNED_UPDATE_MODE_READ_ONLY ? 0.5 : 1.0); + update_section(hwm, merged_image, flash_image_info.read_write_section, tables_size, callback, 0, update_mode == RS2_UNSIGNED_UPDATE_MODE_READ_ONLY ? 0.5f : 1.f); if (update_mode == RS2_UNSIGNED_UPDATE_MODE_READ_ONLY) { diff --git a/src/l500/l500-options.cpp b/src/l500/l500-options.cpp index 5c726d6ad8..a9b06a7698 100644 --- a/src/l500/l500-options.cpp +++ b/src/l500/l500-options.cpp @@ -13,7 +13,7 @@ namespace librealsense float l500_hw_options::query() const { - return query(_resolution->query()); + return query(int(_resolution->query())); } void l500_hw_options::set(float value) @@ -35,7 +35,7 @@ namespace librealsense auto max = _hw_monitor->send(command{ AMCGET, _type, get_max }); auto step = _hw_monitor->send(command{ AMCGET, _type, get_step }); - auto def = query(_resolution->query()); + auto def = query(int(_resolution->query())); if (min.size() < sizeof(int32_t) || max.size() < sizeof(int32_t) || step.size() < sizeof(int32_t)) { @@ -74,7 +74,7 @@ namespace librealsense } auto val = *(reinterpret_cast((void*)res.data())); - return val; + return float(val); } l500_options::l500_options(std::shared_ptr ctx, const platform::backend_device_group & group) : @@ -89,8 +89,8 @@ namespace librealsense depth_sensor.register_option (RS2_OPTION_VISUAL_PRESET, std::make_shared>(raw_depth_sensor, ivcam2::depth_xu, ivcam2::L500_AMBIENT, "Change the depth ambient light to ambient: 1 for no ambient and 2 for low ambient", - std::map{ { RS2_AMBIENT_LIGHT_NO_AMBIENT, "No Ambient"}, - { RS2_AMBIENT_LIGHT_LOW_AMBIENT, "Low Ambient" }})); + std::map{ { float(RS2_AMBIENT_LIGHT_NO_AMBIENT), "No Ambient"}, + { float(RS2_AMBIENT_LIGHT_LOW_AMBIENT), "Low Ambient" }})); } else { diff --git a/src/proc/rates-printer.cpp b/src/proc/rates-printer.cpp index f8a96e291e..4d03baef5f 100644 --- a/src/proc/rates-printer.cpp +++ b/src/proc/rates-printer.cpp @@ -27,7 +27,7 @@ namespace librealsense { auto period = std::chrono::milliseconds(1000 / _render_rate).count(); auto curr_time = std::chrono::steady_clock::now(); - double diff = std::chrono::duration_cast(curr_time - _last_print_time).count(); + auto diff = std::chrono::duration_cast(curr_time - _last_print_time).count(); if (diff < period) return; @@ -45,11 +45,11 @@ namespace librealsense } } - rates_printer::profile::profile() : _counter(0), _last_frame_number(0), _acctual_fps(0) + rates_printer::profile::profile() : _counter(0), _last_frame_number(0), _actual_fps(0) { } - int rates_printer::profile::last_frame_number() + unsigned long long rates_printer::profile::last_frame_number() { return _last_frame_number; } @@ -61,7 +61,7 @@ namespace librealsense float rates_printer::profile::get_fps() { - return _acctual_fps; + return _actual_fps; } void rates_printer::profile::on_frame_arrival(const rs2::frame& f) @@ -79,8 +79,8 @@ namespace librealsense auto oldest = _time_points[0]; if (_time_points.size() > _stream_profile.fps()) _time_points.erase(_time_points.begin()); - double diff = std::chrono::duration_cast(curr_time - oldest).count() / 1000.0; + auto diff = std::chrono::duration_cast(curr_time - oldest).count() / 1000.f; if (diff > 0) - _acctual_fps = _time_points.size() / diff; + _actual_fps = _time_points.size() / diff; } } diff --git a/src/proc/rates-printer.h b/src/proc/rates-printer.h index 475f0e7f7d..8a680a80d9 100644 --- a/src/proc/rates-printer.h +++ b/src/proc/rates-printer.h @@ -24,12 +24,12 @@ namespace librealsense rs2::stream_profile _stream_profile; int _counter; std::vector _time_points; - int _last_frame_number; - float _acctual_fps; + unsigned long long _last_frame_number; + float _actual_fps; std::chrono::steady_clock::time_point _last_time; public: profile(); - int last_frame_number(); + unsigned long long last_frame_number(); rs2::stream_profile get_stream_profile(); float get_fps(); void on_frame_arrival(const rs2::frame& f); diff --git a/src/proc/sse/sse-pointcloud.cpp b/src/proc/sse/sse-pointcloud.cpp index d881e5e76f..c74a7de247 100644 --- a/src/proc/sse/sse-pointcloud.cpp +++ b/src/proc/sse/sse-pointcloud.cpp @@ -175,8 +175,8 @@ namespace librealsense auto fy = _mm_set_ps1(other_intrinsics.fy); auto ppx = _mm_set_ps1(other_intrinsics.ppx); auto ppy = _mm_set_ps1(other_intrinsics.ppy); - auto w = _mm_set_ps1(other_intrinsics.width); - auto h = _mm_set_ps1(other_intrinsics.height); + auto w = _mm_set_ps1(float(other_intrinsics.width)); + auto h = _mm_set_ps1(float(other_intrinsics.height)); auto mask_inv_brown_conrady = _mm_set_ps1(RS2_DISTORTION_INVERSE_BROWN_CONRADY); auto zero = _mm_set_ps1(0); auto one = _mm_set_ps1(1); diff --git a/src/proc/synthetic-stream.cpp b/src/proc/synthetic-stream.cpp index ab8f80c82b..da5c8621b8 100644 --- a/src/proc/synthetic-stream.cpp +++ b/src/proc/synthetic-stream.cpp @@ -164,7 +164,7 @@ namespace librealsense auto stream_selector = std::make_shared>(RS2_STREAM_ANY, RS2_STREAM_COUNT, 1, RS2_STREAM_ANY, (int*)&_stream_filter.stream, "Stream type"); for (int s = RS2_STREAM_ANY; s < RS2_STREAM_COUNT; s++) { - stream_selector->set_description(s, "Process - " + std::string (rs2_stream_to_string((rs2_stream)s))); + stream_selector->set_description(float(s), "Process - " + std::string (rs2_stream_to_string((rs2_stream)s))); } stream_selector->on_set([this, stream_selector](float val) { @@ -180,7 +180,7 @@ namespace librealsense auto format_selector = std::make_shared>(RS2_FORMAT_ANY, RS2_FORMAT_COUNT, 1, RS2_FORMAT_ANY, (int*)&_stream_filter.format, "Stream format"); for (int f = RS2_FORMAT_ANY; f < RS2_FORMAT_COUNT; f++) { - format_selector->set_description(f, "Process - " + std::string(rs2_format_to_string((rs2_format)f))); + format_selector->set_description(float(f), "Process - " + std::string(rs2_format_to_string((rs2_format)f))); } format_selector->on_set([this, format_selector](float val) { diff --git a/tools/convert/converters/converter-bin.hpp b/tools/convert/converters/converter-bin.hpp index 54f4e4846e..4c0595f23e 100644 --- a/tools/convert/converters/converter-bin.hpp +++ b/tools/convert/converters/converter-bin.hpp @@ -44,8 +44,8 @@ namespace rs2 { shift--; } - f = f - 1.0; - uint32_t mantissa = f * ((1U << 23) + 0.5f); + f = f - 1.f; + uint32_t mantissa = uint32_t(f * ((1U << 23) + 0.5f)); uint32_t exponent = shift + ((1 << 7) - 1); ieee754 = (sign << 31) | (exponent << 23) | mantissa;