Skip to content

Commit

Permalink
add rs-dds-config
Browse files Browse the repository at this point in the history
  • Loading branch information
maloel committed Jul 7, 2024
1 parent 87f20ab commit 11cd58f
Show file tree
Hide file tree
Showing 8 changed files with 684 additions and 2 deletions.
1 change: 1 addition & 0 deletions tools/dds/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@

add_subdirectory(dds-sniffer)
add_subdirectory(dds-adapter)
add_subdirectory(dds-config)

4 changes: 2 additions & 2 deletions tools/dds/dds-adapter/rs-dds-adapter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2022 Intel Corporation. All Rights Reserved.
// Copyright(c) 2022-4 Intel Corporation. All Rights Reserved.

#include <realdds/dds-device-server.h>
#include <realdds/dds-stream-server.h>
Expand Down Expand Up @@ -113,7 +113,7 @@ int main( int argc, char * argv[] )
try
{
dds_domain_id domain = -1; // from settings; default to 0
CmdLine cmd( "librealsense rs-dds-adapter tool, use CTRL + C to stop..", ' ' );
CmdLine cmd( "librealsense rs-dds-adapter tool, use CTRL + C to stop..", ' ', RS2_API_FULL_VERSION_STR );
ValueArg< dds_domain_id > domain_arg( "d",
"domain",
"Select domain ID to publish on",
Expand Down
27 changes: 27 additions & 0 deletions tools/dds/dds-config/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# License: Apache 2.0. See LICENSE file in root directory.
# Copyright(c) 2024 Intel Corporation. All Rights Reserved.
cmake_minimum_required( VERSION 3.1.0 )
project( rs-dds-config )

add_executable( ${PROJECT_NAME} )

file( GLOB_RECURSE RS_DDS_CONFIG_SOURCE_FILES
LIST_DIRECTORIES false
RELATIVE ${PROJECT_SOURCE_DIR}
"${CMAKE_CURRENT_LIST_DIR}/*"
)
target_sources( ${PROJECT_NAME} PRIVATE ${RS_DDS_CONFIG_SOURCE_FILES} )

target_link_libraries( ${PROJECT_NAME} PRIVATE realdds realsense2 tclap )

set_target_properties (${PROJECT_NAME} PROPERTIES
FOLDER Tools/dds
CXX_STANDARD 14
)

install( TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

using_easyloggingpp( ${PROJECT_NAME} SHARED )

18 changes: 18 additions & 0 deletions tools/dds/dds-config/eth-config-header.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2024 Intel Corporation. All Rights Reserved.
#pragma once

#include <cstdint>


#pragma pack( push, 1 )

// The header structure for eth config
struct eth_config_header
{
uint16_t version;
uint16_t size; // without header
uint32_t crc; // without header
};

#pragma pack( pop )
36 changes: 36 additions & 0 deletions tools/dds/dds-config/eth-config-v3.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2024 Intel Corporation. All Rights Reserved.
#pragma once

#include "eth-config-header.h"


#pragma pack( push, 1 )

// The structure data for eth config info, version 3
// See table definition in HWMC v0.53 spec
struct eth_config_v3
{
eth_config_header header;
uint32_t link_check_timeout; // The threshold to wait eth link(ms).
uint8_t config_ip[4]; // static IP
uint8_t config_netmask[4]; // static netmask
uint8_t config_gateway[4]; // static gateway
uint8_t actual_ip[4]; // actual IP when dhcp is ON, read-only
uint8_t actual_netmask[4]; // actual netmask when dhcp is ON, read-only
uint8_t actual_gateway[4]; // actual gateway when dhcp is ON, read-only
uint32_t link_speed; // Mbps read-only
uint32_t mtu; // read-only
uint8_t dhcp_on; // 0=off
uint8_t dhcp_timeout; // The threshold to wait valid ip when DHCP is on(s).
uint8_t domain_id; // dds domain id
uint8_t link_priority; // device link priority. 0-USB_ONLY, 1-ETH_ONLY, 2-ETH_FIRST, 3 USB_FIRST
uint8_t mac_address[6]; // read-only
uint8_t reserved[2]; // needed to make size divisible by 4
};

#pragma pack( pop )


static_assert( sizeof( eth_config_v3 ) % 4 == 0, "eth config v3 struct size must be divisible by 4" );

141 changes: 141 additions & 0 deletions tools/dds/dds-config/eth-config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2024 Intel Corporation. All Rights Reserved.

#include "eth-config.h"
#include "eth-config-v3.h"

#include <rsutils/number/crc32.h>
#include <rsutils/string/hexdump.h>
#include <rsutils/string/from.h>


std::ostream & operator<<( std::ostream & os, link_priority p )
{
if( static_cast< uint8_t >( p ) & static_cast< uint8_t >( link_priority::_dynamic_bit ) )
{
os << "dynamic-";
p = static_cast< link_priority >( static_cast< uint8_t >( p )
& ~static_cast< uint8_t >( link_priority::_dynamic_bit ) );
}
switch( p )
{
case link_priority::usb_only:
os << "usb-only";
break;
case link_priority::usb_first:
os << "usb-first";
break;
case link_priority::eth_only:
os << "eth-only";
break;
case link_priority::eth_first:
os << "eth-first";
break;
default:
os << "UNKNOWN-" << (int) p;
break;
}
return os;
}


std::ostream & operator<<( std::ostream & os, ip_3 const & ip3 )
{
os << ip3.ip;
if( ip3.netmask.is_valid() )
os << " & " << ip3.netmask;
if( ip3.gateway.is_valid() )
os << " / " << ip3.gateway;
return os;
}


eth_config::eth_config( eth_config_v3 const & v3 )
: header( v3.header )
, mac_address( rsutils::string::from( rsutils::string::hexdump( v3.mac_address, sizeof( v3.mac_address ) )
.format( "{01}:{01}:{01}:{01}:{01}:{01}" ) ) )
, configured{ v3.config_ip, v3.config_netmask, v3.config_gateway }
, actual{ v3.actual_ip, v3.actual_netmask, v3.actual_gateway }
, dds{ v3.domain_id }
, link{ v3.mtu, v3.link_speed, v3.link_check_timeout, link_priority( v3.link_priority ) }
, dhcp{ v3.dhcp_on != 0, v3.dhcp_timeout }
{
}


eth_config::eth_config( std::vector< uint8_t > const & hwm_response )
{
auto header = reinterpret_cast< eth_config_header const * >( hwm_response.data() );
if( hwm_response.size() < sizeof( *header ) )
throw std::runtime_error( rsutils::string::from()
<< "HWM response size (" << hwm_response.size() << ") does not fit header (size "
<< sizeof( *header ) << ")" );

if( hwm_response.size() != sizeof( *header ) + header->size )
throw std::runtime_error( rsutils::string::from()
<< "HWM response size (" << hwm_response.size() << ") does not fit header ("
<< sizeof( *header ) << ") + header size (" << header->size << ")" );

auto const crc = rsutils::number::calc_crc32( hwm_response.data() + sizeof( *header ), header->size );
if( header->crc != crc )
throw std::runtime_error( rsutils::string::from()
<< "Eth config table CRC (" << header->crc << ") does not match response " << crc );

switch( header->version )
{
case 3: {
if( header->size != sizeof( eth_config_v3 ) - sizeof( *header ) )
throw std::runtime_error( rsutils::string::from()
<< "invalid Eth config table v3 size (" << header->size << "); expecting "
<< sizeof( eth_config_v3 ) << "-" << sizeof( *header ) );
auto config = reinterpret_cast< eth_config_v3 const * >( hwm_response.data() );
*this = *config;
break;
}

default:
throw std::runtime_error( rsutils::string::from()
<< "unrecognized Eth config table version " << header->version );
}
}


bool eth_config::operator==( eth_config const & other ) const noexcept
{
// Only compare those items that are configurable
return configured.ip == other.configured.ip && configured.netmask == other.configured.netmask
&& configured.gateway == other.configured.gateway && dds.domain_id == other.dds.domain_id
&& dhcp.on == other.dhcp.on && link.priority == other.link.priority && link.timeout == other.link.timeout;
}


bool eth_config::operator!=( eth_config const & other ) const noexcept
{
// Only compare those items that are configurable
return configured.ip != other.configured.ip || configured.netmask != other.configured.netmask
|| configured.gateway != other.configured.gateway || dds.domain_id != other.dds.domain_id
|| dhcp.on != other.dhcp.on || link.priority != other.link.priority || link.timeout != other.link.timeout;
}


std::vector< uint8_t > eth_config::build_command() const
{
std::vector< uint8_t > data;
data.resize( sizeof( eth_config_v3 ) );
eth_config_v3 & cfg = *reinterpret_cast< eth_config_v3 * >( data.data() );
configured.ip.get_components( cfg.config_ip );
configured.netmask.get_components( cfg.config_netmask );
configured.gateway.get_components( cfg.config_gateway );
cfg.dhcp_on = dhcp.on;
cfg.dhcp_timeout = dhcp.timeout;
cfg.domain_id = dds.domain_id;
cfg.link_check_timeout = link.timeout;
cfg.link_priority = (uint8_t)link.priority;

cfg.mtu = 9000; // R/O, but must be set to this value

cfg.header.version = 3;
cfg.header.size = sizeof( cfg ) - sizeof( cfg.header );
cfg.header.crc = rsutils::number::calc_crc32( data.data() + sizeof( cfg.header ), cfg.header.size );
return data;
}
72 changes: 72 additions & 0 deletions tools/dds/dds-config/eth-config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2024 Intel Corporation. All Rights Reserved.
#pragma once

#include "eth-config-header.h"

#include <rsutils/type/ip-address.h>


enum class link_priority : uint8_t
{
usb_only = 0,
eth_only = 1,
eth_first = 2,
usb_first = 3,

_dynamic_bit = 0x10,
dynamic_eth_first = eth_first | _dynamic_bit,
dynamic_usb_first = usb_first | _dynamic_bit
};
std::ostream & operator<<( std::ostream & os, link_priority );


struct ip_3
{
rsutils::type::ip_address ip;
rsutils::type::ip_address netmask;
rsutils::type::ip_address gateway;

operator bool() const { return ip.is_valid(); }

bool operator==( ip_3 const & other ) const { return ip == other.ip && netmask == other.netmask && gateway == other.gateway; }
bool operator!=( ip_3 const & other ) const { return ip != other.ip || netmask != other.netmask || gateway != other.gateway; }
};
std::ostream & operator<<( std::ostream &, ip_3 const & );


struct eth_config_v3;


struct eth_config
{
eth_config_header header;
std::string mac_address;
ip_3 configured;
ip_3 actual;
struct
{
int domain_id; // dds domain id
} dds;
struct
{
unsigned mtu; // bytes per packet
unsigned speed; // Mbps read-only; 0 if link is off
unsigned timeout; // The threshold to wait eth link(ms)
link_priority priority;
} link;
struct
{
bool on;
int timeout; // The threshold to wait valid ip when DHCP is on(s)
} dhcp;

eth_config() {}
explicit eth_config( std::vector< uint8_t > const & hwm_response_without_code );
eth_config( eth_config_v3 const & );

bool operator==( eth_config const & ) const noexcept;
bool operator!=( eth_config const & ) const noexcept;

std::vector< uint8_t > build_command() const;
};
Loading

0 comments on commit 11cd58f

Please sign in to comment.