diff --git a/.github/workflows/build-check.yaml b/.github/workflows/build-check.yaml index 144431572..be3e52d7e 100644 --- a/.github/workflows/build-check.yaml +++ b/.github/workflows/build-check.yaml @@ -34,13 +34,15 @@ jobs: check_format: name: Check codebase format with clang-format - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout code uses: actions/checkout@v4 - name: Run clang-format dry-run - run: find include/ src/ tests/ examples/ -iname "*.ino" -o -iname "*.h" -o -iname "*.c" | xargs clang-format -n -Werror + run: | + clang-format --version + find include/ src/ tests/ examples/ -iname "*.ino" -o -iname "*.h" -o -iname "*.c" | xargs clang-format -n -Werror c99_build: name: Check c99 compilation diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 01fb354b2..e72186dbd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,6 +59,7 @@ jobs: - name: Bump and tag project run: bash ci/scripts/bump-and-tag.bash env: + LIVE_RUN: ${{ inputs.live-run || false }} VERSION: ${{ steps.create-release-branch.outputs.version }} GIT_USER_NAME: eclipse-zenoh-bot GIT_USER_EMAIL: eclipse-zenoh-bot@users.noreply.github.com @@ -150,6 +151,19 @@ jobs: name: ${{ steps.build-linux.outputs.archive-deb }} path: ${{ steps.build-linux.outputs.archive-deb }} + debian: + name: Publish Debian packages + needs: [tag, build-linux] + uses: eclipse-zenoh/ci/.github/workflows/release-crates-debian.yml@main + with: + no-build: true + live-run: ${{ inputs.live-run || false }} + version: ${{ needs.tag.outputs.version }} + repo: ${{ github.repository }} + branch: ${{ needs.tag.outputs.branch }} + installation-test: false + secrets: inherit + eclipse: needs: [tag, build-macos, build-linux] runs-on: ubuntu-latest @@ -160,8 +174,8 @@ jobs: version: ${{ needs.tag.outputs.version }} ssh-host: genie.zenoh@projects-storage.eclipse.org ssh-host-path: /home/data/httpd/download.eclipse.org/zenoh/zenoh-pico - ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - ssh-passphrase: ${{ secrets.SSH_PASSPHRASE }} + ssh-private-key: ${{ secrets.ORG_GPG_PRIVATE_KEY }} + ssh-passphrase: ${{ secrets.ORG_GPG_PASSPHRASE }} archive-patterns: '.*\.zip' github: diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f5d01971..9ef984042 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,17 +39,6 @@ configure_file( @ONLY ) -set(project_version "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") -if(NOT DEFINED PROJECT_VERSION_TWEAK) - set(project_version "${project_version}") -elseif(PROJECT_VERSION_TWEAK EQUAL 0) - set(project_version "${project_version}-dev") -elseif(PROJECT_VERSION_TWEAK GREATER 1) - set(project_version "${project_version}-pre.${PROJECT_VERSION_TWEAK}") -endif() -status_print(project_version) - - include(CMakePackageConfigHelpers) include(GNUInstallDirs) @@ -69,6 +58,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Windows") endif() elseif(CMAKE_SYSTEM_NAME MATCHES "Generic") if(WITH_ZEPHYR) + set(PACKAGING OFF) # no packaging support for zephyr set(BUILD_SHARED_LIBS "OFF") endif() endif() @@ -115,44 +105,83 @@ else() endif() endif() +if (PACKAGING) + set(PICO_STATIC ON) + set(PICO_SHARED ON) +endif() +if(BUILD_SHARED_LIBS) + set(PICO_SHARED ON) +else() + set(PICO_STATIC ON) +endif() + set(Libname "zenohpico") -add_library(${Libname}) -add_library(zenohpico::lib ALIAS ${Libname}) +if(PICO_STATIC) + add_library(${Libname}_static STATIC) + set_target_properties(${Libname}_static PROPERTIES OUTPUT_NAME ${Libname}) + add_library(zenohpico::static ALIAS ${Libname}_static) +endif() +if(PICO_SHARED) + add_library(${Libname}_shared SHARED) + set_target_properties(${Libname}_shared PROPERTIES OUTPUT_NAME ${Libname}) + add_library(zenohpico::shared ALIAS ${Libname}_shared) +endif() +if(BUILD_SHARED_LIBS) + add_library(zenohpico::lib ALIAS ${Libname}_shared) +else() + add_library(zenohpico::lib ALIAS ${Libname}_static) +endif() -function(add_definition value) +function(pico_add_compile_definition value) add_definitions(-D${value}) - target_compile_definitions(${Libname} PUBLIC ${value}) + if(PICO_STATIC) + target_compile_definitions(zenohpico_static PUBLIC ${value}) + endif() + if(PICO_SHARED) + target_compile_definitions(zenohpico_shared PUBLIC ${value}) + endif() endfunction() -add_definition(ZENOH_C_STANDARD=${CMAKE_C_STANDARD}) +function(pico_target_link_library value) + if(PICO_STATIC) + target_link_libraries(zenohpico_static ${value}) + endif() + if(PICO_SHARED) + target_link_libraries(zenohpico_shared ${value}) + endif() +endfunction() -# while in development, use timestamp for patch version: -string(TIMESTAMP PROJECT_VERSION_PATCH "%Y%m%ddev") -set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") +pico_add_compile_definition(ZENOH_C_STANDARD=${CMAKE_C_STANDARD}) + +if (NOT CMAKE_BUILD_TYPE MATCHES "RELEASE" OR "Release") + # while in development, use timestamp for patch version: + string(TIMESTAMP PROJECT_VERSION_PATCH "%Y%m%ddev") + set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") +endif() set(CHECK_THREADS "ON") # System definition if(CMAKE_SYSTEM_NAME MATCHES "Linux") - add_definition(ZENOH_LINUX) + pico_add_compile_definition(ZENOH_LINUX) elseif(POSIX_COMPATIBLE) - add_definition(ZENOH_LINUX) + pico_add_compile_definition(ZENOH_LINUX) set(CHECK_THREADS "OFF") elseif(CMAKE_SYSTEM_NAME MATCHES "BSD") - add_definition(ZENOH_BSD) + pico_add_compile_definition(ZENOH_BSD) elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin") - add_definition(ZENOH_MACOS) + pico_add_compile_definition(ZENOH_MACOS) set(MACOSX_RPATH "ON") elseif(CMAKE_SYSTEM_NAME MATCHES "Emscripten") - add_definition(ZENOH_EMSCRIPTEN) + pico_add_compile_definition(ZENOH_EMSCRIPTEN) elseif(CMAKE_SYSTEM_NAME MATCHES "Windows") - add_definition(ZENOH_WINDOWS) - add_definition(_CRT_SECURE_NO_WARNINGS) + pico_add_compile_definition(ZENOH_WINDOWS) + pico_add_compile_definition(_CRT_SECURE_NO_WARNINGS) elseif(CMAKE_SYSTEM_NAME MATCHES "Generic") if(WITH_ZEPHYR) - add_definition(ZENOH_ZEPHYR) + pico_add_compile_definition(ZENOH_ZEPHYR) elseif(WITH_FREERTOS_PLUS_TCP) - add_definition(ZENOH_FREERTOS_PLUS_TCP) + pico_add_compile_definition(ZENOH_FREERTOS_PLUS_TCP) endif() else() message(FATAL_ERROR "zenoh-pico is not yet available on ${CMAKE_SYSTEM_NAME} platform") @@ -162,18 +191,18 @@ endif() # Compiler definition message("Compilers in use: ${CMAKE_C_COMPILER_ID}, ${CMAKE_CXX_COMPILER_ID}") if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") - add_definition(ZENOH_COMPILER_CLANG) + pico_add_compile_definition(ZENOH_COMPILER_CLANG) elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "GNU") - add_definition(ZENOH_COMPILER_GCC) + pico_add_compile_definition(ZENOH_COMPILER_GCC) elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel" OR CMAKE_C_COMPILER_ID STREQUAL "Intel") - add_definition(ZENOH_COMPILER_INTEL) + pico_add_compile_definition(ZENOH_COMPILER_INTEL) elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_C_COMPILER_ID STREQUAL "MSVC") - add_definition(ZENOH_COMPILER_MSVC) + pico_add_compile_definition(ZENOH_COMPILER_MSVC) else() - add_definition(ZENOH_COMPILER_OTHER) + pico_add_compile_definition(ZENOH_COMPILER_OTHER) endif() -add_definition(ZENOH_DEBUG=${ZENOH_DEBUG}) +pico_add_compile_definition(ZENOH_DEBUG=${ZENOH_DEBUG}) # Zenoh pico feature configuration options @@ -187,6 +216,7 @@ set(Z_FEATURE_PUBLICATION 1 CACHE STRING "Toggle publication feature") set(Z_FEATURE_SUBSCRIPTION 1 CACHE STRING "Toggle subscription feature") set(Z_FEATURE_QUERY 1 CACHE STRING "Toggle query feature") set(Z_FEATURE_QUERYABLE 1 CACHE STRING "Toggle queryable feature") +set(Z_FEATURE_LIVELINESS 0 CACHE STRING "Toggle liveliness feature") set(Z_FEATURE_INTEREST 1 CACHE STRING "Toggle interests") set(Z_FEATURE_FRAGMENTATION 1 CACHE STRING "Toggle fragmentation") set(Z_FEATURE_ENCODING_VALUES 1 CACHE STRING "Toggle encoding values") @@ -205,6 +235,12 @@ set(Z_FEATURE_UNICAST_TRANSPORT 1 CACHE STRING "Toggle unicast transport") set(Z_FEATURE_RAWETH_TRANSPORT 0 CACHE STRING "Toggle raw ethernet transport") set(Z_FEATURE_TCP_NODELAY 1 CACHE STRING "Toggle TCP_NODELAY") +# Add a warning message if someone tries to enable Z_FEATURE_LIVELINESS directly +if(Z_FEATURE_LIVELINESS AND NOT Z_FEATURE_UNSTABLE_API) + message(WARNING "Z_FEATURE_LIVELINESS can only be enabled when Z_FEATURE_UNSTABLE_API is also enabled. Disabling Z_FEATURE_LIVELINESS.") + set(Z_FEATURE_LIVELINESS 0 CACHE STRING "Toggle liveliness feature" FORCE) +endif() + add_compile_definitions("Z_BUILD_DEBUG=$") message(STATUS "Building with feature confing:\n\ * UNSTABLE_API: ${Z_FEATURE_UNSTABLE_API}\n\ @@ -213,6 +249,7 @@ message(STATUS "Building with feature confing:\n\ * SUBSCRIPTION: ${Z_FEATURE_SUBSCRIPTION}\n\ * QUERY: ${Z_FEATURE_QUERY}\n\ * QUERYABLE: ${Z_FEATURE_QUERYABLE}\n\ +* LIVELINESS: ${Z_FEATURE_LIVELINESS}\n\ * INTEREST: ${Z_FEATURE_INTEREST}\n\ * RAWETH: ${Z_FEATURE_RAWETH_TRANSPORT}") @@ -266,10 +303,19 @@ file(GLOB_RECURSE PublicHeaders "include/zenoh-pico/utils/*.h" "include/zenoh-pico/config.h" ) -target_include_directories(${Libname} - PUBLIC - $ - $) +if(PICO_STATIC) + target_include_directories(${Libname}_static + PUBLIC + $ + $) +endif() +if(PICO_SHARED) + target_include_directories(${Libname}_shared + PUBLIC + $ + $) +endif() + file(GLOB_RECURSE Sources "src/api/*.c" @@ -303,18 +349,24 @@ endif() set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) link_directories(${LIBRARY_OUTPUT_PATH}) -target_sources(${Libname} PRIVATE ${Sources}) +if(PICO_STATIC) + target_sources(zenohpico_static PRIVATE ${Sources}) +endif() +if(PICO_SHARED) + target_sources(zenohpico_shared PRIVATE ${Sources}) +endif() if(CHECK_THREADS) - target_link_libraries(${Libname} Threads::Threads) + pico_target_link_library(Threads::Threads) endif() if(CMAKE_SYSTEM_NAME MATCHES "Linux") - target_link_libraries(${Libname} rt) + pico_target_link_library(rt) endif() if(CMAKE_SYSTEM_NAME MATCHES "Windows") - target_link_libraries(${Libname} Ws2_32 Iphlpapi) + pico_target_link_library(Ws2_32) + pico_target_link_library(Iphlpapi) endif() # @@ -334,12 +386,22 @@ message(STATUS "Build tools: ${BUILD_TOOLS}") message(STATUS "Build tests: ${BUILD_TESTING}") message(STATUS "Build integration: ${BUILD_INTEGRATION}") -install(TARGETS ${Libname} +set(PICO_LIBS "") +if(PICO_STATIC) + list(APPEND PICO_LIBS zenohpico_static) +endif() +if(PICO_SHARED) + list(APPEND PICO_LIBS zenohpico_shared) +endif() + +install(TARGETS ${PICO_LIBS} EXPORT zenohpicoTargets LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin - COMPONENT Library + LIBRARY COMPONENT Runtime + ARCHIVE COMPONENT Dev + RUNTIME COMPONENT Runtime ) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/zenoh-pico.h DESTINATION include @@ -373,17 +435,18 @@ install( "${CMAKE_CURRENT_BINARY_DIR}/zenohpicoConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_CMAKEDIR}" CONFIGURATIONS ${configurations} - COMPONENT dev) + COMPONENT Dev) # Generate Targets.cmake install( EXPORT zenohpicoTargets NAMESPACE zenohpico:: - DESTINATION "${CMAKE_INSTALL_CMAKEDIR}") + DESTINATION "${CMAKE_INSTALL_CMAKEDIR}" + COMPONENT Dev) if(UNIX) configure_file("${CMAKE_SOURCE_DIR}/zenohpico.pc.in" "${CMAKE_SOURCE_DIR}/zenohpico.pc" @ONLY) - install(FILES "${CMAKE_SOURCE_DIR}/zenohpico.pc" CONFIGURATIONS Release RelWithDebInfo DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + install(FILES "${CMAKE_SOURCE_DIR}/zenohpico.pc" CONFIGURATIONS Release RelWithDebInfo DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" COMPONENT Dev) endif() if(BUILD_EXAMPLES) @@ -394,7 +457,7 @@ if(UNIX OR MSVC) if(BUILD_TOOLS) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tools) add_executable(z_keyexpr_canonizer ${PROJECT_SOURCE_DIR}/tools/z_keyexpr_canonizer.c) - target_link_libraries(z_keyexpr_canonizer ${Libname}) + target_link_libraries(z_keyexpr_canonizer zenohpico::lib) endif() if(BUILD_TESTING AND CMAKE_C_STANDARD MATCHES "11") @@ -418,23 +481,23 @@ if(UNIX OR MSVC) add_executable(z_api_encoding_test ${PROJECT_SOURCE_DIR}/tests/z_api_encoding_test.c) add_executable(z_refcount_test ${PROJECT_SOURCE_DIR}/tests/z_refcount_test.c) - target_link_libraries(z_data_struct_test ${Libname}) - target_link_libraries(z_channels_test ${Libname}) - target_link_libraries(z_collections_test ${Libname}) - target_link_libraries(z_endpoint_test ${Libname}) - target_link_libraries(z_iobuf_test ${Libname}) - target_link_libraries(z_msgcodec_test ${Libname}) - target_link_libraries(z_keyexpr_test ${Libname}) - target_link_libraries(z_api_null_drop_test ${Libname}) - target_link_libraries(z_api_double_drop_test ${Libname}) - target_link_libraries(z_test_fragment_tx ${Libname}) - target_link_libraries(z_test_fragment_rx ${Libname}) - target_link_libraries(z_perf_tx ${Libname}) - target_link_libraries(z_perf_rx ${Libname}) - target_link_libraries(z_bytes_test ${Libname}) - target_link_libraries(z_api_bytes_test ${Libname}) - target_link_libraries(z_api_encoding_test ${Libname}) - target_link_libraries(z_refcount_test ${Libname}) + target_link_libraries(z_data_struct_test zenohpico::lib) + target_link_libraries(z_channels_test zenohpico::lib) + target_link_libraries(z_collections_test zenohpico::lib) + target_link_libraries(z_endpoint_test zenohpico::lib) + target_link_libraries(z_iobuf_test zenohpico::lib) + target_link_libraries(z_msgcodec_test zenohpico::lib) + target_link_libraries(z_keyexpr_test zenohpico::lib) + target_link_libraries(z_api_null_drop_test zenohpico::lib) + target_link_libraries(z_api_double_drop_test zenohpico::lib) + target_link_libraries(z_test_fragment_tx zenohpico::lib) + target_link_libraries(z_test_fragment_rx zenohpico::lib) + target_link_libraries(z_perf_tx zenohpico::lib) + target_link_libraries(z_perf_rx zenohpico::lib) + target_link_libraries(z_bytes_test zenohpico::lib) + target_link_libraries(z_api_bytes_test zenohpico::lib) + target_link_libraries(z_api_encoding_test zenohpico::lib) + target_link_libraries(z_refcount_test zenohpico::lib) configure_file(${PROJECT_SOURCE_DIR}/tests/modularity.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/modularity.py COPYONLY) configure_file(${PROJECT_SOURCE_DIR}/tests/raweth.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/raweth.py COPYONLY) @@ -465,7 +528,7 @@ if(UNIX OR MSVC) if(CMAKE_C_STANDARD MATCHES "11") add_executable(z_peer_multicast_test ${PROJECT_SOURCE_DIR}/tests/z_peer_multicast_test.c) - target_link_libraries(z_peer_multicast_test ${Libname}) + target_link_libraries(z_peer_multicast_test zenohpico::lib) configure_file(${PROJECT_SOURCE_DIR}/tests/multicast.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/multicast.sh COPYONLY) @@ -481,10 +544,12 @@ if(UNIX OR MSVC) add_executable(z_client_test ${PROJECT_SOURCE_DIR}/tests/z_client_test.c) add_executable(z_api_alignment_test ${PROJECT_SOURCE_DIR}/tests/z_api_alignment_test.c) add_executable(z_session_test ${PROJECT_SOURCE_DIR}/tests/z_session_test.c) + add_executable(z_api_liveliness_test ${PROJECT_SOURCE_DIR}/tests/z_api_liveliness_test.c) - target_link_libraries(z_client_test ${Libname}) - target_link_libraries(z_api_alignment_test ${Libname}) - target_link_libraries(z_session_test ${Libname}) + target_link_libraries(z_client_test zenohpico::lib) + target_link_libraries(z_api_alignment_test zenohpico::lib) + target_link_libraries(z_session_test zenohpico::lib) + target_link_libraries(z_api_liveliness_test zenohpico::lib) configure_file(${PROJECT_SOURCE_DIR}/tests/routed.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/routed.sh COPYONLY) configure_file(${PROJECT_SOURCE_DIR}/tests/api.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/api.sh COPYONLY) @@ -493,43 +558,51 @@ if(UNIX OR MSVC) add_test(z_client_test bash ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/routed.sh z_client_test) add_test(z_api_alignment_test bash ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/api.sh z_api_alignment_test) add_test(z_session_test bash ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/api.sh z_session_test) + add_test(z_api_liveliness_test bash ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/api.sh z_api_liveliness_test) endif() endif() endif() # For packaging if(PACKAGING) + set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/packages") - set(CPACK_COMPONENTS_ALL Library Headers) - set(CPACK_COMPONENT_LIBRARY_GROUP "lib") + set(CPACK_COMPONENTS_ALL Runtime Headers Dev) + + set(CPACK_COMPONENT_RUNTIME_GROUP "lib") set(CPACK_COMPONENT_HEADERS_GROUP "dev") - set(CPACK_COMPONENT_HEADERS_DEPENDS Library) + set(CPACK_COMPONENT_DEV_GROUP "dev") + set(CPACK_COMPONENT_HEADERS_DEPENDS Runtime) + set(CPACK_COMPONENT_DEV_DEPENDS Runtime) set(CPACK_PACKAGE_CHECKSUM MD5) set(CPACK_PACKAGE_VENDOR "The Eclipse Foundation") - set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) - set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) - set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) - set(CPACK_COMPONENT_LIB_DESCRIPTION "The C client library for Eclipse zenoh targeting pico devices") - set(CPACK_COMPONENT_DEV_DESCRIPTION "${CPACK_COMPONENT_LIB_DESCRIPTION} - devel files") + if(NOT CPACK_PACKAGE_VERSION) + set(SEM_VER "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") + if(PROJECT_VERSION_TWEAK STREQUAL "") + set(CPACK_PACKAGE_VERSION ${SEM_VER}) + elseif(PROJECT_VERSION_TWEAK EQUAL 0) + set(CPACK_PACKAGE_VERSION "${SEM_VER}~dev-1") + elseif(PROJECT_VERSION_TWEAK GREATER 0) + set(CPACK_PACKAGE_VERSION "${SEM_VER}~pre.${PROJECT_VERSION_TWEAK}-1") + endif() + endif() + set(CPACK_COMPONENT_RUNTIME_DESCRIPTION "The C client library for Eclipse zenoh targeting pico devices") + set(CPACK_COMPONENT_HEADERS_DESCRIPTION "${CPACK_COMPONENT_LIB_DESCRIPTION} - headers") + set(CPACK_COMPONENT_DEV_DESCRIPTION "${CPACK_COMPONENT_LIB_DESCRIPTION} - config files") # Sources package set(CPACK_SOURCE_GENERATOR "TGZ") - set(CPACK_SOURCE_IGNORE_FILES "/.git/;/.github/;/build/;/crossbuilds/") - set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-src-${PROJECT_VERSION}") + set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-src-${project_version}") + + set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") if(PACKAGING MATCHES "DEB") if(NOT DEBARCH) - execute_process( - COMMAND dpkg --print-architecture - OUTPUT_VARIABLE DEBARCH - OUTPUT_STRIP_TRAILING_WHITESPACE - ) + set(DEBARCH ${CMAKE_SYSTEM_PROCESSOR}-${CMAKE_SYSTEM_NAME}) endif() - message(STATUS "Configure DEB packaging for Linux ${DEBARCH}") - if(CPACK_GENERATOR) set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB") else() @@ -541,9 +614,10 @@ if(PACKAGING) set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${DEBARCH}) set(CPACK_DEB_COMPONENT_INSTALL ON) set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) - set(CPACK_DEBIAN_LIB_PACKAGE_NAME ${PROJECT_NAME}) # avoid "-lib" suffix for "lib" package + set(CPACK_DEBIAN_LIB_PACKAGE_NAME "lib${CPACK_PACKAGE_NAME}") set(CPACK_DEBIAN_LIB_PACKAGE_DEPENDS "libc6 (>=2.12)") - set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS "${CPACK_DEBIAN_LIB_PACKAGE_NAME} (=${PROJECT_VERSION})") + set(CPACK_DEBIAN_DEV_PACKAGE_NAME "lib${CPACK_PACKAGE_NAME}-dev") + set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS "${CPACK_DEBIAN_LIB_PACKAGE_NAME} (=${CPACK_PACKAGE_VERSION})") endif() if(PACKAGING MATCHES "RPM") @@ -551,8 +625,6 @@ if(PACKAGING) set(RPMARCH ${CMAKE_SYSTEM_PROCESSOR}) endif() - message(STATUS "Configure RPM packaging for Linux ${RPMARCH}") - if(CPACK_GENERATOR) set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM") else() @@ -563,8 +635,8 @@ if(PACKAGING) set(CPACK_RPM_PACKAGE_ARCHITECTURE ${RPMARCH}) set(CPACK_RPM_COMPONENT_INSTALL ON) set(CPACK_RPM_FILE_NAME RPM-DEFAULT) - set(CPACK_RPM_LIB_PACKAGE_NAME ${PROJECT_NAME}) # avoid "-lib" suffix for "lib" package - set(CPACK_RPM_DEV_PACKAGE_REQUIRES "${CPACK_RPM_LIB_PACKAGE_NAME} = ${PROJECT_VERSION}") + set(CPACK_RPM_LIB_PACKAGE_NAME ${CPACK_PACKAGE_NAME}) # avoid "-lib" suffix for "lib" package + set(CPACK_RPM_DEV_PACKAGE_REQUIRES "${CPACK_RPM_LIB_PACKAGE_NAME} = ${CPACK_PACKAGE_VERSION}") endif() include(CPack) diff --git a/GNUmakefile b/GNUmakefile index fcbbbb4d8..0a254575c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -115,33 +115,33 @@ endif crossbuild: check-docker @echo "FROM dockcross/$(CROSSIMG)\nRUN apt-get update && apt-get -y install rpm" | docker build -t $(CROSSIMG_PREFIX)$(CROSSIMG) - docker run --rm -v $(ROOT_DIR):/workdir -w /workdir $(CROSSIMG_PREFIX)$(CROSSIMG) bash -c "\ - cmake $(CMAKE_OPT) -DPACKAGING=DEB,RPM -DDEBARCH=$(DEBARCH) -DRPMARCH=$(RPMARCH) -B$(CROSSBUILD_DIR)/$(CROSSIMG) && \ + cmake $(CMAKE_OPT) -DCPACK_PACKAGE_NAME=$(PACKAGE_NAME) -DPACKAGING=DEB,RPM -DDEBARCH=$(DEBARCH) -DRPMARCH=$(RPMARCH) -B$(CROSSBUILD_DIR)/$(CROSSIMG) && \ make VERBOSE=1 -C$(CROSSBUILD_DIR)/$(CROSSIMG) all package" docker rmi $(CROSSIMG_PREFIX)$(CROSSIMG) linux-armv5: - CROSSIMG=$@ DEBARCH=arm RPMARCH=arm make crossbuild + PACKAGE_NAME="zenohpico" CROSSIMG=$@ DEBARCH=arm RPMARCH=arm make crossbuild linux-armv6: - CROSSIMG=$@ DEBARCH=arm RPMARCH=arm make crossbuild + PACKAGE_NAME="zenohpico-armv6" CROSSIMG=$@ DEBARCH=arm RPMARCH=arm make crossbuild linux-armv7: - CROSSIMG=$@ DEBARCH=armhf RPMARCH=armhf make crossbuild + PACKAGE_NAME="zenohpico" CROSSIMG=$@ DEBARCH=armhf RPMARCH=armhf make crossbuild linux-armv7a: - CROSSIMG=$@ DEBARCH=armhf RPMARCH=armhf make crossbuild + PACKAGE_NAME="zenohpico-armv7a" CROSSIMG=$@ DEBARCH=armhf RPMARCH=armhf make crossbuild linux-arm64: - CROSSIMG=$@ DEBARCH=arm64 RPMARCH=aarch64 make crossbuild + PACKAGE_NAME="zenohpico" CROSSIMG=$@ DEBARCH=arm64 RPMARCH=aarch64 make crossbuild linux-mips: - CROSSIMG=$@ DEBARCH=mips RPMARCH=mips make crossbuild + PACKAGE_NAME="zenohpico" CROSSIMG=$@ DEBARCH=mips RPMARCH=mips make crossbuild linux-x86: - CROSSIMG=$@ DEBARCH=i386 RPMARCH=x86 make crossbuild + PACKAGE_NAME="zenohpico" CROSSIMG=$@ DEBARCH=i386 RPMARCH=x86 make crossbuild linux-x64: - CROSSIMG=$@ DEBARCH=amd64 RPMARCH=x86_64 make crossbuild + PACKAGE_NAME="zenohpico" CROSSIMG=$@ DEBARCH=amd64 RPMARCH=x86_64 make crossbuild clean: rm -fr $(BUILD_DIR) diff --git a/PackageConfig.cmake.in b/PackageConfig.cmake.in index 94e4777a4..55339d35e 100644 --- a/PackageConfig.cmake.in +++ b/PackageConfig.cmake.in @@ -15,4 +15,15 @@ endif() include("${CMAKE_CURRENT_LIST_DIR}/zenohpicoTargets.cmake") -add_library(zenohpico::lib ALIAS zenohpico::zenohpico) +if(@PICO_SHARED@) + add_library(zenohpico::shared ALIAS zenohpico::zenohpico_shared) +endif() +if(@PICO_STATIC@) + add_library(zenohpico::static ALIAS zenohpico::zenohpico_static) +endif() + +if(@BUILD_SHARED_LIBS@) + add_library(zenohpico::lib ALIAS zenohpico::zenohpico_shared) +else() + add_library(zenohpico::lib ALIAS zenohpico::zenohpico_static) +endif() diff --git a/README.md b/README.md index 452643087..fed957104 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ ![Build](https://github.com/eclipse-zenoh/zenoh-pico/workflows/build/badge.svg) -![Crossbuild](https://github.com/eclipse-zenoh/zenoh-pico/workflows/crossbuild/badge.svg) ![integration](https://github.com/eclipse-zenoh/zenoh-pico/workflows/integration/badge.svg) [![Documentation Status](https://readthedocs.org/projects/zenoh-pico/badge/?version=latest)](https://zenoh-pico.readthedocs.io/en/latest/?badge=latest) [![Discussion](https://img.shields.io/badge/discussion-on%20github-blue)](https://github.com/eclipse-zenoh/roadmap/discussions) @@ -12,14 +11,14 @@ # Eclipse Zenoh The Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. -Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. +Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest, and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks. Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. ------------------------------- # Zenoh-Pico: native C library for constrained devices -zenoh-pico is the [Eclipse zenoh](http://zenoh.io) implementation that targets constrained devices and offers a native C API. +zenoh-pico is the [Eclipse zenoh](http://zenoh.io) implementation that targets constrained devices, offering a native C API. It is fully compatible with its main [Rust Zenoh implementation](https://github.com/eclipse-zenoh/zenoh), providing a lightweight implementation of most functionalities. Currently, zenoh-pico provides support for the following (RT)OSs and protocols: @@ -42,11 +41,11 @@ Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.c ## 1. How to install it The Eclipse zenoh-pico library is available as **Debian**, **RPM**, and **tgz** packages in the [Eclipse zenoh-pico download area](https://download.eclipse.org/zenoh/zenoh-pico/). -Those packages are built using manylinux2010 x86-32 and x86-64 to be compatible with most of the Linux platforms. -There are 2 kind of packages: +Those packages are built using manylinux2010 x86-32 and x86-64 for compatibility with most Linux platforms. +There are two kind of packages: - **libzenohpico**: only contains the library file (.so) -- **libzenohpico-dev**: contains the zenoh-pico header files for development. Depends on *libzenohpico* package +- **libzenohpico-dev**: contains the zenoh-pico header files for development and depends on the *libzenohpico* package For other platforms - like RTOS for embedded systems / microcontrollers -, you will need to clone and build the sources. Check [below](#how-to-build-for-microcontrollers) for more details. diff --git a/ci/scripts/build-linux.bash b/ci/scripts/build-linux.bash index 3d3a33ca4..3ac09ccdc 100644 --- a/ci/scripts/build-linux.bash +++ b/ci/scripts/build-linux.bash @@ -9,13 +9,13 @@ readonly version=${VERSION:?input VERSION is required} # Build target readonly target=${TARGET:?input TARGET is required} -BUILD_TYPE=RELEASE make "$target" +BUILD_SHARED_LIBS=ON BUILD_TYPE=RELEASE make "$target" readonly out=$GITHUB_WORKSPACE readonly repo_name=${repo#*/} -readonly archive_lib=$out/$repo_name-$version-$target.zip -readonly archive_deb=$out/$repo_name-$version-$target-deb-pkgs.zip -readonly archive_rpm=$out/$repo_name-$version-$target-rpm-pkgs.zip +readonly archive_lib=$out/$repo_name-$version-$target-standalone.zip +readonly archive_deb=$out/$repo_name-$version-$target-debian.zip +readonly archive_rpm=$out/$repo_name-$version-$target-rpm.zip readonly archive_examples=$out/$repo_name-$version-$target-examples.zip cd crossbuilds/"$target" @@ -24,8 +24,8 @@ cd - zip -r "$archive_lib" include cd crossbuilds/"$target"/packages -zip "$archive_deb" ./*.deb -zip "$archive_rpm" ./*.rpm +zip -9 -j "$archive_deb" ./*.deb +zip -9 -j "$archive_rpm" ./*.rpm cd - cd crossbuilds/"$target"/examples diff --git a/ci/scripts/bump-and-tag.bash b/ci/scripts/bump-and-tag.bash index 58883d627..f54d8953e 100644 --- a/ci/scripts/bump-and-tag.bash +++ b/ci/scripts/bump-and-tag.bash @@ -2,6 +2,7 @@ set -xeo pipefail +readonly live_run=${LIVE_RUN:-false} # Release number readonly version=${VERSION:-input VERSION is required} # Git actor name @@ -18,7 +19,9 @@ export GIT_COMMITTER_EMAIL=$git_user_email printf '%s' "$version" > version.txt git commit version.txt -m "chore: Bump version to $version" -git tag --force "$version" -m "v$version" +if [[ ${live_run} ]]; then + git tag --force "$version" -m "v$version" +fi git log -10 git show-ref --tags git push --force origin diff --git a/docs/api.rst b/docs/api.rst index b2ff6cf4a..1a3893a0b 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -462,7 +462,16 @@ See details at :ref:`owned_types_concept` .. c:type:: z_owned_closure_sample_t .. c:type:: z_loaned_closure_sample_t .. c:type:: z_moved_closure_sample_t - + +.. c:type:: void (* z_closure_sample_callback_t)(z_loaned_sample_t * sample, void * arg); + + Function pointer type for handling samples. + Represents a callback function that is invoked when a sample is available for processing. + + Parameters: + - **sample** - Pointer to a :c:type:`z_loaned_sample_t` representing the sample to be processed. + - **arg** - A user-defined pointer to additional data that can be used during the processing of the sample. + Functions ^^^^^^^^^ .. autocfunction:: primitives.h::z_closure_sample @@ -486,7 +495,16 @@ See details at :ref:`owned_types_concept` .. c:type:: z_owned_closure_query_t .. c:type:: z_loaned_closure_query_t .. c:type:: z_moved_closure_query_t - + +.. c:type:: void (* z_closure_query_callback_t)(z_loaned_query_t * query, void * arg); + + Function pointer type for handling queries. + Represents a callback function that is invoked when a query is available for processing. + + Parameters: + - **query** - Pointer to a :c:type:`z_loaned_query_t` representing the query to be processed. + - **arg** - A user-defined pointer to additional data that can be used during the processing of the query. + Functions ^^^^^^^^^ .. autocfunction:: primitives.h::z_closure_query @@ -511,7 +529,16 @@ See details at :ref:`owned_types_concept` .. c:type:: z_owned_closure_reply_t .. c:type:: z_loaned_closure_reply_t .. c:type:: z_moved_closure_reply_t - + +.. c:type:: void (* z_closure_reply_callback_t)(z_loaned_reply_t * reply, void * arg); + + Function pointer type for handling replies. + Represents a callback function that is invoked when a reply is available for processing. + + Parameters: + - **reply** - Pointer to a :c:type:`z_loaned_reply_t` representing the reply to be processed. + - **arg** - A user-defined pointer to additional data that can be used during the processing of the reply. + Functions ^^^^^^^^^ .. autocfunction:: primitives.h::z_closure_reply @@ -536,6 +563,15 @@ See details at :ref:`owned_types_concept` .. c:type:: z_owned_closure_hello_t .. c:type:: z_loaned_closure_hello_t .. c:type:: z_moved_closure_hello_t + +.. c:type:: void (* z_closure_hello_callback_t)(z_loaned_hello_t * hello, void * arg); + + Function pointer type for handling scouting response. + Represents a callback function that is invoked when a hello is available for processing. + + Parameters: + - **hello** - Pointer to a :c:type:`z_loaned_hello_t` representing the hello to be processed. + - **arg** - A user-defined pointer to additional data that can be used during the processing of the hello. Functions ^^^^^^^^^ @@ -561,6 +597,15 @@ See details at :ref:`owned_types_concept` .. c:type:: z_owned_closure_zid_t .. c:type:: z_loaned_closure_zid_t .. c:type:: z_moved_closure_zid_t + +.. c:type:: void (* z_closure_zid_callback_t)(z_loaned_zid_t * zid, void * arg); + + Function pointer type for handling Zenoh ID routers response. + Represents a callback function that is invoked when a zid is available for processing. + + Parameters: + - **zid** - Pointer to a :c:type:`z_loaned_zid_t` representing the zid to be processed. + - **arg** - A user-defined pointer to additional data that can be used during the processing of the zid. Functions ^^^^^^^^^ @@ -1192,6 +1237,7 @@ Functions .. autocfunction:: serialization.h::ze_serializer_serialize_buf .. autocfunction:: serialization.h::ze_serializer_serialize_string .. autocfunction:: serialization.h::ze_serializer_serialize_str +.. autocfunction:: serialization.h::ze_serializer_serialize_substr .. autocfunction:: serialization.h::ze_serializer_serialize_sequence_length .. autocfunction:: serialization.h::ze_deserialize_int8 .. autocfunction:: serialization.h::ze_deserialize_int16 @@ -1222,6 +1268,33 @@ Functions .. autocfunction:: serialization.h::ze_serialize_buf .. autocfunction:: serialization.h::ze_serialize_string .. autocfunction:: serialization.h::ze_serialize_str +.. autocfunction:: serialization.h::ze_serialize_substr + + +Liveliness +======================== +Types +----- +.. autoctype:: liveliness.h::z_liveliness_token_options_t +.. autoctype:: liveliness.h::z_liveliness_subscriber_options_t +.. autoctype:: liveliness.h::z_liveliness_get_options_t + +Represents a Liveliness token entity. +See details at :ref:`owned_types_concept` + +.. c:type:: z_owned_liveliness_token_t +.. c:type:: z_loaned_liveliness_token_t +.. c:type:: z_moved_liveliness_token_t + + +Functions +--------- +.. autocfunction:: liveliness.h::z_liveliness_token_options_default +.. autocfunction:: liveliness.h::z_liveliness_declare_token +.. autocfunction:: liveliness.h::z_liveliness_undeclare_token +.. autocfunction:: liveliness.h::z_liveliness_subscriber_options_default +.. autocfunction:: liveliness.h::z_liveliness_declare_subscriber +.. autocfunction:: liveliness.h::z_liveliness_get Others @@ -1230,8 +1303,6 @@ Others Data Structures --------------- -.. autoctype:: types.h::z_zint_t - .. autoctype:: types.h::zp_task_read_options_t .. autoctype:: types.h::zp_task_lease_options_t .. autoctype:: types.h::zp_read_options_t @@ -1270,10 +1341,52 @@ Functions .. autocfunction:: primitives.h::zp_send_join_options_default .. autocfunction:: primitives.h::zp_send_join -.. TODO Logging -.. TODO ======= +Logging +======= + +.. warning:: This API has been marked as unstable: it works as advertised, but it may be changed in a future release. + +Zenoh-Pico provides a flexible logging system to assist with debugging and monitoring. +By default, logging is disabled in release builds, but it can be enabled and configured +based on the desired level of verbosity. + +Logging Levels +-------------- + +Zenoh-Pico supports three logging levels: + +- **Error**: Only error messages are logged. This is the least verbose level. +- **Info**: Logs informational messages and error messages. +- **Debug**: Logs debug messages, informational messages, and error messages. This is the most verbose level. + +Enabling Logging +---------------- + +To enable logging, you can adjust the logging level by defining the ``ZENOH_DEBUG`` macro at compile time. + +- Set ``ZENOH_DEBUG`` to ``1`` to enable error messages. +- Set ``ZENOH_DEBUG`` to ``2`` to enable informational messages. +- Set ``ZENOH_DEBUG`` to ``3`` to enable debug messages (includes info and error). + +Additionally, logging can be automatically enabled in **debug builds** by defining the ``Z_BUILD_DEBUG`` macro. +In release builds, logging is disabled unless ``ZENOH_DEBUG`` is explicitly set. + +Example of Enabling Logging +--------------------------- + +To enable **debug-level logging** in your build, you would add the following flags during compilation: + +.. code-block:: bash + + gcc -DZENOH_DEBUG=3 -o my_program my_program.c +This will enable the most verbose logging, printing debug, info, and error messages. +Disabling Logging +----------------- +To disable all logging, set ``ZENOH_DEBUG`` to ``0`` or ensure it is undefined in release builds: +.. code-block:: bash + gcc -DZENOH_DEBUG=0 -o my_program my_program.c diff --git a/docs/conf.py b/docs/conf.py index 9b980bcfb..e1ee877ba 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -36,7 +36,8 @@ "-DZ_FEATURE_SUBSCRIPTION=1", "-DZ_FEATURE_QUERY=1", "-DZ_FEATURE_QUERYABLE=1", - "-DZ_FEATURE_ENCODING_VALUES=1" + "-DZ_FEATURE_ENCODING_VALUES=1", + "-DZ_FEATURE_LIVELINESS=1", ] # -- Options for HTML output ------------------------------------------------- diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a3fc911cd..96309c42c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -14,7 +14,7 @@ endif() function(add_example name) add_executable(${name} ${ARGN}) set_property(TARGET ${name} PROPERTY C_STANDARD 11) - target_link_libraries(${name} zenohpico) + target_link_libraries(${name} zenohpico::lib) add_dependencies(examples ${name}) endfunction() @@ -41,10 +41,12 @@ if(UNIX) add_example(z_sub_channel unix/c11/z_sub_channel.c) add_example(z_sub_st unix/c11/z_sub_st.c) add_example(z_sub_attachment unix/c11/z_sub_attachment.c) + add_example(z_sub_liveliness unix/c11/z_sub_liveliness.c) add_example(z_pull unix/c11/z_pull.c) add_example(z_get unix/c11/z_get.c) add_example(z_get_channel unix/c11/z_get_channel.c) add_example(z_get_attachment unix/c11/z_get_attachment.c) + add_example(z_get_liveliness unix/c11/z_get_liveliness.c) add_example(z_queryable unix/c11/z_queryable.c) add_example(z_queryable_channel unix/c11/z_queryable_channel.c) add_example(z_queryable_attachment unix/c11/z_queryable_attachment.c) @@ -55,6 +57,7 @@ if(UNIX) add_example(z_pub_thr unix/c11/z_pub_thr.c) add_example(z_sub_thr unix/c11/z_sub_thr.c) add_example(z_bytes unix/c11/z_bytes.c) + add_example(z_liveliness unix/c11/z_liveliness.c) endif() elseif(MSVC) add_example(z_put windows/z_put.c) diff --git a/examples/espidf/z_get.c b/examples/espidf/z_get.c index 5142009b1..fcfb5f975 100644 --- a/examples/espidf/z_get.c +++ b/examples/espidf/z_get.c @@ -169,7 +169,7 @@ void app_main() { opts.payload = z_move(payload); } z_owned_closure_reply_t callback; - z_closure(&callback, reply_handler, reply_dropper); + z_closure(&callback, reply_handler, reply_dropper, NULL); z_view_keyexpr_t ke; z_view_keyexpr_from_str_unchecked(&ke, KEYEXPR); if (z_get(z_loan(s), z_loan(ke), "", z_move(callback), &opts) < 0) { diff --git a/examples/espidf/z_queryable.c b/examples/espidf/z_queryable.c index c95ca377e..0939bfac8 100644 --- a/examples/espidf/z_queryable.c +++ b/examples/espidf/z_queryable.c @@ -169,7 +169,7 @@ void app_main() { // Declare Zenoh queryable printf("Declaring Queryable on %s...", KEYEXPR); z_owned_closure_query_t callback; - z_closure(&callback, query_handler); + z_closure(&callback, query_handler, NULL, NULL); z_owned_queryable_t qable; z_view_keyexpr_t ke; z_view_keyexpr_from_str_unchecked(&ke, KEYEXPR); diff --git a/examples/espidf/z_sub.c b/examples/espidf/z_sub.c index 01bb61de2..d7ac968ae 100644 --- a/examples/espidf/z_sub.c +++ b/examples/espidf/z_sub.c @@ -151,7 +151,7 @@ void app_main() { printf("Declaring Subscriber on '%s'...", KEYEXPR); z_owned_closure_sample_t callback; - z_closure(&callback, data_handler); + z_closure(&callback, data_handler, NULL, NULL); z_owned_subscriber_t sub; z_view_keyexpr_t ke; z_view_keyexpr_from_str_unchecked(&ke, KEYEXPR); diff --git a/examples/freertos_plus_tcp/CMakeLists.txt b/examples/freertos_plus_tcp/CMakeLists.txt index 83f890f30..3a0d44b54 100644 --- a/examples/freertos_plus_tcp/CMakeLists.txt +++ b/examples/freertos_plus_tcp/CMakeLists.txt @@ -55,9 +55,9 @@ FetchContent_MakeAvailable(freertos_kernel freertos_plus_tcp) set(BUILD_SHARED_LIBS OFF) set(WITH_FREERTOS_PLUS_TCP ON) set(ZENOH_DEBUG 3) -configure_include_project(ZENOHPICO zenohpico zenohpico "../.." zenohpico "https://github.com/eclipse-zenoh/zenoh-pico" "") +configure_include_project(ZENOHPICO zenohpico zenohpico::lib "../.." zenohpico "https://github.com/eclipse-zenoh/zenoh-pico" "") -target_link_libraries(zenohpico +target_link_libraries(zenohpico_static freertos_kernel freertos_plus_tcp ) @@ -74,7 +74,7 @@ function(add_example name) main freertos_kernel freertos_plus_tcp - zenohpico + zenohpico::lib ) endfunction() diff --git a/examples/freertos_plus_tcp/z_get.c b/examples/freertos_plus_tcp/z_get.c index 96931fcab..7d76d8de3 100644 --- a/examples/freertos_plus_tcp/z_get.c +++ b/examples/freertos_plus_tcp/z_get.c @@ -93,7 +93,7 @@ void app_main(void) { opts.payload = z_move(payload); } z_owned_closure_reply_t callback; - z_closure(&callback, reply_handler, reply_dropper); + z_closure(&callback, reply_handler, reply_dropper, NULL); if (z_get(z_loan(s), z_loan(ke), "", z_move(callback), &opts) < 0) { printf("Unable to send query.\n"); return; diff --git a/examples/freertos_plus_tcp/z_queryable.c b/examples/freertos_plus_tcp/z_queryable.c index 34c1c2a94..a1f8634f8 100644 --- a/examples/freertos_plus_tcp/z_queryable.c +++ b/examples/freertos_plus_tcp/z_queryable.c @@ -85,7 +85,7 @@ void app_main(void) { printf("Creating Queryable on '%s'...\n", KEYEXPR); z_owned_closure_query_t callback; - z_closure(&callback, query_handler); + z_closure(&callback, query_handler, NULL, NULL); z_owned_queryable_t qable; if (z_declare_queryable(z_loan(s), &qable, z_loan(ke), z_move(callback), NULL) < 0) { printf("Unable to create queryable.\n"); diff --git a/examples/freertos_plus_tcp/z_sub.c b/examples/freertos_plus_tcp/z_sub.c index 45f7c4775..4febeecf7 100644 --- a/examples/freertos_plus_tcp/z_sub.c +++ b/examples/freertos_plus_tcp/z_sub.c @@ -62,7 +62,7 @@ void app_main(void) { } z_owned_closure_sample_t callback; - z_closure(&callback, data_handler); + z_closure(&callback, data_handler, NULL, NULL); printf("Declaring Subscriber on '%s'...\n", KEYEXPR); z_view_keyexpr_t ke; z_view_keyexpr_from_str_unchecked(&ke, KEYEXPR); diff --git a/examples/freertos_plus_tcp/z_sub_st.c b/examples/freertos_plus_tcp/z_sub_st.c index 805a0c949..34ae7b6f4 100644 --- a/examples/freertos_plus_tcp/z_sub_st.c +++ b/examples/freertos_plus_tcp/z_sub_st.c @@ -59,7 +59,7 @@ void app_main(void) { } z_owned_closure_sample_t callback; - z_closure(&callback, data_handler); + z_closure(&callback, data_handler, NULL, NULL); printf("Declaring Subscriber on '%s'...\n", KEYEXPR); z_view_keyexpr_t ke; z_view_keyexpr_from_str_unchecked(&ke, KEYEXPR); diff --git a/examples/unix/c11/z_get.c b/examples/unix/c11/z_get.c index 034ddb2d5..3bf67421f 100644 --- a/examples/unix/c11/z_get.c +++ b/examples/unix/c11/z_get.c @@ -135,7 +135,7 @@ int main(int argc, char **argv) { } z_owned_closure_reply_t callback; - z_closure(&callback, reply_handler, reply_dropper); + z_closure(&callback, reply_handler, reply_dropper, NULL); if (z_get(z_loan(s), z_loan(ke), "", z_move(callback), &opts) < 0) { printf("Unable to send query.\n"); return -1; diff --git a/examples/unix/c11/z_get_attachment.c b/examples/unix/c11/z_get_attachment.c index 842273fc2..f3b18037d 100644 --- a/examples/unix/c11/z_get_attachment.c +++ b/examples/unix/c11/z_get_attachment.c @@ -193,7 +193,7 @@ int main(int argc, char **argv) { opts.encoding = z_move(encoding); z_owned_closure_reply_t callback; - z_closure(&callback, reply_handler, reply_dropper); + z_closure(&callback, reply_handler, reply_dropper, NULL); if (z_get(z_loan(s), z_loan(ke), "", z_move(callback), &opts) < 0) { printf("Unable to send query.\n"); return -1; diff --git a/examples/unix/c11/z_get_liveliness.c b/examples/unix/c11/z_get_liveliness.c new file mode 100644 index 000000000..cefa20175 --- /dev/null +++ b/examples/unix/c11/z_get_liveliness.c @@ -0,0 +1,116 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, + +#include +#include +#include +#include + +#if Z_FEATURE_LIVELINESS == 1 && Z_FEATURE_QUERY == 1 + +int main(int argc, char **argv) { + const char *keyexpr = "group1/**"; + const char *mode = "client"; + const char *clocator = NULL; + const char *llocator = NULL; + + int opt; + while ((opt = getopt(argc, argv, "k:e:m:l:")) != -1) { + switch (opt) { + case 'k': + keyexpr = optarg; + break; + case 'e': + clocator = optarg; + break; + case 'm': + mode = optarg; + break; + case 'l': + llocator = optarg; + break; + case '?': + if (optopt == 'k' || optopt == 'e' || optopt == 'm' || optopt == 'v' || optopt == 'l') { + fprintf(stderr, "Option -%c requires an argument.\n", optopt); + } else { + fprintf(stderr, "Unknown option `-%c'.\n", optopt); + } + return 1; + default: + return -1; + } + } + + z_owned_config_t config; + z_config_default(&config); + zp_config_insert(z_loan_mut(config), Z_CONFIG_MODE_KEY, mode); + if (clocator != NULL) { + zp_config_insert(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, clocator); + } + if (llocator != NULL) { + zp_config_insert(z_loan_mut(config), Z_CONFIG_LISTEN_KEY, llocator); + } + + printf("Opening session...\n"); + z_owned_session_t s; + if (z_open(&s, z_move(config), NULL) < 0) { + printf("Unable to open session!\n"); + return -1; + } + + // Start read and lease tasks for zenoh-pico + if (zp_start_read_task(z_loan_mut(s), NULL) < 0 || zp_start_lease_task(z_loan_mut(s), NULL) < 0) { + printf("Unable to start read and lease tasks\n"); + z_session_drop(z_session_move(&s)); + return -1; + } + + z_view_keyexpr_t ke; + if (z_view_keyexpr_from_str(&ke, keyexpr) < 0) { + printf("%s is not a valid key expression", keyexpr); + return -1; + } + + printf("Sending liveliness query '%s'...\n", keyexpr); + z_owned_fifo_handler_reply_t handler; + z_owned_closure_reply_t closure; + z_fifo_channel_reply_new(&closure, &handler, 16); + if (z_liveliness_get(z_loan(s), z_loan(ke), z_move(closure), NULL) < 0) { + printf("Liveliness query failed"); + return -1; + } + z_owned_reply_t reply; + for (z_result_t res = z_recv(z_loan(handler), &reply); res == Z_OK; res = z_recv(z_loan(handler), &reply)) { + if (z_reply_is_ok(z_loan(reply))) { + const z_loaned_sample_t *sample = z_reply_ok(z_loan(reply)); + z_view_string_t key_str; + z_keyexpr_as_view_string(z_sample_keyexpr(sample), &key_str); + printf(">> Alive token ('%.*s')\n", (int)z_string_len(z_loan(key_str)), z_string_data(z_loan(key_str))); + } else { + printf("Received an error\n"); + } + } + + z_drop(z_move(reply)); + z_drop(z_move(handler)); + z_drop(z_move(s)); + return 0; +} +#else +int main(void) { + printf( + "ERROR: Zenoh pico was compiled without Z_FEATURE_QUERY or Z_FEATURE_LIVELINESS but this example requires " + "them.\n"); + return -2; +} +#endif diff --git a/examples/unix/c11/z_info.c b/examples/unix/c11/z_info.c index 94df7db68..fe4b61beb 100644 --- a/examples/unix/c11/z_info.c +++ b/examples/unix/c11/z_info.c @@ -86,14 +86,14 @@ int main(int argc, char **argv) { printf("Routers IDs:\n"); z_owned_closure_zid_t callback; - z_closure(&callback, print_zid); + z_closure(&callback, print_zid, NULL, NULL); z_info_routers_zid(z_loan(s), z_move(callback)); // `callback` has been `z_move`d just above, so it's safe to reuse the variable, // we'll just have to make sure we `z_move` it again to avoid mem-leaks. printf("Peers IDs:\n"); z_owned_closure_zid_t callback2; - z_closure(&callback2, print_zid); + z_closure(&callback2, print_zid, NULL, NULL); z_info_peers_zid(z_loan(s), z_move(callback2)); z_drop(z_move(s)); diff --git a/examples/unix/c11/z_liveliness.c b/examples/unix/c11/z_liveliness.c new file mode 100644 index 000000000..0798621fe --- /dev/null +++ b/examples/unix/c11/z_liveliness.c @@ -0,0 +1,121 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, + +#include +#include +#include +#include +#include +#include + +#if Z_FEATURE_LIVELINESS == 1 + +static volatile int keepRunning = 1; + +void intHandler(int dummy) { + (void)dummy; + keepRunning = 0; +} + +int main(int argc, char **argv) { + const char *keyexpr = "group1/zenoh-pico"; + const char *mode = "client"; + const char *clocator = NULL; + const char *llocator = NULL; + + int opt; + while ((opt = getopt(argc, argv, "k:e:m:l:")) != -1) { + switch (opt) { + case 'k': + keyexpr = optarg; + break; + case 'e': + clocator = optarg; + break; + case 'm': + mode = optarg; + break; + case 'l': + llocator = optarg; + break; + case '?': + if (optopt == 'k' || optopt == 'e' || optopt == 'm' || optopt == 'v' || optopt == 'l') { + fprintf(stderr, "Option -%c requires an argument.\n", optopt); + } else { + fprintf(stderr, "Unknown option `-%c'.\n", optopt); + } + return 1; + default: + return -1; + } + } + + z_owned_config_t config; + z_config_default(&config); + zp_config_insert(z_loan_mut(config), Z_CONFIG_MODE_KEY, mode); + if (clocator != NULL) { + zp_config_insert(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, clocator); + } + if (llocator != NULL) { + zp_config_insert(z_loan_mut(config), Z_CONFIG_LISTEN_KEY, llocator); + } + + printf("Opening session...\n"); + z_owned_session_t s; + if (z_open(&s, z_move(config), NULL) < 0) { + printf("Unable to open session!\n"); + return -1; + } + + // Start read and lease tasks for zenoh-pico + if (zp_start_read_task(z_loan_mut(s), NULL) < 0 || zp_start_lease_task(z_loan_mut(s), NULL) < 0) { + printf("Unable to start read and lease tasks\n"); + z_session_drop(z_session_move(&s)); + return -1; + } + + z_view_keyexpr_t ke; + if (z_view_keyexpr_from_str(&ke, keyexpr) < 0) { + printf("%s is not a valid key expression", keyexpr); + return -1; + } + + printf("Declaring liveliness token '%s'...\n", keyexpr); + z_owned_liveliness_token_t token; + if (z_liveliness_declare_token(z_loan(s), &token, z_loan(ke), NULL) < 0) { + printf("Unable to create liveliness token!\n"); + exit(-1); + } + + printf("Press CTRL-C to undeclare liveliness token and quit...\n"); + signal(SIGINT, intHandler); + while (keepRunning) { + z_sleep_s(1); + } + + // LivelinessTokens are automatically closed when dropped + // Use the code below to manually undeclare it if needed + printf("Undeclaring liveliness token...\n"); + z_drop(z_move(token)); + + z_drop(z_move(s)); + return 0; +} +#else +int main(void) { + printf( + "ERROR: Zenoh pico was compiled without Z_FEATURE_QUERY or Z_FEATURE_MULTI_THREAD but this example requires " + "them.\n"); + return -2; +} +#endif diff --git a/examples/unix/c11/z_queryable.c b/examples/unix/c11/z_queryable.c index 13ced6dfc..6ec72f517 100644 --- a/examples/unix/c11/z_queryable.c +++ b/examples/unix/c11/z_queryable.c @@ -146,7 +146,7 @@ int main(int argc, char **argv) { printf("Creating Queryable on '%s'...\n", keyexpr); z_owned_closure_query_t callback; - z_closure(&callback, query_handler); + z_closure(&callback, query_handler, NULL, NULL); z_owned_queryable_t qable; if (z_declare_queryable(z_loan(s), &qable, z_loan(ke), z_move(callback), NULL) < 0) { printf("Unable to create queryable.\n"); diff --git a/examples/unix/c11/z_queryable_attachment.c b/examples/unix/c11/z_queryable_attachment.c index 20a2e9ad2..f915d7767 100644 --- a/examples/unix/c11/z_queryable_attachment.c +++ b/examples/unix/c11/z_queryable_attachment.c @@ -186,7 +186,7 @@ int main(int argc, char **argv) { printf("Creating Queryable on '%s'...\n", keyexpr); z_owned_closure_query_t callback; - z_closure(&callback, query_handler); + z_closure(&callback, query_handler, NULL, NULL); z_owned_queryable_t qable; if (z_declare_queryable(z_loan(s), &qable, z_loan(ke), z_move(callback), NULL) < 0) { printf("Unable to create queryable.\n"); diff --git a/examples/unix/c11/z_sub.c b/examples/unix/c11/z_sub.c index 1c9df33b1..0d8b73e39 100644 --- a/examples/unix/c11/z_sub.c +++ b/examples/unix/c11/z_sub.c @@ -98,7 +98,7 @@ int main(int argc, char **argv) { } z_owned_closure_sample_t callback; - z_closure(&callback, data_handler); + z_closure(&callback, data_handler, NULL, NULL); printf("Declaring Subscriber on '%s'...\n", keyexpr); z_owned_subscriber_t sub; z_view_keyexpr_t ke; diff --git a/examples/unix/c11/z_sub_attachment.c b/examples/unix/c11/z_sub_attachment.c index 5720f86fd..73a320d4e 100644 --- a/examples/unix/c11/z_sub_attachment.c +++ b/examples/unix/c11/z_sub_attachment.c @@ -149,7 +149,7 @@ int main(int argc, char **argv) { } z_owned_closure_sample_t callback; - z_closure(&callback, data_handler); + z_closure(&callback, data_handler, NULL, NULL); printf("Declaring Subscriber on '%s'...\n", keyexpr); z_owned_subscriber_t sub; z_view_keyexpr_t ke; diff --git a/examples/unix/c11/z_sub_liveliness.c b/examples/unix/c11/z_sub_liveliness.c new file mode 100644 index 000000000..a302d10a3 --- /dev/null +++ b/examples/unix/c11/z_sub_liveliness.c @@ -0,0 +1,134 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +#include +#include +#include +#include +#include +#include + +#if Z_FEATURE_SUBSCRIPTION == 1 && Z_FEATURE_LIVELINESS == 1 + +void data_handler(z_loaned_sample_t *sample, void *ctx) { + (void)(ctx); + z_view_string_t key_string; + z_keyexpr_as_view_string(z_sample_keyexpr(sample), &key_string); + switch (z_sample_kind(sample)) { + case Z_SAMPLE_KIND_PUT: + printf(">> [LivelinessSubscriber] New alive token ('%.*s')\n", (int)z_string_len(z_loan(key_string)), + z_string_data(z_loan(key_string))); + break; + case Z_SAMPLE_KIND_DELETE: + printf(">> [LivelinessSubscriber] Dropped token ('%.*s')\n", (int)z_string_len(z_loan(key_string)), + z_string_data(z_loan(key_string))); + break; + } +} + +int main(int argc, char **argv) { + const char *keyexpr = "group1/**"; + const char *mode = "client"; + char *clocator = NULL; + char *llocator = NULL; + bool history = false; + + int opt; + while ((opt = getopt(argc, argv, "k:e:m:l:n:h")) != -1) { + switch (opt) { + case 'k': + keyexpr = optarg; + break; + case 'e': + clocator = optarg; + break; + case 'm': + mode = optarg; + break; + case 'l': + llocator = optarg; + break; + case 'h': + history = true; + break; + case '?': + if (optopt == 'k' || optopt == 'e' || optopt == 'm' || optopt == 'l') { + fprintf(stderr, "Option -%c requires an argument.\n", optopt); + } else { + fprintf(stderr, "Unknown option `-%c'.\n", optopt); + } + return 1; + default: + return -1; + } + } + + z_owned_config_t config; + z_config_default(&config); + zp_config_insert(z_loan_mut(config), Z_CONFIG_MODE_KEY, mode); + if (clocator != NULL) { + zp_config_insert(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, clocator); + } + if (llocator != NULL) { + zp_config_insert(z_loan_mut(config), Z_CONFIG_LISTEN_KEY, llocator); + } + + printf("Opening session...\n"); + z_owned_session_t s; + if (z_open(&s, z_move(config), NULL) < 0) { + printf("Unable to open session!\n"); + return -1; + } + + // Start read and lease tasks for zenoh-pico + if (zp_start_read_task(z_loan_mut(s), NULL) < 0 || zp_start_lease_task(z_loan_mut(s), NULL) < 0) { + printf("Unable to start read and lease tasks\n"); + z_session_drop(z_session_move(&s)); + return -1; + } + + printf("Declaring liveliness subscriber on '%s'...\n", keyexpr); + z_owned_closure_sample_t callback; + z_closure(&callback, data_handler, NULL, NULL); + z_owned_subscriber_t sub; + + z_liveliness_subscriber_options_t sub_opt; + z_liveliness_subscriber_options_default(&sub_opt); + sub_opt.history = history; + + z_view_keyexpr_t ke; + z_view_keyexpr_from_str(&ke, keyexpr); + if (z_liveliness_declare_subscriber(z_loan(s), &sub, z_loan(ke), z_move(callback), &sub_opt) < 0) { + printf("Unable to declare liveliness subscriber.\n"); + exit(-1); + } + + printf("Press CTRL-C to quit...\n"); + while (1) { + z_sleep_s(1); + } + + // Clean up + z_drop(z_move(sub)); + z_drop(z_move(s)); + return 0; +} +#else +int main(void) { + printf( + "ERROR: Zenoh pico was compiled without Z_FEATURE_SUBSCRIPTION and Z_FEATURE_LIVELINESS but this example " + "requires it.\n"); + return -2; +} +#endif diff --git a/examples/unix/c11/z_sub_st.c b/examples/unix/c11/z_sub_st.c index 083d9465d..edc3b4e5e 100644 --- a/examples/unix/c11/z_sub_st.c +++ b/examples/unix/c11/z_sub_st.c @@ -90,7 +90,7 @@ int main(int argc, char **argv) { } z_owned_closure_sample_t callback; - z_closure(&callback, data_handler); + z_closure(&callback, data_handler, NULL, NULL); printf("Declaring Subscriber on '%s'...\n", keyexpr); z_owned_subscriber_t sub; z_view_keyexpr_t ke; diff --git a/examples/windows/z_get.c b/examples/windows/z_get.c index 3c5a3f338..dc4cfc862 100644 --- a/examples/windows/z_get.c +++ b/examples/windows/z_get.c @@ -92,7 +92,7 @@ int main(int argc, char **argv) { opts.payload = z_move(payload); } z_owned_closure_reply_t callback; - z_closure(&callback, reply_handler, reply_dropper); + z_closure(&callback, reply_handler, reply_dropper, NULL); if (z_get(z_loan(s), z_loan(ke), "", z_move(callback), &opts) < 0) { printf("Unable to send query.\n"); return -1; diff --git a/examples/windows/z_info.c b/examples/windows/z_info.c index 96f8dcc62..62a459156 100644 --- a/examples/windows/z_info.c +++ b/examples/windows/z_info.c @@ -59,14 +59,14 @@ int main(int argc, char **argv) { printf("Routers IDs:\n"); z_owned_closure_zid_t callback; - z_closure(&callback, print_zid); + z_closure(&callback, print_zid, NULL, NULL); z_info_routers_zid(z_loan(s), z_move(callback)); // `callback` has been `z_move`d just above, so it's safe to reuse the variable, // we'll just have to make sure we `z_move` it again to avoid mem-leaks. printf("Peers IDs:\n"); z_owned_closure_zid_t callback2; - z_closure(&callback2, print_zid); + z_closure(&callback2, print_zid, NULL, NULL); z_info_peers_zid(z_loan(s), z_move(callback2)); z_drop(z_move(s)); diff --git a/examples/windows/z_queryable.c b/examples/windows/z_queryable.c index 11a01d92e..4a1c2e469 100644 --- a/examples/windows/z_queryable.c +++ b/examples/windows/z_queryable.c @@ -79,7 +79,7 @@ int main(int argc, char **argv) { printf("Creating Queryable on '%s'...\n", keyexpr); z_owned_closure_query_t callback; - z_closure(&callback, query_handler); + z_closure(&callback, query_handler, NULL, NULL); z_owned_queryable_t qable; if (z_declare_queryable(z_loan(s), &qable, z_loan(ke), z_move(callback), NULL) < 0) { printf("Unable to create queryable.\n"); diff --git a/examples/windows/z_sub.c b/examples/windows/z_sub.c index 166775ea1..8df2bb696 100644 --- a/examples/windows/z_sub.c +++ b/examples/windows/z_sub.c @@ -59,7 +59,7 @@ int main(int argc, char **argv) { } z_owned_closure_sample_t callback; - z_closure(&callback, data_handler); + z_closure(&callback, data_handler, NULL, NULL); printf("Declaring Subscriber on '%s'...\n", keyexpr); z_owned_subscriber_t sub; z_view_keyexpr_t ke; diff --git a/examples/windows/z_sub_st.c b/examples/windows/z_sub_st.c index 16507ef28..b1d2a6634 100644 --- a/examples/windows/z_sub_st.c +++ b/examples/windows/z_sub_st.c @@ -56,7 +56,7 @@ int main(int argc, char **argv) { } z_owned_closure_sample_t callback; - z_closure(&callback, data_handler); + z_closure(&callback, data_handler, NULL, NULL); printf("Declaring Subscriber on '%s'...\n", keyexpr); z_owned_subscriber_t sub; z_view_keyexpr_t ke; diff --git a/examples/zephyr/z_get.c b/examples/zephyr/z_get.c index 8d22aa0c7..c56049899 100644 --- a/examples/zephyr/z_get.c +++ b/examples/zephyr/z_get.c @@ -66,7 +66,7 @@ int main(int argc, char **argv) { z_owned_session_t s; if (z_open(&s, z_move(config), NULL) < 0) { printf("Unable to open session!\n"); - exit(-1); + return -1; } printf("OK\n"); @@ -87,12 +87,12 @@ int main(int argc, char **argv) { opts.payload = z_move(payload); } z_owned_closure_reply_t callback; - z_closure(&callback, reply_handler, reply_dropper); + z_closure(&callback, reply_handler, reply_dropper, NULL); z_view_keyexpr_t ke; z_view_keyexpr_from_str_unchecked(&ke, KEYEXPR); if (z_get(z_loan(s), z_loan(ke), "", z_move(callback), &opts) < 0) { printf("Unable to send query.\n"); - exit(-1); + return -1; } } diff --git a/examples/zephyr/z_pub.c b/examples/zephyr/z_pub.c index ce91c4d38..4f9f063b7 100644 --- a/examples/zephyr/z_pub.c +++ b/examples/zephyr/z_pub.c @@ -48,7 +48,7 @@ int main(int argc, char **argv) { z_owned_session_t s; if (z_open(&s, z_move(config), NULL) < 0) { printf("Unable to open session!\n"); - exit(-1); + return -1; } printf("OK\n"); @@ -62,7 +62,7 @@ int main(int argc, char **argv) { z_owned_publisher_t pub; if (z_declare_publisher(z_loan(s), &pub, z_loan(ke), NULL) < 0) { printf("Unable to declare publisher for key expression!\n"); - exit(-1); + return -1; } printf("OK\n"); diff --git a/examples/zephyr/z_pull.c b/examples/zephyr/z_pull.c index 06562eed6..e3be5f345 100644 --- a/examples/zephyr/z_pull.c +++ b/examples/zephyr/z_pull.c @@ -48,7 +48,7 @@ int main(int argc, char **argv) { z_owned_session_t s; if (z_open(&s, z_move(config), NULL) < 0) { printf("Unable to open session!\n"); - exit(-1); + return -1; } printf("OK\n"); @@ -56,7 +56,7 @@ int main(int argc, char **argv) { if (zp_start_read_task(z_loan_mut(s), NULL) < 0 || zp_start_lease_task(z_loan_mut(s), NULL) < 0) { printf("Unable to start read and lease tasks\n"); z_session_drop(z_session_move(&s)); - exit(-1); + return -1; } printf("Declaring Subscriber on '%s'...\n", KEYEXPR); @@ -68,7 +68,7 @@ int main(int argc, char **argv) { z_view_keyexpr_from_str(&ke, KEYEXPR); if (z_declare_subscriber(z_loan(s), &sub, z_loan(ke), z_move(closure), NULL) < 0) { printf("Unable to declare subscriber.\n"); - exit(-1); + return -1; } printf("Pulling data every %zu ms... Ring size: %zd\n", INTERVAL, SIZE); diff --git a/examples/zephyr/z_queryable.c b/examples/zephyr/z_queryable.c index 0d34c4c03..1eafda347 100644 --- a/examples/zephyr/z_queryable.c +++ b/examples/zephyr/z_queryable.c @@ -71,7 +71,7 @@ int main(int argc, char **argv) { z_owned_session_t s; if (z_open(&s, z_move(config), NULL) < 0) { printf("Unable to open session!\n"); - exit(-1); + return -1; } printf("OK\n"); @@ -82,13 +82,13 @@ int main(int argc, char **argv) { // Declare Zenoh queryable printf("Declaring Queryable on %s...", KEYEXPR); z_owned_closure_query_t callback; - z_closure(&callback, query_handler); + z_closure(&callback, query_handler, NULL, NULL); z_owned_queryable_t qable; z_view_keyexpr_t ke; z_view_keyexpr_from_str_unchecked(&ke, KEYEXPR); if (z_declare_queryable(z_loan(s), &qable, z_loan(ke), z_move(callback), NULL) < 0) { printf("Unable to declare queryable.\n"); - exit(-1); + return -1; } printf("OK\n"); printf("Zenoh setup finished!\n"); diff --git a/examples/zephyr/z_sub.c b/examples/zephyr/z_sub.c index 68c0f46e1..c49668b3c 100644 --- a/examples/zephyr/z_sub.c +++ b/examples/zephyr/z_sub.c @@ -55,7 +55,7 @@ int main(int argc, char **argv) { z_owned_session_t s; if (z_open(&s, z_move(config), NULL) < 0) { printf("Unable to open session!\n"); - exit(-1); + return -1; } printf("OK\n"); @@ -65,13 +65,13 @@ int main(int argc, char **argv) { printf("Declaring Subscriber on '%s'...", KEYEXPR); z_owned_closure_sample_t callback; - z_closure(&callback, data_handler); + z_closure(&callback, data_handler, NULL, NULL); z_view_keyexpr_t ke; z_view_keyexpr_from_str_unchecked(&ke, KEYEXPR); z_owned_subscriber_t sub; if (z_declare_subscriber(z_loan(s), &sub, z_loan(ke), z_move(callback), NULL) < 0) { printf("Unable to declare subscriber.\n"); - exit(-1); + return -1; } printf("OK!\n"); diff --git a/include/zenoh-pico.h b/include/zenoh-pico.h index b34291ca4..75d392ee9 100644 --- a/include/zenoh-pico.h +++ b/include/zenoh-pico.h @@ -26,6 +26,7 @@ #include "zenoh-pico/api/constants.h" #include "zenoh-pico/api/encoding.h" #include "zenoh-pico/api/handlers.h" +#include "zenoh-pico/api/liveliness.h" #include "zenoh-pico/api/macros.h" #include "zenoh-pico/api/primitives.h" #include "zenoh-pico/api/types.h" diff --git a/include/zenoh-pico.h.in b/include/zenoh-pico.h.in index bd4790b1e..b19efad0e 100644 --- a/include/zenoh-pico.h.in +++ b/include/zenoh-pico.h.in @@ -26,6 +26,7 @@ #include "zenoh-pico/api/constants.h" #include "zenoh-pico/api/encoding.h" #include "zenoh-pico/api/handlers.h" +#include "zenoh-pico/api/liveliness.h" #include "zenoh-pico/api/macros.h" #include "zenoh-pico/api/primitives.h" #include "zenoh-pico/api/types.h" diff --git a/include/zenoh-pico/api/encoding.h b/include/zenoh-pico/api/encoding.h index 3544693b8..7393ae259 100644 --- a/include/zenoh-pico/api/encoding.h +++ b/include/zenoh-pico/api/encoding.h @@ -78,84 +78,84 @@ extern const z_owned_encoding_t ZP_ENCODING_ZENOH_SERIALIZED; * Constant alias for string: `"application/octet-stream"`. */ const z_loaned_encoding_t *z_encoding_application_octet_stream(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_OCTET_STREAM; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_OCTET_STREAM; /** * A textual file. * Constant alias for string: `"text/plain"`. */ const z_loaned_encoding_t *z_encoding_text_plain(void); -extern const z_owned_encoding_t ENCODING_TEXT_PLAIN; +extern const z_owned_encoding_t ZP_ENCODING_TEXT_PLAIN; /** * JSON data intended to be consumed by an application. * Constant alias for string: `"application/json"`. */ const z_loaned_encoding_t *z_encoding_application_json(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_JSON; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_JSON; /** * JSON data intended to be human readable. * Constant alias for string: `"text/json"`. */ const z_loaned_encoding_t *z_encoding_text_json(void); -extern const z_owned_encoding_t ENCODING_TEXT_JSON; +extern const z_owned_encoding_t ZP_ENCODING_TEXT_JSON; /** * A Common Data Representation (CDR)-encoded data. * Constant alias for string: `"application/cdr"`. */ const z_loaned_encoding_t *z_encoding_application_cdr(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_CDR; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_CDR; /** * A Concise Binary Object Representation (CBOR)-encoded data. * Constant alias for string: `"application/cbor"`. */ const z_loaned_encoding_t *z_encoding_application_cbor(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_CBOR; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_CBOR; /** * YAML data intended to be consumed by an application. * Constant alias for string: `"application/yaml"`. */ const z_loaned_encoding_t *z_encoding_application_yaml(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_YAML; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_YAML; /** * YAML data intended to be human readable. * Constant alias for string: `"text/yaml"`. */ const z_loaned_encoding_t *z_encoding_text_yaml(void); -extern const z_owned_encoding_t ENCODING_TEXT_YAML; +extern const z_owned_encoding_t ZP_ENCODING_TEXT_YAML; /** * JSON5 encoded data that are human readable. * Constant alias for string: `"text/json5"`. */ const z_loaned_encoding_t *z_encoding_text_json5(void); -extern const z_owned_encoding_t ENCODING_TEXT_JSON5; +extern const z_owned_encoding_t ZP_ENCODING_TEXT_JSON5; /** * A Python object serialized using `pickle `_. * Constant alias for string: `"application/python-serialized-object"`. */ const z_loaned_encoding_t *z_encoding_application_python_serialized_object(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_PYTHON_SERIALIZED_OBJECT; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_PYTHON_SERIALIZED_OBJECT; /** * An application-specific protobuf-encoded data. * Constant alias for string: `"application/protobuf"`. */ const z_loaned_encoding_t *z_encoding_application_protobuf(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_PROTOBUF; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_PROTOBUF; /** * A Java serialized object. * Constant alias for string: `"application/java-serialized-object"`. */ const z_loaned_encoding_t *z_encoding_application_java_serialized_object(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_JAVA_SERIALIZED_OBJECT; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_JAVA_SERIALIZED_OBJECT; /** * An `openmetrics `_ data, commonly used by @@ -163,266 +163,266 @@ extern const z_owned_encoding_t ENCODING_APPLICATION_JAVA_SERIALIZED_OBJECT; * Constant alias for string: `"application/openmetrics-text"`. */ const z_loaned_encoding_t *z_encoding_application_openmetrics_text(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_OPENMETRICS_TEXT; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_OPENMETRICS_TEXT; /** * A Portable Network Graphics (PNG) image. * Constant alias for string: `"image/png"`. */ const z_loaned_encoding_t *z_encoding_image_png(void); -extern const z_owned_encoding_t ENCODING_IMAGE_PNG; +extern const z_owned_encoding_t ZP_ENCODING_IMAGE_PNG; /** * A Joint Photographic Experts Group (JPEG) image. * Constant alias for string: `"image/jpeg"`. */ const z_loaned_encoding_t *z_encoding_image_jpeg(void); -extern const z_owned_encoding_t ENCODING_IMAGE_JPEG; +extern const z_owned_encoding_t ZP_ENCODING_IMAGE_JPEG; /** * A Graphics Interchange Format (GIF) image. * Constant alias for string: `"image/gif"`. */ const z_loaned_encoding_t *z_encoding_image_gif(void); -extern const z_owned_encoding_t ENCODING_IMAGE_GIF; +extern const z_owned_encoding_t ZP_ENCODING_IMAGE_GIF; /** * A BitMap (BMP) image. * Constant alias for string: `"image/bmp"`. */ const z_loaned_encoding_t *z_encoding_image_bmp(void); -extern const z_owned_encoding_t ENCODING_IMAGE_BMP; +extern const z_owned_encoding_t ZP_ENCODING_IMAGE_BMP; /** * A Web Portable (WebP) image. * Constant alias for string: `"image/webp"`. */ const z_loaned_encoding_t *z_encoding_image_webp(void); -extern const z_owned_encoding_t ENCODING_IMAGE_WEBP; +extern const z_owned_encoding_t ZP_ENCODING_IMAGE_WEBP; /** * An XML file intended to be consumed by an application. * Constant alias for string: `"application/xml"`. */ const z_loaned_encoding_t *z_encoding_application_xml(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_XML; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_XML; /** * An encoded list of tuples, each consisting of a name and a value. * Constant alias for string: `"application/x-www-form-urlencoded"`. */ const z_loaned_encoding_t *z_encoding_application_x_www_form_urlencoded(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_X_WWW_FORM_URLENCODED; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_X_WWW_FORM_URLENCODED; /** * An HTML file. * Constant alias for string: `"text/html"`. */ const z_loaned_encoding_t *z_encoding_text_html(void); -extern const z_owned_encoding_t ENCODING_TEXT_HTML; +extern const z_owned_encoding_t ZP_ENCODING_TEXT_HTML; /** * An XML file that is human-readable. * Constant alias for string: `"text/xml"`. */ const z_loaned_encoding_t *z_encoding_text_xml(void); -extern const z_owned_encoding_t ENCODING_TEXT_XML; +extern const z_owned_encoding_t ZP_ENCODING_TEXT_XML; /** * A CSS file. * Constant alias for string: `"text/css"`. */ const z_loaned_encoding_t *z_encoding_text_css(void); -extern const z_owned_encoding_t ENCODING_TEXT_CSS; +extern const z_owned_encoding_t ZP_ENCODING_TEXT_CSS; /** * A JavaScript file. * Constant alias for string: `"text/javascript"`. */ const z_loaned_encoding_t *z_encoding_text_javascript(void); -extern const z_owned_encoding_t ENCODING_TEXT_JAVASCRIPT; +extern const z_owned_encoding_t ZP_ENCODING_TEXT_JAVASCRIPT; /** * A Markdown file. * Constant alias for string: `"text/markdown"`. */ const z_loaned_encoding_t *z_encoding_text_markdown(void); -extern const z_owned_encoding_t ENCODING_TEXT_MARKDOWN; +extern const z_owned_encoding_t ZP_ENCODING_TEXT_MARKDOWN; /** * A CSV file. * Constant alias for string: `"text/csv"`. */ const z_loaned_encoding_t *z_encoding_text_csv(void); -extern const z_owned_encoding_t ENCODING_TEXT_CSV; +extern const z_owned_encoding_t ZP_ENCODING_TEXT_CSV; /** * An application-specific SQL query. * Constant alias for string: `"application/sql"`. */ const z_loaned_encoding_t *z_encoding_application_sql(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_SQL; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_SQL; /** * Constrained Application Protocol (CoAP) data intended for CoAP-to-HTTP and HTTP-to-CoAP proxies. * Constant alias for string: `"application/coap-payload"`. */ const z_loaned_encoding_t *z_encoding_application_coap_payload(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_COAP_PAYLOAD; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_COAP_PAYLOAD; /** * Defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. * Constant alias for string: `"application/json-patch+json"`. */ const z_loaned_encoding_t *z_encoding_application_json_patch_json(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_JSON_PATCH_JSON; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_JSON_PATCH_JSON; /** * A JSON text sequence consists of any number of JSON texts, all encoded in UTF-8. * Constant alias for string: `"application/json-seq"`. */ const z_loaned_encoding_t *z_encoding_application_json_seq(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_JSON_SEQ; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_JSON_SEQ; /** * A JSONPath defines a string syntax for selecting and extracting JSON values from within a given JSON value. * Constant alias for string: `"application/jsonpath"`. */ const z_loaned_encoding_t *z_encoding_application_jsonpath(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_JSONPATH; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_JSONPATH; /** * A JSON Web Token (JWT). * Constant alias for string: `"application/jwt"`. */ const z_loaned_encoding_t *z_encoding_application_jwt(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_JWT; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_JWT; /** * An application-specific MPEG-4 encoded data, either audio or video. * Constant alias for string: `"application/mp4"`. */ const z_loaned_encoding_t *z_encoding_application_mp4(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_MP4; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_MP4; /** * A SOAP 1.2 message serialized as XML 1.0. * Constant alias for string: `"application/soap+xml"`. */ const z_loaned_encoding_t *z_encoding_application_soap_xml(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_SOAP_XML; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_SOAP_XML; /** * A YANG-encoded data commonly used by the Network Configuration Protocol (NETCONF). * Constant alias for string: `"application/yang"`. */ const z_loaned_encoding_t *z_encoding_application_yang(void); -extern const z_owned_encoding_t ENCODING_APPLICATION_YANG; +extern const z_owned_encoding_t ZP_ENCODING_APPLICATION_YANG; /** * A MPEG-4 Advanced Audio Coding (AAC) media. * Constant alias for string: `"audio/aac"`. */ const z_loaned_encoding_t *z_encoding_audio_aac(void); -extern const z_owned_encoding_t ENCODING_AUDIO_AAC; +extern const z_owned_encoding_t ZP_ENCODING_AUDIO_AAC; /** * A Free Lossless Audio Codec (FLAC) media. * Constant alias for string: `"audio/flac"`. */ const z_loaned_encoding_t *z_encoding_audio_flac(void); -extern const z_owned_encoding_t ENCODING_AUDIO_FLAC; +extern const z_owned_encoding_t ZP_ENCODING_AUDIO_FLAC; /** * An audio codec defined in MPEG-1, MPEG-2, MPEG-4, or registered at the MP4 registration authority. * Constant alias for string: `"audio/mp4"`. */ const z_loaned_encoding_t *z_encoding_audio_mp4(void); -extern const z_owned_encoding_t ENCODING_AUDIO_MP4; +extern const z_owned_encoding_t ZP_ENCODING_AUDIO_MP4; /** * An Ogg-encapsulated audio stream. * Constant alias for string: `"audio/ogg"`. */ const z_loaned_encoding_t *z_encoding_audio_ogg(void); -extern const z_owned_encoding_t ENCODING_AUDIO_OGG; +extern const z_owned_encoding_t ZP_ENCODING_AUDIO_OGG; /** * A Vorbis-encoded audio stream. * Constant alias for string: `"audio/vorbis"`. */ const z_loaned_encoding_t *z_encoding_audio_vorbis(void); -extern const z_owned_encoding_t ENCODING_AUDIO_VORBIS; +extern const z_owned_encoding_t ZP_ENCODING_AUDIO_VORBIS; /** * A h261-encoded video stream. * Constant alias for string: `"video/h261"`. */ const z_loaned_encoding_t *z_encoding_video_h261(void); -extern const z_owned_encoding_t ENCODING_VIDEO_H261; +extern const z_owned_encoding_t ZP_ENCODING_VIDEO_H261; /** * A h263-encoded video stream. * Constant alias for string: `"video/h263"`. */ const z_loaned_encoding_t *z_encoding_video_h263(void); -extern const z_owned_encoding_t ENCODING_VIDEO_H263; +extern const z_owned_encoding_t ZP_ENCODING_VIDEO_H263; /** * A h264-encoded video stream. * Constant alias for string: `"video/h264"`. */ const z_loaned_encoding_t *z_encoding_video_h264(void); -extern const z_owned_encoding_t ENCODING_VIDEO_H264; +extern const z_owned_encoding_t ZP_ENCODING_VIDEO_H264; /** * A h265-encoded video stream. * Constant alias for string: `"video/h265"`. */ const z_loaned_encoding_t *z_encoding_video_h265(void); -extern const z_owned_encoding_t ENCODING_VIDEO_H265; +extern const z_owned_encoding_t ZP_ENCODING_VIDEO_H265; /** * A h266-encoded video stream. * Constant alias for string: `"video/h266"`. */ const z_loaned_encoding_t *z_encoding_video_h266(void); -extern const z_owned_encoding_t ENCODING_VIDEO_H266; +extern const z_owned_encoding_t ZP_ENCODING_VIDEO_H266; /** * A video codec defined in MPEG-1, MPEG-2, MPEG-4, or registered at the MP4 registration authority. * Constant alias for string: `"video/mp4"`. */ const z_loaned_encoding_t *z_encoding_video_mp4(void); -extern const z_owned_encoding_t ENCODING_VIDEO_MP4; +extern const z_owned_encoding_t ZP_ENCODING_VIDEO_MP4; /** * An Ogg-encapsulated video stream. * Constant alias for string: `"video/ogg"`. */ const z_loaned_encoding_t *z_encoding_video_ogg(void); -extern const z_owned_encoding_t ENCODING_VIDEO_OGG; +extern const z_owned_encoding_t ZP_ENCODING_VIDEO_OGG; /** * An uncompressed, studio-quality video stream. * Constant alias for string: `"video/raw"`. */ const z_loaned_encoding_t *z_encoding_video_raw(void); -extern const z_owned_encoding_t ENCODING_VIDEO_RAW; +extern const z_owned_encoding_t ZP_ENCODING_VIDEO_RAW; /** * A VP8-encoded video stream. * Constant alias for string: `"video/vp8"`. */ const z_loaned_encoding_t *z_encoding_video_vp8(void); -extern const z_owned_encoding_t ENCODING_VIDEO_VP8; +extern const z_owned_encoding_t ZP_ENCODING_VIDEO_VP8; /** * A VP9-encoded video stream. * Constant alias for string: `"video/vp9"`. */ const z_loaned_encoding_t *z_encoding_video_vp9(void); -extern const z_owned_encoding_t ENCODING_VIDEO_VP9; +extern const z_owned_encoding_t ZP_ENCODING_VIDEO_VP9; /** * Returns a loaned default `z_loaned_encoding_t`. diff --git a/include/zenoh-pico/api/handlers.h b/include/zenoh-pico/api/handlers.h index 52e3f2ce4..e2d939162 100644 --- a/include/zenoh-pico/api/handlers.h +++ b/include/zenoh-pico/api/handlers.h @@ -140,27 +140,42 @@ extern "C" { /* collection_close_f */ _z_##kind_name##_mt_close, \ /* elem_owned_type */ z_owned_##item_name##_t, \ /* elem_loaned_type */ z_loaned_##item_name##_t, \ - /* elem_clone_f */ z_##item_name##_clone, \ + /* elem_clone_f */ z_##item_name##_clone, \ /* elem_move_f */ z_##item_name##_move, \ /* elem_drop_f */ z_##item_name##_drop, \ - /* elem_null */ z_internal_##item_name##_null) + /* elem_null_f */ z_internal_##item_name##_null) -#define _Z_CHANNEL_DEFINE_DUMMY(item_name, kind_name) \ - typedef struct { \ - uint8_t _foo; \ - } z_owned_##kind_name##_handler_##item_name##_t; \ - typedef struct { \ - uint8_t _foo; \ - } z_loaned_##kind_name##_handler_##item_name##_t; \ - typedef struct { \ - z_owned_##kind_name##_handler_##item_name##_t *_ptr; \ - } z_moved_##kind_name##_handler_##item_name##_t; \ - void *z_##kind_name##_handler_##item_name##_loan(void); \ - void *z_##kind_name##_handler_##item_name##_move(void); \ - void *z_##kind_name##_handler_##item_name##_drop(void); \ - void *z_##kind_name##_handler_##item_name##_recv(void); \ - void *z_##kind_name##_handler_##item_name##_take(void); \ - void *z_##kind_name##_handler_##item_name##_try_recv(void); +#define _Z_CHANNEL_DUMMY_IMPL(handler_type, handler_name, item_name) \ + _Z_OWNED_TYPE_VALUE(handler_type, handler_name) \ + static inline void _z_##handler_name##_clear(handler_type *handler) { _ZP_UNUSED(handler); } \ + static inline bool _z_##handler_name##_check(const handler_type *handler) { \ + _ZP_UNUSED(handler); \ + return false; \ + } \ + static inline handler_type _z_##handler_name##_null(void) { \ + handler_type h = {0}; \ + return h; \ + } \ + _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_INLINE_IMPL(handler_type, handler_name, _z_##handler_name##_check, \ + _z_##handler_name##_null, _z_##handler_name##_clear) \ + static inline z_result_t z_##handler_name##_try_recv(const z_loaned_##handler_name##_t *handler, \ + z_owned_##item_name##_t *e) { \ + _ZP_UNUSED(handler); \ + _ZP_UNUSED(e); \ + return Z_CHANNEL_DISCONNECTED; \ + } \ + static inline z_result_t z_##handler_name##_recv(const z_loaned_##handler_name##_t *handler, \ + z_owned_##item_name##_t *e) { \ + _ZP_UNUSED(handler); \ + _ZP_UNUSED(e); \ + return Z_CHANNEL_DISCONNECTED; \ + } + +#define _Z_CHANNEL_DEFINE_DUMMY(item_name, kind_name) \ + typedef struct { \ + uint8_t _foo; \ + } _z_##kind_name##_handler_##item_name##_t; \ + _Z_CHANNEL_DUMMY_IMPL(_z_##kind_name##_handler_##item_name##_t, kind_name##_handler_##item_name, item_name) // This macro defines: // z_ring_channel_sample_new() diff --git a/include/zenoh-pico/api/liveliness.h b/include/zenoh-pico/api/liveliness.h new file mode 100644 index 000000000..d3751bc4f --- /dev/null +++ b/include/zenoh-pico/api/liveliness.h @@ -0,0 +1,153 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#ifndef INCLUDE_ZENOH_PICO_API_LIVELINESS_H +#define INCLUDE_ZENOH_PICO_API_LIVELINESS_H + +#include +#include + +#include "olv_macros.h" +#include "zenoh-pico/api/types.h" +#include "zenoh-pico/protocol/core.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint32_t _id; + _z_keyexpr_t _key; + _z_session_weak_t _zn; +} _z_liveliness_token_t; + +_Z_OWNED_TYPE_VALUE(_z_liveliness_token_t, liveliness_token) +_Z_OWNED_FUNCTIONS_DEF(liveliness_token) + +#if Z_FEATURE_LIVELINESS == 1 + +/**************** Liveliness Token ****************/ + +/** + * The options for :c:func:`z_liveliness_declare_token()`. + */ +typedef struct z_liveliness_token_options_t { + uint8_t __dummy; +} z_liveliness_token_options_t; + +/** + * Constructs default value for :c:type:`z_liveliness_token_options_t`. + */ +z_result_t z_liveliness_token_options_default(z_liveliness_token_options_t *options); + +/** + * Constructs and declares a liveliness token on the network. + * + * Liveliness token subscribers on an intersecting key expression will receive a PUT sample when connectivity + * is achieved, and a DELETE sample if it's lost. + * + * Parameters: + * zs: A Zenos session to declare the liveliness token. + * token: An uninitialized memory location where liveliness token will be constructed. + * keyexpr: A keyexpr to declare a liveliess token for. + * options: Liveliness token declaration options. + * + * Return: + * ``0`` if put operation is successful, ``negative value`` otherwise. + */ +z_result_t z_liveliness_declare_token(const z_loaned_session_t *zs, z_owned_liveliness_token_t *token, + const z_loaned_keyexpr_t *keyexpr, const z_liveliness_token_options_t *options); + +/** + * Undeclare a liveliness token, notifying subscribers of its destruction. + * + * Parameters: + * token: Moved :c:type:`z_owned_liveliness_token_t` to undeclare. + * + * Return: + * ``0`` if put operation is successful, ``negative value`` otherwise. + */ +z_result_t z_liveliness_undeclare_token(z_moved_liveliness_token_t *token); + +/**************** Liveliness Subscriber ****************/ + +#if Z_FEATURE_SUBSCRIPTION == 1 +/** + * The options for :c:func:`z_liveliness_declare_subscriber()` + */ +typedef struct z_liveliness_subscriber_options_t { + bool history; +} z_liveliness_subscriber_options_t; + +/** + * Constucts default value for :c:type:`z_liveliness_subscriber_options_t`. + */ +z_result_t z_liveliness_subscriber_options_default(z_liveliness_subscriber_options_t *options); + +/** + * Declares a subscriber on liveliness tokens that intersect `keyexpr`. + * + * Parameters: + * zs: The Zenoh session. + * sub: An uninitialized memory location where subscriber will be constructed. + * keyexpr: The key expression to subscribe to. + * callback: The callback function that will be called each time a liveliness token status is changed. + * options: The options to be passed to the liveliness subscriber declaration. + * + * Return: + * ``0`` if put operation is successful, ``negative value`` otherwise. + */ +z_result_t z_liveliness_declare_subscriber(const z_loaned_session_t *zs, z_owned_subscriber_t *sub, + const z_loaned_keyexpr_t *keyexpr, z_moved_closure_sample_t *callback, + z_liveliness_subscriber_options_t *options); +#endif // Z_FEATURE_SUBSCRIPTION == 1 + +/**************** Liveliness Query ****************/ + +#if Z_FEATURE_QUERY == 1 +/** + * The options for :c:func:`z_liveliness_get()` + */ +typedef struct z_liveliness_get_options_t { + uint32_t timeout_ms; +} z_liveliness_get_options_t; + +/** + * Constructs default value :c:type:`z_liveliness_get_options_t`. + */ +z_result_t z_liveliness_get_options_default(z_liveliness_get_options_t *options); + +/** + * Queries liveliness tokens currently on the network with a key expression intersecting with `keyexpr`. + * + * Parameters: + * zs: The Zenoh session. + * keyexpr: The key expression to query liveliness tokens for. + * callback: The callback function that will be called for each received reply. + * options: Additional options for the liveliness get operation. + * + * Return: + * ``0`` if put operation is successful, ``negative value`` otherwise. + */ +z_result_t z_liveliness_get(const z_loaned_session_t *zs, const z_loaned_keyexpr_t *keyexpr, + z_moved_closure_reply_t *callback, z_liveliness_get_options_t *options); + +#endif // Z_FEATURE_QUERY == 1 + +#endif // Z_FEATURE_LIVELINESS == 1 + +#ifdef __cplusplus +} +#endif + +#endif // INCLUDE_ZENOH_PICO_API_LIVELINESS_H diff --git a/include/zenoh-pico/api/macros.h b/include/zenoh-pico/api/macros.h index 0d1c9aea8..f60ba22bd 100644 --- a/include/zenoh-pico/api/macros.h +++ b/include/zenoh-pico/api/macros.h @@ -15,6 +15,7 @@ #define ZENOH_PICO_API_MACROS_H #include "zenoh-pico/api/handlers.h" +#include "zenoh-pico/api/liveliness.h" #include "zenoh-pico/api/primitives.h" #include "zenoh-pico/api/serialization.h" #include "zenoh-pico/api/types.h" @@ -43,6 +44,7 @@ z_owned_subscriber_t : z_subscriber_loan, \ z_owned_publisher_t : z_publisher_loan, \ z_owned_queryable_t : z_queryable_loan, \ + z_owned_liveliness_token_t : z_liveliness_token_loan, \ z_owned_reply_t : z_reply_loan, \ z_owned_hello_t : z_hello_loan, \ z_owned_string_t : z_string_loan, \ @@ -74,28 +76,29 @@ )(&x) #define z_loan_mut(x) _Generic((x), \ - z_owned_keyexpr_t : z_keyexpr_loan_mut, \ - z_owned_config_t : z_config_loan_mut, \ - z_owned_session_t : z_session_loan_mut, \ - z_owned_publisher_t : z_publisher_loan_mut, \ - z_owned_queryable_t : z_queryable_loan_mut, \ - z_owned_subscriber_t : z_subscriber_loan_mut, \ - z_owned_reply_t : z_reply_loan_mut, \ - z_owned_hello_t : z_hello_loan_mut, \ - z_owned_string_t : z_string_loan_mut, \ - z_view_string_t : z_view_string_loan_mut, \ - z_owned_string_array_t : z_string_array_loan_mut, \ - z_owned_sample_t : z_sample_loan_mut, \ - z_owned_query_t : z_query_loan_mut, \ - z_owned_slice_t : z_slice_loan_mut, \ - z_view_slice_t : z_view_slice_loan_mut, \ - z_owned_bytes_t : z_bytes_loan_mut, \ - z_owned_task_t : z_task_loan_mut, \ - z_owned_mutex_t : z_mutex_loan_mut, \ - z_owned_condvar_t : z_condvar_loan_mut, \ - z_owned_reply_err_t : z_reply_err_loan_mut, \ - ze_owned_serializer_t : ze_serializer_loan_mut, \ - z_owned_bytes_writer_t : z_bytes_writer_loan_mut \ + z_owned_keyexpr_t : z_keyexpr_loan_mut, \ + z_owned_config_t : z_config_loan_mut, \ + z_owned_session_t : z_session_loan_mut, \ + z_owned_publisher_t : z_publisher_loan_mut, \ + z_owned_queryable_t : z_queryable_loan_mut, \ + z_owned_liveliness_token_t : z_liveliness_token_loan_mut, \ + z_owned_subscriber_t : z_subscriber_loan_mut, \ + z_owned_reply_t : z_reply_loan_mut, \ + z_owned_hello_t : z_hello_loan_mut, \ + z_owned_string_t : z_string_loan_mut, \ + z_view_string_t : z_view_string_loan_mut, \ + z_owned_string_array_t : z_string_array_loan_mut, \ + z_owned_sample_t : z_sample_loan_mut, \ + z_owned_query_t : z_query_loan_mut, \ + z_owned_slice_t : z_slice_loan_mut, \ + z_view_slice_t : z_view_slice_loan_mut, \ + z_owned_bytes_t : z_bytes_loan_mut, \ + z_owned_task_t : z_task_loan_mut, \ + z_owned_mutex_t : z_mutex_loan_mut, \ + z_owned_condvar_t : z_condvar_loan_mut, \ + z_owned_reply_err_t : z_reply_err_loan_mut, \ + ze_owned_serializer_t : ze_serializer_loan_mut, \ + z_owned_bytes_writer_t : z_bytes_writer_loan_mut \ )(&x) /** @@ -111,6 +114,7 @@ z_moved_subscriber_t* : z_subscriber_drop, \ z_moved_publisher_t* : z_publisher_drop, \ z_moved_queryable_t* : z_queryable_drop, \ + z_moved_liveliness_token_t* : z_liveliness_token_drop, \ z_moved_reply_t* : z_reply_drop, \ z_moved_hello_t* : z_hello_drop, \ z_moved_string_t* : z_string_drop, \ @@ -150,29 +154,30 @@ */ #define z_internal_check(x) _Generic((x), \ - z_owned_keyexpr_t : z_internal_keyexpr_check, \ - z_owned_reply_err_t : z_internal_reply_err_check, \ - z_owned_config_t : z_internal_config_check, \ - z_owned_session_t : z_internal_session_check, \ - z_owned_subscriber_t : z_internal_subscriber_check, \ - z_owned_publisher_t : z_internal_publisher_check, \ - z_owned_queryable_t : z_internal_queryable_check, \ - z_owned_reply_t : z_internal_reply_check, \ - z_owned_hello_t : z_internal_hello_check, \ - z_owned_string_t : z_internal_string_check, \ - z_owned_string_array_t : z_internal_string_array_check, \ - z_owned_closure_sample_t : z_internal_closure_sample_check, \ - z_owned_closure_query_t : z_internal_closure_query_check, \ - z_owned_closure_reply_t : z_internal_closure_reply_check, \ - z_owned_closure_hello_t : z_internal_closure_hello_check, \ - z_owned_closure_zid_t : z_internal_closure_zid_check, \ - z_owned_slice_t : z_internal_slice_check, \ - z_owned_bytes_t : z_internal_bytes_check, \ - z_owned_sample_t : z_internal_sample_check, \ - z_owned_query_t : z_internal_query_check, \ - z_owned_encoding_t : z_internal_encoding_check, \ - ze_owned_serializer_t : ze_internal_serializer_check, \ - z_owned_bytes_writer_t : z_internal_bytes_writer_check \ + z_owned_keyexpr_t : z_internal_keyexpr_check, \ + z_owned_reply_err_t : z_internal_reply_err_check, \ + z_owned_config_t : z_internal_config_check, \ + z_owned_session_t : z_internal_session_check, \ + z_owned_subscriber_t : z_internal_subscriber_check, \ + z_owned_publisher_t : z_internal_publisher_check, \ + z_owned_queryable_t : z_internal_queryable_check, \ + z_owned_liveliness_token_t : z_internal_liveliness_token_check, \ + z_owned_reply_t : z_internal_reply_check, \ + z_owned_hello_t : z_internal_hello_check, \ + z_owned_string_t : z_internal_string_check, \ + z_owned_string_array_t : z_internal_string_array_check, \ + z_owned_closure_sample_t : z_internal_closure_sample_check, \ + z_owned_closure_query_t : z_internal_closure_query_check, \ + z_owned_closure_reply_t : z_internal_closure_reply_check, \ + z_owned_closure_hello_t : z_internal_closure_hello_check, \ + z_owned_closure_zid_t : z_internal_closure_zid_check, \ + z_owned_slice_t : z_internal_slice_check, \ + z_owned_bytes_t : z_internal_bytes_check, \ + z_owned_sample_t : z_internal_sample_check, \ + z_owned_query_t : z_internal_query_check, \ + z_owned_encoding_t : z_internal_encoding_check, \ + ze_owned_serializer_t : ze_internal_serializer_check, \ + z_owned_bytes_writer_t : z_internal_bytes_writer_check \ )(&x) /** @@ -225,6 +230,7 @@ z_owned_subscriber_t : z_subscriber_move, \ z_owned_publisher_t : z_publisher_move, \ z_owned_queryable_t : z_queryable_move, \ + z_owned_liveliness_token_t : z_liveliness_token_move, \ z_owned_reply_t : z_reply_move, \ z_owned_hello_t : z_hello_move, \ z_owned_string_t : z_string_move, \ @@ -283,6 +289,7 @@ z_owned_publisher_t *: z_publisher_take, \ z_owned_query_t *: z_query_take, \ z_owned_queryable_t *: z_queryable_take, \ + z_owned_liveliness_token_t *: z_liveliness_token_take, \ z_owned_reply_t *: z_reply_take, \ z_owned_reply_err_t *: z_reply_err_take, \ z_owned_ring_handler_query_t *: z_ring_handler_query_take, \ @@ -336,6 +343,7 @@ z_owned_config_t * : z_internal_config_null, \ z_owned_subscriber_t * : z_internal_subscriber_null, \ z_owned_queryable_t * : z_internal_queryable_null, \ + z_owned_liveliness_token_t * : z_internal_liveliness_token_null, \ z_owned_query_t * : z_internal_query_null, \ z_owned_reply_t * : z_internal_reply_null, \ z_owned_hello_t * : z_internal_hello_null, \ @@ -389,6 +397,7 @@ inline const z_loaned_session_t* z_loan(const z_owned_session_t& x) { return z_s inline const z_loaned_subscriber_t* z_loan(const z_owned_subscriber_t& x) { return z_subscriber_loan(&x); } inline const z_loaned_publisher_t* z_loan(const z_owned_publisher_t& x) { return z_publisher_loan(&x); } inline const z_loaned_queryable_t* z_loan(const z_owned_queryable_t& x) { return z_queryable_loan(&x); } +inline const z_loaned_liveliness_token_t* z_loan(const z_owned_liveliness_token_t& x) { return z_liveliness_token_loan(&x); } inline const z_loaned_reply_t* z_loan(const z_owned_reply_t& x) { return z_reply_loan(&x); } inline const z_loaned_hello_t* z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } inline const z_loaned_string_t* z_loan(const z_owned_string_t& x) { return z_string_loan(&x); } @@ -425,6 +434,7 @@ inline z_loaned_config_t* z_loan_mut(z_owned_config_t& x) { return z_config_loan inline z_loaned_session_t* z_loan_mut(z_owned_session_t& x) { return z_session_loan_mut(&x); } inline z_loaned_publisher_t* z_loan_mut(z_owned_publisher_t& x) { return z_publisher_loan_mut(&x); } inline z_loaned_queryable_t* z_loan_mut(z_owned_queryable_t& x) { return z_queryable_loan_mut(&x); } +inline z_loaned_liveliness_token_t* z_loan_mut(z_owned_liveliness_token_t& x) { return z_liveliness_token_loan_mut(&x); } inline z_loaned_subscriber_t* z_loan_mut(z_owned_subscriber_t& x) { return z_subscriber_loan_mut(&x); } inline z_loaned_reply_t* z_loan_mut(z_owned_reply_t& x) { return z_reply_loan_mut(&x); } inline z_loaned_hello_t* z_loan_mut(z_owned_hello_t& x) { return z_hello_loan_mut(&x); } @@ -451,6 +461,7 @@ inline void z_drop(z_moved_keyexpr_t* v) { z_keyexpr_drop(v); } inline void z_drop(z_moved_config_t* v) { z_config_drop(v); } inline void z_drop(z_moved_subscriber_t* v) { z_subscriber_drop(v); } inline void z_drop(z_moved_queryable_t* v) { z_queryable_drop(v); } +inline void z_drop(z_moved_liveliness_token_t* v) { z_liveliness_token_drop(v); } inline void z_drop(z_moved_reply_t* v) { z_reply_drop(v); } inline void z_drop(z_moved_hello_t* v) { z_hello_drop(v); } inline void z_drop(z_moved_string_t* v) { z_string_drop(v); } @@ -484,6 +495,7 @@ inline void z_internal_null(z_owned_keyexpr_t* v) { z_internal_keyexpr_null(v); inline void z_internal_null(z_owned_config_t* v) { z_internal_config_null(v); } inline void z_internal_null(z_owned_subscriber_t* v) { z_internal_subscriber_null(v); } inline void z_internal_null(z_owned_queryable_t* v) { z_internal_queryable_null(v); } +inline void z_internal_null(z_owned_liveliness_token_t* v) { z_internal_liveliness_token_null(v); } inline void z_internal_null(z_owned_query_t* v) { z_internal_query_null(v); } inline void z_internal_null(z_owned_sample_t* v) { z_internal_sample_null(v); } inline void z_internal_null(z_owned_reply_t* v) { z_internal_reply_null(v); } @@ -513,6 +525,7 @@ inline bool z_internal_check(const z_owned_keyexpr_t& v) { return z_internal_key inline bool z_internal_check(const z_owned_config_t& v) { return z_internal_config_check(&v); } inline bool z_internal_check(const z_owned_subscriber_t& v) { return z_internal_subscriber_check(&v); } inline bool z_internal_check(const z_owned_queryable_t& v) { return z_internal_queryable_check(&v); } +inline bool z_internal_check(const z_owned_liveliness_token_t& v) { return z_internal_liveliness_token_check(&v); } inline bool z_internal_check(const z_owned_reply_t& v) { return z_internal_reply_check(&v); } inline bool z_internal_check(const z_owned_query_t& v) { return z_internal_query_check(&v); } inline bool z_internal_check(const z_owned_hello_t& v) { return z_internal_hello_check(&v); } @@ -545,8 +558,8 @@ inline void z_call(const z_loaned_closure_zid_t &closure, const z_id_t *zid) inline void z_closure( z_owned_closure_hello_t* closure, void (*call)(z_loaned_hello_t*, void*), - void (*drop)(void*) = NULL, - void *context = NULL) { + void (*drop)(void*), + void *context) { closure->_val.context = context; closure->_val.drop = drop; closure->_val.call = call; @@ -554,8 +567,8 @@ inline void z_closure( inline void z_closure( z_owned_closure_query_t* closure, void (*call)(z_loaned_query_t*, void*), - void (*drop)(void*) = NULL, - void *context = NULL) { + void (*drop)(void*), + void *context) { closure->_val.context = context; closure->_val.drop = drop; closure->_val.call = call; @@ -563,8 +576,8 @@ inline void z_closure( inline void z_closure( z_owned_closure_reply_t* closure, void (*call)(z_loaned_reply_t*, void*), - void (*drop)(void*) = NULL, - void *context = NULL) { + void (*drop)(void*), + void *context) { closure->_val.context = context; closure->_val.drop = drop; closure->_val.call = call; @@ -572,8 +585,8 @@ inline void z_closure( inline void z_closure( z_owned_closure_sample_t* closure, void (*call)(z_loaned_sample_t*, void*), - void (*drop)(void*) = NULL, - void *context = NULL) { + void (*drop)(void*), + void *context) { closure->_val.context = context; closure->_val.drop = drop; closure->_val.call = call; @@ -581,8 +594,8 @@ inline void z_closure( inline void z_closure( z_owned_closure_zid_t* closure, void (*call)(const z_id_t*, void*), - void (*drop)(void*) = NULL, - void *context = NULL) { + void (*drop)(void*), + void *context) { closure->_val.context = context; closure->_val.drop = drop; closure->_val.call = call; @@ -643,6 +656,7 @@ inline z_moved_keyexpr_t* z_move(z_owned_keyexpr_t& x) { return z_keyexpr_move(& inline z_moved_publisher_t* z_move(z_owned_publisher_t& x) { return z_publisher_move(&x); } inline z_moved_query_t* z_move(z_owned_query_t& x) { return z_query_move(&x); } inline z_moved_queryable_t* z_move(z_owned_queryable_t& x) { return z_queryable_move(&x); } +inline z_moved_liveliness_token_t* z_move(z_owned_liveliness_token_t& x) { return z_liveliness_token_move(&x); } inline z_moved_reply_t* z_move(z_owned_reply_t& x) { return z_reply_move(&x); } inline z_moved_sample_t* z_move(z_owned_sample_t& x) { return z_sample_move(&x); } inline z_moved_session_t* z_move(z_owned_session_t& x) { return z_session_move(&x); } @@ -670,6 +684,9 @@ inline void z_take(z_owned_keyexpr_t* this_, z_moved_keyexpr_t* v) { z_keyexpr_t inline void z_take(z_owned_config_t* this_, z_moved_config_t* v) { z_config_take(this_, v); } inline void z_take(z_owned_subscriber_t* this_, z_moved_subscriber_t* v) { return z_subscriber_take(this_, v); } inline void z_take(z_owned_queryable_t* this_, z_moved_queryable_t* v) { return z_queryable_take(this_, v); } +inline void z_take(z_owned_liveliness_token_t* this_, z_moved_liveliness_token_t* v) { + return z_liveliness_token_take(this_, v); +} inline void z_take(z_owned_reply_t* this_, z_moved_reply_t* v) { z_reply_take(this_, v); } inline void z_take(z_owned_hello_t* this_, z_moved_hello_t* v) { z_hello_take(this_, v); } inline void z_take(z_owned_string_t* this_, z_moved_string_t* v) { z_string_take(this_, v); } @@ -803,6 +820,14 @@ struct z_owned_to_loaned_type_t { typedef z_loaned_queryable_t type; }; template <> +struct z_loaned_to_owned_type_t { + typedef z_owned_liveliness_token_t type; +}; +template <> +struct z_owned_to_loaned_type_t { + typedef z_loaned_liveliness_token_t type; +}; +template <> struct z_loaned_to_owned_type_t { typedef z_owned_reply_t type; }; diff --git a/include/zenoh-pico/api/primitives.h b/include/zenoh-pico/api/primitives.h index 79a01f8c8..0ad1a5d6a 100644 --- a/include/zenoh-pico/api/primitives.h +++ b/include/zenoh-pico/api/primitives.h @@ -982,8 +982,8 @@ const z_loaned_keyexpr_t *z_query_keyexpr(const z_loaned_query_t *query); * Return: * ``0`` in case of success, negative error code otherwise */ -z_result_t z_closure_sample(z_owned_closure_sample_t *closure, z_sample_handler_t call, z_dropper_handler_t drop, - void *context); +z_result_t z_closure_sample(z_owned_closure_sample_t *closure, z_closure_sample_callback_t call, + z_closure_drop_callback_t drop, void *context); /** * Calls a sample closure. @@ -1007,8 +1007,8 @@ void z_closure_sample_call(const z_loaned_closure_sample_t *closure, z_loaned_sa * Return: * ``0`` in case of success, negative error code otherwise */ -z_result_t z_closure_query(z_owned_closure_query_t *closure, z_query_handler_t call, z_dropper_handler_t drop, - void *context); +z_result_t z_closure_query(z_owned_closure_query_t *closure, z_closure_query_callback_t call, + z_closure_drop_callback_t drop, void *context); /** * Calls a query closure. @@ -1032,8 +1032,8 @@ void z_closure_query_call(const z_loaned_closure_query_t *closure, z_loaned_quer * Return: * ``0`` in case of success, negative error code otherwise */ -z_result_t z_closure_reply(z_owned_closure_reply_t *closure, z_reply_handler_t call, z_dropper_handler_t drop, - void *context); +z_result_t z_closure_reply(z_owned_closure_reply_t *closure, z_closure_reply_callback_t call, + z_closure_drop_callback_t drop, void *context); /** * Calls a reply closure. @@ -1057,8 +1057,8 @@ void z_closure_reply_call(const z_loaned_closure_reply_t *closure, z_loaned_repl * Return: * ``0`` in case of success, negative error code otherwise */ -z_result_t z_closure_hello(z_owned_closure_hello_t *closure, z_loaned_hello_handler_t call, z_dropper_handler_t drop, - void *context); +z_result_t z_closure_hello(z_owned_closure_hello_t *closure, z_closure_hello_callback_t call, + z_closure_drop_callback_t drop, void *context); /** * Calls a hello closure. @@ -1074,7 +1074,7 @@ void z_closure_hello_call(const z_loaned_closure_hello_t *closure, z_loaned_hell * It consists on a structure that contains all the elements for stateful, memory-leak-free callbacks. * * Parameters: - * closure: Pointer to an uninitialized :c:type:`z_owned_closure_zit_t`. + * closure: Pointer to an uninitialized :c:type:`z_owned_closure_zid_t`. * call: Pointer to the callback function. ``context`` will be passed as its last argument. * drop: Pointer to the function that will free the callback state. ``context`` will be passed as its last argument. * context: Pointer to an arbitrary state. @@ -1082,7 +1082,8 @@ void z_closure_hello_call(const z_loaned_closure_hello_t *closure, z_loaned_hell * Return: * ``0`` in case of success, negative error code otherwise */ -z_result_t z_closure_zid(z_owned_closure_zid_t *closure, z_zid_handler_t call, z_dropper_handler_t drop, void *context); +z_result_t z_closure_zid(z_owned_closure_zid_t *closure, z_closure_zid_callback_t call, z_closure_drop_callback_t drop, + void *context); /** * Calls a zid closure. @@ -1706,6 +1707,7 @@ const z_loaned_sample_t *z_reply_ok(const z_loaned_reply_t *reply); */ const z_loaned_reply_err_t *z_reply_err(const z_loaned_reply_t *reply); +#ifdef Z_FEATURE_UNSTABLE_API /** * Gets the id of the zenoh instance that answered this Reply. * @@ -1716,7 +1718,9 @@ const z_loaned_reply_err_t *z_reply_err(const z_loaned_reply_t *reply); * `true` if id is present */ bool z_reply_replier_id(const z_loaned_reply_t *reply, z_id_t *out_id); -#endif +#endif // Z_FEATURE_UNSTABLE_API + +#endif // Z_FEATURE_QUERY == 1 #if Z_FEATURE_QUERYABLE == 1 /** diff --git a/include/zenoh-pico/api/serialization.h b/include/zenoh-pico/api/serialization.h index d6e579557..d8ff0d648 100644 --- a/include/zenoh-pico/api/serialization.h +++ b/include/zenoh-pico/api/serialization.h @@ -458,6 +458,7 @@ z_result_t ze_deserializer_deserialize_slice(ze_deserializer_t *deserializer, z_ /** * Serializes a null-terminated string and writes it into an underlying :c:type:`z_owned_bytes_t`. + * The string should be a valid UTF-8. * * Parameters: * serializer: A serializer instance. @@ -468,8 +469,23 @@ z_result_t ze_deserializer_deserialize_slice(ze_deserializer_t *deserializer, z_ */ z_result_t ze_serializer_serialize_str(ze_loaned_serializer_t *serializer, const char *val); +/** + * Serializes a substring and writes it into an underlying :c:type:`z_owned_bytes_t`. + * The substring should be a valid UTF-8. + * + * Parameters: + * serializer: A serializer instance. + * start: Pointer to the start of the substring to serialize. + * len: Length of the substring to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serializer_serialize_substr(ze_loaned_serializer_t *serializer, const char *start, size_t len); + /** * Serializes a string and writes it into an underlying :c:type:`z_owned_bytes_t`. + * The string should be a valid UTF-8. * * Parameters: * serializer: A serializer instance. @@ -523,7 +539,7 @@ z_result_t ze_deserializer_deserialize_sequence_length(ze_deserializer_t *deseri * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized data. - * data: Pointer to the data to serialize. Ownership is transferred to the `bytes`. + * data: Pointer to the data to serialize. * len: Number of bytes to serialize. * * Return: @@ -534,6 +550,7 @@ z_result_t ze_serialize_buf(z_owned_bytes_t *bytes, const uint8_t *data, size_t /** * Serializes a string into a :c:type:`z_owned_bytes_t`. * + * The string should be a valid UTF-8. * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized string. * s: Pointer to the string to serialize. @@ -545,16 +562,31 @@ z_result_t ze_serialize_string(z_owned_bytes_t *bytes, const z_loaned_string_t * /** * Serializes a null-terminated string into a :c:type:`z_owned_bytes_t`. + * The string should be a valid UTF-8. * * Parameters: * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized string. - * value: Pointer to the string to serialize. Ownership is transferred to the `bytes`. + * value: Pointer to the string to serialize. * * Return: * ``0`` if serialization is successful, ``negative value`` otherwise. */ z_result_t ze_serialize_str(z_owned_bytes_t *bytes, const char *value); +/** + * Serializes a substring into a :c:type:`z_owned_bytes_t`. + * The substring should be a valid UTF-8. + * + * Parameters: + * bytes: An uninitialized :c:type:`z_owned_bytes_t` to contain the serialized string. + * start: Pointer to the the start of string to serialize. + * len: Length of the substring to serialize. + * + * Return: + * ``0`` if serialization is successful, ``negative value`` otherwise. + */ +z_result_t ze_serialize_substr(z_owned_bytes_t *bytes, const char *start, size_t len); + /** * Serializes a slice into a :c:type:`z_owned_bytes_t`. * diff --git a/include/zenoh-pico/api/types.h b/include/zenoh-pico/api/types.h index 53010ece7..c5a76dbd8 100644 --- a/include/zenoh-pico/api/types.h +++ b/include/zenoh-pico/api/types.h @@ -34,13 +34,6 @@ extern "C" { #endif -/** - * Represents a variable-length encoding unsigned integer. - * - * It is equivalent to the size of a ``size_t``. - */ -typedef _z_zint_t z_zint_t; - /** * Represents a Zenoh ID. * @@ -417,13 +410,13 @@ _Z_OWNED_TYPE_VALUE(_z_reply_t, reply) */ _Z_OWNED_TYPE_VALUE(_z_string_svec_t, string_array) -typedef void (*z_dropper_handler_t)(void *arg); -typedef _z_sample_handler_t z_sample_handler_t; +typedef void (*z_closure_drop_callback_t)(void *arg); +typedef _z_closure_sample_callback_t z_closure_sample_callback_t; typedef struct { void *context; - z_sample_handler_t call; - z_dropper_handler_t drop; + z_closure_sample_callback_t call; + z_closure_drop_callback_t drop; } _z_closure_sample_t; /** @@ -431,12 +424,12 @@ typedef struct { */ _Z_OWNED_TYPE_VALUE(_z_closure_sample_t, closure_sample) -typedef _z_query_handler_t z_query_handler_t; +typedef _z_closure_query_callback_t z_closure_query_callback_t; typedef struct { void *context; - z_query_handler_t call; - z_dropper_handler_t drop; + z_closure_query_callback_t call; + z_closure_drop_callback_t drop; } _z_closure_query_t; /** @@ -444,12 +437,12 @@ typedef struct { */ _Z_OWNED_TYPE_VALUE(_z_closure_query_t, closure_query) -typedef _z_reply_handler_t z_reply_handler_t; +typedef _z_closure_reply_callback_t z_closure_reply_callback_t; typedef struct { void *context; - z_reply_handler_t call; - z_dropper_handler_t drop; + z_closure_reply_callback_t call; + z_closure_drop_callback_t drop; } _z_closure_reply_t; /** @@ -457,12 +450,12 @@ typedef struct { */ _Z_OWNED_TYPE_VALUE(_z_closure_reply_t, closure_reply) -typedef void (*z_loaned_hello_handler_t)(z_loaned_hello_t *hello, void *arg); +typedef void (*z_closure_hello_callback_t)(z_loaned_hello_t *hello, void *arg); typedef struct { void *context; - z_loaned_hello_handler_t call; - z_dropper_handler_t drop; + z_closure_hello_callback_t call; + z_closure_drop_callback_t drop; } _z_closure_hello_t; /** @@ -470,12 +463,12 @@ typedef struct { */ _Z_OWNED_TYPE_VALUE(_z_closure_hello_t, closure_hello) -typedef void (*z_zid_handler_t)(const z_id_t *id, void *arg); +typedef void (*z_closure_zid_callback_t)(const z_id_t *id, void *arg); typedef struct { void *context; - z_zid_handler_t call; - z_dropper_handler_t drop; + z_closure_zid_callback_t call; + z_closure_drop_callback_t drop; } _z_closure_zid_t; /** diff --git a/include/zenoh-pico/collections/arc_slice.h b/include/zenoh-pico/collections/arc_slice.h index ce67d2975..7e03c936c 100644 --- a/include/zenoh-pico/collections/arc_slice.h +++ b/include/zenoh-pico/collections/arc_slice.h @@ -24,6 +24,10 @@ #include "slice.h" #include "zenoh-pico/system/platform_common.h" +#ifdef __cplusplus +extern "C" { +#endif + _Z_REFCOUNT_DEFINE(_z_slice, _z_slice) /*-------- ArcSlice --------*/ @@ -52,4 +56,8 @@ z_result_t _z_arc_slice_copy(_z_arc_slice_t* dst, const _z_arc_slice_t* src); z_result_t _z_arc_slice_move(_z_arc_slice_t* dst, _z_arc_slice_t* src); z_result_t _z_arc_slice_drop(_z_arc_slice_t* s); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_ARC_SLICE_H */ diff --git a/include/zenoh-pico/collections/array.h b/include/zenoh-pico/collections/array.h index 0c08d9af2..b5d077433 100644 --- a/include/zenoh-pico/collections/array.h +++ b/include/zenoh-pico/collections/array.h @@ -19,6 +19,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /*------------------ Internal Array Macros ------------------*/ #define _Z_ARRAY_DEFINE(name, type) \ typedef struct { \ @@ -71,4 +75,8 @@ } \ } +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_ARRAY_H */ diff --git a/include/zenoh-pico/collections/bytes.h b/include/zenoh-pico/collections/bytes.h index b662ff613..05ab01e37 100644 --- a/include/zenoh-pico/collections/bytes.h +++ b/include/zenoh-pico/collections/bytes.h @@ -23,6 +23,10 @@ #include "vec.h" #include "zenoh-pico/protocol/iobuf.h" +#ifdef __cplusplus +extern "C" { +#endif + inline size_t _z_arc_slice_size(const _z_arc_slice_t *s) { (void)s; return sizeof(_z_arc_slice_t); @@ -94,4 +98,8 @@ void _z_bytes_writer_clear(_z_bytes_writer_t *writer); void _z_bytes_writer_move(_z_bytes_writer_t *dst, _z_bytes_writer_t *src); size_t _z_bytes_reader_remaining(const _z_bytes_reader_t *reader); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_BYTES_H */ diff --git a/include/zenoh-pico/collections/element.h b/include/zenoh-pico/collections/element.h index ef5178ad1..bd5701187 100644 --- a/include/zenoh-pico/collections/element.h +++ b/include/zenoh-pico/collections/element.h @@ -21,6 +21,10 @@ #include "zenoh-pico/system/platform.h" #include "zenoh-pico/utils/result.h" +#ifdef __cplusplus +extern "C" { +#endif + /*-------- element functions --------*/ typedef size_t (*z_element_size_f)(void *e); typedef void (*z_element_clear_f)(void *e); @@ -74,4 +78,8 @@ static inline void _z_noop_move(void *dst, void *src) { _Z_ELEM_DEFINE(_z_noop, _z_noop_t, _z_noop_size, _z_noop_clear, _z_noop_copy) +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_ELEMENT_H */ diff --git a/include/zenoh-pico/collections/fifo.h b/include/zenoh-pico/collections/fifo.h index 3e36bb509..0f4a887ce 100644 --- a/include/zenoh-pico/collections/fifo.h +++ b/include/zenoh-pico/collections/fifo.h @@ -20,6 +20,10 @@ #include "zenoh-pico/collections/element.h" #include "zenoh-pico/collections/ring.h" +#ifdef __cplusplus +extern "C" { +#endif + /*-------- Fifo Buffer --------*/ typedef struct { _z_ring_t _ring; @@ -60,4 +64,8 @@ void _z_fifo_free(_z_fifo_t **xs, z_element_free_f f_f); static inline void name##_fifo_clear(name##_fifo_t *r) { _z_fifo_clear(r, name##_elem_free); } \ static inline void name##_fifo_free(name##_fifo_t **r) { _z_fifo_free(r, name##_elem_free); } +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_FIFO_H */ diff --git a/include/zenoh-pico/collections/intmap.h b/include/zenoh-pico/collections/intmap.h index c897e2e50..98ea17379 100644 --- a/include/zenoh-pico/collections/intmap.h +++ b/include/zenoh-pico/collections/intmap.h @@ -22,11 +22,15 @@ #include "zenoh-pico/collections/list.h" #include "zenoh-pico/utils/result.h" +#ifdef __cplusplus +extern "C" { +#endif + /*-------- int-void map --------*/ #define _Z_DEFAULT_INT_MAP_CAPACITY 16 /** - * An entry of an hashmap with integer keys. + * An entry of a hashmap with integer keys. * * Members: * size_t key: the hashed key of the value @@ -50,6 +54,17 @@ typedef struct { _z_list_t **_vals; } _z_int_void_map_t; +/** + * An iterator of an hashmap with integer keys. + */ +typedef struct { + _z_int_void_map_entry_t *_entry; + + const _z_int_void_map_t *_map; + size_t _idx; + _z_list_t *_list_ptr; +} _z_int_void_map_iterator_t; + void _z_int_void_map_init(_z_int_void_map_t *map, size_t capacity); _z_int_void_map_t _z_int_void_map_make(size_t capacity); @@ -67,6 +82,11 @@ _z_int_void_map_t _z_int_void_map_clone(const _z_int_void_map_t *src, z_element_ void _z_int_void_map_clear(_z_int_void_map_t *map, z_element_free_f f); void _z_int_void_map_free(_z_int_void_map_t **map, z_element_free_f f); +_z_int_void_map_iterator_t _z_int_void_map_iterator_make(const _z_int_void_map_t *map); +bool _z_int_void_map_iterator_next(_z_int_void_map_iterator_t *iter); +size_t _z_int_void_map_iterator_key(const _z_int_void_map_iterator_t *iter); +void *_z_int_void_map_iterator_value(const _z_int_void_map_iterator_t *iter); + #define _Z_INT_MAP_DEFINE(name, type) \ typedef _z_int_void_map_entry_t name##_intmap_entry_t; \ static inline void name##_intmap_entry_elem_free(void **e) { \ @@ -85,6 +105,7 @@ void _z_int_void_map_free(_z_int_void_map_t **map, z_element_free_f f); return dst; \ } \ typedef _z_int_void_map_t name##_intmap_t; \ + typedef _z_int_void_map_iterator_t name##_intmap_iterator_t; \ static inline void name##_intmap_init(name##_intmap_t *m) { \ _z_int_void_map_init(m, _Z_DEFAULT_INT_MAP_CAPACITY); \ } \ @@ -111,6 +132,22 @@ void _z_int_void_map_free(_z_int_void_map_t **map, z_element_free_f f); } \ static inline void name##_intmap_free(name##_intmap_t **m) { \ _z_int_void_map_free(m, name##_intmap_entry_elem_free); \ + } \ + static inline name##_intmap_iterator_t name##_intmap_iterator_make(const name##_intmap_t *m) { \ + return _z_int_void_map_iterator_make(m); \ + } \ + static inline bool name##_intmap_iterator_next(name##_intmap_iterator_t *iter) { \ + return _z_int_void_map_iterator_next(iter); \ + } \ + static inline size_t name##_intmap_iterator_key(const name##_intmap_iterator_t *iter) { \ + return _z_int_void_map_iterator_key(iter); \ + } \ + static inline type *name##_intmap_iterator_value(const name##_intmap_iterator_t *iter) { \ + return (type *)_z_int_void_map_iterator_value(iter); \ } +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_INTMAP_H */ diff --git a/include/zenoh-pico/collections/lifo.h b/include/zenoh-pico/collections/lifo.h index cf696b994..b6142b05a 100644 --- a/include/zenoh-pico/collections/lifo.h +++ b/include/zenoh-pico/collections/lifo.h @@ -19,6 +19,10 @@ #include "zenoh-pico/collections/element.h" +#ifdef __cplusplus +extern "C" { +#endif + /*-------- Ring Buffer --------*/ typedef struct { void **_val; @@ -61,4 +65,8 @@ void _z_lifo_free(_z_lifo_t **xs, z_element_free_f f_f); static inline void name##_lifo_clear(name##_lifo_t *r) { _z_lifo_clear(r, name##_elem_free); } \ static inline void name##_lifo_free(name##_lifo_t **r) { _z_lifo_free(r, name##_elem_free); } +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_LIFO_H */ diff --git a/include/zenoh-pico/collections/list.h b/include/zenoh-pico/collections/list.h index a779706f0..590d0f32d 100644 --- a/include/zenoh-pico/collections/list.h +++ b/include/zenoh-pico/collections/list.h @@ -20,6 +20,10 @@ #include "zenoh-pico/collections/element.h" +#ifdef __cplusplus +extern "C" { +#endif + /*-------- Single-linked List --------*/ /** * A single-linked list. @@ -72,4 +76,8 @@ void _z_list_free(_z_list_t **xs, z_element_free_f f_f); static inline name##_list_t *name##_list_clone(name##_list_t *l) { return _z_list_clone(l, name##_elem_clone); } \ static inline void name##_list_free(name##_list_t **l) { _z_list_free(l, name##_elem_free); } +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_LIST_H */ diff --git a/include/zenoh-pico/collections/ring.h b/include/zenoh-pico/collections/ring.h index de8743e58..d1e26ec57 100644 --- a/include/zenoh-pico/collections/ring.h +++ b/include/zenoh-pico/collections/ring.h @@ -19,6 +19,10 @@ #include "zenoh-pico/collections/element.h" +#ifdef __cplusplus +extern "C" { +#endif + /*-------- Ring Buffer --------*/ typedef struct { void **_val; @@ -65,4 +69,8 @@ void _z_ring_free(_z_ring_t **xs, z_element_free_f f_f); static inline void name##_ring_clear(name##_ring_t *r) { _z_ring_clear(r, name##_elem_free); } \ static inline void name##_ring_free(name##_ring_t **r) { _z_ring_free(r, name##_elem_free); } +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_RING_H */ diff --git a/include/zenoh-pico/collections/slice.h b/include/zenoh-pico/collections/slice.h index 8027f6b1c..c57af6ff9 100644 --- a/include/zenoh-pico/collections/slice.h +++ b/include/zenoh-pico/collections/slice.h @@ -21,6 +21,10 @@ #include "zenoh-pico/utils/result.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { void (*deleter)(void *data, void *context); void *context; @@ -67,4 +71,8 @@ void _z_slice_clear(_z_slice_t *bs); void _z_slice_free(_z_slice_t **bs); bool _z_slice_is_alloced(const _z_slice_t *s); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_SLICE_H */ diff --git a/include/zenoh-pico/collections/string.h b/include/zenoh-pico/collections/string.h index f2ebd15ac..a54ac68dd 100644 --- a/include/zenoh-pico/collections/string.h +++ b/include/zenoh-pico/collections/string.h @@ -21,6 +21,10 @@ #include "zenoh-pico/collections/slice.h" #include "zenoh-pico/collections/vec.h" +#ifdef __cplusplus +extern "C" { +#endif + /*-------- str --------*/ typedef char *_z_str_t; @@ -90,9 +94,11 @@ void _z_string_clear(_z_string_t *s); void _z_string_free(_z_string_t **s); void _z_string_reset(_z_string_t *s); bool _z_string_equals(const _z_string_t *left, const _z_string_t *right); -_z_string_t _z_string_convert_bytes(const _z_slice_t *bs); +_z_string_t _z_string_convert_bytes_le(const _z_slice_t *bs); _z_string_t _z_string_preallocate(const size_t len); +char *_z_str_from_string_clone(const _z_string_t *str); + _Z_ELEM_DEFINE(_z_string, _z_string_t, _z_string_len, _z_string_clear, _z_string_copy) static inline void _z_string_elem_move(void *dst, void *src) { _z_string_move((_z_string_t *)dst, (_z_string_t *)src); } @@ -100,4 +106,8 @@ _Z_SVEC_DEFINE(_z_string, _z_string_t) _Z_LIST_DEFINE(_z_string, _z_string_t) _Z_INT_MAP_DEFINE(_z_string, _z_string_t) +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_STRING_H */ diff --git a/include/zenoh-pico/collections/vec.h b/include/zenoh-pico/collections/vec.h index d1c12ec6b..d89acd93c 100644 --- a/include/zenoh-pico/collections/vec.h +++ b/include/zenoh-pico/collections/vec.h @@ -19,6 +19,10 @@ #include "zenoh-pico/collections/element.h" +#ifdef __cplusplus +extern "C" { +#endif + /*-------- Dynamically allocated vector --------*/ /** * A dynamically allocated vector. Elements are stored as pointers. @@ -114,4 +118,8 @@ void _z_svec_release(_z_svec_t *v); static inline void name##_svec_clear(name##_svec_t *v) { _z_svec_clear(v, name##_elem_clear, sizeof(type)); } \ static inline void name##_svec_free(name##_svec_t **v) { _z_svec_free(v, name##_elem_clear, sizeof(type)); } +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_COLLECTIONS_VECTOR_H */ diff --git a/include/zenoh-pico/config.h b/include/zenoh-pico/config.h index b3c5d3ec1..1578b1f50 100644 --- a/include/zenoh-pico/config.h +++ b/include/zenoh-pico/config.h @@ -27,6 +27,7 @@ #define Z_FEATURE_SUBSCRIPTION 1 #define Z_FEATURE_QUERY 1 #define Z_FEATURE_QUERYABLE 1 +#define Z_FEATURE_LIVELINESS 0 #define Z_FEATURE_RAWETH_TRANSPORT 0 #define Z_FEATURE_INTEREST 1 #define Z_FEATURE_DYNAMIC_MEMORY_ALLOCATION 0 diff --git a/include/zenoh-pico/config.h.in b/include/zenoh-pico/config.h.in index 40941d9fa..175fc8fdf 100644 --- a/include/zenoh-pico/config.h.in +++ b/include/zenoh-pico/config.h.in @@ -27,6 +27,7 @@ #define Z_FEATURE_SUBSCRIPTION @Z_FEATURE_SUBSCRIPTION@ #define Z_FEATURE_QUERY @Z_FEATURE_QUERY@ #define Z_FEATURE_QUERYABLE @Z_FEATURE_QUERYABLE@ +#define Z_FEATURE_LIVELINESS @Z_FEATURE_LIVELINESS@ #define Z_FEATURE_RAWETH_TRANSPORT @Z_FEATURE_RAWETH_TRANSPORT@ #define Z_FEATURE_INTEREST @Z_FEATURE_INTEREST@ #define Z_FEATURE_DYNAMIC_MEMORY_ALLOCATION @Z_FEATURE_DYNAMIC_MEMORY_ALLOCATION@ diff --git a/include/zenoh-pico/link/config/bt.h b/include/zenoh-pico/link/config/bt.h index 630b9ae41..fca0740d1 100644 --- a/include/zenoh-pico/link/config/bt.h +++ b/include/zenoh-pico/link/config/bt.h @@ -19,6 +19,10 @@ #include "zenoh-pico/config.h" #include "zenoh-pico/system/platform.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_LINK_BLUETOOTH == 1 #define BT_CONFIG_ARGC 3 @@ -50,4 +54,8 @@ z_result_t _z_bt_config_from_str(_z_str_intmap_t *strint, const char *s); z_result_t _z_bt_config_from_strn(_z_str_intmap_t *strint, const char *s, size_t n); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_LINK_CONFIG_BT_H */ diff --git a/include/zenoh-pico/link/config/raweth.h b/include/zenoh-pico/link/config/raweth.h index c30cc6403..65700aaba 100644 --- a/include/zenoh-pico/link/config/raweth.h +++ b/include/zenoh-pico/link/config/raweth.h @@ -20,6 +20,10 @@ #include "zenoh-pico/config.h" #include "zenoh-pico/link/link.h" +#ifdef __cplusplus +extern "C" { +#endif + #define RAWETH_SCHEMA "reth" z_result_t _z_endpoint_raweth_valid(_z_endpoint_t *endpoint); @@ -29,4 +33,8 @@ char *_z_raweth_config_to_str(const _z_str_intmap_t *s); z_result_t _z_raweth_config_from_strn(_z_str_intmap_t *strint, const char *s, size_t n); z_result_t _z_raweth_config_from_str(_z_str_intmap_t *strint, const char *s); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_LINK_CONFIG_RAWETH_H */ diff --git a/include/zenoh-pico/link/config/serial.h b/include/zenoh-pico/link/config/serial.h index 6180d0a59..3b9f6530a 100644 --- a/include/zenoh-pico/link/config/serial.h +++ b/include/zenoh-pico/link/config/serial.h @@ -20,6 +20,10 @@ #include "zenoh-pico/config.h" #include "zenoh-pico/system/platform.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_LINK_SERIAL == 1 #define SERIAL_CONFIG_ARGC 1 @@ -66,4 +70,8 @@ z_result_t _z_serial_config_from_str(_z_str_intmap_t *strint, const char *s); z_result_t _z_serial_config_from_strn(_z_str_intmap_t *strint, const char *s, size_t n); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_LINK_CONFIG_SERIAL_H */ diff --git a/include/zenoh-pico/link/config/tcp.h b/include/zenoh-pico/link/config/tcp.h index 51792c8ac..c521a1751 100644 --- a/include/zenoh-pico/link/config/tcp.h +++ b/include/zenoh-pico/link/config/tcp.h @@ -19,6 +19,10 @@ #include "zenoh-pico/collections/string.h" #include "zenoh-pico/config.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_LINK_TCP == 1 #define TCP_CONFIG_ARGC 1 @@ -40,4 +44,8 @@ z_result_t _z_tcp_config_from_str(_z_str_intmap_t *strint, const char *s); z_result_t _z_tcp_config_from_strn(_z_str_intmap_t *strint, const char *s, size_t n); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_LINK_CONFIG_TCP_H */ diff --git a/include/zenoh-pico/link/config/udp.h b/include/zenoh-pico/link/config/udp.h index 8af8b5d47..87cd6655e 100644 --- a/include/zenoh-pico/link/config/udp.h +++ b/include/zenoh-pico/link/config/udp.h @@ -18,6 +18,10 @@ #include "zenoh-pico/collections/intmap.h" #include "zenoh-pico/collections/string.h" +#ifdef __cplusplus +extern "C" { +#endif + #define UDP_CONFIG_ARGC 3 #define UDP_CONFIG_IFACE_KEY 0x01 @@ -48,4 +52,8 @@ z_result_t _z_udp_config_from_str(_z_str_intmap_t *strint, const char *s); z_result_t _z_udp_config_from_strn(_z_str_intmap_t *strint, const char *s, size_t n); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_LINK_CONFIG_UDP_H */ diff --git a/include/zenoh-pico/link/config/ws.h b/include/zenoh-pico/link/config/ws.h index e9c3e6be6..a845807c5 100644 --- a/include/zenoh-pico/link/config/ws.h +++ b/include/zenoh-pico/link/config/ws.h @@ -19,6 +19,10 @@ #include "zenoh-pico/collections/string.h" #include "zenoh-pico/config.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_LINK_WS == 1 #define WS_CONFIG_TOUT_KEY 0x01 @@ -39,4 +43,8 @@ z_result_t _z_ws_config_from_str(_z_str_intmap_t *strint, const char *s); z_result_t _z_ws_config_from_strn(_z_str_intmap_t *strint, const char *s, size_t n); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_LINK_CONFIG_WS_H */ diff --git a/include/zenoh-pico/link/endpoint.h b/include/zenoh-pico/link/endpoint.h index 4868f4d44..d6b83e30a 100644 --- a/include/zenoh-pico/link/endpoint.h +++ b/include/zenoh-pico/link/endpoint.h @@ -21,6 +21,10 @@ #include "zenoh-pico/collections/string.h" #include "zenoh-pico/utils/result.h" +#ifdef __cplusplus +extern "C" { +#endif + /*------------------ Locator ------------------*/ #if Z_FEATURE_LINK_TCP == 1 #define TCP_SCHEMA "tcp" @@ -72,4 +76,8 @@ z_result_t _z_endpoint_from_string(_z_endpoint_t *ep, _z_string_t *s); void _z_endpoint_clear(_z_endpoint_t *ep); void _z_endpoint_free(_z_endpoint_t **ep); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_LINK_ENDPOINT_H */ diff --git a/include/zenoh-pico/link/link.h b/include/zenoh-pico/link/link.h index 6356af3cf..522721fe8 100644 --- a/include/zenoh-pico/link/link.h +++ b/include/zenoh-pico/link/link.h @@ -46,6 +46,10 @@ #include "zenoh-pico/utils/result.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * Link transport capability enum. * @@ -144,4 +148,8 @@ z_result_t _z_link_send_wbuf(const _z_link_t *zl, const _z_wbuf_t *wbf); size_t _z_link_recv_zbuf(const _z_link_t *zl, _z_zbuf_t *zbf, _z_slice_t *addr); size_t _z_link_recv_exact_zbuf(const _z_link_t *zl, _z_zbuf_t *zbf, size_t len, _z_slice_t *addr); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_LINK_H */ diff --git a/include/zenoh-pico/link/manager.h b/include/zenoh-pico/link/manager.h index e0aba1f93..7a962e68f 100644 --- a/include/zenoh-pico/link/manager.h +++ b/include/zenoh-pico/link/manager.h @@ -19,6 +19,10 @@ #include "zenoh-pico/config.h" #include "zenoh-pico/link/link.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_LINK_TCP == 1 z_result_t _z_endpoint_tcp_valid(_z_endpoint_t *ep); z_result_t _z_new_link_tcp(_z_link_t *zl, _z_endpoint_t *ep); @@ -44,4 +48,8 @@ z_result_t _z_endpoint_ws_valid(_z_endpoint_t *ep); z_result_t _z_new_link_ws(_z_link_t *zl, _z_endpoint_t *ep); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_LINK_MANAGER_H */ diff --git a/include/zenoh-pico/net/config.h b/include/zenoh-pico/net/config.h index fabc7415f..4977f1b5c 100644 --- a/include/zenoh-pico/net/config.h +++ b/include/zenoh-pico/net/config.h @@ -18,6 +18,10 @@ #include "zenoh-pico/collections/string.h" #include "zenoh-pico/utils/config.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * Create an empty set of properties for zenoh-net session configuration. * @@ -50,4 +54,8 @@ z_result_t _z_config_default(_z_config_t *config); */ z_result_t _z_config_client(_z_config_t *config, const char *locator); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_CONFIG_NETAPI_H */ diff --git a/include/zenoh-pico/net/encoding.h b/include/zenoh-pico/net/encoding.h index 88ac5f0d1..0b35ce338 100644 --- a/include/zenoh-pico/net/encoding.h +++ b/include/zenoh-pico/net/encoding.h @@ -17,6 +17,10 @@ #include "zenoh-pico/api/constants.h" #include "zenoh-pico/collections/string.h" +#ifdef __cplusplus +extern "C" { +#endif + #define _Z_ENCODING_ID_DEFAULT 0 /** @@ -36,4 +40,8 @@ z_result_t _z_encoding_copy(_z_encoding_t *dst, const _z_encoding_t *src); void _z_encoding_move(_z_encoding_t *dst, _z_encoding_t *src); _z_encoding_t _z_encoding_steal(_z_encoding_t *val); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_ENCODING_NETAPI_H */ diff --git a/include/zenoh-pico/net/filtering.h b/include/zenoh-pico/net/filtering.h index 18023b66d..14461a322 100644 --- a/include/zenoh-pico/net/filtering.h +++ b/include/zenoh-pico/net/filtering.h @@ -20,6 +20,10 @@ #include "zenoh-pico/net/session.h" #include "zenoh-pico/protocol/core.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef enum { WRITE_FILTER_INIT = 0, WRITE_FILTER_ACTIVE = 1, @@ -45,4 +49,8 @@ z_result_t _z_write_filter_create(_z_publisher_t *pub); z_result_t _z_write_filter_destroy(_z_publisher_t *pub); bool _z_write_filter_active(const _z_publisher_t *pub); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_FILTERING_NETAPI_H */ diff --git a/include/zenoh-pico/net/liveliness.h b/include/zenoh-pico/net/liveliness.h new file mode 100644 index 000000000..2f1be9e9d --- /dev/null +++ b/include/zenoh-pico/net/liveliness.h @@ -0,0 +1,84 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, + +#ifndef INCLUDE_ZENOH_PICO_NET_LIVELINESS_H +#define INCLUDE_ZENOH_PICO_NET_LIVELINESS_H + +#include "zenoh-pico/api/liveliness.h" +#include "zenoh-pico/net/session.h" +#include "zenoh-pico/net/subscribe.h" +#include "zenoh-pico/protocol/core.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if Z_FEATURE_LIVELINESS == 1 + +z_result_t _z_declare_liveliness_token(const _z_session_rc_t *zn, _z_liveliness_token_t *ret_token, + _z_keyexpr_t keyexpr); +z_result_t _z_undeclare_liveliness_token(_z_liveliness_token_t *token); + +#if Z_FEATURE_SUBSCRIPTION == 1 +/** + * Declare a :c:type:`_z_subscriber_t` for the given liveliness key. + * + * Parameters: + * zn: The zenoh-net session. The caller keeps its ownership. + * keyexpr: The resource key to subscribe. The callee gets the ownership of any allocated value. + * callback: The callback function that will be called each time a matching liveliness token changed. + * history: Enable current interest to return history tokens. + * arg: A pointer that will be passed to the **callback** on each call. + * + * Returns: + * The created :c:type:`_z_subscriber_t` (in null state if the declaration failed). + */ +_z_subscriber_t _z_declare_liveliness_subscriber(const _z_session_rc_t *zn, _z_keyexpr_t keyexpr, + _z_closure_sample_callback_t callback, _z_drop_handler_t dropper, + bool history, void *arg); + +/** + * Undeclare a liveliness :c:type:`_z_subscriber_t`. + * + * Parameters: + * sub: The :c:type:`_z_subscriber_t` to undeclare. The callee releases the + * subscriber upon successful return. + * Returns: + * 0 if success, or a negative value identifying the error. + */ +z_result_t _z_undeclare_liveliness_subscriber(_z_subscriber_t *sub); +#endif // Z_FEATURE_SUBSCRIPTION == 1 + +#if Z_FEATURE_QUERY == 1 +/** + * Query liveliness token state. + * + * Parameters: + * zn: The zenoh-net session. The caller keeps its ownership. + * keyexpr: The resource key to liveliness token. + * callback: The callback function that will be called on reception of replies for this query. + * dropper: The callback function that will be called on upon completion of the callback. + * arg: A pointer that will be passed to the **callback** on each call. + * timeout_ms: The timeout value of this query. + */ +z_result_t _z_liveliness_query(_z_session_t *zn, _z_keyexpr_t keyexpr, _z_closure_reply_callback_t callback, + _z_drop_handler_t dropper, void *arg, uint64_t timeout_ms); +#endif // Z_FEATURE_QUERY == 1 + +#endif // Z_FEATURE_LIVELINESS == 1 + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_ZENOH_PICO_NET_LIVELINESS_H */ diff --git a/include/zenoh-pico/net/logger.h b/include/zenoh-pico/net/logger.h index 73a4bede1..b9bbede1a 100644 --- a/include/zenoh-pico/net/logger.h +++ b/include/zenoh-pico/net/logger.h @@ -15,9 +15,17 @@ #ifndef ZENOH_PICO_LOGGER_NETAPI_H #define ZENOH_PICO_LOGGER_NETAPI_H +#ifdef __cplusplus +extern "C" { +#endif + /** * Initialise the zenoh runtime logger */ void _z_init_logger(void); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_LOGGER_NETAPI_H */ diff --git a/include/zenoh-pico/net/primitives.h b/include/zenoh-pico/net/primitives.h index f5a27034a..b53a8f4e4 100644 --- a/include/zenoh-pico/net/primitives.h +++ b/include/zenoh-pico/net/primitives.h @@ -24,7 +24,10 @@ #include "zenoh-pico/net/session.h" #include "zenoh-pico/net/subscribe.h" #include "zenoh-pico/protocol/core.h" -#include "zenoh-pico/utils/config.h" + +#ifdef __cplusplus +extern "C" { +#endif /*------------------ Discovery ------------------*/ @@ -38,7 +41,7 @@ * timeout: The time that should be spent scouting before returning the results. */ void _z_scout(const z_what_t what, const _z_id_t zid, _z_string_t *locator, const uint32_t timeout, - _z_hello_handler_t callback, void *arg_call, _z_drop_handler_t dropper, void *arg_drop); + _z_closure_hello_callback_t callback, void *arg_call, _z_drop_handler_t dropper, void *arg_drop); /*------------------ Declarations ------------------*/ @@ -72,6 +75,18 @@ uint16_t _z_declare_resource(_z_session_t *zn, _z_keyexpr_t keyexpr); */ z_result_t _z_undeclare_resource(_z_session_t *zn, uint16_t rid); +/** + * Declare keyexpr if it is necessary and allowed. + * Returns updated keyexpr. + * + * Parameters: + * zn: The zenoh-net session. The caller keeps its ownership. + * keyexpr: The resource key to declare. + * Returns: + * Updated keyexpr. + */ +_z_keyexpr_t _z_update_keyexpr_to_declared(_z_session_t *zs, _z_keyexpr_t keyexpr); + #if Z_FEATURE_PUBLICATION == 1 /** * Declare a :c:type:`_z_publisher_t` for the given resource key. @@ -144,8 +159,8 @@ z_result_t _z_write(_z_session_t *zn, const _z_keyexpr_t keyexpr, _z_bytes_t pay * Returns: * The created :c:type:`_z_subscriber_t` (in null state if the declaration failed). */ -_z_subscriber_t _z_declare_subscriber(const _z_session_rc_t *zn, _z_keyexpr_t keyexpr, _z_sample_handler_t callback, - _z_drop_handler_t dropper, void *arg); +_z_subscriber_t _z_declare_subscriber(const _z_session_rc_t *zn, _z_keyexpr_t keyexpr, + _z_closure_sample_callback_t callback, _z_drop_handler_t dropper, void *arg); /** * Undeclare a :c:type:`_z_subscriber_t`. @@ -175,7 +190,7 @@ z_result_t _z_undeclare_subscriber(_z_subscriber_t *sub); * The created :c:type:`_z_queryable_t` (in null state if the declaration failed).. */ _z_queryable_t _z_declare_queryable(const _z_session_rc_t *zn, _z_keyexpr_t keyexpr, bool complete, - _z_query_handler_t callback, _z_drop_handler_t dropper, void *arg); + _z_closure_query_callback_t callback, _z_drop_handler_t dropper, void *arg); /** * Undeclare a :c:type:`_z_queryable_t`. @@ -245,9 +260,10 @@ z_result_t _z_send_reply_err(const _z_query_t *query, const _z_session_rc_t *zsr * */ z_result_t _z_query(_z_session_t *zn, _z_keyexpr_t keyexpr, const char *parameters, const z_query_target_t target, - const z_consolidation_mode_t consolidation, const _z_value_t value, _z_reply_handler_t callback, - _z_drop_handler_t dropper, void *arg, uint64_t timeout_ms, const _z_bytes_t attachment, - z_congestion_control_t cong_ctrl, z_priority_t priority, bool is_express); + const z_consolidation_mode_t consolidation, const _z_value_t value, + _z_closure_reply_callback_t callback, _z_drop_handler_t dropper, void *arg, uint64_t timeout_ms, + const _z_bytes_t attachment, z_congestion_control_t cong_ctrl, z_priority_t priority, + bool is_express); #endif #if Z_FEATURE_INTEREST == 1 @@ -256,4 +272,8 @@ uint32_t _z_add_interest(_z_session_t *zn, _z_keyexpr_t keyexpr, _z_interest_han z_result_t _z_remove_interest(_z_session_t *zn, uint32_t interest_id); #endif +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_NET_PRIMITIVES_H */ diff --git a/include/zenoh-pico/net/publish.h b/include/zenoh-pico/net/publish.h index 21a8b500f..2f29b0b05 100644 --- a/include/zenoh-pico/net/publish.h +++ b/include/zenoh-pico/net/publish.h @@ -19,6 +19,10 @@ #include "zenoh-pico/net/session.h" #include "zenoh-pico/protocol/core.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * Return type when declaring a publisher. */ @@ -43,4 +47,8 @@ bool _z_publisher_check(const _z_publisher_t *publisher); _z_publisher_t _z_publisher_null(void); #endif +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_NET_PUBLISH_H */ diff --git a/include/zenoh-pico/net/query.h b/include/zenoh-pico/net/query.h index 5e57c1eee..ed2c7579c 100644 --- a/include/zenoh-pico/net/query.h +++ b/include/zenoh-pico/net/query.h @@ -21,6 +21,10 @@ #include "zenoh-pico/net/session.h" #include "zenoh-pico/protocol/core.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * The query to be answered by a queryable. */ @@ -58,4 +62,8 @@ _z_queryable_t _z_queryable_null(void); bool _z_queryable_check(const _z_queryable_t *queryable); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_QUERY_NETAPI_H */ diff --git a/include/zenoh-pico/net/reply.h b/include/zenoh-pico/net/reply.h index 14ef1b232..df2a2742e 100644 --- a/include/zenoh-pico/net/reply.h +++ b/include/zenoh-pico/net/reply.h @@ -23,6 +23,10 @@ #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/session/session.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * Reply tag values. * @@ -97,4 +101,8 @@ void _z_pending_reply_clear(_z_pending_reply_t *res); _Z_ELEM_DEFINE(_z_pending_reply, _z_pending_reply_t, _z_noop_size, _z_pending_reply_clear, _z_noop_copy) _Z_LIST_DEFINE(_z_pending_reply, _z_pending_reply_t) +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_REPLY_NETAPI_H */ diff --git a/include/zenoh-pico/net/sample.h b/include/zenoh-pico/net/sample.h index 9fadfbc76..3133c9706 100644 --- a/include/zenoh-pico/net/sample.h +++ b/include/zenoh-pico/net/sample.h @@ -18,6 +18,10 @@ #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/session/session.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * A zenoh-net data sample. * @@ -58,5 +62,8 @@ _z_sample_t _z_sample_duplicate(const _z_sample_t *src); _z_sample_t _z_sample_create(_z_keyexpr_t *key, const _z_bytes_t payload, const _z_timestamp_t *timestamp, _z_encoding_t *encoding, const z_sample_kind_t kind, const _z_qos_t qos, const _z_bytes_t attachment, z_reliability_t reliability); +#ifdef __cplusplus +} +#endif #endif /* ZENOH_PICO_SAMPLE_NETAPI_H */ diff --git a/include/zenoh-pico/net/session.h b/include/zenoh-pico/net/session.h index 6d7ede3a4..ba43ca095 100644 --- a/include/zenoh-pico/net/session.h +++ b/include/zenoh-pico/net/session.h @@ -21,9 +21,14 @@ #include "zenoh-pico/collections/list.h" #include "zenoh-pico/config.h" #include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/session/liveliness.h" #include "zenoh-pico/session/session.h" #include "zenoh-pico/utils/config.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * A zenoh-net session. */ @@ -50,8 +55,17 @@ typedef struct _z_session_t { // Session subscriptions #if Z_FEATURE_SUBSCRIPTION == 1 - _z_subscription_rc_list_t *_local_subscriptions; - _z_subscription_rc_list_t *_remote_subscriptions; + _z_subscription_rc_list_t *_subscriptions; + _z_subscription_rc_list_t *_liveliness_subscriptions; +#endif + +#if Z_FEATURE_LIVELINESS == 1 + _z_keyexpr_intmap_t _local_tokens; + _z_keyexpr_intmap_t _remote_tokens; +#if Z_FEATURE_QUERY == 1 + uint32_t _liveliness_query_id; + _z_liveliness_pending_query_intmap_t _liveliness_pending_queries; +#endif #endif // Session queryables @@ -199,4 +213,8 @@ z_result_t _zp_start_lease_task(_z_session_t *z, z_task_attr_t *attr); z_result_t _zp_stop_lease_task(_z_session_t *z); #endif // Z_FEATURE_MULTI_THREAD == 1 +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_NET_SESSION_H */ diff --git a/include/zenoh-pico/net/subscribe.h b/include/zenoh-pico/net/subscribe.h index 4cf0cb4d4..ae9fad18f 100644 --- a/include/zenoh-pico/net/subscribe.h +++ b/include/zenoh-pico/net/subscribe.h @@ -20,6 +20,10 @@ #include "zenoh-pico/net/session.h" #include "zenoh-pico/protocol/core.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * Return type when declaring a subscriber. */ @@ -36,4 +40,8 @@ bool _z_subscriber_check(const _z_subscriber_t *subscriber); _z_subscriber_t _z_subscriber_null(void); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SUBSCRIBE_NETAPI_H */ diff --git a/include/zenoh-pico/protocol/codec/core.h b/include/zenoh-pico/protocol/codec/core.h index c86d1b18c..00eec6890 100644 --- a/include/zenoh-pico/protocol/codec/core.h +++ b/include/zenoh-pico/protocol/codec/core.h @@ -24,6 +24,10 @@ #include "zenoh-pico/utils/config.h" #include "zenoh-pico/utils/result.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef z_result_t (*__z_single_byte_reader_t)(uint8_t *, void *context); /*------------------ Internal Zenoh-net Macros ------------------*/ z_result_t _z_consolidation_mode_encode(_z_wbuf_t *wbf, z_consolidation_mode_t en); @@ -84,4 +88,8 @@ z_result_t _z_timestamp_encode(_z_wbuf_t *buf, const _z_timestamp_t *ts); z_result_t _z_timestamp_encode_ext(_z_wbuf_t *buf, const _z_timestamp_t *ts); z_result_t _z_timestamp_decode(_z_timestamp_t *ts, _z_zbuf_t *buf); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_CODEC_CORE_H */ diff --git a/include/zenoh-pico/protocol/codec/declarations.h b/include/zenoh-pico/protocol/codec/declarations.h index 86efb1a64..840061d92 100644 --- a/include/zenoh-pico/protocol/codec/declarations.h +++ b/include/zenoh-pico/protocol/codec/declarations.h @@ -17,6 +17,11 @@ #include "zenoh-pico/protocol/definitions/declarations.h" #include "zenoh-pico/protocol/iobuf.h" + +#ifdef __cplusplus +extern "C" { +#endif + #define _Z_DECL_KEXPR_MID 0 #define _Z_DECL_KEXPR_FLAG_N 0x20 #define _Z_UNDECL_KEXPR_MID 1 @@ -50,4 +55,8 @@ z_result_t _z_undecl_token_decode(_z_undecl_token_t *decl, _z_zbuf_t *zbf, uint8 z_result_t _z_declaration_encode(_z_wbuf_t *wbf, const _z_declaration_t *decl); z_result_t _z_declaration_decode(_z_declaration_t *decl, _z_zbuf_t *zbf); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_CODEC_DECLARATIONS_H */ diff --git a/include/zenoh-pico/protocol/codec/ext.h b/include/zenoh-pico/protocol/codec/ext.h index 7efd7063e..cc339dd0d 100644 --- a/include/zenoh-pico/protocol/codec/ext.h +++ b/include/zenoh-pico/protocol/codec/ext.h @@ -21,6 +21,10 @@ #include "zenoh-pico/protocol/ext.h" #include "zenoh-pico/protocol/iobuf.h" +#ifdef __cplusplus +extern "C" { +#endif + /*------------------ Message Extension ------------------*/ z_result_t _z_msg_ext_encode(_z_wbuf_t *wbf, const _z_msg_ext_t *ext, bool has_next); z_result_t _z_msg_ext_decode(_z_msg_ext_t *ext, _z_zbuf_t *zbf, bool *has_next); @@ -66,4 +70,8 @@ z_result_t _z_msg_ext_encode_zbuf(_z_wbuf_t *wbf, const _z_msg_ext_zbuf_t *pld); z_result_t _z_msg_ext_decode_zbuf(_z_msg_ext_zbuf_t *pld, _z_zbuf_t *zbf); z_result_t _z_msg_ext_decode_zbuf_na(_z_msg_ext_zbuf_t *pld, _z_zbuf_t *zbf); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_TEST_H */ diff --git a/include/zenoh-pico/protocol/codec/interest.h b/include/zenoh-pico/protocol/codec/interest.h index 4e8aa4921..b8781efbe 100644 --- a/include/zenoh-pico/protocol/codec/interest.h +++ b/include/zenoh-pico/protocol/codec/interest.h @@ -18,7 +18,15 @@ #include "zenoh-pico/protocol/definitions/interest.h" #include "zenoh-pico/protocol/iobuf.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_interest_encode(_z_wbuf_t *wbf, const _z_interest_t *interest, bool is_final); z_result_t _z_interest_decode(_z_interest_t *decl, _z_zbuf_t *zbf, bool is_final, bool has_ext); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_CODEC_DECLARATIONS_H */ diff --git a/include/zenoh-pico/protocol/codec/message.h b/include/zenoh-pico/protocol/codec/message.h index c9bd9c039..ae4b88567 100644 --- a/include/zenoh-pico/protocol/codec/message.h +++ b/include/zenoh-pico/protocol/codec/message.h @@ -18,6 +18,10 @@ #include "zenoh-pico/protocol/definitions/network.h" #include "zenoh-pico/protocol/iobuf.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_push_body_encode(_z_wbuf_t *wbf, const _z_push_body_t *pshb); z_result_t _z_push_body_decode(_z_push_body_t *body, _z_zbuf_t *zbf, uint8_t header); @@ -36,4 +40,8 @@ z_result_t _z_put_decode(_z_msg_put_t *put, _z_zbuf_t *zbf, uint8_t header); z_result_t _z_del_encode(_z_wbuf_t *wbf, const _z_msg_del_t *del); z_result_t _z_del_decode(_z_msg_del_t *del, _z_zbuf_t *zbf, uint8_t header); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_CODEC_MESSAGE_H */ diff --git a/include/zenoh-pico/protocol/codec/network.h b/include/zenoh-pico/protocol/codec/network.h index 64a5229c8..e74322eb0 100644 --- a/include/zenoh-pico/protocol/codec/network.h +++ b/include/zenoh-pico/protocol/codec/network.h @@ -19,6 +19,11 @@ #include "zenoh-pico/protocol/definitions/network.h" #include "zenoh-pico/protocol/iobuf.h" + +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_push_encode(_z_wbuf_t *wbf, const _z_n_msg_push_t *msg); z_result_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header); z_result_t _z_request_encode(_z_wbuf_t *wbf, const _z_n_msg_request_t *msg); @@ -35,4 +40,8 @@ z_result_t _z_n_interest_decode(_z_n_msg_interest_t *interest, _z_zbuf_t *zbf, u z_result_t _z_network_message_encode(_z_wbuf_t *wbf, const _z_network_message_t *msg); z_result_t _z_network_message_decode(_z_network_message_t *msg, _z_zbuf_t *zbf); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_CODEC_NETWORK_H */ diff --git a/include/zenoh-pico/protocol/codec/transport.h b/include/zenoh-pico/protocol/codec/transport.h index cd0e4a2c5..d7b4320a5 100644 --- a/include/zenoh-pico/protocol/codec/transport.h +++ b/include/zenoh-pico/protocol/codec/transport.h @@ -17,6 +17,11 @@ #include "zenoh-pico/protocol/definitions/transport.h" #include "zenoh-pico/protocol/iobuf.h" + +#ifdef __cplusplus +extern "C" { +#endif + #define _ZENOH_PICO_FRAME_MESSAGES_VEC_SIZE 32 z_result_t _z_scouting_message_encode(_z_wbuf_t *buf, const _z_scouting_message_t *msg); @@ -48,4 +53,9 @@ z_result_t _z_fragment_decode(_z_t_msg_fragment_t *msg, _z_zbuf_t *zbf, uint8_t z_result_t _z_transport_message_encode(_z_wbuf_t *wbf, const _z_transport_message_t *msg); z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *zbf); + +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_CODEC_TRANSPORT_H */ diff --git a/include/zenoh-pico/protocol/core.h b/include/zenoh-pico/protocol/core.h index 7dcf49508..40dd8355e 100644 --- a/include/zenoh-pico/protocol/core.h +++ b/include/zenoh-pico/protocol/core.h @@ -29,6 +29,10 @@ #include "zenoh-pico/net/encoding.h" #include "zenoh-pico/system/platform.h" +#ifdef __cplusplus +extern "C" { +#endif + #define _Z_OPTIONAL #define _Z_MOVE(x) x * @@ -209,4 +213,8 @@ typedef struct { uint32_t _entity_id; } _z_reply_context_t; +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_CORE_H */ diff --git a/include/zenoh-pico/protocol/definitions/declarations.h b/include/zenoh-pico/protocol/definitions/declarations.h index c33cab627..e6f715722 100644 --- a/include/zenoh-pico/protocol/definitions/declarations.h +++ b/include/zenoh-pico/protocol/definitions/declarations.h @@ -20,6 +20,10 @@ #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/protocol/keyexpr.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { uint16_t _id; _z_keyexpr_t _keyexpr; @@ -113,4 +117,8 @@ _z_declaration_t _z_make_undecl_token(uint32_t id, _Z_OPTIONAL const _z_keyexpr_ _z_declaration_t _z_make_decl_final(void); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_DEFINITIONS_DECLARATIONS_H */ diff --git a/include/zenoh-pico/protocol/definitions/interest.h b/include/zenoh-pico/protocol/definitions/interest.h index ca2900874..7e0e849ae 100644 --- a/include/zenoh-pico/protocol/definitions/interest.h +++ b/include/zenoh-pico/protocol/definitions/interest.h @@ -20,6 +20,10 @@ #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/protocol/keyexpr.h" +#ifdef __cplusplus +extern "C" { +#endif + #define _Z_INTEREST_FLAG_KEYEXPRS (1) #define _Z_INTEREST_FLAG_SUBSCRIBERS (1 << 1) #define _Z_INTEREST_FLAG_QUERYABLES (1 << 2) @@ -43,4 +47,8 @@ void _z_interest_clear(_z_interest_t* decl); _z_interest_t _z_make_interest(_Z_MOVE(_z_keyexpr_t) key, uint32_t id, uint8_t flags); _z_interest_t _z_make_interest_final(uint32_t id); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_DEFINITIONS_INTEREST_H */ diff --git a/include/zenoh-pico/protocol/definitions/message.h b/include/zenoh-pico/protocol/definitions/message.h index 5d43defa4..2cfa93cd3 100644 --- a/include/zenoh-pico/protocol/definitions/message.h +++ b/include/zenoh-pico/protocol/definitions/message.h @@ -18,6 +18,11 @@ #include "zenoh-pico/net/encoding.h" #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/protocol/definitions/core.h" + +#ifdef __cplusplus +extern "C" { +#endif + /* Zenoh Messages */ #define _Z_MID_Z_OAM 0x00 #define _Z_MID_Z_PUT 0x01 @@ -140,4 +145,8 @@ typedef struct { void _z_msg_reply_clear(_z_msg_reply_t *msg); #define _Z_FLAG_Z_R_C 0x20 +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_DEFINITIONS_MESSAGE_H */ diff --git a/include/zenoh-pico/protocol/definitions/network.h b/include/zenoh-pico/protocol/definitions/network.h index f0cd40f01..489c996b3 100644 --- a/include/zenoh-pico/protocol/definitions/network.h +++ b/include/zenoh-pico/protocol/definitions/network.h @@ -25,6 +25,11 @@ #include "zenoh-pico/protocol/definitions/message.h" #include "zenoh-pico/protocol/ext.h" #include "zenoh-pico/protocol/keyexpr.h" + +#ifdef __cplusplus +extern "C" { +#endif + /* Network Messages */ #define _Z_MID_N_OAM 0x1f #define _Z_MID_N_DECLARE 0x1e @@ -301,4 +306,8 @@ _z_network_message_t _z_n_msg_make_declare(_z_declaration_t declaration, bool ha _z_network_message_t _z_n_msg_make_push(_Z_MOVE(_z_keyexpr_t) key, _Z_MOVE(_z_push_body_t) body); _z_network_message_t _z_n_msg_make_interest(_z_interest_t interest); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_DEFINITIONS_NETWORK_H */ diff --git a/include/zenoh-pico/protocol/definitions/transport.h b/include/zenoh-pico/protocol/definitions/transport.h index 7334f391a..261c61fc6 100644 --- a/include/zenoh-pico/protocol/definitions/transport.h +++ b/include/zenoh-pico/protocol/definitions/transport.h @@ -21,6 +21,10 @@ #include "zenoh-pico/link/endpoint.h" #include "zenoh-pico/protocol/definitions/network.h" +#ifdef __cplusplus +extern "C" { +#endif + #define _Z_MID_SCOUT 0x01 #define _Z_MID_HELLO 0x02 @@ -541,4 +545,8 @@ void _z_s_msg_copy(_z_scouting_message_t *clone, _z_scouting_message_t *msg); void _z_s_msg_copy_scout(_z_s_msg_scout_t *clone, _z_s_msg_scout_t *msg); void _z_s_msg_copy_hello(_z_s_msg_hello_t *clone, _z_s_msg_hello_t *msg); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_DEFINITIONS_TRANSPORT_H */ diff --git a/include/zenoh-pico/protocol/ext.h b/include/zenoh-pico/protocol/ext.h index cba1ab55d..eb70ede42 100644 --- a/include/zenoh-pico/protocol/ext.h +++ b/include/zenoh-pico/protocol/ext.h @@ -20,6 +20,10 @@ #include "zenoh-pico/protocol/core.h" +#ifdef __cplusplus +extern "C" { +#endif + /*=============================*/ /* Message header */ /*=============================*/ @@ -99,4 +103,8 @@ void _z_msg_ext_copy_zbuf(_z_msg_ext_zbuf_t *clone, const _z_msg_ext_zbuf_t *ext _Z_ELEM_DEFINE(_z_msg_ext, _z_msg_ext_t, _z_noop_size, _z_msg_ext_clear, _z_msg_ext_copy) _Z_VEC_DEFINE(_z_msg_ext, _z_msg_ext_t) +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_PROTOCOL_EXTENSION_H */ diff --git a/include/zenoh-pico/protocol/iobuf.h b/include/zenoh-pico/protocol/iobuf.h index 888b69d46..abd5b1a36 100644 --- a/include/zenoh-pico/protocol/iobuf.h +++ b/include/zenoh-pico/protocol/iobuf.h @@ -23,6 +23,10 @@ #include "zenoh-pico/collections/slice.h" #include "zenoh-pico/collections/vec.h" +#ifdef __cplusplus +extern "C" { +#endif + /*------------------ IOSli ------------------*/ typedef struct { @@ -129,4 +133,8 @@ void _z_wbuf_reset(_z_wbuf_t *wbf); void _z_wbuf_clear(_z_wbuf_t *wbf); void _z_wbuf_free(_z_wbuf_t **wbf); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_PROTOCOL_IOBUF_H */ diff --git a/include/zenoh-pico/protocol/keyexpr.h b/include/zenoh-pico/protocol/keyexpr.h index f171ee32f..8d790f669 100644 --- a/include/zenoh-pico/protocol/keyexpr.h +++ b/include/zenoh-pico/protocol/keyexpr.h @@ -19,6 +19,10 @@ #include "zenoh-pico/api/constants.h" #include "zenoh-pico/protocol/core.h" +#ifdef __cplusplus +extern "C" { +#endif + zp_keyexpr_canon_status_t _z_keyexpr_is_canon(const char *start, size_t len); zp_keyexpr_canon_status_t _z_keyexpr_canonize(char *start, size_t *len); bool _z_keyexpr_suffix_includes(const _z_keyexpr_t *left, const _z_keyexpr_t *right); @@ -28,8 +32,10 @@ bool _z_keyexpr_suffix_equals(const _z_keyexpr_t *left, const _z_keyexpr_t *righ /*------------------ clone/Copy/Free helpers ------------------*/ _z_keyexpr_t _z_keyexpr_from_string(uint16_t rid, _z_string_t *str); _z_keyexpr_t _z_keyexpr_from_substr(uint16_t rid, const char *str, size_t len); +size_t _z_keyexpr_size(_z_keyexpr_t *p); z_result_t _z_keyexpr_copy(_z_keyexpr_t *dst, const _z_keyexpr_t *src); _z_keyexpr_t _z_keyexpr_duplicate(_z_keyexpr_t src); +_z_keyexpr_t *_z_keyexpr_clone(const _z_keyexpr_t *src); _z_keyexpr_t _z_keyexpr_alias(_z_keyexpr_t src); /// Returns either keyexpr defined by id + mapping with null suffix if try_declared is true and id is non-zero, /// or keyexpr defined by its suffix only, with 0 id and no mapping. This is to be used only when forwarding @@ -45,4 +51,8 @@ void _z_keyexpr_move(_z_keyexpr_t *dst, _z_keyexpr_t *src); void _z_keyexpr_clear(_z_keyexpr_t *rk); void _z_keyexpr_free(_z_keyexpr_t **rk); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_KEYEXPR_H */ diff --git a/include/zenoh-pico/session/interest.h b/include/zenoh-pico/session/interest.h index 3e1f6d4da..d8792ca77 100644 --- a/include/zenoh-pico/session/interest.h +++ b/include/zenoh-pico/session/interest.h @@ -19,6 +19,10 @@ #include "zenoh-pico/net/session.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_INTEREST == 1 _z_session_interest_rc_t *_z_get_interest_by_id(_z_session_t *zn, const _z_zint_t id); _z_session_interest_rc_t *_z_register_interest(_z_session_t *zn, _z_session_interest_t *intr); @@ -32,4 +36,8 @@ z_result_t _z_interest_process_declare_final(_z_session_t *zn, uint32_t id); z_result_t _z_interest_process_interest_final(_z_session_t *zn, uint32_t id); z_result_t _z_interest_process_interest(_z_session_t *zn, _z_keyexpr_t key, uint32_t id, uint8_t flags); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SESSION_INTEREST_H */ diff --git a/include/zenoh-pico/session/liveliness.h b/include/zenoh-pico/session/liveliness.h new file mode 100644 index 000000000..3f375f70a --- /dev/null +++ b/include/zenoh-pico/session/liveliness.h @@ -0,0 +1,71 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +#ifndef ZENOH_PICO_SESSION_LIVELINESS_H +#define ZENOH_PICO_SESSION_LIVELINESS_H + +#include "zenoh-pico/session/session.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if Z_FEATURE_LIVELINESS == 1 +typedef struct _z_session_t _z_session_t; + +typedef struct { + _z_keyexpr_t _key; + _z_closure_reply_callback_t _callback; + _z_drop_handler_t _dropper; + void *_arg; +} _z_liveliness_pending_query_t; + +void _z_liveliness_pending_query_clear(_z_liveliness_pending_query_t *res); +void _z_liveliness_pending_query_copy(_z_liveliness_pending_query_t *dst, const _z_liveliness_pending_query_t *src); +_z_liveliness_pending_query_t *_z_liveliness_pending_query_clone(const _z_liveliness_pending_query_t *src); + +_Z_ELEM_DEFINE(_z_liveliness_pending_query, _z_liveliness_pending_query_t, _z_noop_size, + _z_liveliness_pending_query_clear, _z_liveliness_pending_query_copy) +_Z_INT_MAP_DEFINE(_z_liveliness_pending_query, _z_liveliness_pending_query_t) + +uint32_t _z_liveliness_get_query_id(_z_session_t *zn); + +z_result_t _z_liveliness_register_token(_z_session_t *zn, uint32_t id, const _z_keyexpr_t keyexpr); +void _z_liveliness_unregister_token(_z_session_t *zn, uint32_t id); + +#if Z_FEATURE_SUBSCRIPTION == 1 +z_result_t _z_liveliness_subscription_declare(_z_session_t *zn, uint32_t id, const _z_keyexpr_t keyexpr, + const _z_timestamp_t *timestamp); +z_result_t _z_liveliness_subscription_undeclare(_z_session_t *zn, uint32_t id, const _z_timestamp_t *timestamp); +z_result_t _z_liveliness_subscription_trigger_history(_z_session_t *zn, _z_keyexpr_t keyexpr); +#endif + +#if Z_FEATURE_QUERY == 1 +z_result_t _z_liveliness_register_pending_query(_z_session_t *zn, uint32_t id, _z_liveliness_pending_query_t *pen_qry); +void _z_liveliness_unregister_pending_query(_z_session_t *zn, uint32_t id); +#endif + +z_result_t _z_liveliness_process_token_declare(_z_session_t *zn, const _z_n_msg_declare_t *decl); +z_result_t _z_liveliness_process_token_undeclare(_z_session_t *zn, const _z_n_msg_declare_t *decl); +z_result_t _z_liveliness_process_declare_final(_z_session_t *zn, const _z_n_msg_declare_t *decl); + +void _z_liveliness_init(_z_session_t *zn); +void _z_liveliness_clear(_z_session_t *zn); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZENOH_PICO_SESSION_LIVELINESS_H */ diff --git a/include/zenoh-pico/session/push.h b/include/zenoh-pico/session/push.h index 5c774b704..49da5bf21 100644 --- a/include/zenoh-pico/session/push.h +++ b/include/zenoh-pico/session/push.h @@ -21,6 +21,14 @@ #ifndef ZENOH_PICO_SESSION_PUSH_H #define ZENOH_PICO_SESSION_PUSH_H +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_trigger_push(_z_session_t *zn, _z_n_msg_push_t *push, z_reliability_t reliability); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SESSION_PUSH_H */ diff --git a/include/zenoh-pico/session/query.h b/include/zenoh-pico/session/query.h index 1bf03b74d..c096bd793 100644 --- a/include/zenoh-pico/session/query.h +++ b/include/zenoh-pico/session/query.h @@ -18,6 +18,10 @@ #include "zenoh-pico/net/session.h" #include "zenoh-pico/protocol/core.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_QUERY == 1 /*------------------ Query ------------------*/ _z_zint_t _z_get_query_id(_z_session_t *zn); @@ -33,4 +37,8 @@ void _z_unregister_pending_query(_z_session_t *zn, _z_pending_query_t *pq); void _z_flush_pending_queries(_z_session_t *zn); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SESSION_QUERY_H */ diff --git a/include/zenoh-pico/session/reply.h b/include/zenoh-pico/session/reply.h index c10aa0b28..6e5221f49 100644 --- a/include/zenoh-pico/session/reply.h +++ b/include/zenoh-pico/session/reply.h @@ -19,6 +19,10 @@ #include "zenoh-pico/protocol/definitions/message.h" #include "zenoh-pico/protocol/definitions/network.h" +#ifdef __cplusplus +extern "C" { +#endif + #ifndef ZENOH_PICO_SESSION_REPLY_H #define ZENOH_PICO_SESSION_REPLY_H @@ -28,4 +32,8 @@ z_result_t _z_trigger_reply_err(_z_session_t *zn, _z_zint_t id, _z_msg_err_t *er z_result_t _z_trigger_reply_final(_z_session_t *zn, _z_n_msg_response_final_t *final); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SESSION_REPLY_H */ diff --git a/include/zenoh-pico/session/resource.h b/include/zenoh-pico/session/resource.h index 3702a86cd..bedffac06 100644 --- a/include/zenoh-pico/session/resource.h +++ b/include/zenoh-pico/session/resource.h @@ -19,6 +19,10 @@ #include "zenoh-pico/net/session.h" +#ifdef __cplusplus +extern "C" { +#endif + /*------------------ Entity ------------------*/ uint32_t _z_get_entity_id(_z_session_t *zn); @@ -36,4 +40,8 @@ _z_keyexpr_t __unsafe_z_get_expanded_key_from_key(_z_session_t *zn, const _z_key _z_resource_t *__unsafe_z_get_resource_by_id(_z_session_t *zn, uint16_t mapping, _z_zint_t id); _z_resource_t *__unsafe_z_get_resource_matching_key(_z_session_t *zn, const _z_keyexpr_t *keyexpr); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_SESSION_RESOURCE_H */ diff --git a/include/zenoh-pico/session/session.h b/include/zenoh-pico/session/session.h index 9d1d00038..3c1d50dbe 100644 --- a/include/zenoh-pico/session/session.h +++ b/include/zenoh-pico/session/session.h @@ -26,13 +26,19 @@ #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/transport/manager.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * The callback signature of the cleanup functions. */ typedef void (*_z_drop_handler_t)(void *arg); -#define _Z_RESOURCE_IS_REMOTE 0 -#define _Z_RESOURCE_IS_LOCAL 1 +typedef enum { + _Z_SUBSCRIBER_KIND_SUBSCRIBER = 0, + _Z_SUBSCRIBER_KIND_LIVELINESS_SUBSCRIBER = 1, +} _z_subscriber_kind_t; typedef struct { _z_keyexpr_t _key; @@ -44,23 +50,27 @@ bool _z_resource_eq(const _z_resource_t *one, const _z_resource_t *two); void _z_resource_clear(_z_resource_t *res); void _z_resource_copy(_z_resource_t *dst, const _z_resource_t *src); void _z_resource_free(_z_resource_t **res); +size_t _z_resource_size(_z_resource_t *p); -_Z_ELEM_DEFINE(_z_resource, _z_resource_t, _z_noop_size, _z_resource_clear, _z_resource_copy) +_Z_ELEM_DEFINE(_z_resource, _z_resource_t, _z_resource_size, _z_resource_clear, _z_resource_copy) _Z_LIST_DEFINE(_z_resource, _z_resource_t) +_Z_ELEM_DEFINE(_z_keyexpr, _z_keyexpr_t, _z_keyexpr_size, _z_keyexpr_clear, _z_keyexpr_copy) +_Z_INT_MAP_DEFINE(_z_keyexpr, _z_keyexpr_t) + // Forward declaration to avoid cyclical include typedef struct _z_sample_t _z_sample_t; /** * The callback signature of the functions handling data messages. */ -typedef void (*_z_sample_handler_t)(_z_sample_t *sample, void *arg); +typedef void (*_z_closure_sample_callback_t)(_z_sample_t *sample, void *arg); typedef struct { _z_keyexpr_t _key; uint16_t _key_id; uint32_t _id; - _z_sample_handler_t _callback; + _z_closure_sample_callback_t _callback; _z_drop_handler_t _dropper; void *_arg; } _z_subscription_t; @@ -85,12 +95,12 @@ typedef struct _z_query_rc_t _z_query_rc_t; /** * The callback signature of the functions handling query messages. */ -typedef void (*_z_query_handler_t)(_z_query_rc_t *query, void *arg); +typedef void (*_z_closure_query_callback_t)(_z_query_rc_t *query, void *arg); typedef struct { _z_keyexpr_t _key; uint32_t _id; - _z_query_handler_t _callback; + _z_closure_query_callback_t _callback; _z_drop_handler_t _dropper; void *_arg; bool _complete; @@ -114,12 +124,12 @@ typedef struct _z_reply_t _z_reply_t; /** * The callback signature of the functions handling query replies. */ -typedef void (*_z_reply_handler_t)(_z_reply_t *reply, void *arg); +typedef void (*_z_closure_reply_callback_t)(_z_reply_t *reply, void *arg); typedef struct { _z_keyexpr_t _key; _z_zint_t _id; - _z_reply_handler_t _callback; + _z_closure_reply_callback_t _callback; _z_drop_handler_t _dropper; void *_arg; _z_pending_reply_list_t *_pending_replies; @@ -142,11 +152,11 @@ typedef struct { _z_reply_data_list_t *_replies; } _z_pending_query_collect_t; -struct __z_hello_handler_wrapper_t; // Forward declaration to be used in _z_hello_handler_t +struct __z_hello_handler_wrapper_t; // Forward declaration to be used in _z_closure_hello_callback_t /** * The callback signature of the functions handling hello messages. */ -typedef void (*_z_hello_handler_t)(_z_hello_t *hello, struct __z_hello_handler_wrapper_t *arg); +typedef void (*_z_closure_hello_callback_t)(_z_hello_t *hello, struct __z_hello_handler_wrapper_t *arg); z_result_t _z_session_generate_zid(_z_id_t *bs, uint8_t size); @@ -203,4 +213,8 @@ void _z_declare_data_clear(_z_declare_data_t *data); _Z_ELEM_DEFINE(_z_declare_data, _z_declare_data_t, _z_noop_size, _z_declare_data_clear, _z_noop_copy) _Z_LIST_DEFINE(_z_declare_data, _z_declare_data_t) +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_SESSION_SESSION_H */ diff --git a/include/zenoh-pico/session/subscription.h b/include/zenoh-pico/session/subscription.h index dd48ecb83..59c942554 100644 --- a/include/zenoh-pico/session/subscription.h +++ b/include/zenoh-pico/session/subscription.h @@ -18,21 +18,41 @@ #include "zenoh-pico/net/encoding.h" #include "zenoh-pico/net/session.h" +#ifdef __cplusplus +extern "C" { +#endif + /*------------------ Subscription ------------------*/ -void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_bytes_t payload, - _z_encoding_t *encoding, const _z_n_qos_t qos, const _z_timestamp_t *timestamp, - const _z_bytes_t attachment, z_reliability_t reliability); +z_result_t _z_trigger_subscriptions_put(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_bytes_t payload, + _z_encoding_t *encoding, const _z_timestamp_t *timestamp, const _z_n_qos_t qos, + const _z_bytes_t attachment, z_reliability_t reliability); + +z_result_t _z_trigger_subscriptions_del(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_timestamp_t *timestamp, + const _z_n_qos_t qos, const _z_bytes_t attachment, z_reliability_t reliability); + +z_result_t _z_trigger_liveliness_subscriptions_declare(_z_session_t *zn, const _z_keyexpr_t keyexpr, + const _z_timestamp_t *timestamp); + +z_result_t _z_trigger_liveliness_subscriptions_undeclare(_z_session_t *zn, const _z_keyexpr_t keyexpr, + const _z_timestamp_t *timestamp); #if Z_FEATURE_SUBSCRIPTION == 1 -_z_subscription_rc_t *_z_get_subscription_by_id(_z_session_t *zn, uint8_t is_local, const _z_zint_t id); -_z_subscription_rc_list_t *_z_get_subscriptions_by_key(_z_session_t *zn, uint8_t is_local, const _z_keyexpr_t *keyexpr); - -_z_subscription_rc_t *_z_register_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_t *sub); -z_result_t _z_trigger_subscriptions(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_bytes_t payload, - _z_encoding_t *encoding, const _z_zint_t kind, const _z_timestamp_t *timestamp, - const _z_n_qos_t qos, const _z_bytes_t attachment, z_reliability_t reliability); -void _z_unregister_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_rc_t *sub); +_z_subscription_rc_t *_z_get_subscription_by_id(_z_session_t *zn, _z_subscriber_kind_t kind, const _z_zint_t id); +_z_subscription_rc_list_t *_z_get_subscriptions_by_key(_z_session_t *zn, _z_subscriber_kind_t kind, + const _z_keyexpr_t *keyexpr); + +_z_subscription_rc_t *_z_register_subscription(_z_session_t *zn, _z_subscriber_kind_t kind, _z_subscription_t *sub); +z_result_t _z_trigger_subscriptions_impl(_z_session_t *zn, _z_subscriber_kind_t subscriber_kind, + const _z_keyexpr_t keyexpr, const _z_bytes_t payload, _z_encoding_t *encoding, + const _z_zint_t sample_kind, const _z_timestamp_t *timestamp, + const _z_n_qos_t qos, const _z_bytes_t attachment, + z_reliability_t reliability); +void _z_unregister_subscription(_z_session_t *zn, _z_subscriber_kind_t kind, _z_subscription_rc_t *sub); void _z_flush_subscriptions(_z_session_t *zn); #endif +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_SESSION_SUBSCRIPTION_H */ diff --git a/include/zenoh-pico/session/utils.h b/include/zenoh-pico/session/utils.h index 75eaac2e8..97d4d11b3 100644 --- a/include/zenoh-pico/session/utils.h +++ b/include/zenoh-pico/session/utils.h @@ -22,6 +22,10 @@ #include "zenoh-pico/net/session.h" #include "zenoh-pico/protocol/core.h" +#ifdef __cplusplus +extern "C" { +#endif + /*------------------ Session ------------------*/ _z_hello_list_t *_z_scout_inner(const z_what_t what, _z_id_t id, _z_string_t *locator, const uint32_t timeout, const bool exit_on_first); @@ -37,4 +41,8 @@ z_result_t _z_send_n_msg(_z_session_t *zn, _z_network_message_t *n_msg, z_reliab void _zp_session_lock_mutex(_z_session_t *zn); void _zp_session_unlock_mutex(_z_session_t *zn); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_SESSION_UTILS_H */ diff --git a/include/zenoh-pico/system/link/raweth.h b/include/zenoh-pico/system/link/raweth.h index d48bf1fa4..f7b106571 100644 --- a/include/zenoh-pico/system/link/raweth.h +++ b/include/zenoh-pico/system/link/raweth.h @@ -21,6 +21,10 @@ #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/system/platform.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_RAWETH_TRANSPORT == 1 // Ethernet types (big endian) @@ -92,4 +96,8 @@ uint16_t _z_raweth_htons(uint16_t val); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_LINK_RAWETH_H */ diff --git a/include/zenoh-pico/system/link/serial.h b/include/zenoh-pico/system/link/serial.h index 21d832c65..21679d996 100644 --- a/include/zenoh-pico/system/link/serial.h +++ b/include/zenoh-pico/system/link/serial.h @@ -21,6 +21,10 @@ #include "zenoh-pico/config.h" #include "zenoh-pico/system/platform.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_LINK_SERIAL == 1 #define _Z_SERIAL_MTU_SIZE 1500 @@ -43,4 +47,8 @@ size_t _z_send_serial(const _z_sys_net_socket_t sock, const uint8_t *ptr, size_t #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_LINK_BT_H */ diff --git a/include/zenoh-pico/system/link/tcp.h b/include/zenoh-pico/system/link/tcp.h index 22bdc3efc..c6dcd7032 100644 --- a/include/zenoh-pico/system/link/tcp.h +++ b/include/zenoh-pico/system/link/tcp.h @@ -20,6 +20,10 @@ #include "zenoh-pico/collections/string.h" #include "zenoh-pico/system/platform.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_LINK_TCP == 1 typedef struct { @@ -38,4 +42,8 @@ size_t _z_read_tcp(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t len); size_t _z_send_tcp(const _z_sys_net_socket_t sock, const uint8_t *ptr, size_t len); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_LINK_TCP_H */ diff --git a/include/zenoh-pico/system/link/udp.h b/include/zenoh-pico/system/link/udp.h index 47899c04a..a0eb9cb01 100644 --- a/include/zenoh-pico/system/link/udp.h +++ b/include/zenoh-pico/system/link/udp.h @@ -20,6 +20,10 @@ #include "zenoh-pico/collections/string.h" #include "zenoh-pico/system/platform.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_LINK_UDP_UNICAST == 1 || Z_FEATURE_LINK_UDP_MULTICAST == 1 typedef struct { @@ -56,4 +60,8 @@ size_t _z_send_udp_multicast(const _z_sys_net_socket_t sock, const uint8_t *ptr, const _z_sys_net_endpoint_t rep); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_LINK_UDP_H */ diff --git a/include/zenoh-pico/system/link/ws.h b/include/zenoh-pico/system/link/ws.h index aa57fcbf8..c3fcadc14 100644 --- a/include/zenoh-pico/system/link/ws.h +++ b/include/zenoh-pico/system/link/ws.h @@ -20,6 +20,10 @@ #include "zenoh-pico/collections/string.h" #include "zenoh-pico/system/platform.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_LINK_WS == 1 typedef struct { @@ -38,4 +42,8 @@ size_t _z_read_ws(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t len); size_t _z_send_ws(const _z_sys_net_socket_t sock, const uint8_t *ptr, size_t len); #endif +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_LINK_WS_H */ diff --git a/include/zenoh-pico/system/platform/arduino/esp32.h b/include/zenoh-pico/system/platform/arduino/esp32.h index af09722a2..9e8df7a07 100644 --- a/include/zenoh-pico/system/platform/arduino/esp32.h +++ b/include/zenoh-pico/system/platform/arduino/esp32.h @@ -21,6 +21,10 @@ #include #endif // Z_FEATURE_MULTI_THREAD == 1 +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_MULTI_THREAD == 1 typedef void *_z_task_t; typedef void *z_task_attr_t; // Not used in ESP32 @@ -56,4 +60,8 @@ typedef struct { }; } _z_sys_net_endpoint_t; +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_ESP32_TYPES_H */ diff --git a/include/zenoh-pico/system/platform/arduino/opencr.h b/include/zenoh-pico/system/platform/arduino/opencr.h index c9c374d2d..e1fa1da4a 100644 --- a/include/zenoh-pico/system/platform/arduino/opencr.h +++ b/include/zenoh-pico/system/platform/arduino/opencr.h @@ -20,6 +20,10 @@ #include "zenoh-pico/config.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_MULTI_THREAD == 1 typedef void *_z_task_t; typedef void *z_task_attr_t; @@ -60,4 +64,8 @@ typedef struct { bool _err; } _z_sys_net_endpoint_t; +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_ARDUINO_OPENCR_TYPES_H */ diff --git a/include/zenoh-pico/system/platform/emscripten.h b/include/zenoh-pico/system/platform/emscripten.h index edb9c6b44..068cca9f2 100644 --- a/include/zenoh-pico/system/platform/emscripten.h +++ b/include/zenoh-pico/system/platform/emscripten.h @@ -19,6 +19,10 @@ #include "zenoh-pico/config.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_MULTI_THREAD == 1 #include @@ -50,4 +54,8 @@ typedef struct { }; } _z_sys_net_endpoint_t; +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_WASM_TYPES_H */ diff --git a/include/zenoh-pico/system/platform/espidf.h b/include/zenoh-pico/system/platform/espidf.h index 1f35832a6..aadeb782f 100644 --- a/include/zenoh-pico/system/platform/espidf.h +++ b/include/zenoh-pico/system/platform/espidf.h @@ -22,6 +22,10 @@ #include "zenoh-pico/config.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_MULTI_THREAD == 1 #include @@ -69,4 +73,8 @@ typedef struct { }; } _z_sys_net_endpoint_t; +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_ESPIDF_TYPES_H */ diff --git a/include/zenoh-pico/system/platform/flipper.h b/include/zenoh-pico/system/platform/flipper.h index 4a51074f6..8eb94b4c7 100644 --- a/include/zenoh-pico/system/platform/flipper.h +++ b/include/zenoh-pico/system/platform/flipper.h @@ -21,6 +21,10 @@ #include "zenoh-pico/config.h" +#ifdef __cplusplus +extern "C" { +#endif + #define FLIPPER_DEFAULT_THREAD_STACK_SIZE 2048 #define FLIPPER_SERIAL_STREAM_BUFFER_SIZE 512 #define FLIPPER_SERIAL_STREAM_TRIGGERED_LEVEL 10 @@ -43,4 +47,8 @@ typedef struct { #endif } _z_sys_net_socket_t; +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_FLIPPER_TYPES_H */ diff --git a/include/zenoh-pico/system/platform/freertos_plus_tcp.h b/include/zenoh-pico/system/platform/freertos_plus_tcp.h index 7332889c5..31a2dfc83 100644 --- a/include/zenoh-pico/system/platform/freertos_plus_tcp.h +++ b/include/zenoh-pico/system/platform/freertos_plus_tcp.h @@ -18,6 +18,10 @@ #include "FreeRTOS_IP.h" #include "semphr.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_MULTI_THREAD == 1 typedef struct { const char *name; @@ -58,4 +62,8 @@ typedef struct { }; } _z_sys_net_endpoint_t; -#endif \ No newline at end of file +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/zenoh-pico/system/platform/mbed.h b/include/zenoh-pico/system/platform/mbed.h index 08bb09c83..87fdb4626 100644 --- a/include/zenoh-pico/system/platform/mbed.h +++ b/include/zenoh-pico/system/platform/mbed.h @@ -20,6 +20,10 @@ #include "zenoh-pico/config.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef int _z_socket_t; #if Z_FEATURE_MULTI_THREAD == 1 @@ -61,4 +65,8 @@ typedef struct { }; } _z_sys_net_endpoint_t; +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_MBED_TYPES_H */ diff --git a/include/zenoh-pico/system/platform/unix.h b/include/zenoh-pico/system/platform/unix.h index cea7b5868..b83dbb424 100644 --- a/include/zenoh-pico/system/platform/unix.h +++ b/include/zenoh-pico/system/platform/unix.h @@ -19,12 +19,17 @@ #include #include #include +#if Z_FEATURE_MULTI_THREAD == 1 +#include +#endif // Z_FEATURE_MULTI_THREAD == 1 #include "zenoh-pico/config.h" -#if Z_FEATURE_MULTI_THREAD == 1 -#include +#ifdef __cplusplus +extern "C" { +#endif +#if Z_FEATURE_MULTI_THREAD == 1 typedef pthread_t _z_task_t; typedef pthread_attr_t z_task_attr_t; typedef pthread_mutex_t _z_mutex_t; @@ -51,4 +56,8 @@ typedef struct { }; } _z_sys_net_endpoint_t; +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_UNIX_TYPES_H */ diff --git a/include/zenoh-pico/system/platform/void.h b/include/zenoh-pico/system/platform/void.h index cda1b50ab..f46217281 100644 --- a/include/zenoh-pico/system/platform/void.h +++ b/include/zenoh-pico/system/platform/void.h @@ -17,6 +17,10 @@ #include "zenoh-pico/config.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_MULTI_THREAD == 1 typedef void *_z_task_t; typedef void *z_task_attr_t; @@ -27,4 +31,8 @@ typedef void *_z_condvar_t; typedef void *z_clock_t; typedef void *z_time_t; +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_VOID_H */ diff --git a/include/zenoh-pico/system/platform/windows.h b/include/zenoh-pico/system/platform/windows.h index cb41f243d..7ccd38509 100644 --- a/include/zenoh-pico/system/platform/windows.h +++ b/include/zenoh-pico/system/platform/windows.h @@ -20,6 +20,10 @@ #include "zenoh-pico/config.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_MULTI_THREAD == 1 typedef HANDLE *_z_task_t; typedef void *z_task_attr_t; // Not used in Windows @@ -48,4 +52,8 @@ typedef struct { inline void __asm__(char *instruction) { (void)(instruction); } +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_VOID_H */ diff --git a/include/zenoh-pico/system/platform/zephyr.h b/include/zenoh-pico/system/platform/zephyr.h index 966edaa52..1f25e839c 100644 --- a/include/zenoh-pico/system/platform/zephyr.h +++ b/include/zenoh-pico/system/platform/zephyr.h @@ -30,6 +30,10 @@ #include "zenoh-pico/config.h" +#ifdef __cplusplus +extern "C" { +#endif + #if Z_FEATURE_MULTI_THREAD == 1 typedef pthread_t _z_task_t; typedef pthread_attr_t z_task_attr_t; @@ -59,4 +63,8 @@ typedef struct { }; } _z_sys_net_endpoint_t; +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_SYSTEM_ZEPHYR_TYPES_H */ diff --git a/include/zenoh-pico/transport/common/lease.h b/include/zenoh-pico/transport/common/lease.h index 900a2f887..858282636 100644 --- a/include/zenoh-pico/transport/common/lease.h +++ b/include/zenoh-pico/transport/common/lease.h @@ -17,7 +17,15 @@ #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_send_join(_z_transport_t *zt); z_result_t _z_send_keep_alive(_z_transport_t *zt); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_TRANSPORT_LEASE_H */ diff --git a/include/zenoh-pico/transport/common/read.h b/include/zenoh-pico/transport/common/read.h index f298d1878..fe6b79b6a 100644 --- a/include/zenoh-pico/transport/common/read.h +++ b/include/zenoh-pico/transport/common/read.h @@ -17,7 +17,15 @@ #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_read(_z_transport_t *zt); void *_zp_read_task(void *zt_arg); // The argument is void* to avoid incompatible pointer types in tasks +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_TRANSPORT_READ_H */ diff --git a/include/zenoh-pico/transport/common/rx.h b/include/zenoh-pico/transport/common/rx.h index 147273816..e4f548c6e 100644 --- a/include/zenoh-pico/transport/common/rx.h +++ b/include/zenoh-pico/transport/common/rx.h @@ -18,8 +18,16 @@ #include "zenoh-pico/link/link.h" #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + /*------------------ Transmission and Reception helpers ------------------*/ size_t _z_read_stream_size(_z_zbuf_t *zbuf); z_result_t _z_link_recv_t_msg(_z_transport_message_t *t_msg, const _z_link_t *zl); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_TRANSPORT_RX_H */ diff --git a/include/zenoh-pico/transport/common/tx.h b/include/zenoh-pico/transport/common/tx.h index 1eb4abac1..05d22a89e 100644 --- a/include/zenoh-pico/transport/common/tx.h +++ b/include/zenoh-pico/transport/common/tx.h @@ -19,6 +19,10 @@ #include "zenoh-pico/net/session.h" #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + void __unsafe_z_prepare_wbuf(_z_wbuf_t *buf, uint8_t link_flow_capability); void __unsafe_z_finalize_wbuf(_z_wbuf_t *buf, uint8_t link_flow_capability); /*This function is unsafe because it operates in potentially concurrent @@ -29,4 +33,8 @@ z_result_t __unsafe_z_serialize_zenoh_fragment(_z_wbuf_t *dst, _z_wbuf_t *src, z z_result_t _z_send_t_msg(_z_transport_t *zt, const _z_transport_message_t *t_msg); z_result_t _z_link_send_t_msg(const _z_link_t *zl, const _z_transport_message_t *t_msg); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_TRANSPORT_TX_H */ diff --git a/include/zenoh-pico/transport/manager.h b/include/zenoh-pico/transport/manager.h index 8ac95dd7c..321bed3ac 100644 --- a/include/zenoh-pico/transport/manager.h +++ b/include/zenoh-pico/transport/manager.h @@ -19,7 +19,15 @@ #include "zenoh-pico/link/manager.h" #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_new_transport(_z_transport_t *zt, _z_id_t *bs, _z_string_t *locator, z_whatami_t mode); void _z_free_transport(_z_transport_t **zt); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_TRANSPORT_MANAGER_H */ diff --git a/include/zenoh-pico/transport/multicast.h b/include/zenoh-pico/transport/multicast.h index 487ef6dae..bdf939514 100644 --- a/include/zenoh-pico/transport/multicast.h +++ b/include/zenoh-pico/transport/multicast.h @@ -17,7 +17,15 @@ #include "zenoh-pico/api/types.h" +#ifdef __cplusplus +extern "C" { +#endif + void _zp_multicast_fetch_zid(const _z_transport_t *zt, _z_closure_zid_t *callback); void _zp_multicast_info_session(const _z_transport_t *zt, _z_config_t *ps); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_MULTICAST_H */ diff --git a/include/zenoh-pico/transport/multicast/lease.h b/include/zenoh-pico/transport/multicast/lease.h index 09a0b4135..71472bb55 100644 --- a/include/zenoh-pico/transport/multicast/lease.h +++ b/include/zenoh-pico/transport/multicast/lease.h @@ -17,6 +17,10 @@ #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _zp_multicast_send_join(_z_transport_multicast_t *ztm); z_result_t _zp_multicast_send_keep_alive(_z_transport_multicast_t *ztm); z_result_t _zp_multicast_stop_lease_task(_z_transport_multicast_t *ztm); @@ -28,4 +32,8 @@ z_result_t _zp_multicast_start_lease_task(_z_transport_multicast_t *ztm, z_task_ z_result_t _zp_multicast_start_lease_task(_z_transport_multicast_t *ztm, void *attr, void *task); #endif /* Z_FEATURE_MULTI_THREAD == 1 && (Z_FEATURE_MULTICAST_TRANSPORT == 1 || Z_FEATURE_RAWETH_TRANSPORT == 1) */ +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_MULTICAST_LEASE_H */ diff --git a/include/zenoh-pico/transport/multicast/read.h b/include/zenoh-pico/transport/multicast/read.h index acaa82308..63c9a0eda 100644 --- a/include/zenoh-pico/transport/multicast/read.h +++ b/include/zenoh-pico/transport/multicast/read.h @@ -17,6 +17,10 @@ #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _zp_multicast_read(_z_transport_multicast_t *ztm); z_result_t _zp_multicast_stop_read_task(_z_transport_t *zt); void *_zp_multicast_read_task(void *ztm_arg); // The argument is void* to avoid incompatible pointer types in tasks @@ -27,4 +31,8 @@ z_result_t _zp_multicast_start_read_task(_z_transport_t *zt, z_task_attr_t *attr z_result_t _zp_multicast_start_read_task(_z_transport_t *zt, void *attr, void *task); #endif /* #if Z_FEATURE_MULTI_THREAD == 1 && Z_FEATURE_MULTICAST_TRANSPORT == 1 */ +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_MULTICAST_READ_H */ diff --git a/include/zenoh-pico/transport/multicast/rx.h b/include/zenoh-pico/transport/multicast/rx.h index 31a10e64a..c16ca82d4 100644 --- a/include/zenoh-pico/transport/multicast/rx.h +++ b/include/zenoh-pico/transport/multicast/rx.h @@ -17,8 +17,16 @@ #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_multicast_recv_t_msg(_z_transport_multicast_t *ztm, _z_transport_message_t *t_msg, _z_slice_t *addr); z_result_t _z_multicast_handle_transport_message(_z_transport_multicast_t *ztm, _z_transport_message_t *t_msg, _z_slice_t *addr); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_TRANSPORT_LINK_RX_H */ diff --git a/include/zenoh-pico/transport/multicast/transport.h b/include/zenoh-pico/transport/multicast/transport.h index fa9cd085c..ef8b73994 100644 --- a/include/zenoh-pico/transport/multicast/transport.h +++ b/include/zenoh-pico/transport/multicast/transport.h @@ -17,6 +17,10 @@ #include "zenoh-pico/api/types.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_multicast_transport_create(_z_transport_t *zt, _z_link_t *zl, _z_transport_multicast_establish_param_t *param); z_result_t _z_multicast_open_peer(_z_transport_multicast_establish_param_t *param, const _z_link_t *zl, @@ -26,4 +30,9 @@ z_result_t _z_multicast_open_client(_z_transport_multicast_establish_param_t *pa z_result_t _z_multicast_send_close(_z_transport_multicast_t *ztm, uint8_t reason, bool link_only); z_result_t _z_multicast_transport_close(_z_transport_multicast_t *ztm, uint8_t reason); void _z_multicast_transport_clear(_z_transport_t *zt); + +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_MULTICAST_TRANSPORT_H */ diff --git a/include/zenoh-pico/transport/multicast/tx.h b/include/zenoh-pico/transport/multicast/tx.h index c9721523a..903fc80cd 100644 --- a/include/zenoh-pico/transport/multicast/tx.h +++ b/include/zenoh-pico/transport/multicast/tx.h @@ -18,8 +18,16 @@ #include "zenoh-pico/net/session.h" #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_multicast_send_n_msg(_z_session_t *zn, const _z_network_message_t *z_msg, z_reliability_t reliability, z_congestion_control_t cong_ctrl); z_result_t _z_multicast_send_t_msg(_z_transport_multicast_t *ztm, const _z_transport_message_t *t_msg); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_MULTICAST_TX_H */ diff --git a/include/zenoh-pico/transport/raweth/read.h b/include/zenoh-pico/transport/raweth/read.h index 6ead7be9b..f5cc3a6ee 100644 --- a/include/zenoh-pico/transport/raweth/read.h +++ b/include/zenoh-pico/transport/raweth/read.h @@ -17,6 +17,10 @@ #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _zp_raweth_read(_z_transport_multicast_t *ztm); z_result_t _zp_raweth_stop_read_task(_z_transport_t *zt); void *_zp_raweth_read_task(void *ztm_arg); // The argument is void* to avoid incompatible pointer types in tasks @@ -27,4 +31,8 @@ z_result_t _zp_raweth_start_read_task(_z_transport_t *zt, z_task_attr_t *attr, _ z_result_t _zp_raweth_start_read_task(_z_transport_t *zt, void *attr, void *task); #endif /* Z_FEATURE_MULTI_THREAD == 1 && Z_FEATURE_RAWETH_TRANSPORT == 1 */ +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_RAWETH_READ_H */ diff --git a/include/zenoh-pico/transport/raweth/rx.h b/include/zenoh-pico/transport/raweth/rx.h index 81874d633..5ebcfb0e1 100644 --- a/include/zenoh-pico/transport/raweth/rx.h +++ b/include/zenoh-pico/transport/raweth/rx.h @@ -17,7 +17,15 @@ #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_raweth_recv_t_msg(_z_transport_multicast_t *ztm, _z_transport_message_t *t_msg, _z_slice_t *addr); z_result_t _z_raweth_recv_t_msg_na(_z_transport_multicast_t *ztm, _z_transport_message_t *t_msg, _z_slice_t *addr); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_RAWETH_RX_H */ diff --git a/include/zenoh-pico/transport/raweth/tx.h b/include/zenoh-pico/transport/raweth/tx.h index 83abdd9fb..4b191f2de 100644 --- a/include/zenoh-pico/transport/raweth/tx.h +++ b/include/zenoh-pico/transport/raweth/tx.h @@ -18,9 +18,17 @@ #include "zenoh-pico/net/session.h" #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_raweth_link_send_t_msg(const _z_link_t *zl, const _z_transport_message_t *t_msg); z_result_t _z_raweth_send_n_msg(_z_session_t *zn, const _z_network_message_t *z_msg, z_reliability_t reliability, z_congestion_control_t cong_ctrl); z_result_t _z_raweth_send_t_msg(_z_transport_multicast_t *ztm, const _z_transport_message_t *t_msg); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_RAWETH_TX_H */ diff --git a/include/zenoh-pico/transport/transport.h b/include/zenoh-pico/transport/transport.h index 4e013594e..1671786df 100644 --- a/include/zenoh-pico/transport/transport.h +++ b/include/zenoh-pico/transport/transport.h @@ -25,6 +25,10 @@ #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/protocol/definitions/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { #if Z_FEATURE_FRAGMENTATION == 1 // Defragmentation buffers @@ -182,4 +186,8 @@ z_result_t _z_transport_close(_z_transport_t *zt, uint8_t reason); void _z_transport_clear(_z_transport_t *zt); void _z_transport_free(_z_transport_t **zt); +#ifdef __cplusplus +} +#endif + #endif /* INCLUDE_ZENOH_PICO_TRANSPORT_TRANSPORT_H */ diff --git a/include/zenoh-pico/transport/unicast.h b/include/zenoh-pico/transport/unicast.h index 652384e47..4c0d525bd 100644 --- a/include/zenoh-pico/transport/unicast.h +++ b/include/zenoh-pico/transport/unicast.h @@ -17,7 +17,15 @@ #include "zenoh-pico/api/types.h" +#ifdef __cplusplus +extern "C" { +#endif + void _zp_unicast_fetch_zid(const _z_transport_t *zt, _z_closure_zid_t *callback); void _zp_unicast_info_session(const _z_transport_t *zt, _z_config_t *ps); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_UNICAST_H */ diff --git a/include/zenoh-pico/transport/unicast/lease.h b/include/zenoh-pico/transport/unicast/lease.h index 469fd1333..0d607afd6 100644 --- a/include/zenoh-pico/transport/unicast/lease.h +++ b/include/zenoh-pico/transport/unicast/lease.h @@ -17,6 +17,10 @@ #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _zp_unicast_send_keep_alive(_z_transport_unicast_t *ztu); z_result_t _zp_unicast_stop_lease_task(_z_transport_t *zt); void *_zp_unicast_lease_task(void *ztu_arg); // The argument is void* to avoid incompatible pointer types in tasks @@ -27,4 +31,8 @@ z_result_t _zp_unicast_start_lease_task(_z_transport_t *zt, z_task_attr_t *attr, z_result_t _zp_unicast_start_lease_task(_z_transport_t *zt, void *attr, void *task); #endif /* Z_FEATURE_MULTI_THREAD == 1 && Z_FEATURE_UNICAST_TRANSPORT == 1 */ +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_TRANSPORT_LINK_TASK_LEASE_H */ diff --git a/include/zenoh-pico/transport/unicast/read.h b/include/zenoh-pico/transport/unicast/read.h index 63a8976bb..e703a1ee1 100644 --- a/include/zenoh-pico/transport/unicast/read.h +++ b/include/zenoh-pico/transport/unicast/read.h @@ -17,6 +17,10 @@ #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _zp_unicast_read(_z_transport_unicast_t *ztu); z_result_t _zp_unicast_stop_read_task(_z_transport_t *zt); void *_zp_unicast_read_task(void *ztu_arg); // The argument is void* to avoid incompatible pointer types in tasks @@ -27,4 +31,8 @@ z_result_t _zp_unicast_start_read_task(_z_transport_t *zt, z_task_attr_t *attr, z_result_t _zp_unicast_start_read_task(_z_transport_t *zt, void *attr, void *task); #endif /* Z_FEATURE_MULTI_THREAD == 1 && Z_FEATURE_UNICAST_TRANSPORT == 1 */ +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_UNICAST_READ_H */ diff --git a/include/zenoh-pico/transport/unicast/rx.h b/include/zenoh-pico/transport/unicast/rx.h index f36cb592c..6e948dc73 100644 --- a/include/zenoh-pico/transport/unicast/rx.h +++ b/include/zenoh-pico/transport/unicast/rx.h @@ -17,8 +17,16 @@ #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_unicast_recv_t_msg(_z_transport_unicast_t *ztu, _z_transport_message_t *t_msg); z_result_t _z_unicast_recv_t_msg_na(_z_transport_unicast_t *ztu, _z_transport_message_t *t_msg); z_result_t _z_unicast_handle_transport_message(_z_transport_unicast_t *ztu, _z_transport_message_t *t_msg); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_UNICAST_RX_H */ diff --git a/include/zenoh-pico/transport/unicast/transport.h b/include/zenoh-pico/transport/unicast/transport.h index 4b60b7c70..dc39cac54 100644 --- a/include/zenoh-pico/transport/unicast/transport.h +++ b/include/zenoh-pico/transport/unicast/transport.h @@ -17,6 +17,10 @@ #include "zenoh-pico/api/types.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_unicast_transport_create(_z_transport_t *zt, _z_link_t *zl, _z_transport_unicast_establish_param_t *param); z_result_t _z_unicast_open_client(_z_transport_unicast_establish_param_t *param, const _z_link_t *zl, @@ -26,4 +30,9 @@ z_result_t _z_unicast_open_peer(_z_transport_unicast_establish_param_t *param, c z_result_t _z_unicast_send_close(_z_transport_unicast_t *ztu, uint8_t reason, bool link_only); z_result_t _z_unicast_transport_close(_z_transport_unicast_t *ztu, uint8_t reason); void _z_unicast_transport_clear(_z_transport_t *zt); + +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_UNICAST_TRANSPORT_H */ diff --git a/include/zenoh-pico/transport/unicast/tx.h b/include/zenoh-pico/transport/unicast/tx.h index 56a33bfdd..ade38faf0 100644 --- a/include/zenoh-pico/transport/unicast/tx.h +++ b/include/zenoh-pico/transport/unicast/tx.h @@ -18,8 +18,16 @@ #include "zenoh-pico/net/session.h" #include "zenoh-pico/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + z_result_t _z_unicast_send_n_msg(_z_session_t *zn, const _z_network_message_t *z_msg, z_reliability_t reliability, z_congestion_control_t cong_ctrl); z_result_t _z_unicast_send_t_msg(_z_transport_unicast_t *ztu, const _z_transport_message_t *t_msg); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_TRANSPORT_LINK_TX_H */ diff --git a/include/zenoh-pico/transport/utils.h b/include/zenoh-pico/transport/utils.h index aff81dc03..62fa319b4 100644 --- a/include/zenoh-pico/transport/utils.h +++ b/include/zenoh-pico/transport/utils.h @@ -20,6 +20,10 @@ #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/protocol/definitions/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + /*------------------ SN helpers ------------------*/ _z_zint_t _z_sn_max(uint8_t bits); _z_zint_t _z_sn_half(_z_zint_t sn); @@ -31,4 +35,8 @@ _z_zint_t _z_sn_decrement(const _z_zint_t sn_resolution, const _z_zint_t sn); void _z_conduit_sn_list_copy(_z_conduit_sn_list_t *dst, const _z_conduit_sn_list_t *src); void _z_conduit_sn_list_decrement(const _z_zint_t sn_resolution, _z_conduit_sn_list_t *sns); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_TRANSPORT_UTILS_H */ diff --git a/include/zenoh-pico/utils/checksum.h b/include/zenoh-pico/utils/checksum.h index b649ad02b..aad153f9c 100644 --- a/include/zenoh-pico/utils/checksum.h +++ b/include/zenoh-pico/utils/checksum.h @@ -18,6 +18,14 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + uint32_t _z_crc32(const uint8_t *message, size_t len); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_UTILS_CHECKSUM_H */ diff --git a/include/zenoh-pico/utils/config.h b/include/zenoh-pico/utils/config.h index de17a1239..cf67d4189 100644 --- a/include/zenoh-pico/utils/config.h +++ b/include/zenoh-pico/utils/config.h @@ -21,6 +21,10 @@ #include "zenoh-pico/collections/string.h" #include "zenoh-pico/utils/result.h" +#ifdef __cplusplus +extern "C" { +#endif + // Properties returned by _z_info() #define Z_INFO_PID_KEY 0x00 #define Z_INFO_PEER_PID_KEY 0x01 @@ -46,6 +50,7 @@ z_result_t _z_config_init(_z_config_t *ps); * value: The value of the property to add. */ z_result_t _zp_config_insert(_z_config_t *ps, uint8_t key, const char *value); +z_result_t _zp_config_insert_string(_z_config_t *ps, uint8_t key, const _z_string_t *value); /** * Get the property with the given key from a properties map. @@ -109,4 +114,8 @@ char *_z_config_get(const _z_config_t *ps, uint8_t key); */ #define _z_config_free _z_str_intmap_free +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_UTILS_PROPERTY_H */ diff --git a/include/zenoh-pico/utils/encoding.h b/include/zenoh-pico/utils/encoding.h index 266eb4db1..3ff2c6988 100644 --- a/include/zenoh-pico/utils/encoding.h +++ b/include/zenoh-pico/utils/encoding.h @@ -18,7 +18,15 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + size_t _z_cobs_encode(const uint8_t *input, size_t input_len, uint8_t *output); size_t _z_cobs_decode(const uint8_t *input, size_t input_len, uint8_t *output); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_UTILS_ENCODING_H */ diff --git a/include/zenoh-pico/utils/logging.h b/include/zenoh-pico/utils/logging.h index 2c9f3ab0d..b50110bdf 100644 --- a/include/zenoh-pico/utils/logging.h +++ b/include/zenoh-pico/utils/logging.h @@ -19,6 +19,10 @@ #include "zenoh-pico/system/platform_common.h" +#ifdef __cplusplus +extern "C" { +#endif + // Logging values #define _Z_LOG_LVL_ERROR 1 #define _Z_LOG_LVL_INFO 2 @@ -72,4 +76,8 @@ static inline void __z_print_timestamp(void) { } while (false) #endif // ZENOH_DEBUG == 0 && !defined(Z_BUILD_DEBUG) +#ifdef __cplusplus +} +#endif + #endif // ZENOH_PICO_UTILS_LOGGING_H diff --git a/include/zenoh-pico/utils/pointers.h b/include/zenoh-pico/utils/pointers.h index 7ce798c64..a5f5156df 100644 --- a/include/zenoh-pico/utils/pointers.h +++ b/include/zenoh-pico/utils/pointers.h @@ -18,6 +18,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** * Computes the distance between two ``uint8_t`` pointers as an absolute value. * Note that ``l_ptr`` must be higher than ``r_ptr``. @@ -92,4 +96,8 @@ const char *_z_cptr_char_offset(const char *ptr, ptrdiff_t off); */ char *_z_ptr_char_offset(char *ptr, ptrdiff_t off); +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_UTILS_POINTERS_H */ diff --git a/include/zenoh-pico/utils/result.h b/include/zenoh-pico/utils/result.h index 4dd16f141..6b1061d21 100644 --- a/include/zenoh-pico/utils/result.h +++ b/include/zenoh-pico/utils/result.h @@ -17,6 +17,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + #define _ZP_UNUSED(x) (void)(x) #define _ZP_ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) @@ -106,4 +110,8 @@ typedef enum { #define _Z_IS_OK(expr) (expr == _Z_RES_OK) #define _Z_IS_ERR(expr) (expr != _Z_RES_OK) +#ifdef __cplusplus +} +#endif + #endif /* ZENOH_PICO_UTILS_RESULT_H */ diff --git a/include/zenoh-pico/utils/string.h b/include/zenoh-pico/utils/string.h index ca9b5a6b6..e4ffd69d2 100644 --- a/include/zenoh-pico/utils/string.h +++ b/include/zenoh-pico/utils/string.h @@ -12,10 +12,17 @@ // ZettaScale Zenoh Team, // +#ifndef ZENOH_PICO_UTILS_STRING_H +#define ZENOH_PICO_UTILS_STRING_H + #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { char const *start; char const *end; @@ -55,3 +62,9 @@ _z_str_se_t _z_splitstr_nextback(_z_splitstr_t *str); size_t _z_strcnt(char const *haystack_start, const char *harstack_end, const char *needle_start); size_t _z_str_startswith(const char *s, const char *needle); + +#ifdef __cplusplus +} +#endif + +#endif /* ZENOH_PICO_UTILS_STRING_H */ diff --git a/include/zenoh-pico/utils/uuid.h b/include/zenoh-pico/utils/uuid.h index 4bd581a91..13631460b 100644 --- a/include/zenoh-pico/utils/uuid.h +++ b/include/zenoh-pico/utils/uuid.h @@ -14,6 +14,16 @@ #include +#include "zenoh-pico/collections/string.h" +#include "zenoh-pico/protocol/core.h" + +#ifndef ZENOH_PICO_UTILS_UUID_H +#define ZENOH_PICO_UTILS_UUID_H + +#ifdef __cplusplus +extern "C" { +#endif + /** * Converts an UUID in string format to a byte array. * @@ -22,3 +32,20 @@ * uuid_str: A valid UUID string. */ void _z_uuid_to_bytes(uint8_t *bytes, const char *uuid_str); + +/** + * Converts an Zenoh ID to string. + * + * Parameters: + * id: Zenoh ID. + * + * Returns: + * ID string representation + */ +_z_string_t _z_id_to_string(const _z_id_t *id); + +#ifdef __cplusplus +} +#endif + +#endif /* ZENOH_PICO_UTILS_UUID_H */ diff --git a/src/api/api.c b/src/api/api.c index d5404d691..8ff30c7cf 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -549,15 +549,15 @@ static _z_encoding_t _z_encoding_from_owned(const z_owned_encoding_t *encoding) _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_sample_t, sample, _z_sample_check, _z_sample_null, _z_sample_copy, _z_sample_clear) _Z_OWNED_FUNCTIONS_RC_IMPL(session) -_Z_OWNED_FUNCTIONS_CLOSURE_IMPL(closure_sample, _z_sample_handler_t, z_dropper_handler_t) -_Z_OWNED_FUNCTIONS_CLOSURE_IMPL(closure_query, _z_query_handler_t, z_dropper_handler_t) -_Z_OWNED_FUNCTIONS_CLOSURE_IMPL(closure_reply, _z_reply_handler_t, z_dropper_handler_t) -_Z_OWNED_FUNCTIONS_CLOSURE_IMPL(closure_hello, z_loaned_hello_handler_t, z_dropper_handler_t) -_Z_OWNED_FUNCTIONS_CLOSURE_IMPL(closure_zid, z_zid_handler_t, z_dropper_handler_t) +_Z_OWNED_FUNCTIONS_CLOSURE_IMPL(closure_sample, _z_closure_sample_callback_t, z_closure_drop_callback_t) +_Z_OWNED_FUNCTIONS_CLOSURE_IMPL(closure_query, _z_closure_query_callback_t, z_closure_drop_callback_t) +_Z_OWNED_FUNCTIONS_CLOSURE_IMPL(closure_reply, _z_closure_reply_callback_t, z_closure_drop_callback_t) +_Z_OWNED_FUNCTIONS_CLOSURE_IMPL(closure_hello, z_closure_hello_callback_t, z_closure_drop_callback_t) +_Z_OWNED_FUNCTIONS_CLOSURE_IMPL(closure_zid, z_closure_zid_callback_t, z_closure_drop_callback_t) /************* Primitives **************/ typedef struct __z_hello_handler_wrapper_t { - z_loaned_hello_handler_t user_call; + z_closure_hello_callback_t user_call; void *ctx; } __z_hello_handler_wrapper_t; @@ -715,8 +715,7 @@ z_result_t z_info_routers_zid(const z_loaned_session_t *zs, z_moved_closure_zid_ z_id_t z_info_zid(const z_loaned_session_t *zs) { return _Z_RC_IN_VAL(zs)->_local_zid; } z_result_t z_id_to_string(const z_id_t *id, z_owned_string_t *str) { - _z_slice_t buf = _z_slice_alias_buf(id->id, sizeof(id->id)); - str->_val = _z_string_convert_bytes(&buf); + str->_val = _z_id_to_string(id); if (!_z_string_check(&str->_val)) { return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } @@ -828,12 +827,12 @@ z_result_t z_put(const z_loaned_session_t *zs, const z_loaned_keyexpr_t *keyexpr opt.priority, opt.is_express, opt.timestamp, _z_bytes_from_owned_bytes(&opt.attachment->_this), reliability); - // Trigger local subscriptions - _z_trigger_local_subscriptions( + // Trigger subscriptions + _z_trigger_subscriptions_put( _Z_RC_IN_VAL(zs), keyexpr_aliased, _z_bytes_from_owned_bytes(&payload->_this), - opt.encoding == NULL ? NULL : &opt.encoding->_this._val, + opt.encoding == NULL ? NULL : &opt.encoding->_this._val, opt.timestamp, _z_n_qos_make(opt.is_express, opt.congestion_control == Z_CONGESTION_CONTROL_BLOCK, opt.priority), - opt.timestamp, _z_bytes_from_owned_bytes(&opt.attachment->_this), reliability); + _z_bytes_from_owned_bytes(&opt.attachment->_this), reliability); // Clean-up z_encoding_drop(opt.encoding); z_bytes_drop(opt.attachment); @@ -961,11 +960,11 @@ z_result_t z_publisher_put(const z_loaned_publisher_t *pub, z_moved_bytes_t *pay Z_SAMPLE_KIND_PUT, pub->_congestion_control, pub->_priority, pub->_is_express, opt.timestamp, _z_bytes_from_owned_bytes(&opt.attachment->_this), reliability); } - // Trigger local subscriptions - _z_trigger_local_subscriptions( - _Z_RC_IN_VAL(&sess_rc), pub_keyexpr, _z_bytes_from_owned_bytes(&payload->_this), &encoding, + // Trigger subscriptions + _z_trigger_subscriptions_put( + _Z_RC_IN_VAL(&sess_rc), pub_keyexpr, _z_bytes_from_owned_bytes(&payload->_this), &encoding, opt.timestamp, _z_n_qos_make(pub->_is_express, pub->_congestion_control == Z_CONGESTION_CONTROL_BLOCK, pub->_priority), - opt.timestamp, _z_bytes_from_owned_bytes(&opt.attachment->_this), reliability); + _z_bytes_from_owned_bytes(&opt.attachment->_this), reliability); _z_session_rc_drop(&sess_rc); } else { @@ -1087,6 +1086,7 @@ const z_loaned_sample_t *z_reply_ok(const z_loaned_reply_t *reply) { return &rep const z_loaned_reply_err_t *z_reply_err(const z_loaned_reply_t *reply) { return &reply->data._result.error; } +#ifdef Z_FEATURE_UNSTABLE_API bool z_reply_replier_id(const z_loaned_reply_t *reply, z_id_t *out_id) { if (_z_id_check(reply->data.replier_id)) { *out_id = reply->data.replier_id; @@ -1094,7 +1094,9 @@ bool z_reply_replier_id(const z_loaned_reply_t *reply, z_id_t *out_id) { } return false; } -#endif +#endif // Z_FEATURE_UNSTABLE_API + +#endif // Z_FEATURE_QUERY == 1 #if Z_FEATURE_QUERYABLE == 1 _Z_OWNED_FUNCTIONS_RC_IMPL(query) @@ -1396,7 +1398,7 @@ z_result_t z_undeclare_subscriber(z_moved_subscriber_t *sub) { const z_loaned_keyexpr_t *z_subscriber_keyexpr(const z_loaned_subscriber_t *sub) { // Retrieve keyexpr from session uint32_t lookup = sub->_entity_id; - _z_subscription_rc_list_t *tail = _Z_RC_IN_VAL(&sub->_zn)->_local_subscriptions; + _z_subscription_rc_list_t *tail = _Z_RC_IN_VAL(&sub->_zn)->_subscriptions; while (tail != NULL) { _z_subscription_rc_t *head = _z_subscription_rc_list_head(tail); if (_Z_RC_IN_VAL(head)->_id == lookup) { diff --git a/src/api/encoding.c b/src/api/encoding.c index 8cbe24ae1..b4ff4cb18 100644 --- a/src/api/encoding.c +++ b/src/api/encoding.c @@ -262,4 +262,6 @@ z_result_t z_encoding_to_string(const z_loaned_encoding_t *encoding, z_owned_str return _Z_RES_OK; } +#if Z_FEATURE_ENCODING_VALUES == 1 const z_loaned_encoding_t *z_encoding_loan_default(void) { return z_encoding_zenoh_bytes(); } +#endif diff --git a/src/api/liveliness.c b/src/api/liveliness.c new file mode 100644 index 000000000..3fb2c63b1 --- /dev/null +++ b/src/api/liveliness.c @@ -0,0 +1,144 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +#include "zenoh-pico/api/liveliness.h" + +#include "zenoh-pico/api/primitives.h" +#include "zenoh-pico/net/liveliness.h" +#include "zenoh-pico/net/primitives.h" +#include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/protocol/keyexpr.h" +#include "zenoh-pico/utils/result.h" + +#if Z_FEATURE_LIVELINESS == 1 + +/**************** Liveliness Token ****************/ + +_Bool _z_liveliness_token_check(const _z_liveliness_token_t *token) { + _z_keyexpr_check(&token->_key); + return true; +} + +_z_liveliness_token_t _z_liveliness_token_null(void) { + _z_liveliness_token_t s = {0}; + s._key = _z_keyexpr_null(); + return s; +} + +void _z_liveliness_token_clear(_z_liveliness_token_t *token) { + _z_session_rc_t sess_rc = _z_session_weak_upgrade_if_open(&token->_zn); + if (!_Z_RC_IS_NULL(&sess_rc)) { + _z_undeclare_liveliness_token(token); + _z_session_rc_drop(&sess_rc); + } + _z_keyexpr_clear(&token->_key); +} + +_Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL(_z_liveliness_token_t, liveliness_token, _z_liveliness_token_check, + _z_liveliness_token_null, _z_liveliness_token_clear) + +z_result_t z_liveliness_token_options_default(z_liveliness_token_options_t *options) { + options->__dummy = 0; + return _Z_RES_OK; +} + +z_result_t z_liveliness_declare_token(const z_loaned_session_t *zs, z_owned_liveliness_token_t *token, + const z_loaned_keyexpr_t *keyexpr, const z_liveliness_token_options_t *options) { + (void)options; + + _z_keyexpr_t key = _z_update_keyexpr_to_declared(_Z_RC_IN_VAL(zs), *keyexpr); + + return _z_declare_liveliness_token(zs, &token->_val, key); +} + +z_result_t z_liveliness_undeclare_token(z_moved_liveliness_token_t *token) { + return _z_undeclare_liveliness_token(&token->_this._val); +} + +/**************** Liveliness Subscriber ****************/ + +#if Z_FEATURE_SUBSCRIPTION == 1 +z_result_t z_liveliness_subscriber_options_default(z_liveliness_subscriber_options_t *options) { + options->history = false; + return _Z_RES_OK; +} + +z_result_t z_liveliness_declare_subscriber(const z_loaned_session_t *zs, z_owned_subscriber_t *sub, + const z_loaned_keyexpr_t *keyexpr, z_moved_closure_sample_t *callback, + z_liveliness_subscriber_options_t *options) { + void *ctx = callback->_this._val.context; + callback->_this._val.context = NULL; + + z_liveliness_subscriber_options_t opt; + if (options == NULL) { + z_liveliness_subscriber_options_default(&opt); + } else { + opt = *options; + } + + _z_keyexpr_t key = _z_update_keyexpr_to_declared(_Z_RC_IN_VAL(zs), *keyexpr); + + _z_subscriber_t int_sub = _z_declare_liveliness_subscriber(zs, key, callback->_this._val.call, + callback->_this._val.drop, opt.history, ctx); + + z_internal_closure_sample_null(&callback->_this); + sub->_val = int_sub; + + if (!_z_subscriber_check(&sub->_val)) { + return _Z_ERR_SYSTEM_OUT_OF_MEMORY; + } + + if (opt.history) { + z_result_t ret = _z_liveliness_subscription_trigger_history(_Z_RC_IN_VAL(zs), *keyexpr); + if (ret != _Z_RES_OK) { + return ret; + } + } + + return _Z_RES_OK; +} +#endif // Z_FEATURE_SUBSCRIPTION == 1 + +/**************** Liveliness Query ****************/ + +#if Z_FEATURE_QUERY == 1 +z_result_t z_liveliness_get_options_default(z_liveliness_get_options_t *options) { + options->timeout_ms = Z_GET_TIMEOUT_DEFAULT; + return _Z_RES_OK; +} + +z_result_t z_liveliness_get(const z_loaned_session_t *zs, const z_loaned_keyexpr_t *keyexpr, + z_moved_closure_reply_t *callback, z_liveliness_get_options_t *options) { + z_result_t ret = _Z_RES_OK; + + void *ctx = callback->_this._val.context; + callback->_this._val.context = NULL; + + z_liveliness_get_options_t opt; + if (options == NULL) { + z_liveliness_get_options_default(&opt); + } else { + opt = *options; + } + + ret = _z_liveliness_query(_Z_RC_IN_VAL(zs), *keyexpr, callback->_this._val.call, callback->_this._val.drop, ctx, + opt.timeout_ms); + + z_internal_closure_reply_null( + &callback->_this); // call and drop passed to _z_liveliness_query, so we nullify the closure here + return ret; +} +#endif // Z_FEATURE_QUERY == 1 + +#endif // Z_FEATURE_LIVELINESS == 1 diff --git a/src/api/serialization.c b/src/api/serialization.c index b5ff623d6..c6b018593 100644 --- a/src/api/serialization.c +++ b/src/api/serialization.c @@ -84,9 +84,13 @@ z_result_t ze_deserializer_deserialize_slice(ze_deserializer_t *deserializer, z_ return Z_OK; } +z_result_t ze_serializer_serialize_substr(ze_loaned_serializer_t *serializer, const char *start, size_t len) { + // TODO: perform a UTF-8 correctness check. + return ze_serializer_serialize_buf(serializer, (const uint8_t *)start, len); +} + z_result_t ze_serializer_serialize_str(ze_loaned_serializer_t *serializer, const char *val) { - size_t len = strlen(val); - return ze_serializer_serialize_buf(serializer, (const uint8_t *)val, len); + return ze_serializer_serialize_substr(serializer, val, strlen(val)); } z_result_t ze_serializer_serialize_string(ze_loaned_serializer_t *serializer, const z_loaned_string_t *val) { @@ -121,6 +125,11 @@ z_result_t ze_deserialize_slice(const z_loaned_bytes_t *bytes, z_owned_slice_t * return ze_deserializer_deserialize_slice(&deserializer, data); } +z_result_t ze_serialize_substr(z_owned_bytes_t *bytes, const char *start, size_t len) { + _Z_BUILD_BYTES_FROM_SERIALIZER(ze_serializer_serialize_substr(&serializer, start, len)); + return _Z_RES_OK; +} + z_result_t ze_serialize_str(z_owned_bytes_t *bytes, const char *data) { _Z_BUILD_BYTES_FROM_SERIALIZER(ze_serializer_serialize_str(&serializer, data)); return _Z_RES_OK; diff --git a/src/collections/fifo_mt.c b/src/collections/fifo_mt.c index e8d735f94..91c918673 100644 --- a/src/collections/fifo_mt.c +++ b/src/collections/fifo_mt.c @@ -17,6 +17,7 @@ #include "zenoh-pico/protocol/codec/core.h" #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/utils/logging.h" +#include "zenoh-pico/utils/result.h" /*-------- Fifo Buffer Multithreaded --------*/ z_result_t _z_fifo_mt_init(_z_fifo_mt_t *fifo, size_t capacity) { diff --git a/src/collections/intmap.c b/src/collections/intmap.c index 004e61bdd..0d7eac9ad 100644 --- a/src/collections/intmap.c +++ b/src/collections/intmap.c @@ -68,6 +68,9 @@ z_result_t _z_int_void_map_copy(_z_int_void_map_t *dst, const _z_int_void_map_t _z_int_void_map_t _z_int_void_map_clone(const _z_int_void_map_t *src, z_element_clone_f f_c, z_element_free_f f_f) { _z_int_void_map_t dst = {._capacity = src->_capacity, ._vals = NULL}; + if (src->_vals == NULL) { + return dst; + } // Lazily allocate and initialize to NULL all the pointers size_t len = dst._capacity * sizeof(_z_list_t *); dst._vals = (_z_list_t **)z_malloc(len); @@ -144,6 +147,41 @@ void *_z_int_void_map_get(const _z_int_void_map_t *map, size_t k) { return ret; } +_z_int_void_map_iterator_t _z_int_void_map_iterator_make(const _z_int_void_map_t *map) { + _z_int_void_map_iterator_t iter = {0}; + + iter._map = map; + + return iter; +} + +bool _z_int_void_map_iterator_next(_z_int_void_map_iterator_t *iter) { + if (iter->_map->_vals == NULL) { + return false; + } + + while (iter->_idx < iter->_map->_capacity) { + if (iter->_list_ptr == NULL) { + iter->_list_ptr = iter->_map->_vals[iter->_idx]; + } else { + iter->_list_ptr = _z_list_tail(iter->_list_ptr); + } + if (iter->_list_ptr == NULL) { + iter->_idx++; + continue; + } + + iter->_entry = iter->_list_ptr->_val; + + return true; + } + return false; +} + +size_t _z_int_void_map_iterator_key(const _z_int_void_map_iterator_t *iter) { return iter->_entry->_key; } + +void *_z_int_void_map_iterator_value(const _z_int_void_map_iterator_t *iter) { return iter->_entry->_val; } + void _z_int_void_map_clear(_z_int_void_map_t *map, z_element_free_f f_f) { if (map->_vals != NULL) { for (size_t idx = 0; idx < map->_capacity; idx++) { diff --git a/src/collections/string.c b/src/collections/string.c index 753c7cad5..e734ee79a 100644 --- a/src/collections/string.c +++ b/src/collections/string.c @@ -113,7 +113,7 @@ bool _z_string_equals(const _z_string_t *left, const _z_string_t *right) { return (strncmp(_z_string_data(left), _z_string_data(right), _z_string_len(left)) == 0); } -_z_string_t _z_string_convert_bytes(const _z_slice_t *bs) { +_z_string_t _z_string_convert_bytes_le(const _z_slice_t *bs) { _z_string_t s = _z_string_null(); size_t len = bs->len * (size_t)2; char *s_val = (char *)z_malloc((len) * sizeof(char)); @@ -121,10 +121,11 @@ _z_string_t _z_string_convert_bytes(const _z_slice_t *bs) { return s; } - const char c[] = "0123456789ABCDEF"; + const char c[] = "0123456789abcdef"; + size_t pos = bs->len * 2; for (size_t i = 0; i < bs->len; i++) { - s_val[i * (size_t)2] = c[(bs->start[i] & (uint8_t)0xF0) >> (uint8_t)4]; - s_val[(i * (size_t)2) + 1] = c[bs->start[i] & (uint8_t)0x0F]; + s_val[--pos] = c[bs->start[i] & (uint8_t)0x0F]; + s_val[--pos] = c[(bs->start[i] & (uint8_t)0xF0) >> (uint8_t)4]; } s._slice = _z_slice_from_buf_custom_deleter((const uint8_t *)s_val, len, _z_delete_context_default()); return s; @@ -220,4 +221,8 @@ char *_z_str_n_clone(const char *src, size_t len) { return dst; } +char *_z_str_from_string_clone(const _z_string_t *str) { + return _z_str_n_clone((const char *)str->_slice.start, str->_slice.len); +} + bool _z_str_eq(const char *left, const char *right) { return strcmp(left, right) == 0; } diff --git a/src/net/liveliness.c b/src/net/liveliness.c new file mode 100644 index 000000000..45966698f --- /dev/null +++ b/src/net/liveliness.c @@ -0,0 +1,173 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, + +#include "zenoh-pico/api/liveliness.h" + +#include "zenoh-pico/net/primitives.h" +#include "zenoh-pico/protocol/definitions/interest.h" +#include "zenoh-pico/protocol/definitions/network.h" +#include "zenoh-pico/protocol/keyexpr.h" +#include "zenoh-pico/session/resource.h" +#include "zenoh-pico/session/session.h" +#include "zenoh-pico/session/subscription.h" +#include "zenoh-pico/session/utils.h" +#include "zenoh-pico/utils/result.h" + +#if Z_FEATURE_LIVELINESS == 1 + +/**************** Liveliness Token ****************/ + +z_result_t _z_declare_liveliness_token(const _z_session_rc_t *zn, _z_liveliness_token_t *ret_token, + _z_keyexpr_t keyexpr) { + z_result_t ret; + + uint32_t id = _z_get_entity_id(_Z_RC_IN_VAL(zn)); + + _z_declaration_t declaration = _z_make_decl_token(&keyexpr, id); + _z_network_message_t n_msg = _z_n_msg_make_declare(declaration, false, 0); + ret = _z_send_n_msg(_Z_RC_IN_VAL(zn), &n_msg, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK); + _z_n_msg_clear(&n_msg); + + _z_liveliness_register_token(_Z_RC_IN_VAL(zn), id, keyexpr); + + ret_token->_id = id; + _z_keyexpr_move(&ret_token->_key, &keyexpr); + ret_token->_zn = _z_session_rc_clone_as_weak(zn); + return ret; +} + +z_result_t _z_undeclare_liveliness_token(_z_liveliness_token_t *token) { + if (token == NULL || _Z_RC_IS_NULL(&token->_zn)) { + return _Z_ERR_ENTITY_UNKNOWN; + } + + z_result_t ret; + + _z_liveliness_unregister_token(_Z_RC_IN_VAL(&token->_zn), token->_id); + + _z_declaration_t declaration = _z_make_undecl_token(token->_id, &token->_key); + _z_network_message_t n_msg = _z_n_msg_make_declare(declaration, false, 0); + ret = _z_send_n_msg(_Z_RC_IN_VAL(&token->_zn), &n_msg, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK); + _z_n_msg_clear(&n_msg); + + return ret; +} + +/**************** Liveliness Subscriber ****************/ + +#if Z_FEATURE_SUBSCRIPTION == 1 +_z_subscriber_t _z_declare_liveliness_subscriber(const _z_session_rc_t *zn, _z_keyexpr_t keyexpr, + _z_closure_sample_callback_t callback, _z_drop_handler_t dropper, + bool history, void *arg) { + _z_subscription_t s; + s._id = _z_get_entity_id(_Z_RC_IN_VAL(zn)); + s._key_id = keyexpr._id; + s._key = _z_get_expanded_key_from_key(_Z_RC_IN_VAL(zn), &keyexpr); + s._callback = callback; + s._dropper = dropper; + s._arg = arg; + + _z_subscriber_t ret = _z_subscriber_null(); + // Register subscription, stored at session-level, do not drop it by the end of this function. + _z_subscription_rc_t *sp_s = + _z_register_subscription(_Z_RC_IN_VAL(zn), _Z_SUBSCRIBER_KIND_LIVELINESS_SUBSCRIBER, &s); + if (sp_s == NULL) { + _z_subscriber_clear(&ret); + return ret; + } + // Build the declare message to send on the wire + uint8_t mode = history ? (_Z_INTEREST_FLAG_CURRENT | _Z_INTEREST_FLAG_FUTURE) : _Z_INTEREST_FLAG_FUTURE; + _z_interest_t interest = _z_make_interest( + &keyexpr, s._id, _Z_INTEREST_FLAG_KEYEXPRS | _Z_INTEREST_FLAG_TOKENS | _Z_INTEREST_FLAG_RESTRICTED | mode); + + _z_network_message_t n_msg = _z_n_msg_make_interest(interest); + if (_z_send_n_msg(_Z_RC_IN_VAL(zn), &n_msg, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK) != _Z_RES_OK) { + _z_unregister_subscription(_Z_RC_IN_VAL(zn), _Z_SUBSCRIBER_KIND_LIVELINESS_SUBSCRIBER, sp_s); + _z_subscriber_clear(&ret); + return ret; + } + _z_n_msg_clear(&n_msg); + + ret._entity_id = s._id; + ret._zn = _z_session_rc_clone_as_weak(zn); + return ret; +} + +z_result_t _z_undeclare_liveliness_subscriber(_z_subscriber_t *sub) { + if (sub == NULL || _Z_RC_IS_NULL(&sub->_zn)) { + return _Z_ERR_ENTITY_UNKNOWN; + } + + _z_subscription_rc_t *s = + _z_get_subscription_by_id(_Z_RC_IN_VAL(&sub->_zn), _Z_SUBSCRIBER_KIND_LIVELINESS_SUBSCRIBER, sub->_entity_id); + if (s == NULL) { + return _Z_ERR_ENTITY_UNKNOWN; + } + + _z_interest_t interest = _z_make_interest_final(s->_val->_id); + _z_network_message_t n_msg = _z_n_msg_make_interest(interest); + if (_z_send_n_msg(_Z_RC_IN_VAL(&sub->_zn), &n_msg, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK) != + _Z_RES_OK) { + return _Z_ERR_TRANSPORT_TX_FAILED; + } + _z_n_msg_clear(&n_msg); + + _z_undeclare_resource(_Z_RC_IN_VAL(&sub->_zn), _Z_RC_IN_VAL(s)->_key_id); + _z_unregister_subscription(_Z_RC_IN_VAL(&sub->_zn), _Z_SUBSCRIBER_KIND_LIVELINESS_SUBSCRIBER, s); + return _Z_RES_OK; +} +#endif // Z_FEATURE_SUBSCRIPTION == 1 + +/**************** Liveliness Query ****************/ + +#if Z_FEATURE_QUERY == 1 +z_result_t _z_liveliness_query(_z_session_t *zn, _z_keyexpr_t keyexpr, _z_closure_reply_callback_t callback, + _z_drop_handler_t dropper, void *arg, uint64_t timeout_ms) { + z_result_t ret = _Z_RES_OK; + + // Create the pending liveliness query object + _z_liveliness_pending_query_t *pq = + (_z_liveliness_pending_query_t *)z_malloc(sizeof(_z_liveliness_pending_query_t)); + if (pq != NULL) { + uint32_t id = _z_liveliness_get_query_id(zn); + pq->_key = _z_get_expanded_key_from_key(zn, &keyexpr); + pq->_callback = callback; + pq->_dropper = dropper; + pq->_arg = arg; + + ret = _z_liveliness_register_pending_query(zn, id, pq); + if (ret == _Z_RES_OK) { + _ZP_UNUSED(timeout_ms); // Current interest in pico don't support timeout + + _z_interest_t interest = _z_make_interest(&keyexpr, id, + _Z_INTEREST_FLAG_KEYEXPRS | _Z_INTEREST_FLAG_TOKENS | + _Z_INTEREST_FLAG_RESTRICTED | _Z_INTEREST_FLAG_CURRENT); + + _z_network_message_t n_msg = _z_n_msg_make_interest(interest); + if (_z_send_n_msg(zn, &n_msg, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK) != _Z_RES_OK) { + _z_liveliness_unregister_pending_query(zn, id); + ret = _Z_ERR_TRANSPORT_TX_FAILED; + } + + _z_n_msg_clear(&n_msg); + + } else { + _z_liveliness_pending_query_clear(pq); + } + } + + return ret; +} +#endif // Z_FEATURE_QUERY == 1 + +#endif // Z_FEATURE_LIVELINESS == 1 diff --git a/src/net/primitives.c b/src/net/primitives.c index b2b8d9d7d..13a78eea8 100644 --- a/src/net/primitives.c +++ b/src/net/primitives.c @@ -21,16 +21,17 @@ #include "zenoh-pico/collections/slice.h" #include "zenoh-pico/config.h" #include "zenoh-pico/net/filtering.h" -#include "zenoh-pico/net/logger.h" -#include "zenoh-pico/net/sample.h" #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/protocol/definitions/declarations.h" +#include "zenoh-pico/protocol/definitions/interest.h" #include "zenoh-pico/protocol/definitions/network.h" #include "zenoh-pico/protocol/keyexpr.h" #include "zenoh-pico/session/interest.h" +#include "zenoh-pico/session/liveliness.h" #include "zenoh-pico/session/query.h" #include "zenoh-pico/session/queryable.h" #include "zenoh-pico/session/resource.h" +#include "zenoh-pico/session/session.h" #include "zenoh-pico/session/subscription.h" #include "zenoh-pico/session/utils.h" #include "zenoh-pico/utils/logging.h" @@ -38,7 +39,7 @@ /*------------------ Scouting ------------------*/ void _z_scout(const z_what_t what, const _z_id_t zid, _z_string_t *locator, const uint32_t timeout, - _z_hello_handler_t callback, void *arg_call, _z_drop_handler_t dropper, void *arg_drop) { + _z_closure_hello_callback_t callback, void *arg_call, _z_drop_handler_t dropper, void *arg_drop) { _z_hello_list_t *hellos = _z_scout_inner(what, zid, locator, timeout, false); while (hellos != NULL) { @@ -100,6 +101,27 @@ z_result_t _z_undeclare_resource(_z_session_t *zn, uint16_t rid) { return ret; } +// TODO(sashacmc): currently used only for liveliness, because it have little bit different behavior from others +// It seems also correct for z_declare_queryable and z_declare_publisher, but it need to be verified +_z_keyexpr_t _z_update_keyexpr_to_declared(_z_session_t *zs, _z_keyexpr_t keyexpr) { + _z_keyexpr_t keyexpr_aliased = _z_keyexpr_alias_from_user_defined(keyexpr, true); + _z_keyexpr_t key = keyexpr_aliased; + + // TODO: Currently, if resource declarations are done over multicast transports, the current protocol definition + // lacks a way to convey them to later-joining nodes. Thus, in the current version automatic + // resource declarations are only performed on unicast transports. + if (zs->_tp._type == _Z_TRANSPORT_UNICAST_TYPE) { + _z_resource_t *r = _z_get_resource_by_key(zs, &keyexpr_aliased); + if (r != NULL) { + key = _z_rid_with_suffix(r->_id, NULL); + } else { + uint16_t id = _z_declare_resource(zs, keyexpr_aliased); + key = _z_rid_with_suffix(id, NULL); + } + } + return key; +} + #if Z_FEATURE_PUBLICATION == 1 /*------------------ Publisher Declaration ------------------*/ _z_publisher_t _z_declare_publisher(const _z_session_rc_t *zn, _z_keyexpr_t keyexpr, _z_encoding_t *encoding, @@ -192,8 +214,8 @@ z_result_t _z_write(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_bytes #if Z_FEATURE_SUBSCRIPTION == 1 /*------------------ Subscriber Declaration ------------------*/ -_z_subscriber_t _z_declare_subscriber(const _z_session_rc_t *zn, _z_keyexpr_t keyexpr, _z_sample_handler_t callback, - _z_drop_handler_t dropper, void *arg) { +_z_subscriber_t _z_declare_subscriber(const _z_session_rc_t *zn, _z_keyexpr_t keyexpr, + _z_closure_sample_callback_t callback, _z_drop_handler_t dropper, void *arg) { _z_subscription_t s; s._id = _z_get_entity_id(_Z_RC_IN_VAL(zn)); s._key_id = keyexpr._id; @@ -204,7 +226,7 @@ _z_subscriber_t _z_declare_subscriber(const _z_session_rc_t *zn, _z_keyexpr_t ke _z_subscriber_t ret = _z_subscriber_null(); // Register subscription, stored at session-level, do not drop it by the end of this function. - _z_subscription_rc_t *sp_s = _z_register_subscription(_Z_RC_IN_VAL(zn), _Z_RESOURCE_IS_LOCAL, &s); + _z_subscription_rc_t *sp_s = _z_register_subscription(_Z_RC_IN_VAL(zn), _Z_SUBSCRIBER_KIND_SUBSCRIBER, &s); if (sp_s == NULL) { _z_subscriber_clear(&ret); return ret; @@ -213,7 +235,7 @@ _z_subscriber_t _z_declare_subscriber(const _z_session_rc_t *zn, _z_keyexpr_t ke _z_declaration_t declaration = _z_make_decl_subscriber(&keyexpr, s._id); _z_network_message_t n_msg = _z_n_msg_make_declare(declaration, false, 0); if (_z_send_n_msg(_Z_RC_IN_VAL(zn), &n_msg, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK) != _Z_RES_OK) { - _z_unregister_subscription(_Z_RC_IN_VAL(zn), _Z_RESOURCE_IS_LOCAL, sp_s); + _z_unregister_subscription(_Z_RC_IN_VAL(zn), _Z_SUBSCRIBER_KIND_SUBSCRIBER, sp_s); _z_subscriber_clear(&ret); return ret; } @@ -229,7 +251,8 @@ z_result_t _z_undeclare_subscriber(_z_subscriber_t *sub) { return _Z_ERR_ENTITY_UNKNOWN; } // Find subscription entry - _z_subscription_rc_t *s = _z_get_subscription_by_id(_Z_RC_IN_VAL(&sub->_zn), _Z_RESOURCE_IS_LOCAL, sub->_entity_id); + _z_subscription_rc_t *s = + _z_get_subscription_by_id(_Z_RC_IN_VAL(&sub->_zn), _Z_SUBSCRIBER_KIND_SUBSCRIBER, sub->_entity_id); if (s == NULL) { return _Z_ERR_ENTITY_UNKNOWN; } @@ -248,7 +271,7 @@ z_result_t _z_undeclare_subscriber(_z_subscriber_t *sub) { _z_n_msg_clear(&n_msg); // Only if message is successfully send, local subscription state can be removed _z_undeclare_resource(_Z_RC_IN_VAL(&sub->_zn), _Z_RC_IN_VAL(s)->_key_id); - _z_unregister_subscription(_Z_RC_IN_VAL(&sub->_zn), _Z_RESOURCE_IS_LOCAL, s); + _z_unregister_subscription(_Z_RC_IN_VAL(&sub->_zn), _Z_SUBSCRIBER_KIND_SUBSCRIBER, s); return _Z_RES_OK; } #endif @@ -256,7 +279,7 @@ z_result_t _z_undeclare_subscriber(_z_subscriber_t *sub) { #if Z_FEATURE_QUERYABLE == 1 /*------------------ Queryable Declaration ------------------*/ _z_queryable_t _z_declare_queryable(const _z_session_rc_t *zn, _z_keyexpr_t keyexpr, bool complete, - _z_query_handler_t callback, _z_drop_handler_t dropper, void *arg) { + _z_closure_query_callback_t callback, _z_drop_handler_t dropper, void *arg) { _z_session_queryable_t q; q._id = _z_get_entity_id(_Z_RC_IN_VAL(zn)); q._key = _z_get_expanded_key_from_key(_Z_RC_IN_VAL(zn), &keyexpr); @@ -452,7 +475,7 @@ z_result_t _z_send_reply_err(const _z_query_t *query, const _z_session_rc_t *zsr #if Z_FEATURE_QUERY == 1 /*------------------ Query ------------------*/ z_result_t _z_query(_z_session_t *zn, _z_keyexpr_t keyexpr, const char *parameters, const z_query_target_t target, - const z_consolidation_mode_t consolidation, _z_value_t value, _z_reply_handler_t callback, + const z_consolidation_mode_t consolidation, _z_value_t value, _z_closure_reply_callback_t callback, _z_drop_handler_t dropper, void *arg, uint64_t timeout_ms, const _z_bytes_t attachment, z_congestion_control_t cong_ctrl, z_priority_t priority, bool is_express) { z_result_t ret = _Z_RES_OK; diff --git a/src/net/session.c b/src/net/session.c index 0e8fcac4e..a71cbcc3e 100644 --- a/src/net/session.c +++ b/src/net/session.c @@ -166,11 +166,8 @@ _z_config_t *_z_info(const _z_session_t *zn) { _z_config_t *ps = (_z_config_t *)z_malloc(sizeof(_z_config_t)); if (ps != NULL) { _z_config_init(ps); - _z_slice_t local_zid = _z_slice_alias_buf(zn->_local_zid.id, _z_id_len(zn->_local_zid)); - // TODO(sasahcmc): is it zero terminated??? - // rework it!!! - _z_string_t s = _z_string_convert_bytes(&local_zid); - _zp_config_insert(ps, Z_INFO_PID_KEY, _z_string_data(&s)); + _z_string_t s = _z_id_to_string(&zn->_local_zid); + _zp_config_insert_string(ps, Z_INFO_PID_KEY, &s); _z_string_clear(&s); switch (zn->_tp._type) { diff --git a/src/protocol/config.c b/src/protocol/config.c index dcdb4f904..1cfcff9c3 100644 --- a/src/protocol/config.c +++ b/src/protocol/config.c @@ -19,6 +19,7 @@ #include #include +#include "zenoh-pico/collections/string.h" #include "zenoh-pico/utils/pointers.h" z_result_t _z_config_init(_z_config_t *ps) { @@ -37,6 +38,18 @@ z_result_t _zp_config_insert(_z_config_t *ps, uint8_t key, const char *value) { return ret; } +z_result_t _zp_config_insert_string(_z_config_t *ps, uint8_t key, const _z_string_t *value) { + z_result_t ret = _Z_RES_OK; + char *str = _z_str_from_string_clone(value); + char *res = _z_str_intmap_insert(ps, key, str); + if (strcmp(res, str) != 0) { + ret = _Z_ERR_CONFIG_FAILED_INSERT; + } + z_free(str); + + return ret; +} + char *_z_config_get(const _z_config_t *ps, uint8_t key) { return _z_str_intmap_get(ps, key); } /*------------------ int-string map ------------------*/ diff --git a/src/protocol/keyexpr.c b/src/protocol/keyexpr.c index a097b2c40..e27180f63 100644 --- a/src/protocol/keyexpr.c +++ b/src/protocol/keyexpr.c @@ -48,6 +48,11 @@ _z_keyexpr_t _z_keyexpr_from_substr(uint16_t rid, const char *str, size_t len) { }; } +size_t _z_keyexpr_size(_z_keyexpr_t *p) { + _ZP_UNUSED(p); + return sizeof(_z_keyexpr_t); +} + z_result_t _z_keyexpr_copy(_z_keyexpr_t *dst, const _z_keyexpr_t *src) { *dst = _z_keyexpr_null(); dst->_id = src->_id; @@ -65,17 +70,21 @@ _z_keyexpr_t _z_keyexpr_duplicate(_z_keyexpr_t src) { return dst; } +_z_keyexpr_t *_z_keyexpr_clone(const _z_keyexpr_t *src) { + _z_keyexpr_t *dst = z_malloc(sizeof(_z_keyexpr_t)); + if (dst != NULL) { + _z_keyexpr_copy(dst, src); + } + return dst; +} + _z_keyexpr_t _z_keyexpr_steal(_Z_MOVE(_z_keyexpr_t) src) { _z_keyexpr_t stolen = *src; *src = _z_keyexpr_null(); return stolen; } -void _z_keyexpr_move(_z_keyexpr_t *dst, _z_keyexpr_t *src) { - dst->_id = src->_id; - dst->_mapping = src->_mapping; - _z_string_move(&dst->_suffix, &src->_suffix); -} +void _z_keyexpr_move(_z_keyexpr_t *dst, _z_keyexpr_t *src) { *dst = _z_keyexpr_steal(src); } void _z_keyexpr_clear(_z_keyexpr_t *rk) { rk->_id = 0; diff --git a/src/session/interest.c b/src/session/interest.c index a16884ee7..d0d7e407d 100644 --- a/src/session/interest.c +++ b/src/session/interest.c @@ -21,10 +21,12 @@ #include "zenoh-pico/net/query.h" #include "zenoh-pico/protocol/codec/core.h" #include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/protocol/definitions/declarations.h" #include "zenoh-pico/protocol/definitions/network.h" #include "zenoh-pico/protocol/keyexpr.h" #include "zenoh-pico/session/queryable.h" #include "zenoh-pico/session/resource.h" +#include "zenoh-pico/session/session.h" #include "zenoh-pico/session/utils.h" #include "zenoh-pico/utils/logging.h" @@ -117,7 +119,7 @@ static z_result_t _z_interest_send_decl_resource(_z_session_t *zn, uint32_t inte #if Z_FEATURE_SUBSCRIPTION == 1 static z_result_t _z_interest_send_decl_subscriber(_z_session_t *zn, uint32_t interest_id) { _zp_session_lock_mutex(zn); - _z_subscription_rc_list_t *sub_list = _z_subscription_rc_list_clone(zn->_local_subscriptions); + _z_subscription_rc_list_t *sub_list = _z_subscription_rc_list_clone(zn->_subscriptions); _zp_session_unlock_mutex(zn); _z_subscription_rc_list_t *xs = sub_list; while (xs != NULL) { @@ -173,6 +175,35 @@ static z_result_t _z_interest_send_decl_queryable(_z_session_t *zn, uint32_t int } #endif +#if Z_FEATURE_LIVELINESS == 1 +static z_result_t _z_interest_send_decl_token(_z_session_t *zn, uint32_t interest_id) { + _zp_session_lock_mutex(zn); + _z_keyexpr_intmap_t token_list = _z_keyexpr_intmap_clone(&zn->_local_tokens); + _zp_session_unlock_mutex(zn); + _z_keyexpr_intmap_iterator_t iter = _z_keyexpr_intmap_iterator_make(&token_list); + while (_z_keyexpr_intmap_iterator_next(&iter)) { + // Build the declare message to send on the wire + uint32_t id = (uint32_t)_z_keyexpr_intmap_iterator_key(&iter); + _z_keyexpr_t key = *_z_keyexpr_intmap_iterator_value(&iter); + _z_declaration_t declaration = _z_make_decl_token(&key, id); + _z_network_message_t n_msg = _z_n_msg_make_declare(declaration, true, interest_id); + if (_z_send_n_msg(zn, &n_msg, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK) != _Z_RES_OK) { + return _Z_ERR_TRANSPORT_TX_FAILED; + } + _z_n_msg_clear(&n_msg); + } + _z_keyexpr_intmap_clear(&token_list); + + return _Z_RES_OK; +} +#else +static z_result_t _z_interest_send_decl_token(_z_session_t *zn, uint32_t interest_id) { + _ZP_UNUSED(zn); + _ZP_UNUSED(interest_id); + return _Z_RES_OK; +} +#endif + static z_result_t _z_interest_send_declare_final(_z_session_t *zn, uint32_t interest_id) { _z_declaration_t decl = _z_make_decl_final(); _z_network_message_t n_msg = _z_n_msg_make_declare(decl, true, interest_id); @@ -265,6 +296,13 @@ z_result_t _z_interest_process_declares(_z_session_t *zn, const _z_declaration_t decl_type = _Z_DECLARE_TYPE_QUERYABLE; flags = _Z_INTEREST_FLAG_QUERYABLES; break; + case _Z_DECL_TOKEN: + msg.type = _Z_INTEREST_MSG_TYPE_DECL_TOKEN; + msg.id = decl->_body._decl_token._id; + decl_key = &decl->_body._decl_token._keyexpr; + decl_type = _Z_DECLARE_TYPE_TOKEN; + flags = _Z_INTEREST_FLAG_TOKENS; + break; default: return _Z_ERR_MESSAGE_ZENOH_DECLARATION_UNKNOWN; } @@ -312,6 +350,12 @@ z_result_t _z_interest_process_undeclares(_z_session_t *zn, const _z_declaration decl_type = _Z_DECLARE_TYPE_QUERYABLE; flags = _Z_INTEREST_FLAG_QUERYABLES; break; + case _Z_UNDECL_TOKEN: + msg.type = _Z_INTEREST_MSG_TYPE_UNDECL_TOKEN; + msg.id = decl->_body._undecl_token._id; + decl_type = _Z_DECLARE_TYPE_TOKEN; + flags = _Z_INTEREST_FLAG_TOKENS; + break; default: return _Z_ERR_MESSAGE_ZENOH_DECLARATION_UNKNOWN; } @@ -402,7 +446,8 @@ z_result_t _z_interest_process_interest(_z_session_t *zn, _z_keyexpr_t key, uint _Z_RETURN_IF_ERR(_z_interest_send_decl_queryable(zn, id)); } if (_Z_HAS_FLAG(flags, _Z_INTEREST_FLAG_TOKENS)) { - // Zenoh pico doesn't support liveliness token for now + _Z_DEBUG("Sending declare tokens"); + _Z_RETURN_IF_ERR(_z_interest_send_decl_token(zn, id)); } // Send final declare _Z_RETURN_IF_ERR(_z_interest_send_declare_final(zn, id)); diff --git a/src/session/liveliness.c b/src/session/liveliness.c new file mode 100644 index 000000000..a02a99cc3 --- /dev/null +++ b/src/session/liveliness.c @@ -0,0 +1,336 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +#include "zenoh-pico/api/liveliness.h" + +#include +#include + +#include "zenoh-pico/api/primitives.h" +#include "zenoh-pico/collections/bytes.h" +#include "zenoh-pico/config.h" +#include "zenoh-pico/net/reply.h" +#include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/protocol/keyexpr.h" +#include "zenoh-pico/session/resource.h" +#include "zenoh-pico/session/session.h" +#include "zenoh-pico/session/subscription.h" +#include "zenoh-pico/session/utils.h" +#include "zenoh-pico/utils/logging.h" +#include "zenoh-pico/utils/result.h" + +#if Z_FEATURE_LIVELINESS == 1 + +/**************** Liveliness Token ****************/ + +z_result_t _z_liveliness_register_token(_z_session_t *zn, uint32_t id, const _z_keyexpr_t keyexpr) { + z_result_t ret = _Z_RES_OK; + + _Z_DEBUG("Register liveliness token (%i:%.*s)", (int)id, (int)_z_string_len(&keyexpr._suffix), + _z_string_data(&keyexpr._suffix)); + + _zp_session_lock_mutex(zn); + + const _z_keyexpr_t *pkeyexpr = _z_keyexpr_intmap_get(&zn->_local_tokens, id); + if (pkeyexpr != NULL) { + _Z_ERROR("Duplicate token id %i", (int)id); + ret = _Z_ERR_ENTITY_DECLARATION_FAILED; + } else { + _z_keyexpr_intmap_insert(&zn->_local_tokens, id, _z_keyexpr_clone(&keyexpr)); + } + + _zp_session_unlock_mutex(zn); + + return ret; +} + +void _z_liveliness_unregister_token(_z_session_t *zn, uint32_t id) { + _zp_session_lock_mutex(zn); + + _Z_DEBUG("Unregister liveliness token (%i)", (int)id); + + _z_keyexpr_intmap_remove(&zn->_local_tokens, id); + + _zp_session_unlock_mutex(zn); +} + +/**************** Liveliness Subscriber ****************/ + +#if Z_FEATURE_SUBSCRIPTION == 1 +z_result_t _z_liveliness_subscription_declare(_z_session_t *zn, uint32_t id, const _z_keyexpr_t keyexpr, + const _z_timestamp_t *timestamp) { + z_result_t ret = _Z_RES_OK; + + _zp_session_lock_mutex(zn); + + const _z_keyexpr_t *pkeyexpr = _z_keyexpr_intmap_get(&zn->_remote_tokens, id); + if (pkeyexpr != NULL) { + _Z_ERROR("Duplicate token id %i", (int)id); + ret = _Z_ERR_ENTITY_DECLARATION_FAILED; + } else { + _z_keyexpr_intmap_insert(&zn->_remote_tokens, id, _z_keyexpr_clone(&keyexpr)); + } + + _zp_session_unlock_mutex(zn); + + if (ret == _Z_RES_OK) { + ret = _z_trigger_liveliness_subscriptions_declare(zn, keyexpr, timestamp); + } + + return ret; +} + +z_result_t _z_liveliness_subscription_undeclare(_z_session_t *zn, uint32_t id, const _z_timestamp_t *timestamp) { + z_result_t ret = _Z_RES_OK; + + _z_keyexpr_t *key = NULL; + _zp_session_lock_mutex(zn); + const _z_keyexpr_t *keyexpr = _z_keyexpr_intmap_get(&zn->_remote_tokens, id); + if (keyexpr != NULL) { + key = _z_keyexpr_clone(keyexpr); + _z_keyexpr_intmap_remove(&zn->_remote_tokens, id); + } else { + ret = _Z_ERR_ENTITY_UNKNOWN; + } + _zp_session_unlock_mutex(zn); + + if (key != NULL) { + ret = _z_trigger_liveliness_subscriptions_undeclare(zn, *key, timestamp); + _z_keyexpr_clear(key); + } + + return ret; +} + +z_result_t _z_liveliness_subscription_trigger_history(_z_session_t *zn, _z_keyexpr_t keyexpr) { + z_result_t ret = _Z_RES_OK; + + _Z_DEBUG("Retrieve liveliness history for %.*s", (int)_z_string_len(&keyexpr._suffix), + _z_string_data(&keyexpr._suffix)); + + _zp_session_lock_mutex(zn); + _z_keyexpr_intmap_t token_list = _z_keyexpr_intmap_clone(&zn->_remote_tokens); + _zp_session_unlock_mutex(zn); + + _z_keyexpr_intmap_iterator_t iter = _z_keyexpr_intmap_iterator_make(&token_list); + _z_timestamp_t tm = _z_timestamp_null(); + while (_z_keyexpr_intmap_iterator_next(&iter)) { + _z_keyexpr_t key = *_z_keyexpr_intmap_iterator_value(&iter); + if (_z_keyexpr_suffix_intersects(&key, &keyexpr)) { + ret = _z_trigger_liveliness_subscriptions_declare(zn, key, &tm); + if (ret != _Z_RES_OK) { + break; + } + } + } + _z_keyexpr_intmap_clear(&token_list); + + return ret; +} +#endif // Z_FEATURE_SUBSCRIPTION == 1 + +/**************** Liveliness Query ****************/ + +#if Z_FEATURE_QUERY == 1 + +void _z_liveliness_pending_query_clear(_z_liveliness_pending_query_t *pen_qry) { + if (pen_qry->_dropper != NULL) { + pen_qry->_dropper(pen_qry->_arg); + } + _z_keyexpr_clear(&pen_qry->_key); +} + +void _z_liveliness_pending_query_copy(_z_liveliness_pending_query_t *dst, const _z_liveliness_pending_query_t *src) { + dst->_arg = src->_arg; + dst->_callback = src->_callback; + dst->_dropper = src->_dropper; + _z_keyexpr_copy(&dst->_key, &src->_key); +} + +_z_liveliness_pending_query_t *_z_liveliness_pending_query_clone(const _z_liveliness_pending_query_t *src) { + _z_liveliness_pending_query_t *dst = z_malloc(sizeof(_z_liveliness_pending_query_t)); + if (dst != NULL) { + _z_liveliness_pending_query_copy(dst, src); + } + return dst; +} + +uint32_t _z_liveliness_get_query_id(_z_session_t *zn) { return zn->_liveliness_query_id++; } + +z_result_t _z_liveliness_register_pending_query(_z_session_t *zn, uint32_t id, _z_liveliness_pending_query_t *pen_qry) { + z_result_t ret = _Z_RES_OK; + + _Z_DEBUG("Register liveliness query for (%ju:%.*s)", (uintmax_t)pen_qry->_key._id, + (int)_z_string_len(&pen_qry->_key._suffix), _z_string_data(&pen_qry->_key._suffix)); + + _zp_session_lock_mutex(zn); + + const _z_liveliness_pending_query_t *pq = + _z_liveliness_pending_query_intmap_get(&zn->_liveliness_pending_queries, id); + if (pq != NULL) { + _Z_ERROR("Duplicate liveliness query id %i", (int)id); + ret = _Z_ERR_ENTITY_DECLARATION_FAILED; + } else { + _z_liveliness_pending_query_intmap_insert(&zn->_liveliness_pending_queries, id, + _z_liveliness_pending_query_clone(pen_qry)); + } + + _zp_session_unlock_mutex(zn); + + return ret; +} + +z_result_t _z_liveliness_pending_query_reply(_z_session_t *zn, uint32_t interest_id, const _z_keyexpr_t keyexpr, + const _z_timestamp_t *timestamp) { + z_result_t ret = _Z_RES_OK; + + _zp_session_lock_mutex(zn); + + const _z_liveliness_pending_query_t *pq = + _z_liveliness_pending_query_intmap_get(&zn->_liveliness_pending_queries, interest_id); + if (pq == NULL) { + ret = _Z_ERR_ENTITY_UNKNOWN; + } + + _Z_DEBUG("Liveliness pending query reply %i resolve result %i", (int)interest_id, ret); + + if (ret == _Z_RES_OK) { + _Z_DEBUG("Resolving %d - %.*s on mapping 0x%x", keyexpr._id, (int)_z_string_len(&keyexpr._suffix), + _z_string_data(&keyexpr._suffix), _z_keyexpr_mapping_id(&keyexpr)); + _z_keyexpr_t expanded_ke = __unsafe_z_get_expanded_key_from_key(zn, &keyexpr); + _Z_DEBUG("Reply liveliness query for %d - %.*s", expanded_ke._id, (int)_z_string_len(&expanded_ke._suffix), + _z_string_data(&expanded_ke._suffix)); + + if (!_z_keyexpr_suffix_intersects(&pq->_key, &expanded_ke)) { + ret = _Z_ERR_QUERY_NOT_MATCH; + } + + if (ret == _Z_RES_OK) { + _z_encoding_t encoding = _z_encoding_null(); + _z_reply_t reply = _z_reply_create(expanded_ke, zn->_local_zid, _z_bytes_null(), timestamp, &encoding, + Z_SAMPLE_KIND_PUT, _z_bytes_null()); + + pq->_callback(&reply, pq->_arg); + _z_reply_clear(&reply); + } + } + + _zp_session_unlock_mutex(zn); + + return ret; +} + +z_result_t _z_liveliness_pending_query_drop(_z_session_t *zn, uint32_t interest_id) { + z_result_t ret = _Z_RES_OK; + + _zp_session_lock_mutex(zn); + + const _z_liveliness_pending_query_t *pq = + _z_liveliness_pending_query_intmap_get(&zn->_liveliness_pending_queries, interest_id); + if (pq == NULL) { + ret = _Z_ERR_ENTITY_UNKNOWN; + } + + _Z_DEBUG("Liveliness pending query drop %i resolve result %i", (int)interest_id, ret); + + if (ret == _Z_RES_OK) { + _z_liveliness_pending_query_intmap_remove(&zn->_liveliness_pending_queries, interest_id); + } + + _zp_session_unlock_mutex(zn); + + return ret; +} + +void _z_liveliness_unregister_pending_query(_z_session_t *zn, uint32_t id) { + _zp_session_lock_mutex(zn); + + _z_liveliness_pending_query_intmap_remove(&zn->_liveliness_pending_queries, id); + + _zp_session_unlock_mutex(zn); +} + +#endif // Z_FEATURE_QUERY == 1 + +/**************** Interest processing ****************/ + +z_result_t _z_liveliness_process_token_declare(_z_session_t *zn, const _z_n_msg_declare_t *decl) { +#if Z_FEATURE_QUERY == 1 + if (decl->has_interest_id) { + _z_liveliness_pending_query_reply(zn, decl->_interest_id, decl->_decl._body._decl_token._keyexpr, + &decl->_ext_timestamp); + } +#endif + +#if Z_FEATURE_SUBSCRIPTION == 1 + return _z_liveliness_subscription_declare(zn, decl->_decl._body._decl_token._id, + decl->_decl._body._decl_token._keyexpr, &decl->_ext_timestamp); +#else + _ZP_UNUSED(zn); + _ZP_UNUSED(decl); + return _Z_RES_OK; +#endif +} + +z_result_t _z_liveliness_process_token_undeclare(_z_session_t *zn, const _z_n_msg_declare_t *decl) { +#if Z_FEATURE_SUBSCRIPTION == 1 + return _z_liveliness_subscription_undeclare(zn, decl->_decl._body._undecl_token._id, &decl->_ext_timestamp); +#else + _ZP_UNUSED(zn); + _ZP_UNUSED(decl); + return _Z_RES_OK; +#endif +} + +z_result_t _z_liveliness_process_declare_final(_z_session_t *zn, const _z_n_msg_declare_t *decl) { +#if Z_FEATURE_QUERY == 1 + if (decl->has_interest_id) { + _z_liveliness_pending_query_drop(zn, decl->_interest_id); + } + return _Z_RES_OK; +#else + _ZP_UNUSED(zn); + _ZP_UNUSED(decl); + return _Z_RES_OK; +#endif +} + +/**************** Init/Clear ****************/ + +void _z_liveliness_init(_z_session_t *zn) { + _zp_session_lock_mutex(zn); + + zn->_remote_tokens = _z_keyexpr_intmap_make(); + zn->_local_tokens = _z_keyexpr_intmap_make(); +#if Z_FEATURE_QUERY == 1 + zn->_liveliness_query_id = 1; + zn->_liveliness_pending_queries = _z_liveliness_pending_query_intmap_make(); +#endif + + _zp_session_unlock_mutex(zn); +} + +void _z_liveliness_clear(_z_session_t *zn) { + _zp_session_lock_mutex(zn); + +#if Z_FEATURE_QUERY == 1 + _z_liveliness_pending_query_intmap_clear(&zn->_liveliness_pending_queries); +#endif + _z_keyexpr_intmap_clear(&zn->_local_tokens); + _z_keyexpr_intmap_clear(&zn->_remote_tokens); + + _zp_session_unlock_mutex(zn); +} + +#endif // Z_FEATURE_LIVELINESS == 1 diff --git a/src/session/push.c b/src/session/push.c index 6b45de25b..6f0a6c371 100644 --- a/src/session/push.c +++ b/src/session/push.c @@ -27,17 +27,14 @@ z_result_t _z_trigger_push(_z_session_t *zn, _z_n_msg_push_t *push, z_reliabilit // TODO check body to know where to dispatch - size_t kind = push->_body._is_put ? Z_SAMPLE_KIND_PUT : Z_SAMPLE_KIND_DELETE; if (push->_body._is_put) { _z_msg_put_t *put = &push->_body._body._put; - ret = _z_trigger_subscriptions(zn, push->_key, put->_payload, &put->_encoding, kind, &put->_commons._timestamp, - push->_qos, put->_attachment, reliability); + ret = _z_trigger_subscriptions_put(zn, push->_key, put->_payload, &put->_encoding, &put->_commons._timestamp, + push->_qos, put->_attachment, reliability); } else { - _z_encoding_t encoding = _z_encoding_null(); - _z_bytes_t payload = _z_bytes_null(); _z_msg_del_t *del = &push->_body._body._del; - ret = _z_trigger_subscriptions(zn, push->_key, payload, &encoding, kind, &del->_commons._timestamp, push->_qos, - del->_attachment, reliability); + ret = _z_trigger_subscriptions_del(zn, push->_key, &del->_commons._timestamp, push->_qos, del->_attachment, + reliability); } return ret; } diff --git a/src/session/resource.c b/src/session/resource.c index b573e600a..ec8f90703 100644 --- a/src/session/resource.c +++ b/src/session/resource.c @@ -31,6 +31,11 @@ bool _z_resource_eq(const _z_resource_t *other, const _z_resource_t *this_) { re void _z_resource_clear(_z_resource_t *res) { _z_keyexpr_clear(&res->_key); } +size_t _z_resource_size(_z_resource_t *p) { + _ZP_UNUSED(p); + return sizeof(_z_resource_t); +} + void _z_resource_copy(_z_resource_t *dst, const _z_resource_t *src) { _z_keyexpr_copy(&dst->_key, &src->_key); dst->_id = src->_id; diff --git a/src/session/rx.c b/src/session/rx.c index afacc75d7..df53fe63e 100644 --- a/src/session/rx.c +++ b/src/session/rx.c @@ -25,11 +25,11 @@ #include "zenoh-pico/protocol/definitions/network.h" #include "zenoh-pico/protocol/keyexpr.h" #include "zenoh-pico/session/interest.h" +#include "zenoh-pico/session/liveliness.h" #include "zenoh-pico/session/push.h" #include "zenoh-pico/session/queryable.h" #include "zenoh-pico/session/reply.h" #include "zenoh-pico/session/resource.h" -#include "zenoh-pico/session/session.h" #include "zenoh-pico/session/subscription.h" #include "zenoh-pico/session/utils.h" #include "zenoh-pico/utils/logging.h" @@ -41,8 +41,8 @@ z_result_t _z_handle_network_message(_z_session_rc_t *zsrc, _z_zenoh_message_t * switch (msg->_tag) { case _Z_N_DECLARE: { - _Z_DEBUG("Handling _Z_N_DECLARE"); _z_n_msg_declare_t *decl = &msg->_body._declare; + _Z_DEBUG("Handling _Z_N_DECLARE: %i", decl->_decl._tag); switch (decl->_decl._tag) { case _Z_DECL_KEXPR: { if (_z_register_resource(zn, decl->_decl._body._decl_kexpr._keyexpr, @@ -59,19 +59,28 @@ z_result_t _z_handle_network_message(_z_session_rc_t *zsrc, _z_zenoh_message_t * case _Z_DECL_QUERYABLE: { _z_interest_process_declares(zn, &decl->_decl); } break; + case _Z_DECL_TOKEN: { +#if Z_FEATURE_LIVELINESS == 1 + _z_liveliness_process_token_declare(zn, decl); +#endif + _z_interest_process_declares(zn, &decl->_decl); + } break; case _Z_UNDECL_SUBSCRIBER: { _z_interest_process_undeclares(zn, &decl->_decl); } break; case _Z_UNDECL_QUERYABLE: { _z_interest_process_undeclares(zn, &decl->_decl); } break; - case _Z_DECL_TOKEN: { - // TODO: add support or explicitly discard - } break; case _Z_UNDECL_TOKEN: { - // TODO: add support or explicitly discard +#if Z_FEATURE_LIVELINESS == 1 + _z_liveliness_process_token_undeclare(zn, decl); +#endif + _z_interest_process_undeclares(zn, &decl->_decl); } break; case _Z_DECL_FINAL: { +#if Z_FEATURE_LIVELINESS == 1 + _z_liveliness_process_declare_final(zn, decl); +#endif // Check that interest id is valid if (!decl->has_interest_id) { return _Z_ERR_MESSAGE_ZENOH_DECLARATION_UNKNOWN; @@ -101,9 +110,9 @@ z_result_t _z_handle_network_message(_z_session_rc_t *zsrc, _z_zenoh_message_t * case _Z_REQUEST_PUT: { #if Z_FEATURE_SUBSCRIPTION == 1 _z_msg_put_t put = req->_body._put; - ret = _z_trigger_subscriptions(zn, req->_key, put._payload, &put._encoding, Z_SAMPLE_KIND_PUT, - &put._commons._timestamp, req->_ext_qos, put._attachment, - msg->_reliability); + ret = _z_trigger_subscriptions_put(zn, req->_key, put._payload, &put._encoding, + &put._commons._timestamp, req->_ext_qos, put._attachment, + msg->_reliability); #endif if (ret == _Z_RES_OK) { _z_network_message_t final = _z_n_msg_make_response_final(req->_rid); @@ -113,10 +122,8 @@ z_result_t _z_handle_network_message(_z_session_rc_t *zsrc, _z_zenoh_message_t * case _Z_REQUEST_DEL: { #if Z_FEATURE_SUBSCRIPTION == 1 _z_msg_del_t del = req->_body._del; - _z_encoding_t encoding = _z_encoding_null(); - ret = _z_trigger_subscriptions(zn, req->_key, _z_bytes_null(), &encoding, Z_SAMPLE_KIND_DELETE, - &del._commons._timestamp, req->_ext_qos, del._attachment, - msg->_reliability); + ret = _z_trigger_subscriptions_del(zn, req->_key, &del._commons._timestamp, req->_ext_qos, + del._attachment, msg->_reliability); #endif if (ret == _Z_RES_OK) { _z_network_message_t final = _z_n_msg_make_response_final(req->_rid); diff --git a/src/session/subscription.c b/src/session/subscription.c index b7bf19f26..eb611815e 100644 --- a/src/session/subscription.c +++ b/src/session/subscription.c @@ -17,6 +17,7 @@ #include #include +#include "zenoh-pico/api/constants.h" #include "zenoh-pico/api/types.h" #include "zenoh-pico/config.h" #include "zenoh-pico/net/sample.h" @@ -78,9 +79,10 @@ _z_subscription_rc_list_t *__z_get_subscriptions_by_key(_z_subscription_rc_list_ * Make sure that the following mutexes are locked before calling this function: * - zn->_mutex_inner */ -_z_subscription_rc_t *__unsafe_z_get_subscription_by_id(_z_session_t *zn, uint8_t is_local, const _z_zint_t id) { +_z_subscription_rc_t *__unsafe_z_get_subscription_by_id(_z_session_t *zn, _z_subscriber_kind_t kind, + const _z_zint_t id) { _z_subscription_rc_list_t *subs = - (is_local == _Z_RESOURCE_IS_LOCAL) ? zn->_local_subscriptions : zn->_remote_subscriptions; + (kind == _Z_SUBSCRIBER_KIND_SUBSCRIBER) ? zn->_subscriptions : zn->_liveliness_subscriptions; return __z_get_subscription_by_id(subs, id); } @@ -89,34 +91,35 @@ _z_subscription_rc_t *__unsafe_z_get_subscription_by_id(_z_session_t *zn, uint8_ * Make sure that the following mutexes are locked before calling this function: * - zn->_mutex_inner */ -_z_subscription_rc_list_t *__unsafe_z_get_subscriptions_by_key(_z_session_t *zn, uint8_t is_local, +_z_subscription_rc_list_t *__unsafe_z_get_subscriptions_by_key(_z_session_t *zn, _z_subscriber_kind_t kind, const _z_keyexpr_t *key) { _z_subscription_rc_list_t *subs = - (is_local == _Z_RESOURCE_IS_LOCAL) ? zn->_local_subscriptions : zn->_remote_subscriptions; + (kind == _Z_SUBSCRIBER_KIND_SUBSCRIBER) ? zn->_subscriptions : zn->_liveliness_subscriptions; return __z_get_subscriptions_by_key(subs, key); } -_z_subscription_rc_t *_z_get_subscription_by_id(_z_session_t *zn, uint8_t is_local, const _z_zint_t id) { +_z_subscription_rc_t *_z_get_subscription_by_id(_z_session_t *zn, _z_subscriber_kind_t kind, const _z_zint_t id) { _zp_session_lock_mutex(zn); - _z_subscription_rc_t *sub = __unsafe_z_get_subscription_by_id(zn, is_local, id); + _z_subscription_rc_t *sub = __unsafe_z_get_subscription_by_id(zn, kind, id); _zp_session_unlock_mutex(zn); return sub; } -_z_subscription_rc_list_t *_z_get_subscriptions_by_key(_z_session_t *zn, uint8_t is_local, const _z_keyexpr_t *key) { +_z_subscription_rc_list_t *_z_get_subscriptions_by_key(_z_session_t *zn, _z_subscriber_kind_t kind, + const _z_keyexpr_t *key) { _zp_session_lock_mutex(zn); - _z_subscription_rc_list_t *subs = __unsafe_z_get_subscriptions_by_key(zn, is_local, key); + _z_subscription_rc_list_t *subs = __unsafe_z_get_subscriptions_by_key(zn, kind, key); _zp_session_unlock_mutex(zn); return subs; } -_z_subscription_rc_t *_z_register_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_t *s) { +_z_subscription_rc_t *_z_register_subscription(_z_session_t *zn, _z_subscriber_kind_t kind, _z_subscription_t *s) { _Z_DEBUG(">>> Allocating sub decl for (%ju:%.*s)", (uintmax_t)s->_key._id, (int)_z_string_len(&s->_key._suffix), _z_string_data(&s->_key._suffix)); _z_subscription_rc_t *ret = NULL; @@ -126,10 +129,10 @@ _z_subscription_rc_t *_z_register_subscription(_z_session_t *zn, uint8_t is_loca ret = (_z_subscription_rc_t *)z_malloc(sizeof(_z_subscription_rc_t)); if (ret != NULL) { *ret = _z_subscription_rc_new_from_val(s); - if (is_local == _Z_RESOURCE_IS_LOCAL) { - zn->_local_subscriptions = _z_subscription_rc_list_push(zn->_local_subscriptions, ret); + if (kind == _Z_SUBSCRIBER_KIND_SUBSCRIBER) { + zn->_subscriptions = _z_subscription_rc_list_push(zn->_subscriptions, ret); } else { - zn->_remote_subscriptions = _z_subscription_rc_list_push(zn->_remote_subscriptions, ret); + zn->_liveliness_subscriptions = _z_subscription_rc_list_push(zn->_liveliness_subscriptions, ret); } } @@ -138,17 +141,42 @@ _z_subscription_rc_t *_z_register_subscription(_z_session_t *zn, uint8_t is_loca return ret; } -void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_bytes_t payload, - _z_encoding_t *encoding, const _z_n_qos_t qos, const _z_timestamp_t *timestamp, - const _z_bytes_t attachment, z_reliability_t reliability) { - z_result_t ret = _z_trigger_subscriptions(zn, keyexpr, payload, encoding, Z_SAMPLE_KIND_PUT, timestamp, qos, - attachment, reliability); - (void)ret; +z_result_t _z_trigger_subscriptions_put(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_bytes_t payload, + _z_encoding_t *encoding, const _z_timestamp_t *timestamp, const _z_n_qos_t qos, + const _z_bytes_t attachment, z_reliability_t reliability) { + return _z_trigger_subscriptions_impl(zn, _Z_SUBSCRIBER_KIND_SUBSCRIBER, keyexpr, payload, encoding, + Z_SAMPLE_KIND_PUT, timestamp, qos, attachment, reliability); } -z_result_t _z_trigger_subscriptions(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_bytes_t payload, - _z_encoding_t *encoding, const _z_zint_t kind, const _z_timestamp_t *timestamp, - const _z_n_qos_t qos, const _z_bytes_t attachment, z_reliability_t reliability) { +z_result_t _z_trigger_subscriptions_del(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_timestamp_t *timestamp, + const _z_n_qos_t qos, const _z_bytes_t attachment, + z_reliability_t reliability) { + _z_encoding_t encoding = _z_encoding_null(); + return _z_trigger_subscriptions_impl(zn, _Z_SUBSCRIBER_KIND_SUBSCRIBER, keyexpr, _z_bytes_null(), &encoding, + Z_SAMPLE_KIND_DELETE, timestamp, qos, attachment, reliability); +} + +z_result_t _z_trigger_liveliness_subscriptions_declare(_z_session_t *zn, const _z_keyexpr_t keyexpr, + const _z_timestamp_t *timestamp) { + _z_encoding_t encoding = _z_encoding_null(); + return _z_trigger_subscriptions_impl(zn, _Z_SUBSCRIBER_KIND_LIVELINESS_SUBSCRIBER, keyexpr, _z_bytes_null(), + &encoding, Z_SAMPLE_KIND_PUT, timestamp, _Z_N_QOS_DEFAULT, _z_bytes_null(), + Z_RELIABILITY_RELIABLE); +} + +z_result_t _z_trigger_liveliness_subscriptions_undeclare(_z_session_t *zn, const _z_keyexpr_t keyexpr, + const _z_timestamp_t *timestamp) { + _z_encoding_t encoding = _z_encoding_null(); + return _z_trigger_subscriptions_impl(zn, _Z_SUBSCRIBER_KIND_LIVELINESS_SUBSCRIBER, keyexpr, _z_bytes_null(), + &encoding, Z_SAMPLE_KIND_DELETE, timestamp, _Z_N_QOS_DEFAULT, _z_bytes_null(), + Z_RELIABILITY_RELIABLE); +} + +z_result_t _z_trigger_subscriptions_impl(_z_session_t *zn, _z_subscriber_kind_t subscriber_kind, + const _z_keyexpr_t keyexpr, const _z_bytes_t payload, _z_encoding_t *encoding, + const _z_zint_t sample_kind, const _z_timestamp_t *timestamp, + const _z_n_qos_t qos, const _z_bytes_t attachment, + z_reliability_t reliability) { z_result_t ret = _Z_RES_OK; _zp_session_lock_mutex(zn); @@ -158,12 +186,13 @@ z_result_t _z_trigger_subscriptions(_z_session_t *zn, const _z_keyexpr_t keyexpr _z_keyexpr_t key = __unsafe_z_get_expanded_key_from_key(zn, &keyexpr); _Z_DEBUG("Triggering subs for %d - %.*s", key._id, (int)_z_string_len(&key._suffix), _z_string_data(&key._suffix)); if (_z_keyexpr_has_suffix(&key)) { - _z_subscription_rc_list_t *subs = __unsafe_z_get_subscriptions_by_key(zn, _Z_RESOURCE_IS_LOCAL, &key); + _z_subscription_rc_list_t *subs = __unsafe_z_get_subscriptions_by_key(zn, subscriber_kind, &key); _zp_session_unlock_mutex(zn); // Build the sample - _z_sample_t sample = _z_sample_create(&key, payload, timestamp, encoding, kind, qos, attachment, reliability); + _z_sample_t sample = + _z_sample_create(&key, payload, timestamp, encoding, sample_kind, qos, attachment, reliability); // Parse subscription list _z_subscription_rc_list_t *xs = subs; _Z_DEBUG("Triggering %ju subs", (uintmax_t)_z_subscription_rc_list_len(xs)); @@ -183,15 +212,14 @@ z_result_t _z_trigger_subscriptions(_z_session_t *zn, const _z_keyexpr_t keyexpr return ret; } -void _z_unregister_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_rc_t *sub) { +void _z_unregister_subscription(_z_session_t *zn, _z_subscriber_kind_t kind, _z_subscription_rc_t *sub) { _zp_session_lock_mutex(zn); - if (is_local == _Z_RESOURCE_IS_LOCAL) { - zn->_local_subscriptions = - _z_subscription_rc_list_drop_filter(zn->_local_subscriptions, _z_subscription_rc_eq, sub); + if (kind == _Z_SUBSCRIBER_KIND_SUBSCRIBER) { + zn->_subscriptions = _z_subscription_rc_list_drop_filter(zn->_subscriptions, _z_subscription_rc_eq, sub); } else { - zn->_remote_subscriptions = - _z_subscription_rc_list_drop_filter(zn->_remote_subscriptions, _z_subscription_rc_eq, sub); + zn->_liveliness_subscriptions = + _z_subscription_rc_list_drop_filter(zn->_liveliness_subscriptions, _z_subscription_rc_eq, sub); } _zp_session_unlock_mutex(zn); @@ -200,16 +228,16 @@ void _z_unregister_subscription(_z_session_t *zn, uint8_t is_local, _z_subscript void _z_flush_subscriptions(_z_session_t *zn) { _zp_session_lock_mutex(zn); - _z_subscription_rc_list_free(&zn->_local_subscriptions); - _z_subscription_rc_list_free(&zn->_remote_subscriptions); + _z_subscription_rc_list_free(&zn->_subscriptions); + _z_subscription_rc_list_free(&zn->_liveliness_subscriptions); _zp_session_unlock_mutex(zn); } #else // Z_FEATURE_SUBSCRIPTION == 0 -void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_bytes_t payload, - _z_encoding_t *encoding, const _z_n_qos_t qos, const _z_timestamp_t *timestamp, - const _z_bytes_t attachment, z_reliability_t reliability) { +z_result_t _z_trigger_subscriptions_put(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_bytes_t payload, + _z_encoding_t *encoding, const _z_timestamp_t *timestamp, const _z_n_qos_t qos, + const _z_bytes_t attachment, z_reliability_t reliability) { _ZP_UNUSED(zn); _ZP_UNUSED(keyexpr); _ZP_UNUSED(payload); @@ -218,6 +246,39 @@ void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t keyexpr _ZP_UNUSED(timestamp); _ZP_UNUSED(attachment); _ZP_UNUSED(reliability); + + return _Z_RES_OK; +} + +z_result_t _z_trigger_subscriptions_del(_z_session_t *zn, const _z_keyexpr_t keyexpr, const _z_timestamp_t *timestamp, + const _z_n_qos_t qos, const _z_bytes_t attachment, + z_reliability_t reliability) { + _ZP_UNUSED(zn); + _ZP_UNUSED(keyexpr); + _ZP_UNUSED(qos); + _ZP_UNUSED(timestamp); + _ZP_UNUSED(attachment); + _ZP_UNUSED(reliability); + + return _Z_RES_OK; +} + +z_result_t _z_trigger_liveliness_subscriptions_declare(_z_session_t *zn, const _z_keyexpr_t keyexpr, + const _z_timestamp_t *timestamp) { + _ZP_UNUSED(zn); + _ZP_UNUSED(keyexpr); + _ZP_UNUSED(timestamp); + + return _Z_RES_OK; +} + +z_result_t _z_trigger_liveliness_subscriptions_undeclare(_z_session_t *zn, const _z_keyexpr_t keyexpr, + const _z_timestamp_t *timestamp) { + _ZP_UNUSED(zn); + _ZP_UNUSED(keyexpr); + _ZP_UNUSED(timestamp); + + return _Z_RES_OK; } #endif // Z_FEATURE_SUBSCRIPTION == 1 diff --git a/src/session/utils.c b/src/session/utils.c index d82f9d84c..44874a115 100644 --- a/src/session/utils.c +++ b/src/session/utils.c @@ -19,11 +19,11 @@ #include "zenoh-pico/config.h" #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/session/interest.h" +#include "zenoh-pico/session/liveliness.h" #include "zenoh-pico/session/query.h" #include "zenoh-pico/session/queryable.h" #include "zenoh-pico/session/resource.h" #include "zenoh-pico/session/subscription.h" -#include "zenoh-pico/utils/logging.h" /*------------------ clone helpers ------------------*/ _z_timestamp_t _z_timestamp_duplicate(const _z_timestamp_t *tstamp) { @@ -60,8 +60,8 @@ z_result_t _z_session_init(_z_session_rc_t *zsrc, _z_id_t *zid) { zn->_local_resources = NULL; zn->_remote_resources = NULL; #if Z_FEATURE_SUBSCRIPTION == 1 - zn->_local_subscriptions = NULL; - zn->_remote_subscriptions = NULL; + zn->_subscriptions = NULL; + zn->_liveliness_subscriptions = NULL; #endif #if Z_FEATURE_QUERYABLE == 1 zn->_local_queryable = NULL; @@ -78,6 +78,10 @@ z_result_t _z_session_init(_z_session_rc_t *zsrc, _z_id_t *zid) { } #endif // Z_FEATURE_MULTI_THREAD == 1 +#if Z_FEATURE_LIVELINESS == 1 + _z_liveliness_init(zn); +#endif + zn->_local_zid = *zid; // Note session in transport switch (zn->_tp._type) { @@ -119,6 +123,9 @@ void _z_session_clear(_z_session_t *zn) { #endif #if Z_FEATURE_QUERY == 1 _z_flush_pending_queries(zn); +#endif +#if Z_FEATURE_LIVELINESS == 1 + _z_liveliness_clear(zn); #endif _z_flush_interest(zn); diff --git a/src/system/emscripten/system.c b/src/system/emscripten/system.c index 9bfa8f7d6..52065d2db 100644 --- a/src/system/emscripten/system.c +++ b/src/system/emscripten/system.c @@ -55,11 +55,7 @@ z_result_t _z_task_detach(_z_task_t *task) { _Z_CHECK_SYS_ERR(pthread_detach(*ta z_result_t _z_task_cancel(_z_task_t *task) { _Z_CHECK_SYS_ERR(pthread_cancel(*task)); } -void _z_task_free(_z_task_t **task) { - _z_task_t *ptr = *task; - z_free(ptr); - *task = NULL; -} +void _z_task_free(_z_task_t **task) { *task = NULL; } /*------------------ Mutex ------------------*/ z_result_t _z_mutex_init(_z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_mutex_init(m, 0)); } diff --git a/src/system/unix/system.c b/src/system/unix/system.c index beb78ceef..d1c0c5886 100644 --- a/src/system/unix/system.c +++ b/src/system/unix/system.c @@ -114,11 +114,7 @@ z_result_t _z_task_detach(_z_task_t *task) { _Z_CHECK_SYS_ERR(pthread_detach(*ta z_result_t _z_task_cancel(_z_task_t *task) { _Z_CHECK_SYS_ERR(pthread_cancel(*task)); } -void _z_task_free(_z_task_t **task) { - _z_task_t *ptr = *task; - z_free(ptr); - *task = NULL; -} +void _z_task_free(_z_task_t **task) { *task = NULL; } /*------------------ Mutex ------------------*/ z_result_t _z_mutex_init(_z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_mutex_init(m, 0)); } diff --git a/src/system/zephyr/system.c b/src/system/zephyr/system.c index c76e26a02..7818c9993 100644 --- a/src/system/zephyr/system.c +++ b/src/system/zephyr/system.c @@ -89,11 +89,7 @@ z_result_t _z_task_detach(_z_task_t *task) { _Z_CHECK_SYS_ERR(pthread_detach(*ta z_result_t _z_task_cancel(_z_task_t *task) { _Z_CHECK_SYS_ERR(pthread_cancel(*task)); } -void _z_task_free(_z_task_t **task) { - _z_task_t *ptr = *task; - z_free(ptr); - *task = NULL; -} +void _z_task_free(_z_task_t **task) { *task = NULL; } /*------------------ Mutex ------------------*/ z_result_t _z_mutex_init(_z_mutex_t *m) { _Z_CHECK_SYS_ERR(pthread_mutex_init(m, 0)); } diff --git a/src/transport/multicast.c b/src/transport/multicast.c index 42059f6dc..6c8db89d0 100644 --- a/src/transport/multicast.c +++ b/src/transport/multicast.c @@ -19,15 +19,7 @@ #include #include -#include "zenoh-pico/link/link.h" -#include "zenoh-pico/transport/common/lease.h" -#include "zenoh-pico/transport/common/read.h" -#include "zenoh-pico/transport/common/tx.h" -#include "zenoh-pico/transport/multicast/rx.h" -#include "zenoh-pico/transport/multicast/tx.h" -#include "zenoh-pico/transport/unicast/rx.h" -#include "zenoh-pico/transport/utils.h" -#include "zenoh-pico/utils/logging.h" +#include "zenoh-pico/utils/uuid.h" #if Z_FEATURE_MULTICAST_TRANSPORT == 1 void _zp_multicast_fetch_zid(const _z_transport_t *zt, _z_closure_zid_t *callback) { @@ -45,9 +37,8 @@ void _zp_multicast_info_session(const _z_transport_t *zt, _z_config_t *ps) { _z_transport_peer_entry_list_t *xs = zt->_transport._multicast._peers; while (xs != NULL) { _z_transport_peer_entry_t *peer = _z_transport_peer_entry_list_head(xs); - _z_slice_t remote_zid = _z_slice_alias_buf(peer->_remote_zid.id, _z_id_len(peer->_remote_zid)); - _z_string_t remote_zid_str = _z_string_convert_bytes(&remote_zid); - _zp_config_insert(ps, Z_INFO_PEER_PID_KEY, _z_string_data(&remote_zid_str)); + _z_string_t remote_zid_str = _z_id_to_string(&peer->_remote_zid); + _zp_config_insert_string(ps, Z_INFO_PEER_PID_KEY, &remote_zid_str); _z_string_clear(&remote_zid_str); xs = _z_transport_peer_entry_list_tail(xs); diff --git a/src/transport/multicast/transport.c b/src/transport/multicast/transport.c index d0f6abb3a..091539fbb 100644 --- a/src/transport/multicast/transport.c +++ b/src/transport/multicast/transport.c @@ -185,11 +185,11 @@ void _z_multicast_transport_clear(_z_transport_t *zt) { // Clean up tasks if (ztm->_read_task != NULL) { _z_task_join(ztm->_read_task); - _z_task_free(&ztm->_read_task); + z_free(ztm->_read_task); } if (ztm->_lease_task != NULL) { _z_task_join(ztm->_lease_task); - _z_task_free(&ztm->_lease_task); + z_free(ztm->_lease_task); } // Clean up the mutexes _z_mutex_drop(&ztm->_mutex_tx); diff --git a/src/transport/unicast.c b/src/transport/unicast.c index dca9ae0ea..f194b4ee3 100644 --- a/src/transport/unicast.c +++ b/src/transport/unicast.c @@ -16,19 +16,8 @@ #include #include #include -#include -#include - -#include "zenoh-pico/link/link.h" -#include "zenoh-pico/transport/common/rx.h" -#include "zenoh-pico/transport/common/tx.h" -#include "zenoh-pico/transport/multicast/rx.h" -#include "zenoh-pico/transport/unicast/lease.h" -#include "zenoh-pico/transport/unicast/read.h" -#include "zenoh-pico/transport/unicast/rx.h" -#include "zenoh-pico/transport/unicast/tx.h" -#include "zenoh-pico/transport/utils.h" -#include "zenoh-pico/utils/logging.h" + +#include "zenoh-pico/utils/uuid.h" #if Z_FEATURE_UNICAST_TRANSPORT == 1 void _zp_unicast_fetch_zid(const _z_transport_t *zt, _z_closure_zid_t *callback) { @@ -39,9 +28,9 @@ void _zp_unicast_fetch_zid(const _z_transport_t *zt, _z_closure_zid_t *callback) void _zp_unicast_info_session(const _z_transport_t *zt, _z_config_t *ps) { _z_id_t remote_zid = zt->_transport._unicast._remote_zid; - _z_slice_t remote_zid_bytes = _z_slice_alias_buf(remote_zid.id, _z_id_len(remote_zid)); - _z_string_t remote_zid_str = _z_string_convert_bytes(&remote_zid_bytes); - _zp_config_insert(ps, Z_INFO_ROUTER_PID_KEY, _z_string_data(&remote_zid_str)); + + _z_string_t remote_zid_str = _z_id_to_string(&remote_zid); + _zp_config_insert_string(ps, Z_INFO_ROUTER_PID_KEY, &remote_zid_str); _z_string_clear(&remote_zid_str); } diff --git a/src/transport/unicast/transport.c b/src/transport/unicast/transport.c index c4433ac1a..01c19ce91 100644 --- a/src/transport/unicast/transport.c +++ b/src/transport/unicast/transport.c @@ -281,11 +281,11 @@ void _z_unicast_transport_clear(_z_transport_t *zt) { // Clean up tasks if (ztu->_read_task != NULL) { _z_task_join(ztu->_read_task); - _z_task_free(&ztu->_read_task); + z_free(ztu->_read_task); } if (ztu->_lease_task != NULL) { _z_task_join(ztu->_lease_task); - _z_task_free(&ztu->_lease_task); + z_free(ztu->_lease_task); } // Clean up the mutexes diff --git a/src/utils/uuid.c b/src/utils/uuid.c index 7b9984871..1f2d97fe6 100644 --- a/src/utils/uuid.c +++ b/src/utils/uuid.c @@ -17,6 +17,7 @@ #include #include +#include "zenoh-pico/api/types.h" #include "zenoh-pico/utils/pointers.h" #define UUID_SIZE 16 @@ -32,3 +33,8 @@ void _z_uuid_to_bytes(uint8_t *bytes, const char *uuid_str) { bytes = _z_ptr_u8_offset(bytes, 1); } } + +_z_string_t _z_id_to_string(const z_id_t *id) { + _z_slice_t buf = _z_slice_alias_buf(id->id, sizeof(id->id)); + return _z_string_convert_bytes_le(&buf); +} diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index a8b48eb3e..abef93a46 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -132,11 +132,9 @@ int main(int argc, char **argv) { zc_init_logger(); const char *encoding_expected = z_sample_kind(sample) == Z_SAMPLE_KIND_PUT ? "zenoh/bytes" : "zenoh/bytes;test_encoding"; - z_pu #endif - z_view_keyexpr_t key_demo_example, - key_demo_example_a, key_demo_example_starstar; + z_view_keyexpr_t key_demo_example, key_demo_example_a, key_demo_example_starstar; z_view_keyexpr_from_str(&key_demo_example, "demo/example"); z_view_keyexpr_from_str(&key_demo_example_a, "demo/example/a"); z_view_keyexpr_from_str(&key_demo_example_starstar, "demo/example/**"); @@ -199,10 +197,9 @@ int main(int argc, char **argv) { assert(z_internal_check(s1)); z_id_t _ret_zid = z_info_zid(z_loan(s1)); printf("Session 1 with PID: 0x"); - for (unsigned long i = 0; i < sizeof(_ret_zid); i++) { - printf("%.2X", _ret_zid.id[i]); - } - printf("\n"); + z_owned_string_t id_str; + z_id_to_string(&_ret_zid, &id_str); + printf("%.*s\n", (int)z_string_len(z_loan(id_str)), z_string_data(z_loan(id_str))); z_owned_closure_zid_t _ret_closure_zid; z_closure(&_ret_closure_zid, zid_handler, NULL, NULL); @@ -243,10 +240,8 @@ int main(int argc, char **argv) { assert(z_internal_check(s2)); _ret_zid = z_info_zid(z_loan(s2)); printf("Session 2 with PID: 0x"); - for (unsigned long i = 0; i < sizeof(_ret_zid); i++) { - printf("%.2X", _ret_zid.id[i]); - } - printf("\n"); + z_id_to_string(&_ret_zid, &id_str); + printf("%.*s\n", (int)z_string_len(z_loan(id_str)), z_string_data(z_loan(id_str))); #ifdef ZENOH_PICO zp_start_read_task(z_loan_mut(s2), NULL); diff --git a/tests/z_api_liveliness_test.c b/tests/z_api_liveliness_test.c new file mode 100644 index 000000000..2cf4c350e --- /dev/null +++ b/tests/z_api_liveliness_test.c @@ -0,0 +1,229 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, + +#include +#include +#include +#include +#include +#include + +#include "zenoh-pico.h" +#include "zenoh-pico/api/handlers.h" +#include "zenoh-pico/api/liveliness.h" +#include "zenoh-pico/api/primitives.h" +#include "zenoh-pico/api/types.h" + +#if Z_FEATURE_LIVELINESS == 1 && Z_FEATURE_SUBSCRIPTION == 1 && Z_FEATURE_QUERY == 1 + +#undef NDEBUG +#include +typedef struct context_t { + bool token1_put; + bool token2_put; + bool token1_drop; + bool token2_drop; +} context_t; + +#define assert_ok(x) \ + { \ + int ret = (int)x; \ + if (ret != Z_OK) { \ + printf("%s failed: %d\n", #x, ret); \ + assert(false); \ + } \ + } + +const char* token1_expr = "zenoh-pico/liveliness/test/1"; +const char* token2_expr = "zenoh-pico/liveliness/test/2"; + +void on_receive(z_loaned_sample_t* s, void* context) { + context_t* c = (context_t*)context; + const z_loaned_keyexpr_t* k = z_sample_keyexpr(s); + z_view_string_t ks; + z_keyexpr_as_view_string(k, &ks); + + if (z_sample_kind(s) == Z_SAMPLE_KIND_PUT) { + if (strncmp(token1_expr, z_string_data(z_view_string_loan(&ks)), z_string_len(z_view_string_loan(&ks))) == 0) { + c->token1_put = true; + } else if (strncmp(token2_expr, z_string_data(z_view_string_loan(&ks)), + z_string_len(z_view_string_loan(&ks))) == 0) { + c->token2_put = true; + } + } else if (z_sample_kind(s) == Z_SAMPLE_KIND_DELETE) { + if (strncmp(token1_expr, z_string_data(z_view_string_loan(&ks)), z_string_len(z_view_string_loan(&ks))) == 0) { + c->token1_drop = true; + } else if (strncmp(token2_expr, z_string_data(z_view_string_loan(&ks)), + z_string_len(z_view_string_loan(&ks))) == 0) { + c->token2_drop = true; + } + } +} + +void test_liveliness_sub(bool multicast, bool history) { + printf("test_liveliness_sub: multicast=%d, history=%d\n", multicast, history); + const char* expr = "zenoh-pico/liveliness/test/*"; + + z_owned_session_t s1, s2; + z_owned_config_t c1, c2; + z_config_default(&c1); + z_config_default(&c2); + z_view_keyexpr_t k, k1, k2; + z_view_keyexpr_from_str(&k, expr); + z_view_keyexpr_from_str(&k1, token1_expr); + z_view_keyexpr_from_str(&k2, token2_expr); + + if (multicast) { + zp_config_insert(z_loan_mut(c1), Z_CONFIG_MODE_KEY, "peer"); + zp_config_insert(z_loan_mut(c1), Z_CONFIG_LISTEN_KEY, "udp/224.0.0.224:7447#iface=lo"); + + zp_config_insert(z_loan_mut(c2), Z_CONFIG_MODE_KEY, "client"); + zp_config_insert(z_loan_mut(c2), Z_CONFIG_LISTEN_KEY, "udp/224.0.0.224:7447#iface=lo"); + } + + assert_ok(z_open(&s1, z_config_move(&c1), NULL)); + assert_ok(z_open(&s2, z_config_move(&c2), NULL)); + + assert_ok(zp_start_read_task(z_loan_mut(s1), NULL)); + assert_ok(zp_start_read_task(z_loan_mut(s2), NULL)); + assert_ok(zp_start_lease_task(z_loan_mut(s1), NULL)); + assert_ok(zp_start_lease_task(z_loan_mut(s2), NULL)); + + z_owned_liveliness_token_t t1, t2; + // In history mode we can declare token before subsribing + if (history) { + assert_ok(z_liveliness_declare_token(z_session_loan(&s2), &t1, z_view_keyexpr_loan(&k1), NULL)); + assert_ok(z_liveliness_declare_token(z_session_loan(&s2), &t2, z_view_keyexpr_loan(&k2), NULL)); + } + + z_sleep_s(1); + z_owned_closure_sample_t closure; + context_t context = {false, false, false, false}; + z_closure_sample(&closure, on_receive, NULL, (void*)(&context)); + + z_owned_subscriber_t sub; + z_liveliness_subscriber_options_t sub_opt; + z_liveliness_subscriber_options_default(&sub_opt); + sub_opt.history = history; + assert_ok(z_liveliness_declare_subscriber(z_session_loan(&s1), &sub, z_view_keyexpr_loan(&k), + z_closure_sample_move(&closure), &sub_opt)); + + z_sleep_s(1); + if (!history) { + assert_ok(z_liveliness_declare_token(z_session_loan(&s2), &t1, z_view_keyexpr_loan(&k1), NULL)); + assert_ok(z_liveliness_declare_token(z_session_loan(&s2), &t2, z_view_keyexpr_loan(&k2), NULL)); + } + + z_sleep_s(1); + + assert(context.token1_put); + assert(context.token2_put); + + assert_ok(z_liveliness_undeclare_token(z_liveliness_token_move(&t1))); + z_sleep_s(1); + + assert(context.token1_drop); + assert(!context.token2_drop); + + assert_ok(z_liveliness_undeclare_token(z_liveliness_token_move(&t2))); + z_sleep_s(1); + assert(context.token2_drop); + + assert_ok(zp_stop_read_task(z_loan_mut(s1))); + assert_ok(zp_stop_read_task(z_loan_mut(s2))); + assert_ok(zp_stop_lease_task(z_loan_mut(s1))); + assert_ok(zp_stop_lease_task(z_loan_mut(s2))); + + z_session_drop(z_session_move(&s1)); + z_session_drop(z_session_move(&s2)); +} + +void test_liveliness_get(void) { + const char* expr = "zenoh-pico/liveliness/test/*"; + + z_owned_session_t s1, s2; + z_owned_config_t c1, c2; + z_config_default(&c1); + z_config_default(&c2); + z_view_keyexpr_t k, k1; + z_view_keyexpr_from_str(&k, expr); + z_view_keyexpr_from_str(&k1, token1_expr); + + assert_ok(z_open(&s1, z_config_move(&c1), NULL)); + assert_ok(z_open(&s2, z_config_move(&c2), NULL)); + + assert_ok(zp_start_read_task(z_loan_mut(s1), NULL)); + assert_ok(zp_start_read_task(z_loan_mut(s2), NULL)); + assert_ok(zp_start_lease_task(z_loan_mut(s1), NULL)); + assert_ok(zp_start_lease_task(z_loan_mut(s2), NULL)); + + z_sleep_s(1); + z_owned_liveliness_token_t t1; + assert_ok(z_liveliness_declare_token(z_session_loan(&s1), &t1, z_view_keyexpr_loan(&k1), NULL)); + z_sleep_s(1); + + z_owned_fifo_handler_reply_t handler; + z_owned_closure_reply_t cb; + assert_ok(z_fifo_channel_reply_new(&cb, &handler, 3)); + + assert_ok(z_liveliness_get(z_session_loan(&s2), z_view_keyexpr_loan(&k), z_closure_reply_move(&cb), NULL)); + z_owned_reply_t reply; + assert_ok(z_fifo_handler_reply_recv(z_fifo_handler_reply_loan(&handler), &reply)); + assert(z_reply_is_ok(z_reply_loan(&reply))); + const z_loaned_keyexpr_t* reply_keyexpr = z_sample_keyexpr(z_reply_ok(z_reply_loan(&reply))); + z_view_string_t reply_keyexpr_s; + z_keyexpr_as_view_string(reply_keyexpr, &reply_keyexpr_s); + assert(strlen(token1_expr) == z_string_len(z_view_string_loan(&reply_keyexpr_s))); + assert(strncmp(token1_expr, z_string_data(z_view_string_loan(&reply_keyexpr_s)), + z_string_len(z_view_string_loan(&reply_keyexpr_s))) == 0); + + z_reply_drop(z_reply_move(&reply)); + assert(z_fifo_handler_reply_recv(z_fifo_handler_reply_loan(&handler), &reply) == Z_CHANNEL_DISCONNECTED); + + z_liveliness_token_drop(z_liveliness_token_move(&t1)); + z_fifo_handler_reply_drop(z_fifo_handler_reply_move(&handler)); + z_sleep_s(1); + assert_ok(z_fifo_channel_reply_new(&cb, &handler, 3)); + + z_liveliness_get(z_session_loan(&s2), z_view_keyexpr_loan(&k), z_closure_reply_move(&cb), NULL); + assert(z_fifo_handler_reply_recv(z_fifo_handler_reply_loan(&handler), &reply) == Z_CHANNEL_DISCONNECTED); + + z_fifo_handler_reply_drop(z_fifo_handler_reply_move(&handler)); + + assert_ok(zp_stop_read_task(z_loan_mut(s1))); + assert_ok(zp_stop_read_task(z_loan_mut(s2))); + assert_ok(zp_stop_lease_task(z_loan_mut(s1))); + assert_ok(zp_stop_lease_task(z_loan_mut(s2))); + + z_session_drop(z_session_move(&s1)); + z_session_drop(z_session_move(&s2)); +} + +int main(int argc, char** argv) { + (void)argc; + (void)argv; +#if defined(ZENOH_LINUX) + test_liveliness_sub(true, false); + test_liveliness_sub(true, true); +#endif + test_liveliness_sub(false, false); + test_liveliness_sub(false, true); + test_liveliness_get(); +} + +#else +int main(int argc, char** argv) { + (void)argc; + (void)argv; +} +#endif diff --git a/tests/z_client_test.c b/tests/z_client_test.c index d073bc554..ca230002c 100644 --- a/tests/z_client_test.c +++ b/tests/z_client_test.c @@ -20,6 +20,7 @@ #include "zenoh-pico.h" #include "zenoh-pico/api/types.h" #include "zenoh-pico/collections/string.h" +#include "zenoh-pico/utils/uuid.h" #undef NDEBUG #include @@ -116,11 +117,6 @@ void data_handler(z_loaned_sample_t *sample, void *arg) { free(res); } -_z_string_t format_id(const z_id_t *id) { - _z_slice_t id_as_bytes = _z_slice_alias_buf(id->id, _z_id_len(*id)); - return _z_string_convert_bytes(&id_as_bytes); -} - int main(int argc, char **argv) { setvbuf(stdout, NULL, _IOLBF, 1024); @@ -137,8 +133,8 @@ int main(int argc, char **argv) { z_owned_session_t s1; assert(z_open(&s1, z_move(config), NULL) == Z_OK); - _z_string_t zid1 = format_id(&(_Z_RC_IN_VAL(z_loan(s1))->_local_zid)); - printf("Session 1 with PID: %s\n", _z_string_data(&zid1)); + _z_string_t zid1 = _z_id_to_string(&(_Z_RC_IN_VAL(z_loan(s1))->_local_zid)); + printf("Session 1 with PID: %*.s\n", (int)_z_string_len(&zid1), _z_string_data(&zid1)); _z_string_clear(&zid1); // Start the read session session lease loops @@ -153,8 +149,8 @@ int main(int argc, char **argv) { z_owned_session_t s2; assert(z_open(&s2, z_move(config), NULL) == Z_OK); assert(z_internal_check(s2)); - _z_string_t zid2 = format_id(&(_Z_RC_IN_VAL(z_loan(s2))->_local_zid)); - printf("Session 2 with PID: %s\n", _z_string_data(&zid2)); + _z_string_t zid2 = _z_id_to_string(&(_Z_RC_IN_VAL(z_loan(s2))->_local_zid)); + printf("Session 2 with PID: %*.s\n", (int)_z_string_len(&zid2), _z_string_data(&zid2)); _z_string_clear(&zid2); // Start the read session session lease loops @@ -213,7 +209,7 @@ int main(int argc, char **argv) { z_view_keyexpr_t ke; z_view_keyexpr_from_str(&ke, s1_res); assert(z_declare_queryable(z_loan(s2), qle, z_loan(ke), z_move(callback), NULL) == _Z_RES_OK); - printf("Declared queryable on session 2: %ju %zu %s\n", (uintmax_t)qle->_val._entity_id, (z_zint_t)0, s1_res); + printf("Declared queryable on session 2: %ju %i %s\n", (uintmax_t)qle->_val._entity_id, 0, s1_res); qles2 = _z_list_push(qles2, qle); } @@ -315,7 +311,7 @@ int main(int argc, char **argv) { z_view_keyexpr_t ke; z_view_keyexpr_from_str(&ke, s1_res); z_get(z_loan(s1), z_loan(ke), "", z_move(callback), NULL); - printf("Queried data from session 1: %zu %s\n", (z_zint_t)0, s1_res); + printf("Queried data from session 1: %i %s\n", 0, s1_res); } } diff --git a/tests/z_collections_test.c b/tests/z_collections_test.c index ec103b444..8bb54007f 100644 --- a/tests/z_collections_test.c +++ b/tests/z_collections_test.c @@ -18,6 +18,7 @@ #include "zenoh-pico/collections/fifo.h" #include "zenoh-pico/collections/lifo.h" +#include "zenoh-pico/collections/list.h" #include "zenoh-pico/collections/ring.h" #include "zenoh-pico/collections/string.h" @@ -308,6 +309,46 @@ void fifo_test_init_free(void) { assert(r == NULL); } +void int_map_iterator_test(void) { + _z_str_intmap_t map; + + map = _z_str_intmap_make(); + _z_str_intmap_insert(&map, 10, "A"); + _z_str_intmap_insert(&map, 20, "B"); + _z_str_intmap_insert(&map, 30, "C"); + _z_str_intmap_insert(&map, 40, "D"); + +#define TEST_MAP(map) \ + { \ + _z_str_intmap_iterator_t iter = _z_str_intmap_iterator_make(&map); \ + assert(_z_str_intmap_iterator_next(&iter)); \ + assert(_z_str_intmap_iterator_key(&iter) == 20); \ + assert(strcmp(_z_str_intmap_iterator_value(&iter), "B") == 0); \ + \ + assert(_z_str_intmap_iterator_next(&iter)); \ + assert(_z_str_intmap_iterator_key(&iter) == 40); \ + assert(strcmp(_z_str_intmap_iterator_value(&iter), "D") == 0); \ + \ + assert(_z_str_intmap_iterator_next(&iter)); \ + assert(_z_str_intmap_iterator_key(&iter) == 10); \ + assert(strcmp(_z_str_intmap_iterator_value(&iter), "A") == 0); \ + \ + assert(_z_str_intmap_iterator_next(&iter)); \ + assert(_z_str_intmap_iterator_key(&iter) == 30); \ + assert(strcmp(_z_str_intmap_iterator_value(&iter), "C") == 0); \ + \ + assert(!_z_str_intmap_iterator_next(&iter)); \ + } + + TEST_MAP(map); + + _z_str_intmap_t map2 = _z_str_intmap_clone(&map); + + TEST_MAP(map2); + +#undef TEST_MAP +} + int main(void) { ring_test(); ring_test_init_free(); @@ -315,4 +356,6 @@ int main(void) { lifo_test_init_free(); fifo_test(); fifo_test_init_free(); + + int_map_iterator_test(); } diff --git a/tests/z_data_struct_test.c b/tests/z_data_struct_test.c index 0b7cfa702..e3dff0fa5 100644 --- a/tests/z_data_struct_test.c +++ b/tests/z_data_struct_test.c @@ -233,11 +233,24 @@ void z_string_array_test(void) { z_string_array_drop(z_string_array_move(&a)); } +void z_id_to_string_test(void) { + z_id_t id; + for (uint8_t i = 0; i < sizeof(id.id); i++) { + id.id[i] = i; + } + z_owned_string_t id_str; + z_id_to_string(&id, &id_str); + assert(z_string_len(z_string_loan(&id_str)) == 32); + assert(strncmp("0f0e0d0c0b0a09080706050403020100", z_string_data(z_string_loan(&id_str)), + z_string_len(z_string_loan(&id_str))) == 0); +} + int main(void) { entry_list_test(); str_vec_list_intmap_test(); z_slice_custom_delete_test(); z_string_array_test(); + z_id_to_string_test(); return 0; } diff --git a/tests/z_msgcodec_test.c b/tests/z_msgcodec_test.c index 81f16f50c..59237b3b2 100644 --- a/tests/z_msgcodec_test.c +++ b/tests/z_msgcodec_test.c @@ -842,6 +842,49 @@ void queryable_declaration(void) { _z_wbuf_clear(&wbf); } +/*------------------ Token declaration ------------------*/ +_z_decl_token_t gen_token_declaration(void) { + _z_decl_token_t e_qd = {._keyexpr = gen_keyexpr(), ._id = (uint32_t)gen_uint64()}; + + return e_qd; +} + +void assert_eq_token_declaration(const _z_decl_token_t *left, const _z_decl_token_t *right) { + assert_eq_keyexpr(&left->_keyexpr, &right->_keyexpr); + assert(left->_id == right->_id); +} + +void token_declaration(void) { + printf("\n>> Queryable declaration\n"); + _z_wbuf_t wbf = gen_wbuf(UINT16_MAX); + + // Initialize + _z_decl_token_t e_qd = gen_token_declaration(); + + // Encode + int8_t res = _z_decl_token_encode(&wbf, &e_qd); + assert(res == _Z_RES_OK); + (void)(res); + + // Decode + _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); + _z_decl_token_t d_qd; + uint8_t e_hdr = 0; + _z_uint8_decode(&e_hdr, &zbf); + res = _z_decl_token_decode(&d_qd, &zbf, e_hdr); + assert(res == _Z_RES_OK); + + printf(" "); + assert_eq_token_declaration(&e_qd, &d_qd); + printf("\n"); + + // Free + _z_keyexpr_clear(&e_qd._keyexpr); + _z_keyexpr_clear(&d_qd._keyexpr); + _z_zbuf_clear(&zbf); + _z_wbuf_clear(&wbf); +} + /*------------------ Forget Resource declaration ------------------*/ _z_undecl_kexpr_t gen_forget_resource_declaration(void) { _z_undecl_kexpr_t e_frd; @@ -969,12 +1012,52 @@ void forget_queryable_declaration(void) { _z_wbuf_clear(&wbf); } +/*------------------ Forget Token declaration ------------------*/ +_z_undecl_token_t gen_forget_token_declaration(void) { + _z_undecl_token_t e_fqd = {._ext_keyexpr = gen_keyexpr(), ._id = (uint32_t)gen_zint()}; + return e_fqd; +} + +void assert_eq_forget_token_declaration(const _z_undecl_token_t *left, const _z_undecl_token_t *right) { + assert_eq_keyexpr(&left->_ext_keyexpr, &right->_ext_keyexpr); + assert(left->_id == right->_id); +} + +void forget_token_declaration(void) { + printf("\n>> Forget token declaration\n"); + _z_wbuf_t wbf = gen_wbuf(UINT16_MAX); + + // Initialize + _z_undecl_token_t e_fqd = gen_forget_token_declaration(); + + // Encode + int8_t res = _z_undecl_token_encode(&wbf, &e_fqd); + assert(res == _Z_RES_OK); + (void)(res); + + // Decode + _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); + uint8_t e_hdr = 0; + _z_uint8_decode(&e_hdr, &zbf); + _z_undecl_token_t d_fqd = {._ext_keyexpr = _z_keyexpr_null()}; + res = _z_undecl_token_decode(&d_fqd, &zbf, e_hdr); + assert(res == _Z_RES_OK); + + printf(" "); + assert_eq_forget_token_declaration(&e_fqd, &d_fqd); + printf("\n"); + + // Free + _z_keyexpr_clear(&e_fqd._ext_keyexpr); + _z_keyexpr_clear(&d_fqd._ext_keyexpr); + _z_zbuf_clear(&zbf); + _z_wbuf_clear(&wbf); +} + /*------------------ Declaration ------------------*/ _z_declaration_t gen_declaration(void) { - uint8_t decl[] = { - _Z_DECL_KEXPR, _Z_UNDECL_KEXPR, _Z_DECL_SUBSCRIBER, - _Z_UNDECL_SUBSCRIBER, _Z_DECL_QUERYABLE, _Z_UNDECL_QUERYABLE, - }; + uint8_t decl[] = {_Z_DECL_KEXPR, _Z_UNDECL_KEXPR, _Z_DECL_SUBSCRIBER, _Z_UNDECL_SUBSCRIBER, + _Z_DECL_QUERYABLE, _Z_UNDECL_QUERYABLE, _Z_DECL_TOKEN, _Z_UNDECL_TOKEN}; _z_declaration_t d; d._tag = decl[gen_uint8() % (sizeof(decl) / sizeof(uint8_t))]; @@ -998,6 +1081,12 @@ _z_declaration_t gen_declaration(void) { case _Z_UNDECL_QUERYABLE: { d._body._undecl_queryable = gen_forget_queryable_declaration(); } break; + case _Z_DECL_TOKEN: { + d._body._decl_token = gen_token_declaration(); + } break; + case _Z_UNDECL_TOKEN: { + d._body._undecl_token = gen_forget_token_declaration(); + } break; default: assert(false); } @@ -1020,6 +1109,9 @@ void assert_eq_declaration(const _z_declaration_t *left, const _z_declaration_t case _Z_DECL_QUERYABLE: assert_eq_queryable_declaration(&left->_body._decl_queryable, &right->_body._decl_queryable); break; + case _Z_DECL_TOKEN: + assert_eq_token_declaration(&left->_body._decl_token, &right->_body._decl_token); + break; case _Z_UNDECL_KEXPR: assert_eq_forget_resource_declaration(&left->_body._undecl_kexpr, &right->_body._undecl_kexpr); break; @@ -1029,6 +1121,9 @@ void assert_eq_declaration(const _z_declaration_t *left, const _z_declaration_t case _Z_UNDECL_QUERYABLE: assert_eq_forget_queryable_declaration(&left->_body._undecl_queryable, &right->_body._undecl_queryable); break; + case _Z_UNDECL_TOKEN: + assert_eq_forget_token_declaration(&left->_body._undecl_token, &right->_body._undecl_token); + break; default: assert(false); } diff --git a/tests/z_peer_multicast_test.c b/tests/z_peer_multicast_test.c index 383ba799d..d558eccc8 100644 --- a/tests/z_peer_multicast_test.c +++ b/tests/z_peer_multicast_test.c @@ -20,6 +20,7 @@ #include "zenoh-pico.h" #include "zenoh-pico/collections/slice.h" #include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/utils/uuid.h" #undef NDEBUG #include @@ -76,10 +77,8 @@ int main(int argc, char **argv) { z_owned_session_t s1; assert(z_open(&s1, z_move(config), NULL) == Z_OK); - _z_slice_t id_as_bytes = - _z_slice_alias_buf(_Z_RC_IN_VAL(z_loan(s1))->_local_zid.id, _z_id_len(_Z_RC_IN_VAL(z_loan(s1))->_local_zid)); - _z_string_t zid1 = _z_string_convert_bytes(&id_as_bytes); - printf("Session 1 with PID: %s\n", z_string_data(&zid1)); + _z_string_t zid1 = _z_id_to_string(&(_Z_RC_IN_VAL(z_loan(s1))->_local_zid)); + printf("Session 1 with PID: %*.s\n", (int)_z_string_len(&zid1), _z_string_data(&zid1)); _z_string_clear(&zid1); // Start the read session session lease loops @@ -95,10 +94,8 @@ int main(int argc, char **argv) { z_owned_session_t s2; assert(z_open(&s2, z_move(config), NULL) == Z_OK); - id_as_bytes = - _z_slice_alias_buf(_Z_RC_IN_VAL(z_loan(s2))->_local_zid.id, _z_id_len(_Z_RC_IN_VAL(z_loan(s2))->_local_zid)); - _z_string_t zid2 = _z_string_convert_bytes(&id_as_bytes); - printf("Session 2 with PID: %s\n", z_string_data(&zid2)); + _z_string_t zid2 = _z_id_to_string(&(_Z_RC_IN_VAL(z_loan(s2))->_local_zid)); + printf("Session 2 with PID: %*.s\n", (int)_z_string_len(&zid2), _z_string_data(&zid2)); _z_string_clear(&zid2); // Start the read session session lease loops @@ -119,8 +116,8 @@ int main(int argc, char **argv) { z_view_keyexpr_from_str(&ke, s1_res); z_result_t res = z_declare_subscriber(z_loan(s2), sub, z_loan(ke), z_move(callback), NULL); assert(res == _Z_RES_OK); - printf("Declared subscription on session 2: %ju %zu %s\n", (uintmax_t)z_subscriber_loan(sub)->_entity_id, - (z_zint_t)0, s1_res); + printf("Declared subscription on session 2: %ju %i %s\n", (uintmax_t)z_subscriber_loan(sub)->_entity_id, 0, + s1_res); subs2 = _z_list_push(subs2, sub); } diff --git a/tests/z_test_fragment_rx.c b/tests/z_test_fragment_rx.c index 21184df52..d5dde99a3 100644 --- a/tests/z_test_fragment_rx.c +++ b/tests/z_test_fragment_rx.c @@ -80,7 +80,7 @@ int main(int argc, char **argv) { } // Declare subscriber z_owned_closure_sample_t callback; - z_closure(&callback, data_handler); + z_closure(&callback, data_handler, NULL, NULL); z_owned_subscriber_t sub; z_view_keyexpr_t ke; z_view_keyexpr_from_str(&ke, keyexpr); diff --git a/zenohpico.pc b/zenohpico.pc index f3f450c20..1e3b39ae2 100644 --- a/zenohpico.pc +++ b/zenohpico.pc @@ -3,6 +3,6 @@ prefix=/usr/local Name: zenohpico Description: URL: -Version: 1.0.20241004dev +Version: 1.0.20241018dev Cflags: -I${prefix}/include Libs: -L${prefix}/lib -lzenohpico diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 3559a1c90..f358d4659 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -37,6 +37,7 @@ file(GLOB_RECURSE Sources "../src/session/*.c" "../src/transport/*.c" "../src/utils/*.c" + "../src/system/platform_common.c" ) file (GLOB Sources_Zephyr "../src/system/zephyr/*.c")