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
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ target_sources(${LRS_TARGET}
"${CMAKE_CURRENT_LIST_DIR}/device.cpp"
"${CMAKE_CURRENT_LIST_DIR}/device-info.cpp"
"${CMAKE_CURRENT_LIST_DIR}/device_hub.cpp"
"${CMAKE_CURRENT_LIST_DIR}/rscore/device-factory.h"
"${CMAKE_CURRENT_LIST_DIR}/environment.cpp"
"${CMAKE_CURRENT_LIST_DIR}/error-handling.cpp"
"${CMAKE_CURRENT_LIST_DIR}/firmware_logger_device.cpp"
Expand Down
2 changes: 1 addition & 1 deletion src/backend-device-factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ std::shared_ptr< platform::backend > backend_device::get_backend()


backend_device_factory::backend_device_factory( context & ctx, callback && cb )
: _context( ctx )
: super( ctx )
, _device_watcher( backend_device_watcher.instance() )
, _dtor( _device_watcher->subscribe(
[this, cb = std::move( cb )]( platform::backend_device_group const & old,
Expand Down
18 changes: 5 additions & 13 deletions src/backend-device-factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,13 @@

#pragma once

#include <rscore/device-factory.h>
#include <rsutils/subscription.h>
#include <memory>
#include <vector>


struct rs2_device_info;


namespace librealsense {


class device_info;
class context;
class device_watcher_singleton;


Expand All @@ -35,23 +29,21 @@ class platform_device_info;
// manages these device-info objects such that lifetime is tracked and updated appropriately, without the caller's
// knowledge.
//
class backend_device_factory
class backend_device_factory : public device_factory
{
context & _context;
typedef device_factory super;

std::shared_ptr< device_watcher_singleton > const _device_watcher;
rsutils::subscription const _dtor; // raii generic code, used to automatically unsubscribe our callback

public:
using callback = std::function< void( std::vector< rs2_device_info > & rs2_devices_info_removed,
std::vector< rs2_device_info > & rs2_devices_info_added ) >;

backend_device_factory( context &, callback && );
~backend_device_factory();

// Query any subset of available devices and return them as device-info objects
// Devices will match both the requested mask and the device-mask from the context settings
//
std::vector< std::shared_ptr< device_info > > query_devices( unsigned mask ) const;
std::vector< std::shared_ptr< device_info > > query_devices( unsigned mask ) const override;

private:
std::vector< std::shared_ptr< platform::platform_device_info > >
Expand Down
178 changes: 33 additions & 145 deletions src/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,24 @@
// Copyright(c) 2015 Intel Corporation. All Rights Reserved.

#include "context.h"

#include "media/playback/playback-device-info.h"
#include "environment.h"
#include <src/backend.h>


#include "backend-device-factory.h"
#ifdef BUILD_WITH_DDS
#include "dds/rs-dds-device-info.h"

#include <realdds/dds-device-watcher.h>
#include <realdds/dds-participant.h>
#include <realdds/dds-device.h>
#include <realdds/topics/device-info-msg.h>
#include <rsutils/shared-ptr-singleton.h>
#include <rsutils/os/executable-name.h>
#include <rsutils/string/slice.h>

// We manage one participant and device-watcher per domain:
// Two contexts with the same domain-id will share the same participant and watcher, while a third context on a
// different domain will have its own.
//
struct dds_domain_context
{
rsutils::shared_ptr_singleton< realdds::dds_participant > participant;
rsutils::shared_ptr_singleton< realdds::dds_device_watcher > device_watcher;
};
//
// Domains are mapped by ID:
// Two contexts with the same participant name on different domain-ids are using two different participants!
//
static std::map< realdds::dds_domain_id, dds_domain_context > dds_domain_context_by_id;

#endif // BUILD_WITH_DDS
#include "dds/rsdds-device-factory.h"
#endif

#include <rsutils/string/from.h>
#include <rsutils/json.h>
using json = nlohmann::json;


namespace librealsense
{
context::context( json const & settings )
: _settings( settings )
, _device_mask( rsutils::json::get< unsigned >( settings, "device-mask", RS2_PRODUCT_LINE_ANY ) )
, _devices_changed_callback( nullptr, []( rs2_devices_changed_callback * ) {} )
, _backend_device_factory(
*this,
[this]( std::vector< rs2_device_info > & removed, std::vector< rs2_device_info > & added )
{ invoke_devices_changed_callbacks( removed, added ); } )
{
static bool version_logged = false;
if( ! version_logged )
Expand All @@ -57,39 +28,17 @@ namespace librealsense
LOG_DEBUG( "Librealsense VERSION: " << RS2_API_VERSION_STR );
}

#ifdef BUILD_WITH_DDS
nlohmann::json dds_settings
= rsutils::json::get< nlohmann::json >( settings, std::string( "dds", 3 ), nlohmann::json::object() );
if( dds_settings.is_object() )
{
realdds::dds_domain_id domain_id
= rsutils::json::get< int >( dds_settings, std::string( "domain", 6 ), 0 );
std::string participant_name = rsutils::json::get< std::string >( dds_settings,
std::string( "participant", 11 ),
rsutils::os::executable_name() );

auto & domain = dds_domain_context_by_id[domain_id];
_dds_participant = domain.participant.instance();
if( ! _dds_participant->is_valid() )
{
_dds_participant->init( domain_id, participant_name, std::move( dds_settings ) );
}
else if( rsutils::json::has_value( dds_settings, std::string( "participant", 11 ) )
&& participant_name != _dds_participant->name() )
{
throw std::runtime_error( rsutils::string::from() << "A DDS participant '" << _dds_participant->name()
<< "' already exists in domain " << domain_id
<< "; cannot create '" << participant_name << "'" );
}
_dds_watcher = domain.device_watcher.instance( _dds_participant );
_factories.push_back( std::make_shared< backend_device_factory >(
*this,
[this]( std::vector< rs2_device_info > & removed, std::vector< rs2_device_info > & added )
{ invoke_devices_changed_callbacks( removed, added ); } ) );

// The DDS device watcher should always be on
if( _dds_watcher && _dds_watcher->is_stopped() )
{
start_dds_device_watcher();
}
}
#endif //BUILD_WITH_DDS
#ifdef BUILD_WITH_DDS
_factories.push_back( std::make_shared< rsdds_device_factory >(
*this,
[this]( std::vector< rs2_device_info > & removed, std::vector< rs2_device_info > & added )
{ invoke_devices_changed_callbacks( removed, added ); } ) );
#endif
}


Expand All @@ -101,10 +50,6 @@ namespace librealsense

context::~context()
{
#ifdef BUILD_WITH_DDS
if( _dds_watcher )
_dds_watcher->stop();
#endif //BUILD_WITH_DDS
}


Expand All @@ -120,65 +65,31 @@ namespace librealsense
}


std::vector<std::shared_ptr<device_info>> context::query_devices( int requested_mask ) const
std::vector< std::shared_ptr< device_info > > context::query_devices( int requested_mask ) const
{
auto list = _backend_device_factory.query_devices( requested_mask );
query_software_devices( list, requested_mask );
std::vector< std::shared_ptr< device_info > > list;
for( auto & factory : _factories )
{
for( auto & dev_info : factory->query_devices( requested_mask ) )
{
LOG_INFO( "... " << dev_info->get_address() );
list.push_back( dev_info );
}
}
for( auto & item : _playback_devices )
{
if( auto dev_info = item.second.lock() )
{
LOG_INFO( "... " << dev_info->get_address() );
list.push_back( dev_info );
}
}
LOG_INFO( "Found " << list.size() << " RealSense devices (0x" << std::hex << requested_mask << " requested & 0x"
<< get_device_mask() << " from device-mask in settings)" << std::dec );
for( auto & item : list )
LOG_INFO( "... " << item->get_address() );
return list;
}


void context::query_software_devices( std::vector< std::shared_ptr< device_info > > & list, unsigned requested_mask ) const
{
unsigned mask = combine_device_masks( requested_mask, get_device_mask() );

auto t = const_cast<context *>(this); // While generally a bad idea, we need to provide mutable reference to the devices
// to allow them to modify context later on
auto ctx = t->shared_from_this();

#ifdef BUILD_WITH_DDS
if( _dds_watcher )
_dds_watcher->foreach_device(
[&]( std::shared_ptr< realdds::dds_device > const & dev ) -> bool
{
if( !dev->is_ready() )
{
LOG_DEBUG( "device '" << dev->device_info().debug_name() << "' is not yet ready" );
return true;
}
if( dev->device_info().product_line == "D400" )
{
if( !(mask & RS2_PRODUCT_LINE_D400) )
return true;
}
else if( dev->device_info().product_line == "D500" )
{
if( !(mask & RS2_PRODUCT_LINE_D500) )
return true;
}
else if( !(mask & RS2_PRODUCT_LINE_NON_INTEL) )
{
return true;
}

std::shared_ptr< device_info > info = std::make_shared< dds_device_info >( ctx, dev );
list.push_back( info );
return true;
} );
#endif //BUILD_WITH_DDS

for( auto && item : _playback_devices )
{
if( auto dev = item.second.lock() )
list.push_back( dev );
}
}


void context::invoke_devices_changed_callbacks( std::vector<rs2_device_info> & rs2_devices_info_removed,
std::vector<rs2_device_info> & rs2_devices_info_added )
{
Expand Down Expand Up @@ -225,29 +136,6 @@ namespace librealsense
}


#ifdef BUILD_WITH_DDS
void context::start_dds_device_watcher()
{
_dds_watcher->on_device_added( [this]( std::shared_ptr< realdds::dds_device > const & dev ) {
dev->wait_until_ready(); // make sure handshake is complete

std::vector<rs2_device_info> rs2_device_info_added;
std::vector<rs2_device_info> rs2_device_info_removed;
auto info = std::make_shared< dds_device_info >( shared_from_this(), dev );
rs2_device_info_added.push_back( { shared_from_this(), info } );
invoke_devices_changed_callbacks( rs2_device_info_removed, rs2_device_info_added );
} );
_dds_watcher->on_device_removed( [this]( std::shared_ptr< realdds::dds_device > const & dev ) {
std::vector<rs2_device_info> rs2_device_info_added;
std::vector<rs2_device_info> rs2_device_info_removed;
auto info = std::make_shared< dds_device_info >( shared_from_this(), dev );
rs2_device_info_removed.push_back( { shared_from_this(), info } );
invoke_devices_changed_callbacks( rs2_device_info_removed, rs2_device_info_added );
} );
_dds_watcher->start();
}
#endif //BUILD_WITH_DDS

uint64_t context::register_internal_device_callback(devices_changed_callback_ptr callback)
{
std::lock_guard<std::mutex> lock(_devices_changed_callbacks_mtx);
Expand Down
21 changes: 3 additions & 18 deletions src/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#pragma once

#include "backend-device-factory.h"
#include "types.h" // devices_changed_callback_ptr

#include <rsutils/lazy.h>
Expand Down Expand Up @@ -38,18 +37,11 @@ struct rs2_stream_profile
};


#ifdef BUILD_WITH_DDS
namespace realdds {
class dds_device_watcher;
class dds_participant;
} // namespace realdds
#endif


namespace librealsense
{
class playback_device_info;
class stream_interface;
class device_factory;

class context : public std::enable_shared_from_this<context>
{
Expand Down Expand Up @@ -77,8 +69,6 @@ namespace librealsense
void unregister_internal_device_callback(uint64_t cb_id);
void set_devices_changed_callback(devices_changed_callback_ptr callback);

void query_software_devices( std::vector< std::shared_ptr< device_info > > & list, unsigned requested_mask ) const;

std::shared_ptr<playback_device_info> add_device(const std::string& file);
void remove_device(const std::string& file);

Expand All @@ -93,16 +83,11 @@ namespace librealsense

std::map<std::string, std::weak_ptr<device_info>> _playback_devices;
std::map<uint64_t, devices_changed_callback_ptr> _devices_changed_callbacks;
#ifdef BUILD_WITH_DDS
std::shared_ptr< realdds::dds_participant > _dds_participant;
std::shared_ptr< realdds::dds_device_watcher > _dds_watcher;

void start_dds_device_watcher();
#endif

nlohmann::json _settings; // Save operation settings
unsigned const _device_mask;
backend_device_factory _backend_device_factory;

std::vector< std::shared_ptr< device_factory > > _factories;

devices_changed_callback_ptr _devices_changed_callback;
std::map<int, std::weak_ptr<const stream_interface>> _streams;
Expand Down
Loading