Merge pull request #149 from eProsima/v1.2.1

Release v1.2.1
This commit is contained in:
Pablo Garrido 2020-05-08 07:53:32 +02:00 committed by GitHub
commit 46ee5bcd3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
101 changed files with 3496 additions and 1162 deletions

8
.gitignore vendored
View File

@ -9,3 +9,11 @@ tags
# eclipse
.cproject
.project
src/c/profile/transport/ip/tcp/tcp_transport_external.c
src/c/profile/transport/ip/udp/udp_transport_external.c
src/c/profile/transport/serial/serial_transport_external.c
include/uxr/client/profile/transport/ip/tcp/tcp_transport_external.h
include/uxr/client/profile/transport/ip/udp/udp_transport_external.h
include/uxr/client/profile/transport/serial/serial_transport_external.h

View File

@ -26,6 +26,7 @@ option(UCLIENT_BUILD_EXAMPLES "Build examples." OFF)
option(UCLIENT_VERBOSE_SERIALIZATION "Build with serialization verbosity." OFF)
option(UCLIENT_VERBOSE_MESSAGE "Build with message verbosity." OFF)
option(UCLIENT_PIC "Control Position Independent Code." ON)
option(UCLIENT_ISOLATED_INSTALL "Install the project and dependencies into separeted folders with version control." ON)
option(BUILD_SHARED_LIBS "Control shared/static library building." OFF)
option(UCLIENT_BUILD_CI_TESTS "Build CI test cases." OFF)
@ -43,22 +44,11 @@ option(UCLIENT_BIG_ENDIANNESS "Set the machine endianness to big endianness (by
set(UCLIENT_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/client.config" CACHE PATH "Configuration client file.")
include(GNUInstallDirs)
set(BIN_INSTALL_DIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for binaries")
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for C headers")
set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries")
set(DATA_INSTALL_DIR ${CMAKE_INSTALL_DATADIR} CACHE PATH "Installation directory for data")
if(WIN32)
set(LICENSE_INSTALL_DIR . CACHE PATH "Installation directory for licenses")
else()
set(LICENSE_INSTALL_DIR ${DATA_INSTALL_DIR}/${PROJECT_NAME} CACHE PATH "Installation directory for licenses")
endif()
###############################################################################
# Dependencies
###############################################################################
set(_microcdr_version 1.1.2)
set(_microcdr_tag v1.1.2)
set(_microcdr_version 1.2.0)
set(_microcdr_tag v1.2.0)
set(_deps "")
list(APPEND _deps "microcdr\;${_microcdr_version}")
@ -68,7 +58,7 @@ list(APPEND _deps "microcdr\;${_microcdr_version}")
###############################################################################
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
if(NOT UCLIENT_SUPERBUILD)
project(microxrcedds_client VERSION "1.1.6" LANGUAGES C)
project(microxrcedds_client VERSION "1.2.1" LANGUAGES C)
else()
project(uclient_superbuild NONE)
include(${PROJECT_SOURCE_DIR}/cmake/SuperBuild.cmake)
@ -120,55 +110,25 @@ endforeach()
###############################################################################
# Check platform.
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(PLATFORM_NAME_LINUX ON)
set(TRANSPORT_TYPES "UDP" "TCP" "SERIAL")
set(UCLIENT_PLATFORM_LINUX ON)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(PLATFORM_NAME_WINDOWS ON)
set(TRANSPORT_TYPES "UDP" "TCP")
set(UCLIENT_PLATFORM_WINDOWS ON)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Generic")
if(PLATFORM_NAME STREQUAL "nuttx")
set(PLATFORM_NAME_NUTTX ON)
set(TRANSPORT_TYPES "UDP" "TCP" "SERIAL")
set(UCLIENT_PLATFORM_NUTTX ON)
elseif(PLATFORM_NAME STREQUAL "LwIP")
set(UCLIENT_PLATFORM_POSIX_NOPOLL ON)
endif()
endif()
# Transport sources.
foreach(TRANS_TYPE ${TRANSPORT_TYPES})
if(PROFILE_${TRANS_TYPE}_TRANSPORT)
string(TOLOWER ${TRANS_TYPE} TT)
if(PLATFORM_NAME_LINUX)
set(${TRANS_TYPE}_SRCS
src/c/profile/transport/${TT}/${TT}_transport.c
src/c/profile/transport/${TT}/${TT}_transport_linux.c
)
elseif(PLATFORM_NAME_WINDOWS)
set(${TRANS_TYPE}_SRCS
src/c/profile/transport/${TT}/${TT}_transport.c
src/c/profile/transport/${TT}/${TT}_transport_windows.c
)
elseif(PLATFORM_NAME_NUTTX)
set(${TRANS_TYPE}_SRCS
src/c/profile/transport/${TT}/${TT}_transport.c
src/c/profile/transport/${TT}/${TT}_transport_linux.c
)
endif()
endif()
endforeach()
if(PROFILE_SERIAL_TRANSPORT)
set(SERIAL_SRCS ${SERIAL_SRCS} src/c/profile/transport/serial/serial_protocol.c)
if(UCLIENT_PLATFORM_LINUX OR UCLIENT_PLATFORM_NUTTX)
set(UCLIENT_PLATFORM_POSIX ON)
endif()
# Transport discovery source.
if(PROFILE_DISCOVERY)
if(PLATFORM_NAME_LINUX)
set(UDP_DISCOVERY_SRCS src/c/profile/discovery/transport/udp_transport_datagram_linux.c)
elseif(PLATFORM_NAME_WINDOWS)
set(UDP_DISCOVERY_SRCS src/c/profile/discovery/transport/udp_transport_datagram_windows.c)
elseif(PLATFORM_NAME_NUTTX)
set(UDP_DISCOVERY_SRCS src/c/profile/discovery/transport/udp_transport_datagram_linux.c)
endif()
endif()
# Check external transport.
option(UCLIENT_EXTERNAL_TCP "Enable external serial transport." OFF)
option(UCLIENT_EXTERNAL_UDP "Enable external serial transport." OFF)
option(UCLIENT_EXTERNAL_SERIAL "Enable external serial transport." OFF)
# Other sources
set(SRCS
@ -183,7 +143,7 @@ set(SRCS
src/c/core/session/session_info.c
src/c/core/session/submessage.c
src/c/core/session/object_id.c
src/c/core/serialization/xrce_protocol.c
src/c/core/serialization/xrce_types.c
src/c/core/serialization/xrce_header.c
src/c/core/serialization/xrce_subheader.c
src/c/util/time.c
@ -194,12 +154,44 @@ set(SRCS
src/c/core/session/write_access.c
$<$<OR:$<BOOL:${UCLIENT_VERBOSE_MESSAGE}>,$<BOOL:${UCLIENT_VERBOSE_SERIALIZATION}>>:src/c/core/log/log.c>
$<$<BOOL:${PROFILE_DISCOVERY}>:src/c/profile/discovery/discovery.c>
${UDP_DISCOVERY_SRCS}
${UDP_SRCS}
${TCP_SRCS}
${SERIAL_SRCS}
$<$<BOOL:${PROFILE_DISCOVERY}>:src/c/profile/transport/ip/udp/udp_transport.c>
$<$<AND:$<BOOL:${PROFILE_DISCOVERY}>,$<BOOL:${UCLIENT_PLATFORM_POSIX}>>:src/c/profile/discovery/transport/udp_transport_datagram_posix.c>
$<$<AND:$<BOOL:${PROFILE_DISCOVERY}>,$<PLATFORM_ID:Windows>>:src/c/profile/discovery/transport/udp_transport_datagram_windows.c>
$<$<BOOL:${PROFILE_UDP_TRANSPORT}>:src/c/profile/transport/ip/udp/udp_transport.c>
$<$<AND:$<BOOL:${PROFILE_UDP_TRANSPORT}>,$<BOOL:${UCLIENT_PLATFORM_POSIX}>>:src/c/profile/transport/ip/udp/udp_transport_posix.c>
$<$<AND:$<BOOL:${PROFILE_UDP_TRANSPORT}>,$<BOOL:${UCLIENT_PLATFORM_POSIX_NOPOLL}>>:src/c/profile/transport/ip/udp/udp_transport_posix_nopoll.c>
$<$<AND:$<BOOL:${PROFILE_UDP_TRANSPORT}>,$<PLATFORM_ID:Windows>>:src/c/profile/transport/ip/udp/udp_transport_windows.c>
$<$<BOOL:${PROFILE_TCP_TRANSPORT}>:src/c/profile/transport/ip/tcp/tcp_transport.c>
$<$<AND:$<BOOL:${PROFILE_TCP_TRANSPORT}>,$<BOOL:${UCLIENT_PLATFORM_POSIX}>>:src/c/profile/transport/ip/tcp/tcp_transport_posix.c>
$<$<AND:$<BOOL:${PROFILE_TCP_TRANSPORT}>,$<PLATFORM_ID:Windows>>:src/c/profile/transport/ip/tcp/tcp_transport_windows.c>
$<$<AND:$<BOOL:${PROFILE_SERIAL_TRANSPORT}>,$<OR:$<PLATFORM_ID:Linux>,$<PLATFORM_ID:Generic>>>:src/c/profile/transport/serial/serial_transport.c>
$<$<AND:$<BOOL:${PROFILE_SERIAL_TRANSPORT}>,$<OR:$<PLATFORM_ID:Linux>,$<PLATFORM_ID:Generic>>>:src/c/profile/transport/serial/serial_protocol.c>
$<$<AND:$<BOOL:${PROFILE_SERIAL_TRANSPORT}>,$<BOOL:${UCLIENT_PLATFORM_POSIX}>>:src/c/profile/transport/serial/serial_transport_posix.c>
$<$<BOOL:${UCLIENT_EXTERNAL_TCP}>:src/c/profile/transport/ip/tcp/tcp_transport_external.c>
$<$<BOOL:${UCLIENT_EXTERNAL_UDP}>:src/c/profile/transport/ip/udp/udp_transport_external.c>
$<$<BOOL:${UCLIENT_EXTERNAL_SERIAL}>:src/c/profile/transport/serial/serial_transport_external.c>
$<$<OR:$<BOOL:${UCLIENT_PLATFORM_POSIX}>,$<BOOL:${UCLIENT_PLATFORM_POSIX_NOPOLL}>>:src/c/profile/transport/ip/ip_posix.c>
$<$<BOOL:$<PLATFORM_ID:Windows>>:src/c/profile/transport/ip/ip_windows.c>
)
###############################################################################
# Set install directories
###############################################################################
if(UCLIENT_ISOLATED_INSTALL)
set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}-${PROJECT_VERSION}")
endif()
include(GNUInstallDirs)
set(BIN_INSTALL_DIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for binaries")
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for C headers")
set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries")
set(DATA_INSTALL_DIR ${CMAKE_INSTALL_DATADIR} CACHE PATH "Installation directory for data")
if(WIN32)
set(LICENSE_INSTALL_DIR . CACHE PATH "Installation directory for licenses")
else()
set(LICENSE_INSTALL_DIR ${DATA_INSTALL_DIR}/${PROJECT_NAME} CACHE PATH "Installation directory for licenses")
endif()
###############################################################################
# Targets
###############################################################################
@ -254,7 +246,7 @@ target_include_directories(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
$<INSTALL_INTERFACE:${INCLUDE_INSTALL_DIR}>
PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src/c>
)
@ -293,8 +285,9 @@ if(UCLIENT_BUILD_EXAMPLES)
add_subdirectory(examples/ShapesDemo)
add_subdirectory(examples/Deployment)
add_subdirectory(examples/Discovery)
add_subdirectory(examples/TimeSync)
add_subdirectory(examples/TimeSyncWithCb)
add_subdirectory(examples/RequestAdder)
add_subdirectory(examples/ReplyAdder)
add_subdirectory(examples/MultiSessionHelloWorld)
endif()
###############################################################################
@ -314,12 +307,12 @@ if(UCLIENT_BUILD_TESTS)
include(CTest)
add_subdirectory(test/unitary)
if(PLATFORM_NAME_LINUX)
if(UCLIENT_PLATFORM_LINUX)
add_subdirectory(test/transport/serial_comm)
endif()
endif()
if(PLATFORM_NAME_LINUX AND UCLIENT_MEMORY_TESTS)
if(UCLIENT_PLATFORM_LINUX AND UCLIENT_MEMORY_TESTS)
add_subdirectory(test/memory/consumption)
endif()
@ -403,12 +396,18 @@ install(
${DATA_INSTALL_DIR}/${PROJECT_NAME}/cmake
)
# Install dependencies
# Install dependencies.
if(EXISTS ${CMAKE_BINARY_DIR}/temp_install/)
install(
DIRECTORY
${CMAKE_BINARY_DIR}/temp_install/
DESTINATION
${CMAKE_INSTALL_PREFIX}
file(GLOB _deps RELATIVE ${CMAKE_BINARY_DIR}/temp_install ${CMAKE_BINARY_DIR}/temp_install/*)
foreach(_d ${_deps})
install(
DIRECTORY
${CMAKE_BINARY_DIR}/temp_install/${_d}$<IF:$<BOOL:${UCLIENT_ISOLATED_INSTALL}>,,/>
DESTINATION
${CMAKE_INSTALL_PREFIX}$<IF:$<BOOL:${UCLIENT_ISOLATED_INSTALL}>,/../,>
COMPONENT
${_d}
USE_SOURCE_PERMISSIONS
)
endforeach()
endif()

View File

@ -18,5 +18,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(MEMORYCHECK_COMMAND_OPTIONS "${MEMORYCHECK_COMMAND_OPTIONS} --quiet --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=50 --xml=yes --xml-file=test_%p_memcheck.xml \"--suppressions=${CMAKE_CURRENT_SOURCE_DIR}/ci/valgrind.supp\"")
# Coverage configuration.
find_program(COVERAGE_COMMAND NAMES gcov)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
find_program(COVERAGE_COMMAND NAMES gcov)
endif()
endif()

View File

@ -16,20 +16,35 @@ cmake_minimum_required(VERSION 3.5.0 FATAL_ERROR)
project(microxrcedds_client_ci LANGUAGES C CXX)
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
message(FATAL_ERROR "Unsupported compiler")
endif()
include(ExternalProject)
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)
set(_c_flags "-fwrapv -fprofile-arcs -ftest-coverage")
set(_cxx_flags "-fwrapv -fprofile-arcs -ftest-coverage")
set(_exe_linker_flags "-fprofile-arcs -ftest-coverage")
set(_shared_linker_flags "-fprofile-arcs -ftest-coverage")
ExternalProject_Add(microxrcedds_client
check_cxx_compiler_flag("-fprofile-abs-path" _have_cxx_fprofile_abs_path)
if(_have_cxx_fprofile_abs_path)
set(_cxx_flags "${_cxx_flags} -fprofile-abs-path")
endif()
check_c_compiler_flag("-fprofile-abs-path" _have_c_fprofile_abs_path)
if(_have_c_fprofile_abs_path)
set(_c_flags "${_c_flags} -fprofile-abs-path")
endif()
ExternalProject_Add(microxrcedds_client_isolated
SOURCE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/../../
BINARY_DIR
${PROJECT_BINARY_DIR}/microxrcedds_client-build
INSTALL_DIR
${PROJECT_BINARY_DIR}/temp_install
${PROJECT_BINARY_DIR}/temp_install/isolated
TEST_AFTER_INSTALL
TRUE
TEST_COMMAND
@ -37,6 +52,8 @@ ExternalProject_Add(microxrcedds_client
COMMAND ${CMAKE_CTEST_COMMAND} -VV -T MemCheck -E "test-case*"
COMMAND ${CMAKE_CTEST_COMMAND} -VV -T Coverage -E "test-case*"
CMAKE_CACHE_ARGS
-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCMAKE_C_FLAGS:STRING=${_c_flags}
-DCMAKE_CXX_FLAGS:STRING=${_cxx_flags}
@ -44,5 +61,39 @@ ExternalProject_Add(microxrcedds_client
-DCMAKE_SHARED_LINKER_FLAGS:STRING=${_shared_linker_flags}
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-DUCLIENT_BUILD_CI_TESTS:BOOL=ON
-DUCLIENT_ISOLATED_INSTALL:BOOL=ON
-DUCLIENT_VERBOSE_SERIALIZATION:BOOL=ON
-DUCLIENT_VERBOSE_MESSAGE:BOOL=ON
-DGTEST_INDIVIDUAL:BOOL=ON
)
ExternalProject_Add(microxrcedds_client_non-isolated
SOURCE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/../../
BINARY_DIR
${PROJECT_BINARY_DIR}/microxrcedds_client-build
INSTALL_DIR
${PROJECT_BINARY_DIR}/temp_install/non-isolated
TEST_AFTER_INSTALL
TRUE
BUILD_COMMAND
""
TEST_COMMAND
COMMAND ${CMAKE_CTEST_COMMAND} -VV -T Test -R "test-case*"
CMAKE_CACHE_ARGS
-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCMAKE_C_FLAGS:STRING=${_c_flags}
-DCMAKE_CXX_FLAGS:STRING=${_cxx_flags}
-DCMAKE_EXE_LINKER_FLAGS:STRING=${_exe_linker_flags}
-DCMAKE_SHARED_LINKER_FLAGS:STRING=${_shared_linker_flags}
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-DUCLIENT_BUILD_CI_TESTS:BOOL=ON
-DUCLIENT_ISOLATED_INSTALL:BOOL=OFF
-DUCLIENT_VERBOSE_SERIALIZATION:BOOL=ON
-DUCLIENT_VERBOSE_MESSAGE:BOOL=ON
-DGTEST_INDIVIDUAL:BOOL=ON
DEPENDS
microxrcedds_client_isolated
)

View File

@ -8,8 +8,8 @@ CONFIG_MAX_OUTPUT_RELIABLE_STREAMS=1
CONFIG_MAX_INPUT_BEST_EFFORT_STREAMS=1
CONFIG_MAX_INPUT_RELIABLE_STREAMS=1
CONFIG_MAX_SESSION_CONNECTION_ATTEMPTS=5
CONFIG_MIN_SESSION_CONNECTION_INTERVAL=500
CONFIG_MAX_SESSION_CONNECTION_ATTEMPTS=10
CONFIG_MIN_SESSION_CONNECTION_INTERVAL=25
CONFIG_MIN_HEARTBEAT_TIME_INTERVAL=1
CONFIG_BIG_ENDIANNESS=FALSE

View File

@ -16,19 +16,25 @@ include(ExternalProject)
unset(_deps)
enable_language(C)
enable_language(CXX)
# Micro CDR.
unset(microcdr_DIR CACHE)
find_package(microcdr ${_microcdr_version} EXACT QUIET)
if(NOT microcdr_FOUND)
ExternalProject_Add(ucdr
ExternalProject_Add(microcdr
GIT_REPOSITORY
https://github.com/eProsima/Micro-CDR.git
GIT_TAG
${_microcdr_tag}
PREFIX
${PROJECT_BINARY_DIR}/ucdr
${PROJECT_BINARY_DIR}/microcdr
INSTALL_DIR
${PROJECT_BINARY_DIR}/temp_install
CMAKE_CACHE_ARGS
-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
CMAKE_ARGS
-DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
@ -38,7 +44,7 @@ if(NOT microcdr_FOUND)
-DCONFIG_BIG_ENDIANNESS=${UCLIENT_BIG_ENDIANNESS}
-DUCDR_PIC=${UCLIENT_PIC}
)
list(APPEND _deps ucdr)
list(APPEND _deps microcdr)
endif()
if(UCLIENT_BUILD_TESTS)
@ -57,7 +63,7 @@ if(UCLIENT_BUILD_TESTS)
PREFIX
${PROJECT_BINARY_DIR}/googletest
INSTALL_DIR
${PROJECT_BINARY_DIR}/temp_install
${PROJECT_BINARY_DIR}/temp_install/googletest
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
$<$<PLATFORM_ID:Windows>:-Dgtest_force_shared_crt:BOOL=ON>
@ -67,8 +73,8 @@ if(UCLIENT_BUILD_TESTS)
INSTALL_COMMAND
""
)
set(GTEST_ROOT ${PROJECT_BINARY_DIR}/temp_install CACHE PATH "" FORCE)
set(GMOCK_ROOT ${PROJECT_BINARY_DIR}/temp_install CACHE PATH "" FORCE)
set(GTEST_ROOT ${PROJECT_BINARY_DIR}/temp_install/googletest CACHE PATH "" FORCE)
set(GMOCK_ROOT ${PROJECT_BINARY_DIR}/temp_install/googletest CACHE PATH "" FORCE)
list(APPEND _deps googletest)
endif()
endif()
@ -85,4 +91,4 @@ ExternalProject_Add(uclient
""
DEPENDS
${_deps}
)
)

11
colcon.pkg Normal file
View File

@ -0,0 +1,11 @@
{
"name": "microxrcedds_client",
"type": "cmake",
"dependencies":[
"microcdr"
],
"cmake-args":[
"-DUCLIENT_ISOLATED_INSTALL=OFF",
"-DUCLIENT_SUPERBUILD=OFF"
]
}

View File

@ -78,7 +78,7 @@ int main(int args, char** argv)
// Transport
uxrUDPTransport transport;
uxrUDPPlatform udp_platform;
if(!uxr_init_udp_transport(&transport, &udp_platform, "127.0.0.1", 2018))
if(!uxr_init_udp_transport(&transport, &udp_platform, UXR_IPv4, "127.0.0.1", "2018"))
{
printf("Error at create transport.\n");
return 1;

View File

@ -38,7 +38,7 @@ int main(int args, char** argv)
// Transport
uxrUDPTransport transport;
uxrUDPPlatform udp_platform;
if(!uxr_init_udp_transport(&transport, &udp_platform, "127.0.0.1", 2018))
if(!uxr_init_udp_transport(&transport, &udp_platform, UXR_IPv4, "127.0.0.1", "2018"))
{
printf("Error at create transport.\n");
return 1;

View File

@ -22,9 +22,16 @@
#define STREAM_HISTORY 8
#define BUFFER_SIZE UXR_CONFIG_UDP_TRANSPORT_MTU * STREAM_HISTORY
void on_topic(uxrSession* session, uxrObjectId object_id, uint16_t request_id, uxrStreamId stream_id, struct ucdrBuffer* ub, void* args)
void on_topic(
uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
uxrStreamId stream_id,
struct ucdrBuffer* ub,
uint16_t length,
void* args)
{
(void) session; (void) object_id; (void) request_id; (void) stream_id; (void) args;
(void) session; (void) object_id; (void) request_id; (void) stream_id; (void) args; (void) length;
HelloWorld topic;
HelloWorld_deserialize_topic(ub, &topic);
@ -46,7 +53,7 @@ int main(int args, char** argv)
// Transport
uxrUDPTransport transport;
uxrUDPPlatform udp_platform;
if(!uxr_init_udp_transport(&transport, &udp_platform, "127.0.0.1", 2018))
if(!uxr_init_udp_transport(&transport, &udp_platform, UXR_IPv4, "127.0.0.1", "2018"))
{
printf("Error at create transport.\n");
return 1;

View File

@ -19,10 +19,33 @@
#define MAX_AGENTS 10
void on_agent_found(const uxrAgentAddress* address, void* args)
bool on_agent_found(const TransportLocator* locator, void* args)
{
(void) args;
printf("Found agent => ip: %s, port: %d\n", address->ip, address->port);
switch (locator->format)
{
case ADDRESS_FORMAT_MEDIUM:
{
char ip[16];
uint16_t port;
uxrIpProtocol ip_protocol;
uxr_locator_to_ip(locator, ip, sizeof(ip), &port, &ip_protocol);
printf("Agent found => ip: %s, port: %d\n", ip, port);
break;
}
case ADDRESS_FORMAT_LARGE:
{
char ip[46];
uint16_t port;
uxrIpProtocol ip_protocol;
uxr_locator_to_ip(locator, ip, sizeof(ip), &port, &ip_protocol);
printf("Agent found => ip: %s, port: %d\n", ip, port);
break;
}
default:
break;
}
return false;
}
int main(int args, char** argv)
@ -43,11 +66,10 @@ int main(int args, char** argv)
else
{
size_t size = 0;
uxrAgentAddress agent_list[MAX_AGENTS];
TransportLocator agent_list[MAX_AGENTS];
for(int i = 1; i < args; i += 2, size++)
{
strcpy(agent_list[size].ip, argv[i]);
agent_list[size++].port = (uint8_t)atoi(argv[i + 1]);
uxr_ip_to_locator(argv[i], (uint16_t)atoi(argv[i + 1]), UXR_IPv4, &agent_list[i++]);
}
uxr_discovery_agents(10, 1000, on_agent_found, NULL, agent_list, size);

View File

@ -0,0 +1,51 @@
# Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 2.8.12)
if (${CMAKE_VERSION} VERSION_GREATER 3.0)
cmake_policy(SET CMP0048 NEW)
endif()
project(MultiSessionHelloWorld)
if(NOT UCLIENT_BUILD_EXAMPLES)
find_package(microxrcedds_client REQUIRED)
endif()
if(NOT PROFILE_UDP_TRANSPORT)
message(WARNING "Can not compile example: The PROFILE_UDP_TRANSPORT must be enabled.")
else()
add_executable(${PROJECT_NAME} main.c HelloWorld.c)
if(MSVC OR MSVC_IDE)
target_compile_options(${PROJECT_NAME} PRIVATE /wd4996)
endif()
set_target_properties(${PROJECT_NAME} PROPERTIES
C_STANDARD 99
C_STANDARD_REQUIRED YES
)
target_link_libraries(${PROJECT_NAME} microxrcedds_client $<$<C_COMPILER_ID:GNU>:-Wl,--gc-section,--no-export-dynamic>)
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION examples/uxr/client/${PROJECT_NAME}/${BIN_INSTALL_DIR}
)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/
DESTINATION examples/uxr/client/${PROJECT_NAME}
FILES_MATCHING PATTERN "*.h"
PATTERN "*.c"
PATTERN "*.idl"
)
endif()

View File

@ -0,0 +1,53 @@
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*!
* @file HelloWorld.c
* This source file contains the definition of the described types in the IDL file.
*
* This file was generated by the tool gen.
*/
#include "HelloWorld.h"
#include <ucdr/microcdr.h>
#include <string.h>
bool HelloWorld_serialize_topic(ucdrBuffer* writer, const HelloWorld* topic)
{
(void) ucdr_serialize_uint32_t(writer, topic->index);
(void) ucdr_serialize_string(writer, topic->message);
return !writer->error;
}
bool HelloWorld_deserialize_topic(ucdrBuffer* reader, HelloWorld* topic)
{
(void) ucdr_deserialize_uint32_t(reader, &topic->index);
(void) ucdr_deserialize_string(reader, topic->message, 255);
return !reader->error;
}
uint32_t HelloWorld_size_of_topic(const HelloWorld* topic, uint32_t size)
{
uint32_t previousSize = size;
size += (uint32_t)(ucdr_alignment(size, 4) + 4);
size += (uint32_t)(ucdr_alignment(size, 4) + 4 + strlen(topic->message) + 1);
return size - previousSize;
}

View File

@ -0,0 +1,55 @@
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*!
* @file HelloWorld.h
* This header file contains the declaration of the described types in the IDL file.
*
* This file was generated by the tool gen.
*/
#ifndef _HelloWorld_H_
#define _HelloWorld_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#include <stdbool.h>
/*!
* @brief This struct represents the structure HelloWorld defined by the user in the IDL file.
* @ingroup HELLOWORLD
*/
typedef struct HelloWorld
{
uint32_t index;
char message[255];
} HelloWorld;
struct ucdrBuffer;
bool HelloWorld_serialize_topic(struct ucdrBuffer* writer, const HelloWorld* topic);
bool HelloWorld_deserialize_topic(struct ucdrBuffer* reader, HelloWorld* topic);
uint32_t HelloWorld_size_of_topic(const HelloWorld* topic, uint32_t size);
#ifdef __cplusplus
}
#endif
#endif // _HelloWorld_H_

View File

@ -0,0 +1,5 @@
struct HelloWorld
{
unsigned long index;
string message;
};

View File

@ -0,0 +1,27 @@
# MultiSessionHelloWorld example
This example will show how to create multiple sessions on the same program. Both session
will have a publisher and a subscriber communicating each other.
In order to compile this example, it is necessary to have the following profiles enabled in `client.config` file:
- `PROFILE_CREATE_ENTITIES_XML`
- `PROFILE_WRITE_ACCESS`
- `PROFILE_UDP_TRANSPORT`
## Usage
1. Run an agent in port *2018*.
2. Run the *MultiSessionHelloWorld* example.
## Topic
The *HelloWorld* topic has the following *IDL* representation:
```
struct HelloWorld
{
unsigned long index;
string message;
};
```

View File

@ -0,0 +1,274 @@
// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "HelloWorld.h"
#include <uxr/client/client.h>
#include <ucdr/microcdr.h>
#include <stdio.h> //printf
#include <string.h> //strcmp
#include <stdlib.h> //atoi
#define STREAM_HISTORY 8
#define BUFFER_SIZE UXR_CONFIG_UDP_TRANSPORT_MTU * STREAM_HISTORY
void on_topic(
uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
uxrStreamId stream_id,
struct ucdrBuffer* ub,
uint16_t length,
void* args)
{
(void) session; (void) object_id; (void) request_id; (void) stream_id; (void) length;
HelloWorld topic;
HelloWorld_deserialize_topic(ub, &topic);
char key[20];
snprintf(key, 20, "0x%X%X%X%X", session->info.key[0], session->info.key[1], session->info.key[2], session->info.key[3]);
printf("Session %s: %s (%i)\n", key, topic.message, topic.index);
}
int main(int args, char** argv)
{
// CLI
if(3 > args || 0 == atoi(argv[2]))
{
printf("usage: program [-h | --help] | ip port [<max_topics>]\n");
return 0;
}
char* ip = argv[1];
char* port = argv[2];
uint32_t max_topics = (args == 4) ? (uint32_t)atoi(argv[3]) : UINT32_MAX;
// ------ SESSION 1 ------
// Transport
uxrUDPTransport transport_1;
uxrUDPPlatform udp_platform_1;
if(!uxr_init_udp_transport(&transport_1, &udp_platform_1, UXR_IPv4, ip, port))
{
printf("Error at create transport.\n");
return 1;
}
// Session
uxrSession session_1;
uxr_init_session(&session_1, &transport_1.comm, 0x11111111);
uxr_set_topic_callback(&session_1, on_topic, NULL);
if(!uxr_create_session(&session_1))
{
printf("Error at create session 1.\n");
return 1;
}
// Streams
uint8_t output_reliable_stream_buffer_1[BUFFER_SIZE];
uxrStreamId reliable_out_1 = uxr_create_output_reliable_stream(&session_1, output_reliable_stream_buffer_1, BUFFER_SIZE, STREAM_HISTORY);
uint8_t input_reliable_stream_buffer_1[BUFFER_SIZE];
uxrStreamId reliable_in_1 = uxr_create_input_reliable_stream(&session_1, input_reliable_stream_buffer_1, BUFFER_SIZE, STREAM_HISTORY);
// Create entities
uxrObjectId participant_id_1 = uxr_object_id(0x01, UXR_PARTICIPANT_ID);
const char* participant_xml_1 = "<dds>"
"<participant>"
"<rtps>"
"<name>default_xrce_participant_1</name>"
"</rtps>"
"</participant>"
"</dds>";
uint16_t participant_req_1 = uxr_buffer_create_participant_xml(&session_1, reliable_out_1, participant_id_1, 0, participant_xml_1, UXR_REPLACE);
uxrObjectId topic_id_1 = uxr_object_id(0x01, UXR_TOPIC_ID);
const char* topic_xml_1 = "<dds>"
"<topic>"
"<name>HelloWorldTopic</name>"
"<dataType>HelloWorld</dataType>"
"</topic>"
"</dds>";
uint16_t topic_req_1 = uxr_buffer_create_topic_xml(&session_1, reliable_out_1, topic_id_1, participant_id_1, topic_xml_1, UXR_REPLACE);
uxrObjectId publisher_id_1 = uxr_object_id(0x01, UXR_PUBLISHER_ID);
const char* publisher_xml_1 = "";
uint16_t publisher_req_1 = uxr_buffer_create_publisher_xml(&session_1, reliable_out_1, publisher_id_1, participant_id_1, publisher_xml_1, UXR_REPLACE);
uxrObjectId datawriter_id_1 = uxr_object_id(0x01, UXR_DATAWRITER_ID);
const char* datawriter_xml_1 = "<dds>"
"<data_writer>"
"<topic>"
"<kind>NO_KEY</kind>"
"<name>HelloWorldTopic_1_to_2</name>"
"<dataType>HelloWorld</dataType>"
"</topic>"
"</data_writer>"
"</dds>";
uint16_t datawriter_req_1 = uxr_buffer_create_datawriter_xml(&session_1, reliable_out_1, datawriter_id_1, publisher_id_1, datawriter_xml_1, UXR_REPLACE);
uxrObjectId subscriber_id_1 = uxr_object_id(0x01, UXR_SUBSCRIBER_ID);
const char* subscriber_xml_1 = "";
uint16_t subscriber_req_1 = uxr_buffer_create_subscriber_xml(&session_1, reliable_out_1, subscriber_id_1, participant_id_1, subscriber_xml_1, UXR_REPLACE);
uxrObjectId datareader_id_1 = uxr_object_id(0x01, UXR_DATAREADER_ID);
const char* datareader_xml_1 = "<dds>"
"<data_reader>"
"<topic>"
"<kind>NO_KEY</kind>"
"<name>HelloWorldTopic_2_to_1</name>"
"<dataType>HelloWorld</dataType>"
"</topic>"
"</data_reader>"
"</dds>";
uint16_t datareader_req_1 = uxr_buffer_create_datareader_xml(&session_1, reliable_out_1, datareader_id_1, subscriber_id_1, datareader_xml_1, UXR_REPLACE);
// Send create entities message and wait its status
uint8_t status_1[6];
uint16_t requests_1[6] = {participant_req_1, topic_req_1, publisher_req_1, datawriter_req_1, subscriber_req_1, datareader_req_1};
if(!uxr_run_session_until_all_status(&session_1, 1000, requests_1, status_1, 6))
{
printf("Error at create entities session 1\n");
return 1;
}
// ------ SESSION 2 ------
// Transport
uxrUDPTransport transport_2;
uxrUDPPlatform udp_platform_2;
if(!uxr_init_udp_transport(&transport_2, &udp_platform_2, UXR_IPv4, ip, port))
{
printf("Error at create transport.\n");
return 1;
}
// Session
uxrSession session_2;
uxr_init_session(&session_2, &transport_2.comm, 0x22222222);
uxr_set_topic_callback(&session_2, on_topic, NULL);
if(!uxr_create_session(&session_2))
{
printf("Error at create session 2.\n");
return 1;
}
// Streams
uint8_t output_reliable_stream_buffer_2[BUFFER_SIZE];
uxrStreamId reliable_out_2 = uxr_create_output_reliable_stream(&session_2, output_reliable_stream_buffer_2, BUFFER_SIZE, STREAM_HISTORY);
uint8_t input_reliable_stream_buffer_2[BUFFER_SIZE];
uxrStreamId reliable_in_2 = uxr_create_input_reliable_stream(&session_2, input_reliable_stream_buffer_2, BUFFER_SIZE, STREAM_HISTORY);
// Create entities
uxrObjectId participant_id_2 = uxr_object_id(0x01, UXR_PARTICIPANT_ID);
const char* participant_xml_2 = "<dds>"
"<participant>"
"<rtps>"
"<name>default_xrce_participant_2</name>"
"</rtps>"
"</participant>"
"</dds>";
uint16_t participant_req_2 = uxr_buffer_create_participant_xml(&session_2, reliable_out_2, participant_id_2, 0, participant_xml_2, UXR_REPLACE);
uxrObjectId topic_id_2 = uxr_object_id(0x01, UXR_TOPIC_ID);
const char* topic_xml_2 = "<dds>"
"<topic>"
"<name>HelloWorldTopic</name>"
"<dataType>HelloWorld</dataType>"
"</topic>"
"</dds>";
uint16_t topic_req_2 = uxr_buffer_create_topic_xml(&session_2, reliable_out_2, topic_id_2, participant_id_2, topic_xml_2, UXR_REPLACE);
uxrObjectId publisher_id_2 = uxr_object_id(0x01, UXR_PUBLISHER_ID);
const char* publisher_xml_2 = "";
uint16_t publisher_req_2 = uxr_buffer_create_publisher_xml(&session_2, reliable_out_2, publisher_id_2, participant_id_2, publisher_xml_2, UXR_REPLACE);
uxrObjectId datawriter_id_2 = uxr_object_id(0x01, UXR_DATAWRITER_ID);
const char* datawriter_xml_2 = "<dds>"
"<data_writer>"
"<topic>"
"<kind>NO_KEY</kind>"
"<name>HelloWorldTopic_2_to_1</name>"
"<dataType>HelloWorld</dataType>"
"</topic>"
"</data_writer>"
"</dds>";
uint16_t datawriter_req_2 = uxr_buffer_create_datawriter_xml(&session_2, reliable_out_2, datawriter_id_2, publisher_id_2, datawriter_xml_2, UXR_REPLACE);
uxrObjectId subscriber_id_2 = uxr_object_id(0x01, UXR_SUBSCRIBER_ID);
const char* subscriber_xml_2 = "";
uint16_t subscriber_req_2 = uxr_buffer_create_subscriber_xml(&session_2, reliable_out_2, subscriber_id_2, participant_id_2, subscriber_xml_2, UXR_REPLACE);
uxrObjectId datareader_id_2 = uxr_object_id(0x01, UXR_DATAREADER_ID);
const char* datareader_xml_2 = "<dds>"
"<data_reader>"
"<topic>"
"<kind>NO_KEY</kind>"
"<name>HelloWorldTopic_1_to_2</name>"
"<dataType>HelloWorld</dataType>"
"</topic>"
"</data_reader>"
"</dds>";
uint16_t datareader_req_2 = uxr_buffer_create_datareader_xml(&session_2, reliable_out_2, datareader_id_2, subscriber_id_2, datareader_xml_2, UXR_REPLACE);
// Send create entities message and wait its status
uint8_t status_2[6];
uint16_t requests_2[6] = {participant_req_2, topic_req_2, publisher_req_2, datawriter_req_2, subscriber_req_2, datareader_req_2};
if(!uxr_run_session_until_all_status(&session_2, 1000, requests_2, status_2, 6))
{
printf("Error at create entities session 2\n");
return 1;
}
// Request topics of both sessions
uxrDeliveryControl delivery_control = {0};
delivery_control.max_samples = UXR_MAX_SAMPLES_UNLIMITED;
uint16_t read_data_req_1 = uxr_buffer_request_data(&session_1, reliable_out_1, datareader_id_1, reliable_in_1, &delivery_control);
uint16_t read_data_req_2 = uxr_buffer_request_data(&session_2, reliable_out_2, datareader_id_2, reliable_in_2, &delivery_control);
// Write topics
uint32_t count = 0;
bool connected = true;
while(connected)
{
// Session 1 publication
HelloWorld topic_1 = {count, "Publisher 1 says hello"};
ucdrBuffer ub_1;
uint32_t topic_size_1 = HelloWorld_size_of_topic(&topic_1, 0);
uxr_prepare_output_stream(&session_1, reliable_out_1, datawriter_id_1, &ub_1, topic_size_1);
HelloWorld_serialize_topic(&ub_1, &topic_1);
// Session 2 publication
HelloWorld topic_2 = {count, "Publisher 2 says hello"};
ucdrBuffer ub_2;
uint32_t topic_size_2 = HelloWorld_size_of_topic(&topic_2, 0);
uxr_prepare_output_stream(&session_2, reliable_out_2, datawriter_id_2, &ub_2, topic_size_2);
HelloWorld_serialize_topic(&ub_2, &topic_2);
connected = uxr_run_session_time(&session_1, 1000);
connected &= uxr_run_session_time(&session_2, 1000);
count++;
}
// Delete resources
uxr_delete_session(&session_1);
uxr_delete_session(&session_2);
uxr_close_udp_transport(&transport_1);
uxr_close_udp_transport(&transport_2);
return 0;
}

View File

@ -34,13 +34,13 @@ int main(int args, char** argv)
}
char* ip = argv[1];
uint16_t port = (uint16_t)atoi(argv[2]);
char* port = argv[2];
uint32_t max_topics = (args == 4) ? (uint32_t)atoi(argv[3]) : UINT32_MAX;
// Transport
uxrUDPTransport transport;
uxrUDPPlatform udp_platform;
if(!uxr_init_udp_transport(&transport, &udp_platform, ip, port))
if(!uxr_init_udp_transport(&transport, &udp_platform, UXR_IPv4, ip, port))
{
printf("Error at create transport.\n");
return 1;

View File

@ -34,13 +34,13 @@ int main(int args, char** argv)
}
char* ip = argv[1];
uint16_t port = (uint16_t)atoi(argv[2]);
char* port = argv[2];
uint32_t max_topics = (args == 4) ? (uint32_t)atoi(argv[3]) : UINT32_MAX;
// Transport
uxrUDPTransport transport;
uxrUDPPlatform udp_platform;
if(!uxr_init_udp_transport(&transport, &udp_platform, ip, port))
if(!uxr_init_udp_transport(&transport, &udp_platform, UXR_IPv4, ip, port))
{
printf("Error at create transport.\n");
return 1;

View File

@ -0,0 +1,52 @@
# Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.5.0 FATAL_ERROR)
project(ReplyAdder)
if(NOT PROFILE_UDP_TRANSPORT)
message(WARNING "Can not compile example: the PROFILE_UDP_TRANSPORT must be enables.")
else()
add_executable(${PROJECT_NAME} main.c)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_compile_options(${PROJECT_NAME} PRIVATE /wd4996)
endif()
set_target_properties(${PROJECT_NAME} PROPERTIES
C_STANDARD
99
C_STANDARD_REQUIRED
YES
)
target_link_libraries(${PROJECT_NAME}
PRIVATE
microxrcedds_client
)
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION
examples/uxr/client/${PROJECT_NAME}/${BIN_INSTALL_DIR}
)
install(DIRECTORY ${PROJECT_SOURCE_DIR}
DESTINATION
examples/uxr/client/${PROJECT_NAME}
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.c"
PATTERN "*.idl"
)
endif()

147
examples/ReplyAdder/main.c Normal file
View File

@ -0,0 +1,147 @@
// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <uxr/client/client.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#define STREAM_HISTORY 8
#define BUFFER_SIZE UXR_CONFIG_UDP_TRANSPORT_MTU * STREAM_HISTORY
static uxrStreamId reliable_out;
static uxrStreamId reliable_in;
static uxrObjectId participant_id;
static uxrObjectId replier_id;
void on_request(
uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
SampleIdentity* sample_id,
ucdrBuffer* ub,
uint16_t length,
void* args)
{
(void) object_id;
(void) request_id;
(void) length;
uint32_t rhs;
uint32_t lhs;
ucdr_deserialize_uint32_t(ub, &rhs);
ucdr_deserialize_uint32_t(ub, &lhs);
printf("Request received: (%d + %d)\n", rhs, lhs);
uint8_t reply_buffer[8] = {0};
ucdrBuffer reply_ub;
ucdr_init_buffer(&reply_ub, reply_buffer, sizeof(reply_buffer));
ucdr_serialize_uint64_t(&reply_ub, rhs + lhs);
uxr_buffer_reply(session, reliable_out, replier_id, sample_id, reply_buffer, sizeof(reply_buffer));
#ifdef WIN32
printf("Reply send: %I64u\n", (uint64_t)(rhs + lhs));
#else
printf("Reply send: %" PRIu64 "\n", (uint64_t)(rhs + lhs));
#endif
}
int main(int args, char** argv)
{
if(3 > args || 0 == atoi(argv[2]))
{
printf("usage: program [-h | --help] | ip port [key]\n");
return 0;
}
char* ip = argv[1];
char* port = argv[2];
uint32_t key = (args == 4) ? (uint32_t)atoi(argv[3]) : 0xCCCCDDDD;
// Transport
uxrUDPTransport transport;
uxrUDPPlatform udp_platform;
if (!uxr_init_udp_transport(&transport, &udp_platform, UXR_IPv4, ip, port))
{
printf("Error at init transport.\n");
return 1;
}
// Session
uxrSession session;
uxr_init_session(&session, &transport.comm, key);
uxr_set_request_callback(&session, on_request, 0);
if (!uxr_create_session(&session))
{
printf("Error at init session.\n");
return 1;
}
// Streams
uint8_t output_reliable_stream_buffer[BUFFER_SIZE];
reliable_out = uxr_create_output_reliable_stream(&session, output_reliable_stream_buffer, BUFFER_SIZE, STREAM_HISTORY);
uint8_t input_reliable_stream_buffer[BUFFER_SIZE];
reliable_in = uxr_create_input_reliable_stream(&session, input_reliable_stream_buffer, BUFFER_SIZE, STREAM_HISTORY);
// Create entities
participant_id = uxr_object_id(0x01, UXR_PARTICIPANT_ID);
const char* participant_xml = "<dds>"
"<participant>"
"<rtps>"
"<name>default_xrce_participant</name>"
"</rtps>"
"</participant>"
"</dds>";
uint16_t participant_req = uxr_buffer_create_participant_xml(&session, reliable_out, participant_id, 0, participant_xml, UXR_REPLACE);
replier_id = uxr_object_id(0x01, UXR_REPLIER_ID);
const char* replier_xml = "<dds>"
"<replier profile_name=\"my_requester\""
"service_name=\"service_name\""
"request_type=\"request_type\""
"reply_type=\"reply_type\">"
"</replier>"
"</dds>";
uint16_t replier_req = uxr_buffer_create_replier_xml(&session, reliable_out, replier_id, participant_id, replier_xml, UXR_REPLACE);
// Send create entities message and wait its status
uint8_t status[2];
uint16_t requests[2] = {participant_req, replier_req};
if(!uxr_run_session_until_all_status(&session, 1000, requests, status, 2))
{
printf("Error at create entities: participant: %i requester: %i\n", status[0], status[1]);
return 1;
}
// Request requests
uxrDeliveryControl delivery_control = {0};
delivery_control.max_samples = UXR_MAX_SAMPLES_UNLIMITED;
uint16_t read_data_req = uxr_buffer_request_data(&session, reliable_out, replier_id, reliable_in, &delivery_control);
// Read request
bool connected = true;
while (connected)
{
uint8_t read_data_status;
connected = uxr_run_session_until_all_status(&session, UXR_TIMEOUT_INF, &read_data_req, &read_data_status, 1);
}
return 0;
}

View File

@ -0,0 +1,52 @@
# Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.5.0 FATAL_ERROR)
project(RequestAdder)
if(NOT PROFILE_UDP_TRANSPORT)
message(WARNING "Can not compile example: the PROFILE_UDP_TRANSPORT must be enables.")
else()
add_executable(${PROJECT_NAME} main.c)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_compile_options(${PROJECT_NAME} PRIVATE /wd4996)
endif()
set_target_properties(${PROJECT_NAME} PROPERTIES
C_STANDARD
99
C_STANDARD_REQUIRED
YES
)
target_link_libraries(${PROJECT_NAME}
PRIVATE
microxrcedds_client
)
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION
examples/uxr/client/${PROJECT_NAME}/${BIN_INSTALL_DIR}
)
install(DIRECTORY ${PROJECT_SOURCE_DIR}
DESTINATION
examples/uxr/client/${PROJECT_NAME}
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.c"
PATTERN "*.idl"
)
endif()

View File

@ -0,0 +1,141 @@
// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <uxr/client/client.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#define STREAM_HISTORY 8
#define BUFFER_SIZE UXR_CONFIG_UDP_TRANSPORT_MTU * STREAM_HISTORY
void on_reply(
uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
uint16_t reply_id,
ucdrBuffer* ub,
uint16_t length,
void* args)
{
(void) object_id;
(void) request_id;
(void) length;
uint64_t result;
ucdr_deserialize_uint64_t(ub, &result);
#ifdef WIN32
printf("Reply received: %I64u [id: %d]\n", result, reply_id);
#else
printf("Reply received: %" PRIu64 " [id: %d]\n", result, reply_id);
#endif
}
int main(int args, char** argv)
{
if(3 > args || 0 == atoi(argv[2]))
{
printf("usage: program [-h | --help] | ip port [key]\n");
return 0;
}
char* ip = argv[1];
char* port = argv[2];
uint32_t key = (args == 4) ? (uint32_t)atoi(argv[3]) : 0xAAAABBBB;
// Transport
uxrUDPTransport transport;
uxrUDPPlatform udp_platform;
if (!uxr_init_udp_transport(&transport, &udp_platform, UXR_IPv4, ip, port))
{
printf("Error at init transport.\n");
return 1;
}
// Session
uxrSession session;
uxr_init_session(&session, &transport.comm, key);
uxr_set_reply_callback(&session, on_reply, false);
if (!uxr_create_session(&session))
{
printf("Error at init session.\n");
return 1;
}
// Streams
uint8_t output_reliable_stream_buffer[BUFFER_SIZE];
uxrStreamId reliable_out = uxr_create_output_reliable_stream(&session, output_reliable_stream_buffer, BUFFER_SIZE, STREAM_HISTORY);
uint8_t input_reliable_stream_buffer[BUFFER_SIZE];
uxrStreamId reliable_in = uxr_create_input_reliable_stream(&session, input_reliable_stream_buffer, BUFFER_SIZE, STREAM_HISTORY);
// Create entities
uxrObjectId participant_id = uxr_object_id(0x01, UXR_PARTICIPANT_ID);
const char* participant_xml = "<dds>"
"<participant>"
"<rtps>"
"<name>default_xrce_participant</name>"
"</rtps>"
"</participant>"
"</dds>";
uint16_t participant_req = uxr_buffer_create_participant_xml(&session, reliable_out, participant_id, 0, participant_xml, UXR_REPLACE);
uxrObjectId requester_id = uxr_object_id(0x01, UXR_REQUESTER_ID);
const char* requester_xml = "<dds>"
"<requester profile_name=\"my_requester\""
"service_name=\"service_name\""
"request_type=\"request_type\""
"reply_type=\"reply_type\">"
"</requester>"
"</dds>";
uint16_t requester_req = uxr_buffer_create_requester_xml(&session, reliable_out, requester_id, participant_id, requester_xml, UXR_REPLACE);
// Send create entities message and wait its status
uint8_t status[2];
uint16_t requests[2] = {participant_req, requester_req};
if(!uxr_run_session_until_all_status(&session, 1000, requests, status, 2))
{
printf("Error at create entities: participant: %i requester: %i\n", status[0], status[1]);
return 1;
}
// Request replies
uxrDeliveryControl delivery_control = {0};
delivery_control.max_samples = UXR_MAX_SAMPLES_UNLIMITED;
uint16_t read_data_req = uxr_buffer_request_data(&session, reliable_out, requester_id, reliable_in, &delivery_control);
// Write requests
bool connected = true;
uint32_t count = 0;
while (connected)
{
uint8_t request[2 * 4] = {0};
ucdrBuffer ub;
ucdr_init_buffer(&ub, request, sizeof(request));
ucdr_serialize_uint32_t(&ub, count);
ucdr_serialize_uint32_t(&ub, count);
uint16_t request_id = uxr_buffer_request(&session, reliable_out, requester_id, request, sizeof(request));
printf("Request sent: (%d + %d) [id: %d]\n", count, count, request_id);
connected = uxr_run_session_time(&session, 1000);
++count;
}
return 0;
}

View File

@ -51,7 +51,7 @@ static bool compute_command(uxrSession* session, uxrStreamId* stream_id, int len
uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t arg5, const char* topic_color);
static bool compute_print_command(uxrSession* session, uxrStreamId* stream_id, int length, const char* name,
uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t arg5, const char* topic_color);
static void on_topic(uxrSession* session, uxrObjectId object_id, uint16_t request_id, uxrStreamId stream_id, struct ucdrBuffer* serialization, void* args);
static void on_topic(uxrSession* session, uxrObjectId object_id, uint16_t request_id, uxrStreamId stream_id, struct ucdrBuffer* serialization, uint16_t length, void* args);
static void on_status(uxrSession* session, uxrObjectId object_id, uint16_t request_id, uint8_t status, void* args);
static void print_ShapeType_topic(const ShapeType* topic);
static void print_status(uint8_t status);
@ -75,30 +75,56 @@ int main(int args, char** argv)
int args_index = 0;
if(args >= 4 && strcmp(argv[1], "--udp") == 0)
if(args >= 4 && strcmp(argv[1], "--udp4") == 0)
{
char* ip = argv[2];
uint16_t port = (uint16_t)atoi(argv[3]);
if(!uxr_init_udp_transport(&udp, &udp_platform, ip, port))
char* port = argv[3];
if(!uxr_init_udp_transport(&udp, &udp_platform, UXR_IPv4, ip, port))
{
printf("%sCan not create an udp connection%s\n", RED_CONSOLE_COLOR, RESTORE_COLOR);
return 1;
}
comm = &udp.comm;
printf("Running in UDP mode => ip: %s, port: %hu\n", argv[2], port);
printf("Running in UDP/IPv4 mode => ip: %s, port: %s\n", ip, port);
args_index = 4;
}
else if(args >= 4 && strcmp(argv[1], "--tcp") == 0)
else if(args >= 4 && strcmp(argv[1], "--udp6") == 0)
{
char* ip = argv[2];
uint16_t port = (uint16_t)atoi(argv[3]);
if(!uxr_init_tcp_transport(&tcp, &tcp_platform, ip, port))
char* port = argv[3];
if(!uxr_init_udp_transport(&udp, &udp_platform, UXR_IPv6, ip, port))
{
printf("%sCan not create an udp connection%s\n", RED_CONSOLE_COLOR, RESTORE_COLOR);
return 1;
}
comm = &udp.comm;
printf("Running in UDP/IPv6 mode => ip: %s, port: %s\n", ip, port);
args_index = 4;
}
else if(args >= 4 && strcmp(argv[1], "--tcp4") == 0)
{
char* ip = argv[2];
char* port = argv[3];
if(!uxr_init_tcp_transport(&tcp, &tcp_platform, UXR_IPv4, ip, port))
{
printf("%sCan not create a tcp connection%s\n", RED_CONSOLE_COLOR, RESTORE_COLOR);
return 1;
}
comm = &tcp.comm;
printf("Running TCP mode => ip: %s, port: %hu\n", argv[2], port);
printf("Running TCP mode => ip: %s, port: %s\n", ip, port);
args_index = 4;
}
else if(args >= 4 && strcmp(argv[1], "--tcp6") == 0)
{
char* ip = argv[2];
char* port = argv[3];
if(!uxr_init_tcp_transport(&tcp, &tcp_platform, UXR_IPv6, ip, port))
{
printf("%sCan not create a tcp connection%s\n", RED_CONSOLE_COLOR, RESTORE_COLOR);
return 1;
}
comm = &tcp.comm;
printf("Running TCP mode => ip: %s, port: %s\n", ip, port);
args_index = 4;
}
#if !defined(WIN32)
@ -377,9 +403,16 @@ void on_status(uxrSession* session, uxrObjectId object_id, uint16_t request_id,
print_status(status);
}
void on_topic(uxrSession* session, uxrObjectId object_id, uint16_t request_id, uxrStreamId stream_id, struct ucdrBuffer* serialization, void* args)
void on_topic(
uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
uxrStreamId stream_id,
struct ucdrBuffer* serialization,
uint16_t length,
void* args)
{
(void) session; (void) object_id; (void) request_id; (void) stream_id; (void) serialization; (void) args;
(void) session; (void) object_id; (void) request_id; (void) stream_id; (void) serialization; (void) args; (void) length;
ShapeType topic;
ShapeType_deserialize_topic(serialization, &topic);
@ -462,8 +495,10 @@ void print_help(void)
printf(" program <transport> [--key <number>] [--history <number>]\n");
printf("List of available transports:\n");
printf(" --serial <device>\n");
printf(" --udp <agent-ip> <agent-port>\n");
printf(" --tcp <agent-ip> <agent-port>\n");
printf(" --udp4 <agent-ip> <agent-port>\n");
printf(" --udp6 <agent-ip> <agent-port>\n");
printf(" --tcp4 <agent-ip> <agent-port>\n");
printf(" --tcp6 <agent-ip> <agent-port>\n");
}
void print_commands(void)

View File

@ -23,9 +23,16 @@
#define STREAM_HISTORY 8
#define BUFFER_SIZE UXR_CONFIG_UDP_TRANSPORT_MTU * STREAM_HISTORY
void on_topic(uxrSession* session, uxrObjectId object_id, uint16_t request_id, uxrStreamId stream_id, struct ucdrBuffer* ub, void* args)
void on_topic(
uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
uxrStreamId stream_id,
struct ucdrBuffer* ub,
uint16_t length,
void* args)
{
(void) session; (void) object_id; (void) request_id; (void) stream_id;
(void) session; (void) object_id; (void) request_id; (void) stream_id; (void) length;
HelloWorld topic;
HelloWorld_deserialize_topic(ub, &topic);
@ -46,7 +53,7 @@ int main(int args, char** argv)
}
char* ip = argv[1];
uint16_t port = (uint16_t)atoi(argv[2]);
char* port = argv[2];
uint32_t max_topics = (args == 4) ? (uint32_t)atoi(argv[3]) : UINT32_MAX;
// State
@ -55,7 +62,7 @@ int main(int args, char** argv)
// Transport
uxrUDPTransport transport;
uxrUDPPlatform udp_platform;
if(!uxr_init_udp_transport(&transport, &udp_platform, ip, port))
if(!uxr_init_udp_transport(&transport, &udp_platform, UXR_IPv4, ip, port))
{
printf("Error at create transport.\n");
return 1;

View File

@ -23,9 +23,16 @@
#define STREAM_HISTORY 8
#define BUFFER_SIZE UXR_CONFIG_UDP_TRANSPORT_MTU * STREAM_HISTORY
void on_topic(uxrSession* session, uxrObjectId object_id, uint16_t request_id, uxrStreamId stream_id, struct ucdrBuffer* ub, void* args)
void on_topic(
uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
uxrStreamId stream_id,
struct ucdrBuffer* ub,
uint16_t length,
void* args)
{
(void) session; (void) object_id; (void) request_id; (void) stream_id;
(void) session; (void) object_id; (void) request_id; (void) stream_id; (void) length;
HelloWorld topic;
HelloWorld_deserialize_topic(ub, &topic);
@ -46,7 +53,7 @@ int main(int args, char** argv)
}
char* ip = argv[1];
uint16_t port = (uint16_t)atoi(argv[2]);
char* port = argv[2];
uint32_t max_topics = (args == 4) ? (uint32_t)atoi(argv[3]) : UINT32_MAX;
// State
@ -55,7 +62,7 @@ int main(int args, char** argv)
// Transport
uxrUDPTransport transport;
uxrUDPPlatform udp_platform;
if(!uxr_init_udp_transport(&transport, &udp_platform, ip, port))
if(!uxr_init_udp_transport(&transport, &udp_platform, UXR_IPv4, ip, port))
{
printf("Error at create transport.\n");
return 1;

View File

@ -26,9 +26,18 @@
#cmakedefine PROFILE_TCP_TRANSPORT
#cmakedefine PROFILE_SERIAL_TRANSPORT
#cmakedefine PLATFORM_NAME_LINUX
#cmakedefine PLATFORM_NAME_WINDOWS
#cmakedefine PLATFORM_NAME_NUTTX
#cmakedefine UCLIENT_PLATFORM_LINUX
#cmakedefine UCLIENT_PLATFORM_WINDOWS
#cmakedefine UCLIENT_PLATFORM_NUTTX
#cmakedefine UCLIENT_PLATFORM_POSIX_NOPOLL
#cmakedefine UCLIENT_EXTERNAL_TCP
#cmakedefine UCLIENT_EXTERNAL_UDP
#cmakedefine UCLIENT_EXTERNAL_SERIAL
#if defined(UCLIENT_PLATFORM_LINUX) || defined(UCLIENT_PLATFORM_NUTTX)
#define UCLIENT_PLATFORM_POSIX
#endif
#define UXR_CONFIG_MAX_OUTPUT_BEST_EFFORT_STREAMS @CONFIG_MAX_OUTPUT_BEST_EFFORT_STREAMS@
#define UXR_CONFIG_MAX_OUTPUT_RELIABLE_STREAMS @CONFIG_MAX_OUTPUT_RELIABLE_STREAMS@

View File

@ -118,6 +118,56 @@ UXRDLLAPI uint16_t uxr_buffer_create_datareader_ref(
const char* ref,
uint8_t mode);
/**
* @brief Buffers into the stream identified by `stream_id` an XRCE CREATE submessage with an XRCE Requester payload.
* The submessage will be sent when `uxr_flag_output_streams` or `uxr_run_session` functions are called.
* As a result of the reception of this submessage, the Agent will create an XRCE Requester according to
* the reference provided in the CREATE submessage.
*
* @param session A uxrSession structure previously initialized.
* @param stream_id The output stream identifier where the CREATE submessage will be buffered.
* @param object_id The identifier of the XRCE Requester.
* @param participant_id The identifier of the associated XRCE Participant.
* @param ref The reference of the XRCE Requester.
* @param mode The set of flags that determines the entitiy creation mode.
* the Creation Mode Table describes the entities creation behaviour according to the
* `UXR_REUSE` and `UXR_REPLACE` flags.
* @return A `request_id` that identifies the request made by the Client.
* This could be used in the `uxr_run_session_until_one_status` or `uxr_run_session_until_all_status` functions.
*/
UXRDLLAPI uint16_t uxr_buffer_create_requester_ref(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId object_id,
uxrObjectId participant_id,
const char* ref,
uint8_t mode);
/**
* @brief Buffers into the stream identified by `stream_id` an XRCE CREATE submessage with an XRCE Replier payload.
* The submessage will be sent when `uxr_flag_output_streams` or `uxr_run_session` functions are called.
* As a result of the reception of this submessage, the Agent will create an XRCE Replier according to
* the reference provided in the CREATE submessage.
*
* @param session A uxrSession structure previously initialized.
* @param stream_id The output stream identifier where the CREATE submessage will be buffered.
* @param object_id The identifier of the XRCE Requester.
* @param participant_id The identifier of the associated XRCE Participant.
* @param ref The reference of the XRCE Replier.
* @param mode The set of flags that determines the entitiy creation mode.
* the Creation Mode Table describes the entities creation behaviour according to the
* `UXR_REUSE` and `UXR_REPLACE` flags.
* @return A `request_id` that identifies the request made by the Client.
* This could be used in the `uxr_run_session_until_one_status` or `uxr_run_session_until_all_status` functions.
*/
UXRDLLAPI uint16_t uxr_buffer_create_replier_ref(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId object_id,
uxrObjectId participant_id,
const char* ref,
uint8_t mode);
#ifdef __cplusplus
}
#endif

View File

@ -166,6 +166,56 @@ UXRDLLAPI uint16_t uxr_buffer_create_datareader_xml(
const char* xml,
uint8_t mode);
/**
* @brief Buffers into the stream identified by `stream_id` an XRCE CREATE submessage with an XRCE Requester payload.
* The submessage will be sent when `uxr_flag_output_streams` or `uxr_run_session` functions are called.
* As a result of the reception of this submessage, the Agent will create an XRCE Requester according to
* the reference provided in the CREATE submessage.
*
* @param session A uxrSession structure previously initialized.
* @param stream_id The output stream identifier where the CREATE submessage will be buffered.
* @param object_id The identifier of the XRCE Requester.
* @param participant_id The identifier of the associated XRCE Participant.
* @param xml The XML that describes XRCE Requester.
* @param mode The set of flags that determines the entitiy creation mode.
* the Creation Mode Table describes the entities creation behaviour according to the
* `UXR_REUSE` and `UXR_REPLACE` flags.
* @return A `request_id` that identifies the request made by the Client.
* This could be used in the `uxr_run_session_until_one_status` or `uxr_run_session_until_all_status` functions.
*/
UXRDLLAPI uint16_t uxr_buffer_create_requester_xml(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId object_id,
uxrObjectId participant_id,
const char* xml,
uint8_t mode);
/**
* @brief Buffers into the stream identified by `stream_id` an XRCE CREATE submessage with an XRCE Replier payload.
* The submessage will be sent when `uxr_flag_output_streams` or `uxr_run_session` functions are called.
* As a result of the reception of this submessage, the Agent will create an XRCE Replier according to
* the reference provided in the CREATE submessage.
*
* @param session A uxrSession structure previously initialized.
* @param stream_id The output stream identifier where the CREATE submessage will be buffered.
* @param object_id The identifier of the XRCE Requester.
* @param participant_id The identifier of the associated XRCE Participant.
* @param xml The XML that describes the XRCE Replier.
* @param mode The set of flags that determines the entitiy creation mode.
* the Creation Mode Table describes the entities creation behaviour according to the
* `UXR_REUSE` and `UXR_REPLACE` flags.
* @return A `request_id` that identifies the request made by the Client.
* This could be used in the `uxr_run_session_until_one_status` or `uxr_run_session_until_all_status` functions.
*/
UXRDLLAPI uint16_t uxr_buffer_create_replier_xml(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId object_id,
uxrObjectId participant_id,
const char* xml,
uint8_t mode);
#ifdef __cplusplus
}
#endif

View File

@ -30,6 +30,8 @@ extern "C"
#define UXR_SUBSCRIBER_ID 0x04
#define UXR_DATAWRITER_ID 0x05
#define UXR_DATAREADER_ID 0x06
#define UXR_REQUESTER_ID 0x07
#define UXR_REPLIER_ID 0x08
#define UXR_OTHER_ID 0x0F
typedef struct uxrObjectId

View File

@ -22,31 +22,54 @@ extern "C"
#include <uxr/client/core/session/session_info.h>
#include <uxr/client/core/session/stream/stream_storage.h>
#include <uxr/client/core/type/xrce_types.h>
#define UXR_TIMEOUT_INF -1
struct uxrSession;
struct uxrCommunication;
typedef void (*uxrOnStatusFunc) (struct uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
uint8_t status,
void* args);
typedef void (*uxrOnStatusFunc) (
struct uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
uint8_t status,
void* args);
typedef void (*uxrOnTopicFunc) (struct uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
uxrStreamId stream_id,
struct ucdrBuffer* ub,
void* args);
typedef void (*uxrOnTopicFunc) (
struct uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
uxrStreamId stream_id,
struct ucdrBuffer* ub,
uint16_t length,
void* args);
typedef void (*uxrOnTimeFunc) (struct uxrSession* session,
int64_t current_timestamp,
int64_t transmit_timestamp,
int64_t received_timestamp,
int64_t originate_timestamp,
void* args);
typedef void (*uxrOnTimeFunc) (
struct uxrSession* session,
int64_t current_timestamp,
int64_t transmit_timestamp,
int64_t received_timestamp,
int64_t originate_timestamp,
void* args);
typedef void (*uxrOnRequestFunc) (
struct uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
SampleIdentity* sample_id,
struct ucdrBuffer* ub,
uint16_t length,
void* args);
typedef void (*uxrOnReplyFunc) (
struct uxrSession* session,
uxrObjectId object_id,
uint16_t request_id,
uint16_t reply_id,
struct ucdrBuffer* ub,
uint16_t length,
void* args);
#ifdef PERFORMANCE_TESTING
typedef void (*uxrOnPerformanceFunc) (struct uxrSession* session, struct ucdrBuffer* mb, void* args);
@ -73,6 +96,12 @@ typedef struct uxrSession
int64_t time_offset;
bool synchronized;
uxrOnRequestFunc on_request;
void* on_request_args;
uxrOnReplyFunc on_reply;
void* on_reply_args;
#ifdef PERFORMANCE_TESTING
uxrOnPerformanceFunc on_performance;
void* on_performance_args;
@ -97,7 +126,7 @@ UXRDLLAPI void uxr_init_session(
* This is called when a status message is received from the Agent.
* @param session A uxrSession structure previously initialized.
* @param on_status_func The function that will be called when a valid status message arrives from the Agent.
* @param args User pointer data. The args will be provided to `on_status_func` function.
* @param args User pointer data. The args will be provided to the `on_status_func` callback.
*/
UXRDLLAPI void uxr_set_status_callback(
uxrSession* session,
@ -107,10 +136,10 @@ UXRDLLAPI void uxr_set_status_callback(
/**
* @brief Sets the topic callback.
* This is called when a topic is received from the Agent.
* The topics will be received only if a `request_data` function has been called.
* The topics will be received only if a `request_data` function has been called with a `DataReader` object id.
* @param session A uxrSession structure previously initialized.
* @param on_topic_func The function that will be called when a valid data message arrives from the Agent.
* @param args User pointer data. The args will be provided to `on_topic_func` function.
* @param args User pointer data. The args will be provided to the `on_topic_func` callback.
*/
UXRDLLAPI void uxr_set_topic_callback(
uxrSession* session,
@ -123,13 +152,42 @@ UXRDLLAPI void uxr_set_topic_callback(
* The user could use this callback to implement her/his own time synchronization protocol.
* @param session A uxrSession structure previously initialized.
* @param on_time_func The function that will be called when a TIMESTAMP_REPLY submessage arrives from the Agent.
* @param args A user pointer data. The args will be provided to `on_time_func` function.
* @param args A user pointer data. The args will be provided to the `on_time_func` callback.
*/
UXRDLLAPI void uxr_set_time_callback(
uxrSession* session,
uxrOnTimeFunc on_time_func,
void* args);
/**
* @brief Sets the request callback.
* It will be called when a request is received from the Agent.
* The requests will be received only if a `request_data` function has been called with a `Requester` object id.
*
* @param session A uxrSession structure previously initialized.
* @param on_request_func The function that will be called when a valid request message arrives from the Agent.
* @param args User pointer data. The args will be provided to the `on_request_func` callback.
*/
UXRDLLAPI void uxr_set_request_callback(
uxrSession* session,
uxrOnRequestFunc on_request_func,
void* args);
/**
* @brief Sets the reply callback.
* It will be called when a reply is received from the Agent.
* The reply will be received only if a `request_data` function has been called with a `Replier` object id.
*
* @param session A uxrSession structure previosly initialized.
* @param on_reply_func The function that will be called when a valid reply message arrives from the Agent.
* @param args User pointer data. The args will be provided to the `on_reply_func` callback.
* @return UXRDLLAPI uxr_set_reply_callback
*/
UXRDLLAPI void uxr_set_reply_callback(
uxrSession* session,
uxrOnReplyFunc on_reply_func,
void* args);
#ifdef PERFORMANCE_TESTING
UXRDLLAPI void uxr_set_performance_callback(uxrSession* session, uxrOnPerformanceFunc on_performance_func, void* args);
#endif
@ -231,6 +289,20 @@ UXRDLLAPI bool uxr_run_session_time(
uxrSession* session,
int time);
/**
* @brief Keeps communication between the Client and the Agent.
* This function involves the following actions:
* 1. flashing all the output streams sending the data through the transport,
* 2. listening messages from the Agent calling the associated callback (topic and status).
* The aforementioned actions will be performed in a loop until the `timeout` is exceeded.
* @param session A uxrSession structure previously initialized.
* @param timeout The waiting time in milliseconds.
* @return `true` in case of the Agent confirms the reception of all the output messages. `false` in other case.
*/
UXRDLLAPI bool uxr_run_session_timeout(
uxrSession* session,
int timeout);
/**
* @brief Keeps communication between the Client and the Agent.
* This function involves the following actions:

View File

@ -1,4 +1,4 @@
// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima).
// Copyright 2017-present Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -12,18 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _UXR_CLIENT_CORE_SESSION_STREAM_INPUT_RELIABLE_STREAM_H_
#define _UXR_CLIENT_CORE_SESSION_STREAM_INPUT_RELIABLE_STREAM_H_
#ifndef UXR__CLIENT__CORE__SESSION__STREAM__INPUT_RELIABLE_STREAM_H_
#define UXR__CLIENT__CORE__SESSION__STREAM__INPUT_RELIABLE_STREAM_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <uxr/client/core/session/stream/reliable_stream.h>
#include <uxr/client/core/session/stream/seq_num.h>
#include <stdbool.h>
#include <stddef.h>
struct ucdrBuffer;
@ -39,19 +39,19 @@ typedef FragmentationInfo (*OnGetFragmentationInfo)(uint8_t* buffer);
typedef struct uxrInputReliableStream
{
uint8_t* buffer;
size_t size;
uint16_t history;
uxrReliableStream base;
uxrSeqNum last_handled;
uxrSeqNum last_announced;
OnGetFragmentationInfo on_get_fragmentation_info;
bool cleanup_flag;
} uxrInputReliableStream;
#ifdef __cplusplus
}
#endif
#endif // _UXR_CLIENT_CORE_SESSION_STREAM_INPUT_RELIABLE_STREAM_H_
#endif // UXR__CLIENT__CORE__SESSION__STREAM__INPUT_RELIABLE_STREAM_H_

View File

@ -1,4 +1,4 @@
// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima).
// Copyright 2017-present Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -12,17 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _UXR_CLIENT_CORE_SESSION_STREAM_OUTPUT_RELIABLE_STREAM_H_
#define _UXR_CLIENT_CORE_SESSION_STREAM_OUTPUT_RELIABLE_STREAM_H_
#ifndef UXR__CLIENT__CORE__SESSION__STREAM__OUTPUT_RELIABLE_STREAM_H_
#define UXR__CLIENT__CORE__SESSION__STREAM__OUTPUT_RELIABLE_STREAM_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <uxr/client/core/session/stream/reliable_stream.h>
#include <uxr/client/core/session/stream/seq_num.h>
#include <stddef.h>
#include <stdbool.h>
struct ucdrBuffer;
@ -32,9 +32,7 @@ typedef void (*OnNewFragment)(struct ucdrBuffer* ub, struct uxrOutputReliableStr
typedef struct uxrOutputReliableStream
{
uint8_t* buffer;
size_t size;
uint16_t history;
uxrReliableStream base;
uint8_t offset;
uxrSeqNum last_written;
@ -45,12 +43,10 @@ typedef struct uxrOutputReliableStream
uint8_t next_heartbeat_tries;
bool send_lost;
OnNewFragment on_new_fragment;
} uxrOutputReliableStream;
#ifdef __cplusplus
}
#endif
#endif // _UXR_CLIENT_CORE_SESSION_STREAM_OUTPUT_RELIABLE_STREAM_H_
#endif // UXR__CLIENT__CORE__SESSION__STREAM__OUTPUT_RELIABLE_STREAM_H_

View File

@ -0,0 +1,38 @@
// Copyright 2017-present Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef UXR__CLIENT__CORE__SESSION__STREAM__RELIABLE_STREAM_H_
#define UXR__CLIENT__CORE__SESSION__STREAM__RELIABLE_STREAM_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#include <stddef.h>
typedef struct uxrReliableStream
{
uint8_t * buffer;
size_t size;
uint16_t history;
} uxrReliableStream;
#ifdef __cplusplus
}
#endif
#endif // UXR__CLIENT__CORE__SESSION__STREAM__RELIABLE_STREAM_H_

View File

@ -22,12 +22,53 @@ extern "C"
#include <uxr/client/core/session/session.h>
/**
* @brief Buffers into the stream identified by `stream_id` an XRCE WRITE_DATA submessage.
* As a consequence, an XRCE request is generated associated to the WRITE_DATA submessage.
*
* @param session A uxrSession structure previously initialized.
* @param stream_id The output stream identifier where the WRITE_DATA submessage will be buffered.
* @param requester_id The identifier of the XRCE Requester that will write the request into the DDS GDS.
* @param buffer The pointer to the request data.
* @param len The length of the request data.
* @return A `request_id` that identifies the XRCE request made by the Client.
* This could be used in the `uxr_run_session_until_one_status` or `uxr_run_session_until_all_status` functions.
*/
uint16_t uxr_buffer_request(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId requester_id,
uint8_t* buffer,
size_t len);
/**
* @brief Buffers into the stream identified by `stream_id` an XRCE WRITE_DATA submessage.
* As a consequence, an XRCE request is generated associated to the WRITE_DATA submessage.
*
* @param session A uxrSession structure previously initialized.
* @param stream_id The output stream identifier where the WRITE_DATA submessage will be buffered.
* @param replier_id The identifier of the XRCE Replier that will write the reply into the DDS GDS.
* @param sample_id The `SampleIdentity` that identifies the request.
* It will be read by the Requester to filter and identify the reply.
* @param buffer The pointer to the reply data.
* @param len The length of the reply data.
* @return A `request_id` that identifies the XRCE request made by the Client.
* This could be used in the `uxr_run_session_until_one_status` or `uxr_run_session_until_all_status` functions.
*/
uint16_t uxr_buffer_reply(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId replier_id,
SampleIdentity* sample_id,
uint8_t* buffer,
size_t len);
/**
* @brief Buffers into the stream identified by `stream_id` an XRCE WRITE_DATA submessage.
* The submessage will be sent when `uxr_flash_output_stream` or `uxr_run_session` function are called.
* As a result of the reception of this submessage, the Agent will write a topic into the DDS Global-Data-Space.
* @param session A uxrSession structure previously initialized.
* @param stream_id The output stream identifier where the READ_DATA submessage will be buffered.
* @param stream_id The output stream identifier where the WRITE_DATA submessage will be buffered.
* @param datawriter_id The identifier of the XRCE DataWriter that will write the topic into the DDS GDS.
* @param ub_topic The ucdrBuffer structure used for serializing the topic.
* @param topic_size The size of the topic in bytes.

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_C_CORE_SERIALIZATION_XRCE_PROTOCOL_INTERNAL_H_
#define SRC_C_CORE_SERIALIZATION_XRCE_PROTOCOL_INTERNAL_H_
#ifndef UXR_CLIENT_CORE_TYPE_XRCETYPES_H_
#define UXR_CLIENT_CORE_TYPE_XRCETYPES_H_
#ifdef __cplusplus
extern "C"
@ -29,6 +29,7 @@ extern "C"
#include <stdint.h>
#include <stdbool.h>
// TODO (julibert): move this configuration to CMake flags.
#define UXR_STRING_SIZE_MAX 512
#define UXR_SAMPLE_DATA_SIZE_MAX 512
#define UXR_STRING_SEQUENCE_MAX 8
@ -37,7 +38,7 @@ extern "C"
#define UXR_SAMPLE_DATA_SEQUENCE_MAX 8
#define UXR_SAMPLE_DELTA_SEQUENCE_MAX 8
#define UXR_PACKED_SAMPLES_SEQUENCE_MAX 8
#define UXR_TRANSPORT_LOCATOR_SEQUENCE_MAX 1
#define UXR_TRANSPORT_LOCATOR_SEQUENCE_MAX 4
#define UXR_PROPERTY_SEQUENCE_MAX 1
typedef struct Time_t
@ -68,22 +69,24 @@ typedef struct ClientKey
} ClientKey;
#define CLIENT_INVALID COMPOUND_LITERAL(ClientKey){{0x00, 0x00, 0x00, 0x00}}
#define DDS_XRCE_CLIENT_INVALID COMPOUND_LITERAL(ClientKey){{0x00, 0x00, 0x00, 0x00}}
typedef uint8_t ObjectKind;
#define OBJK_INVALID 0x00
#define OBJK_PARTICIPANT 0x01
#define OBJK_TOPIC 0x02
#define OBJK_PUBLISHER 0x03
#define OBJK_SUBSCRIBER 0x04
#define OBJK_DATAWRITER 0x05
#define OBJK_DATAREADER 0x06
#define OBJK_TYPE 0x0A
#define OBJK_QOSPROFILE 0x0B
#define OBJK_APPLICATION 0x0C
#define OBJK_AGENT 0x0D
#define OBJK_CLIENT 0x0E
#define OBJK_OTHER 0x0F
#define DDS_XRCE_OBJK_INVALID 0x00
#define DDS_XRCE_OBJK_PARTICIPANT 0x01
#define DDS_XRCE_OBJK_TOPIC 0x02
#define DDS_XRCE_OBJK_PUBLISHER 0x03
#define DDS_XRCE_OBJK_SUBSCRIBER 0x04
#define DDS_XRCE_OBJK_DATAWRITER 0x05
#define DDS_XRCE_OBJK_DATAREADER 0x06
#define DDS_XRCE_OBJK_REQUESTER 0x07
#define DDS_XRCE_OBJK_REPLIER 0x08
#define DDS_XRCE_OBJK_TYPE 0x0A
#define DDS_XRCE_OBJK_QOSPROFILE 0x0B
#define DDS_XRCE_OBJK_APPLICATION 0x0C
#define DDS_XRCE_OBJK_AGENT 0x0D
#define DDS_XRCE_OBJK_CLIENT 0x0E
#define DDS_XRCE_OBJK_OTHER 0x0F
typedef struct ObjectId
@ -98,10 +101,10 @@ typedef struct ObjectPrefix
uint8_t data[2];
} ObjectPrefix;
#define OBJECTID_INVALID COMPOUND_LITERAL(ObjectId){{0x00, 0x00}}
#define OBJECTID_AGENT COMPOUND_LITERAL(ObjectId){{0xFF, 0xFD}}
#define OBJECTID_CLIENT COMPOUND_LITERAL(ObjectId){{0xFF, 0xFE}}
#define OBJECTID_SESSION COMPOUND_LITERAL(ObjectId){{0xFF, 0xFF}}
#define DDS_XRCE_OBJECTID_INVALID COMPOUND_LITERAL(ObjectId){{0x00, 0x00}}
#define DDS_XRCE_OBJECTID_AGENT COMPOUND_LITERAL(ObjectId){{0xFF, 0xFD}}
#define DDS_XRCE_OBJECTID_CLIENT COMPOUND_LITERAL(ObjectId){{0xFF, 0xFE}}
#define DDS_XRCE_OBJECTID_SESSION COMPOUND_LITERAL(ObjectId){{0xFF, 0xFF}}
typedef struct XrceCookie
@ -109,7 +112,7 @@ typedef struct XrceCookie
uint8_t data[4];
} XrceCookie;
#define XRCE_COOKIE COMPOUND_LITERAL(XrceCookie){{0x58, 0x52, 0x43, 0x45}}
#define DDS_XRCE_XRCE_COOKIE COMPOUND_LITERAL(XrceCookie){{0x58, 0x52, 0x43, 0x45}}
typedef struct XrceVersion
@ -117,9 +120,9 @@ typedef struct XrceVersion
uint8_t data[2];
} XrceVersion;
#define XRCE_VERSION_MAJOR 0x01
#define XRCE_VERSION_MINOR 0x00
#define XRCE_VERSION COMPOUND_LITERAL(XrceVersion){{XRCE_VERSION_MAJOR, XRCE_VERSION_MINOR}}
#define DDS_XRCE_XRCE_VERSION_MAJOR 0x01
#define DDS_XRCE_XRCE_VERSION_MINOR 0x00
#define DDS_XRCE_XRCE_VERSION COMPOUND_LITERAL(XrceVersion){{DDS_XRCE_XRCE_VERSION_MAJOR, DDS_XRCE_XRCE_VERSION_MINOR}}
typedef struct XrceVendorId
@ -127,7 +130,7 @@ typedef struct XrceVendorId
uint8_t data[2];
} XrceVendorId;
#define XRCE_VENDOR_INVALID {0x00, 0x00}
#define DDS_XRCE_XRCE_VENDOR_INVALID {0x00, 0x00}
typedef enum TransportLocatorFormat
{
@ -237,10 +240,10 @@ typedef struct AGENT_Representation
} AGENT_Representation;
typedef uint8_t RepresentationFormat;
#define REPRESENTATION_BY_REFERENCE 0x01
#define REPRESENTATION_AS_XML_STRING 0x02
#define REPRESENTATION_IN_BINARY 0x03
#define REFERENCE_MAX_LEN 128
#define DDS_XRCE_REPRESENTATION_BY_REFERENCE 0x01
#define DDS_XRCE_REPRESENTATION_AS_XML_STRING 0x02
#define DDS_XRCE_REPRESENTATION_IN_BINARY 0x03
#define DDS_XRCE_REFERENCE_MAX_LEN 128
typedef union OBJK_Representation3FormatsU
@ -389,6 +392,22 @@ typedef struct OBJK_TOPIC_Representation
} OBJK_TOPIC_Representation;
typedef struct OBJK_REQUESTER_Representation
{
OBJK_Representation3_Base base;
ObjectId participant_id;
} OBJK_REQUESTER_Representation;
typedef struct OBJK_REPLIER_Representation
{
OBJK_Representation3_Base base;
ObjectId participant_id;
} OBJK_REPLIER_Representation;
typedef struct OBJK_DomainParticipant_Binary
{
bool optional_domain_reference;
@ -526,6 +545,8 @@ typedef union ObjectVariantU
OBJK_TOPIC_Representation topic;
OBJK_PUBLISHER_Representation publisher;
OBJK_SUBSCRIBER_Representation subscriber;
OBJK_REQUESTER_Representation requester;
OBJK_REPLIER_Representation replier;
DATAWRITER_Representation data_writer;
DATAREADER_Representation data_reader;
@ -571,14 +592,6 @@ typedef struct BaseObjectRequest
} BaseObjectRequest;
typedef BaseObjectRequest RelatedObjectRequest;
#define STATUS_LAST_OP_NONE 0x00
#define STATUS_LAST_OP_CREATE 0x01
#define STATUS_LAST_OP_UPDATE 0x02
#define STATUS_LAST_OP_DELETE 0x03
#define STATUS_LAST_OP_LOOKUP 0x04
#define STATUS_LAST_OP_READ 0x05
#define STATUS_LAST_OP_WRITE 0x06
typedef enum InfoMask
{
@ -996,6 +1009,40 @@ typedef struct TIMESTAMP_REPLY_Payload
} TIMESTAMP_REPLY_Payload;
typedef struct GuidPrefix
{
uint8_t data[12];
} GuidPrefix_t;
typedef struct EntityId_t
{
uint8_t entityKey[3];
uint8_t entityKind;
} EntityId_t;
typedef struct GUID_t
{
GuidPrefix_t guidPrefix;
EntityId_t entityId;
} GUID_t;
typedef struct SequenceNumber_t
{
int32_t high;
uint32_t low;
} SequenceNumber_t;
typedef struct SampleIdentity
{
GUID_t writer_guid;
SequenceNumber_t sequence_number;
} SampleIdentity;
#ifdef PERFORMANCE_TESTING
typedef struct PERFORMANCE_Payload
{
@ -1112,6 +1159,12 @@ bool uxr_deserialize_OBJK_PARTICIPANT_Representation(ucdrBuffer* buffer, OBJK_PA
bool uxr_serialize_OBJK_TOPIC_Representation(ucdrBuffer* buffer, const OBJK_TOPIC_Representation* input);
bool uxr_deserialize_OBJK_TOPIC_Representation(ucdrBuffer* buffer, OBJK_TOPIC_Representation* output);
bool uxr_serialize_OBJK_REQUESTER_Representation(ucdrBuffer* buffer, const OBJK_REQUESTER_Representation* input);
bool uxr_deserialize_OBJK_REQUESTER_Representation(ucdrBuffer* buffer, OBJK_REQUESTER_Representation* output);
bool uxr_serialize_OBJK_REPLIER_Representation(ucdrBuffer* buffer, const OBJK_REPLIER_Representation* input);
bool uxr_deserialize_OBJK_REPLIER_Representation(ucdrBuffer* buffer, OBJK_REPLIER_Representation* output);
bool uxr_serialize_OBJK_DomainParticipant_Binary(ucdrBuffer* buffer, const OBJK_DomainParticipant_Binary* input);
bool uxr_deserialize_OBJK_DomainParticipant_Binary(ucdrBuffer* buffer, OBJK_DomainParticipant_Binary* output);
@ -1289,6 +1342,21 @@ bool uxr_deserialize_TIMESTAMP_Payload(ucdrBuffer* buffer, TIMESTAMP_Payload* ou
bool uxr_serialize_TIMESTAMP_REPLY_Payload(ucdrBuffer* buffer, const TIMESTAMP_REPLY_Payload* input);
bool uxr_deserialize_TIMESTAMP_REPLY_Payload(ucdrBuffer* buffer, TIMESTAMP_REPLY_Payload* output);
bool uxr_serialize_GuidPrefix_t(ucdrBuffer* buffer, const GuidPrefix_t* input);
bool uxr_deserialize_GuidPrefix_t(ucdrBuffer* buffer, GuidPrefix_t* output);
bool uxr_serialize_EntityId_t(ucdrBuffer* buffer, const EntityId_t* input);
bool uxr_deserialize_EntityId_t(ucdrBuffer* buffer, EntityId_t* output);
bool uxr_serialize_GUID_t(ucdrBuffer* buffer, const GUID_t* input);
bool uxr_deserialize_GUID_t(ucdrBuffer* buffer, GUID_t* output);
bool uxr_serialize_SequenceNumber_t(ucdrBuffer* buffer, const SequenceNumber_t* input);
bool uxr_deserialize_SequenceNumber_t(ucdrBuffer* buffer, SequenceNumber_t* output);
bool uxr_serialize_SampleIdentity(ucdrBuffer* buffer, const SampleIdentity* input);
bool uxr_deserialize_SampleIdentity(ucdrBuffer* buffer, SampleIdentity* output);
#ifdef PERFORMANCE_TESTING
bool uxr_serialize_PERFORMANCE_Payload(ucdrBuffer* buffer, const PERFORMANCE_Payload* input);
bool uxr_deserialize_PERFORMANCE_Payload(ucdrBuffer* buffer, PERFORMANCE_Payload* input);
@ -1298,4 +1366,4 @@ bool uxr_deserialize_PERFORMANCE_Payload(ucdrBuffer* buffer, PERFORMANCE_Payload
}
#endif
#endif // SRC_C_CORE_SERIALIZATION_XRCE_PROTOCOL_H_
#endif // UXR_CLIENT_CORE_TYPE_XRCETYPES_H_

View File

@ -22,19 +22,13 @@ extern "C"
#include <uxr/client/config.h>
#include <uxr/client/visibility.h>
#include <uxr/client/core/type/xrce_types.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
typedef struct uxrAgentAddress
{
char ip[16];
uint16_t port;
} uxrAgentAddress;
typedef void (*uxrOnAgentFound) (const uxrAgentAddress* address, void* args);
typedef bool (*uxrOnAgentFound) (const TransportLocator* locator, void* args);
/**
* @brief Discovers Agents within the network using UDP/IP multicast with address "239.255.0.2" and port 7400.
@ -63,7 +57,7 @@ UXRDLLAPI void uxr_discovery_agents(
int period,
uxrOnAgentFound on_agent_func,
void* args,
const uxrAgentAddress* agent_list,
const TransportLocator* agent_list,
size_t agent_list_size);
#ifdef __cplusplus

View File

@ -0,0 +1,73 @@
// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef UXR_CLIENT_PROFILE_TRANSPORT_IP_IP_H_
#define UXR_CLIENT_PROFILE_TRANSPORT_IP_IP_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <uxr/client/core/type/xrce_types.h>
typedef enum uxrIpProtocol
{
UXR_IPv4,
UXR_IPv6
} uxrIpProtocol;
/**
* @brief Converts IPv4/IPv6 address + port to a TransportLocator.
*
* @param ip The IP address to convert.
* It could be IPv4 or IPv6 address.
* @param port The port to convert.
* @param ip_protocol The IP protocol of the IP address.
* @param locator The TransportLocator resulted from the conversion.
* In case of error it will be NULL.
* @return true In case of successful conversion.
* @return false In other case.
*/
bool uxr_ip_to_locator(
char const * ip,
uint16_t port,
uxrIpProtocol ip_protocol,
TransportLocator * locator);
/**
* @brief Converts a TrasnportLocator to an IPv4/IPv6 address + port.
*
* @param locator The TransportLocator resulted from the conversion.
* In case of error it will be NULL.
* @param ip A char buffer there the address will be copied.
* @param size The size of the IP buffer.
* @param port The resulted port.
* @param ip_protocol The resulted IP protocol of the IP address.
* @return true In case of successful conversion.
* @return false In other case.
*/
bool uxr_locator_to_ip(
TransportLocator const * locator,
char * ip,
size_t size,
uint16_t * port,
uxrIpProtocol * ip_protocol);
#ifdef __cplusplus
}
#endif
#endif // UXR_CLIENT_PROFILE_TRANSPORT_IP_IP_H_

View File

@ -12,14 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _UXR_CLIENT_TCP_TRANSPORT_H_
#define _UXR_CLIENT_TCP_TRANSPORT_H_
#ifndef UXR_CLIENT_TCP_TRANSPORT_H_
#define UXR_CLIENT_TCP_TRANSPORT_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <uxr/client/profile/transport/ip/ip.h>
#include <uxr/client/core/communication/communication.h>
#include <uxr/client/config.h>
#include <uxr/client/visibility.h>
@ -55,28 +56,31 @@ typedef struct uxrTCPTransport
/**
* @brief Initializes a TCP transport.
* @param transport The uninitialized transport structure used for managing the transport.
* This structure must be accesible during the connection.
* @param platform A structure that contains the platform dependencies.
* @param ip The IP address of the Agent.
* @param port The port of the Agent.
* @param transport The uninitialized transport structure used for managing the transport.
* This structure must be accesible during the connection.
* @param platform A structure that contains the platform dependencies.
* @param ip_protocol The IP protocol, it could be UXR_IPv4 or UXR_IPv6.
* @param ip The IP address of the Agent.
* @param port The port of the Agent.
* @return `true` in case of successful initialization. `false` in other case.
*/
UXRDLLAPI bool uxr_init_tcp_transport(
uxrTCPTransport* transport,
struct uxrTCPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
uint16_t port);
const char* port);
/**
* @brief Closes a TCP transport.
* @param transport The transport structure.
* @return `true` in case of successful closing. `false` in other case.
*/
UXRDLLAPI bool uxr_close_tcp_transport(uxrTCPTransport* transport);
UXRDLLAPI bool uxr_close_tcp_transport(
uxrTCPTransport* transport);
#ifdef __cplusplus
}
#endif
#endif //_UXR_CLIENT_TCP_TRANSPORT_H_
#endif // UXR_CLIENT_TCP_TRANSPORT_H_

View File

@ -0,0 +1,20 @@
#ifndef UXR_CLIENT_PROFILE_TRANSPORT_IP_TCP_EXTERNAL_H_
#define UXR_CLIENT_PROFILE_TRANSPORT_IP_TCP_EXTERNAL_H_
#ifdef __cplusplus
extern "C"
{
#endif
// Place here your includes
typedef struct uxrTCPPlatform
{
// Place here your platform data
} uxrTCPPlatform;
#ifdef __cplusplus
}
#endif
#endif // UXR_CLIENT_PROFILE_TRANSPORT_IP_TCP_EXTERNAL_H_

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _UXR_CLIENT_TCP_TRANSPORT_LINUX_H_
#define _UXR_CLIENT_TCP_TRANSPORT_LINUX_H_
#ifndef UXR_CLIENT_PROFILE_TRANSPORT_IP_TCP_TCPTRANSPORTPOSIX_H_
#define UXR_CLIENT_PROFILE_TRANSPORT_IP_TCP_TCPTRANSPORTPOSIX_H_
#ifdef __cplusplus
extern "C"
@ -26,7 +26,6 @@ extern "C"
typedef struct uxrTCPPlatform
{
struct sockaddr remote_addr;
struct pollfd poll_fd;
} uxrTCPPlatform;
@ -35,4 +34,4 @@ typedef struct uxrTCPPlatform
}
#endif
#endif //_UXR_CLIENT_TCP_TRANSPORT_LINUX_H_
#endif // UXR_CLIENT_PROFILE_TRANSPORT_IP_TCP_TCPTRANSPORTPOSIX_H_

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _UXR_CLIENT_TCP_TRANSPORT_WINDOWS_H_
#define _UXR_CLIENT_TCP_TRANSPORT_WINDOWS_H_
#ifndef UXR_CLIENT_TCP_TRANSPORT_WINDOWS_H_
#define UXR_CLIENT_TCP_TRANSPORT_WINDOWS_H_
#ifdef __cplusplus
extern "C"
@ -24,7 +24,6 @@ extern "C"
typedef struct uxrTCPPlatform
{
struct sockaddr remote_addr;
WSAPOLLFD poll_fd;
} uxrTCPPlatform;
@ -33,4 +32,4 @@ typedef struct uxrTCPPlatform
}
#endif
#endif //_UXR_CLIENT_TCP_TRANSPORT_WINDOWS_H_
#endif // UXR_CLIENT_TCP_TRANSPORT_WINDOWS_H_

View File

@ -20,6 +20,7 @@ extern "C"
{
#endif
#include <uxr/client/profile/transport/ip/ip.h>
#include <uxr/client/core/communication/communication.h>
#include <uxr/client/config.h>
#include <uxr/client/visibility.h>
@ -36,25 +37,28 @@ typedef struct uxrUDPTransport
/**
* @brief Initializes a UDP transport.
* @param transport The uninitialized transport structure used for managing the transport.
* This structure must be accesible during the connection.
* @param platform A structure that contains the platform dependencies.
* @param ip The IP address of the Agent.
* @param port The port of the Agent.
* @param transport The uninitialized transport structure used for managing the transport.
* This structure must be accesible during the connection.
* @param platform A structure that contains the platform dependencies.
* @param ip_protocol The IP protocol, it could be UXR_IPv4 or UXR_IPv6.
* @param ip The IP address of the Agent.
* @param port The port of the Agent.
* @return `true` in case of successful initialization. `false` in other case.
*/
UXRDLLAPI bool uxr_init_udp_transport(
uxrUDPTransport* transport,
struct uxrUDPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
uint16_t port);
const char* port);
/**
* @brief Closes a UDP transport.
* @param transport The transport structure.
* @return `true` in case of successful closing. `false` in other case.
*/
UXRDLLAPI bool uxr_close_udp_transport(uxrUDPTransport* transport);
UXRDLLAPI bool uxr_close_udp_transport(
uxrUDPTransport* transport);
#ifdef __cplusplus

View File

@ -0,0 +1,20 @@
#ifndef UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_EXTERNAL_H_
#define UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_EXTERNAL_H_
#ifdef __cplusplus
extern "C"
{
#endif
// Place here your includes
typedef struct uxrUDPPlatform
{
// Place here your platform data
} uxrUDPPlatform;
#ifdef __cplusplus
}
#endif
#endif // UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_EXTERNAL_H_

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _UXR_CLIENT_UDP_TRANSPORT_LINUX_H_
#define _UXR_CLIENT_UDP_TRANSPORT_LINUX_H_
#ifndef UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_UDPTRANSPORTPOSIX_H_
#define UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_UDPTRANSPORTPOSIX_H_
#ifdef __cplusplus
extern "C"
@ -26,7 +26,6 @@ extern "C"
typedef struct uxrUDPPlatform
{
struct sockaddr remote_addr;
struct pollfd poll_fd;
} uxrUDPPlatform;
@ -35,4 +34,4 @@ typedef struct uxrUDPPlatform
}
#endif
#endif //_UXR_CLIENT_UDP_TRANSPORT_LINUX_H_
#endif // UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_UDPTRANSPORTPOSIX_H_

View File

@ -0,0 +1,32 @@
// Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_UDPTRANSPORTPOSIXNOPOLL_H_
#define UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_UDPTRANSPORTPOSIXNOPOLL_H_
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct uxrUDPPlatform
{
int fd;
} uxrUDPPlatform;
#ifdef __cplusplus
}
#endif
#endif // UXR_CLIENT_PROFILE_TRANSPORT_IP_UDP_UDPTRANSPORTPOSIXNOPOLL_H_

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _UXR_CLIENT_UDP_TRANSPORT_WINDOWS_H_
#define _UXR_CLIENT_UDP_TRANSPORT_WINDOWS_H_
#ifndef UXR_CLIENT_UDP_TRANSPORT_WINDOWS_H_
#define UXR_CLIENT_UDP_TRANSPORT_WINDOWS_H_
#ifdef __cplusplus
extern "C"
@ -24,7 +24,6 @@ extern "C"
typedef struct uxrUDPPlatform
{
struct sockaddr remote_addr;
WSAPOLLFD poll_fd;
} uxrUDPPlatform;
@ -33,4 +32,4 @@ typedef struct uxrUDPPlatform
}
#endif
#endif //_UXR_CLIENT_UDP_TRANSPORT_WINDOWS_H_
#endif // UXR_CLIENT_UDP_TRANSPORT_WINDOWS_H_

View File

@ -0,0 +1,20 @@
#ifndef UXR_CLIENT_PROFILE_TRANSPORT_SERIAL_EXTERNAL_H_
#define UXR_CLIENT_PROFILE_TRANSPORT_SERIAL_EXTERNAL_H_
#ifdef __cplusplus
extern "C"
{
#endif
// Place here your includes
typedef struct uxrSerialPlatform
{
// Place here your platform data
} uxrSerialPlatform;
#ifdef __cplusplus
}
#endif
#endif // UXR_CLIENT_PROFILE_TRANSPORT_SERIAL_EXTERNAL_H_

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _SRC_C_PROFILE_TRANSPORT_SERIAL_SERIAL_TRANSPORT_INTERNAL_H_
#define _SRC_C_PROFILE_TRANSPORT_SERIAL_SERIAL_TRANSPORT_INTERNAL_H_
#ifndef _SRC_C_PROFILE_TRANSPORT_SERIAL_SERIAL_TRANSPORT_PLATFORM_H_
#define _SRC_C_PROFILE_TRANSPORT_SERIAL_SERIAL_TRANSPORT_PLATFORM_H_
#ifdef __cplusplus
extern "C"
@ -40,4 +40,4 @@ size_t uxr_read_serial_data_platform(struct uxrSerialPlatform* platform,
}
#endif
#endif //_SRC_C_PROFILE_TRANSPORT_SERIAL_SERIAL_TRANSPORT_INTERNAL_H_
#endif //_SRC_C_PROFILE_TRANSPORT_SERIAL_SERIAL_TRANSPORT_PLATFORM_H_

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _UXR_CLIENT_SERIAL_TRANSPORT_LINUX_H_
#define _UXR_CLIENT_SERIAL_TRANSPORT_LINUX_H_
#ifndef UXR_CLIENT_PROFILE_TRANSPORT_SERIAL_SERIALTRANSPORTPOSIX_H_
#define UXR_CLIENT_PROFILE_TRANSPORT_SERIAL_SERIALTRANSPORTPOSIX_H_
#ifdef __cplusplus
extern "C"
@ -32,4 +32,4 @@ typedef struct uxrSerialPlatform
}
#endif
#endif //_UXR_CLIENT_SERIAL_TRANSPORT_LINUX_H_
#endif // UXR_CLIENT_PROFILE_TRANSPORT_SERIAL_SERIALTRANSPORTPOSIX_H_

View File

@ -12,41 +12,43 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _UXR_CLIENT_TRANSPORT_H_
#define _UXR_CLIENT_TRANSPORT_H_
#ifndef UXR_CLIENT_TRANSPORT_H_
#define UXR_CLIENT_TRANSPORT_H_
#include <uxr/client/config.h>
#ifdef PROFILE_UDP_TRANSPORT
#include <uxr/client/profile/transport/udp/udp_transport.h>
#if defined(PLATFORM_NAME_LINUX)
#include <uxr/client/profile/transport/udp/udp_transport_linux.h>
#elif defined(PLATFORM_NAME_WINDOWS)
#include <uxr/client/profile/transport/udp/udp_transport_windows.h>
#elif defined(PLATFORM_NAME_NUTTX)
#include <uxr/client/profile/transport/udp/udp_transport_linux.h>
#include <uxr/client/profile/transport/ip/udp/udp_transport.h>
#if defined(UCLIENT_EXTERNAL_UDP)
#include <uxr/client/profile/transport/ip/udp/udp_transport_external.h>
#elif defined(UCLIENT_PLATFORM_POSIX_NOPOLL)
#include <uxr/client/profile/transport/ip/udp/udp_transport_posix_nopoll.h>
#elif defined(UCLIENT_PLATFORM_POSIX)
#include <uxr/client/profile/transport/ip/udp/udp_transport_posix.h>
#elif defined(UCLIENT_PLATFORM_WINDOWS)
#include <uxr/client/profile/transport/ip/udp/udp_transport_windows.h>
#endif
#endif //PROFILE_UDP_TRANSPORT
#ifdef PROFILE_TCP_TRANSPORT
#include <uxr/client/profile/transport/tcp/tcp_transport.h>
#if defined(PLATFORM_NAME_LINUX)
#include <uxr/client/profile/transport/tcp/tcp_transport_linux.h>
#elif defined(PLATFORM_NAME_WINDOWS)
#include <uxr/client/profile/transport/tcp/tcp_transport_windows.h>
#elif defined(PLATFORM_NAME_NUTTX)
#include <uxr/client/profile/transport/tcp/tcp_transport_linux.h>
#include <uxr/client/profile/transport/ip/tcp/tcp_transport.h>
#if defined(UCLIENT_EXTERNAL_TCP)
#include <uxr/client/profile/transport/ip/tcp/tcp_transport_external.h>
#elif defined(UCLIENT_PLATFORM_POSIX)
#include <uxr/client/profile/transport/ip/tcp/tcp_transport_posix.h>
#elif defined(UCLIENT_PLATFORM_WINDOWS)
#include <uxr/client/profile/transport/ip/tcp/tcp_transport_windows.h>
#endif
#endif //PROFILE_TCP_TRANSPORT
#ifdef PROFILE_SERIAL_TRANSPORT
#include <uxr/client/profile/transport/serial/serial_transport.h>
#if defined(PLATFORM_NAME_LINUX)
#include <uxr/client/profile/transport/serial/serial_transport_linux.h>
#elif defined(PLATFORM_NAME_WINDOWS)
#elif defined(PLATFORM_NAME_NUTTX)
#include <uxr/client/profile/transport/serial/serial_transport_linux.h>
#if defined(UCLIENT_EXTERNAL_SERIAL)
#include <uxr/client/profile/transport/serial/serial_transport_external.h>
#elif defined(UCLIENT_PLATFORM_POSIX)
#include <uxr/client/profile/transport/serial/serial_transport_posix.h>
#elif defined(UCLIENT_PLATFORM_WINDOWS)
#endif
#endif //PROFILE_SERIAL_TRANSPORT
#endif // _UXR_CLIENT_TRANSPORT_H_
#endif // UXR_CLIENT_TRANSPORT_H_

View File

@ -13,11 +13,11 @@
// limitations under the License.
#include <uxr/client/core/session/session_info.h>
#include <uxr/client/core/type/xrce_types.h>
#include <uxr/client/util/time.h>
#include <uxr/client/config.h>
#include "../serialization/xrce_header_internal.h"
#include "../serialization/xrce_protocol_internal.h"
#include "../session/submessage_internal.h"
#include "log_internal.h"
@ -388,15 +388,15 @@ void print_create_submessage(const char* pre, const CREATE_Payload* payload, uin
char type[4];
switch(payload->object_representation._.participant.base.representation.format)
{
case REPRESENTATION_AS_XML_STRING:
case DDS_XRCE_REPRESENTATION_AS_XML_STRING:
strcpy(type, "xml");
break;
case REPRESENTATION_BY_REFERENCE:
case DDS_XRCE_REPRESENTATION_BY_REFERENCE:
strcpy(type, "ref");
break;
case REPRESENTATION_IN_BINARY:
case DDS_XRCE_REPRESENTATION_IN_BINARY:
strcpy(type, "bin");
break;
@ -405,36 +405,36 @@ void print_create_submessage(const char* pre, const CREATE_Payload* payload, uin
char content[DATA_TO_STRING_BUFFER];
switch(payload->object_representation.kind)
{
case OBJK_PARTICIPANT:
case DDS_XRCE_OBJK_PARTICIPANT:
sprintf(content, "PARTICIPANT | %s: %zu",
type,
strlen(payload->object_representation._.participant.base.representation._.xml_string_represenatation) + 1);
break;
case OBJK_TOPIC:
case DDS_XRCE_OBJK_TOPIC:
sprintf(content, "TOPIC | obj: 0x%s | %s: %zu",
print_array_2(payload->object_representation._.data_reader.subscriber_id.data),
type,
strlen(payload->object_representation._.topic.base.representation._.xml_string_represenatation) + 1);
break;
case OBJK_PUBLISHER:
case DDS_XRCE_OBJK_PUBLISHER:
sprintf(content, "PUBLISHER | obj: 0x%s | %s: %zu",
print_array_2(payload->object_representation._.publisher.participant_id.data),
type,
strlen(payload->object_representation._.publisher.base.representation._.string_represenatation) + 1);
break;
case OBJK_SUBSCRIBER:
case DDS_XRCE_OBJK_SUBSCRIBER:
sprintf(content, "SUBSCRIBER | obj: 0x%s | %s: %zu",
print_array_2(payload->object_representation._.subscriber.participant_id.data),
type,
strlen(payload->object_representation._.subscriber.base.representation._.string_represenatation) + 1);
break;
case OBJK_DATAWRITER:
case DDS_XRCE_OBJK_DATAWRITER:
sprintf(content, "DATAWRITER | obj: 0x%s | %s: %zu",
print_array_2(payload->object_representation._.data_writer.publisher_id.data),
type,
strlen(payload->object_representation._.data_writer.base.representation._.xml_string_represenatation) + 1);
break;
case OBJK_DATAREADER:
case DDS_XRCE_OBJK_DATAREADER:
sprintf(content, "DATAREADER | obj: 0x%s | %s: %zu",
print_array_2(payload->object_representation._.data_reader.subscriber_id.data),
type,

View File

@ -1,4 +1,4 @@
#include "xrce_protocol_internal.h"
#include <uxr/client/core/type/xrce_types.h>
#include <string.h>
//==================================================================
@ -406,13 +406,13 @@ bool uxr_serialize_OBJK_Representation3Formats(ucdrBuffer* buffer, const OBJK_Re
{
switch(input->format)
{
case REPRESENTATION_BY_REFERENCE:
case DDS_XRCE_REPRESENTATION_BY_REFERENCE:
ret &= ucdr_serialize_string(buffer, input->_.object_reference);
break;
case REPRESENTATION_AS_XML_STRING:
case DDS_XRCE_REPRESENTATION_AS_XML_STRING:
ret &= ucdr_serialize_string(buffer, input->_.xml_string_represenatation);
break;
case REPRESENTATION_IN_BINARY:
case DDS_XRCE_REPRESENTATION_IN_BINARY:
ret &= uxr_serialize_BinarySequence_t(buffer, &input->_.binary_representation);
break;
default:
@ -430,13 +430,13 @@ bool uxr_deserialize_OBJK_Representation3Formats(ucdrBuffer* buffer, OBJK_Repres
{
switch(output->format)
{
case REPRESENTATION_BY_REFERENCE:
case DDS_XRCE_REPRESENTATION_BY_REFERENCE:
ret &= ucdr_deserialize_string(buffer, output->_.object_reference, UXR_STRING_SIZE_MAX);
break;
case REPRESENTATION_AS_XML_STRING:
case DDS_XRCE_REPRESENTATION_AS_XML_STRING:
ret &= ucdr_deserialize_string(buffer, output->_.xml_string_represenatation, UXR_STRING_SIZE_MAX);
break;
case REPRESENTATION_IN_BINARY:
case DDS_XRCE_REPRESENTATION_IN_BINARY:
ret &= uxr_deserialize_BinarySequence_t(buffer, &output->_.binary_representation);
break;
default:
@ -454,10 +454,10 @@ bool uxr_serialize_OBJK_RepresentationRefAndXMLFormats(ucdrBuffer* buffer, const
{
switch(input->format)
{
case REPRESENTATION_BY_REFERENCE:
case DDS_XRCE_REPRESENTATION_BY_REFERENCE:
ret &= ucdr_serialize_string(buffer, input->_.object_name);
break;
case REPRESENTATION_AS_XML_STRING:
case DDS_XRCE_REPRESENTATION_AS_XML_STRING:
ret &= ucdr_serialize_string(buffer, input->_.xml_string_represenatation);
break;
default:
@ -475,10 +475,10 @@ bool uxr_deserialize_OBJK_RepresentationRefAndXMLFormats(ucdrBuffer* buffer, OBJ
{
switch(output->format)
{
case REPRESENTATION_BY_REFERENCE:
case DDS_XRCE_REPRESENTATION_BY_REFERENCE:
ret &= ucdr_deserialize_string(buffer, output->_.object_name, UXR_STRING_SIZE_MAX);
break;
case REPRESENTATION_AS_XML_STRING:
case DDS_XRCE_REPRESENTATION_AS_XML_STRING:
ret &= ucdr_deserialize_string(buffer, output->_.xml_string_represenatation, UXR_STRING_SIZE_MAX);
break;
default:
@ -496,10 +496,10 @@ bool uxr_serialize_OBJK_RepresentationBinAndXMLFormats(ucdrBuffer* buffer, const
{
switch(input->format)
{
case REPRESENTATION_IN_BINARY:
case DDS_XRCE_REPRESENTATION_IN_BINARY:
ret &= uxr_serialize_BinarySequence_t(buffer, &input->_.binary_representation);
break;
case REPRESENTATION_AS_XML_STRING:
case DDS_XRCE_REPRESENTATION_AS_XML_STRING:
ret &= ucdr_serialize_string(buffer, input->_.string_represenatation);
break;
default:
@ -517,10 +517,10 @@ bool uxr_deserialize_OBJK_RepresentationBinAndXMLFormats(ucdrBuffer* buffer, OBJ
{
switch(output->format)
{
case REPRESENTATION_IN_BINARY:
case DDS_XRCE_REPRESENTATION_IN_BINARY:
ret &= uxr_deserialize_BinarySequence_t(buffer, &output->_.binary_representation);
break;
case REPRESENTATION_AS_XML_STRING:
case DDS_XRCE_REPRESENTATION_AS_XML_STRING:
ret &= ucdr_deserialize_string(buffer, output->_.string_represenatation, UXR_STRING_SIZE_MAX);
break;
default:
@ -724,6 +724,38 @@ bool uxr_deserialize_OBJK_TOPIC_Representation(ucdrBuffer* buffer, OBJK_TOPIC_Re
return ret;
}
bool uxr_serialize_OBJK_REQUESTER_Representation(ucdrBuffer* buffer, const OBJK_REQUESTER_Representation* input)
{
bool ret = true;
ret &= uxr_serialize_OBJK_Representation3_Base(buffer, &input->base);
ret &= uxr_serialize_ObjectId(buffer, &input->participant_id);
return ret;
}
bool uxr_deserialize_OBJK_REQUESTER_Representation(ucdrBuffer* buffer, OBJK_REQUESTER_Representation* output)
{
bool ret = true;
ret &= uxr_deserialize_OBJK_Representation3_Base(buffer, &output->base);
ret &= uxr_deserialize_ObjectId(buffer, &output->participant_id);
return ret;
}
bool uxr_serialize_OBJK_REPLIER_Representation(ucdrBuffer* buffer, const OBJK_REPLIER_Representation* input)
{
bool ret = true;
ret &= uxr_serialize_OBJK_Representation3_Base(buffer, &input->base);
ret &= uxr_serialize_ObjectId(buffer, &input->participant_id);
return ret;
}
bool uxr_deserialize_OBJK_REPLIER_Representation(ucdrBuffer* buffer, OBJK_REPLIER_Representation* output)
{
bool ret = true;
ret &= uxr_deserialize_OBJK_Representation3_Base(buffer, &output->base);
ret &= uxr_deserialize_ObjectId(buffer, &output->participant_id);
return ret;
}
bool uxr_serialize_OBJK_DomainParticipant_Binary(ucdrBuffer* buffer, const OBJK_DomainParticipant_Binary* input)
{
bool ret = true;
@ -1128,39 +1160,45 @@ bool uxr_serialize_ObjectVariant(ucdrBuffer* buffer, const ObjectVariant* input)
{
switch(input->kind)
{
case OBJK_AGENT:
case DDS_XRCE_OBJK_AGENT:
ret &= uxr_serialize_AGENT_Representation(buffer, &input->_.agent);
break;
case OBJK_CLIENT:
case DDS_XRCE_OBJK_CLIENT:
ret &= uxr_serialize_CLIENT_Representation(buffer, &input->_.client);
break;
case OBJK_APPLICATION:
case DDS_XRCE_OBJK_APPLICATION:
ret &= uxr_serialize_OBJK_APPLICATION_Representation(buffer, &input->_.application);
break;
case OBJK_PARTICIPANT:
case DDS_XRCE_OBJK_PARTICIPANT:
ret &= uxr_serialize_OBJK_PARTICIPANT_Representation(buffer, &input->_.participant);
break;
case OBJK_QOSPROFILE:
case DDS_XRCE_OBJK_QOSPROFILE:
ret &= uxr_serialize_OBJK_QOSPROFILE_Representation(buffer, &input->_.qos_profile);
break;
case OBJK_TYPE:
case DDS_XRCE_OBJK_TYPE:
ret &= uxr_serialize_OBJK_TYPE_Representation(buffer, &input->_.type);
break;
case OBJK_TOPIC:
case DDS_XRCE_OBJK_TOPIC:
ret &= uxr_serialize_OBJK_TOPIC_Representation(buffer, &input->_.topic);
break;
case OBJK_PUBLISHER:
case DDS_XRCE_OBJK_PUBLISHER:
ret &= uxr_serialize_OBJK_PUBLISHER_Representation(buffer, &input->_.publisher);
break;
case OBJK_SUBSCRIBER:
case DDS_XRCE_OBJK_SUBSCRIBER:
ret &= uxr_serialize_OBJK_SUBSCRIBER_Representation(buffer, &input->_.subscriber);
break;
case OBJK_DATAWRITER:
case DDS_XRCE_OBJK_DATAWRITER:
ret &= uxr_serialize_DATAWRITER_Representation(buffer, &input->_.data_writer);
break;
case OBJK_DATAREADER:
case DDS_XRCE_OBJK_DATAREADER:
ret &= uxr_serialize_DATAREADER_Representation(buffer, &input->_.data_reader);
break;
case DDS_XRCE_OBJK_REQUESTER:
ret &= uxr_serialize_OBJK_REQUESTER_Representation(buffer, &input->_.requester);
break;
case DDS_XRCE_OBJK_REPLIER:
ret &= uxr_serialize_OBJK_REPLIER_Representation(buffer, &input->_.replier);
break;
default:
break;
}
@ -1176,39 +1214,45 @@ bool uxr_deserialize_ObjectVariant(ucdrBuffer* buffer, ObjectVariant* output)
{
switch(output->kind)
{
case OBJK_AGENT:
case DDS_XRCE_OBJK_AGENT:
ret &= uxr_deserialize_AGENT_Representation(buffer, &output->_.agent);
break;
case OBJK_CLIENT:
case DDS_XRCE_OBJK_CLIENT:
ret &= uxr_deserialize_CLIENT_Representation(buffer, &output->_.client);
break;
case OBJK_APPLICATION:
case DDS_XRCE_OBJK_APPLICATION:
ret &= uxr_deserialize_OBJK_APPLICATION_Representation(buffer, &output->_.application);
break;
case OBJK_PARTICIPANT:
case DDS_XRCE_OBJK_PARTICIPANT:
ret &= uxr_deserialize_OBJK_PARTICIPANT_Representation(buffer, &output->_.participant);
break;
case OBJK_QOSPROFILE:
case DDS_XRCE_OBJK_QOSPROFILE:
ret &= uxr_deserialize_OBJK_QOSPROFILE_Representation(buffer, &output->_.qos_profile);
break;
case OBJK_TYPE:
case DDS_XRCE_OBJK_TYPE:
ret &= uxr_deserialize_OBJK_TYPE_Representation(buffer, &output->_.type);
break;
case OBJK_TOPIC:
case DDS_XRCE_OBJK_TOPIC:
ret &= uxr_deserialize_OBJK_TOPIC_Representation(buffer, &output->_.topic);
break;
case OBJK_PUBLISHER:
case DDS_XRCE_OBJK_PUBLISHER:
ret &= uxr_deserialize_OBJK_PUBLISHER_Representation(buffer, &output->_.publisher);
break;
case OBJK_SUBSCRIBER:
case DDS_XRCE_OBJK_SUBSCRIBER:
ret &= uxr_deserialize_OBJK_SUBSCRIBER_Representation(buffer, &output->_.subscriber);
break;
case OBJK_DATAWRITER:
case DDS_XRCE_OBJK_DATAWRITER:
ret &= uxr_deserialize_DATAWRITER_Representation(buffer, &output->_.data_writer);
break;
case OBJK_DATAREADER:
case DDS_XRCE_OBJK_DATAREADER:
ret &= uxr_deserialize_DATAREADER_Representation(buffer, &output->_.data_reader);
break;
case DDS_XRCE_OBJK_REQUESTER:
ret &= uxr_deserialize_OBJK_REQUESTER_Representation(buffer, &output->_.requester);
break;
case DDS_XRCE_OBJK_REPLIER:
ret &= uxr_deserialize_OBJK_REPLIER_Representation(buffer, &output->_.replier);
break;
default:
break;
}
@ -1332,13 +1376,13 @@ bool uxr_serialize_ActivityInfoVariant(ucdrBuffer* buffer, const ActivityInfoVar
{
switch(input->kind)
{
case OBJK_AGENT:
case DDS_XRCE_OBJK_AGENT:
ret &= uxr_serialize_AGENT_ActivityInfo(buffer, &input->_.agent);
break;
case OBJK_DATAWRITER:
case DDS_XRCE_OBJK_DATAWRITER:
ret &= uxr_serialize_DATAWRITER_ActivityInfo(buffer, &input->_.data_writer);
break;
case OBJK_DATAREADER:
case DDS_XRCE_OBJK_DATAREADER:
ret &= uxr_serialize_DATAREADER_ActivityInfo(buffer, &input->_.data_reader);
break;
default:
@ -1356,13 +1400,13 @@ bool uxr_deserialize_ActivityInfoVariant(ucdrBuffer* buffer, ActivityInfoVariant
{
switch(output->kind)
{
case OBJK_AGENT:
case DDS_XRCE_OBJK_AGENT:
ret &= uxr_deserialize_AGENT_ActivityInfo(buffer, &output->_.agent);
break;
case OBJK_DATAWRITER:
case DDS_XRCE_OBJK_DATAWRITER:
ret &= uxr_deserialize_DATAWRITER_ActivityInfo(buffer, &output->_.data_writer);
break;
case OBJK_DATAREADER:
case DDS_XRCE_OBJK_DATAREADER:
ret &= uxr_deserialize_DATAREADER_ActivityInfo(buffer, &output->_.data_reader);
break;
default:
@ -2158,6 +2202,84 @@ bool uxr_deserialize_TIMESTAMP_REPLY_Payload(ucdrBuffer* buffer, TIMESTAMP_REPLY
return ret;
}
bool uxr_serialize_GuidPrefix_t(ucdrBuffer* buffer, const GuidPrefix_t* input)
{
bool ret = true;
ret &= ucdr_serialize_array_uint8_t(buffer, input->data, sizeof(GuidPrefix_t));
return ret;
}
bool uxr_deserialize_GuidPrefix_t(ucdrBuffer* buffer, GuidPrefix_t* output)
{
bool ret = true;
ret &= ucdr_deserialize_array_uint8_t(buffer, output->data, sizeof(GuidPrefix_t));
return ret;
}
bool uxr_serialize_EntityId_t(ucdrBuffer* buffer, const EntityId_t* input)
{
bool ret = true;
ret &= ucdr_serialize_array_uint8_t(buffer, input->entityKey, sizeof(((EntityId_t *)0)->entityKey));
ret &= ucdr_serialize_uint8_t(buffer, input->entityKind);
return ret;
}
bool uxr_deserialize_EntityId_t(ucdrBuffer* buffer, EntityId_t* output)
{
bool ret = true;
ret &= ucdr_deserialize_array_uint8_t(buffer, output->entityKey, sizeof(((EntityId_t *)0)->entityKey));
ret &= ucdr_deserialize_uint8_t(buffer, &output->entityKind);
return ret;
}
bool uxr_serialize_GUID_t(ucdrBuffer* buffer, const GUID_t* input)
{
bool ret = true;
ret &= uxr_serialize_GuidPrefix_t(buffer, &input->guidPrefix);
ret &= uxr_serialize_EntityId_t(buffer, &input->entityId);
return ret;
}
bool uxr_deserialize_GUID_t(ucdrBuffer* buffer, GUID_t* output)
{
bool ret = true;
ret &= uxr_deserialize_GuidPrefix_t(buffer, &output->guidPrefix);
ret &= uxr_deserialize_EntityId_t(buffer, &output->entityId);
return ret;
}
bool uxr_serialize_SequenceNumber_t(ucdrBuffer* buffer, const SequenceNumber_t* input)
{
bool ret = true;
ret &= ucdr_serialize_int32_t(buffer, input->high);
ret &= ucdr_serialize_uint32_t(buffer, input->low);
return ret;
}
bool uxr_deserialize_SequenceNumber_t(ucdrBuffer* buffer, SequenceNumber_t* output)
{
bool ret = true;
ret &= ucdr_deserialize_int32_t(buffer, &output->high);
ret &= ucdr_deserialize_uint32_t(buffer, &output->low);
return ret;
}
bool uxr_serialize_SampleIdentity(ucdrBuffer* buffer, const SampleIdentity* input)
{
bool ret = true;
ret &= uxr_serialize_GUID_t(buffer, &input->writer_guid);
ret &= uxr_serialize_SequenceNumber_t(buffer, &input->sequence_number);
return ret;
}
bool uxr_deserialize_SampleIdentity(ucdrBuffer* buffer, SampleIdentity* output)
{
bool ret = true;
ret &= uxr_deserialize_GUID_t(buffer, &output->writer_guid);
ret &= uxr_deserialize_SequenceNumber_t(buffer, &output->sequence_number);
return ret;
}
#ifdef PERFORMANCE_TESTING
bool uxr_serialize_PERFORMANCE_Payload(ucdrBuffer* buffer, const PERFORMANCE_Payload* input)
{

View File

@ -1,8 +1,9 @@
#include <uxr/client/core/type/xrce_types.h>
#include "common_create_entities_internal.h"
#include "session_internal.h"
#include "session_info_internal.h"
#include "submessage_internal.h"
#include "../serialization/xrce_protocol_internal.h"
//==================================================================
// PUBLIC
@ -41,7 +42,7 @@ uint16_t uxr_common_create_entity(uxrSession* session, uxrStreamId stream_id,
payload_length = (uint16_t)(payload_length + 2); // padding
payload_length = (uint16_t)(payload_length + 4); // xml length
payload_length = (uint16_t)(payload_length + xml_ref_size); // xml data (note: compiler executes strlen one time this function)
payload_length = (uint16_t)(payload_length + ((object_id.type == OBJK_PARTICIPANT && payload_length % 2 != 0) ? 1 : 0)); // necessary padding
payload_length = (uint16_t)(payload_length + ((object_id.type == DDS_XRCE_OBJK_PARTICIPANT && payload_length % 2 != 0) ? 1 : 0)); // necessary padding
payload_length = (uint16_t)(payload_length + 2); //object id ref
ucdrBuffer ub;

View File

@ -1,7 +1,7 @@
#include <uxr/client/core/session/create_entities_ref.h>
#include <uxr/client/core/type/xrce_types.h>
#include "common_create_entities_internal.h"
#include "../serialization/xrce_protocol_internal.h"
#include <string.h>
@ -18,7 +18,7 @@ uint16_t uxr_buffer_create_participant_ref(uxrSession* session, uxrStreamId stre
//assert with the object_id type
CREATE_Payload payload;
payload.object_representation.kind = OBJK_PARTICIPANT;
payload.object_representation.kind = DDS_XRCE_OBJK_PARTICIPANT;
payload.object_representation._.participant.domain_id = domain_id;
return create_entity_ref(session, stream_id, object_id, ref, mode, &payload);
@ -29,7 +29,7 @@ uint16_t uxr_buffer_create_topic_ref(uxrSession* session, uxrStreamId stream_id,
const char* ref, uint8_t mode)
{
CREATE_Payload payload;
payload.object_representation.kind = OBJK_TOPIC;
payload.object_representation.kind = DDS_XRCE_OBJK_TOPIC;
uxr_object_id_to_raw(participant_id, payload.object_representation._.topic.participant_id.data);
return create_entity_ref(session, stream_id, object_id, ref, mode, &payload);
@ -40,7 +40,7 @@ uint16_t uxr_buffer_create_datawriter_ref(uxrSession* session, uxrStreamId strea
const char* ref, uint8_t mode)
{
CREATE_Payload payload;
payload.object_representation.kind = OBJK_DATAWRITER;
payload.object_representation.kind = DDS_XRCE_OBJK_DATAWRITER;
uxr_object_id_to_raw(publisher_id, payload.object_representation._.data_writer.publisher_id.data);
return create_entity_ref(session, stream_id, object_id, ref, mode, &payload);
@ -51,12 +51,42 @@ uint16_t uxr_buffer_create_datareader_ref(uxrSession* session, uxrStreamId strea
const char* ref, uint8_t mode)
{
CREATE_Payload payload;
payload.object_representation.kind = OBJK_DATAREADER;
payload.object_representation.kind = DDS_XRCE_OBJK_DATAREADER;
uxr_object_id_to_raw(subscriber_id, payload.object_representation._.data_reader.subscriber_id.data);
return create_entity_ref(session, stream_id, object_id, ref, mode, &payload);
}
uint16_t uxr_buffer_create_requester_ref(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId object_id,
uxrObjectId participant_id,
const char* ref,
uint8_t mode)
{
CREATE_Payload payload;
payload.object_representation.kind = DDS_XRCE_OBJK_REQUESTER;
uxr_object_id_to_raw(participant_id, payload.object_representation._.requester.participant_id.data);
return create_entity_ref(session, stream_id, object_id, ref, mode, &payload);
}
uint16_t uxr_buffer_create_replier_ref(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId object_id,
uxrObjectId participant_id,
const char* ref,
uint8_t mode)
{
CREATE_Payload payload;
payload.object_representation.kind = DDS_XRCE_OBJK_REPLIER;
uxr_object_id_to_raw(participant_id, payload.object_representation._.replier.participant_id.data);
return create_entity_ref(session, stream_id, object_id, ref, mode, &payload);
}
//==================================================================
// PRIVATE
//==================================================================
@ -66,7 +96,7 @@ inline uint16_t create_entity_ref(uxrSession* session, uxrStreamId stream_id,
CREATE_Payload* payload)
{
// Use participant access to access to the ref base of any object variant. //Future elegant change?
payload->object_representation._.participant.base.representation.format = REPRESENTATION_BY_REFERENCE;
payload->object_representation._.participant.base.representation.format = DDS_XRCE_REPRESENTATION_BY_REFERENCE;
payload->object_representation._.participant.base.representation._.object_reference = (char*) ref;
return uxr_common_create_entity(session, stream_id, object_id, (uint16_t)(strlen(ref) + 1), mode, payload);

View File

@ -1,7 +1,7 @@
#include <uxr/client/core/session/create_entities_xml.h>
#include <uxr/client/core/type/xrce_types.h>
#include "common_create_entities_internal.h"
#include "../serialization/xrce_protocol_internal.h"
#include <string.h>
@ -18,7 +18,7 @@ uint16_t uxr_buffer_create_participant_xml(uxrSession* session, uxrStreamId stre
//assert with the object_id type
CREATE_Payload payload;
payload.object_representation.kind = OBJK_PARTICIPANT;
payload.object_representation.kind = DDS_XRCE_OBJK_PARTICIPANT;
payload.object_representation._.participant.domain_id = (int16_t)domain;
return create_entity_xml(session, stream_id, object_id, xml, mode, &payload);
@ -30,7 +30,7 @@ uint16_t uxr_buffer_create_topic_xml(uxrSession* session, uxrStreamId stream_id,
//assert with the object_id type
CREATE_Payload payload;
payload.object_representation.kind = OBJK_TOPIC;
payload.object_representation.kind = DDS_XRCE_OBJK_TOPIC;
uxr_object_id_to_raw(participant_id, payload.object_representation._.topic.participant_id.data);
return create_entity_xml(session, stream_id, object_id, xml, mode, &payload);
@ -42,7 +42,7 @@ uint16_t uxr_buffer_create_publisher_xml(uxrSession* session, uxrStreamId stream
//assert with the object_id type
CREATE_Payload payload;
payload.object_representation.kind = OBJK_PUBLISHER;
payload.object_representation.kind = DDS_XRCE_OBJK_PUBLISHER;
uxr_object_id_to_raw(participant_id, payload.object_representation._.publisher.participant_id.data);
return create_entity_xml(session, stream_id, object_id, xml, mode, &payload);
@ -54,7 +54,7 @@ uint16_t uxr_buffer_create_subscriber_xml(uxrSession* session, uxrStreamId strea
//assert with the object_id type
CREATE_Payload payload;
payload.object_representation.kind = OBJK_SUBSCRIBER;
payload.object_representation.kind = DDS_XRCE_OBJK_SUBSCRIBER;
uxr_object_id_to_raw(participant_id, payload.object_representation._.subscriber.participant_id.data);
return create_entity_xml(session, stream_id, object_id, xml, mode, &payload);
@ -66,7 +66,7 @@ uint16_t uxr_buffer_create_datawriter_xml(uxrSession* session, uxrStreamId strea
//assert with the object_id type
CREATE_Payload payload;
payload.object_representation.kind = OBJK_DATAWRITER;
payload.object_representation.kind = DDS_XRCE_OBJK_DATAWRITER;
uxr_object_id_to_raw(publisher_id, payload.object_representation._.data_writer.publisher_id.data);
return create_entity_xml(session, stream_id, object_id, xml, mode, &payload);
@ -78,12 +78,42 @@ uint16_t uxr_buffer_create_datareader_xml(uxrSession* session, uxrStreamId strea
//assert with the object_id type
CREATE_Payload payload;
payload.object_representation.kind = OBJK_DATAREADER;
payload.object_representation.kind = DDS_XRCE_OBJK_DATAREADER;
uxr_object_id_to_raw(subscriber_id, payload.object_representation._.data_reader.subscriber_id.data);
return create_entity_xml(session, stream_id, object_id, xml, mode, &payload);
}
uint16_t uxr_buffer_create_requester_xml(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId object_id,
uxrObjectId participant_id,
const char* xml,
uint8_t mode)
{
CREATE_Payload payload;
payload.object_representation.kind = DDS_XRCE_OBJK_REQUESTER;
uxr_object_id_to_raw(participant_id, payload.object_representation._.requester.participant_id.data);
return create_entity_xml(session, stream_id, object_id, xml, mode, &payload);
}
uint16_t uxr_buffer_create_replier_xml(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId object_id,
uxrObjectId participant_id,
const char* xml,
uint8_t mode)
{
CREATE_Payload payload;
payload.object_representation.kind = DDS_XRCE_OBJK_REPLIER;
uxr_object_id_to_raw(participant_id, payload.object_representation._.replier.participant_id.data);
return create_entity_xml(session, stream_id, object_id, xml, mode, &payload);
}
//==================================================================
// PRIVATE
//==================================================================
@ -93,7 +123,7 @@ inline uint16_t create_entity_xml(uxrSession* session, uxrStreamId stream_id,
CREATE_Payload* payload)
{
// Use participant access to access to the xml base of any object variant. //Future elegant change?
payload->object_representation._.participant.base.representation.format = REPRESENTATION_AS_XML_STRING;
payload->object_representation._.participant.base.representation.format = DDS_XRCE_REPRESENTATION_AS_XML_STRING;
payload->object_representation._.participant.base.representation._.xml_string_represenatation = (char*)xml;
return uxr_common_create_entity(session, stream_id, object_id, (uint16_t)(strlen(xml) + 1), mode, payload);

View File

@ -1,9 +1,9 @@
#include <uxr/client/core/session/read_access.h>
#include <uxr/client/core/type/xrce_types.h>
#include "session_internal.h"
#include "session_info_internal.h"
#include "submessage_internal.h"
#include "../serialization/xrce_protocol_internal.h"
extern void read_submessage_format(
uxrSession* session,
@ -154,9 +154,87 @@ inline void read_format_data(
uint16_t request_id)
{
(void) length;
ub->last_data_size = 8; //reset alignment (as if we were created a new ucdrBuffer)
session->on_topic(session, object_id, request_id, stream_id, ub, session->on_topic_args);
ucdrBuffer temp_buffer;
ucdr_init_buffer(&temp_buffer, ub->iterator, (size_t)(ub->final - ub->iterator));
ucdr_set_on_full_buffer_callback(&temp_buffer, ub->on_full_buffer, ub->args);
if (ub->args)
{
uxrInputReliableStream * stream = (uxrInputReliableStream*) ub->args;
stream->cleanup_flag = false;
}
switch (object_id.type)
{
case UXR_DATAREADER_ID:
{
if (NULL != session->on_topic)
{
session->on_topic(session, object_id, request_id, stream_id, &temp_buffer, length, session->on_topic_args);
}
break;
}
case UXR_REPLIER_ID:
{
if (NULL != session->on_request)
{
SampleIdentity sample_id;
size_t offset = temp_buffer.offset;
if (uxr_deserialize_SampleIdentity(&temp_buffer, &sample_id))
{
length = (uint16_t)(length - (temp_buffer.offset - offset));
ucdr_init_buffer(&temp_buffer, temp_buffer.iterator, (size_t)(temp_buffer.final - temp_buffer.iterator));
ucdr_set_on_full_buffer_callback(&temp_buffer, ub->on_full_buffer, ub->args);
session->on_request(
session,
object_id,
request_id,
&sample_id,
&temp_buffer,
(size_t)length,
session->on_request_args);
}
}
break;
}
case UXR_REQUESTER_ID:
{
if (NULL != session->on_reply)
{
BaseObjectRequest request;
size_t offset = temp_buffer.offset;
if (uxr_deserialize_BaseObjectRequest(&temp_buffer, &request))
{
length = (uint16_t)(length - (temp_buffer.offset - offset));
ucdr_init_buffer(&temp_buffer, temp_buffer.iterator, (size_t)(temp_buffer.final - temp_buffer.iterator));
ucdr_set_on_full_buffer_callback(&temp_buffer, ub->on_full_buffer, ub->args);
session->on_reply(
session,
object_id,
request_id,
(uint16_t)((request.request_id.data[0] << 8) + request.request_id.data[1]),
&temp_buffer,
(size_t)length,
session->on_reply_args);
}
}
ub->iterator += length;
break;
}
default:
break;
}
if (ub->args)
{
uxrInputReliableStream * stream = (uxrInputReliableStream*) ub->args;
stream->cleanup_flag = true;
}
ucdr_advance_buffer(ub, length);
}
void read_format_sample(

View File

@ -1,6 +1,7 @@
#include <uxr/client/core/session/session.h>
#include <uxr/client/util/time.h>
#include <uxr/client/core/communication/communication.h>
#include <uxr/client/core/type/xrce_types.h>
#include <uxr/client/config.h>
#include "submessage_internal.h"
@ -13,7 +14,6 @@
#include "stream/output_best_effort_stream_internal.h"
#include "stream/output_reliable_stream_internal.h"
#include "stream/seq_num_internal.h"
#include "../serialization/xrce_protocol_internal.h"
#include "../log/log_internal.h"
#include "../../util/time_internal.h"
@ -53,7 +53,6 @@ static void read_submessage_performance(uxrSession* session, ucdrBuffer* submess
static void process_status(uxrSession* session, uxrObjectId object_id, uint16_t request_id, uint8_t status);
static void process_timestamp_reply(uxrSession* session, TIMESTAMP_REPLY_Payload* timestamp);
static void on_new_output_reliable_stream_segment(ucdrBuffer* ub, uxrOutputReliableStream* args);
static FragmentationInfo on_get_fragmentation_info(uint8_t* submessage_header);
static bool run_session_until_sync(uxrSession* session, int timeout);
@ -102,6 +101,18 @@ void uxr_set_time_callback(uxrSession* session, uxrOnTimeFunc on_time_func, void
session->on_time_args = args;
}
void uxr_set_request_callback(uxrSession* session, uxrOnRequestFunc on_request_func, void* args)
{
session->on_request = on_request_func;
session->on_request_args = args;
}
void uxr_set_reply_callback(uxrSession* session, uxrOnReplyFunc on_reply_func, void* args)
{
session->on_reply = on_reply_func;
session->on_reply_args = args;
}
#ifdef PERFORMANCE_TESTING
void uxr_set_performance_callback(uxrSession* session, uxrOnPerformanceFunc on_echo_func, void* args)
{
@ -116,7 +127,7 @@ bool uxr_create_session(uxrSession* session)
uint8_t create_session_buffer[CREATE_SESSION_MAX_MSG_SIZE];
ucdrBuffer ub;
ucdr_init_buffer_offset(&ub, create_session_buffer, CREATE_SESSION_MAX_MSG_SIZE, uxr_session_header_offset(&session->info));
ucdr_init_buffer_origin_offset(&ub, create_session_buffer, CREATE_SESSION_MAX_MSG_SIZE, 0u, uxr_session_header_offset(&session->info));
uxr_buffer_create_session(&session->info, &ub, (uint16_t)(session->comm->mtu - INTERNAL_RELIABLE_BUFFER_OFFSET));
uxr_stamp_create_session_header(&session->info, ub.init);
@ -130,7 +141,7 @@ bool uxr_delete_session(uxrSession* session)
{
uint8_t delete_session_buffer[DELETE_SESSION_MAX_MSG_SIZE];
ucdrBuffer ub;
ucdr_init_buffer_offset(&ub, delete_session_buffer, DELETE_SESSION_MAX_MSG_SIZE, uxr_session_header_offset(&session->info));
ucdr_init_buffer_origin_offset(&ub, delete_session_buffer, DELETE_SESSION_MAX_MSG_SIZE, 0u, uxr_session_header_offset(&session->info));
uxr_buffer_delete_session(&session->info, &ub);
uxr_stamp_session_header(&session->info, 0, 0, ub.init);
@ -148,7 +159,7 @@ uxrStreamId uxr_create_output_best_effort_stream(uxrSession* session, uint8_t* b
uxrStreamId uxr_create_output_reliable_stream(uxrSession* session, uint8_t* buffer, size_t size, uint16_t history)
{
uint8_t header_offset = uxr_session_header_offset(&session->info);
return uxr_add_output_reliable_buffer(&session->streams, buffer, size, history, header_offset, on_new_output_reliable_stream_segment);
return uxr_add_output_reliable_buffer(&session->streams, buffer, size, history, header_offset);
}
uxrStreamId uxr_create_input_best_effort_stream(uxrSession* session)
@ -174,6 +185,21 @@ bool uxr_run_session_time(uxrSession* session, int timeout_ms)
return uxr_output_streams_confirmed(&session->streams);
}
bool uxr_run_session_timeout(uxrSession* session, int timeout_ms)
{
int64_t start_timestamp = uxr_millis();
int remaining_time = timeout_ms;
uxr_flash_output_streams(session);
while(remaining_time > 0)
{
listen_message_reliably(session, remaining_time);
remaining_time = timeout_ms - (int)(uxr_millis() - start_timestamp);
}
return uxr_output_streams_confirmed(&session->streams);
}
bool uxr_run_session_until_timeout(uxrSession* session, int timeout_ms)
{
uxr_flash_output_streams(session);
@ -265,7 +291,7 @@ bool uxr_sync_session(uxrSession* session, int time)
{
uint8_t timestamp_buffer[TIMESTAMP_MAX_MSG_SIZE];
ucdrBuffer ub;
ucdr_init_buffer_offset(&ub, timestamp_buffer, sizeof(timestamp_buffer), uxr_session_header_offset(&session->info));
ucdr_init_buffer_origin_offset(&ub, timestamp_buffer, sizeof(timestamp_buffer), 0u, uxr_session_header_offset(&session->info));
uxr_buffer_submessage_header(&ub, SUBMESSAGE_ID_TIMESTAMP, TIMESTAMP_PAYLOAD_SIZE, 0);
TIMESTAMP_Payload timestamp;
@ -441,7 +467,7 @@ void write_submessage_heartbeat(const uxrSession* session, uxrStreamId id)
{
uint8_t heartbeat_buffer[HEARTBEAT_MAX_MSG_SIZE];
ucdrBuffer ub;
ucdr_init_buffer_offset(&ub, heartbeat_buffer, HEARTBEAT_MAX_MSG_SIZE, uxr_session_header_offset(&session->info));
ucdr_init_buffer_origin_offset(&ub, heartbeat_buffer, HEARTBEAT_MAX_MSG_SIZE, 0u, uxr_session_header_offset(&session->info));
const uxrOutputReliableStream* stream = &session->streams.output_reliable[id.index];
@ -464,7 +490,7 @@ void write_submessage_acknack(const uxrSession* session, uxrStreamId id)
{
uint8_t acknack_buffer[ACKNACK_MAX_MSG_SIZE];
ucdrBuffer ub;
ucdr_init_buffer_offset(&ub, acknack_buffer, ACKNACK_MAX_MSG_SIZE, uxr_session_header_offset(&session->info));
ucdr_init_buffer_origin_offset(&ub, acknack_buffer, ACKNACK_MAX_MSG_SIZE, 0u, uxr_session_header_offset(&session->info));
const uxrInputReliableStream* stream = &session->streams.input_reliable[id.index];
@ -618,15 +644,12 @@ void read_submessage_data(uxrSession* session, ucdrBuffer* submessage, uint16_t
uxr_deserialize_BaseObjectRequest(submessage, &base);
length = (uint16_t)(length - 4); //CHANGE: by a future size_of_BaseObjectRequest
uxrObjectId object_id; uint16_t request_id;
uxrObjectId object_id;
uint16_t request_id;
uxr_parse_base_object_request(&base, &object_id, &request_id);
process_status(session, object_id, request_id, UXR_STATUS_OK);
if(session->on_topic != NULL)
{
read_submessage_format(session, submessage, length, format, stream_id, object_id, request_id);
}
read_submessage_format(session, submessage, length, format, stream_id, object_id, request_id);
}
void read_submessage_heartbeat(uxrSession* session, ucdrBuffer* submessage)
@ -739,7 +762,7 @@ bool uxr_prepare_stream_to_write_submessage(uxrSession* session, uxrStreamId str
case UXR_RELIABLE_STREAM:
{
uxrOutputReliableStream* stream = uxr_get_output_reliable_stream(&session->streams, stream_id.index);
available = stream && uxr_prepare_reliable_buffer_to_write(stream, submessage_size, SUBHEADER_SIZE, ub);
available = stream && uxr_prepare_reliable_buffer_to_write(stream, submessage_size, ub);
break;
}
default:
@ -754,14 +777,6 @@ bool uxr_prepare_stream_to_write_submessage(uxrSession* session, uxrStreamId str
return available;
}
void on_new_output_reliable_stream_segment(ucdrBuffer* ub, uxrOutputReliableStream* stream)
{
uint8_t* last_buffer = uxr_get_output_buffer(stream, stream->last_written % stream->history);
uint8_t last_fragment_flag = FLAG_LAST_FRAGMENT * (last_buffer == ub->init);
(void) uxr_buffer_submessage_header(ub, SUBMESSAGE_ID_FRAGMENT, (uint16_t)(ucdr_buffer_remaining(ub) - SUBHEADER_SIZE), last_fragment_flag);
}
FragmentationInfo on_get_fragmentation_info(uint8_t* submessage_header)
{
ucdrBuffer ub;

View File

@ -1,9 +1,9 @@
#include <uxr/client/defines.h>
#include <uxr/client/core/session/object_id.h>
#include <uxr/client/core/type/xrce_types.h>
#include "session_info_internal.h"
#include "submessage_internal.h"
#include "../serialization/xrce_protocol_internal.h"
#include "../serialization/xrce_header_internal.h"
#include <string.h>
@ -34,8 +34,8 @@ void uxr_init_session_info(uxrSessionInfo* info, uint8_t id, uint32_t key)
void uxr_buffer_create_session(uxrSessionInfo* info, ucdrBuffer* ub, uint16_t mtu)
{
CREATE_CLIENT_Payload payload;
payload.client_representation.xrce_cookie = XRCE_COOKIE;
payload.client_representation.xrce_version = XRCE_VERSION;
payload.client_representation.xrce_cookie = DDS_XRCE_XRCE_COOKIE;
payload.client_representation.xrce_version = DDS_XRCE_XRCE_VERSION;
payload.client_representation.xrce_vendor_id = VENDOR_ID_EPROSIMA;
payload.client_representation.client_key.data[0] = info->key[0];
payload.client_representation.client_key.data[1] = info->key[1];
@ -55,7 +55,7 @@ void uxr_buffer_delete_session(uxrSessionInfo* info, ucdrBuffer* ub)
{
DELETE_Payload payload;
payload.base.request_id = COMPOUND_LITERAL(RequestId){{0x00, UXR_REQUEST_LOGOUT}};
payload.base.object_id = OBJECTID_CLIENT;
payload.base.object_id = DDS_XRCE_OBJECTID_CLIENT;
info->last_request_id = UXR_REQUEST_LOGOUT;

View File

@ -1,4 +1,4 @@
// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima).
// Copyright 2017-present Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -12,14 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _SRC_C_CORE_SESSION_STREAM_COMMON_RELIABLE_STREAM_INTERNAL_H_
#define _SRC_C_CORE_SESSION_STREAM_COMMON_RELIABLE_STREAM_INTERNAL_H_
#ifndef SRC__C__CORE__SESSION__STREAM__COMMON_RELIABLE_STREAM_INTERNAL_H_
#define SRC__C__CORE__SESSION__STREAM__COMMON_RELIABLE_STREAM_INTERNAL_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <uxr/client/core/session/stream/reliable_stream.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
@ -28,33 +30,54 @@ extern "C"
typedef uint32_t length_t;
#define INTERNAL_RELIABLE_BUFFER_OFFSET sizeof(length_t)
static inline uint8_t * uxr_get_reliable_buffer(
uxrReliableStream const * stream,
uint16_t seq_num)
{
return stream->buffer
+ ((seq_num % stream->history) * (stream->size / stream->history))
+ INTERNAL_RELIABLE_BUFFER_OFFSET;
}
static inline size_t uxr_get_reliable_buffer_length(uint8_t* buffer)
static inline size_t uxr_get_reliable_buffer_capacity(
uxrReliableStream const * stream)
{
return stream->size / stream->history - INTERNAL_RELIABLE_BUFFER_OFFSET;
}
static inline uint16_t uxr_get_reliable_buffer_history_position(
uxrReliableStream const * stream,
uint8_t const * current_position)
{
return (uint16_t)((size_t)(current_position - stream->buffer) / (stream->size / stream->history));
}
static inline size_t uxr_get_reliable_buffer_size(
uxrReliableStream const * stream,
uint16_t seq_num)
{
length_t length;
memcpy(&length, buffer - INTERNAL_RELIABLE_BUFFER_OFFSET, INTERNAL_RELIABLE_BUFFER_OFFSET);
memcpy(
&length,
uxr_get_reliable_buffer(stream, (seq_num % stream->history)) - INTERNAL_RELIABLE_BUFFER_OFFSET,
sizeof(length_t));
return (size_t)length;
}
static inline void uxr_set_reliable_buffer_length(uint8_t* buffer, size_t length)
static inline void uxr_set_reliable_buffer_size(
uxrReliableStream const * stream,
uint16_t seq_num,
size_t length)
{
length_t internal_length = (length_t)length;
memcpy(buffer - INTERNAL_RELIABLE_BUFFER_OFFSET, &internal_length, INTERNAL_RELIABLE_BUFFER_OFFSET);
length_t temp_length = (length_t)length;
memcpy(
uxr_get_reliable_buffer(stream, (seq_num % stream->history)) - INTERNAL_RELIABLE_BUFFER_OFFSET,
&temp_length,
INTERNAL_RELIABLE_BUFFER_OFFSET);
}
static inline uint8_t* uxr_get_reliable_buffer(uint8_t* buffer, size_t size, size_t history, size_t history_pos)
{
return buffer + history_pos * (size / history) + INTERNAL_RELIABLE_BUFFER_OFFSET;
}
static inline size_t uxr_get_reliable_buffer_size(size_t size, size_t history)
{
return size / history - INTERNAL_RELIABLE_BUFFER_OFFSET;
}
#ifdef __cplusplus
}
#endif
#endif // _SRC_C_CORE_SESSION_STREAM_COMMON_RELIABLE_STREAM_INTERNAL_H_
#endif // SRC__C__CORE__SESSION__STREAM__COMMON_RELIABLE_STREAM_INTERNAL_H_

View File

@ -1,8 +1,10 @@
#include "seq_num_internal.h"
#include "input_reliable_stream_internal.h"
#include "common_reliable_stream_internal.h"
#include <ucdr/microcdr.h>
#include "./seq_num_internal.h"
#include "./input_reliable_stream_internal.h"
#include "./common_reliable_stream_internal.h"
#include "../submessage_internal.h"
#include <string.h>
static bool check_last_fragment(uxrInputReliableStream* stream, uxrSeqNum* last);
@ -15,20 +17,20 @@ static bool on_full_input_buffer(ucdrBuffer* ub, void* args);
void uxr_init_input_reliable_stream(uxrInputReliableStream* stream, uint8_t* buffer, size_t size, uint16_t history, OnGetFragmentationInfo on_get_fragmentation_info)
{
// assert for history (must be 2^)
stream->buffer = buffer;
stream->size = size;
stream->history = history;
stream->base.buffer = buffer;
stream->base.size = size;
stream->base.history = history;
stream->on_get_fragmentation_info = on_get_fragmentation_info;
stream->cleanup_flag = false;
uxr_reset_input_reliable_stream(stream);
}
void uxr_reset_input_reliable_stream(uxrInputReliableStream* stream)
{
for(size_t i = 0; i < stream->history; ++i)
for(uint16_t i = 0; i < stream->base.history; ++i)
{
uint8_t* internal_buffer = uxr_get_input_buffer(stream, i);
uxr_set_reliable_buffer_length(internal_buffer, 0);
uxr_set_reliable_buffer_size(&stream->base, i, 0);
}
stream->last_handled = SEQ_NUM_MAX;
@ -40,7 +42,7 @@ bool uxr_receive_reliable_message(uxrInputReliableStream* stream, uint16_t seq_n
bool ready_to_read = false;
/* Check if the seq_num is valid for the stream state */
uxrSeqNum last_history = uxr_seq_num_add(stream->last_handled, stream->history);
uxrSeqNum last_history = uxr_seq_num_add(stream->last_handled, stream->base.history);
if(0 > uxr_seq_num_cmp(stream->last_handled, seq_num) && 0 <= uxr_seq_num_cmp(last_history, seq_num))
{
/* Process the message */
@ -56,11 +58,11 @@ bool uxr_receive_reliable_message(uxrInputReliableStream* stream, uint16_t seq_n
else
{
/* Check if the message received is not already received */
uint8_t* internal_buffer = uxr_get_input_buffer(stream, seq_num % stream->history);
if(0 == uxr_get_reliable_buffer_length(internal_buffer))
uint8_t * internal_buffer = uxr_get_reliable_buffer(&stream->base, seq_num);
if(0 == uxr_get_reliable_buffer_size(&stream->base, seq_num))
{
memcpy(internal_buffer, buffer, length);
uxr_set_reliable_buffer_length(internal_buffer, length);
uxr_set_reliable_buffer_size(&stream->base, seq_num, length);
*message_stored = true;
if(NO_FRAGMENTED != fragmentation_info)
@ -86,16 +88,16 @@ bool uxr_receive_reliable_message(uxrInputReliableStream* stream, uint16_t seq_n
bool uxr_next_input_reliable_buffer_available(uxrInputReliableStream* stream, ucdrBuffer* ub, size_t fragment_offset)
{
uxrSeqNum next = uxr_seq_num_add(stream->last_handled, 1);
uint8_t* internal_buffer = uxr_get_input_buffer(stream, next % stream->history);
size_t length = uxr_get_reliable_buffer_length(internal_buffer);
bool available_to_read = 0 != length;
uint8_t* internal_buffer = uxr_get_reliable_buffer(&stream->base, next);
size_t length = uxr_get_reliable_buffer_size(&stream->base, next);
bool available_to_read = (0 != length);
if(available_to_read)
{
FragmentationInfo fragmentation_info = stream->on_get_fragmentation_info(internal_buffer);
if(NO_FRAGMENTED == fragmentation_info)
{
ucdr_init_buffer(ub, internal_buffer, (uint32_t)length);
uxr_set_reliable_buffer_length(internal_buffer, 0);
uxr_set_reliable_buffer_size(&stream->base, next, 0);
stream->last_handled = next;
}
else
@ -104,7 +106,7 @@ bool uxr_next_input_reliable_buffer_available(uxrInputReliableStream* stream, uc
available_to_read = check_last_fragment(stream, &last);
if(available_to_read)
{
uxr_set_reliable_buffer_length(internal_buffer, 0);
uxr_set_reliable_buffer_size(&stream->base, next, 0);
ucdr_init_buffer(ub, internal_buffer + fragment_offset, (uint32_t)(length - fragment_offset));
ucdr_set_on_full_buffer_callback(ub, on_full_input_buffer, stream);
stream->last_handled = last;
@ -140,8 +142,7 @@ uint16_t uxr_compute_acknack(const uxrInputReliableStream* stream, uxrSeqNum* fr
for(size_t i = 0; i < buffers_to_ack; ++i)
{
uxrSeqNum seq_num = uxr_seq_num_add(*from, (uxrSeqNum)i);
uint8_t* internal_buffer = uxr_get_input_buffer(stream, seq_num % stream->history);
if(0 == uxr_get_reliable_buffer_length(internal_buffer))
if(0 == uxr_get_reliable_buffer_size(&stream->base, seq_num))
{
nack_bitmap = (uint16_t)(nack_bitmap | (1 << i));
}
@ -150,16 +151,6 @@ uint16_t uxr_compute_acknack(const uxrInputReliableStream* stream, uxrSeqNum* fr
return nack_bitmap;
}
uint8_t* uxr_get_input_buffer(const uxrInputReliableStream* stream, size_t history_pos)
{
return uxr_get_reliable_buffer(stream->buffer, stream->size, stream->history, history_pos);
}
size_t uxr_get_input_buffer_size(const uxrInputReliableStream* stream)
{
return uxr_get_reliable_buffer_size(stream->size, stream->history);
}
//==================================================================
// PRIVATE
//==================================================================
@ -171,8 +162,8 @@ bool check_last_fragment(uxrInputReliableStream* stream, uxrSeqNum* last_fragmen
do
{
next = uxr_seq_num_add(next, 1);
uint8_t* next_buffer = uxr_get_input_buffer(stream, next % stream->history);
more_messages = 0 != uxr_get_reliable_buffer_length(next_buffer);
uint8_t* next_buffer = uxr_get_reliable_buffer(&stream->base, next);
more_messages = (0 != uxr_get_reliable_buffer_size(&stream->base, next));
if(more_messages)
{
FragmentationInfo next_fragmentation_info = stream->on_get_fragmentation_info(next_buffer);
@ -193,11 +184,10 @@ bool check_last_fragment(uxrInputReliableStream* stream, uxrSeqNum* last_fragmen
uxrSeqNum uxr_get_first_unacked(const uxrInputReliableStream* stream)
{
uxrSeqNum first_unknown = stream->last_handled;
for(size_t i = 0; i < stream->history; ++i)
for(size_t i = 0; i < stream->base.history; ++i)
{
uxrSeqNum seq_num = uxr_seq_num_add(stream->last_handled, (uint16_t)(i + 1));
uint8_t* buffer = uxr_get_input_buffer(stream, seq_num % stream->history);
if(0 == uxr_get_reliable_buffer_length(buffer))
if(0 == uxr_get_reliable_buffer_size(&stream->base, seq_num))
{
first_unknown = seq_num;
break;
@ -211,16 +201,20 @@ bool on_full_input_buffer(ucdrBuffer* ub, void* args)
{
uxrInputReliableStream* stream = (uxrInputReliableStream*) args;
size_t slot_pos = (size_t)(ub->init - stream->buffer) / (stream->size / stream->history);
uint8_t* buffer = uxr_get_input_buffer(stream, slot_pos % stream->history);
uint8_t* next_buffer = uxr_get_input_buffer(stream, (slot_pos + 1) % stream->history);
size_t offset = (size_t)(ub->init - buffer);
uint16_t history_position = (uint16_t)(1 + uxr_get_reliable_buffer_history_position(&stream->base, ub->init));
uint8_t * buffer = uxr_get_reliable_buffer(&stream->base, history_position);
size_t buffer_size = uxr_get_reliable_buffer_size(&stream->base, history_position);
uint8_t* next_init = next_buffer + offset;
size_t next_length = uxr_get_reliable_buffer_length(next_buffer) - offset;
uxr_set_reliable_buffer_length(next_buffer, 0);
if (stream->cleanup_flag)
{
uxr_set_reliable_buffer_size(&stream->base, history_position, 0);
}
ucdr_init_buffer(ub, next_init, (uint32_t)next_length);
ucdr_init_buffer_origin(
ub,
buffer + SUBHEADER_SIZE,
(uint32_t)(buffer_size - SUBHEADER_SIZE),
ub->offset);
ucdr_set_on_full_buffer_callback(ub, on_full_input_buffer, stream);
return false;

View File

@ -40,9 +40,6 @@ void uxr_process_heartbeat(uxrInputReliableStream* stream, uxrSeqNum first_seq_n
bool uxr_is_input_up_to_date(const uxrInputReliableStream* stream);
uint8_t* uxr_get_input_buffer(const uxrInputReliableStream* stream, size_t history_pos);
size_t uxr_get_input_buffer_size(const uxrInputReliableStream* stream);
#ifdef __cplusplus
}
#endif

View File

@ -31,7 +31,7 @@ bool uxr_prepare_best_effort_buffer_to_write(uxrOutputBestEffortStream* stream,
bool available_to_write = future_length <= stream->size;
if(available_to_write)
{
ucdr_init_buffer_offset(ub, stream->buffer, (uint32_t)future_length, (uint32_t)(stream->writer + current_padding));
ucdr_init_buffer_origin_offset(ub, stream->buffer, (uint32_t)future_length, 0u, (uint32_t)(stream->writer + current_padding));
stream->writer += size;
}

View File

@ -1,12 +1,13 @@
#include "output_reliable_stream_internal.h"
#include <uxr/client/config.h>
#include <ucdr/microcdr.h>
#include <string.h>
#include "seq_num_internal.h"
#include "output_reliable_stream_internal.h"
#include "common_reliable_stream_internal.h"
#include <ucdr/microcdr.h>
#include "./seq_num_internal.h"
#include "./output_reliable_stream_internal.h"
#include "./common_reliable_stream_internal.h"
#include "../submessage_internal.h"
#define MIN_HEARTBEAT_TIME_INTERVAL ((int64_t) UXR_CONFIG_MIN_HEARTBEAT_TIME_INTERVAL) // ms
#define MAX_HEARTBEAT_TRIES (sizeof(int64_t) * 8 - 1)
@ -16,25 +17,23 @@ static bool on_full_output_buffer(ucdrBuffer* ub, void* args);
//==================================================================
// PUBLIC
//==================================================================
void uxr_init_output_reliable_stream(uxrOutputReliableStream* stream, uint8_t* buffer, size_t size, uint16_t history, uint8_t header_offset, OnNewFragment on_new_fragment)
void uxr_init_output_reliable_stream(uxrOutputReliableStream* stream, uint8_t* buffer, size_t size, uint16_t history, uint8_t header_offset)
{
// assert for history (must be 2^)
stream->buffer = buffer;
stream->size = size;
stream->base.buffer = buffer;
stream->base.size = size;
stream->base.history = history;
stream->offset = header_offset;
stream->history = history;
stream->on_new_fragment = on_new_fragment;
uxr_reset_output_reliable_stream(stream);
}
void uxr_reset_output_reliable_stream(uxrOutputReliableStream* stream)
{
for(size_t i = 0; i < stream->history; i++)
for(uint16_t i = 0; i < stream->base.history; ++i)
{
uint8_t* internal_buffer = uxr_get_output_buffer(stream, i);
uxr_set_reliable_buffer_length(internal_buffer, stream->offset);
uxr_set_reliable_buffer_size(&stream->base, i, stream->offset);
}
stream->last_written = 0;
@ -46,81 +45,105 @@ void uxr_reset_output_reliable_stream(uxrOutputReliableStream* stream)
stream->send_lost = false;
}
bool uxr_prepare_reliable_buffer_to_write(uxrOutputReliableStream* stream, size_t length, size_t fragment_offset, ucdrBuffer* ub)
bool uxr_prepare_reliable_buffer_to_write(uxrOutputReliableStream* stream, size_t length, ucdrBuffer* ub)
{
bool available_to_write = false;
size_t block_size = uxr_get_output_buffer_size(stream);
uint8_t* initial_buffer = uxr_get_output_buffer(stream, stream->last_written % stream->history);
size_t initial_length = uxr_get_reliable_buffer_length(initial_buffer);
uxrSeqNum seq_num = stream->last_written;
size_t buffer_capacity = uxr_get_reliable_buffer_capacity(&stream->base);
uint8_t * buffer = uxr_get_reliable_buffer(&stream->base, seq_num);
size_t buffer_size = uxr_get_reliable_buffer_size(&stream->base, seq_num);
/* Check if the message fit in the current buffer */
if(initial_length + length <= block_size)
if(buffer_size + length <= buffer_capacity)
{
/* Check if there is space in the stream history to write */
uxrSeqNum last_available = uxr_seq_num_add(stream->last_acknown, stream->history);
available_to_write = 0 >= uxr_seq_num_cmp(stream->last_written, last_available);
uxrSeqNum last_available = uxr_seq_num_add(stream->last_acknown, stream->base.history);
available_to_write = (0 >= uxr_seq_num_cmp(seq_num, last_available));
if(available_to_write)
{
size_t future_length = initial_length + length;
uxr_set_reliable_buffer_length(initial_buffer, future_length);
ucdr_init_buffer_offset(ub, initial_buffer, (uint32_t)future_length, (uint32_t)initial_length);
size_t final_buffer_size = buffer_size + length;
uxr_set_reliable_buffer_size(&stream->base, seq_num, final_buffer_size);
ucdr_init_buffer_origin_offset(ub, buffer, (uint32_t)final_buffer_size, 0u, (uint32_t)buffer_size);
}
}
/* Check if the message fit in a new empty buffer */
else if(stream->offset + length <= block_size)
else if(stream->offset + length <= buffer_capacity)
{
/* Check if there is space in the stream history to write */
uxrSeqNum next = uxr_seq_num_add(stream->last_written, 1);
uxrSeqNum last_available = uxr_seq_num_add(stream->last_acknown, stream->history);
available_to_write = 0 >= uxr_seq_num_cmp(next, last_available);
seq_num = uxr_seq_num_add(stream->last_written, 1);
uxrSeqNum last_available = uxr_seq_num_add(stream->last_acknown, stream->base.history);
available_to_write = (0 >= uxr_seq_num_cmp(seq_num, last_available));
if(available_to_write)
{
stream->last_written = next;
uint8_t* buffer = uxr_get_output_buffer(stream, next % stream->history);
size_t future_length = stream->offset + length;
uxr_set_reliable_buffer_length(buffer, future_length);
ucdr_init_buffer_offset(ub, buffer, (uint32_t)future_length, stream->offset);
buffer = uxr_get_reliable_buffer(&stream->base, seq_num);
size_t final_buffer_size = stream->offset + length;
uxr_set_reliable_buffer_size(&stream->base, seq_num, final_buffer_size);
ucdr_init_buffer_origin_offset(ub, buffer, (uint32_t)final_buffer_size, 0u, stream->offset);
stream->last_written = seq_num;
}
}
/* Check if the message fit in a fragmented message */
else
{
size_t remaining_blocks = uxr_seq_num_sub(stream->last_acknown, stream->last_written) % stream->history;
uxrSeqNum init = stream->last_written;
size_t remaining_blocks = uxr_seq_num_sub(stream->last_acknown, seq_num) % stream->base.history;
/* Check if the current buffer free space is too small */
if(initial_length + fragment_offset >= block_size)
if(buffer_size + (size_t)SUBHEADER_SIZE >= buffer_capacity)
{
init = uxr_seq_num_add(stream->last_written, 1);
initial_buffer = uxr_get_output_buffer(stream, init % stream->history);
initial_length = uxr_get_reliable_buffer_length(initial_buffer);
seq_num = uxr_seq_num_add(seq_num, 1);
buffer = uxr_get_reliable_buffer(&stream->base, seq_num);
buffer_size = uxr_get_reliable_buffer_size(&stream->base, seq_num);
remaining_blocks = (0 < remaining_blocks) ? remaining_blocks - 1 : 0;
}
size_t available_block_size = block_size - (stream->offset + fragment_offset);
size_t first_fragment_size = (block_size - (initial_length + fragment_offset));
size_t remaining_size = length - first_fragment_size;
size_t last_fragment_size = (remaining_size % available_block_size);
size_t necessary_blocks = (size_t)(0 < first_fragment_size) + (remaining_size / available_block_size) + (size_t)(0 < last_fragment_size);
uint16_t available_block_size = (uint16_t)(buffer_capacity - (uint16_t)(stream->offset + SUBHEADER_SIZE));
uint16_t first_fragment_size = (uint16_t)(buffer_capacity - (uint16_t)(buffer_size + SUBHEADER_SIZE));
uint16_t remaining_size = (uint16_t)(length - first_fragment_size);
uint16_t last_fragment_size;
uint16_t necessary_blocks;
if (0 == (remaining_size % available_block_size))
{
last_fragment_size = available_block_size;
necessary_blocks = (uint16_t)((0 < first_fragment_size) + (remaining_size / available_block_size));
}
else
{
last_fragment_size = remaining_size % available_block_size;
necessary_blocks = (uint16_t)((0 < first_fragment_size) + (remaining_size / available_block_size) + 1);
}
available_to_write = necessary_blocks <= remaining_blocks;
if(available_to_write)
{
stream->last_written = init;
for(size_t i = 0; i < necessary_blocks - 1; i++)
ucdrBuffer temp_ub;
for(uint16_t i = 0; i < necessary_blocks - 1; i++)
{
uint8_t* buffer = uxr_get_output_buffer(stream, stream->last_written % stream->history);
uxr_set_reliable_buffer_length(buffer, block_size);
stream->last_written = uxr_seq_num_add(stream->last_written, 1);
ucdr_init_buffer_origin_offset(
&temp_ub,
uxr_get_reliable_buffer(&stream->base, seq_num),
buffer_capacity,
0u,
uxr_get_reliable_buffer_size(&stream->base, seq_num));
uxr_buffer_submessage_header(&temp_ub, SUBMESSAGE_ID_FRAGMENT, available_block_size, 0);
uxr_set_reliable_buffer_size(&stream->base, seq_num, buffer_capacity);
seq_num = uxr_seq_num_add(seq_num, 1);
}
uint8_t* final_buffer = uxr_get_output_buffer(stream, stream->last_written % stream->history);
uxr_set_reliable_buffer_length(final_buffer, stream->offset + fragment_offset + last_fragment_size);
ucdr_init_buffer_origin_offset(
&temp_ub,
uxr_get_reliable_buffer(&stream->base, seq_num),
buffer_capacity,
0u,
uxr_get_reliable_buffer_size(&stream->base, seq_num));
uxr_buffer_submessage_header(&temp_ub, SUBMESSAGE_ID_FRAGMENT, last_fragment_size, FLAG_LAST_FRAGMENT);
uxr_set_reliable_buffer_size(&stream->base, seq_num, stream->offset + (size_t)(SUBHEADER_SIZE) + last_fragment_size);
ucdr_init_buffer_offset(ub, initial_buffer, (uint32_t)block_size, (uint32_t)initial_length);
ucdr_init_buffer(
ub,
buffer + buffer_size + SUBHEADER_SIZE,
(uint32_t)(buffer_capacity - buffer_size - SUBHEADER_SIZE));
ucdr_set_on_full_buffer_callback(ub, on_full_output_buffer, stream);
stream->on_new_fragment(ub, stream);
stream->last_written = seq_num;
}
}
@ -130,12 +153,12 @@ bool uxr_prepare_reliable_buffer_to_write(uxrOutputReliableStream* stream, size_
bool uxr_prepare_next_reliable_buffer_to_send(uxrOutputReliableStream* stream, uint8_t** buffer, size_t* length, uxrSeqNum* seq_num)
{
*seq_num = uxr_seq_num_add(stream->last_sent, 1);
*buffer = uxr_get_output_buffer(stream, *seq_num % stream->history);
*length = uxr_get_reliable_buffer_length(*buffer);
*buffer = uxr_get_reliable_buffer(&stream->base, *seq_num);
*length = uxr_get_reliable_buffer_size(&stream->base, *seq_num);
bool data_to_send = 0 >= uxr_seq_num_cmp(*seq_num, stream->last_written)
&& *length > stream->offset
&& uxr_seq_num_sub(stream->last_sent, stream->last_acknown) != stream->history;
&& uxr_seq_num_sub(stream->last_sent, stream->last_acknown) != stream->base.history;
if(data_to_send)
{
stream->last_sent = *seq_num;
@ -192,8 +215,8 @@ bool uxr_next_reliable_nack_buffer_to_send(uxrOutputReliableStream* stream, uint
check_next_buffer = 0 >= uxr_seq_num_cmp(*seq_num_it, stream->last_sent);
if(check_next_buffer)
{
*buffer = uxr_get_output_buffer(stream, *seq_num_it % stream->history);
*length = uxr_get_reliable_buffer_length(*buffer);
*buffer = uxr_get_reliable_buffer(&stream->base, *seq_num_it);
*length = uxr_get_reliable_buffer_size(&stream->base, *seq_num_it);
it_updated = *length != stream->offset;
}
}
@ -214,8 +237,7 @@ void uxr_process_acknack(uxrOutputReliableStream* stream, uint16_t bitmap, uxrSe
for(size_t i = 0; i < buffers_to_clean; i++)
{
stream->last_acknown = uxr_seq_num_add(stream->last_acknown, 1);
uint8_t* internal_buffer = uxr_get_output_buffer(stream, stream->last_acknown % stream->history);
uxr_set_reliable_buffer_length(internal_buffer, stream->offset); /* clear buffer */
uxr_set_reliable_buffer_size(&stream->base, stream->last_acknown, stream->offset);
}
stream->send_lost = (0 < bitmap);
@ -229,16 +251,6 @@ bool uxr_is_output_up_to_date(const uxrOutputReliableStream* stream)
return 0 == uxr_seq_num_cmp(stream->last_acknown, stream->last_sent);
}
uint8_t* uxr_get_output_buffer(const uxrOutputReliableStream* stream, size_t history_pos)
{
return uxr_get_reliable_buffer(stream->buffer, stream->size, stream->history, history_pos);
}
size_t uxr_get_output_buffer_size(const uxrOutputReliableStream* stream)
{
return uxr_get_reliable_buffer_size(stream->size, stream->history);
}
//==================================================================
// PRIVATE
//==================================================================
@ -246,15 +258,17 @@ bool on_full_output_buffer(ucdrBuffer* ub, void* args)
{
uxrOutputReliableStream* stream = (uxrOutputReliableStream*) args;
size_t slot = (size_t)(ub->init - stream->buffer) / (stream->size / stream->history);
uint8_t* next_buffer = uxr_get_output_buffer(stream, (slot + 1) % stream->history);
size_t next_length = uxr_get_reliable_buffer_length(next_buffer);
uint16_t history_position = (uint16_t)(1 + uxr_get_reliable_buffer_history_position(&stream->base, ub->init));
uint8_t* buffer = uxr_get_reliable_buffer(&stream->base, history_position);
size_t buffer_size = uxr_get_reliable_buffer_size(&stream->base, history_position);
ucdr_init_buffer_offset(ub, next_buffer, (uint32_t)next_length, stream->offset);
ucdr_init_buffer_origin(
ub,
buffer + stream->offset + SUBHEADER_SIZE,
(uint32_t)(buffer_size - stream->offset - SUBHEADER_SIZE),
ub->offset);
ucdr_set_on_full_buffer_callback(ub, on_full_output_buffer, stream);
stream->on_new_fragment(ub, stream);
return false;
}

View File

@ -28,9 +28,9 @@ extern "C"
#define HEARTBEAT_PAYLOAD_SIZE 5
void uxr_init_output_reliable_stream(uxrOutputReliableStream* stream, uint8_t* buffer, size_t size, uint16_t history, uint8_t header_offset, OnNewFragment on_new_fragment);
void uxr_init_output_reliable_stream(uxrOutputReliableStream* stream, uint8_t* buffer, size_t size, uint16_t history, uint8_t header_offset);
void uxr_reset_output_reliable_stream(uxrOutputReliableStream* stream);
bool uxr_prepare_reliable_buffer_to_write(uxrOutputReliableStream* stream, size_t size, size_t fragment_offset, struct ucdrBuffer* ub);
bool uxr_prepare_reliable_buffer_to_write(uxrOutputReliableStream* stream, size_t size, struct ucdrBuffer* ub);
bool uxr_prepare_next_reliable_buffer_to_send(uxrOutputReliableStream* stream, uint8_t** buffer, size_t* length, uxrSeqNum* seq_num);
bool uxr_update_output_stream_heartbeat_timestamp(uxrOutputReliableStream* stream, int64_t current_timestamp);
@ -40,9 +40,6 @@ void uxr_process_acknack(uxrOutputReliableStream* stream, uint16_t bitmap, uxrSe
bool uxr_is_output_up_to_date(const uxrOutputReliableStream* stream);
uint8_t* uxr_get_output_buffer(const uxrOutputReliableStream* stream, size_t history_pos);
size_t uxr_get_output_buffer_size(const uxrOutputReliableStream* stream);
#ifdef __cplusplus
}
#endif

View File

@ -47,12 +47,12 @@ uxrStreamId uxr_add_output_best_effort_buffer(uxrStreamStorage* storage, uint8_t
return uxr_stream_id(index, UXR_BEST_EFFORT_STREAM, UXR_OUTPUT_STREAM);
}
uxrStreamId uxr_add_output_reliable_buffer(uxrStreamStorage* storage, uint8_t* buffer, size_t size, uint16_t history, uint8_t header_offset, OnNewFragment on_new_fragment)
uxrStreamId uxr_add_output_reliable_buffer(uxrStreamStorage* storage, uint8_t* buffer, size_t size, uint16_t history, uint8_t header_offset)
{
uint8_t index = storage->output_reliable_size++;
//TODO: assert for index
uxrOutputReliableStream* stream = &storage->output_reliable[index];
uxr_init_output_reliable_stream(stream, buffer, size, history, header_offset, on_new_fragment);
uxr_init_output_reliable_stream(stream, buffer, size, history, header_offset);
return uxr_stream_id(index, UXR_RELIABLE_STREAM, UXR_OUTPUT_STREAM);
}

View File

@ -32,7 +32,7 @@ void uxr_init_stream_storage(uxrStreamStorage* storage);
void uxr_reset_stream_storage(uxrStreamStorage* storage);
uxrStreamId uxr_add_output_best_effort_buffer(uxrStreamStorage* storage, uint8_t* buffer, size_t size, uint8_t header_offset);
uxrStreamId uxr_add_output_reliable_buffer(uxrStreamStorage* storage, uint8_t* buffer, size_t size, uint16_t history, uint8_t header_offset, OnNewFragment on_new_fragment);
uxrStreamId uxr_add_output_reliable_buffer(uxrStreamStorage* storage, uint8_t* buffer, size_t size, uint16_t history, uint8_t header_offset);
uxrStreamId uxr_add_input_best_effort_buffer(uxrStreamStorage* storage);
uxrStreamId uxr_add_input_reliable_buffer(uxrStreamStorage* storage, uint8_t* buffer, size_t size, uint16_t history, OnGetFragmentationInfo on_get_fragmentation_info);

View File

@ -1,15 +1,64 @@
#include <uxr/client/core/session/write_access.h>
#include <uxr/client/core/type/xrce_types.h>
#include "session_internal.h"
#include "session_info_internal.h"
#include "submessage_internal.h"
#include "../serialization/xrce_protocol_internal.h"
#define WRITE_DATA_PAYLOAD_SIZE 4
#define SAMPLE_IDENTITY_SIZE 24
//==================================================================
// PUBLIC
//==================================================================
uint16_t uxr_buffer_request(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId requester_id,
uint8_t* buffer,
size_t len)
{
uint16_t rv = UXR_INVALID_REQUEST_ID;
ucdrBuffer ub;
size_t payload_size = WRITE_DATA_PAYLOAD_SIZE + len;
ub.error = !uxr_prepare_stream_to_write_submessage(session, stream_id, payload_size, &ub, SUBMESSAGE_ID_WRITE_DATA, FORMAT_DATA);
if (!ub.error)
{
WRITE_DATA_Payload_Data payload;
rv = uxr_init_base_object_request(&session->info, requester_id, &payload.base);
uxr_serialize_WRITE_DATA_Payload_Data(&ub, &payload);
ucdr_serialize_array_uint8_t(&ub, buffer, len);
}
return rv;
}
uint16_t uxr_buffer_reply(
uxrSession* session,
uxrStreamId stream_id,
uxrObjectId replier_id,
SampleIdentity* sample_id,
uint8_t* buffer,
size_t len)
{
uint16_t rv = UXR_INVALID_REQUEST_ID;
ucdrBuffer ub;
size_t payload_size = WRITE_DATA_PAYLOAD_SIZE + SAMPLE_IDENTITY_SIZE + len;
ub.error = !uxr_prepare_stream_to_write_submessage(session, stream_id, payload_size, &ub, SUBMESSAGE_ID_WRITE_DATA, FORMAT_DATA);
if (!ub.error)
{
WRITE_DATA_Payload_Data payload;
rv = uxr_init_base_object_request(&session->info, replier_id, &payload.base);
uxr_serialize_WRITE_DATA_Payload_Data(&ub, &payload);
uxr_serialize_SampleIdentity(&ub, sample_id);
ucdr_serialize_array_uint8_t(&ub, buffer, len);
}
return rv;
}
bool uxr_prepare_output_stream(uxrSession* session, uxrStreamId stream_id, uxrObjectId datawriter_id,
ucdrBuffer* ub, uint32_t topic_size)
{
@ -21,7 +70,10 @@ bool uxr_prepare_output_stream(uxrSession* session, uxrStreamId stream_id, uxrOb
uxr_init_base_object_request(&session->info, datawriter_id, &payload.base);
(void) uxr_serialize_WRITE_DATA_Payload_Data(ub, &payload);
ub->last_data_size = 8; //reset alignment (as if we were created a new ucdrBuffer)
OnFullBuffer on_full_buffer = ub->on_full_buffer;
void* args = ub->args;
ucdr_init_buffer(ub, ub->iterator, (size_t)(ub->final - ub->iterator));
ucdr_set_on_full_buffer_callback(ub, on_full_buffer, args);
}
return !ub->error;

View File

@ -1,9 +1,10 @@
#include <uxr/client/profile/discovery/discovery.h>
#include <uxr/client/profile/transport/ip/ip.h>
#include <uxr/client/core/session/object_id.h>
#include <uxr/client/core/session/stream/seq_num.h>
#include <uxr/client/core/type/xrce_types.h>
#include <uxr/client/util/time.h>
#include "../../core/serialization/xrce_protocol_internal.h"
#include "../../core/serialization/xrce_header_internal.h"
#include "../../core/session/submessage_internal.h"
#include "../../core/log/log_internal.h"
@ -28,7 +29,6 @@ static void write_get_info_message(ucdrBuffer* ub);
static bool listen_info_message(uxrUDPTransportDatagram* transport, int period, CallbackData* callback);
static bool read_info_headers(ucdrBuffer* ub);
static bool read_info_message(ucdrBuffer* ub, CallbackData* callback);
static bool process_info(CallbackData* callback, TransportLocator* transport);
//==================================================================
// PUBLIC
@ -40,7 +40,8 @@ void uxr_discovery_agents_default(
uxrOnAgentFound on_agent_func,
void* args)
{
uxrAgentAddress multicast = {MULTICAST_DEFAULT_IP, MULTICAST_DEFAULT_PORT};
TransportLocator multicast;
uxr_ip_to_locator(MULTICAST_DEFAULT_IP, (uint16_t)MULTICAST_DEFAULT_PORT, UXR_IPv4, &multicast);
uxr_discovery_agents(attempts, period, on_agent_func, args, &multicast, 1);
}
@ -49,7 +50,7 @@ void uxr_discovery_agents(
int period,
uxrOnAgentFound on_agent_func,
void* args,
const uxrAgentAddress* agent_list,
const TransportLocator* agent_list,
size_t agent_list_size)
{
CallbackData callback;
@ -70,7 +71,7 @@ void uxr_discovery_agents(
{
for(size_t i = 0; i < agent_list_size; ++i)
{
(void) uxr_udp_send_datagram_to(&transport, output_buffer, message_length, agent_list[i].ip, agent_list[i].port);
(void) uxr_udp_send_datagram_to(&transport, output_buffer, message_length, &agent_list[i]);
UXR_DEBUG_PRINT_MESSAGE(UXR_SEND, output_buffer, message_length, 0);
}
@ -93,7 +94,7 @@ void write_get_info_message(ucdrBuffer* ub)
{
GET_INFO_Payload payload;
payload.base.request_id = (RequestId){{0x00, GET_INFO_REQUEST_ID}};
payload.base.object_id = OBJECTID_AGENT;
payload.base.object_id = DDS_XRCE_OBJECTID_AGENT;
payload.info_mask = INFO_CONFIGURATION | INFO_ACTIVITY;
uxr_serialize_message_header(ub, SESSION_ID_WITHOUT_CLIENT_KEY, 0, 0, 0);
@ -144,34 +145,16 @@ bool read_info_message(
if(uxr_deserialize_INFO_Payload(ub, &payload))
{
XrceVersion* version = &payload.object_info.config._.agent.xrce_version;
TransportLocator* transport = &payload.object_info.activity._.agent.address_seq.data[0];
if(0 == memcmp(version->data, XRCE_VERSION.data, sizeof(XRCE_VERSION.data)))
TransportLocatorSeq * locators = &payload.object_info.activity._.agent.address_seq;
for (size_t i = 0; i < (size_t)locators->size; ++i)
{
is_succeed = process_info(callback, transport);
TransportLocator* transport = &locators->data[i];
if(0 == memcmp(version->data, DDS_XRCE_XRCE_VERSION.data, sizeof(DDS_XRCE_XRCE_VERSION.data)))
{
is_succeed = callback->on_agent(transport, callback->args);
}
}
}
return is_succeed;
}
bool process_info(
CallbackData* callback,
TransportLocator* locator)
{
bool processed = false;
if(locator->format == ADDRESS_FORMAT_MEDIUM)
{
uxrAgentAddress address;
uxr_bytes_to_ip(locator->_.medium_locator.address, address.ip);
address.port = locator->_.medium_locator.locator_port;
callback->on_agent(&address, callback->args);
processed = true;
}
return processed;
}

View File

@ -22,34 +22,30 @@ extern "C"
#include <uxr/client/visibility.h>
#include <uxr/client/config.h>
#include <uxr/client/core/type/xrce_types.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#if defined(PLATFORM_NAME_LINUX)
#define PLATFORM_TYPE_POSIX
#elif defined(PLATFORM_NAME_NUTTX)
#define PLATFORM_TYPE_POSIX
#endif
#if defined(PLATFORM_TYPE_POSIX)
#if defined(UCLIENT_PLATFORM_POSIX)
#include <sys/types.h>
#include <sys/socket.h>
#include <poll.h>
#elif defined(PLATFORM_NAME_WINDOWS)
#elif defined(UCLIENT_PLATFORM_WINDOWS)
#include <winsock2.h>
#endif
#define UXR_UDP_TRANSPORT_MTU_DATAGRAM 52 //Adjusted to the minimun necessary buffer for discovery messages.
// TODO (julibert): move this to CMake flag.
#define UXR_UDP_TRANSPORT_MTU_DATAGRAM 200 //Adjusted to the minimun necessary buffer for discovery messages.
typedef struct uxrUDPTransportDatagram
{
uint8_t buffer[UXR_UDP_TRANSPORT_MTU_DATAGRAM];
#if defined(PLATFORM_TYPE_POSIX)
#if defined(UCLIENT_PLATFORM_POSIX)
struct pollfd poll_fd;
#elif defined(PLATFORM_NAME_WINDOWS)
#elif defined(UCLIENT_PLATFORM_WINDOWS)
WSAPOLLFD poll_fd;
#endif
@ -61,9 +57,8 @@ bool uxr_init_udp_transport_datagram(
bool uxr_udp_send_datagram_to(
struct uxrUDPTransportDatagram* transport,
const uint8_t* buf,
size_t len,
const char* ip,
uint16_t port);
size_t length,
const TransportLocator* locator);
bool uxr_udp_recv_datagram(
struct uxrUDPTransportDatagram* transport,

View File

@ -25,25 +25,30 @@ bool uxr_udp_send_datagram_to(
uxrUDPTransportDatagram* transport,
const uint8_t* buf,
size_t len,
const char* ip,
uint16_t port)
const TransportLocator* locator)
{
bool rv = true;
struct sockaddr_in remote_addr;
if(0 != inet_aton(ip, &remote_addr.sin_addr))
switch (locator->format)
{
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(port);
ssize_t bytes_sent = sendto(transport->poll_fd.fd, (const void*)buf, len, 0,
(struct sockaddr*)&remote_addr, sizeof(remote_addr));
if (0 > bytes_sent)
case ADDRESS_FORMAT_MEDIUM:
{
rv = false;
}
}
struct sockaddr_in remote_addr;
memcpy(&remote_addr.sin_addr, locator->_.medium_locator.address, sizeof(remote_addr.sin_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(locator->_.medium_locator.locator_port);
ssize_t bytes_sent = sendto(transport->poll_fd.fd, (const void*)buf, len, 0,
(struct sockaddr*)&remote_addr, sizeof(remote_addr));
if (0 > bytes_sent)
{
rv = false;
}
break;
}
default:
rv = false;
break;
}
return rv;
}

View File

@ -3,7 +3,8 @@
#include <WS2tcpip.h>
#include <string.h>
bool uxr_init_udp_transport_datagram(uxrUDPTransportDatagram* transport)
bool uxr_init_udp_transport_datagram(
uxrUDPTransportDatagram* transport)
{
bool rv = false;
@ -24,7 +25,8 @@ bool uxr_init_udp_transport_datagram(uxrUDPTransportDatagram* transport)
return rv;
}
bool uxr_close_udp_transport_datagram(uxrUDPTransportDatagram* transport)
bool uxr_close_udp_transport_datagram(
uxrUDPTransportDatagram* transport)
{
bool rv = (INVALID_SOCKET == transport->poll_fd.fd) ? true : (0 == closesocket(transport->poll_fd.fd));
return (0 == WSACleanup()) && rv;
@ -34,22 +36,26 @@ bool uxr_udp_send_datagram_to(
uxrUDPTransportDatagram* transport,
const uint8_t* buf,
size_t len,
const char* ip,
uint16_t port)
const TransportLocator* locator)
{
bool rv = false;
struct sockaddr_in remote_addr;
if(0 != inet_pton(AF_INET, ip, &remote_addr.sin_addr))
switch (locator->format)
{
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(port);
case ADDRESS_FORMAT_MEDIUM:
{
struct sockaddr_in remote_addr;
memcpy(&remote_addr.sin_addr, locator->_.medium_locator.address, sizeof(remote_addr.sin_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(locator->_.medium_locator.locator_port);
int bytes_sent = sendto(transport->poll_fd.fd, (const char*)buf, (int)len, 0,
(struct sockaddr*)&remote_addr, sizeof(remote_addr));
rv = (SOCKET_ERROR != bytes_sent);
int bytes_sent = sendto(transport->poll_fd.fd, (const char*)buf, (int)len, 0,
(struct sockaddr*)&remote_addr, sizeof(remote_addr));
rv = (SOCKET_ERROR != bytes_sent);
break;
}
default:
break;
}
return rv;
}

View File

@ -0,0 +1,73 @@
// Copyright 2017-present Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <uxr/client/profile/transport/ip/ip.h>
#include <uxr/client/config.h>
#if defined(UCLIENT_PLATFORM_POSIX)
#include <arpa/inet.h>
#elif defined(UCLIENT_PLATFORM_POSIX_NOPOLL)
#include <sys/socket.h>
#endif
bool uxr_ip_to_locator(
char const * ip,
uint16_t port,
uxrIpProtocol ip_protocol,
TransportLocator * locator)
{
bool result = false;
switch (ip_protocol)
{
case UXR_IPv4:
locator->format = ADDRESS_FORMAT_MEDIUM;
locator->_.medium_locator.locator_port = port;
result = (1 == inet_pton(AF_INET, ip, locator->_.medium_locator.address));
break;
case UXR_IPv6:
locator->format = ADDRESS_FORMAT_LARGE;
locator->_.large_locator.locator_port = port;
result = (1 == inet_pton(AF_INET6, ip, locator->_.large_locator.address));
break;
default:
break;
}
return result;
}
bool uxr_locator_to_ip(
TransportLocator const * locator,
char * ip,
size_t size,
uint16_t * port,
uxrIpProtocol * ip_protocol)
{
bool result = false;
switch (locator->format)
{
case ADDRESS_FORMAT_MEDIUM:
*port = locator->_.medium_locator.locator_port;
*ip_protocol = UXR_IPv4;
result = (NULL != inet_ntop(AF_INET, locator->_.medium_locator.address, ip, (socklen_t)size));
break;
case ADDRESS_FORMAT_LARGE:
*port = (uint16_t)locator->_.large_locator.locator_port;
*ip_protocol = UXR_IPv6;
result = (NULL != inet_ntop(AF_INET6, locator->_.large_locator.address, ip, (socklen_t)size));
break;
default:
break;
}
return result;
}

View File

@ -0,0 +1,68 @@
// Copyright 2017-present Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <uxr/client/profile/transport/ip/ip.h>
#include <ws2tcpip.h>
bool uxr_ip_to_locator(
char const * ip,
uint16_t port,
uxrIpProtocol ip_protocol,
TransportLocator * locator)
{
bool result = false;
switch (ip_protocol)
{
case UXR_IPv4:
locator->format = ADDRESS_FORMAT_MEDIUM;
locator->_.medium_locator.locator_port = port;
result = (1 == inet_pton(AF_INET, ip, locator->_.medium_locator.address));
break;
case UXR_IPv6:
locator->format = ADDRESS_FORMAT_LARGE;
locator->_.large_locator.locator_port = port;
result = (1 == inet_pton(AF_INET6, ip, locator->_.large_locator.address));
break;
default:
break;
}
return result;
}
bool uxr_locator_to_ip(
TransportLocator const * locator,
char * ip,
size_t size,
uint16_t * port,
uxrIpProtocol * ip_protocol)
{
bool result = false;
switch (locator->format)
{
case ADDRESS_FORMAT_MEDIUM:
*port = locator->_.medium_locator.locator_port;
*ip_protocol = UXR_IPv4;
result = (NULL != inet_ntop(AF_INET, locator->_.medium_locator.address, ip, (socklen_t)size));
break;
case ADDRESS_FORMAT_LARGE:
*port = (uint16_t)locator->_.large_locator.locator_port;
*ip_protocol = UXR_IPv6;
result = (NULL != inet_ntop(AF_INET6, locator->_.large_locator.address, ip, (socklen_t)size));
break;
default:
break;
}
return result;
}

View File

@ -281,11 +281,16 @@ size_t read_tcp_data(uxrTCPTransport* transport, int timeout)
/*******************************************************************************
* Public function definitions.
*******************************************************************************/
bool uxr_init_tcp_transport(uxrTCPTransport* transport, struct uxrTCPPlatform* platform, const char* ip, uint16_t port)
bool uxr_init_tcp_transport(
uxrTCPTransport* transport,
struct uxrTCPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
const char* port)
{
bool rv = false;
if(uxr_init_tcp_platform(platform, ip, port))
if(uxr_init_tcp_platform(platform, ip_protocol, ip, port))
{
/* Setup platform. */
transport->platform = platform;

View File

@ -0,0 +1,48 @@
#include <uxr/client/profile/transport/ip/tcp/tcp_transport_external.h>
#include "tcp_transport_internal.h"
// Place here your includes
bool uxr_init_tcp_platform(
struct uxrTCPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
const char* port)
{
// Place here your initialization platform code
// Return true if success
}
bool uxr_close_tcp_platform(
struct uxrTCPPlatform* platform)
{
// Place here your closing platform code
// Return true if success
}
size_t uxr_write_tcp_data_platform(
struct uxrTCPPlatform* platform,
const uint8_t* buf,
size_t len,
uint8_t* errcode)
{
// Place here your writing bytes platform code
// Return number of bytes written
}
size_t uxr_read_tcp_data_platform(
struct uxrTCPPlatform* platform,
uint8_t* buf,
size_t len,
int timeout,
uint8_t* errcode)
{
// Place here your reading bytes platform code
// Return number of bytes read (max bytes: len)
}
void uxr_disconnect_tcp_platform(
struct uxrTCPPlatform* platform)
{
// Place here your disconnection platform code
}

View File

@ -0,0 +1,54 @@
// Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_C_PROFILE_TRANSPORT_TCP_TCP_TRANSPORT_INTERNAL_H_
#define SRC_C_PROFILE_TRANSPORT_TCP_TCP_TRANSPORT_INTERNAL_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <uxr/client/profile/transport/ip/tcp/tcp_transport.h>
bool uxr_init_tcp_platform(
struct uxrTCPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
const char* port);
bool uxr_close_tcp_platform(
struct uxrTCPPlatform* platform);
size_t uxr_write_tcp_data_platform(
struct uxrTCPPlatform* platform,
const uint8_t* buf,
size_t len,
uint8_t* errcode);
size_t uxr_read_tcp_data_platform(
struct uxrTCPPlatform* platform,
uint8_t* buf,
size_t len,
int timeout,
uint8_t* errcode);
void uxr_disconnect_tcp_platform(
struct uxrTCPPlatform* platform);
#ifdef __cplusplus
}
#endif
#endif // SRC_C_PROFILE_TRANSPORT_TCP_TCP_TRANSPORT_INTERNAL_H_

View File

@ -0,0 +1,134 @@
#include <uxr/client/profile/transport/ip/tcp/tcp_transport_posix.h>
#include "tcp_transport_internal.h"
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <netdb.h>
#ifdef UCLIENT_PLATFORM_LINUX
static void sigpipe_handler(int fd)
{
(void)fd;
}
#endif
bool uxr_init_tcp_platform(
struct uxrTCPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
const char* port)
{
bool rv = false;
switch (ip_protocol)
{
case UXR_IPv4:
platform->poll_fd.fd = socket(AF_INET, SOCK_STREAM, 0);
break;
case UXR_IPv6:
platform->poll_fd.fd = socket(AF_INET6, SOCK_STREAM, 0);
break;
}
if (-1 != platform->poll_fd.fd)
{
#ifdef UCLIENT_PLATFORM_LINUX
signal(SIGPIPE, sigpipe_handler);
#endif
struct addrinfo hints;
struct addrinfo* result;
struct addrinfo* ptr;
memset(&hints, 0, sizeof(hints));
switch (ip_protocol)
{
case UXR_IPv4:
hints.ai_family = AF_INET;
break;
case UXR_IPv6:
hints.ai_family = AF_INET6;
break;
}
hints.ai_socktype = SOCK_STREAM;
if (0 == getaddrinfo(ip, port, &hints, &result))
{
for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
{
if (0 == connect(platform->poll_fd.fd, ptr->ai_addr, ptr->ai_addrlen))
{
platform->poll_fd.events = POLLIN;
rv = true;
break;
}
}
}
freeaddrinfo(result);
}
return rv;
}
bool uxr_close_tcp_platform(
struct uxrTCPPlatform* platform)
{
return (-1 == platform->poll_fd.fd) ? true : (0 == close(platform->poll_fd.fd));
}
size_t uxr_write_tcp_data_platform(
struct uxrTCPPlatform* platform,
const uint8_t* buf,
size_t len,
uint8_t* errcode)
{
size_t rv = 0;
ssize_t bytes_sent = send(platform->poll_fd.fd, (void*)buf, len, 0);
if (-1 != bytes_sent)
{
rv = (size_t)bytes_sent;
*errcode = 0;
}
else
{
*errcode = 1;
}
return rv;
}
size_t uxr_read_tcp_data_platform(
struct uxrTCPPlatform* platform,
uint8_t* buf,
size_t len,
int timeout,
uint8_t* errcode)
{
size_t rv = 0;
int poll_rv = poll(&platform->poll_fd, 1, timeout);
if (0 < poll_rv)
{
ssize_t bytes_received = recv(platform->poll_fd.fd, (void*)buf, len, 0);
if (-1 != bytes_received)
{
rv = (size_t)bytes_received;
*errcode = 0;
}
else
{
*errcode = 1;
}
}
else
{
*errcode = (0 == poll_rv) ? 0 : 1;
}
return rv;
}
void uxr_disconnect_tcp_platform(
struct uxrTCPPlatform* platform)
{
close(platform->poll_fd.fd);
platform->poll_fd.fd = -1;
}

View File

@ -1,38 +1,66 @@
#include <uxr/client/profile/transport/tcp/tcp_transport_windows.h>
#include <uxr/client/profile/transport/ip/tcp/tcp_transport_windows.h>
#include "tcp_transport_internal.h"
#include <uxr/client/util/time.h>
bool uxr_init_tcp_platform(struct uxrTCPPlatform* platform, const char* ip, uint16_t port)
#include <ws2tcpip.h>
bool uxr_init_tcp_platform(
struct uxrTCPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
const char* port)
{
bool rv = false;
/* WSA initialization. */
WSADATA wsa_data;
if (0 != WSAStartup(MAKEWORD(2, 2), &wsa_data))
{
return false;
}
/* Socket initialization. */
platform->poll_fd.fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
switch (ip_protocol)
{
case UXR_IPv4:
platform->poll_fd.fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
break;
case UXR_IPv6:
platform->poll_fd.fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
break;
}
if (INVALID_SOCKET != platform->poll_fd.fd)
{
/* Remote IP setup. */
struct sockaddr_in temp_addr;
temp_addr.sin_family = AF_INET;
temp_addr.sin_port = htons(port);
temp_addr.sin_addr.s_addr = inet_addr(ip);
platform->remote_addr = *((struct sockaddr *) &temp_addr);
struct addrinfo hints;
struct addrinfo* result;
struct addrinfo* ptr;
/* Poll setup. */
platform->poll_fd.events = POLLIN;
ZeroMemory(&hints, sizeof(hints));
switch (ip_protocol)
{
case UXR_IPv4:
hints.ai_family = AF_INET;
break;
case UXR_IPv6:
hints.ai_family = AF_INET6;
break;
}
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
/* Server connection. */
int connected = connect(platform->poll_fd.fd,
&platform->remote_addr,
sizeof(platform->remote_addr));
rv = (SOCKET_ERROR != connected);
if (0 == getaddrinfo(ip, port, &hints, &result))
{
for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
{
if (0 == connect(platform->poll_fd.fd, ptr->ai_addr, (int)ptr->ai_addrlen))
{
platform->poll_fd.events = POLLIN;
rv = true;
break;
}
}
}
freeaddrinfo(result);
}
return rv;
}

View File

@ -65,11 +65,16 @@ static uint8_t get_udp_error(void)
/*******************************************************************************
* Public function definitions.
*******************************************************************************/
bool uxr_init_udp_transport(uxrUDPTransport* transport, struct uxrUDPPlatform* platform, const char* ip, uint16_t port)
bool uxr_init_udp_transport(
uxrUDPTransport* transport,
struct uxrUDPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
const char* port)
{
bool rv = false;
if (uxr_init_udp_platform(platform, ip, port))
if (uxr_init_udp_platform(platform, ip_protocol, ip, port))
{
/* Setup platform. */
transport->platform = platform;

View File

@ -0,0 +1,42 @@
#include <uxr/client/profile/transport/ip/udp/udp_transport_external.h>
#include "udp_transport_internal.h"
// Place here your includes
bool uxr_init_udp_platform(
uxrUDPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
const char* port)
{
// Place here your initialization platform code
// Return true if success
}
bool uxr_close_udp_platform(
uxrUDPPlatform* platform)
{
// Place here your closing platform code
// Return true if success
}
size_t uxr_write_udp_data_platform(
uxrUDPPlatform* platform,
const uint8_t* buf,
size_t len,
uint8_t* errcode)
{
// Place here your writing bytes platform code
// Return number of bytes written
}
size_t uxr_read_udp_data_platform(
uxrUDPPlatform* platform,
uint8_t* buf,
size_t len,
int timeout,
uint8_t* errcode)
{
// Place here your reading bytes platform code
// Return number of bytes read (max bytes: len)
}

View File

@ -0,0 +1,51 @@
// Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_C_PROFILE_TRANSPORT_UDP_UDP_TRANSPORT_INTERNAL_H_
#define SRC_C_PROFILE_TRANSPORT_UDP_UDP_TRANSPORT_INTERNAL_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <uxr/client/profile/transport/ip/udp/udp_transport.h>
bool uxr_init_udp_platform(
struct uxrUDPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
const char* port);
bool uxr_close_udp_platform(
struct uxrUDPPlatform* platform);
size_t uxr_write_udp_data_platform(
struct uxrUDPPlatform* platform,
const uint8_t* buf,
size_t len,
uint8_t* errcode);
size_t uxr_read_udp_data_platform(
struct uxrUDPPlatform* platform,
uint8_t* buf,
size_t len,
int timeout,
uint8_t* errcode);
#ifdef __cplusplus
}
#endif
#endif // SRC_C_PROFILE_TRANSPORT_UDP_UDP_TRANSPORT_INTERNAL_H_

View File

@ -0,0 +1,116 @@
#include <uxr/client/profile/transport/ip/udp/udp_transport_posix.h>
#include "udp_transport_internal.h"
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
bool uxr_init_udp_platform(
uxrUDPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
const char* port)
{
bool rv = false;
switch (ip_protocol)
{
case UXR_IPv4:
platform->poll_fd.fd = socket(AF_INET, SOCK_DGRAM, 0);
break;
case UXR_IPv6:
platform->poll_fd.fd = socket(AF_INET6, SOCK_DGRAM, 0);
break;
}
if (-1 != platform->poll_fd.fd)
{
struct addrinfo hints;
struct addrinfo* result;
struct addrinfo* ptr;
memset(&hints, 0, sizeof(hints));
switch (ip_protocol)
{
case UXR_IPv4:
hints.ai_family = AF_INET;
break;
case UXR_IPv6:
hints.ai_family = AF_INET6;
break;
}
hints.ai_socktype = SOCK_DGRAM;
if (0 == getaddrinfo(ip, port, &hints, &result))
{
for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
{
if (0 == connect(platform->poll_fd.fd, ptr->ai_addr, ptr->ai_addrlen))
{
platform->poll_fd.events = POLLIN;
rv = true;
break;
}
}
}
freeaddrinfo(result);
}
return rv;
}
bool uxr_close_udp_platform(
uxrUDPPlatform* platform)
{
return (-1 == platform->poll_fd.fd) ? true : (0 == close(platform->poll_fd.fd));
}
size_t uxr_write_udp_data_platform(
uxrUDPPlatform* platform,
const uint8_t* buf,
size_t len,
uint8_t* errcode)
{
size_t rv = 0;
ssize_t bytes_sent = send(platform->poll_fd.fd, (void*)buf, len, 0);
if (-1 != bytes_sent)
{
rv = (size_t)bytes_sent;
*errcode = 0;
}
else
{
*errcode = 1;
}
return rv;
}
size_t uxr_read_udp_data_platform(
uxrUDPPlatform* platform,
uint8_t* buf,
size_t len,
int timeout,
uint8_t* errcode)
{
size_t rv = 0;
int poll_rv = poll(&platform->poll_fd, 1, timeout);
if (0 < poll_rv)
{
ssize_t bytes_received = recv(platform->poll_fd.fd, (void*)buf, len, 0);
if (-1 != bytes_received)
{
rv = (size_t)bytes_received;
*errcode = 0;
}
else
{
*errcode = 1;
}
}
else
{
*errcode = (0 == poll_rv) ? 0 : 1;
}
return rv;
}

View File

@ -0,0 +1,116 @@
#include <uxr/client/profile/transport/ip/udp/udp_transport_posix_nopoll.h>
#include "udp_transport_internal.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
bool uxr_init_udp_platform(
uxrUDPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
const char* port)
{
bool rv = false;
switch (ip_protocol)
{
case UXR_IPv4:
platform->fd = socket(AF_INET, SOCK_DGRAM, 0);
break;
case UXR_IPv6:
platform->fd = socket(AF_INET6, SOCK_DGRAM, 0);
break;
}
if (-1 != platform->fd)
{
struct addrinfo hints;
struct addrinfo* result;
struct addrinfo* ptr;
memset(&hints, 0, sizeof(hints));
switch (ip_protocol)
{
case UXR_IPv4:
hints.ai_family = AF_INET;
break;
case UXR_IPv6:
hints.ai_family = AF_INET6;
break;
}
hints.ai_socktype = SOCK_DGRAM;
if (0 == getaddrinfo(ip, port, &hints, &result))
{
for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
{
if (0 == connect(platform->fd, ptr->ai_addr, ptr->ai_addrlen))
{
rv = true;
break;
}
}
}
freeaddrinfo(result);
}
return rv;
}
bool uxr_close_udp_platform(
uxrUDPPlatform* platform)
{
return (-1 == platform->fd) ? true : (0 == close(platform->fd));
}
size_t uxr_write_udp_data_platform(
uxrUDPPlatform* platform,
const uint8_t* buf,
size_t len,
uint8_t* errcode)
{
size_t rv = 0;
ssize_t bytes_sent = send(platform->fd, (void*)buf, len, 0);
if (-1 != bytes_sent)
{
rv = (size_t)bytes_sent;
*errcode = 0;
}
else
{
*errcode = 1;
}
return rv;
}
size_t uxr_read_udp_data_platform(
uxrUDPPlatform* platform,
uint8_t* buf,
size_t len,
int timeout,
uint8_t* errcode)
{
size_t rv = 0;
struct timeval tv;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
setsockopt(platform->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
ssize_t bytes_received = recv(platform->fd, (void*)buf, len, 0);
if (-1 != bytes_received)
{
rv = (size_t)bytes_received;
*errcode = 0;
}
else
{
*errcode = 1;
}
return rv;
}

View File

@ -0,0 +1,119 @@
#include <uxr/client/profile/transport/ip/udp/udp_transport_windows.h>
#include "udp_transport_internal.h"
#include <ws2tcpip.h>
bool uxr_init_udp_platform(
uxrUDPPlatform* platform,
uxrIpProtocol ip_protocol,
const char* ip,
const char* port)
{
bool rv = false;
WSADATA wsa_data;
if (0 != WSAStartup(MAKEWORD(2, 2), &wsa_data))
{
return false;
}
switch (ip_protocol)
{
case UXR_IPv4:
platform->poll_fd.fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
break;
case UXR_IPv6:
platform->poll_fd.fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
break;
}
if (INVALID_SOCKET != platform->poll_fd.fd)
{
struct addrinfo hints;
struct addrinfo* result;
struct addrinfo* ptr;
ZeroMemory(&hints, sizeof(hints));
switch (ip_protocol)
{
case UXR_IPv4:
hints.ai_family = AF_INET;
break;
case UXR_IPv6:
hints.ai_family = AF_INET6;
break;
}
hints.ai_socktype = SOCK_DGRAM;
if (0 == getaddrinfo(ip, port, &hints, &result))
{
for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
{
if (0 == connect(platform->poll_fd.fd, ptr->ai_addr, (int)ptr->ai_addrlen))
{
platform->poll_fd.events = POLLIN;
rv = true;
break;
}
}
}
freeaddrinfo(result);
}
return rv;
}
bool uxr_close_udp_platform(
uxrUDPPlatform* platform)
{
bool rv = (INVALID_SOCKET == platform->poll_fd.fd) ? true : (0 == closesocket(platform->poll_fd.fd));
return (0 == WSACleanup()) && rv;
}
size_t uxr_write_udp_data_platform(
uxrUDPPlatform* platform,
const uint8_t* buf,
size_t len,
uint8_t* errcode)
{
size_t rv = 0;
int bytes_sent = send(platform->poll_fd.fd, (const char*)buf, (int)len, 0);
if (SOCKET_ERROR != bytes_sent)
{
rv = (size_t)bytes_sent;
*errcode = 0;
}
else
{
*errcode = 1;
}
return rv;
}
size_t uxr_read_udp_data_platform(
uxrUDPPlatform* platform,
uint8_t* buf,
size_t len,
int timeout,
uint8_t* errcode)
{
size_t rv = 0;
int poll_rv = WSAPoll(&platform->poll_fd, 1, timeout);
if (0 < poll_rv)
{
int bytes_received = recv(platform->poll_fd.fd, (char*)buf, (int)len, 0);
if (SOCKET_ERROR != bytes_received)
{
rv = (size_t)bytes_received;
*errcode = 0;
}
else
{
*errcode = 1;
}
}
else
{
*errcode = (0 == poll_rv) ? 0 : 1;
}
return rv;
}

View File

@ -1,4 +1,4 @@
#include "serial_transport_internal.h"
#include <uxr/client/profile/transport/serial/serial_transport_platform.h>
#include "serial_protocol_internal.h"
#include <uxr/client/util/time.h>

View File

@ -0,0 +1,28 @@
#include <uxr/client/profile/transport/serial/serial_transport_external.h>
#include <uxr/client/profile/transport/serial/serial_transport_platform.h>
// Place here your includes
bool uxr_init_serial_platform(struct uxrSerialPlatform* platform, int fd, uint8_t remote_addr, uint8_t local_addr)
{
// Place here your initialization platform code
// Return true if success
}
bool uxr_close_serial_platform(struct uxrSerialPlatform* platform)
{
// Place here your closing platform code
// Return true if success
}
size_t uxr_write_serial_data_platform(uxrSerialPlatform* platform, uint8_t* buf, size_t len, uint8_t* errcode)
{
// Place here your writing bytes platform code
// Return number of bytes written
}
size_t uxr_read_serial_data_platform(uxrSerialPlatform* platform, uint8_t* buf, size_t len, int timeout, uint8_t* errcode)
{
// Place here your reading bytes platform code
// Return number of bytes read (max bytes: len)
}

View File

@ -1,5 +1,5 @@
#include <uxr/client/profile/transport/serial/serial_transport_linux.h>
#include "serial_transport_internal.h"
#include <uxr/client/profile/transport/serial/serial_transport_posix.h>
#include <uxr/client/profile/transport/serial/serial_transport_platform.h>
#include <unistd.h>
#include <errno.h>

View File

@ -1,2 +1,2 @@
#include <uxr/client/profile/transport/serial/serial_transport_windows.h>
#include "serial_transport_internal.h"
#include <uxr/client/profile/transport/serial/serial_transport_platform.h>

View File

@ -1,45 +0,0 @@
// Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _SRC_C_PROFILE_TRANSPORT_TCP_TCP_TRANSPORT_INTERNAL_H_
#define _SRC_C_PROFILE_TRANSPORT_TCP_TCP_TRANSPORT_INTERNAL_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <uxr/client/profile/transport/tcp/tcp_transport.h>
bool uxr_init_tcp_platform(struct uxrTCPPlatform* platform, const char* ip, uint16_t port);
bool uxr_close_tcp_platform(struct uxrTCPPlatform* platform);
size_t uxr_write_tcp_data_platform(struct uxrTCPPlatform* platform,
const uint8_t* buf,
size_t len,
uint8_t* errcode);
size_t uxr_read_tcp_data_platform(struct uxrTCPPlatform* platform,
uint8_t* buf,
size_t len,
int timeout,
uint8_t* errcode);
void uxr_disconnect_tcp_platform(struct uxrTCPPlatform* platform);
#ifdef __cplusplus
}
#endif
#endif //_SRC_C_PROFILE_TRANSPORT_TCP_TCP_TRANSPORT_INTERNAL_H_

View File

@ -1,104 +0,0 @@
#include <uxr/client/profile/transport/tcp/tcp_transport_linux.h>
#include "tcp_transport_internal.h"
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#ifdef PLATFORM_NAME_LINUX
static void sigpipe_handler(int fd)
{
(void)fd;
}
#endif
bool uxr_init_tcp_platform(struct uxrTCPPlatform* platform, const char* ip, uint16_t port)
{
bool rv = false;
/* Socket initialization. */
platform->poll_fd.fd = socket(PF_INET, SOCK_STREAM, 0);
if (-1 != platform->poll_fd.fd)
{
#ifdef PLATFORM_NAME_LINUX
signal(SIGPIPE, sigpipe_handler);
#endif
/* Remote IP setup. */
struct sockaddr_in temp_addr;
temp_addr.sin_family = AF_INET;
temp_addr.sin_port = htons(port);
temp_addr.sin_addr.s_addr = inet_addr(ip);
platform->remote_addr = *((struct sockaddr *) &temp_addr);
/* Poll setup. */
platform->poll_fd.events = POLLIN;
/* Server connection. */
int connected = connect(platform->poll_fd.fd,
&platform->remote_addr,
sizeof(platform->remote_addr));
rv = (0 == connected);
}
return rv;
}
bool uxr_close_tcp_platform(struct uxrTCPPlatform* platform)
{
return (-1 == platform->poll_fd.fd) ? true : (0 == close(platform->poll_fd.fd));
}
size_t uxr_write_tcp_data_platform(struct uxrTCPPlatform* platform,
const uint8_t* buf,
size_t len,
uint8_t* errcode)
{
size_t rv = 0;
ssize_t bytes_sent = send(platform->poll_fd.fd, (void*)buf, len, 0);
if (-1 != bytes_sent)
{
rv = (size_t)bytes_sent;
*errcode = 0;
}
else
{
*errcode = 1;
}
return rv;
}
size_t uxr_read_tcp_data_platform(struct uxrTCPPlatform* platform,
uint8_t* buf,
size_t len,
int timeout,
uint8_t* errcode)
{
size_t rv = 0;
int poll_rv = poll(&platform->poll_fd, 1, timeout);
if (0 < poll_rv)
{
ssize_t bytes_received = recv(platform->poll_fd.fd, (void*)buf, len, 0);
if (-1 != bytes_received)
{
rv = (size_t)bytes_received;
*errcode = 0;
}
else
{
*errcode = 1;
}
}
else
{
*errcode = (0 == poll_rv) ? 0 : 1;
}
return rv;
}
void uxr_disconnect_tcp_platform(struct uxrTCPPlatform* platform)
{
close(platform->poll_fd.fd);
platform->poll_fd.fd = -1;
}

View File

@ -1,43 +0,0 @@
// Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _SRC_C_PROFILE_TRANSPORT_UDP_UDP_TRANSPORT_INTERNAL_H_
#define _SRC_C_PROFILE_TRANSPORT_UDP_UDP_TRANSPORT_INTERNAL_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <uxr/client/profile/transport/udp/udp_transport.h>
bool uxr_init_udp_platform(struct uxrUDPPlatform* platform, const char* ip, uint16_t port);
bool uxr_close_udp_platform(struct uxrUDPPlatform* platform);
size_t uxr_write_udp_data_platform(struct uxrUDPPlatform* platform,
const uint8_t* buf,
size_t len,
uint8_t* errcode);
size_t uxr_read_udp_data_platform(struct uxrUDPPlatform* platform,
uint8_t* buf,
size_t len,
int timeout,
uint8_t* errcode);
#ifdef __cplusplus
}
#endif
#endif //_SRC_C_PROFILE_TRANSPORT_UDP_UDP_TRANSPORT_INTERNAL_H_

View File

@ -1,77 +0,0 @@
#include <uxr/client/profile/transport/udp/udp_transport_linux.h>
#include "udp_transport_internal.h"
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
bool uxr_init_udp_platform(uxrUDPPlatform* platform, const char* ip, uint16_t port)
{
bool rv = false;
/* Socket initialization */
platform->poll_fd.fd = socket(PF_INET, SOCK_DGRAM, 0);
if (-1 != platform->poll_fd.fd)
{
/* Remote IP setup. */
struct sockaddr_in temp_addr;
temp_addr.sin_family = AF_INET;
temp_addr.sin_port = htons(port);
temp_addr.sin_addr.s_addr = inet_addr(ip);
platform->remote_addr = *((struct sockaddr *) &temp_addr);
/* Poll setup. */
platform->poll_fd.events = POLLIN;
/* Remote address filter. */
int connected = connect(platform->poll_fd.fd, &platform->remote_addr, sizeof(platform->remote_addr));
rv = (0 == connected);
}
return rv;
}
bool uxr_close_udp_platform(uxrUDPPlatform* platform)
{
return (-1 == platform->poll_fd.fd) ? true : (0 == close(platform->poll_fd.fd));
}
size_t uxr_write_udp_data_platform(uxrUDPPlatform* platform, const uint8_t* buf, size_t len, uint8_t* errcode)
{
size_t rv = 0;
ssize_t bytes_sent = send(platform->poll_fd.fd, (void*)buf, len, 0);
if (-1 != bytes_sent)
{
rv = (size_t)bytes_sent;
*errcode = 0;
}
else
{
*errcode = 1;
}
return rv;
}
size_t uxr_read_udp_data_platform(uxrUDPPlatform* platform, uint8_t* buf, size_t len, int timeout, uint8_t* errcode)
{
size_t rv = 0;
int poll_rv = poll(&platform->poll_fd, 1, timeout);
if (0 < poll_rv)
{
ssize_t bytes_received = recv(platform->poll_fd.fd, (void*)buf, len, 0);
if (-1 != bytes_received)
{
rv = (size_t)bytes_received;
*errcode = 0;
}
else
{
*errcode = 1;
}
}
else
{
*errcode = (0 == poll_rv) ? 0 : 1;
}
return rv;
}

View File

@ -1,81 +0,0 @@
#include <uxr/client/profile/transport/udp/udp_transport_windows.h>
#include "udp_transport_internal.h"
bool uxr_init_udp_platform(uxrUDPPlatform* platform, const char* ip, uint16_t port)
{
bool rv = false;
/* WSA initialization. */
WSADATA wsa_data;
if (0 != WSAStartup(MAKEWORD(2, 2), &wsa_data))
{
return false;
}
/* Socket initialization */
platform->poll_fd.fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (INVALID_SOCKET != platform->poll_fd.fd)
{
/* Remote IP setup. */
struct sockaddr_in temp_addr;
temp_addr.sin_family = AF_INET;
temp_addr.sin_port = htons(port);
temp_addr.sin_addr.s_addr = inet_addr(ip);
memset(temp_addr.sin_zero, '\0', sizeof(temp_addr.sin_zero));
platform->remote_addr = *((struct sockaddr *) &temp_addr);
/* Poll setup. */
platform->poll_fd.events = POLLIN;
/* Remote address filter. */
int connected = connect(platform->poll_fd.fd, &platform->remote_addr, sizeof(platform->remote_addr));
rv = (0 == connected);
}
return rv;
}
bool uxr_close_udp_platform(uxrUDPPlatform* platform)
{
bool rv = (INVALID_SOCKET == platform->poll_fd.fd) ? true : (0 == closesocket(platform->poll_fd.fd));
return (0 == WSACleanup()) && rv;
}
size_t uxr_write_udp_data_platform(uxrUDPPlatform* platform, const uint8_t* buf, size_t len, uint8_t* errcode)
{
size_t rv = 0;
int bytes_sent = send(platform->poll_fd.fd, (const char*)buf, (int)len, 0);
if (SOCKET_ERROR != bytes_sent)
{
rv = (size_t)bytes_sent;
*errcode = 0;
}
else
{
*errcode = 1;
}
return rv;
}
size_t uxr_read_udp_data_platform(uxrUDPPlatform* platform, uint8_t* buf, size_t len, int timeout, uint8_t* errcode)
{
size_t rv = 0;
int poll_rv = WSAPoll(&platform->poll_fd, 1, timeout);
if (0 < poll_rv)
{
int bytes_received = recv(platform->poll_fd.fd, (char*)buf, (int)len, 0);
if (SOCKET_ERROR != bytes_received)
{
rv = (size_t)bytes_received;
*errcode = 0;
}
else
{
*errcode = 1;
}
}
else
{
*errcode = (0 == poll_rv) ? 0 : 1;
}
return rv;
}

View File

@ -18,7 +18,8 @@ add_test(
COMMAND
${CMAKE_COMMAND}
-DINSTALL_PATH=${CMAKE_INSTALL_PREFIX}
-DLIBRARY_NAME=$<TARGET_FILE_NAME:${PROJECT_NAME}>
-DLIBRARY_NAME=$<TARGET_FILE_NAME:${PROJECT_NAME}>
-DREQUIRED_VERSION=${PROJECT_VERSION}
-P ${CMAKE_CURRENT_SOURCE_DIR}/installation/InstallationTest.cmake
)
@ -28,7 +29,7 @@ add_test(
COMMAND
${CMAKE_COMMAND}
-DORIGINAL_DIR=${CMAKE_CURRENT_SOURCE_DIR}/packaging
-DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}
-DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}$<IF:$<BOOL:${UCLIENT_ISOLATED_INSTALL}>,/../,>
-DREQUIRED_VERSION=${PROJECT_VERSION}
-DCMAKE_GENERATOR_TOOLSET=${CMAKE_GENERATOR_TOOLSET}
-DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}

View File

@ -3,7 +3,7 @@
extern "C"
{
#include <c/core/serialization/xrce_protocol.c>
#include <c/core/serialization/xrce_types.c>
#include <c/core/serialization/xrce_header.c>
#include <c/core/serialization/xrce_subheader.c>
@ -223,9 +223,9 @@ public:
}
static void on_topic_func (struct uxrSession* session, uxrObjectId object_id, uint16_t request_id,
uxrStreamId stream_id, struct ucdrBuffer* ub, void* args)
uxrStreamId stream_id, struct ucdrBuffer* ub, uint16_t length, void* args)
{
(void) session; (void) object_id; (void) request_id; (void) stream_id; (void) args;
(void) session; (void) object_id; (void) request_id; (void) stream_id; (void) length; (void) args;
if (std::string("ReadUint64") == ::testing::UnitTest::GetInstance()->current_test_info()->name())
{
uint64_t data;
@ -465,7 +465,7 @@ TEST_F(SessionTest, ReadUint64)
DATA_Payload_Data payload{};
uxr_serialize_DATA_Payload_Data(&ub, &payload);
ub.last_data_size = 8; // reset buffer alignment.
ucdr_init_buffer(&ub, ub.iterator, size_t(ub.final - ub.iterator));
ucdr_serialize_uint64_t(&ub, UINT64_MAX);
ucdr_init_buffer(&ub, buffer.data(), size_t(ub.iterator - ub.init));
@ -485,16 +485,6 @@ TEST_F(SessionTest, WriteUint64)
uxr_run_session_time(&session, 1);
uint8_t session_id; uint8_t stream_id; uint16_t seq_num; uint8_t key[4];
uxr_deserialize_message_header(&expected_ub, &session_id, &stream_id, &seq_num, key);
uint8_t id; uint8_t flags; uint16_t lenght;
uxr_deserialize_submessage_header(&expected_ub, &id, &flags, &lenght);
WRITE_DATA_Payload_Data payload;
uxr_deserialize_WRITE_DATA_Payload_Data(&expected_ub, &payload);
expected_ub.last_data_size = 8; // reset buffer alignment.
uint64_t data;
ucdr_deserialize_uint64_t(&expected_ub, &data);
EXPECT_EQ(data, UINT64_MAX);

View File

@ -2,7 +2,7 @@
extern "C"
{
#include <c/core/serialization/xrce_protocol.c>
#include <c/core/serialization/xrce_types.c>
#include <c/core/serialization/xrce_header.c>
#include <c/core/serialization/xrce_subheader.c>
#include <c/core/session/object_id.c>

View File

@ -5,29 +5,29 @@
#define BUFFER_SIZE size_t(512)
#define HISTORY size_t(8)
uint8_t stream_buffer[BUFFER_SIZE];
uxrReliableStream stream{stream_buffer, BUFFER_SIZE, HISTORY};
TEST(CommonReliableStreamTest, GetBufferSize)
{
size_t buffer_size = uxr_get_reliable_buffer_size(BUFFER_SIZE, HISTORY);
EXPECT_EQ(BUFFER_SIZE / HISTORY - INTERNAL_RELIABLE_BUFFER_OFFSET, buffer_size);
size_t buffer_capacity = uxr_get_reliable_buffer_capacity(&stream);
EXPECT_EQ(BUFFER_SIZE / HISTORY - INTERNAL_RELIABLE_BUFFER_OFFSET, buffer_capacity);
}
TEST(CommonReliableStreamTest, GetBuffer)
{
size_t history_pos = 3;
uint8_t buffer[BUFFER_SIZE];
uint8_t* slot = uxr_get_reliable_buffer(buffer, BUFFER_SIZE, HISTORY, history_pos);
uint16_t history_pos = 3;
uint8_t * buffer = uxr_get_reliable_buffer(&stream, history_pos);
size_t slot_size = BUFFER_SIZE / HISTORY;
EXPECT_EQ(history_pos * slot_size + INTERNAL_RELIABLE_BUFFER_OFFSET, size_t(slot - buffer));
EXPECT_EQ(history_pos * slot_size + INTERNAL_RELIABLE_BUFFER_OFFSET, size_t(buffer - stream_buffer));
}
TEST(CommonReliableStreamTest, SetGetBufferLength)
{
size_t input_length = 0xFFFF;
uint8_t buffer[BUFFER_SIZE];
uint8_t* slot = buffer + INTERNAL_RELIABLE_BUFFER_OFFSET;
uxr_set_reliable_buffer_length(slot, input_length);
size_t output_length = uxr_get_reliable_buffer_length(slot);
uxr_set_reliable_buffer_size(&stream, 0, input_length);
size_t output_length = uxr_get_reliable_buffer_size(&stream, 0);
EXPECT_EQ(input_length, output_length);
}

View File

@ -14,12 +14,13 @@ extern "C"
bool operator == (const uxrInputReliableStream& stream1, const uxrInputReliableStream& stream2)
{
return stream1.buffer == stream2.buffer
&& stream1.size == stream2.size
&& stream1.history == stream2.history
return stream1.base.buffer == stream2.base.buffer
&& stream1.base.size == stream2.base.size
&& stream1.base.history == stream2.base.history
&& stream1.last_handled == stream2.last_handled
&& stream1.last_announced == stream2.last_announced
&& stream1.on_get_fragmentation_info == stream2.on_get_fragmentation_info;
&& stream1.on_get_fragmentation_info == stream2.on_get_fragmentation_info
&& stream1.cleanup_flag == stream2.cleanup_flag;
}
bool operator != (const uxrInputReliableStream& stream1, const uxrInputReliableStream& stream2)
@ -33,29 +34,31 @@ public:
InputReliableStreamTest()
{
uxr_init_input_reliable_stream(&stream, buffer, BUFFER_SIZE, HISTORY, on_get_fragmentation_info);
EXPECT_EQ(buffer, stream.buffer);
EXPECT_EQ(BUFFER_SIZE, stream.size);
EXPECT_EQ(HISTORY, stream.history);
EXPECT_EQ(buffer, stream.base.buffer);
EXPECT_EQ(BUFFER_SIZE, stream.base.size);
EXPECT_EQ(HISTORY, stream.base.history);
EXPECT_EQ(SEQ_NUM_MAX, stream.last_handled);
EXPECT_EQ(SEQ_NUM_MAX, stream.last_announced);
EXPECT_EQ(false, stream.cleanup_flag);
for(size_t i = 0; i < HISTORY; ++i)
for(uint16_t i = 0; i < HISTORY; ++i)
{
uint8_t* slot = uxr_get_reliable_buffer(buffer, BUFFER_SIZE, HISTORY, i);
EXPECT_EQ(size_t(0), uxr_get_reliable_buffer_length(slot));
EXPECT_EQ(size_t(0), uxr_get_reliable_buffer_size(&stream.base, i));
}
}
void copy(uxrInputReliableStream* dest, uxrInputReliableStream* source)
{
dest->buffer = source->buffer;
dest->size = source->size;
dest->history = source->history;
dest->base.buffer = source->base.buffer;
dest->base.size = source->base.size;
dest->base.history = source->base.history;
dest->last_handled = source->last_handled;
dest->last_announced = source->last_announced;
dest->on_get_fragmentation_info = source->on_get_fragmentation_info;
dest->cleanup_flag = source->cleanup_flag;
}
virtual ~InputReliableStreamTest()
@ -74,21 +77,6 @@ protected:
}
};
TEST_F(InputReliableStreamTest, InputBuffer)
{
uint8_t* buffer_from_generic = uxr_get_reliable_buffer(buffer, BUFFER_SIZE, HISTORY, 2);
uint8_t* buffer_from_input = uxr_get_input_buffer(&stream, 2);
EXPECT_EQ(buffer_from_generic, buffer_from_input);
}
TEST_F(InputReliableStreamTest, InputBufferSize)
{
size_t size_from_generic = uxr_get_reliable_buffer_size(BUFFER_SIZE, HISTORY);
size_t size_from_input = uxr_get_input_buffer_size(&stream);
EXPECT_EQ(size_from_generic, size_from_input);
}
TEST_F(InputReliableStreamTest, UpToDate)
{
bool up_to_date = uxr_is_input_up_to_date(&stream);
@ -227,49 +215,50 @@ TEST_F(InputReliableStreamTest, Reset)
uxr_reset_input_reliable_stream(&stream);
EXPECT_EQ(backup, stream);
for(size_t i = 0; i < HISTORY; ++i)
for(uint16_t i = 0; i < HISTORY; ++i)
{
uint8_t* slot = uxr_get_reliable_buffer(buffer, BUFFER_SIZE, HISTORY, i);
EXPECT_EQ(size_t(0), uxr_get_reliable_buffer_length(slot));
EXPECT_EQ(size_t(0), uxr_get_reliable_buffer_size(&stream.base, i));
}
}
TEST_F(InputReliableStreamTest, FragmentationJumpToNextBuffer)
{
size_t size = uxr_get_reliable_buffer_size(BUFFER_SIZE, HISTORY);
uint8_t* slot_0 = uxr_get_input_buffer(&stream, 0);
uint8_t* slot_1 = uxr_get_input_buffer(&stream, 1);
uxr_set_reliable_buffer_length(slot_0, size);
uxr_set_reliable_buffer_length(slot_1, size / 2);
size_t capacity = uxr_get_reliable_buffer_capacity(&stream.base);
uint8_t* slot_0 = uxr_get_reliable_buffer(&stream.base, 0);
uint8_t* slot_1 = uxr_get_reliable_buffer(&stream.base, 1);
uxr_set_reliable_buffer_size(&stream.base, 0, capacity);
uxr_set_reliable_buffer_size(&stream.base, 1, capacity - 1);
ucdrBuffer ub;
ucdr_init_buffer(&ub, slot_0, uint32_t(size));
ucdr_init_buffer(&ub, slot_0, uint32_t(capacity));
ucdr_set_on_full_buffer_callback(&ub, on_full_input_buffer, &stream);
stream.cleanup_flag = true;
uint8_t array[BUFFER_SIZE];
(void) ucdr_serialize_array_uint8_t(&ub, array, uint32_t(size + size / 2));
(void) ucdr_serialize_array_uint8_t(&ub, array, uint32_t((capacity + capacity - 1) - 2 * (sizeof(length_t) + SUBHEADER_SIZE)));
ASSERT_FALSE(ub.error);
EXPECT_EQ(slot_1, ub.init);
EXPECT_EQ(slot_1 + size / 2, ub.final);
EXPECT_EQ(size_t(0), uxr_get_reliable_buffer_length(slot_1));
EXPECT_EQ(slot_1 + SUBHEADER_SIZE, ub.init);
EXPECT_EQ(slot_1 + capacity - 1, ub.final);
EXPECT_EQ(size_t(0), uxr_get_reliable_buffer_size(&stream.base, 1));
}
TEST_F(InputReliableStreamTest, FragmentationJumpToNextBufferLastPosition)
{
size_t size = uxr_get_reliable_buffer_size(BUFFER_SIZE, HISTORY);
uint8_t* slot_history_1 = uxr_get_input_buffer(&stream, HISTORY - 1);
uint8_t* slot_0 = uxr_get_input_buffer(&stream, 0);
uxr_set_reliable_buffer_length(slot_history_1, size);
uxr_set_reliable_buffer_length(slot_0, size / 2);
size_t capacity = uxr_get_reliable_buffer_capacity(&stream.base);
uint8_t* slot_history_1 = uxr_get_reliable_buffer(&stream.base, HISTORY - 1);
uint8_t* slot_0 = uxr_get_reliable_buffer(&stream.base, 0);
uxr_set_reliable_buffer_size(&stream.base, HISTORY -1, capacity);
uxr_set_reliable_buffer_size(&stream.base, 0, capacity - 1);
ucdrBuffer ub;
ucdr_init_buffer(&ub, slot_history_1, uint32_t(size));
ucdr_init_buffer(&ub, slot_history_1, uint32_t(capacity));
ucdr_set_on_full_buffer_callback(&ub, on_full_input_buffer, &stream);
stream.cleanup_flag = true;
uint8_t array[BUFFER_SIZE];
(void) ucdr_serialize_array_uint8_t(&ub, array, uint32_t(size + size / 2));
(void) ucdr_serialize_array_uint8_t(&ub, array, uint32_t((capacity + capacity - 1) - 2 * (sizeof(length_t) + SUBHEADER_SIZE)));
ASSERT_FALSE(ub.error);
EXPECT_EQ(slot_0, ub.init);
EXPECT_EQ(slot_0 + size / 2, ub.final);
EXPECT_EQ(size_t(0), uxr_get_reliable_buffer_length(slot_0));
EXPECT_EQ(slot_0 + SUBHEADER_SIZE, ub.init);
EXPECT_EQ(slot_0 + capacity - 1, ub.final);
EXPECT_EQ(size_t(0), uxr_get_reliable_buffer_size(&stream.base, 0));
}

View File

@ -5,6 +5,8 @@ extern "C"
{
#include <c/core/session/stream/seq_num.c>
#include <c/core/session/stream/output_reliable_stream.c>
#include <c/core/serialization/xrce_subheader.c>
#include <c/core/session/submessage.c>
}
#define BUFFER_SIZE size_t(128)
@ -14,20 +16,20 @@ extern "C"
#define SUBMESSAGE_SIZE size_t(8)
#define MAX_SUBMESSAGE_SIZE (MAX_MESSAGE_SIZE - OFFSET)
#define FRAGMENT_OFFSET size_t(4)
#define MAX_FRAGMENT_SIZE (MAX_MESSAGE_SIZE - OFFSET - FRAGMENT_OFFSET)
bool operator == (const uxrOutputReliableStream& stream1, const uxrOutputReliableStream& stream2)
{
return stream1.buffer == stream2.buffer
&& stream1.size == stream2.size
&& stream1.history == stream2.history
return stream1.base.buffer == stream2.base.buffer
&& stream1.base.size == stream2.base.size
&& stream1.base.history == stream2.base.history
&& stream1.offset == stream2.offset
&& stream1.last_written == stream2.last_written
&& stream1.last_sent == stream2.last_sent
&& stream1.last_acknown == stream2.last_acknown
&& stream1.next_heartbeat_timestamp == stream2.next_heartbeat_timestamp
&& stream1.next_heartbeat_tries == stream2.next_heartbeat_tries
&& stream1.send_lost == stream2.send_lost
&& stream1.on_new_fragment == stream2.on_new_fragment;
&& stream1.send_lost == stream2.send_lost;
}
bool operator != (const uxrOutputReliableStream& stream1, const uxrOutputReliableStream& stream2)
@ -40,10 +42,10 @@ class OutputReliableStreamTest : public testing::Test
public:
OutputReliableStreamTest()
{
uxr_init_output_reliable_stream(&stream, buffer, BUFFER_SIZE, HISTORY, OFFSET, on_new_fragment);
EXPECT_EQ(buffer, stream.buffer);
EXPECT_EQ(BUFFER_SIZE, stream.size);
EXPECT_EQ(HISTORY, stream.history);
uxr_init_output_reliable_stream(&stream, buffer, BUFFER_SIZE, HISTORY, OFFSET);
EXPECT_EQ(buffer, stream.base.buffer);
EXPECT_EQ(BUFFER_SIZE, stream.base.size);
EXPECT_EQ(HISTORY, stream.base.history);
EXPECT_EQ(OFFSET, stream.offset);
EXPECT_EQ(0, stream.last_written);
EXPECT_EQ(SEQ_NUM_MAX, stream.last_sent);
@ -52,18 +54,17 @@ public:
EXPECT_EQ(0, stream.next_heartbeat_tries);
EXPECT_EQ(false, stream.send_lost);
for(size_t i = 0; i < HISTORY; ++i)
for(uint16_t i = 0; i < HISTORY; ++i)
{
uint8_t* slot = uxr_get_reliable_buffer(buffer, BUFFER_SIZE, HISTORY, i);
EXPECT_EQ(OFFSET, uxr_get_reliable_buffer_length(slot));
EXPECT_EQ(OFFSET, uxr_get_reliable_buffer_size(&stream.base, i));
}
}
void copy(uxrOutputReliableStream* dest, uxrOutputReliableStream* source)
{
dest->buffer = source->buffer;
dest->size = source->size;
dest->history = source->history;
dest->base.buffer = source->base.buffer;
dest->base.size = source->base.size;
dest->base.history = source->base.history;
dest->offset = source->offset;
dest->last_written = source->last_written;
@ -73,8 +74,6 @@ public:
dest->next_heartbeat_timestamp = source->next_heartbeat_timestamp;
dest->next_heartbeat_tries = source->next_heartbeat_tries;
dest->send_lost = source->send_lost;
dest->on_new_fragment = source->on_new_fragment;
}
virtual ~OutputReliableStreamTest()
@ -84,30 +83,9 @@ public:
protected:
uxrOutputReliableStream stream;
uint8_t buffer[BUFFER_SIZE];
static void on_new_fragment(ucdrBuffer* ub, uxrOutputReliableStream* stream)
{
(void) stream;
uint8_t fragment_header[FRAGMENT_OFFSET];
ucdr_serialize_array_uint8_t(ub, fragment_header, FRAGMENT_OFFSET);
}
};
TEST_F(OutputReliableStreamTest, OutputBuffer)
{
uint8_t* buffer_from_generic = uxr_get_reliable_buffer(buffer, BUFFER_SIZE, HISTORY, 2);
uint8_t* buffer_from_output = uxr_get_output_buffer(&stream, 2);
EXPECT_EQ(buffer_from_generic, buffer_from_output);
}
TEST_F(OutputReliableStreamTest, OutputBufferSize)
{
size_t size_from_generic = uxr_get_reliable_buffer_size(BUFFER_SIZE, HISTORY);
size_t size_from_output = uxr_get_output_buffer_size(&stream);
EXPECT_EQ(size_from_generic, size_from_output);
}
TEST_F(OutputReliableStreamTest, UpToDate)
{
bool up_to_date = uxr_is_output_up_to_date(&stream);
@ -117,7 +95,7 @@ TEST_F(OutputReliableStreamTest, UpToDate)
TEST_F(OutputReliableStreamTest, NotUpToDate)
{
ucdrBuffer ub;
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
uint8_t* message; size_t length; uxrSeqNum seq_num;
(void) uxr_prepare_next_reliable_buffer_to_send(&stream, &message, &length, &seq_num);
@ -127,13 +105,13 @@ TEST_F(OutputReliableStreamTest, NotUpToDate)
TEST_F(OutputReliableStreamTest, WriteOneMessageSameSlot)
{
uint8_t* slot_0 = uxr_get_output_buffer(&stream, 0);
uint8_t* slot_0 = uxr_get_reliable_buffer(&stream.base, 0);
ucdrBuffer ub;
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
ASSERT_TRUE(available_to_write);
EXPECT_EQ(0u, stream.last_written);
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE, uxr_get_reliable_buffer_length(slot_0));
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE, uxr_get_reliable_buffer_size(&stream.base, 0));
EXPECT_EQ(slot_0, ub.init);
EXPECT_EQ(slot_0 + OFFSET, ub.iterator);
EXPECT_EQ(slot_0 + OFFSET + SUBMESSAGE_SIZE, ub.final);
@ -141,21 +119,21 @@ TEST_F(OutputReliableStreamTest, WriteOneMessageSameSlot)
TEST_F(OutputReliableStreamTest, WriteTwoMessagesSameSlot)
{
uint8_t* slot_0 = uxr_get_output_buffer(&stream, 0);
uint8_t* slot_0 = uxr_get_reliable_buffer(&stream.base, 0);
ucdrBuffer ub;
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
ASSERT_TRUE(available_to_write);
EXPECT_EQ(0u, stream.last_written);
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE, uxr_get_reliable_buffer_length(slot_0));
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE, uxr_get_reliable_buffer_size(&stream.base, 0));
EXPECT_EQ(slot_0, ub.init);
EXPECT_EQ(slot_0 + OFFSET, ub.iterator);
EXPECT_EQ(slot_0 + OFFSET + SUBMESSAGE_SIZE, ub.final);
available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
ASSERT_TRUE(available_to_write);
EXPECT_EQ(0u, stream.last_written);
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE * 2, uxr_get_reliable_buffer_length(slot_0));
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE * 2, uxr_get_reliable_buffer_size(&stream.base, 0));
EXPECT_EQ(slot_0, ub.init);
EXPECT_EQ(slot_0 + OFFSET + SUBMESSAGE_SIZE, ub.iterator);
EXPECT_EQ(slot_0 + OFFSET + SUBMESSAGE_SIZE * 2, ub.final);
@ -163,31 +141,31 @@ TEST_F(OutputReliableStreamTest, WriteTwoMessagesSameSlot)
TEST_F(OutputReliableStreamTest, WriteThreeMessagessTwoSlots)
{
uint8_t* slot_0 = uxr_get_output_buffer(&stream, 0);
uint8_t* slot_1 = uxr_get_output_buffer(&stream, 1);
uint8_t* slot_0 = uxr_get_reliable_buffer(&stream.base, 0);
uint8_t* slot_1 = uxr_get_reliable_buffer(&stream.base, 1);
ucdrBuffer ub;
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
ASSERT_TRUE(available_to_write);
EXPECT_EQ(0u, stream.last_written);
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE, uxr_get_reliable_buffer_length(slot_0));
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE, uxr_get_reliable_buffer_size(&stream.base, 0));
EXPECT_EQ(slot_0, ub.init);
EXPECT_EQ(slot_0 + OFFSET, ub.iterator);
EXPECT_EQ(slot_0 + OFFSET + SUBMESSAGE_SIZE, ub.final);
available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
ASSERT_TRUE(available_to_write);
EXPECT_EQ(0u, stream.last_written);
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE * 2, uxr_get_reliable_buffer_length(slot_0));
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE * 2, uxr_get_reliable_buffer_size(&stream.base, 0));
EXPECT_EQ(slot_0, ub.init);
EXPECT_EQ(slot_0 + OFFSET + SUBMESSAGE_SIZE, ub.iterator);
EXPECT_EQ(slot_0 + OFFSET + SUBMESSAGE_SIZE * 2, ub.final);
available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
ASSERT_TRUE(available_to_write);
EXPECT_EQ(1u, stream.last_written);
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE * 2, uxr_get_reliable_buffer_length(slot_0));
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE, uxr_get_reliable_buffer_length(slot_1));
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE * 2, uxr_get_reliable_buffer_size(&stream.base, 0));
EXPECT_EQ(OFFSET + SUBMESSAGE_SIZE, uxr_get_reliable_buffer_size(&stream.base, 1));
EXPECT_EQ(slot_1, ub.init);
EXPECT_EQ(slot_1 + OFFSET, ub.iterator);
EXPECT_EQ(slot_1 + OFFSET + SUBMESSAGE_SIZE, ub.final);
@ -195,66 +173,72 @@ TEST_F(OutputReliableStreamTest, WriteThreeMessagessTwoSlots)
TEST_F(OutputReliableStreamTest, WriteFragmentMessage)
{
size_t size = uxr_get_output_buffer_size(&stream);
size_t capacity = uxr_get_reliable_buffer_capacity(&stream.base);
const size_t message_length = BUFFER_SIZE / HISTORY + SUBMESSAGE_SIZE;
uint8_t* slot_0 = uxr_get_output_buffer(&stream, 0);
uint8_t* slot_1 = uxr_get_output_buffer(&stream, 1);
uint8_t* slot_2 = uxr_get_output_buffer(&stream, 2);
uint8_t* slot_0 = uxr_get_reliable_buffer(&stream.base, 0);
uint8_t* slot_2 = uxr_get_reliable_buffer(&stream.base, 2);
uxrOutputReliableStream backup;
copy(&backup, &stream);
ucdrBuffer ub;
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, message_length, FRAGMENT_OFFSET, &ub);
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, message_length, &ub);
ASSERT_TRUE(available_to_write);
EXPECT_EQ(2u, stream.last_written);
EXPECT_EQ(size, uxr_get_reliable_buffer_length(slot_0));
EXPECT_EQ(size, uxr_get_reliable_buffer_length(slot_1));
EXPECT_EQ(OFFSET + FRAGMENT_OFFSET + SUBMESSAGE_SIZE, uxr_get_reliable_buffer_length(slot_2));
EXPECT_EQ(slot_0, ub.init);
EXPECT_EQ(capacity, uxr_get_reliable_buffer_size(&stream.base, 0));
EXPECT_EQ(capacity, uxr_get_reliable_buffer_size(&stream.base, 1));
EXPECT_EQ(OFFSET + FRAGMENT_OFFSET + SUBMESSAGE_SIZE, uxr_get_reliable_buffer_size(&stream.base, 2));
EXPECT_EQ(slot_0 + OFFSET + FRAGMENT_OFFSET, ub.init);
EXPECT_EQ(slot_0 + OFFSET + FRAGMENT_OFFSET, ub.iterator);
EXPECT_EQ(slot_0 + size, ub.final);
EXPECT_EQ(slot_0 + capacity, ub.final);
uint8_t message_to_write[message_length];
EXPECT_TRUE(ucdr_serialize_array_uint8_t(&ub, message_to_write, message_length));
EXPECT_EQ(slot_2, ub.init);
EXPECT_EQ(slot_2 + OFFSET + FRAGMENT_OFFSET + SUBMESSAGE_SIZE, ub.iterator);
EXPECT_EQ(slot_2 + OFFSET + FRAGMENT_OFFSET + SUBMESSAGE_SIZE, ub.final);
}
TEST_F(OutputReliableStreamTest, WriteMaxSubmessageSize)
{
ucdrBuffer ub;
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, 2 * MAX_FRAGMENT_SIZE, &ub);
ASSERT_TRUE(available_to_write);
EXPECT_EQ(MAX_MESSAGE_SIZE, uxr_get_reliable_buffer_size(&stream.base, 0));
EXPECT_EQ(MAX_MESSAGE_SIZE, uxr_get_reliable_buffer_size(&stream.base, 1));
}
TEST_F(OutputReliableStreamTest, WriteMessagesUntilFullBuffer)
{
ucdrBuffer ub;
for(size_t i = 0; i < HISTORY; ++i)
{
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, MAX_SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, MAX_SUBMESSAGE_SIZE, &ub);
ASSERT_TRUE(available_to_write);
}
uxrOutputReliableStream backup;
copy(&backup, &stream);
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, MAX_SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
bool available_to_write = uxr_prepare_reliable_buffer_to_write(&stream, MAX_SUBMESSAGE_SIZE, &ub);
ASSERT_FALSE(available_to_write);
EXPECT_EQ(backup, stream);
for(size_t i = 0; i < HISTORY; ++i)
for(uint16_t i = 0; i < HISTORY; ++i)
{
uint8_t* slot_i = uxr_get_output_buffer(&stream, i);
EXPECT_EQ(MAX_MESSAGE_SIZE, uxr_get_reliable_buffer_length(slot_i));
EXPECT_EQ(MAX_MESSAGE_SIZE, uxr_get_reliable_buffer_size(&stream.base, i));
}
}
TEST_F(OutputReliableStreamTest, PrepareToSendOneMessage)
{
ucdrBuffer ub;
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
uint8_t* slot_0 = uxr_get_output_buffer(&stream, 0);
uint8_t* slot_0 = uxr_get_reliable_buffer(&stream.base, 0);
uint8_t* message; size_t length; uxrSeqNum seq_num;
bool data_to_send = uxr_prepare_next_reliable_buffer_to_send(&stream, &message, &length, &seq_num);
ASSERT_TRUE(data_to_send);
EXPECT_EQ(slot_0, message);
EXPECT_EQ(uxr_get_reliable_buffer_length(slot_0), length);
EXPECT_EQ(uxr_get_reliable_buffer_size(&stream.base, 0), length);
EXPECT_EQ(uxr_seq_num_add(SEQ_NUM_MAX, 1), seq_num);
}
@ -273,17 +257,17 @@ TEST_F(OutputReliableStreamTest, PrepareToSendAllMessages)
ucdrBuffer ub;
for(size_t i = 0; i < HISTORY; ++i)
{
(void) uxr_prepare_reliable_buffer_to_write(&stream, MAX_SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
(void) uxr_prepare_reliable_buffer_to_write(&stream, MAX_SUBMESSAGE_SIZE, &ub);
}
for(size_t i = 0; i < HISTORY; ++i)
for(uint16_t i = 0; i < HISTORY; ++i)
{
uint8_t* slot_i = uxr_get_output_buffer(&stream, i);
uint8_t* slot_i = uxr_get_reliable_buffer(&stream.base, i);
uint8_t* message; size_t length; uxrSeqNum seq_num;
bool data_to_send = uxr_prepare_next_reliable_buffer_to_send(&stream, &message, &length, &seq_num);
ASSERT_TRUE(data_to_send);
EXPECT_EQ(slot_i, message);
EXPECT_EQ(uxr_get_reliable_buffer_length(slot_i), length);
EXPECT_EQ(uxr_get_reliable_buffer_size(&stream.base, i), length);
EXPECT_EQ(uxr_seq_num_add(SEQ_NUM_MAX, uint16_t(i + 1)), seq_num);
}
@ -294,10 +278,9 @@ TEST_F(OutputReliableStreamTest, PrepareToSendAllMessages)
ASSERT_FALSE(data_to_send);
EXPECT_EQ(backup, stream);
for(size_t i = 0; i < HISTORY; ++i)
for(uint16_t i = 0; i < HISTORY; ++i)
{
uint8_t* slot_i = uxr_get_output_buffer(&stream, i);
EXPECT_EQ(MAX_MESSAGE_SIZE, uxr_get_reliable_buffer_length(slot_i));
EXPECT_EQ(MAX_MESSAGE_SIZE, uxr_get_reliable_buffer_size(&stream.base, i));
}
}
@ -313,7 +296,7 @@ TEST_F(OutputReliableStreamTest, HeartbeatWithUpToDate)
TEST_F(OutputReliableStreamTest, HeartbeatFirstTry)
{
ucdrBuffer ub;
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
uint8_t* message; size_t length; uxrSeqNum seq_num;
(void) uxr_prepare_next_reliable_buffer_to_send(&stream, &message, &length, &seq_num);
@ -326,7 +309,7 @@ TEST_F(OutputReliableStreamTest, HeartbeatFirstTry)
TEST_F(OutputReliableStreamTest, HeartbeatSuccessfulTry)
{
ucdrBuffer ub;
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
uint8_t* message; size_t length; uxrSeqNum seq_num;
(void) uxr_prepare_next_reliable_buffer_to_send(&stream, &message, &length, &seq_num);
(void) uxr_update_output_stream_heartbeat_timestamp(&stream, 0);
@ -340,7 +323,7 @@ TEST_F(OutputReliableStreamTest, HeartbeatSuccessfulTry)
TEST_F(OutputReliableStreamTest, HeartbeatTwoSuccessfulTry)
{
ucdrBuffer ub;
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
uint8_t* message; size_t length; uxrSeqNum seq_num;
(void) uxr_prepare_next_reliable_buffer_to_send(&stream, &message, &length, &seq_num);
(void) uxr_update_output_stream_heartbeat_timestamp(&stream, 0);
@ -355,7 +338,7 @@ TEST_F(OutputReliableStreamTest, HeartbeatTwoSuccessfulTry)
TEST_F(OutputReliableStreamTest, HeartbeatUnsuccessfulSecondHeartbeat)
{
ucdrBuffer ub;
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
uint8_t* message; size_t length; uxrSeqNum seq_num;
(void) uxr_prepare_next_reliable_buffer_to_send(&stream, &message, &length, &seq_num);
(void) uxr_update_output_stream_heartbeat_timestamp(&stream, 0);
@ -369,9 +352,8 @@ TEST_F(OutputReliableStreamTest, HeartbeatUnsuccessfulSecondHeartbeat)
TEST_F(OutputReliableStreamTest, AcknackProcessNoLost)
{
uint8_t* slot_0 = uxr_get_output_buffer(&stream, 0);
ucdrBuffer ub;
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
uint8_t* message; size_t length; uxrSeqNum seq_num;
(void) uxr_prepare_next_reliable_buffer_to_send(&stream, &message, &length, &seq_num);
(void) uxr_update_output_stream_heartbeat_timestamp(&stream, 0);
@ -380,25 +362,23 @@ TEST_F(OutputReliableStreamTest, AcknackProcessNoLost)
EXPECT_FALSE(stream.send_lost);
EXPECT_EQ(0u, stream.last_acknown);
EXPECT_EQ(0u, stream.next_heartbeat_tries);
EXPECT_EQ(OFFSET, uxr_get_reliable_buffer_length(slot_0));
EXPECT_EQ(OFFSET, uxr_get_reliable_buffer_size(&stream.base, 0));
}
TEST_F(OutputReliableStreamTest, AcknackProcessLost)
{
uint8_t* slot_0 = uxr_get_output_buffer(&stream, 0);
ucdrBuffer ub;
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
uint8_t* message; size_t length; uxrSeqNum seq_num;
(void) uxr_prepare_next_reliable_buffer_to_send(&stream, &message, &length, &seq_num);
(void) uxr_update_output_stream_heartbeat_timestamp(&stream, 0);
size_t message_length = uxr_get_reliable_buffer_length(slot_0);
size_t message_length = uxr_get_reliable_buffer_size(&stream.base,0);
uxr_process_acknack(&stream, 1, uxrSeqNum(0));
EXPECT_TRUE(stream.send_lost);
EXPECT_EQ(SEQ_NUM_MAX, stream.last_acknown);
EXPECT_EQ(0u, stream.next_heartbeat_tries);
EXPECT_EQ(message_length, uxr_get_reliable_buffer_length(slot_0));
EXPECT_EQ(message_length, uxr_get_reliable_buffer_size(&stream.base, 0));
}
TEST_F(OutputReliableStreamTest, SendMessageLostNoLost)
@ -410,9 +390,9 @@ TEST_F(OutputReliableStreamTest, SendMessageLostNoLost)
TEST_F(OutputReliableStreamTest, SendMessageLost)
{
uint8_t* slot_0 = uxr_get_output_buffer(&stream, 0);
uint8_t* slot_0 = uxr_get_reliable_buffer(&stream.base, 0);
ucdrBuffer ub;
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, FRAGMENT_OFFSET, &ub);
(void) uxr_prepare_reliable_buffer_to_write(&stream, SUBMESSAGE_SIZE, &ub);
uint8_t* message; size_t length; uxrSeqNum seq_num;
(void) uxr_prepare_next_reliable_buffer_to_send(&stream, &message, &length, &seq_num);
(void) uxr_update_output_stream_heartbeat_timestamp(&stream, 0);
@ -433,16 +413,14 @@ TEST_F(OutputReliableStreamTest, SendMessageLost)
TEST_F(OutputReliableStreamTest, FragmentedSerialization)
{
uint8_t* slot_1 = uxr_get_output_buffer(&stream, 1);
uint8_t* slot_1 = uxr_get_reliable_buffer(&stream.base, 1);
ucdrBuffer ub;
uint8_t message[MAX_MESSAGE_SIZE + 4];
(void) uxr_prepare_reliable_buffer_to_write(&stream, MAX_SUBMESSAGE_SIZE + 4, FRAGMENT_OFFSET, &ub);
(void) uxr_prepare_reliable_buffer_to_write(&stream, MAX_SUBMESSAGE_SIZE + 4, &ub);
bool serialize = ucdr_serialize_array_uint8_t(&ub, message, MAX_SUBMESSAGE_SIZE + 4);
ASSERT_TRUE(serialize);
EXPECT_EQ(slot_1, ub.init);
EXPECT_EQ(slot_1 + uxr_get_reliable_buffer_length(slot_1), ub.iterator);
EXPECT_EQ(slot_1 + uxr_get_reliable_buffer_length(slot_1), ub.final);
EXPECT_EQ(slot_1 + uxr_get_reliable_buffer_size(&stream.base, 1), ub.iterator);
EXPECT_EQ(slot_1 + uxr_get_reliable_buffer_size(&stream.base, 1), ub.final);
}

Some files were not shown because too many files have changed in this diff Show More