Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/librealsense2/h/rs_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ 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);

/**
* Check if a camera is in recovery mode
* \param[in] device The RealSense device to check
* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored*/
int rs2_is_in_recovery_mode(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
Expand Down
11 changes: 11 additions & 0 deletions include/librealsense2/hpp/rs_device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ namespace rs2
error::handle(e);
}

/**
* Find if a camera is in recovery mode
*/
bool is_in_recovery_mode()
{
rs2_error* e = nullptr;
auto result = rs2_is_in_recovery_mode(_dev.get(), &e);
error::handle(e);
return result;
}

device& operator=(const std::shared_ptr<rs2_device> dev)
{
_dev.reset();
Expand Down
2 changes: 2 additions & 0 deletions src/core/device-interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class device_interface

virtual bool is_valid() const = 0;

virtual bool is_in_recovery_mode() const = 0;

virtual std::vector< tagged_profile > get_profiles_tags() const = 0;

using stream_profiles = std::vector< std::shared_ptr< stream_profile_interface > >;
Expand Down
5 changes: 5 additions & 0 deletions src/dds/rs-dds-device-proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,11 @@ void dds_device_proxy::hardware_reset()
_dds_dev->send_control( control, &reply );
}

bool dds_device_proxy::is_in_recovery_mode() const
{
return _dds_dev->device_info().is_recovery();
}

std::string dds_device_proxy::get_opcode_string(int opcode) const
{
std::string product_line = get_info(RS2_CAMERA_INFO_PRODUCT_LINE);
Expand Down
2 changes: 2 additions & 0 deletions src/dds/rs-dds-device-proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class dds_device_proxy

void hardware_reset() override;

bool is_in_recovery_mode() const override;

// calibration_change_device
public:
void register_calibration_change_callback( rs2_calibration_change_callback_sptr callback ) override
Expand Down
2 changes: 2 additions & 0 deletions src/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class device

bool is_valid() const override { return *_is_alive; }

bool is_in_recovery_mode() const override { return false; }

void tag_profiles(stream_profiles profiles) const override;

virtual bool compress_while_record() const override { return true; }
Expand Down
5 changes: 5 additions & 0 deletions src/fw-update/fw-update-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,11 @@ namespace librealsense
return true;
}

bool update_device::is_in_recovery_mode() const
{
return true;
}

std::vector<tagged_profile> update_device::get_profiles_tags() const
{
return std::vector<tagged_profile>();
Expand Down
2 changes: 2 additions & 0 deletions src/fw-update/fw-update-device.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ namespace librealsense

virtual bool is_valid() const override;

virtual bool is_in_recovery_mode() const override;

virtual std::vector<tagged_profile> get_profiles_tags() const override;

virtual void tag_profiles(stream_profiles profiles) const override;
Expand Down
5 changes: 5 additions & 0 deletions src/media/playback/playback_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,11 @@ bool playback_device::is_valid() const
return true;
}

bool playback_device::is_in_recovery_mode() const
{
return false;
}

void playback_device::update_time_base(device_serializer::nanoseconds base_timestamp)
{
m_base_sys_time = std::chrono::high_resolution_clock::now();
Expand Down
1 change: 1 addition & 0 deletions src/media/playback/playback_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ namespace librealsense
std::pair<uint32_t, rs2_extrinsics> get_extrinsics(const stream_interface& stream) const override;
static bool try_extend_snapshot(std::shared_ptr<extension_snapshot>& e, rs2_extension extension_type, void** ext);
bool is_valid() const override;
bool is_in_recovery_mode() const override;

std::vector<tagged_profile> get_profiles_tags() const override { return std::vector<tagged_profile>(); };//no hard-coded default streams for playback
void tag_profiles(stream_profiles profiles) const override
Expand Down
5 changes: 5 additions & 0 deletions src/media/record/record_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,3 +465,8 @@ bool record_device::is_valid() const
{
return m_device->is_valid();
}

bool record_device::is_in_recovery_mode() const
{
return m_device->is_in_recovery_mode();
}
1 change: 1 addition & 0 deletions src/media/record/record_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ namespace librealsense
std::shared_ptr< const device_info > get_device_info() const override;
std::pair<uint32_t, rs2_extrinsics> get_extrinsics(const stream_interface& stream) const override;
bool is_valid() const override;
bool is_in_recovery_mode() const override;

std::vector<tagged_profile> get_profiles_tags() const override { return m_device->get_profiles_tags(); };
void tag_profiles(stream_profiles profiles) const override { m_device->tag_profiles(profiles); }
Expand Down
1 change: 1 addition & 0 deletions src/realsense.def
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ EXPORTS
rs2_start_cpp
rs2_stop
rs2_hardware_reset
rs2_is_in_recovery_mode

rs2_set_notifications_callback
rs2_set_notifications_callback_cpp
Expand Down
8 changes: 8 additions & 0 deletions src/rs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1748,6 +1748,14 @@ void rs2_hardware_reset(const rs2_device* device, rs2_error** error) BEGIN_API_C
}
HANDLE_EXCEPTIONS_AND_RETURN(, device)

int rs2_is_in_recovery_mode(const rs2_device* device, rs2_error** error) BEGIN_API_CALL
{
VALIDATE_NOT_NULL(device);
VALIDATE_NOT_NULL(device->device);
return device->device->is_in_recovery_mode();
}
HANDLE_EXCEPTIONS_AND_RETURN(0, device)

// Verify and provide API version encoded as integer value
int rs2_get_api_version(rs2_error** error) BEGIN_API_CALL
{
Expand Down
83 changes: 34 additions & 49 deletions tools/fw-update/rs-fw-update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ std::vector<uint8_t> read_fw_file(std::string file_path)
std::vector<uint8_t> rv;

std::ifstream file(file_path, std::ios::in | std::ios::binary | std::ios::ate);
auto file_deleter = std::unique_ptr< std::ifstream, void (*)(std::ifstream*) >(&file,
[](std::ifstream* file)
{
if (file)
file->close();
});
if (file.is_open())
{
rv.resize(file.tellg());
Expand Down Expand Up @@ -175,33 +169,35 @@ void waiting_for_device_to_reconnect(rs2::context& ctx, rs2::cli::value<std::str

}

bool is_fw_compatible(const rs2::device& dev, const std::vector< uint8_t >& fw_image)
{
auto upd = dev.as<rs2::updatable>();
if ( !upd )
{
throw std::runtime_error("Device could not be used as updatable device");
}
// checking compatibility bewtween firmware and device
if ( !upd.check_firmware_compatibility( fw_image ) )
{
std::stringstream ss;
ss << "This firmware version is not compatible with ";
ss << dev.get_info( RS2_CAMERA_INFO_NAME ) << std::endl;
std::cout << std::endl << ss.str() << std::endl;
return false;
}
return true;
}

int write_fw_to_mipi_device(rs2::context& ctx, rs2::cli::value<std::string>& serial_number_arg, const rs2::device& dev, const std::vector< uint8_t >& fw_image)
{
// Write firmware to appropriate file descriptor
std::cout << std::endl << "Update can take up to 2 minutes" << std::endl;
std::ofstream fw_path_in_device( dev.get_info( RS2_CAMERA_INFO_DFU_DEVICE_PATH ), std::ios::binary );
auto file_deleter = std::unique_ptr< std::ofstream, void ( * )( std::ofstream * ) >( &fw_path_in_device,
[]( std::ofstream * file )
{
if( file )
file->close();
} );

if( fw_path_in_device )
{
auto upd = dev.as<rs2::updatable>();
if ( !upd )
{
throw std::runtime_error("Device could not be used as updatable device");
}
// checking compatibility bewtween firmware and device
if( !upd.check_firmware_compatibility( fw_image ) )
{
std::stringstream ss;
ss << "This firmware version is not compatible with ";
ss << dev.get_info( RS2_CAMERA_INFO_NAME ) << std::endl;
std::cout << std::endl << ss.str() << std::endl;
if (!is_fw_compatible(dev, fw_image))
return EXIT_FAILURE;
}

bool burn_done = false;
std::thread show_progress_thread(
Expand Down Expand Up @@ -322,7 +318,7 @@ try

for (auto&& d : devs)
{
if (!d.is< rs2::update_device >())
if (!d.is_in_recovery_mode())
continue;
auto sn = d.get_info(RS2_CAMERA_INFO_FIRMWARE_UPDATE_ID);
if (!selected_serial_number.empty() && sn != selected_serial_number)
Expand All @@ -347,7 +343,7 @@ try
ctx.set_devices_changed_callback([&](rs2::event_information& info) {
for (auto&& d : info.get_new_devices())
{
if (d.is< rs2::update_device >())
if (d.is_in_recovery_mode())
continue;
auto recovery_sn = d.get_info(RS2_CAMERA_INFO_FIRMWARE_UPDATE_ID);
if (recovery_sn == update_serial_number)
Expand All @@ -363,6 +359,13 @@ try
});
std::cout << std::endl << "Recovering device: " << std::endl;
print_device_info(recovery_device);

std::string camera_name = recovery_device.get_info(RS2_CAMERA_INFO_NAME);
// on D555 check FW compatibility also sends FW to the device
if (camera_name.find("D555") != std::string::npos &&
(!is_fw_compatible(recovery_device, fw_image)))
return EXIT_FAILURE;

update(recovery_device, fw_image);
std::cout << "Waiting for new device..." << std::endl;
if (!d457_recovery_device)
Expand Down Expand Up @@ -404,7 +407,7 @@ try
for (auto&& d : info.get_new_devices())
{
std::lock_guard<std::mutex> lk(mutex);
if (d.is<rs2::update_device>() && (d.get_info(RS2_CAMERA_INFO_FIRMWARE_UPDATE_ID) == update_serial_number))
if (d.is_in_recovery_mode() && (d.get_info(RS2_CAMERA_INFO_FIRMWARE_UPDATE_ID) == update_serial_number))
new_fw_update_device = d;
else
new_device = d;
Expand All @@ -424,7 +427,7 @@ try
if (devs.size() == 1)
{
auto dev = devs[0];
if (dev.is< rs2::update_device >() && !dev.is< rs2::updatable >())
if (dev.is_in_recovery_mode() && !dev.is< rs2::updatable >())
{
std::cout << std::endl << "Device is in recovery mode, use -r to recover" << std::endl << std::endl;
return EXIT_FAILURE;
Expand Down Expand Up @@ -486,12 +489,6 @@ try
{
auto temp = backup_arg.getValue();
std::ofstream file(temp.c_str(), std::ios::binary);
auto file_deleter = std::unique_ptr< std::ofstream, void (*)(std::ofstream*) >(&file,
[](std::ofstream* file)
{
if (file)
file->close();
});
try
{
file.write((const char*)flash.data(), flash.size());
Expand Down Expand Up @@ -543,22 +540,10 @@ try
}
else
{
auto upd = d.as<rs2::updatable>();

if ( !upd )
{
throw std::runtime_error("Device could not be used as updatable device");
}
// checking compatibility bewtween firmware and device
if( !upd.check_firmware_compatibility( fw_image ) )
{
std::stringstream ss;
ss << "This firmware version is not compatible with ";
ss << d.get_info(RS2_CAMERA_INFO_NAME) << std::endl;
std::cout << std::endl << ss.str() << std::endl;
if (!is_fw_compatible(d, fw_image))
return EXIT_FAILURE;
}

auto upd = d.as<rs2::updatable>();
upd.enter_update_state();

// Some devices may immediately get in an update state?
Expand Down
2 changes: 1 addition & 1 deletion unit-tests/py/rspy/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ def recovery():
:return: A set of all device serial-numbers that are in recovery mode
"""
global _device_by_sn
return { device.serial_number for device in _device_by_sn.values() if device.handle.is_update_device() }
return { device.serial_number for device in _device_by_sn.values() if device.handle.is_in_recovery_mode() }


def enable_only( serial_numbers, recycle = False, timeout = MAX_ENUMERATION_TIME ):
Expand Down
2 changes: 1 addition & 1 deletion unit-tests/test-fw-update.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def find_image_or_exit( product_name, fw_version_regex = r'(\d+\.){3}(\d+)' ):
test.start( "Update FW" )
# check if recovery. If so recover
recovered = False
if device.is_update_device():
if device.is_in_recovery_mode():
log.d( "recovering device ..." )
try:
# always flash signed fw when device on recovery befre flashing anything else
Expand Down
1 change: 1 addition & 0 deletions wrappers/python/pyrs_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void init_device(py::module &m) {
.def("__nonzero__", &rs2::device::operator bool) // Called to implement truth value testing in Python 2
.def("__bool__", &rs2::device::operator bool) // Called to implement truth value testing in Python 3
.def( "is_connected", &rs2::device::is_connected )
.def("is_in_recovery_mode", &rs2::device::is_in_recovery_mode)
.def(BIND_DOWNCAST(device, debug_protocol))
.def(BIND_DOWNCAST(device, playback))
.def(BIND_DOWNCAST(device, recorder))
Expand Down
Loading