Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON-based device-info & fix for no 'dds' settings #12540

Merged
merged 12 commits into from
Jan 1, 2024
12 changes: 2 additions & 10 deletions src/dds/rs-dds-device-info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,14 @@ std::string dds_device_info::get_address() const

return rsutils::string::from() << "dds." << domain_id << "://"
<< _dev->participant()->print( _dev->server_guid() ) << "@"
<< _dev->device_info().topic_root;
<< _dev->device_info().topic_root();
}


void dds_device_info::to_stream( std::ostream & os ) const
{
os << "DDS device (" << _dev->participant()->print( _dev->guid() ) << " on domain "
<< _dev->participant()->get()->get_domain_id() << "):";
os << "\n\tName: " << _dev->device_info().name;
if( ! _dev->device_info().serial.empty() )
os << "\n\tSerial: " << _dev->device_info().serial;
if( ! _dev->device_info().product_line.empty() )
os << "\n\tProduct line: " << _dev->device_info().product_line;
os << "\n\tTopic root: " << _dev->device_info().topic_root;
if( _dev->device_info().locked )
os << "\n\tLOCKED";
<< _dev->participant()->get()->get_domain_id() << "):" << _dev->device_info().to_json().dump( 4 );
}


Expand Down
23 changes: 18 additions & 5 deletions src/dds/rs-dds-device-proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,25 @@ dds_device_proxy::dds_device_proxy( std::shared_ptr< const device_info > const &
, _dds_dev( dev )
{
LOG_DEBUG( "=====> dds-device-proxy " << this << " created on top of dds-device " << _dds_dev.get() );
register_info( RS2_CAMERA_INFO_NAME, dev->device_info().name );
register_info( RS2_CAMERA_INFO_SERIAL_NUMBER, dev->device_info().serial );
register_info( RS2_CAMERA_INFO_PRODUCT_LINE, dev->device_info().product_line );
register_info( RS2_CAMERA_INFO_NAME, dev->device_info().name() );
register_info( RS2_CAMERA_INFO_PHYSICAL_PORT, dev->device_info().topic_root() );
register_info( RS2_CAMERA_INFO_PRODUCT_ID, "DDS" );
register_info( RS2_CAMERA_INFO_PHYSICAL_PORT, dev->device_info().topic_root );
register_info( RS2_CAMERA_INFO_CAMERA_LOCKED, dev->device_info().locked ? "YES" : "NO" );

auto & j = dev->device_info().to_json();
std::string str;
if( rsutils::json::get_ex( j, "serial", &str ) )
{
register_info( RS2_CAMERA_INFO_SERIAL_NUMBER, str );
rsutils::json::get_ex( j, "fw-update-id", &str ); // if fails, str will be the serial
register_info( RS2_CAMERA_INFO_FIRMWARE_UPDATE_ID, str );
}
else if( rsutils::json::get_ex( j, "fw-update-id", &str ) )
register_info( RS2_CAMERA_INFO_FIRMWARE_UPDATE_ID, str );
if( rsutils::json::get_ex( j, "fw-version", &str ) )
register_info( RS2_CAMERA_INFO_FIRMWARE_VERSION, str );
if( rsutils::json::get_ex( j, "product-line", &str ) )
register_info( RS2_CAMERA_INFO_PRODUCT_LINE, str );
register_info( RS2_CAMERA_INFO_CAMERA_LOCKED, rsutils::json::get( j, "locked", true ) ? "YES" : "NO" );

// Assumes dds_device initialization finished
struct sensor_info
Expand Down
2 changes: 1 addition & 1 deletion src/dds/rs-dds-sensor-proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ void dds_sensor_proxy::start( rs2_frame_callback_sptr callback )
}
auto const & dds_stream = streamit->second;
// Opening it will start streaming on the server side automatically
dds_stream->open( "rt/" + _dev->device_info().topic_root + '_' + dds_stream->name(), _dev->subscriber() );
dds_stream->open( "rt/" + _dev->device_info().topic_root() + '_' + dds_stream->name(), _dev->subscriber() );
auto & streaming = _streaming_by_name[dds_stream->name()];
streaming.syncer.on_frame_release( frame_releaser );
streaming.syncer.on_frame_ready(
Expand Down
22 changes: 15 additions & 7 deletions src/dds/rsdds-device-factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,23 @@ std::vector< std::shared_ptr< device_info > > rsdds_device_factory::query_device
LOG_DEBUG( "device '" << dev->device_info().debug_name() << "' is not ready" );
return true;
}
if( dev->device_info().product_line == "D400" )
std::string product_line;
if( rsutils::json::get_ex( dev->device_info().to_json(), "product-line", &product_line ) )
{
if( ! ( mask & RS2_PRODUCT_LINE_D400 ) )
return true;
}
else if( dev->device_info().product_line == "D500" )
{
if( ! ( mask & RS2_PRODUCT_LINE_D500 ) )
if( product_line == "D400" )
{
if( ! ( mask & RS2_PRODUCT_LINE_D400 ) )
return true;
}
else if( product_line == "D500" )
{
if( ! ( mask & RS2_PRODUCT_LINE_D500 ) )
return true;
}
else if( ! ( mask & RS2_PRODUCT_LINE_NON_INTEL ) )
{
return true;
}
}
else if( ! ( mask & RS2_PRODUCT_LINE_NON_INTEL ) )
{
Expand Down
24 changes: 16 additions & 8 deletions third-party/realdds/include/realdds/topics/device-info-msg.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2022 Intel Corporation. All Rights Reserved.

#pragma once

#include <nlohmann/json_fwd.hpp>
#include <nlohmann/json.hpp>

#include <rsutils/string/slice.h>

Expand All @@ -12,14 +11,23 @@ namespace topics {

class device_info
{
nlohmann::json _json;

public:
std::string name;
std::string serial;
std::string product_line;
std::string topic_root;
bool locked = true;
//std::string serial;
//std::string product_line;
//bool locked = true;

std::string const & name() const;
void set_name( std::string && );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure from user perspective that rvalue is always desired, for instance rs2_device_to_info copies the name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I debated but eventually I just decided that it's fine if we copied before calling the function. Otherwise I can change to const &. What would you prefer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I prefer const &

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means always a copy vs. a move if possible. But OK, done.


std::string const & topic_root() const;
void set_topic_root( std::string && );

std::string const & serial_number() const;
void set_serial_number( std::string && );

nlohmann::json to_json() const;
nlohmann::json const & to_json() const;
static device_info from_json( nlohmann::json const & j );

// Substring of information already stored in the device-info that can be used to print the device 'name'.
Expand Down
23 changes: 6 additions & 17 deletions third-party/realdds/py/pyrealdds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,27 +375,16 @@ PYBIND11_MODULE(NAME, m) {
py::class_< device_info >( message, "device_info" )
.def( py::init<>() )
.def_static( "create_topic", static_cast< flexible_msg_create_topic * >( &flexible_msg::create_topic ) )
.def_readwrite( "name", &device_info::name )
.def_readwrite( "serial", &device_info::serial )
.def_readwrite( "product_line", &device_info::product_line )
.def_readwrite( "locked", &device_info::locked )
.def_readwrite( "topic_root", &device_info::topic_root )
.def_property( "name", &device_info::name, &device_info::set_name )
.def_property( "topic_root", &device_info::topic_root, &device_info::set_topic_root )
.def_property( "serial", &device_info::serial_number, &device_info::set_serial_number )
.def_static( "from_json", &device_info::from_json )
.def( "to_json", &device_info::to_json )
.def( "__repr__",
[]( device_info const & self ) {
std::ostringstream os;
os << "<" SNAME ".device_info";
if( ! self.name.empty() )
os << " \"" << self.name << "\"";
if( ! self.serial.empty() )
os << " s/n \"" << self.serial << "\"";
if( ! self.topic_root.empty() )
os << " @ \"" << self.topic_root << "\"";
if( ! self.product_line.empty() )
os << " product-line \"" << self.product_line << "\"";
if( self.locked )
os << " locked";
os << " " << self.to_json();
os << ">";
return os.str();
} );
Expand Down Expand Up @@ -953,8 +942,8 @@ PYBIND11_MODULE(NAME, m) {
std::ostringstream os;
os << "<" SNAME ".device";
os << " " << self.participant()->print( self.guid() );
if( ! self.device_info().name.empty() )
os << " \"" << self.device_info().name << "\"";
if( ! self.device_info().name().empty() )
os << " \"" << self.device_info().name() << "\"";
os << " @ " << self.device_info().debug_name();
os << ">";
return os.str();
Expand Down
2 changes: 1 addition & 1 deletion third-party/realdds/src/dds-device-broadcaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ void dds_device_broadcaster::broadcast() const
}
catch( std::exception const & e )
{
LOG_ERROR( "Error sending device-info message for S/N " << _device_info.serial << ": " << e.what() );
LOG_ERROR( "Error sending device-info message for S/N " << _device_info.serial_number() << ": " << e.what() );
}
}

Expand Down
6 changes: 3 additions & 3 deletions third-party/realdds/src/dds-device-impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ void dds_device::impl::create_notifications_reader()
if( _notifications_reader )
return;

auto topic = topics::flexible_msg::create_topic( _participant, _info.topic_root + topics::NOTIFICATION_TOPIC_NAME );
auto topic = topics::flexible_msg::create_topic( _participant, _info.topic_root() + topics::NOTIFICATION_TOPIC_NAME );

// We have some complicated topic structures. In particular, the metadata topic is created on demand while handling
// other notifications, which doesn't work well (deadlock) if the notification is not called from another thread. So
Expand Down Expand Up @@ -518,7 +518,7 @@ void dds_device::impl::create_metadata_reader()
if( _metadata_reader ) // We can be called multiple times, once per stream
return;

auto topic = topics::flexible_msg::create_topic( _participant, _info.topic_root + topics::METADATA_TOPIC_NAME );
auto topic = topics::flexible_msg::create_topic( _participant, _info.topic_root() + topics::METADATA_TOPIC_NAME );
_metadata_reader = std::make_shared< dds_topic_reader_thread >( topic, _subscriber );
_metadata_reader->on_data_available(
[this]()
Expand Down Expand Up @@ -549,7 +549,7 @@ void dds_device::impl::create_control_writer()
if( _control_writer )
return;

auto topic = topics::flexible_msg::create_topic( _participant, _info.topic_root + topics::CONTROL_TOPIC_NAME );
auto topic = topics::flexible_msg::create_topic( _participant, _info.topic_root() + topics::CONTROL_TOPIC_NAME );
_control_writer = std::make_shared< dds_topic_writer >( topic );
dds_topic_writer::qos wqos( eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS );
wqos.history().depth = 10; // default is 1
Expand Down
2 changes: 1 addition & 1 deletion third-party/realdds/src/dds-device-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ void dds_device_server::broadcast( topics::device_info const & device_info )
{
if( _broadcaster )
DDS_THROW( runtime_error, "device server was already broadcast" );
if( device_info.topic_root != _topic_root )
if( device_info.topic_root() != _topic_root )
DDS_THROW( runtime_error, "topic roots do not match" );
_broadcaster = std::make_shared< dds_device_broadcaster >( _publisher, device_info );
}
Expand Down
2 changes: 1 addition & 1 deletion third-party/realdds/src/dds-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace realdds {
dds_device::dds_device( std::shared_ptr< dds_participant > const & participant, topics::device_info const & info )
: _impl( std::make_shared< dds_device::impl >( participant, info ) )
{
LOG_DEBUG( "+device '" << _impl->debug_name() << "' on " << info.topic_root );
LOG_DEBUG( "+device '" << _impl->debug_name() << "' on " << info.topic_root() );
}


Expand Down
71 changes: 51 additions & 20 deletions third-party/realdds/src/topics/device-info-msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <realdds/topics/device-info-msg.h>
#include <realdds/topics/dds-topic-names.h>
#include <realdds/dds-exceptions.h>

#include <rsutils/json.h>
#include <rsutils/easylogging/easyloggingpp.h>
Expand All @@ -11,41 +12,71 @@ namespace realdds {
namespace topics {


static std::string name_key( "name", 4 );
static std::string topic_root_key( "topic-root", 10 );
static std::string serial_number_key( "serial", 6 );


/* static */ device_info device_info::from_json( nlohmann::json const & j )
{
device_info ret;
ret._json = j;

ret.name = rsutils::json::get< std::string >( j, "name" );
rsutils::json::get_ex( j, "serial", &ret.serial );
rsutils::json::get_ex( j, "product-line", &ret.product_line );
ret.topic_root = rsutils::json::get< std::string >( j, "topic-root" );
rsutils::json::get_ex( j, "locked", &ret.locked );
// Check the two mandatory fields are there
if( ret.name().empty() )
DDS_THROW( runtime_error, "empty device-info name" );
if( ret.topic_root().empty() )
DDS_THROW( runtime_error, "empty device-info topic-root" );

return ret;
}


nlohmann::json device_info::to_json() const
nlohmann::json const & device_info::to_json() const
{
return _json;
}


std::string const & device_info::name() const
{
return rsutils::json::nested( _json, name_key ).string_ref_or_empty();
}

void device_info::set_name( std::string && v )
{
_json[name_key] = std::move( v );
}


std::string const & device_info::topic_root() const
{
return rsutils::json::nested( _json, topic_root_key ).string_ref_or_empty();
}

void device_info::set_topic_root( std::string && v )
{
_json[topic_root_key] = std::move( v );
}


std::string const & device_info::serial_number() const
{
return rsutils::json::nested( _json, serial_number_key ).string_ref_or_empty();
}

void device_info::set_serial_number( std::string && v )
{
auto msg = nlohmann::json( {
{ "name", name },
{ "topic-root", topic_root },
} );
if( ! serial.empty() )
msg["serial"] = serial;
if( ! product_line.empty() )
msg["product-line"] = product_line;
if( ! locked )
msg["locked"] = false;
return msg;
_json[serial_number_key] = std::move( v );
}


rsutils::string::slice device_info::debug_name() const
{
auto begin = topic_root.c_str();
auto end = begin + topic_root.length();
if( topic_root.length() > ROOT_LEN && SEPARATOR == begin[ROOT_LEN-1] )
auto & root = topic_root();
auto begin = root.c_str();
auto end = begin + root.length();
if( root.length() > ROOT_LEN && SEPARATOR == begin[ROOT_LEN-1] )
begin += ROOT_LEN;
return{ begin, end };
}
Expand Down
Loading