diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index b1912789a1..0ac28df07a 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -80,6 +80,23 @@ int rs2_supports_device_info(const rs2_device* device, rs2_camera_info info, rs2 */ void rs2_hardware_reset(const rs2_device * device, rs2_error ** error); +/** +* Build debug_protocol raw data command from opcode, parameters and data. +* The result can be used as raw_data_to_send parameter in send_and_receive_raw_data +* \param[in] device RealSense device to send data to +* \param[in] opcode Commad opcode +* \param[in] param1 First input parameter +* \param[in] param2 Second parameter +* \param[in] param3 Third parameter +* \param[in] param4 Fourth parameter +* \param[in] data Input Data (up to 1024 bytes) +* \param[in] size_of_data Size of input data in bytes +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored +* \return rs2_raw_data_buffer which includes raw command +*/ +const rs2_raw_data_buffer* rs2_build_debug_protocol_command(rs2_device* device, unsigned opcode, unsigned param1, unsigned param2, + unsigned param3, unsigned param4, void* data, unsigned size_of_data, rs2_error** error); + /** * Send raw data to device * \param[in] device RealSense device to send data to diff --git a/include/librealsense2/hpp/rs_device.hpp b/include/librealsense2/hpp/rs_device.hpp index c6dbd641d3..6a27e364fa 100644 --- a/include/librealsense2/hpp/rs_device.hpp +++ b/include/librealsense2/hpp/rs_device.hpp @@ -830,6 +830,32 @@ namespace rs2 error::handle(e); } + std::vector build_command(uint32_t opcode, + uint32_t param1 = 0, + uint32_t param2 = 0, + uint32_t param3 = 0, + uint32_t param4 = 0, + std::vector const & data = {}) const + { + std::vector results; + + rs2_error* e = nullptr; + auto buffer = rs2_build_debug_protocol_command(_dev.get(), opcode, param1, param2, param3, param4, + (void*)data.data(), (uint32_t)data.size(), &e); + std::shared_ptr list(buffer, 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); + error::handle(e); + + results.insert(results.begin(), start, start + size); + + return results; + } + std::vector send_and_receive_raw_data(const std::vector& input) const { std::vector results; @@ -844,6 +870,7 @@ namespace rs2 error::handle(e); auto start = rs2_get_raw_data(list.get(), &e); + error::handle(e); results.insert(results.begin(), start, start + size); diff --git a/src/core/debug.h b/src/core/debug.h index f3060dac46..0a3aa3c50d 100644 --- a/src/core/debug.h +++ b/src/core/debug.h @@ -12,6 +12,14 @@ namespace librealsense { public: virtual std::vector send_receive_raw_data(const std::vector& input) = 0; + virtual std::vector build_command(uint32_t opcode, + uint32_t param1 = 0, + uint32_t param2 = 0, + uint32_t param3 = 0, + uint32_t param4 = 0, + uint8_t const * data = nullptr, + size_t dataLength = 0) const = 0; + }; MAP_EXTENSION(RS2_EXTENSION_DEBUG, librealsense::debug_interface); diff --git a/src/ds5/ds5-device.cpp b/src/ds5/ds5-device.cpp index 062dca68ce..be1c6c0010 100644 --- a/src/ds5/ds5-device.cpp +++ b/src/ds5/ds5-device.cpp @@ -122,6 +122,17 @@ namespace librealsense { return _hw_monitor->send(input); } + + std::vector ds5_device::build_command(uint32_t opcode, + uint32_t param1, + uint32_t param2, + uint32_t param3, + uint32_t param4, + uint8_t const * data, + size_t dataLength) const + { + return _hw_monitor->build_command(opcode, param1, param2, param3, param4, data, dataLength); + } void ds5_device::hardware_reset() { diff --git a/src/ds5/ds5-device.h b/src/ds5/ds5-device.h index 57b341f1c7..044b6a71bd 100644 --- a/src/ds5/ds5-device.h +++ b/src/ds5/ds5-device.h @@ -55,6 +55,14 @@ namespace librealsense std::vector send_receive_raw_data(const std::vector& input) override; + std::vector build_command(uint32_t opcode, + uint32_t param1 = 0, + uint32_t param2 = 0, + uint32_t param3 = 0, + uint32_t param4 = 0, + uint8_t const * data = nullptr, + size_t dataLength = 0) const override; + void hardware_reset() override; void create_snapshot(std::shared_ptr& snapshot) const override; diff --git a/src/hw-monitor.cpp b/src/hw-monitor.cpp index 3478160f46..cd8f4cc323 100644 --- a/src/hw-monitor.cpp +++ b/src/hw-monitor.cpp @@ -174,6 +174,22 @@ namespace librealsense newCommand.receivedCommandData + newCommand.receivedCommandDataLength); } + std::vector hw_monitor::build_command(uint32_t opcode, + uint32_t param1, + uint32_t param2, + uint32_t param3, + uint32_t param4, + uint8_t const * data, + size_t dataLength) const + { + int length; + std::vector result; + result.resize(IVCAM_MONITOR_MAX_BUFFER_SIZE); + fill_usb_buffer(opcode, param1, param2, param3, param4, data, static_cast(dataLength), result.data(), length); + result.resize(length); + return result; + } + std::string hwmon_error_string( command const & cmd, hwmon_response e ) { auto str = hwmon_error2str( e ); diff --git a/src/hw-monitor.h b/src/hw-monitor.h index eb6493c061..a0a63921f4 100644 --- a/src/hw-monitor.h +++ b/src/hw-monitor.h @@ -332,6 +332,14 @@ namespace librealsense std::vector< uint8_t > send( std::vector< uint8_t > const & data ) const; std::vector send( command cmd, hwmon_response * = nullptr, bool locked_transfer = false ) const; + std::vector build_command(uint32_t opcode, + uint32_t param1 = 0, + uint32_t param2 = 0, + uint32_t param3 = 0, + uint32_t param4 = 0, + uint8_t const * data = nullptr, + size_t dataLength = 0) const; + void get_gvd(size_t sz, unsigned char* gvd, uint8_t gvd_cmd) const; static std::string get_firmware_version_string(const std::vector& buff, size_t index, size_t length = 4); static std::string get_module_serial_string(const std::vector& buff, size_t index, size_t length = 6); diff --git a/src/ivcam/sr300.h b/src/ivcam/sr300.h index 0ac054e015..05b2dbad3b 100644 --- a/src/ivcam/sr300.h +++ b/src/ivcam/sr300.h @@ -341,6 +341,18 @@ namespace librealsense return _hw_monitor->send(input); } + + std::vector build_command(uint32_t opcode, + uint32_t param1 = 0, + uint32_t param2 = 0, + uint32_t param3 = 0, + uint32_t param4 = 0, + uint8_t const * data = nullptr, + size_t dataLength = 0) const override + { + return _hw_monitor->build_command(opcode, param1, param2, param3, param4, data, dataLength); + } + void hardware_reset() override { force_hardware_reset(); diff --git a/src/l500/l500-device.cpp b/src/l500/l500-device.cpp index a3df320a6e..7183f69ea7 100644 --- a/src/l500/l500-device.cpp +++ b/src/l500/l500-device.cpp @@ -587,6 +587,16 @@ namespace librealsense return _hw_monitor->send(input); } + std::vector l500_device::build_command(uint32_t opcode, + uint32_t param1, + uint32_t param2, + uint32_t param3, + uint32_t param4, + uint8_t const * data, + size_t dataLength) const + { + return _hw_monitor->build_command(opcode, param1, param2, param3, param4, data, dataLength); + } ivcam2::extended_temperatures l500_device::get_temperatures() const { diff --git a/src/l500/l500-device.h b/src/l500/l500-device.h index 0be0f60a09..6d28eb38ed 100644 --- a/src/l500/l500-device.h +++ b/src/l500/l500-device.h @@ -48,6 +48,13 @@ namespace librealsense } std::vector< uint8_t > send_receive_raw_data(const std::vector< uint8_t > & input) override; + std::vector build_command(uint32_t opcode, + uint32_t param1 = 0, + uint32_t param2 = 0, + uint32_t param3 = 0, + uint32_t param4 = 0, + uint8_t const * data = nullptr, + size_t dataLength = 0) const override; void hardware_reset() override { diff --git a/src/realsense.def b/src/realsense.def index 1874bf376a..88326af84a 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -101,6 +101,7 @@ EXPORTS rs2_set_region_of_interest rs2_get_region_of_interest + rs2_build_debug_protocol_command rs2_send_and_receive_raw_data rs2_get_raw_data_size rs2_delete_raw_data diff --git a/src/rs.cpp b/src/rs.cpp index b343018653..aedfb19b32 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -557,6 +557,19 @@ rs2_stream_profile* rs2_clone_video_stream_profile(const rs2_stream_profile* mod } HANDLE_EXCEPTIONS_AND_RETURN(nullptr, mode, stream, index, format, width, height, intr) +const rs2_raw_data_buffer* rs2_build_debug_protocol_command(rs2_device* device, unsigned opcode, unsigned param1, unsigned param2, + unsigned param3, unsigned param4, void* data, unsigned size_of_data, rs2_error** error) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL(device); + + auto debug_interface = VALIDATE_INTERFACE(device->device, librealsense::debug_interface); + auto ret_data = debug_interface->build_command(opcode, param1, param2, param3, param4, static_cast(data), size_of_data); + + return new rs2_raw_data_buffer{ std::move(ret_data) }; + +} +HANDLE_EXCEPTIONS_AND_RETURN(nullptr, device) + const rs2_raw_data_buffer* rs2_send_and_receive_raw_data(rs2_device* device, void* raw_data_to_send, unsigned size_of_raw_data_to_send, rs2_error** error) BEGIN_API_CALL { VALIDATE_NOT_NULL(device); @@ -566,7 +579,7 @@ const rs2_raw_data_buffer* rs2_send_and_receive_raw_data(rs2_device* device, voi auto raw_data_buffer = static_cast(raw_data_to_send); std::vector buffer_to_send(raw_data_buffer, raw_data_buffer + size_of_raw_data_to_send); auto ret_data = debug_interface->send_receive_raw_data(buffer_to_send); - return new rs2_raw_data_buffer{ ret_data }; + return new rs2_raw_data_buffer{ std::move(ret_data) }; } HANDLE_EXCEPTIONS_AND_RETURN(nullptr, device) diff --git a/unit-tests/debug_protocol/test-build-command.py b/unit-tests/debug_protocol/test-build-command.py new file mode 100644 index 0000000000..9b450f52c2 --- /dev/null +++ b/unit-tests/debug_protocol/test-build-command.py @@ -0,0 +1,88 @@ +import pyrealsense2 as rs +from rspy import devices, log, test, file, repo + + +############################################################################################# +# Help Functions +############################################################################################# + +def convert_bytes_string_to_decimal_list(command): + command_input = [] # array of uint_8t + + # Parsing the command to array of unsigned integers(size should be < 8bits) + # threw out spaces + command = command.lower() + command = command.split() + + for byte in command: + command_input.append(int('0x' + byte, 0)) + + return command_input + + +def send_hardware_monitor_command(device, command): + raw_result = rs.debug_protocol(device).send_and_receive_raw_data(command) + status = raw_result[:4] + result = raw_result[4:] + return status, result + + +############################################################################################# +# Tests +############################################################################################# + +test.start("Init") +try: + ctx = rs.context() + dev = ctx.query_devices()[0] +except: + test.unexpected_exception() +test.finish() + +############################################################################################# + +test.start("Old Scenario Test") +try: + # creating a raw data command + # [msg_length, magic_number, opcode, params, data] + # all values are in hex - little endian + msg_length = "14 00" + magic_number = "ab cd" + gvd_opcode_as_string = "10 00 00 00" # gvd opcode = 0x10 + params_and_data = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" # empty params and data + gvd_command = msg_length + " " + magic_number + " " + gvd_opcode_as_string + " " + params_and_data + raw_command = convert_bytes_string_to_decimal_list(gvd_command) + + status, old_scenario_result = send_hardware_monitor_command(dev, raw_command) + + # expected status in case of success of "send_hardware_monitor_command" is the same as opcode + expected_status = convert_bytes_string_to_decimal_list(gvd_opcode_as_string) + + test.check_equal_lists(status, expected_status) +except: + test.unexpected_exception() +test.finish() + +############################################################################################# + +test.start("New Scenario Test") +try: + gvd_opcode_as_int = 0x10 + gvd_opcode_as_string = "10 00 00 00" # little endian + + raw_command = rs.debug_protocol(dev).build_command(gvd_opcode_as_int) + status, new_scenario_result = send_hardware_monitor_command(dev, raw_command) + + # expected status in case of success of "send_hardware_monitor_command" is the same as opcode + expected_status = convert_bytes_string_to_decimal_list(gvd_opcode_as_string) + + test.check_equal_lists(status, expected_status) + test.check_equal_lists(new_scenario_result, old_scenario_result) +except: + test.unexpected_exception() +test.finish() + + +############################################################################################# + +test.print_results_and_exit() diff --git a/unit-tests/live/hw-errors/l500/l500-error-common.h b/unit-tests/live/hw-errors/l500/l500-error-common.h index bdd0ab3384..661835cb68 100644 --- a/unit-tests/live/hw-errors/l500/l500-error-common.h +++ b/unit-tests/live/hw-errors/l500/l500-error-common.h @@ -35,17 +35,11 @@ std::map< uint8_t, std::pair< std::string, rs2_log_severity > > build_log_errors void trigger_error_or_exit( const rs2::device & dev, uint8_t num ) { - std::vector< uint8_t > raw_data( 24, 0 ); - raw_data[0] = 0x14; - raw_data[2] = 0xab; - raw_data[3] = 0xcd; - raw_data[4] = l500_trigger_error_opcode; - raw_data[12] = num; - if( auto debug = dev.as< debug_protocol >() ) { try { + auto raw_data = debug.build_command(l500_trigger_error_opcode, 0, num); debug.send_and_receive_raw_data( raw_data ); } catch(std::exception const& e) diff --git a/unit-tests/test-fw-update.py b/unit-tests/test-fw-update.py index 3bd8a39503..48d5acc0de 100644 --- a/unit-tests/test-fw-update.py +++ b/unit-tests/test-fw-update.py @@ -7,6 +7,11 @@ #test:device each(D400*) import pyrealsense2 as rs, sys, os, subprocess +import os +import subprocess +import re +import platform +import pyrealsense2 as rs from rspy import devices, log, test, file, repo import re, platform @@ -26,49 +31,43 @@ # needed to verify it is available above... devices.acroname = None -def send_hardware_monitor_command( device, command ): - command_input = [] # array of uint_8t - - # Parsing the command to array of unsigned integers(size should be < 8bits) - # threw out spaces - command = command.lower() - command = command.replace(" ", "") - current_uint8_t_string = '' - for i in range(0, len(command)): - current_uint8_t_string += command[i] - if len(current_uint8_t_string) >= 2: - command_input.append(int('0x' + current_uint8_t_string, 0)) - current_uint8_t_string = '' - if current_uint8_t_string != '': - command_input.append(int('0x' + current_uint8_t_string, 0)) +def send_hardware_monitor_command(device, command): # byte_index = -1 - raw_result = rs.debug_protocol( device ).send_and_receive_raw_data( command_input ) + raw_result = rs.debug_protocol(device).send_and_receive_raw_data(command) return raw_result[4:] -def get_update_counter( device ): - product_line = device.get_info( rs.camera_info.product_line ) - cmd = None + +def get_update_counter(device): + product_line = device.get_info(rs.camera_info.product_line) + opcode = 0x09 + start_index = 0x30 + size = None if product_line == "L500": - cmd = "14 00 AB CD 09 00 00 00 30 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00" + size = 0x1 elif product_line == "D400": - cmd = "14 00 AB CD 09 00 00 00 30 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00" + size = 0x2 else: log.f( "Incompatible product line:", product_line ) - counter = send_hardware_monitor_command( device, cmd ) + raw_cmd = rs.debug_protocol(device).build_command(opcode, start_index, size) + counter = send_hardware_monitor_command(device, raw_cmd) return counter[0] + def reset_update_counter( device ): product_line = device.get_info( rs.camera_info.product_line ) - cmd = None if product_line == "L500": - cmd = "14 00 AB CD 0A 00 00 00 30 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00" + opcode = 0x09 + start_index = 0x30 + size = 0x01 + raw_cmd = rs.debug_protocol(device).build_command(opcode, start_index, size) elif product_line == "D400": - cmd = "14 00 AB CD 86 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + opcode = 0x86 + raw_cmd = rs.debug_protocol(device).build_command(opcode) else: log.f( "Incompatible product line:", product_line ) diff --git a/unit-tests/unit-tests-internal.cpp b/unit-tests/unit-tests-internal.cpp index 23405dd3a5..a7df8fddb4 100644 --- a/unit-tests/unit-tests-internal.cpp +++ b/unit-tests/unit-tests-internal.cpp @@ -1944,14 +1944,12 @@ void metadata_verification(const std::vector& da ////serialize_json void trigger_error(const rs2::device& dev, int num) { - std::vector raw_data(24, 0); - raw_data[0] = 0x14; - raw_data[2] = 0xab; - raw_data[3] = 0xcd; - raw_data[4] = 0x4d; - raw_data[8] = num; + int opcode = 0x4d; if (auto debug = dev.as()) + { + auto& raw_data = debug.build_raw_data(opcode, num) debug.send_and_receive_raw_data(raw_data); + } } diff --git a/unit-tests/unit-tests-live.cpp b/unit-tests/unit-tests-live.cpp index ce4321c918..6a389a3d09 100644 --- a/unit-tests/unit-tests-live.cpp +++ b/unit-tests/unit-tests-live.cpp @@ -2035,14 +2035,12 @@ void metadata_verification(const std::vector& da ////serialize_json void trigger_error(const rs2::device& dev, int num) { - std::vector raw_data(24, 0); - raw_data[0] = 0x14; - raw_data[2] = 0xab; - raw_data[3] = 0xcd; - raw_data[4] = 0x4d; - raw_data[8] = num; + int opcode = 0x4d; if (auto debug = dev.as()) + { + auto raw_data = debug.build_command(opcode, num); debug.send_and_receive_raw_data(raw_data); + } } diff --git a/wrappers/csharp/Intel.RealSense/Devices/DebugDevice.cs b/wrappers/csharp/Intel.RealSense/Devices/DebugDevice.cs index 947a8dd1c3..628f6abc53 100644 --- a/wrappers/csharp/Intel.RealSense/Devices/DebugDevice.cs +++ b/wrappers/csharp/Intel.RealSense/Devices/DebugDevice.cs @@ -30,6 +30,39 @@ public static DebugDevice FromDevice(Device dev) return Device.Create(dev.Handle); } + + public byte[] BuildCommand(UInt32 opcode, UInt32 param1 = 0, UInt32 param2 = 0, UInt32 param3 = 0, + UInt32 param4 = 0, byte[] data = null) + { + IntPtr nativeBytes = IntPtr.Zero; + uint dataLength = 0; + try + { + object error; + if (data != null) { + nativeBytes = Marshal.AllocHGlobal(data.Length); + Marshal.Copy(data, 0, nativeBytes, data.Length); + dataLength = (uint)data.Length; + } + + IntPtr rawDataBuffer = NativeMethods.rs2_build_debug_protocol_command(Handle, opcode, param1, param2, param3, + param4, nativeBytes, dataLength, out error); + + IntPtr start = NativeMethods.rs2_get_raw_data(rawDataBuffer, out error); + int size = NativeMethods.rs2_get_raw_data_size(rawDataBuffer, out error); + + byte[] managedBytes = new byte[size]; + Marshal.Copy(start, managedBytes, 0, size); + NativeMethods.rs2_delete_raw_data(rawDataBuffer); + + return managedBytes; + } + finally + { + Marshal.FreeHGlobal(nativeBytes); + } + } + public byte[] SendReceiveRawData(byte[] command_bytes) { IntPtr nativeBytes = IntPtr.Zero; diff --git a/wrappers/csharp/Intel.RealSense/NativeMethods.cs b/wrappers/csharp/Intel.RealSense/NativeMethods.cs index bf7f5e7190..2364a93ef2 100644 --- a/wrappers/csharp/Intel.RealSense/NativeMethods.cs +++ b/wrappers/csharp/Intel.RealSense/NativeMethods.cs @@ -505,6 +505,9 @@ internal static MemCpyDelegate GetMethod() [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr rs2_send_and_receive_raw_data(IntPtr device, IntPtr raw_data_to_send, uint size_of_raw_data_to_send, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ErrorMarshaler))] out object error); + [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr rs2_build_debug_protocol_command(IntPtr device, uint opdoce, uint param1, uint param2, uint param3, uint param4, IntPtr raw_data_to_send, uint size_of_raw_data_to_send, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ErrorMarshaler))] out object error); + [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] internal static extern int rs2_is_device_extendable_to(IntPtr device, Extension extension, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ErrorMarshaler))] out object error); @@ -700,11 +703,11 @@ internal static MemCpyDelegate GetMethod() internal static extern IntPtr rs2_run_tare_calibration(IntPtr dev, float ground_truth_mm, [MarshalAs(UnmanagedType.LPStr)] string json_content, int content_size, [MarshalAs(UnmanagedType.FunctionPtr)] rs2_update_progress_callback callback, IntPtr client_data, int timeout_ms, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ErrorMarshaler))] out object error); [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] - internal static extern IntPtr rs2_run_focal_length_calibration(IntPtr dev, IntPtr left_queue, IntPtr right_queue, float target_width_mm, float target_height_mm, int adjust_both_sides, out float ratio, out float angle, + internal static extern IntPtr rs2_run_focal_length_calibration(IntPtr dev, IntPtr left_queue, IntPtr right_queue, float target_width_mm, float target_height_mm, int adjust_both_sides, out float ratio, out float angle, [MarshalAs(UnmanagedType.FunctionPtr)] rs2_update_progress_callback callback, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ErrorMarshaler))] out object error); [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] - internal static extern IntPtr rs2_run_uv_map_calibration(IntPtr dev, IntPtr left_queue, IntPtr rgb_queue, IntPtr depth_queue, int px_py_only, out float ratio, out float angle, + internal static extern IntPtr rs2_run_uv_map_calibration(IntPtr dev, IntPtr left_queue, IntPtr rgb_queue, IntPtr depth_queue, int px_py_only, out float ratio, out float angle, [MarshalAs(UnmanagedType.FunctionPtr)] rs2_update_progress_callback callback, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ErrorMarshaler))] out object error); [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] diff --git a/wrappers/python/pyrs_device.cpp b/wrappers/python/pyrs_device.cpp index a8dd90366a..9dae62b0c7 100644 --- a/wrappers/python/pyrs_device.cpp +++ b/wrappers/python/pyrs_device.cpp @@ -226,8 +226,10 @@ void init_device(py::module &m) { py::class_ debug_protocol(m, "debug_protocol"); // No docstring in C++ debug_protocol.def(py::init()) + .def("build_command", &rs2::debug_protocol::build_command, "opcode"_a, "param1"_a = 0, + "param2"_a = 0, "param3"_a = 0, "param4"_a = 0, "data"_a = std::vector()) .def("send_and_receive_raw_data", &rs2::debug_protocol::send_and_receive_raw_data, - "input"_a); // No docstring in C++ + "input"_a); // No docstring in C++ py::class_ device_list(m, "device_list"); // No docstring in C++ device_list.def(py::init<>())