diff --git a/.gitignore b/.gitignore index 9cb55751..eb55723e 100644 --- a/.gitignore +++ b/.gitignore @@ -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 \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c6f1f9e..2f7e7116 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 $<$,$>:src/c/core/log/log.c> $<$:src/c/profile/discovery/discovery.c> - ${UDP_DISCOVERY_SRCS} - ${UDP_SRCS} - ${TCP_SRCS} - ${SERIAL_SRCS} + $<$:src/c/profile/transport/ip/udp/udp_transport.c> + $<$,$>:src/c/profile/discovery/transport/udp_transport_datagram_posix.c> + $<$,$>:src/c/profile/discovery/transport/udp_transport_datagram_windows.c> + $<$:src/c/profile/transport/ip/udp/udp_transport.c> + $<$,$>:src/c/profile/transport/ip/udp/udp_transport_posix.c> + $<$,$>:src/c/profile/transport/ip/udp/udp_transport_posix_nopoll.c> + $<$,$>:src/c/profile/transport/ip/udp/udp_transport_windows.c> + $<$:src/c/profile/transport/ip/tcp/tcp_transport.c> + $<$,$>:src/c/profile/transport/ip/tcp/tcp_transport_posix.c> + $<$,$>:src/c/profile/transport/ip/tcp/tcp_transport_windows.c> + $<$,$,$>>:src/c/profile/transport/serial/serial_transport.c> + $<$,$,$>>:src/c/profile/transport/serial/serial_protocol.c> + $<$,$>:src/c/profile/transport/serial/serial_transport_posix.c> + $<$: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> + $<$,$>:src/c/profile/transport/ip/ip_posix.c> + $<$>: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 $ $ - $ + $ PRIVATE $ ) @@ -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}$,,/> + DESTINATION + ${CMAKE_INSTALL_PREFIX}$,/../,> + COMPONENT + ${_d} + USE_SOURCE_PERMISSIONS ) + endforeach() endif() diff --git a/CTestConfig.cmake b/CTestConfig.cmake index f10eab53..aecb4819 100644 --- a/CTestConfig.cmake +++ b/CTestConfig.cmake @@ -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() \ No newline at end of file diff --git a/ci/linux/CMakeLists.txt b/ci/linux/CMakeLists.txt index 261a72be..929d8037 100644 --- a/ci/linux/CMakeLists.txt +++ b/ci/linux/CMakeLists.txt @@ -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,37 @@ 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} + -DCMAKE_EXE_LINKER_FLAGS:STRING=${_exe_linker_flags} + -DCMAKE_SHARED_LINKER_FLAGS:STRING=${_shared_linker_flags} + -DCMAKE_INSTALL_PREFIX:PATH= + -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} @@ -44,5 +90,10 @@ ExternalProject_Add(microxrcedds_client -DCMAKE_SHARED_LINKER_FLAGS:STRING=${_shared_linker_flags} -DCMAKE_INSTALL_PREFIX:PATH= -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 ) \ No newline at end of file diff --git a/client.config b/client.config index 5f03cf16..273d9ef2 100644 --- a/client.config +++ b/client.config @@ -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 diff --git a/cmake/SuperBuild.cmake b/cmake/SuperBuild.cmake index 46e81b30..6dd80029 100644 --- a/cmake/SuperBuild.cmake +++ b/cmake/SuperBuild.cmake @@ -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= @@ -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= $<$:-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} - ) + ) \ No newline at end of file diff --git a/colcon.pkg b/colcon.pkg new file mode 100644 index 00000000..4ff49e3d --- /dev/null +++ b/colcon.pkg @@ -0,0 +1,11 @@ +{ + "name": "microxrcedds_client", + "type": "cmake", + "dependencies":[ + "microcdr" + ], + "cmake-args":[ + "-DUCLIENT_ISOLATED_INSTALL=OFF", + "-DUCLIENT_SUPERBUILD=OFF" + ] +} diff --git a/examples/Deployment/configurator_client.c b/examples/Deployment/configurator_client.c index 6dedd002..a2603abe 100644 --- a/examples/Deployment/configurator_client.c +++ b/examples/Deployment/configurator_client.c @@ -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; diff --git a/examples/Deployment/publisher.c b/examples/Deployment/publisher.c index e3bf5313..92a3c9d2 100644 --- a/examples/Deployment/publisher.c +++ b/examples/Deployment/publisher.c @@ -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; diff --git a/examples/Deployment/subscriber.c b/examples/Deployment/subscriber.c index f21bb077..5b0553fa 100644 --- a/examples/Deployment/subscriber.c +++ b/examples/Deployment/subscriber.c @@ -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; diff --git a/examples/Discovery/main.c b/examples/Discovery/main.c index c298c77a..f88b8cd7 100644 --- a/examples/Discovery/main.c +++ b/examples/Discovery/main.c @@ -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); diff --git a/examples/MultiSessionHelloWorld/CMakeLists.txt b/examples/MultiSessionHelloWorld/CMakeLists.txt new file mode 100644 index 00000000..e5fe4d70 --- /dev/null +++ b/examples/MultiSessionHelloWorld/CMakeLists.txt @@ -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 $<$:-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() diff --git a/examples/MultiSessionHelloWorld/HelloWorld.c b/examples/MultiSessionHelloWorld/HelloWorld.c new file mode 100644 index 00000000..7ebb8253 --- /dev/null +++ b/examples/MultiSessionHelloWorld/HelloWorld.c @@ -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 +#include + +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; +} diff --git a/examples/MultiSessionHelloWorld/HelloWorld.h b/examples/MultiSessionHelloWorld/HelloWorld.h new file mode 100644 index 00000000..0e718021 --- /dev/null +++ b/examples/MultiSessionHelloWorld/HelloWorld.h @@ -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 +#include + +/*! + * @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_ diff --git a/examples/MultiSessionHelloWorld/HelloWorld.idl b/examples/MultiSessionHelloWorld/HelloWorld.idl new file mode 100644 index 00000000..0fd2c355 --- /dev/null +++ b/examples/MultiSessionHelloWorld/HelloWorld.idl @@ -0,0 +1,5 @@ +struct HelloWorld +{ + unsigned long index; + string message; +}; diff --git a/examples/MultiSessionHelloWorld/README.md b/examples/MultiSessionHelloWorld/README.md new file mode 100644 index 00000000..f1e619df --- /dev/null +++ b/examples/MultiSessionHelloWorld/README.md @@ -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; +}; +``` + diff --git a/examples/MultiSessionHelloWorld/main.c b/examples/MultiSessionHelloWorld/main.c new file mode 100644 index 00000000..4b700931 --- /dev/null +++ b/examples/MultiSessionHelloWorld/main.c @@ -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 +#include + +#include //printf +#include //strcmp +#include //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 []\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 = "" + "" + "" + "default_xrce_participant_1" + "" + "" + ""; + 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 = "" + "" + "HelloWorldTopic" + "HelloWorld" + "" + ""; + 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 = "" + "" + "" + "NO_KEY" + "HelloWorldTopic_1_to_2" + "HelloWorld" + "" + "" + ""; + 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 = "" + "" + "" + "NO_KEY" + "HelloWorldTopic_2_to_1" + "HelloWorld" + "" + "" + ""; + 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 = "" + "" + "" + "default_xrce_participant_2" + "" + "" + ""; + 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 = "" + "" + "HelloWorldTopic" + "HelloWorld" + "" + ""; + 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 = "" + "" + "" + "NO_KEY" + "HelloWorldTopic_2_to_1" + "HelloWorld" + "" + "" + ""; + 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 = "" + "" + "" + "NO_KEY" + "HelloWorldTopic_1_to_2" + "HelloWorld" + "" + "" + ""; + 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; +} diff --git a/examples/PublishHelloWorld/main.c b/examples/PublishHelloWorld/main.c index 6fdd9237..aeed1679 100644 --- a/examples/PublishHelloWorld/main.c +++ b/examples/PublishHelloWorld/main.c @@ -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; diff --git a/examples/PublishHelloWorldP2P/main.c b/examples/PublishHelloWorldP2P/main.c index 7804bbdd..1b0383b3 100644 --- a/examples/PublishHelloWorldP2P/main.c +++ b/examples/PublishHelloWorldP2P/main.c @@ -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; diff --git a/examples/ReplyAdder/CMakeLists.txt b/examples/ReplyAdder/CMakeLists.txt new file mode 100644 index 00000000..65812b55 --- /dev/null +++ b/examples/ReplyAdder/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/examples/ReplyAdder/main.c b/examples/ReplyAdder/main.c new file mode 100644 index 00000000..3c5d3938 --- /dev/null +++ b/examples/ReplyAdder/main.c @@ -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 + +#include +#include +#include +#include + +#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 = "" + "" + "" + "default_xrce_participant" + "" + "" + ""; + 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 = "" + "" + "" + ""; + 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; +} \ No newline at end of file diff --git a/examples/RequestAdder/CMakeLists.txt b/examples/RequestAdder/CMakeLists.txt new file mode 100644 index 00000000..d692af8d --- /dev/null +++ b/examples/RequestAdder/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/examples/RequestAdder/main.c b/examples/RequestAdder/main.c new file mode 100644 index 00000000..160f94ce --- /dev/null +++ b/examples/RequestAdder/main.c @@ -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 + +#include +#include +#include +#include + +#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 = "" + "" + "" + "default_xrce_participant" + "" + "" + ""; + 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 = "" + "" + "" + ""; + 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; +} \ No newline at end of file diff --git a/examples/ShapesDemo/main.c b/examples/ShapesDemo/main.c index aaa5cc92..23f268b3 100644 --- a/examples/ShapesDemo/main.c +++ b/examples/ShapesDemo/main.c @@ -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: %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: %hu\n", argv[2], port); + 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 [--key ] [--history ]\n"); printf("List of available transports:\n"); printf(" --serial \n"); - printf(" --udp \n"); - printf(" --tcp \n"); + printf(" --udp4 \n"); + printf(" --udp6 \n"); + printf(" --tcp4 \n"); + printf(" --tcp6 \n"); } void print_commands(void) diff --git a/examples/SubscribeHelloWorld/main.c b/examples/SubscribeHelloWorld/main.c index 61fe78d9..cae84527 100644 --- a/examples/SubscribeHelloWorld/main.c +++ b/examples/SubscribeHelloWorld/main.c @@ -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; diff --git a/examples/SubscribeHelloWorldP2P/main.c b/examples/SubscribeHelloWorldP2P/main.c index 368554d1..973d6c3d 100644 --- a/examples/SubscribeHelloWorldP2P/main.c +++ b/examples/SubscribeHelloWorldP2P/main.c @@ -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; diff --git a/include/uxr/client/config.h.in b/include/uxr/client/config.h.in index e32973da..2bec7e7a 100644 --- a/include/uxr/client/config.h.in +++ b/include/uxr/client/config.h.in @@ -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@ diff --git a/include/uxr/client/core/session/create_entities_ref.h b/include/uxr/client/core/session/create_entities_ref.h index 6d058de4..89254d69 100644 --- a/include/uxr/client/core/session/create_entities_ref.h +++ b/include/uxr/client/core/session/create_entities_ref.h @@ -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 diff --git a/include/uxr/client/core/session/create_entities_xml.h b/include/uxr/client/core/session/create_entities_xml.h index b720fad7..20b287dd 100644 --- a/include/uxr/client/core/session/create_entities_xml.h +++ b/include/uxr/client/core/session/create_entities_xml.h @@ -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 diff --git a/include/uxr/client/core/session/object_id.h b/include/uxr/client/core/session/object_id.h index 22e76af3..781eda14 100644 --- a/include/uxr/client/core/session/object_id.h +++ b/include/uxr/client/core/session/object_id.h @@ -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 diff --git a/include/uxr/client/core/session/session.h b/include/uxr/client/core/session/session.h index 16439375..8a63c14f 100644 --- a/include/uxr/client/core/session/session.h +++ b/include/uxr/client/core/session/session.h @@ -22,31 +22,54 @@ extern "C" #include #include +#include #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 (*uxrOnTopicFunc) (struct uxrSession* session, - uxrObjectId object_id, - uint16_t request_id, - uxrStreamId stream_id, - struct ucdrBuffer* ub, - 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 (*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, + 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 (*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: diff --git a/include/uxr/client/core/session/stream/input_reliable_stream.h b/include/uxr/client/core/session/stream/input_reliable_stream.h index 4486f19c..c92f9048 100644 --- a/include/uxr/client/core/session/stream/input_reliable_stream.h +++ b/include/uxr/client/core/session/stream/input_reliable_stream.h @@ -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 #include #include -#include 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_ diff --git a/include/uxr/client/core/session/stream/output_reliable_stream.h b/include/uxr/client/core/session/stream/output_reliable_stream.h index 3c1bd40e..6f124b6b 100644 --- a/include/uxr/client/core/session/stream/output_reliable_stream.h +++ b/include/uxr/client/core/session/stream/output_reliable_stream.h @@ -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 #include -#include #include 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_ diff --git a/include/uxr/client/core/session/stream/reliable_stream.h b/include/uxr/client/core/session/stream/reliable_stream.h new file mode 100644 index 00000000..8461f6c6 --- /dev/null +++ b/include/uxr/client/core/session/stream/reliable_stream.h @@ -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 +#include + +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_ diff --git a/include/uxr/client/core/session/write_access.h b/include/uxr/client/core/session/write_access.h index 59293412..0552d137 100644 --- a/include/uxr/client/core/session/write_access.h +++ b/include/uxr/client/core/session/write_access.h @@ -22,12 +22,53 @@ extern "C" #include +/** + * @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. diff --git a/src/c/core/serialization/xrce_protocol_internal.h b/include/uxr/client/core/type/xrce_types.h similarity index 90% rename from src/c/core/serialization/xrce_protocol_internal.h rename to include/uxr/client/core/type/xrce_types.h index c600bc57..6e78f34d 100644 --- a/src/c/core/serialization/xrce_protocol_internal.h +++ b/include/uxr/client/core/type/xrce_types.h @@ -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 #include +// 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_ diff --git a/include/uxr/client/profile/discovery/discovery.h b/include/uxr/client/profile/discovery/discovery.h index 6af13a66..761272bb 100644 --- a/include/uxr/client/profile/discovery/discovery.h +++ b/include/uxr/client/profile/discovery/discovery.h @@ -22,19 +22,13 @@ extern "C" #include #include +#include #include #include #include -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 diff --git a/include/uxr/client/profile/transport/ip/ip.h b/include/uxr/client/profile/transport/ip/ip.h new file mode 100644 index 00000000..c5664105 --- /dev/null +++ b/include/uxr/client/profile/transport/ip/ip.h @@ -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 + +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_ diff --git a/include/uxr/client/profile/transport/tcp/tcp_transport.h b/include/uxr/client/profile/transport/ip/tcp/tcp_transport.h similarity index 71% rename from include/uxr/client/profile/transport/tcp/tcp_transport.h rename to include/uxr/client/profile/transport/ip/tcp/tcp_transport.h index b5a55d55..c83838fe 100644 --- a/include/uxr/client/profile/transport/tcp/tcp_transport.h +++ b/include/uxr/client/profile/transport/ip/tcp/tcp_transport.h @@ -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 #include #include #include @@ -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_ diff --git a/include/uxr/client/profile/transport/ip/tcp/tcp_transport_external.h.template b/include/uxr/client/profile/transport/ip/tcp/tcp_transport_external.h.template new file mode 100644 index 00000000..8c74efc9 --- /dev/null +++ b/include/uxr/client/profile/transport/ip/tcp/tcp_transport_external.h.template @@ -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_ \ No newline at end of file diff --git a/include/uxr/client/profile/transport/tcp/tcp_transport_linux.h b/include/uxr/client/profile/transport/ip/tcp/tcp_transport_posix.h similarity index 81% rename from include/uxr/client/profile/transport/tcp/tcp_transport_linux.h rename to include/uxr/client/profile/transport/ip/tcp/tcp_transport_posix.h index 2b06aa61..c111308d 100644 --- a/include/uxr/client/profile/transport/tcp/tcp_transport_linux.h +++ b/include/uxr/client/profile/transport/ip/tcp/tcp_transport_posix.h @@ -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_ \ No newline at end of file diff --git a/include/uxr/client/profile/transport/tcp/tcp_transport_windows.h b/include/uxr/client/profile/transport/ip/tcp/tcp_transport_windows.h similarity index 82% rename from include/uxr/client/profile/transport/tcp/tcp_transport_windows.h rename to include/uxr/client/profile/transport/ip/tcp/tcp_transport_windows.h index 2b7041bc..987a3a38 100644 --- a/include/uxr/client/profile/transport/tcp/tcp_transport_windows.h +++ b/include/uxr/client/profile/transport/ip/tcp/tcp_transport_windows.h @@ -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_ diff --git a/include/uxr/client/profile/transport/udp/udp_transport.h b/include/uxr/client/profile/transport/ip/udp/udp_transport.h similarity index 71% rename from include/uxr/client/profile/transport/udp/udp_transport.h rename to include/uxr/client/profile/transport/ip/udp/udp_transport.h index cc7df576..79213676 100644 --- a/include/uxr/client/profile/transport/udp/udp_transport.h +++ b/include/uxr/client/profile/transport/ip/udp/udp_transport.h @@ -20,6 +20,7 @@ extern "C" { #endif +#include #include #include #include @@ -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 diff --git a/include/uxr/client/profile/transport/ip/udp/udp_transport_external.h.template b/include/uxr/client/profile/transport/ip/udp/udp_transport_external.h.template new file mode 100644 index 00000000..b61409a5 --- /dev/null +++ b/include/uxr/client/profile/transport/ip/udp/udp_transport_external.h.template @@ -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_ \ No newline at end of file diff --git a/include/uxr/client/profile/transport/udp/udp_transport_linux.h b/include/uxr/client/profile/transport/ip/udp/udp_transport_posix.h similarity index 81% rename from include/uxr/client/profile/transport/udp/udp_transport_linux.h rename to include/uxr/client/profile/transport/ip/udp/udp_transport_posix.h index 9dc751cf..b661e44a 100644 --- a/include/uxr/client/profile/transport/udp/udp_transport_linux.h +++ b/include/uxr/client/profile/transport/ip/udp/udp_transport_posix.h @@ -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_ diff --git a/include/uxr/client/profile/transport/ip/udp/udp_transport_posix_nopoll.h b/include/uxr/client/profile/transport/ip/udp/udp_transport_posix_nopoll.h new file mode 100644 index 00000000..22a500e2 --- /dev/null +++ b/include/uxr/client/profile/transport/ip/udp/udp_transport_posix_nopoll.h @@ -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_ \ No newline at end of file diff --git a/include/uxr/client/profile/transport/udp/udp_transport_windows.h b/include/uxr/client/profile/transport/ip/udp/udp_transport_windows.h similarity index 82% rename from include/uxr/client/profile/transport/udp/udp_transport_windows.h rename to include/uxr/client/profile/transport/ip/udp/udp_transport_windows.h index d7445a6a..9afb9590 100644 --- a/include/uxr/client/profile/transport/udp/udp_transport_windows.h +++ b/include/uxr/client/profile/transport/ip/udp/udp_transport_windows.h @@ -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_ diff --git a/include/uxr/client/profile/transport/serial/serial_transport_external.h.template b/include/uxr/client/profile/transport/serial/serial_transport_external.h.template new file mode 100644 index 00000000..ad8661c8 --- /dev/null +++ b/include/uxr/client/profile/transport/serial/serial_transport_external.h.template @@ -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_ \ No newline at end of file diff --git a/src/c/profile/transport/serial/serial_transport_internal.h b/include/uxr/client/profile/transport/serial/serial_transport_platform.h similarity index 87% rename from src/c/profile/transport/serial/serial_transport_internal.h rename to include/uxr/client/profile/transport/serial/serial_transport_platform.h index 58bbc4bd..3dfc4a79 100644 --- a/src/c/profile/transport/serial/serial_transport_internal.h +++ b/include/uxr/client/profile/transport/serial/serial_transport_platform.h @@ -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_ diff --git a/include/uxr/client/profile/transport/serial/serial_transport_linux.h b/include/uxr/client/profile/transport/serial/serial_transport_posix.h similarity index 79% rename from include/uxr/client/profile/transport/serial/serial_transport_linux.h rename to include/uxr/client/profile/transport/serial/serial_transport_posix.h index f41fbef3..6a0545c5 100644 --- a/include/uxr/client/profile/transport/serial/serial_transport_linux.h +++ b/include/uxr/client/profile/transport/serial/serial_transport_posix.h @@ -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_ diff --git a/include/uxr/client/transport.h b/include/uxr/client/transport.h index 879dfb4f..f006416e 100644 --- a/include/uxr/client/transport.h +++ b/include/uxr/client/transport.h @@ -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 #ifdef PROFILE_UDP_TRANSPORT -#include -#if defined(PLATFORM_NAME_LINUX) -#include -#elif defined(PLATFORM_NAME_WINDOWS) -#include -#elif defined(PLATFORM_NAME_NUTTX) -#include +#include +#if defined(UCLIENT_EXTERNAL_UDP) +#include +#elif defined(UCLIENT_PLATFORM_POSIX_NOPOLL) +#include +#elif defined(UCLIENT_PLATFORM_POSIX) +#include +#elif defined(UCLIENT_PLATFORM_WINDOWS) +#include #endif #endif //PROFILE_UDP_TRANSPORT #ifdef PROFILE_TCP_TRANSPORT -#include -#if defined(PLATFORM_NAME_LINUX) -#include -#elif defined(PLATFORM_NAME_WINDOWS) -#include -#elif defined(PLATFORM_NAME_NUTTX) -#include +#include +#if defined(UCLIENT_EXTERNAL_TCP) +#include +#elif defined(UCLIENT_PLATFORM_POSIX) +#include +#elif defined(UCLIENT_PLATFORM_WINDOWS) +#include #endif #endif //PROFILE_TCP_TRANSPORT #ifdef PROFILE_SERIAL_TRANSPORT #include -#if defined(PLATFORM_NAME_LINUX) -#include -#elif defined(PLATFORM_NAME_WINDOWS) -#elif defined(PLATFORM_NAME_NUTTX) -#include +#if defined(UCLIENT_EXTERNAL_SERIAL) +#include +#elif defined(UCLIENT_PLATFORM_POSIX) +#include +#elif defined(UCLIENT_PLATFORM_WINDOWS) #endif #endif //PROFILE_SERIAL_TRANSPORT -#endif // _UXR_CLIENT_TRANSPORT_H_ +#endif // UXR_CLIENT_TRANSPORT_H_ diff --git a/src/c/core/log/log.c b/src/c/core/log/log.c index 060d0bcc..2d717cfa 100644 --- a/src/c/core/log/log.c +++ b/src/c/core/log/log.c @@ -13,11 +13,11 @@ // limitations under the License. #include +#include #include #include #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, diff --git a/src/c/core/serialization/xrce_protocol.c b/src/c/core/serialization/xrce_types.c similarity index 91% rename from src/c/core/serialization/xrce_protocol.c rename to src/c/core/serialization/xrce_types.c index 282bd975..20925277 100644 --- a/src/c/core/serialization/xrce_protocol.c +++ b/src/c/core/serialization/xrce_types.c @@ -1,4 +1,4 @@ -#include "xrce_protocol_internal.h" +#include #include //================================================================== @@ -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) { diff --git a/src/c/core/session/common_create_entities.c b/src/c/core/session/common_create_entities.c index 5b5f8a7c..75d1fbeb 100644 --- a/src/c/core/session/common_create_entities.c +++ b/src/c/core/session/common_create_entities.c @@ -1,8 +1,9 @@ +#include + #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; diff --git a/src/c/core/session/create_entities_ref.c b/src/c/core/session/create_entities_ref.c index 6135d77c..b4fd44e8 100644 --- a/src/c/core/session/create_entities_ref.c +++ b/src/c/core/session/create_entities_ref.c @@ -1,7 +1,7 @@ #include +#include #include "common_create_entities_internal.h" -#include "../serialization/xrce_protocol_internal.h" #include @@ -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); diff --git a/src/c/core/session/create_entities_xml.c b/src/c/core/session/create_entities_xml.c index e7514a99..0d3256f6 100644 --- a/src/c/core/session/create_entities_xml.c +++ b/src/c/core/session/create_entities_xml.c @@ -1,7 +1,7 @@ #include +#include #include "common_create_entities_internal.h" -#include "../serialization/xrce_protocol_internal.h" #include @@ -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); diff --git a/src/c/core/session/read_access.c b/src/c/core/session/read_access.c index f2d6ec61..54653f5d 100644 --- a/src/c/core/session/read_access.c +++ b/src/c/core/session/read_access.c @@ -1,9 +1,9 @@ #include +#include #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( diff --git a/src/c/core/session/session.c b/src/c/core/session/session.c index 3315770f..21cc2f99 100644 --- a/src/c/core/session/session.c +++ b/src/c/core/session/session.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #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; diff --git a/src/c/core/session/session_info.c b/src/c/core/session/session_info.c index b4d430e5..a962feff 100644 --- a/src/c/core/session/session_info.c +++ b/src/c/core/session/session_info.c @@ -1,9 +1,9 @@ #include #include +#include #include "session_info_internal.h" #include "submessage_internal.h" -#include "../serialization/xrce_protocol_internal.h" #include "../serialization/xrce_header_internal.h" #include @@ -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; diff --git a/src/c/core/session/stream/common_reliable_stream_internal.h b/src/c/core/session/stream/common_reliable_stream_internal.h index d6ca0bc2..a10a460a 100644 --- a/src/c/core/session/stream/common_reliable_stream_internal.h +++ b/src/c/core/session/stream/common_reliable_stream_internal.h @@ -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 + #include #include #include @@ -28,33 +30,54 @@ extern "C" typedef uint32_t length_t; #define INTERNAL_RELIABLE_BUFFER_OFFSET sizeof(length_t) - -static inline size_t uxr_get_reliable_buffer_length(uint8_t* buffer) +static inline uint8_t * uxr_get_reliable_buffer( + uxrReliableStream const * stream, + uint16_t seq_num) { - length_t length; - memcpy(&length, buffer - INTERNAL_RELIABLE_BUFFER_OFFSET, INTERNAL_RELIABLE_BUFFER_OFFSET); - return (size_t)length; + return stream->buffer + + ((seq_num % stream->history) * (stream->size / stream->history)) + + INTERNAL_RELIABLE_BUFFER_OFFSET; } -static inline void uxr_set_reliable_buffer_length(uint8_t* buffer, size_t length) +static inline size_t uxr_get_reliable_buffer_capacity( + uxrReliableStream const * stream) { - length_t internal_length = (length_t)length; - memcpy(buffer - INTERNAL_RELIABLE_BUFFER_OFFSET, &internal_length, INTERNAL_RELIABLE_BUFFER_OFFSET); + return stream->size / stream->history - 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) +static inline uint16_t uxr_get_reliable_buffer_history_position( + uxrReliableStream const * stream, + uint8_t const * current_position) { - return buffer + history_pos * (size / history) + INTERNAL_RELIABLE_BUFFER_OFFSET; + return (uint16_t)((size_t)(current_position - stream->buffer) / (stream->size / stream->history)); } -static inline size_t uxr_get_reliable_buffer_size(size_t size, size_t history) +static inline size_t uxr_get_reliable_buffer_size( + uxrReliableStream const * stream, + uint16_t seq_num) { - return size / history - INTERNAL_RELIABLE_BUFFER_OFFSET; + length_t length; + 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_size( + uxrReliableStream const * stream, + uint16_t seq_num, + size_t length) +{ + 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); +} #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_ diff --git a/src/c/core/session/stream/input_reliable_stream.c b/src/c/core/session/stream/input_reliable_stream.c index 8e99d2ac..d90976f3 100644 --- a/src/c/core/session/stream/input_reliable_stream.c +++ b/src/c/core/session/stream/input_reliable_stream.c @@ -1,8 +1,10 @@ -#include "seq_num_internal.h" -#include "input_reliable_stream_internal.h" -#include "common_reliable_stream_internal.h" #include +#include "./seq_num_internal.h" +#include "./input_reliable_stream_internal.h" +#include "./common_reliable_stream_internal.h" +#include "../submessage_internal.h" + #include 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; diff --git a/src/c/core/session/stream/input_reliable_stream_internal.h b/src/c/core/session/stream/input_reliable_stream_internal.h index cf794731..5c88d8b4 100644 --- a/src/c/core/session/stream/input_reliable_stream_internal.h +++ b/src/c/core/session/stream/input_reliable_stream_internal.h @@ -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 diff --git a/src/c/core/session/stream/output_best_effort_stream.c b/src/c/core/session/stream/output_best_effort_stream.c index f70903bc..f28d0cb4 100644 --- a/src/c/core/session/stream/output_best_effort_stream.c +++ b/src/c/core/session/stream/output_best_effort_stream.c @@ -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; } diff --git a/src/c/core/session/stream/output_reliable_stream.c b/src/c/core/session/stream/output_reliable_stream.c index 8ac6cced..6894bce9 100644 --- a/src/c/core/session/stream/output_reliable_stream.c +++ b/src/c/core/session/stream/output_reliable_stream.c @@ -1,12 +1,13 @@ #include "output_reliable_stream_internal.h" #include +#include #include -#include "seq_num_internal.h" -#include "output_reliable_stream_internal.h" -#include "common_reliable_stream_internal.h" -#include +#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_offset(ub, initial_buffer, (uint32_t)block_size, (uint32_t)initial_length); + 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( + 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; } diff --git a/src/c/core/session/stream/output_reliable_stream_internal.h b/src/c/core/session/stream/output_reliable_stream_internal.h index 47d05581..31eace83 100644 --- a/src/c/core/session/stream/output_reliable_stream_internal.h +++ b/src/c/core/session/stream/output_reliable_stream_internal.h @@ -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 diff --git a/src/c/core/session/stream/stream_storage.c b/src/c/core/session/stream/stream_storage.c index 71584197..8cae5690 100644 --- a/src/c/core/session/stream/stream_storage.c +++ b/src/c/core/session/stream/stream_storage.c @@ -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); } diff --git a/src/c/core/session/stream/stream_storage_internal.h b/src/c/core/session/stream/stream_storage_internal.h index 97abd0bd..d2b65b6b 100644 --- a/src/c/core/session/stream/stream_storage_internal.h +++ b/src/c/core/session/stream/stream_storage_internal.h @@ -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); diff --git a/src/c/core/session/write_access.c b/src/c/core/session/write_access.c index 4d3baacf..7a60d155 100644 --- a/src/c/core/session/write_access.c +++ b/src/c/core/session/write_access.c @@ -1,15 +1,64 @@ #include +#include #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; diff --git a/src/c/profile/discovery/discovery.c b/src/c/profile/discovery/discovery.c index 385eef37..87346938 100644 --- a/src/c/profile/discovery/discovery.c +++ b/src/c/profile/discovery/discovery.c @@ -1,9 +1,10 @@ #include +#include #include #include +#include #include -#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; -} - diff --git a/src/c/profile/discovery/transport/udp_transport_datagram_internal.h b/src/c/profile/discovery/transport/udp_transport_datagram_internal.h index c4c51226..257ec1b5 100644 --- a/src/c/profile/discovery/transport/udp_transport_datagram_internal.h +++ b/src/c/profile/discovery/transport/udp_transport_datagram_internal.h @@ -22,34 +22,30 @@ extern "C" #include #include +#include #include #include #include -#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 #include #include -#elif defined(PLATFORM_NAME_WINDOWS) +#elif defined(UCLIENT_PLATFORM_WINDOWS) #include #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, diff --git a/src/c/profile/discovery/transport/udp_transport_datagram_linux.c b/src/c/profile/discovery/transport/udp_transport_datagram_posix.c similarity index 69% rename from src/c/profile/discovery/transport/udp_transport_datagram_linux.c rename to src/c/profile/discovery/transport/udp_transport_datagram_posix.c index 58790f74..00e9d839 100644 --- a/src/c/profile/discovery/transport/udp_transport_datagram_linux.c +++ b/src/c/profile/discovery/transport/udp_transport_datagram_posix.c @@ -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; } diff --git a/src/c/profile/discovery/transport/udp_transport_datagram_windows.c b/src/c/profile/discovery/transport/udp_transport_datagram_windows.c index 9e17245d..4b3c3878 100644 --- a/src/c/profile/discovery/transport/udp_transport_datagram_windows.c +++ b/src/c/profile/discovery/transport/udp_transport_datagram_windows.c @@ -3,7 +3,8 @@ #include #include -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; } diff --git a/src/c/profile/transport/ip/ip_posix.c b/src/c/profile/transport/ip/ip_posix.c new file mode 100644 index 00000000..66a0b263 --- /dev/null +++ b/src/c/profile/transport/ip/ip_posix.c @@ -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 +#include + +#if defined(UCLIENT_PLATFORM_POSIX) +#include +#elif defined(UCLIENT_PLATFORM_POSIX_NOPOLL) +#include +#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; +} \ No newline at end of file diff --git a/src/c/profile/transport/ip/ip_windows.c b/src/c/profile/transport/ip/ip_windows.c new file mode 100644 index 00000000..9854519b --- /dev/null +++ b/src/c/profile/transport/ip/ip_windows.c @@ -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 + +#include + +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; +} \ No newline at end of file diff --git a/src/c/profile/transport/tcp/tcp_transport.c b/src/c/profile/transport/ip/tcp/tcp_transport.c similarity index 97% rename from src/c/profile/transport/tcp/tcp_transport.c rename to src/c/profile/transport/ip/tcp/tcp_transport.c index 83a446f7..d0c70743 100644 --- a/src/c/profile/transport/tcp/tcp_transport.c +++ b/src/c/profile/transport/ip/tcp/tcp_transport.c @@ -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; diff --git a/src/c/profile/transport/ip/tcp/tcp_transport_external.c.template b/src/c/profile/transport/ip/tcp/tcp_transport_external.c.template new file mode 100644 index 00000000..bcf8720b --- /dev/null +++ b/src/c/profile/transport/ip/tcp/tcp_transport_external.c.template @@ -0,0 +1,48 @@ +#include +#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 +} diff --git a/src/c/profile/transport/ip/tcp/tcp_transport_internal.h b/src/c/profile/transport/ip/tcp/tcp_transport_internal.h new file mode 100644 index 00000000..5902a48e --- /dev/null +++ b/src/c/profile/transport/ip/tcp/tcp_transport_internal.h @@ -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 + +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_ diff --git a/src/c/profile/transport/ip/tcp/tcp_transport_posix.c b/src/c/profile/transport/ip/tcp/tcp_transport_posix.c new file mode 100644 index 00000000..696d85e2 --- /dev/null +++ b/src/c/profile/transport/ip/tcp/tcp_transport_posix.c @@ -0,0 +1,134 @@ +#include +#include "tcp_transport_internal.h" + +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/src/c/profile/transport/tcp/tcp_transport_windows.c b/src/c/profile/transport/ip/tcp/tcp_transport_windows.c similarity index 56% rename from src/c/profile/transport/tcp/tcp_transport_windows.c rename to src/c/profile/transport/ip/tcp/tcp_transport_windows.c index a36fdc2d..3fd9a31e 100644 --- a/src/c/profile/transport/tcp/tcp_transport_windows.c +++ b/src/c/profile/transport/ip/tcp/tcp_transport_windows.c @@ -1,38 +1,66 @@ -#include +#include #include "tcp_transport_internal.h" #include -bool uxr_init_tcp_platform(struct uxrTCPPlatform* platform, const char* ip, uint16_t port) +#include + +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; } diff --git a/src/c/profile/transport/udp/udp_transport.c b/src/c/profile/transport/ip/udp/udp_transport.c similarity index 91% rename from src/c/profile/transport/udp/udp_transport.c rename to src/c/profile/transport/ip/udp/udp_transport.c index 1353a7b7..4ce77585 100644 --- a/src/c/profile/transport/udp/udp_transport.c +++ b/src/c/profile/transport/ip/udp/udp_transport.c @@ -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; diff --git a/src/c/profile/transport/ip/udp/udp_transport_external.c.template b/src/c/profile/transport/ip/udp/udp_transport_external.c.template new file mode 100644 index 00000000..8f7d985b --- /dev/null +++ b/src/c/profile/transport/ip/udp/udp_transport_external.c.template @@ -0,0 +1,42 @@ +#include +#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) +} diff --git a/src/c/profile/transport/ip/udp/udp_transport_internal.h b/src/c/profile/transport/ip/udp/udp_transport_internal.h new file mode 100644 index 00000000..c8ff1aad --- /dev/null +++ b/src/c/profile/transport/ip/udp/udp_transport_internal.h @@ -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 + +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_ diff --git a/src/c/profile/transport/ip/udp/udp_transport_posix.c b/src/c/profile/transport/ip/udp/udp_transport_posix.c new file mode 100644 index 00000000..c9e33103 --- /dev/null +++ b/src/c/profile/transport/ip/udp/udp_transport_posix.c @@ -0,0 +1,116 @@ +#include +#include "udp_transport_internal.h" + +#include +#include +#include +#include +#include + +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; +} diff --git a/src/c/profile/transport/ip/udp/udp_transport_posix_nopoll.c b/src/c/profile/transport/ip/udp/udp_transport_posix_nopoll.c new file mode 100644 index 00000000..0f405cba --- /dev/null +++ b/src/c/profile/transport/ip/udp/udp_transport_posix_nopoll.c @@ -0,0 +1,116 @@ +#include +#include "udp_transport_internal.h" + +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/src/c/profile/transport/ip/udp/udp_transport_windows.c b/src/c/profile/transport/ip/udp/udp_transport_windows.c new file mode 100644 index 00000000..0e3e754b --- /dev/null +++ b/src/c/profile/transport/ip/udp/udp_transport_windows.c @@ -0,0 +1,119 @@ +#include +#include "udp_transport_internal.h" + +#include + +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; +} diff --git a/src/c/profile/transport/serial/serial_transport.c b/src/c/profile/transport/serial/serial_transport.c index 4d8f3af4..4ab0c9ed 100644 --- a/src/c/profile/transport/serial/serial_transport.c +++ b/src/c/profile/transport/serial/serial_transport.c @@ -1,4 +1,4 @@ -#include "serial_transport_internal.h" +#include #include "serial_protocol_internal.h" #include diff --git a/src/c/profile/transport/serial/serial_transport_external.c.template b/src/c/profile/transport/serial/serial_transport_external.c.template new file mode 100644 index 00000000..295c4dd2 --- /dev/null +++ b/src/c/profile/transport/serial/serial_transport_external.c.template @@ -0,0 +1,28 @@ +#include +#include + +// 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) +} diff --git a/src/c/profile/transport/serial/serial_transport_linux.c b/src/c/profile/transport/serial/serial_transport_posix.c similarity index 90% rename from src/c/profile/transport/serial/serial_transport_linux.c rename to src/c/profile/transport/serial/serial_transport_posix.c index d532a234..3c311c05 100644 --- a/src/c/profile/transport/serial/serial_transport_linux.c +++ b/src/c/profile/transport/serial/serial_transport_posix.c @@ -1,5 +1,5 @@ -#include -#include "serial_transport_internal.h" +#include +#include #include #include diff --git a/src/c/profile/transport/serial/serial_transport_windows.c b/src/c/profile/transport/serial/serial_transport_windows.c index 78d932d9..d16843e6 100644 --- a/src/c/profile/transport/serial/serial_transport_windows.c +++ b/src/c/profile/transport/serial/serial_transport_windows.c @@ -1,2 +1,2 @@ #include -#include "serial_transport_internal.h" +#include diff --git a/src/c/profile/transport/tcp/tcp_transport_internal.h b/src/c/profile/transport/tcp/tcp_transport_internal.h deleted file mode 100644 index 6399c33a..00000000 --- a/src/c/profile/transport/tcp/tcp_transport_internal.h +++ /dev/null @@ -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 - -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_ diff --git a/src/c/profile/transport/tcp/tcp_transport_linux.c b/src/c/profile/transport/tcp/tcp_transport_linux.c deleted file mode 100644 index 1aea8137..00000000 --- a/src/c/profile/transport/tcp/tcp_transport_linux.c +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include "tcp_transport_internal.h" - -#include -#include -#include -#include -#include - -#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; -} diff --git a/src/c/profile/transport/udp/udp_transport_internal.h b/src/c/profile/transport/udp/udp_transport_internal.h deleted file mode 100644 index ecfdf930..00000000 --- a/src/c/profile/transport/udp/udp_transport_internal.h +++ /dev/null @@ -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 - -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_ diff --git a/src/c/profile/transport/udp/udp_transport_linux.c b/src/c/profile/transport/udp/udp_transport_linux.c deleted file mode 100644 index 2193f6c3..00000000 --- a/src/c/profile/transport/udp/udp_transport_linux.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include "udp_transport_internal.h" - -#include -#include -#include -#include - -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; -} diff --git a/src/c/profile/transport/udp/udp_transport_windows.c b/src/c/profile/transport/udp/udp_transport_windows.c deleted file mode 100644 index 658336f4..00000000 --- a/src/c/profile/transport/udp/udp_transport_windows.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#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; -} diff --git a/test/case/CMakeLists.txt b/test/case/CMakeLists.txt index 0ce49839..bd714946 100644 --- a/test/case/CMakeLists.txt +++ b/test/case/CMakeLists.txt @@ -18,7 +18,8 @@ add_test( COMMAND ${CMAKE_COMMAND} -DINSTALL_PATH=${CMAKE_INSTALL_PREFIX} - -DLIBRARY_NAME=$ + -DLIBRARY_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}$,/../,> -DREQUIRED_VERSION=${PROJECT_VERSION} -DCMAKE_GENERATOR_TOOLSET=${CMAKE_GENERATOR_TOOLSET} -DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM} diff --git a/test/unitary/session/Session.cpp b/test/unitary/session/Session.cpp index 7cca079e..0706a8a8 100644 --- a/test/unitary/session/Session.cpp +++ b/test/unitary/session/Session.cpp @@ -3,7 +3,7 @@ extern "C" { -#include +#include #include #include @@ -223,9 +223,9 @@ class SessionTest : public testing::Test } 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); diff --git a/test/unitary/session/SessionInfo.cpp b/test/unitary/session/SessionInfo.cpp index b7051693..8d502ba5 100644 --- a/test/unitary/session/SessionInfo.cpp +++ b/test/unitary/session/SessionInfo.cpp @@ -2,7 +2,7 @@ extern "C" { -#include +#include #include #include #include diff --git a/test/unitary/session/streams/CommonReliableStream.cpp b/test/unitary/session/streams/CommonReliableStream.cpp index 6c21c73e..c2ca2427 100644 --- a/test/unitary/session/streams/CommonReliableStream.cpp +++ b/test/unitary/session/streams/CommonReliableStream.cpp @@ -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); } diff --git a/test/unitary/session/streams/InputReliableStream.cpp b/test/unitary/session/streams/InputReliableStream.cpp index 58c6bd06..e99772e4 100644 --- a/test/unitary/session/streams/InputReliableStream.cpp +++ b/test/unitary/session/streams/InputReliableStream.cpp @@ -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 @@ class InputReliableStreamTest : public testing::Test 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 @@ class InputReliableStreamTest : public testing::Test } }; - -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)); } diff --git a/test/unitary/session/streams/OutputReliableStream.cpp b/test/unitary/session/streams/OutputReliableStream.cpp index 460105e8..8abcbbfa 100644 --- a/test/unitary/session/streams/OutputReliableStream.cpp +++ b/test/unitary/session/streams/OutputReliableStream.cpp @@ -5,6 +5,8 @@ extern "C" { #include #include +#include +#include } #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 @@ class OutputReliableStreamTest : public testing::Test 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 @@ class OutputReliableStreamTest : public testing::Test 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 @@ class OutputReliableStreamTest : public testing::Test 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); } - diff --git a/test/unitary/session/streams/StreamStorage.cpp b/test/unitary/session/streams/StreamStorage.cpp index c9559285..de6026e0 100644 --- a/test/unitary/session/streams/StreamStorage.cpp +++ b/test/unitary/session/streams/StreamStorage.cpp @@ -35,12 +35,6 @@ class StreamStorageTest : public testing::Test uint8_t or_buffer[BUFFER_SIZE]; uint8_t ir_buffer[BUFFER_SIZE]; - static void on_new_fragment(struct ucdrBuffer* ub, struct uxrOutputReliableStream* stream) - { - (void) ub; - (void) stream; - } - static FragmentationInfo on_get_fragmentation_info(uint8_t* buffer) { (void) buffer; @@ -82,7 +76,7 @@ TEST_F(StreamStorageTest, Reset) (void) uxr_add_input_best_effort_buffer(&storage); (void) uxr_add_output_best_effort_buffer(&storage, ob_buffer, BUFFER_SIZE / HISTORY, OFFSET); (void) uxr_add_input_reliable_buffer(&storage, ir_buffer, BUFFER_SIZE, HISTORY, on_get_fragmentation_info); - (void) uxr_add_output_reliable_buffer(&storage, or_buffer, BUFFER_SIZE, HISTORY, OFFSET, on_new_fragment); + (void) uxr_add_output_reliable_buffer(&storage, or_buffer, BUFFER_SIZE, HISTORY, OFFSET); uxr_reset_stream_storage(&storage); @@ -128,7 +122,7 @@ TEST_F(StreamStorageTest, InputReliableInitialization) TEST_F(StreamStorageTest, OutputReliableInitialization) { output_reliable_initialized = false; - uxrStreamId id = uxr_add_output_reliable_buffer(&storage, or_buffer, BUFFER_SIZE, HISTORY, OFFSET, on_new_fragment); + uxrStreamId id = uxr_add_output_reliable_buffer(&storage, or_buffer, BUFFER_SIZE, HISTORY, OFFSET); EXPECT_TRUE(output_reliable_initialized); EXPECT_EQ(0, id.index); EXPECT_EQ(128, id.raw); @@ -141,7 +135,7 @@ TEST_F(StreamStorageTest, GetOk) (void) uxr_add_input_best_effort_buffer(&storage); (void) uxr_add_output_best_effort_buffer(&storage, ob_buffer, BUFFER_SIZE / HISTORY, OFFSET); (void) uxr_add_input_reliable_buffer(&storage, ir_buffer, BUFFER_SIZE, HISTORY, on_get_fragmentation_info); - (void) uxr_add_output_reliable_buffer(&storage, or_buffer, BUFFER_SIZE, HISTORY, OFFSET, on_new_fragment); + (void) uxr_add_output_reliable_buffer(&storage, or_buffer, BUFFER_SIZE, HISTORY, OFFSET); EXPECT_NE(nullptr, uxr_get_input_best_effort_stream(&storage, 0)); EXPECT_NE(nullptr, uxr_get_output_best_effort_stream(&storage, 0)); @@ -160,14 +154,14 @@ TEST_F(StreamStorageTest, GetNoOk) TEST_F(StreamStorageTest, OutputStreamConfirmed) { output_reliable_up_to_date = true; - (void) uxr_add_output_reliable_buffer(&storage, or_buffer, BUFFER_SIZE, HISTORY, OFFSET, on_new_fragment); + (void) uxr_add_output_reliable_buffer(&storage, or_buffer, BUFFER_SIZE, HISTORY, OFFSET); EXPECT_TRUE(uxr_output_streams_confirmed(&storage)); } TEST_F(StreamStorageTest, OutputStreamNoConfirmed) { output_reliable_up_to_date = false; - (void) uxr_add_output_reliable_buffer(&storage, or_buffer, BUFFER_SIZE, HISTORY, OFFSET, on_new_fragment); + (void) uxr_add_output_reliable_buffer(&storage, or_buffer, BUFFER_SIZE, HISTORY, OFFSET); EXPECT_FALSE(uxr_output_streams_confirmed(&storage)); } // ****************************************************************************Y @@ -215,9 +209,9 @@ void uxr_init_input_reliable_stream(uxrInputReliableStream* stream, uint8_t* buf StreamStorageTest::input_reliable_initialized = true; } -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) stream; (void) buffer; (void) size; (void) history; (void) header_offset; (void) on_new_fragment; + (void) stream; (void) buffer; (void) size; (void) history; (void) header_offset; StreamStorageTest::output_reliable_initialized = true; }