diff --git a/include/librealsense2/h/rs_internal.h b/include/librealsense2/h/rs_internal.h index 3807d6b69b..f779c1dc9c 100644 --- a/include/librealsense2/h/rs_internal.h +++ b/include/librealsense2/h/rs_internal.h @@ -448,6 +448,13 @@ void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_pa */ 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); +/** +* \brief Returns number of fw logs already polled from device but not by user yet +* \param[in] dev Device from which the FW log will be taken +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. +* \return number of fw logs already polled from device but not by user yet +*/ +unsigned int rs2_get_number_of_fw_logs(rs2_device* dev, rs2_error** error); /** * \brief Gets RealSense firmware log parsed message. * \param[in] fw_log_parsed_msg firmware log parsed message object @@ -496,6 +503,14 @@ unsigned int rs2_get_fw_log_parsed_line(rs2_firmware_log_parsed_message* fw_log_ */ unsigned int rs2_get_fw_log_parsed_timestamp(rs2_firmware_log_parsed_message* fw_log_parsed_msg, rs2_error** error); +/** +* \brief Gets RealSense firmware log parsed message sequence id - cyclic number of FW log with [0..15] range +* \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 sequence of the firmware log parsed message +*/ +unsigned int rs2_get_fw_log_parsed_sequence_id(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 diff --git a/include/librealsense2/hpp/rs_internal.hpp b/include/librealsense2/hpp/rs_internal.hpp index 5fbd6ba7b0..e0cb79f043 100644 --- a/include/librealsense2/hpp/rs_internal.hpp +++ b/include/librealsense2/hpp/rs_internal.hpp @@ -465,6 +465,14 @@ namespace rs2 return timestamp; } + uint32_t sequence_id() const + { + rs2_error* e = nullptr; + uint32_t sequence(rs2_get_fw_log_parsed_sequence_id(_parsed_fw_log.get(), &e)); + error::handle(e); + return sequence; + } + const std::shared_ptr get_message() const { return _parsed_fw_log; } private: @@ -550,6 +558,15 @@ namespace rs2 return parsingResult; } + + unsigned int get_number_of_fw_logs() const + { + rs2_error* e = nullptr; + unsigned int num_of_fw_logs = rs2_get_number_of_fw_logs(_dev.get(), &e); + error::handle(e); + + return num_of_fw_logs; + } }; class terminal_parser diff --git a/src/android/jni/fw_logger.cpp b/src/android/jni/fw_logger.cpp index 08d9054408..eda1af3965 100644 --- a/src/android/jni/fw_logger.cpp +++ b/src/android/jni/fw_logger.cpp @@ -45,6 +45,17 @@ Java_com_intel_realsense_librealsense_FwLogger_nGetFlashLog(JNIEnv *env, jobject return (jlong)log_msg; } +extern "C" +JNIEXPORT jlong JNICALL +Java_com_intel_realsense_librealsense_FwLogger_nGetNumberOfFwLogs(JNIEnv *env, jobject instance, + jlong fw_logger_handle) { + rs2_error* e = NULL; + unsigned int numOfFwLogsPolledFromDevice = rs2_get_number_of_fw_logs(reinterpret_cast(fw_logger_handle), &e); + handle_error(env, e); + + return (jlong)(unsigned long long)numOfFwLogsPolledFromDevice; +} + extern "C" JNIEXPORT jboolean JNICALL Java_com_intel_realsense_librealsense_FwLogger_nInitParser(JNIEnv *env, jclass clazz, @@ -199,3 +210,11 @@ Java_com_intel_realsense_librealsense_FwLogParsedMsg_nGetTimestamp(JNIEnv *env, return (jlong)(unsigned long long)timestamp; } +extern "C" JNIEXPORT jint JNICALL +Java_com_intel_realsense_librealsense_FwLogParsedMsg_nGetSequenceId(JNIEnv *env, jclass clazz, jlong handle) { + rs2_error* e = NULL; + unsigned int sequence = rs2_get_fw_log_parsed_sequence_id(reinterpret_cast(handle), &e); + handle_error(env, e); + return (jint)sequence; +} + diff --git a/src/firmware_logger_device.cpp b/src/firmware_logger_device.cpp index dafc039acb..504b456408 100644 --- a/src/firmware_logger_device.cpp +++ b/src/firmware_logger_device.cpp @@ -38,6 +38,10 @@ namespace librealsense return result; } + unsigned int firmware_logger_device::get_number_of_fw_logs() const + { + return _fw_logs.size(); + } void firmware_logger_device::get_fw_logs_from_hw_monitor() { diff --git a/src/firmware_logger_device.h b/src/firmware_logger_device.h index 631f54c098..e6ebe01362 100644 --- a/src/firmware_logger_device.h +++ b/src/firmware_logger_device.h @@ -16,6 +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 unsigned int get_number_of_fw_logs() const = 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,6 +32,8 @@ 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; + + unsigned int get_number_of_fw_logs() const 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; diff --git a/src/fw-logs/fw-log-data.cpp b/src/fw-logs/fw-log-data.cpp index 60560d5abc..5f609fd4dc 100644 --- a/src/fw-logs/fw-log-data.cpp +++ b/src/fw-logs/fw-log-data.cpp @@ -69,6 +69,11 @@ namespace librealsense return _timestamp; } + uint32_t fw_log_data::get_sequence_id() const + { + return _sequence; + } + rs2_log_severity fw_logs_binary_data::get_severity() const { const fw_log_binary* log_binary = reinterpret_cast(logs_buffer.data()); diff --git a/src/fw-logs/fw-log-data.h b/src/fw-logs/fw-log-data.h index 62774dc68c..5db0733c43 100644 --- a/src/fw-logs/fw-log-data.h +++ b/src/fw-logs/fw-log-data.h @@ -102,6 +102,7 @@ namespace librealsense const std::string& get_thread_name() const; uint32_t get_line() const; uint32_t get_timestamp() const; + uint32_t get_sequence_id() const; }; } } diff --git a/src/realsense.def b/src/realsense.def index 1dce1a8a6b..253328db9a 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -373,6 +373,7 @@ EXPORTS rs2_create_fw_log_message rs2_delete_fw_log_message + rs2_get_number_of_fw_logs rs2_get_fw_log rs2_get_flash_log rs2_fw_log_message_severity @@ -389,6 +390,7 @@ EXPORTS rs2_get_fw_log_parsed_severity rs2_get_fw_log_parsed_line rs2_get_fw_log_parsed_timestamp + rs2_get_fw_log_parsed_sequence_id rs2_create_terminal_parser rs2_delete_terminal_parser diff --git a/src/rs.cpp b/src/rs.cpp index d2e5a7d15c..b26c74c320 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -3143,7 +3143,7 @@ HANDLE_EXCEPTIONS_AND_RETURN(, dev, json_content, content_size) 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); + auto fw_logger = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); return new rs2_firmware_log_message{ std::make_shared () }; } @@ -3153,10 +3153,10 @@ int rs2_get_fw_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_er { VALIDATE_NOT_NULL(dev); VALIDATE_NOT_NULL(fw_log_msg); - auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + auto fw_logger = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); fw_logs::fw_logs_binary_data binary_data; - bool result = fw_loggerable->get_fw_log(binary_data); + bool result = fw_logger->get_fw_log(binary_data); if (result) { *(fw_log_msg->firmware_log_binary_data).get() = binary_data; @@ -3169,10 +3169,10 @@ int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2 { VALIDATE_NOT_NULL(dev); VALIDATE_NOT_NULL(fw_log_msg); - auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + auto fw_logger = 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); + bool result = fw_logger->get_flash_log(binary_data); if (result) { *(fw_log_msg->firmware_log_binary_data).get() = binary_data; @@ -3218,9 +3218,9 @@ int rs2_init_fw_log_parser(rs2_device* dev, const char* xml_content,rs2_error** { VALIDATE_NOT_NULL(xml_content); - auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + auto fw_logger = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); - return (fw_loggerable->init_parser(xml_content)) ? 1 : 0; + return (fw_logger->init_parser(xml_content)) ? 1 : 0; } HANDLE_EXCEPTIONS_AND_RETURN(0, xml_content) @@ -3228,7 +3228,7 @@ rs2_firmware_log_parsed_message* rs2_create_fw_log_parsed_message(rs2_device* de { VALIDATE_NOT_NULL(dev); - auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + auto fw_logger = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); return new rs2_firmware_log_parsed_message{ std::make_shared () }; } @@ -3240,15 +3240,24 @@ int rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg VALIDATE_NOT_NULL(fw_log_msg); VALIDATE_NOT_NULL(parsed_msg); - auto fw_loggerable = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + auto fw_logger = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); - bool parsing_result = fw_loggerable->parse_log(fw_log_msg->firmware_log_binary_data.get(), + bool parsing_result = fw_logger->parse_log(fw_log_msg->firmware_log_binary_data.get(), parsed_msg->firmware_log_parsed.get()); return parsing_result ? 1 : 0; } HANDLE_EXCEPTIONS_AND_RETURN(0, dev, fw_log_msg) +unsigned int rs2_get_number_of_fw_logs(rs2_device* dev, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(dev); + + auto fw_logger = VALIDATE_INTERFACE(dev->device, librealsense::firmware_logger_extensions); + return fw_logger->get_number_of_fw_logs(); +} +HANDLE_EXCEPTIONS_AND_RETURN(0, dev) + 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); @@ -3298,6 +3307,12 @@ unsigned int rs2_get_fw_log_parsed_timestamp(rs2_firmware_log_parsed_message* fw } HANDLE_EXCEPTIONS_AND_RETURN(0, fw_log_parsed_msg) +unsigned int rs2_get_fw_log_parsed_sequence_id(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_sequence_id(); +} +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/tools/fw-logger/readme.md b/tools/fw-logger/readme.md index 1e3eb55e5c..b48496a266 100644 --- a/tools/fw-logger/readme.md +++ b/tools/fw-logger/readme.md @@ -6,9 +6,10 @@ If you are suspecting that you have an issue that is related to the camera’s f 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| -|---|---|---| +|Flag |Description |Default| Range| +|---|---|---|---| |`-l `|xml file ful path, used to parse the logs|| +|`-p `|logs polling interval (in milliseconds)| 100 | 25-300| |`-f`|collect flash logs instead of firmware logs|| ## Usage diff --git a/tools/fw-logger/rs-fw-logger.cpp b/tools/fw-logger/rs-fw-logger.cpp index aba0bb9a2e..bed38d9a8f 100644 --- a/tools/fw-logger/rs-fw-logger.cpp +++ b/tools/fw-logger/rs-fw-logger.cpp @@ -46,10 +46,13 @@ string datetime_string() int main(int argc, char* argv[]) { + int default_polling_interval_ms = 100; 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"); + ValueArg polling_interval_arg("p", "polling_interval", "Time Interval between each log messages polling (in milliseconds)", false, default_polling_interval_ms, ""); SwitchArg flash_logs_arg("f", "flash", "Flash Logs Request", false); cmd.add(xml_arg); + cmd.add(polling_interval_arg); cmd.add(flash_logs_arg); cmd.parse(argc, argv); @@ -57,6 +60,12 @@ int main(int argc, char* argv[]) auto use_xml_file = false; auto xml_full_file_path = xml_arg.getValue(); + auto polling_interval_ms = polling_interval_arg.getValue(); + if (polling_interval_ms < 25 || polling_interval_ms > 300) + { + std::cout << "Polling interval time provided: " << polling_interval_ms << "ms, is not in the valid range [25,300]. Default value " << default_polling_interval_ms << "ms is used." << std::endl; + polling_interval_ms = default_polling_interval_ms; + } bool are_flash_logs_requested = flash_logs_arg.isSet(); @@ -91,6 +100,7 @@ int main(int argc, char* argv[]) } bool are_there_remaining_flash_logs_to_pull = true; + auto time_of_previous_polling_ms = std::chrono::high_resolution_clock::now(); while (hub.is_connected(dev)) { @@ -118,10 +128,11 @@ int main(int argc, char* argv[]) bool parsing_result = fw_log_device.parse_log(log_message, parsed_log); stringstream sstr; - sstr << datetime_string() << " " << parsed_log.timestamp() << " " << parsed_log.severity() << " " << parsed_log.message() - << " " << parsed_log.thread_name() << " " << parsed_log.file_name() - << " " << parsed_log.line(); - + sstr << datetime_string() << " " << parsed_log.timestamp() << " " << parsed_log.sequence_id() + << " " << parsed_log.severity() << " " << parsed_log.thread_name() + << " " << parsed_log.file_name() << " " << parsed_log.line() + << " " << parsed_log.message(); + fw_log_lines.push_back(sstr.str()); } else @@ -136,7 +147,7 @@ int main(int argc, char* argv[]) fw_log_lines.push_back(sstr.str()); } for (auto& line : fw_log_lines) - cout << line << endl; + cout << line << endl; } else { @@ -145,6 +156,17 @@ int main(int argc, char* argv[]) are_there_remaining_flash_logs_to_pull = false; } } + auto num_of_messages = fw_log_device.get_number_of_fw_logs(); + if (num_of_messages == 0) + { + auto current_time = std::chrono::high_resolution_clock::now(); + auto time_since_previous_polling_ms = std::chrono::duration_cast(current_time - time_of_previous_polling_ms).count(); + if (time_since_previous_polling_ms < polling_interval_ms) + { + std::this_thread::sleep_for(chrono::milliseconds(polling_interval_ms - time_since_previous_polling_ms)); + } + time_of_previous_polling_ms = std::chrono::high_resolution_clock::now(); + } } } catch (const error & e) diff --git a/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/FwLogParsedMsg.java b/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/FwLogParsedMsg.java index 39226d81f0..06d76a49b5 100644 --- a/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/FwLogParsedMsg.java +++ b/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/FwLogParsedMsg.java @@ -17,6 +17,7 @@ public void close() { public String getSeverity() {return nGetSeverity(mHandle);} public int getLine() {return nGetLine(mHandle);} public long getTimestamp(){return nGetTimestamp(mHandle);} + public int getSequenceId() {return nGetSequenceId(mHandle);} private native static void nRelease(long handle); @@ -26,4 +27,5 @@ public void close() { private native static String nGetSeverity(long handle); private native static int nGetLine(long handle); private native static long nGetTimestamp(long handle); + private native static int nGetSequenceId(long handle); } diff --git a/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/FwLogger.java b/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/FwLogger.java index 693bdff7db..0e06b0fff6 100644 --- a/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/FwLogger.java +++ b/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/FwLogger.java @@ -44,6 +44,10 @@ public FwLogMsg getFwLogsFromFlash() { return new FwLogMsg(nGetFlashLog(mHandle)); } + public long getNumberOfUnreadFWLogs() { + return nGetNumberOfFwLogs(mHandle); + } + public boolean getFwLogPullingStatus() { return mFwLogPullingStatus; } public FwLogParsedMsg parseFwLog(FwLogMsg msg) { @@ -53,6 +57,7 @@ public FwLogParsedMsg parseFwLog(FwLogMsg msg) { private native long nGetFwLog(long handle); private native long nGetFlashLog(long handle); + private native long nGetNumberOfFwLogs(long handle); private static native boolean nInitParser(long handle, String xml_content); private static native long nParseFwLog(long handle, long fw_log_msg_handle); } diff --git a/wrappers/csharp/Intel.RealSense/Devices/FirmwareLogsDevice.cs b/wrappers/csharp/Intel.RealSense/Devices/FirmwareLogsDevice.cs index 7a8fcdafd2..6049512f89 100644 --- a/wrappers/csharp/Intel.RealSense/Devices/FirmwareLogsDevice.cs +++ b/wrappers/csharp/Intel.RealSense/Devices/FirmwareLogsDevice.cs @@ -42,6 +42,12 @@ public FwParsedLog CreateFwParsedLog() return FwParsedLog.Create(NativeMethods.rs2_create_fw_log_parsed_message(Handle, out error)); } + public uint GetNumberOfFwLogs() + { + object error; + return NativeMethods.rs2_get_number_of_fw_logs(Handle, out error); + } + public bool GetFwLog(ref FwLog fwLog) { object error; diff --git a/wrappers/csharp/Intel.RealSense/NativeMethods.cs b/wrappers/csharp/Intel.RealSense/NativeMethods.cs index d053efbe1a..a35be66cf0 100644 --- a/wrappers/csharp/Intel.RealSense/NativeMethods.cs +++ b/wrappers/csharp/Intel.RealSense/NativeMethods.cs @@ -738,6 +738,9 @@ internal static MemCpyDelegate GetMethod() [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] internal static extern void rs2_delete_fw_log_message(IntPtr fw_log); + [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint rs2_get_number_of_fw_logs(IntPtr device, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ErrorMarshaler))] out object error); + [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] internal static extern int rs2_get_fw_log(IntPtr device, IntPtr fw_log_, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ErrorMarshaler))] out object error); @@ -785,6 +788,10 @@ internal static MemCpyDelegate GetMethod() [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] internal static extern uint rs2_get_fw_log_parsed_timestamp(IntPtr fw_parsed_log, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ErrorMarshaler))] out object error); + + [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern uint rs2_get_fw_log_parsed_sequence_id(IntPtr fw_parsed_log, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ErrorMarshaler))] out object error); + #endregion #region terminal_parser [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] diff --git a/wrappers/csharp/Intel.RealSense/Types/FwParsedLog.cs b/wrappers/csharp/Intel.RealSense/Types/FwParsedLog.cs index 7be09c0593..d5eb1519ea 100644 --- a/wrappers/csharp/Intel.RealSense/Types/FwParsedLog.cs +++ b/wrappers/csharp/Intel.RealSense/Types/FwParsedLog.cs @@ -57,6 +57,11 @@ public uint GetTimestamp() return NativeMethods.rs2_get_fw_log_parsed_timestamp(Handle, out error); } + public uint GetSequenceId() + { + object error; + return NativeMethods.rs2_get_fw_log_parsed_sequence_id(Handle, out error); + } } } diff --git a/wrappers/python/pyrs_internal.cpp b/wrappers/python/pyrs_internal.cpp index f62b6b756a..7b584e2095 100644 --- a/wrappers/python/pyrs_internal.cpp +++ b/wrappers/python/pyrs_internal.cpp @@ -168,13 +168,15 @@ void init_internal(py::module &m) { .def("get_thread_name", &rs2::firmware_log_parsed_message::thread_name, "Get thread name ") .def("get_severity", &rs2::firmware_log_parsed_message::severity, "Get severity ") .def("get_line", &rs2::firmware_log_parsed_message::line, "Get line ") - .def("get_timestamp", &rs2::firmware_log_parsed_message::timestamp, "Get timestamp "); + .def("get_timestamp", &rs2::firmware_log_parsed_message::timestamp, "Get timestamp ") + .def("get_sequence_id", &rs2::firmware_log_parsed_message::sequence_id, "Get sequence id"); // rs2::firmware_logger py::class_ firmware_logger(m, "firmware_logger"); firmware_logger.def(py::init(), "device"_a) .def("create_message", &rs2::firmware_logger::create_message, "Create FW Log") .def("create_parsed_message", &rs2::firmware_logger::create_parsed_message, "Create FW Parsed Log") + .def("get_number_of_fw_logs", &rs2::firmware_logger::get_number_of_fw_logs, "Get Number of Fw Logs Polled From Device") .def("get_firmware_log", &rs2::firmware_logger::get_firmware_log, "Get FW Log", "msg"_a) .def("get_flash_log", &rs2::firmware_logger::get_flash_log, "Get Flash Log", "msg"_a) .def("init_parser", &rs2::firmware_logger::init_parser, "Initialize Parser with content of xml file",