From 3d954cdb94a05d4ac1040fd19dd44385898a4e08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Sat, 12 Aug 2023 15:56:35 +0200 Subject: [PATCH 01/39] FreeRTOS-Plus-TCP port: system and UDP unicast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- CMakeLists.txt | 7 ++ include/zenoh-pico/system/platform.h | 2 + .../system/platform/freertos_plus_tcp.h | 26 +++++ src/system/freertos_plus_tcp/network.c | 106 ++++++++++++++++++ src/system/freertos_plus_tcp/system.c | 86 ++++++++++++++ 5 files changed, 227 insertions(+) create mode 100644 include/zenoh-pico/system/platform/freertos_plus_tcp.h create mode 100644 src/system/freertos_plus_tcp/network.c create mode 100644 src/system/freertos_plus_tcp/system.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 332bf0411..08e7a7ead 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ include(CMakePackageConfigHelpers) option(BUILD_SHARED_LIBS "Build shared libraries if ON, otherwise build static libraries" ON) option(ZENOH_DEBUG "Use this to set the ZENOH_DEBUG variable." 0) option(WITH_ZEPHYR "Build for Zephyr RTOS" OFF) +option(WITH_FREERTOS_PLUS_TCP "Build for FreeRTOS RTOS and FreeRTOS-Plus-TCP network stack" OFF) if(CMAKE_SYSTEM_NAME MATCHES "Windows") set(BUILD_SHARED_LIBS "OFF") @@ -85,6 +86,8 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Windows") elseif(CMAKE_SYSTEM_NAME MATCHES "Generic") if(WITH_ZEPHYR) add_definition(ZENOH_ZEPHYR) + elseif(WITH_FREERTOS_PLUS_TCP) + add_definition(ZENOH_FREERTOS_PLUS_TCP) endif() else() message(FATAL_ERROR "zenoh-pico is not yet available on ${CMAKE_SYSTEM_NAME} platform") @@ -98,6 +101,7 @@ message(STATUS "Building in ${CMAKE_BUILD_TYPE} mode") message(STATUS "Build shared library: ${BUILD_SHARED_LIBS}") message(STATUS "Zenoh Level Log: ${ZENOH_DEBUG}") message(STATUS "Build for Zephyr RTOS: ${WITH_ZEPHYR}") +message(STATUS "Build for FreeRTOS-Plus-TCP: ${WITH_FREERTOS_PLUS_TCP}") message(STATUS "Configuring for ${CMAKE_SYSTEM_NAME}") if(SKBUILD) @@ -170,6 +174,9 @@ file(GLOB Sources "src/*.c" if(WITH_ZEPHYR) file (GLOB Sources_Zephyr "src/system/zephyr/*.c") list(APPEND Sources ${Sources_Zephyr}) +elseif(WITH_FREERTOS_PLUS_TCP) + file (GLOB Sources_Freertos_Plus_TCP "src/system/freertos_plus_tcp/*.c") + list(APPEND Sources ${Sources_Freertos_Plus_TCP}) elseif(CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Darwin" OR CMAKE_SYSTEM_NAME MATCHES "BSD" OR POSIX_COMPATIBLE) file (GLOB Sources_Unix "src/system/unix/*.c") list(APPEND Sources ${Sources_Unix}) diff --git a/include/zenoh-pico/system/platform.h b/include/zenoh-pico/system/platform.h index 07e1f009e..6a76e39a0 100644 --- a/include/zenoh-pico/system/platform.h +++ b/include/zenoh-pico/system/platform.h @@ -35,6 +35,8 @@ #include "zenoh-pico/system/platform/arduino/opencr.h" #elif defined(ZENOH_EMSCRIPTEN) #include "zenoh-pico/system/platform/emscripten.h" +#elif defined(ZENOH_FREERTOS_PLUS_TCP) +#include "zenoh-pico/system/platform/freertos_plus_tcp.h" #else #include "zenoh-pico/system/platform/void.h" #error "Unknown platform" diff --git a/include/zenoh-pico/system/platform/freertos_plus_tcp.h b/include/zenoh-pico/system/platform/freertos_plus_tcp.h new file mode 100644 index 000000000..f321ef10d --- /dev/null +++ b/include/zenoh-pico/system/platform/freertos_plus_tcp.h @@ -0,0 +1,26 @@ +#ifndef ZENOH_PICO_SYSTEM_FREERTOS_PLUS_TCP_TYPES_H +#define ZENOH_PICO_SYSTEM_FREERTOS_PLUS_TCP_TYPES_H + +#include "FreeRTOS.h" +#include "FreeRTOS_IP.h" + +typedef TickType_t z_clock_t; +typedef TickType_t z_time_t; + +typedef struct { + union { +#if Z_LINK_UDP_MULTICAST == 1 || Z_LINK_UDP_UNICAST == 1 + Socket_t _socket; +#endif + }; +} _z_sys_net_socket_t; + +typedef struct { + union { +#if Z_LINK_TCP == 1 || Z_LINK_UDP_MULTICAST == 1 || Z_LINK_UDP_UNICAST == 1 + struct freertos_addrinfo *_iptcp; +#endif + }; +} _z_sys_net_endpoint_t; + +#endif \ No newline at end of file diff --git a/src/system/freertos_plus_tcp/network.c b/src/system/freertos_plus_tcp/network.c new file mode 100644 index 000000000..523f4844a --- /dev/null +++ b/src/system/freertos_plus_tcp/network.c @@ -0,0 +1,106 @@ +#include + +#include "zenoh-pico/system/platform.h" +#include "zenoh-pico/utils/pointers.h" +#include "zenoh-pico/utils/result.h" + +// FreeRTOS includes +#include "FreeRTOS.h" +#include "FreeRTOS_IP.h" + +#if Z_LINK_UDP_UNICAST == 1 || Z_LINK_UDP_MULTICAST == 1 +/*------------------ UDP sockets ------------------*/ +int8_t _z_create_endpoint_udp(_z_sys_net_endpoint_t *ep, const char *s_address, const char *s_port) { + int8_t ret = _Z_RES_OK; + + if (FreeRTOS_getaddrinfo(s_address, NULL, NULL, &ep->_iptcp) < 0) { + ret = _Z_ERR_GENERIC; + } + + ep->_iptcp->ai_addr->sin_family = FREERTOS_AF_INET4; + + // Parse and check the validity of the port + uint32_t port = strtoul(s_port, NULL, 10); + if ((port > (uint32_t)0) && (port <= (uint32_t)65355)) { // Port numbers should range from 1 to 65355 + ep->_iptcp->ai_addr->sin_port = FreeRTOS_htons((uint16_t)port); + } else { + ret = _Z_ERR_GENERIC; + } + + return ret; +} + +void _z_free_endpoint_udp(_z_sys_net_endpoint_t *ep) { FreeRTOS_freeaddrinfo(ep->_iptcp); } +#endif + +#if Z_LINK_UDP_UNICAST == 1 +int8_t _z_open_udp_unicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t rep, uint32_t tout) { + int8_t ret = _Z_RES_OK; + + sock->_socket = FreeRTOS_socket(rep._iptcp->ai_family, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP); + if (sock->_socket != FREERTOS_INVALID_SOCKET) { + TickType_t receive_timeout = pdMS_TO_TICKS(tout); + + if (FreeRTOS_setsockopt(sock->_socket, 0, FREERTOS_SO_RCVTIMEO, &receive_timeout, 0) != 0) { + ret = _Z_ERR_GENERIC; + } + + if (ret != _Z_RES_OK) { + FreeRTOS_closesocket(sock->_socket); + } + } else { + ret = _Z_ERR_GENERIC; + } + + return ret; +} + +int8_t _z_listen_udp_unicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t rep, uint32_t tout) { + int8_t ret = _Z_RES_OK; + (void)sock; + (void)rep; + (void)tout; + + // @TODO: To be implemented + ret = _Z_ERR_GENERIC; + + return ret; +} + +void _z_close_udp_unicast(_z_sys_net_socket_t *sock) { FreeRTOS_closesocket(sock->_socket); } + +size_t _z_read_udp_unicast(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t len) { + struct freertos_sockaddr raddr; + uint32_t addrlen = sizeof(struct freertos_sockaddr); + + int32_t rb = FreeRTOS_recvfrom(sock._socket, ptr, len, 0, &raddr, &addrlen); + if (rb < 0) { + rb = SIZE_MAX; + } + + return rb; +} + +size_t _z_read_exact_udp_unicast(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t len) { + size_t n = 0; + uint8_t *pos = &ptr[0]; + + do { + size_t rb = _z_read_udp_unicast(sock, pos, len - n); + if (rb == SIZE_MAX) { + n = rb; + break; + } + + n = n + rb; + pos = _z_ptr_u8_offset(pos, n); + } while (n != len); + + return n; +} + +size_t _z_send_udp_unicast(const _z_sys_net_socket_t sock, const uint8_t *ptr, size_t len, + const _z_sys_net_endpoint_t rep) { + return FreeRTOS_sendto(sock._socket, ptr, len, 0, rep._iptcp->ai_addr, sizeof(struct freertos_sockaddr)); +} +#endif \ No newline at end of file diff --git a/src/system/freertos_plus_tcp/system.c b/src/system/freertos_plus_tcp/system.c new file mode 100644 index 000000000..8cb6b7ee4 --- /dev/null +++ b/src/system/freertos_plus_tcp/system.c @@ -0,0 +1,86 @@ +#include +#include +#include + +#include "FreeRTOS_IP.h" +#include "zenoh-pico/config.h" +#include "zenoh-pico/system/platform.h" + +/*------------------ Random ------------------*/ +uint8_t z_random_u8(void) { return z_random_u32(); } + +uint16_t z_random_u16(void) { return z_random_u32(); } + +uint32_t z_random_u32(void) { + uint32_t ret = 0; + xApplicationGetRandomNumber(&ret); + return ret; +} + +uint64_t z_random_u64(void) { + uint64_t ret = 0; + ret |= z_random_u32(); + ret = ret << 32; + ret |= z_random_u32(); + return ret; +} + +void z_random_fill(void *buf, size_t len) { + for (size_t i = 0; i < len; i++) { + *((uint8_t *)buf) = z_random_u8(); + } +} + +/*------------------ Memory ------------------*/ +void *z_malloc(size_t size) { return pvPortMalloc(size); } + +void *z_realloc(void *ptr, size_t size) { + // realloc not implemented in FreeRTOS + return NULL; +} + +void z_free(void *ptr) { vPortFree(ptr); } + +/*------------------ Sleep ------------------*/ +int z_sleep_us(size_t time) { + vTaskDelay(pdMS_TO_TICKS(time / 1000)); + return 0; +} + +int z_sleep_ms(size_t time) { + vTaskDelay(pdMS_TO_TICKS(time)); + return 0; +} + +int z_sleep_s(size_t time) { + vTaskDelay(pdMS_TO_TICKS(time * 1000)); + return 0; +} + +/*------------------ Clock ------------------*/ +z_clock_t z_clock_now(void) { return z_time_now(); } + +unsigned long z_clock_elapsed_us(z_clock_t *instant) { return z_clock_elapsed_ms(instant) * 1000; } + +unsigned long z_clock_elapsed_ms(z_clock_t *instant) { return z_time_elapsed_ms(instant); } + +unsigned long z_clock_elapsed_s(z_clock_t *instant) { return z_time_elapsed_ms(instant) * 1000; } + +/*------------------ Time ------------------*/ +z_time_t z_time_now(void) { return xTaskGetTickCount(); } + +const char *z_time_now_as_str(char *const buf, unsigned long buflen) { + snprintf(buf, buflen, "%u", z_time_now()); + return buf; +} + +unsigned long z_time_elapsed_us(z_time_t *time) { return z_time_elapsed_ms(time) * 1000; } + +unsigned long z_time_elapsed_ms(z_time_t *time) { + z_time_t now = z_time_now(); + + unsigned long elapsed = (now - *time) * portTICK_PERIOD_MS; + return elapsed; +} + +unsigned long z_time_elapsed_s(z_time_t *time) { return z_time_elapsed_ms(time) / 1000; } From 2d9ed4024509e97999f6cb3da10633f2c32011a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 14 Aug 2023 00:50:23 +0200 Subject: [PATCH 02/39] Fix clock_elapsed_s method --- src/system/freertos_plus_tcp/system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/freertos_plus_tcp/system.c b/src/system/freertos_plus_tcp/system.c index 8cb6b7ee4..3b46d3e55 100644 --- a/src/system/freertos_plus_tcp/system.c +++ b/src/system/freertos_plus_tcp/system.c @@ -64,7 +64,7 @@ unsigned long z_clock_elapsed_us(z_clock_t *instant) { return z_clock_elapsed_ms unsigned long z_clock_elapsed_ms(z_clock_t *instant) { return z_time_elapsed_ms(instant); } -unsigned long z_clock_elapsed_s(z_clock_t *instant) { return z_time_elapsed_ms(instant) * 1000; } +unsigned long z_clock_elapsed_s(z_clock_t *instant) { return z_clock_elapsed_ms(instant) / 1000; } /*------------------ Time ------------------*/ z_time_t z_time_now(void) { return xTaskGetTickCount(); } From d3e8cc10d3354436415fce11419b2e30f3c0f3e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 14 Aug 2023 18:51:15 +0200 Subject: [PATCH 03/39] Avoid double free --- src/system/freertos_plus_tcp/network.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/system/freertos_plus_tcp/network.c b/src/system/freertos_plus_tcp/network.c index 523f4844a..3740eb0f9 100644 --- a/src/system/freertos_plus_tcp/network.c +++ b/src/system/freertos_plus_tcp/network.c @@ -44,10 +44,6 @@ int8_t _z_open_udp_unicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_ if (FreeRTOS_setsockopt(sock->_socket, 0, FREERTOS_SO_RCVTIMEO, &receive_timeout, 0) != 0) { ret = _Z_ERR_GENERIC; } - - if (ret != _Z_RES_OK) { - FreeRTOS_closesocket(sock->_socket); - } } else { ret = _Z_ERR_GENERIC; } From f949eb374b34713e7e01dda172392b7e54c4c043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 14 Aug 2023 18:51:35 +0200 Subject: [PATCH 04/39] Add TCP transport --- src/system/freertos_plus_tcp/network.c | 88 ++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/system/freertos_plus_tcp/network.c b/src/system/freertos_plus_tcp/network.c index 3740eb0f9..a50f061ed 100644 --- a/src/system/freertos_plus_tcp/network.c +++ b/src/system/freertos_plus_tcp/network.c @@ -8,6 +8,94 @@ #include "FreeRTOS.h" #include "FreeRTOS_IP.h" +#if Z_LINK_TCP == 1 +/*------------------ TCP sockets ------------------*/ +int8_t _z_create_endpoint_tcp(_z_sys_net_endpoint_t *ep, const char *s_address, const char *s_port) { + int8_t ret = _Z_RES_OK; + + if (FreeRTOS_getaddrinfo(s_address, NULL, NULL, &ep->_iptcp) < 0) { + ret = _Z_ERR_GENERIC; + } + + ep->_iptcp->ai_addr->sin_family = FREERTOS_AF_INET4; + + // Parse and check the validity of the port + uint32_t port = strtoul(s_port, NULL, 10); + if ((port > (uint32_t)0) && (port <= (uint32_t)65355)) { // Port numbers should range from 1 to 65355 + ep->_iptcp->ai_addr->sin_port = FreeRTOS_htons((uint16_t)port); + } else { + ret = _Z_ERR_GENERIC; + } + + return ret; +} + +void _z_free_endpoint_tcp(_z_sys_net_endpoint_t *ep) { FreeRTOS_freeaddrinfo(ep->_iptcp); } + +int8_t _z_open_tcp(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t rep, uint32_t tout) { + int8_t ret = _Z_RES_OK; + + sock->_socket = FreeRTOS_socket(rep._iptcp->ai_family, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP); + if (sock->_socket != FREERTOS_INVALID_SOCKET) { + TickType_t receive_timeout = pdMS_TO_TICKS(tout); + + if (FreeRTOS_setsockopt(sock->_socket, 0, FREERTOS_SO_RCVTIMEO, &receive_timeout, 0) != 0) { + ret = _Z_ERR_GENERIC; + } else if (FreeRTOS_connect(sock->_socket, rep._iptcp->ai_addr, rep._iptcp->ai_addrlen) < 0) { + ret = _Z_ERR_GENERIC; + } + } else { + ret = _Z_ERR_GENERIC; + } + + return ret; +} + +int8_t _z_listen_tcp(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t lep) { + int8_t ret = _Z_RES_OK; + (void)sock; + (void)lep; + + // @TODO: To be implemented + ret = _Z_ERR_GENERIC; + + return ret; +} + +void _z_close_tcp(_z_sys_net_socket_t *sock) { FreeRTOS_closesocket(sock->_socket); } + +size_t _z_read_tcp(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t len) { + ssize_t rb = FreeRTOS_recv(sock._socket, ptr, len, 0); + if (rb < (ssize_t)0) { + rb = SIZE_MAX; + } + + return rb; +} + +size_t _z_read_exact_tcp(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t len) { + size_t n = 0; + uint8_t *pos = &ptr[0]; + + do { + size_t rb = _z_read_tcp(sock, pos, len - n); + if (rb == SIZE_MAX) { + n = rb; + break; + } + + n = n + rb; + pos = _z_ptr_u8_offset(pos, n); + } while (n != len); + + return n; +} + +size_t _z_send_tcp(const _z_sys_net_socket_t sock, const uint8_t *ptr, size_t len) { + return FreeRTOS_send(sock._socket, ptr, len, 0); +} +#endif + #if Z_LINK_UDP_UNICAST == 1 || Z_LINK_UDP_MULTICAST == 1 /*------------------ UDP sockets ------------------*/ int8_t _z_create_endpoint_udp(_z_sys_net_endpoint_t *ep, const char *s_address, const char *s_port) { From 8e2d99d10b21e5755924a2fd476642fc7ee2ff6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 14 Aug 2023 18:58:42 +0200 Subject: [PATCH 05/39] Fix build when only TCP is enabled --- include/zenoh-pico/system/platform/freertos_plus_tcp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zenoh-pico/system/platform/freertos_plus_tcp.h b/include/zenoh-pico/system/platform/freertos_plus_tcp.h index f321ef10d..aad78d8af 100644 --- a/include/zenoh-pico/system/platform/freertos_plus_tcp.h +++ b/include/zenoh-pico/system/platform/freertos_plus_tcp.h @@ -9,7 +9,7 @@ typedef TickType_t z_time_t; typedef struct { union { -#if Z_LINK_UDP_MULTICAST == 1 || Z_LINK_UDP_UNICAST == 1 +#if Z_LINK_TCP == 1 || Z_LINK_UDP_MULTICAST == 1 || Z_LINK_UDP_UNICAST == 1 Socket_t _socket; #endif }; From ba1c4c060f3cebf9f6e759338b6dc74fc36213e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Fri, 25 Aug 2023 18:28:27 +0200 Subject: [PATCH 06/39] Initial FreeRTOS-Plus-TCP example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/CMakeLists.txt | 69 ++++++++++ .../include/FreeRTOSConfig.h | 51 ++++++++ .../include/FreeRTOSIPConfig.h | 41 ++++++ examples/freertos_plus_tcp/main.c | 121 ++++++++++++++++++ examples/freertos_plus_tcp/z_pub.c | 76 +++++++++++ 5 files changed, 358 insertions(+) create mode 100644 examples/freertos_plus_tcp/CMakeLists.txt create mode 100644 examples/freertos_plus_tcp/include/FreeRTOSConfig.h create mode 100644 examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h create mode 100644 examples/freertos_plus_tcp/main.c create mode 100644 examples/freertos_plus_tcp/z_pub.c diff --git a/examples/freertos_plus_tcp/CMakeLists.txt b/examples/freertos_plus_tcp/CMakeLists.txt new file mode 100644 index 000000000..75f76ced0 --- /dev/null +++ b/examples/freertos_plus_tcp/CMakeLists.txt @@ -0,0 +1,69 @@ +cmake_minimum_required(VERSION 3.20) +project(zenohpico_freertos_plus_tcp_examples) + +set(CMAKE_SYSTEM_NAME "Generic") + +include(../../cmake/helpers.cmake) +set_default_build_type(Release) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(SLIRP REQUIRED slirp) + +add_library(slirp INTERFACE) +target_link_libraries(slirp INTERFACE ${SLIRP_LINK_LIBRARIES}) +target_include_directories(slirp INTERFACE ${SLIRP_INCLUDE_DIRS}) +target_compile_options(slirp INTERFACE -Wno-error) + +include(FetchContent) + +FetchContent_Declare(freertos_kernel + GIT_REPOSITORY "https://github.com/FreeRTOS/FreeRTOS-Kernel.git" + GIT_TAG "V10.6.1" +) + +FetchContent_Declare(freertos_plus_tcp + GIT_REPOSITORY "https://github.com/bjsowa/FreeRTOS-Plus-TCP.git" + GIT_TAG "44289aa" + GIT_SUBMODULES "" +) + +add_library(freertos_config INTERFACE) +target_include_directories(freertos_config SYSTEM + INTERFACE + include +) + +set(FREERTOS_HEAP "3" CACHE STRING "" FORCE) +set(FREERTOS_PORT "GCC_POSIX" CACHE STRING "" FORCE) +set(FREERTOS_PLUS_TCP_NETWORK_IF "LIBSLIRP" CACHE STRING "" FORCE) +set(FREERTOS_PLUS_TCP_BUFFER_ALLOCATION "2" CACHE STRING "" FORCE) + +FetchContent_MakeAvailable(freertos_kernel freertos_plus_tcp) + +set(BUILD_SHARED_LIBS OFF) +set(WITH_FREERTOS_PLUS_TCP ON) +configure_include_project(ZENOHPICO zenohpico zenohpico "../.." zenohpico "https://github.com/eclipse-zenoh/zenoh-pico" "") + +target_link_libraries(zenohpico + freertos_kernel + freertos_plus_tcp +) +target_compile_definitions(zenohpico + PUBLIC + Z_MULTI_THREAD=0 + Z_LINK_TCP=1 + Z_SCOUTING_UDP=1 + Z_LINK_UDP_UNICAST=1 + Z_LINK_UDP_MULTICAST=0 +) + +add_executable(z_pub + main.c + z_pub.c +) + +target_link_libraries(z_pub + freertos_kernel + freertos_plus_tcp + zenohpico +) diff --git a/examples/freertos_plus_tcp/include/FreeRTOSConfig.h b/examples/freertos_plus_tcp/include/FreeRTOSConfig.h new file mode 100644 index 000000000..98d65e1af --- /dev/null +++ b/examples/freertos_plus_tcp/include/FreeRTOSConfig.h @@ -0,0 +1,51 @@ +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "bits/pthread_stack_min.h" + +/* Core options */ +#define configUSE_PREEMPTION 1 +#define configTICK_RATE_HZ ((TickType_t)1000) +#define configMAX_PRIORITIES (56) +#define configMINIMAL_STACK_SIZE ((uint16_t) PTHREAD_STACK_MIN) +#define configMAX_TASK_NAME_LEN (16) +#define configUSE_16_BIT_TICKS 0 +#define configQUEUE_REGISTRY_SIZE 0 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#define configUSE_SB_COMPLETED_CALLBACK 0 + +/* Enable/Disable features */ +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_CO_ROUTINES 0 +#define configUSE_TIMERS 0 +#define configUSE_TRACE_FACILITY 0 +#define configUSE_QUEUE_SETS 0 +#define configUSE_NEWLIB_REENTRANT 0 + +/* Set the API functions which should be included */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xQueueGetMutexHolder 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTimerPendFunctionCall 0 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h b/examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h new file mode 100644 index 000000000..b620ea05c --- /dev/null +++ b/examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h @@ -0,0 +1,41 @@ +#ifndef FREERTOS_IP_CONFIG_H +#define FREERTOS_IP_CONFIG_H + +// Driver specific +#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN +#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1 +#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1 +#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1 +#define ipconfigZERO_COPY_RX_DRIVER 1 +#define ipconfigZERO_COPY_TX_DRIVER 1 +#define ipconfigUSE_LINKED_RX_MESSAGES 1 +#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60 + +// Enable/Disable features +#define ipconfigUSE_IPv4 1 +#define ipconfigUSE_IPv6 1 +#define ipconfigUSE_DHCP 1 +#define ipconfigUSE_DHCPv6 0 +#define ipconfigUSE_RA 0 +#define ipconfigUSE_DNS 1 +#define ipconfigUSE_TCP 1 +#define ipconfigUSE_ARP_REMOVE_ENTRY 0 +#define ipconfigUSE_ARP_REVERSED_LOOKUP 0 +#define ipconfigSUPPORT_SELECT_FUNCTION 0 +#define ipconfigSUPPORT_OUTGOING_PINGS 0 +#define ipconfigUSE_NETWORK_EVENT_HOOK 1 +#define ipconfigUSE_DHCP_HOOK 0 + +// DHCP +#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD (pdMS_TO_TICKS(1000U)) +#define ipconfigDHCP_REGISTER_HOSTNAME 1 + +#define ipconfigIP_TASK_PRIORITY (configMAX_PRIORITIES - 2) +#define ipconfigIP_TASK_STACK_SIZE_WORDS (configMINIMAL_STACK_SIZE * 5) + +// Set ipconfigBUFFER_PADDING on 64-bit platforms +#if INTPTR_MAX == INT64_MAX + #define ipconfigBUFFER_PADDING 14U +#endif + +#endif /* FREERTOS_IP_CONFIG_H */ \ No newline at end of file diff --git a/examples/freertos_plus_tcp/main.c b/examples/freertos_plus_tcp/main.c new file mode 100644 index 000000000..9865c07a5 --- /dev/null +++ b/examples/freertos_plus_tcp/main.c @@ -0,0 +1,121 @@ +#include +#include + +#include "FreeRTOS.h" +#include "FreeRTOS_IP.h" +#include "task.h" + +#define APP_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE +#define APP_TASK_PRIORITY 10 + +static const uint8_t ucIPAddress[] = {192, 168, 1, 80}; +static const uint8_t ucNetMask[] = {255, 255, 255, 0}; +static const uint8_t ucGatewayAddress[] = {192, 168, 1, 1}; +static const uint8_t ucDNSServerAddress[] = {192, 168, 1, 1}; +static const uint8_t ucMACAddress[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; + +NetworkInterface_t *pxLibslirp_FillInterfaceDescriptor(BaseType_t xEMACIndex, NetworkInterface_t *pxInterface); + +static NetworkInterface_t xInterface; +static NetworkEndPoint_t xEndPoint; + +static TaskHandle_t xAppTaskHandle; +static StaticTask_t xAppTaskTCB; +static StackType_t uxAppTaskStack[APP_TASK_STACK_DEPTH]; + +void app_main(); + +void vAppTask(void * /*argument*/) { + printf("Waiting for network...\n"); + + uint32_t ulNotificationValue = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(5000)); + + if (ulNotificationValue == 0) { + printf("Timed out waiting for network.\n"); + } else { + printf("Starting Zenoh App...\n"); + app_main(); + } + + vTaskDelete(NULL); +} + +int main(int argc, char **argv) { + memcpy(ipLOCAL_MAC_ADDRESS, ucMACAddress, sizeof(ucMACAddress)); + + pxLibslirp_FillInterfaceDescriptor(0, &xInterface); + + FreeRTOS_FillEndPoint(&xInterface, &xEndPoint, ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, + ucMACAddress); + xEndPoint.bits.bWantDHCP = 1; + + FreeRTOS_IPInit_Multi(); + + xAppTaskHandle = + xTaskCreateStatic(vAppTask, "", APP_TASK_STACK_DEPTH, NULL, APP_TASK_PRIORITY, uxAppTaskStack, &xAppTaskTCB); + vTaskStartScheduler(); + + return 0; +} + +void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize) { + static StaticTask_t xIdleTaskTCB; + static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE]; + + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} + +BaseType_t xApplicationGetRandomNumber(uint32_t *pulNumber) { + *pulNumber = (uint32_t)rand(); + + return pdTRUE; +} + +uint32_t ulApplicationGetNextSequenceNumber(uint32_t /*ulSourceAddress*/, uint16_t /*usSourcePort*/, + uint32_t /*ulDestinationAddress*/, uint16_t /*usDestinationPort*/) { + uint32_t ulNext = 0; + xApplicationGetRandomNumber(&ulNext); + + return ulNext; +} + +const char *pcApplicationHostnameHook(void) { return "FreeRTOS-simulator"; } + +void vApplicationIPNetworkEventHook_Multi(eIPCallbackEvent_t eNetworkEvent, struct xNetworkEndPoint * /*xEndPoint*/) { + if (eNetworkEvent == eNetworkUp) { + printf("Network is up!\n"); + + uint32_t ulIPAddress = 0; + uint32_t ulNetMask = 0; + uint32_t ulGatewayAddress = 0; + uint32_t ulDNSServerAddress = 0; + char cBuf[50]; + + // The network is up and configured. Print out the configuration obtained + // from the DHCP server. + FreeRTOS_GetEndPointConfiguration(&ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress, &xEndPoint); + + // Convert the IP address to a string then print it out. + FreeRTOS_inet_ntoa(ulIPAddress, cBuf); + printf("IP Address: %s\n", cBuf); + + // Convert the net mask to a string then print it out. + FreeRTOS_inet_ntoa(ulNetMask, cBuf); + printf("Subnet Mask: %s\n", cBuf); + + // Convert the IP address of the gateway to a string then print it out. + FreeRTOS_inet_ntoa(ulGatewayAddress, cBuf); + printf("Gateway IP Address: %s\n", cBuf); + + // Convert the IP address of the DNS server to a string then print it out. + FreeRTOS_inet_ntoa(ulDNSServerAddress, cBuf); + printf("DNS server IP Address: %s\r", cBuf); + + xTaskNotifyGive(xAppTaskHandle); + } else if (eNetworkEvent == eNetworkDown) { + printf("IPv4 End Point is down!\n"); + } +} diff --git a/examples/freertos_plus_tcp/z_pub.c b/examples/freertos_plus_tcp/z_pub.c new file mode 100644 index 000000000..e0758f846 --- /dev/null +++ b/examples/freertos_plus_tcp/z_pub.c @@ -0,0 +1,76 @@ +// +// Copyright (c) 2022 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: +// Błażej Sowa, + +#include + +#define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode +#if CLIENT_OR_PEER == 0 +#define MODE "client" +#define PEER "" // If empty, it will scout +#elif CLIENT_OR_PEER == 1 +#define MODE "peer" +#define PEER "udp/224.0.0.225:7447" +#else +#error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." +#endif + +#define KEYEXPR "demo/example/zenoh-pico-pub" +#define VALUE "[FreeRTOS-Plus-TCP] Pub from Zenoh-Pico!" + +void app_main() { + // Initialize Zenoh Session and other parameters + z_owned_config_t config = z_config_default(); + zp_config_insert(z_config_loan(&config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); + if (strcmp(PEER, "") != 0) { + zp_config_insert(z_config_loan(&config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + } + + // Open Zenoh session + printf("Opening Zenoh Session...\n"); + z_owned_session_t s = z_open(z_config_move(&config)); + if (!z_session_check(&s)) { + printf("Unable to open session!\n"); + return; + } + printf("OK\n"); + + // Start the receive and the session lease loop for zenoh-pico + zp_start_read_task(z_session_loan(&s), NULL); + zp_start_lease_task(z_session_loan(&s), NULL); + + printf("Declaring publisher for '%s'...", KEYEXPR); + z_owned_publisher_t pub = z_declare_publisher(z_session_loan(&s), z_keyexpr(KEYEXPR), NULL); + if (!z_publisher_check(&pub)) { + printf("Unable to declare publisher for key expression!\n"); + return; + } + printf("OK\n"); + + char buf[256]; + for (int idx = 0; 1; ++idx) { + z_sleep_s(1); + sprintf(buf, "[%4d] %s", idx, VALUE); + printf("Putting Data ('%s': '%s')...\n", KEYEXPR, buf); + z_publisher_put(z_publisher_loan(&pub), (const uint8_t *)buf, strlen(buf), NULL); + } + + printf("Closing Zenoh Session...\n"); + z_undeclare_publisher(z_publisher_move(&pub)); + + // Stop the receive and the session lease loop for zenoh-pico + zp_stop_read_task(z_session_loan(&s)); + zp_stop_lease_task(z_session_loan(&s)); + + z_close(z_session_move(&s)); + printf("OK!\n"); +} From d5024924398ffeea09f5fef54ccdff61ad0a593d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Fri, 25 Aug 2023 18:28:40 +0200 Subject: [PATCH 07/39] Initial CI workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- .github/workflows/freertos_plus_tcp.yaml | 41 ++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/freertos_plus_tcp.yaml diff --git a/.github/workflows/freertos_plus_tcp.yaml b/.github/workflows/freertos_plus_tcp.yaml new file mode 100644 index 000000000..7f919b52a --- /dev/null +++ b/.github/workflows/freertos_plus_tcp.yaml @@ -0,0 +1,41 @@ +# +# Copyright (c) 2023 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: +# Błażej Sowa, +# +name: freertos_plus_tcp + +on: + push: + branches: [ '**' ] + pull_request: + branches: [ '**' ] + +jobs: + build: + name: Build on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + steps: + - uses: actions/checkout@v2 + - uses: jwlawson/actions-setup-cmake@v1.13 + - name: Install requirements + run: | + sudo apt update + sudo apt install -y ninja-build libslirp-dev + - name: Build examples + run: | + cd examples/freertos_plus_tcp + cmake -Bbuild -G"Ninja Multi-Config" + cmake --build ./build --config Debug From c8c8b3de15c28779a7d82e8d01b2fef44310a5fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 08:34:41 +0200 Subject: [PATCH 08/39] Fix newline character in printf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/freertos_plus_tcp/main.c b/examples/freertos_plus_tcp/main.c index 9865c07a5..ec24aef94 100644 --- a/examples/freertos_plus_tcp/main.c +++ b/examples/freertos_plus_tcp/main.c @@ -112,7 +112,7 @@ void vApplicationIPNetworkEventHook_Multi(eIPCallbackEvent_t eNetworkEvent, stru // Convert the IP address of the DNS server to a string then print it out. FreeRTOS_inet_ntoa(ulDNSServerAddress, cBuf); - printf("DNS server IP Address: %s\r", cBuf); + printf("DNS server IP Address: %s\n", cBuf); xTaskNotifyGive(xAppTaskHandle); } else if (eNetworkEvent == eNetworkDown) { From b86ce9800eaf683d54b253958a76eb5fad9e32ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 08:35:47 +0200 Subject: [PATCH 09/39] Fix network driver checksum options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h b/examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h index b620ea05c..4619fbaa5 100644 --- a/examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h +++ b/examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h @@ -4,7 +4,7 @@ // Driver specific #define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN #define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1 -#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1 +#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 0 #define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1 #define ipconfigZERO_COPY_RX_DRIVER 1 #define ipconfigZERO_COPY_TX_DRIVER 1 From 46bde552a285ecfa222d0fb21bb1d49ada677e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 13:17:41 +0200 Subject: [PATCH 10/39] Fix printf newline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/z_pub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/freertos_plus_tcp/z_pub.c b/examples/freertos_plus_tcp/z_pub.c index e0758f846..caf5d0105 100644 --- a/examples/freertos_plus_tcp/z_pub.c +++ b/examples/freertos_plus_tcp/z_pub.c @@ -48,7 +48,7 @@ void app_main() { zp_start_read_task(z_session_loan(&s), NULL); zp_start_lease_task(z_session_loan(&s), NULL); - printf("Declaring publisher for '%s'...", KEYEXPR); + printf("Declaring publisher for '%s'...\n", KEYEXPR); z_owned_publisher_t pub = z_declare_publisher(z_session_loan(&s), z_keyexpr(KEYEXPR), NULL); if (!z_publisher_check(&pub)) { printf("Unable to declare publisher for key expression!\n"); From 6314ac91488ac0ac3affef6cf6bc7c6cbbf8be32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 13:18:39 +0200 Subject: [PATCH 11/39] Make vAppTask static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/freertos_plus_tcp/main.c b/examples/freertos_plus_tcp/main.c index ec24aef94..75101cb30 100644 --- a/examples/freertos_plus_tcp/main.c +++ b/examples/freertos_plus_tcp/main.c @@ -25,7 +25,7 @@ static StackType_t uxAppTaskStack[APP_TASK_STACK_DEPTH]; void app_main(); -void vAppTask(void * /*argument*/) { +static void vAppTask(void * /*argument*/) { printf("Waiting for network...\n"); uint32_t ulNotificationValue = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(5000)); From 649fed584e9c674f96b86b0ee25645469d290aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 13:19:20 +0200 Subject: [PATCH 12/39] Resolve MAC address of gateway before running Zenoh app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/freertos_plus_tcp/main.c b/examples/freertos_plus_tcp/main.c index 75101cb30..6985f338f 100644 --- a/examples/freertos_plus_tcp/main.c +++ b/examples/freertos_plus_tcp/main.c @@ -114,7 +114,13 @@ void vApplicationIPNetworkEventHook_Multi(eIPCallbackEvent_t eNetworkEvent, stru FreeRTOS_inet_ntoa(ulDNSServerAddress, cBuf); printf("DNS server IP Address: %s\n", cBuf); - xTaskNotifyGive(xAppTaskHandle); + // Make sure MAC address of the gateway is known + if (xARPWaitResolution(ulGatewayAddress, pdMS_TO_TICKS(3000)) < 0) { + xTaskNotifyGive(xAppTaskHandle); + } else { + printf("Failed to obtain the MAC address of the gateway!\n"); + } + } else if (eNetworkEvent == eNetworkDown) { printf("IPv4 End Point is down!\n"); } From c7cb1efea825bce12f4f616c52084134008230b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 13:23:10 +0200 Subject: [PATCH 13/39] Set zenoh debug level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/freertos_plus_tcp/CMakeLists.txt b/examples/freertos_plus_tcp/CMakeLists.txt index 75f76ced0..e16ee2359 100644 --- a/examples/freertos_plus_tcp/CMakeLists.txt +++ b/examples/freertos_plus_tcp/CMakeLists.txt @@ -42,6 +42,7 @@ 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" "") target_link_libraries(zenohpico From 996550073c979a59884e828f432048a263b45984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 13:23:25 +0200 Subject: [PATCH 14/39] Increase socket timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/freertos_plus_tcp/CMakeLists.txt b/examples/freertos_plus_tcp/CMakeLists.txt index e16ee2359..36f9843fc 100644 --- a/examples/freertos_plus_tcp/CMakeLists.txt +++ b/examples/freertos_plus_tcp/CMakeLists.txt @@ -56,6 +56,7 @@ target_compile_definitions(zenohpico Z_SCOUTING_UDP=1 Z_LINK_UDP_UNICAST=1 Z_LINK_UDP_MULTICAST=0 + Z_CONFIG_SOCKET_TIMEOUT=1000 ) add_executable(z_pub From 98be97f8c851b177f8aa5309a1dad37e26c6aaef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 13:44:51 +0200 Subject: [PATCH 15/39] Fix segfault when failed to create endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- src/system/freertos_plus_tcp/network.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/system/freertos_plus_tcp/network.c b/src/system/freertos_plus_tcp/network.c index a50f061ed..fdf700521 100644 --- a/src/system/freertos_plus_tcp/network.c +++ b/src/system/freertos_plus_tcp/network.c @@ -15,6 +15,7 @@ int8_t _z_create_endpoint_tcp(_z_sys_net_endpoint_t *ep, const char *s_address, if (FreeRTOS_getaddrinfo(s_address, NULL, NULL, &ep->_iptcp) < 0) { ret = _Z_ERR_GENERIC; + return ret; } ep->_iptcp->ai_addr->sin_family = FREERTOS_AF_INET4; @@ -103,6 +104,7 @@ int8_t _z_create_endpoint_udp(_z_sys_net_endpoint_t *ep, const char *s_address, if (FreeRTOS_getaddrinfo(s_address, NULL, NULL, &ep->_iptcp) < 0) { ret = _Z_ERR_GENERIC; + return ret; } ep->_iptcp->ai_addr->sin_family = FREERTOS_AF_INET4; From 28fe14f43fcb03c81df2276b1f5f059708c663a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 13:48:35 +0200 Subject: [PATCH 16/39] Fix warning about overflow in int conversion when using 64-bit system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- src/system/freertos_plus_tcp/network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/freertos_plus_tcp/network.c b/src/system/freertos_plus_tcp/network.c index fdf700521..4117f5454 100644 --- a/src/system/freertos_plus_tcp/network.c +++ b/src/system/freertos_plus_tcp/network.c @@ -159,7 +159,7 @@ size_t _z_read_udp_unicast(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t struct freertos_sockaddr raddr; uint32_t addrlen = sizeof(struct freertos_sockaddr); - int32_t rb = FreeRTOS_recvfrom(sock._socket, ptr, len, 0, &raddr, &addrlen); + size_t rb = FreeRTOS_recvfrom(sock._socket, ptr, len, 0, &raddr, &addrlen); if (rb < 0) { rb = SIZE_MAX; } From 1390425a9399fb792359aef92d84b7d9f69329a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 13:49:35 +0200 Subject: [PATCH 17/39] Use ai_family returned by getaddrinfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- src/system/freertos_plus_tcp/network.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system/freertos_plus_tcp/network.c b/src/system/freertos_plus_tcp/network.c index 4117f5454..2ccd22ca5 100644 --- a/src/system/freertos_plus_tcp/network.c +++ b/src/system/freertos_plus_tcp/network.c @@ -18,7 +18,7 @@ int8_t _z_create_endpoint_tcp(_z_sys_net_endpoint_t *ep, const char *s_address, return ret; } - ep->_iptcp->ai_addr->sin_family = FREERTOS_AF_INET4; + ep->_iptcp->ai_addr->sin_family = ep->_iptcp->ai_family; // Parse and check the validity of the port uint32_t port = strtoul(s_port, NULL, 10); @@ -107,7 +107,7 @@ int8_t _z_create_endpoint_udp(_z_sys_net_endpoint_t *ep, const char *s_address, return ret; } - ep->_iptcp->ai_addr->sin_family = FREERTOS_AF_INET4; + ep->_iptcp->ai_addr->sin_family = ep->_iptcp->ai_family; // Parse and check the validity of the port uint32_t port = strtoul(s_port, NULL, 10); From 933324f80789973d755c3ef25e2cef00642b3766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 14:33:47 +0200 Subject: [PATCH 18/39] Fix tcp and udp read methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- src/system/freertos_plus_tcp/network.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/system/freertos_plus_tcp/network.c b/src/system/freertos_plus_tcp/network.c index 2ccd22ca5..4000c0052 100644 --- a/src/system/freertos_plus_tcp/network.c +++ b/src/system/freertos_plus_tcp/network.c @@ -66,9 +66,9 @@ int8_t _z_listen_tcp(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t lep) void _z_close_tcp(_z_sys_net_socket_t *sock) { FreeRTOS_closesocket(sock->_socket); } size_t _z_read_tcp(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t len) { - ssize_t rb = FreeRTOS_recv(sock._socket, ptr, len, 0); - if (rb < (ssize_t)0) { - rb = SIZE_MAX; + BaseType_t rb = FreeRTOS_recv(sock._socket, ptr, len, 0); + if (rb < 0) { + return SIZE_MAX; } return rb; @@ -159,9 +159,9 @@ size_t _z_read_udp_unicast(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t struct freertos_sockaddr raddr; uint32_t addrlen = sizeof(struct freertos_sockaddr); - size_t rb = FreeRTOS_recvfrom(sock._socket, ptr, len, 0, &raddr, &addrlen); + int32_t rb = FreeRTOS_recvfrom(sock._socket, ptr, len, 0, &raddr, &addrlen); if (rb < 0) { - rb = SIZE_MAX; + return SIZE_MAX; } return rb; From 863333368ec0b3acecf1b8e47036a2f30e70f3ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 14:44:49 +0200 Subject: [PATCH 19/39] Retain original contributor in z_pub example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/z_pub.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/freertos_plus_tcp/z_pub.c b/examples/freertos_plus_tcp/z_pub.c index caf5d0105..9daf07021 100644 --- a/examples/freertos_plus_tcp/z_pub.c +++ b/examples/freertos_plus_tcp/z_pub.c @@ -9,6 +9,7 @@ // SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 // // Contributors: +// ZettaScale Zenoh Team, // Błażej Sowa, #include From 1c0d0b36818e6510d8388861a9ab2a21881f78ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 14:45:29 +0200 Subject: [PATCH 20/39] Add z_scout example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/CMakeLists.txt | 23 ++++-- examples/freertos_plus_tcp/z_scout.c | 91 +++++++++++++++++++++++ 2 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 examples/freertos_plus_tcp/z_scout.c diff --git a/examples/freertos_plus_tcp/CMakeLists.txt b/examples/freertos_plus_tcp/CMakeLists.txt index 36f9843fc..96de37eb3 100644 --- a/examples/freertos_plus_tcp/CMakeLists.txt +++ b/examples/freertos_plus_tcp/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.20) project(zenohpico_freertos_plus_tcp_examples) set(CMAKE_SYSTEM_NAME "Generic") +set(CMAKE_C_STANDARD 11) include(../../cmake/helpers.cmake) set_default_build_type(Release) @@ -57,15 +58,23 @@ target_compile_definitions(zenohpico Z_LINK_UDP_UNICAST=1 Z_LINK_UDP_MULTICAST=0 Z_CONFIG_SOCKET_TIMEOUT=1000 -) - -add_executable(z_pub - main.c - z_pub.c ) -target_link_libraries(z_pub +add_library(main OBJECT main.c) +target_link_libraries(main freertos_kernel freertos_plus_tcp - zenohpico ) + +function(add_example name) + add_executable(${name} ${name}.c) + target_link_libraries(${name} + main + freertos_kernel + freertos_plus_tcp + zenohpico + ) +endfunction() + +add_example(z_pub) +add_example(z_scout) diff --git a/examples/freertos_plus_tcp/z_scout.c b/examples/freertos_plus_tcp/z_scout.c new file mode 100644 index 000000000..349a4c6e9 --- /dev/null +++ b/examples/freertos_plus_tcp/z_scout.c @@ -0,0 +1,91 @@ +// +// Copyright (c) 2022 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, +// Błażej Sowa, + +#include +#include +#include +#include +#include + +#include "FreeRTOS.h" + +void fprintzid(FILE *stream, z_bytes_t zid) { + if (zid.start == NULL) { + fprintf(stream, "None"); + } else { + fprintf(stream, "Some("); + for (unsigned int i = 0; i < zid.len; i++) { + fprintf(stream, "%02X", (int)zid.start[i]); + } + fprintf(stream, ")"); + } +} + +void fprintwhatami(FILE *stream, unsigned int whatami) { + if (whatami == Z_WHATAMI_ROUTER) { + fprintf(stream, "\"Router\""); + } else if (whatami == Z_WHATAMI_PEER) { + fprintf(stream, "\"Peer\""); + } else { + fprintf(stream, "\"Other\""); + } +} + +void fprintlocators(FILE *stream, const z_str_array_t *locs) { + fprintf(stream, "["); + for (unsigned int i = 0; i < z_str_array_len(locs); i++) { + fprintf(stream, "\""); + fprintf(stream, "%s", *z_str_array_get(locs, i)); + fprintf(stream, "\""); + if (i < z_str_array_len(locs) - 1) { + fprintf(stream, ", "); + } + } + fprintf(stream, "]"); +} + +void fprinthello(FILE *stream, const z_hello_t hello) { + fprintf(stream, "Hello { zid: "); + fprintzid(stream, hello.zid); + fprintf(stream, ", whatami: "); + fprintwhatami(stream, hello.whatami); + fprintf(stream, ", locators: "); + fprintlocators(stream, &hello.locators); + fprintf(stream, " }"); +} + +void callback(z_owned_hello_t *hello, void *context) { + fprinthello(stdout, z_loan(*hello)); + fprintf(stdout, "\n"); + (*(int *)context)++; +} + +void drop(void *context) { + int count = *(int *)context; + free(context); + if (!count) { + printf("Did not find any zenoh process.\n"); + } else { + printf("Dropping scout results.\n"); + } +} + +void app_main() { + int *context = (int *)pvPortMalloc(sizeof(int)); + *context = 0; + z_owned_scouting_config_t config = z_scouting_config_default(); + z_owned_closure_hello_t closure = z_closure(callback, drop, context); + printf("Scouting...\n"); + z_scout(z_move(config), z_move(closure)); +} From 663724b4392559da6a784af8418f96bf0f5bdaa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 15:29:10 +0200 Subject: [PATCH 21/39] Base the z_pub example on unix example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/z_pub.c | 49 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/examples/freertos_plus_tcp/z_pub.c b/examples/freertos_plus_tcp/z_pub.c index 9daf07021..0dad3a9ac 100644 --- a/examples/freertos_plus_tcp/z_pub.c +++ b/examples/freertos_plus_tcp/z_pub.c @@ -14,6 +14,8 @@ #include +#include "FreeRTOS.h" + #define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode #if CLIENT_OR_PEER == 0 #define MODE "client" @@ -29,49 +31,48 @@ #define VALUE "[FreeRTOS-Plus-TCP] Pub from Zenoh-Pico!" void app_main() { - // Initialize Zenoh Session and other parameters z_owned_config_t config = z_config_default(); - zp_config_insert(z_config_loan(&config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); + zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); if (strcmp(PEER, "") != 0) { - zp_config_insert(z_config_loan(&config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); } - // Open Zenoh session - printf("Opening Zenoh Session...\n"); - z_owned_session_t s = z_open(z_config_move(&config)); - if (!z_session_check(&s)) { + printf("Opening session...\n"); + z_owned_session_t s = z_open(z_move(config)); + if (!z_check(s)) { printf("Unable to open session!\n"); return; } - printf("OK\n"); - // Start the receive and the session lease loop for zenoh-pico - zp_start_read_task(z_session_loan(&s), NULL); - zp_start_lease_task(z_session_loan(&s), NULL); + // Start read and lease tasks for zenoh-pico + if (zp_start_read_task(z_loan(s), NULL) < 0 || zp_start_lease_task(z_loan(s), NULL) < 0) { + printf("Unable to start read and lease tasks\n"); + return; + } printf("Declaring publisher for '%s'...\n", KEYEXPR); - z_owned_publisher_t pub = z_declare_publisher(z_session_loan(&s), z_keyexpr(KEYEXPR), NULL); - if (!z_publisher_check(&pub)) { + z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(KEYEXPR), NULL); + if (!z_check(pub)) { printf("Unable to declare publisher for key expression!\n"); return; } - printf("OK\n"); - char buf[256]; + char *buf = (char *)pvPortMalloc(256); for (int idx = 0; 1; ++idx) { z_sleep_s(1); - sprintf(buf, "[%4d] %s", idx, VALUE); + snprintf(buf, 256, "[%4d] %s", idx, VALUE); printf("Putting Data ('%s': '%s')...\n", KEYEXPR, buf); - z_publisher_put(z_publisher_loan(&pub), (const uint8_t *)buf, strlen(buf), NULL); + + z_publisher_put_options_t options = z_publisher_put_options_default(); + options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); + z_publisher_put(z_loan(pub), (const uint8_t *)buf, strlen(buf), &options); } - printf("Closing Zenoh Session...\n"); - z_undeclare_publisher(z_publisher_move(&pub)); + z_undeclare_publisher(z_move(pub)); - // Stop the receive and the session lease loop for zenoh-pico - zp_stop_read_task(z_session_loan(&s)); - zp_stop_lease_task(z_session_loan(&s)); + // Stop read and lease tasks for zenoh-pico + zp_stop_read_task(z_loan(s)); + zp_stop_lease_task(z_loan(s)); - z_close(z_session_move(&s)); - printf("OK!\n"); + z_close(z_move(s)); } From fe5d30e26bdfb904d4f6103a740906cb2d0fa43e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Mon, 28 Aug 2023 15:59:46 +0200 Subject: [PATCH 22/39] Add more examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/CMakeLists.txt | 4 + examples/freertos_plus_tcp/z_get.c | 97 +++++++++++++++++++++++ examples/freertos_plus_tcp/z_pub_st.c | 74 +++++++++++++++++ examples/freertos_plus_tcp/z_sub.c | 73 +++++++++++++++++ examples/freertos_plus_tcp/z_sub_st.c | 69 ++++++++++++++++ 5 files changed, 317 insertions(+) create mode 100644 examples/freertos_plus_tcp/z_get.c create mode 100644 examples/freertos_plus_tcp/z_pub_st.c create mode 100644 examples/freertos_plus_tcp/z_sub.c create mode 100644 examples/freertos_plus_tcp/z_sub_st.c diff --git a/examples/freertos_plus_tcp/CMakeLists.txt b/examples/freertos_plus_tcp/CMakeLists.txt index 96de37eb3..6f3ce2a36 100644 --- a/examples/freertos_plus_tcp/CMakeLists.txt +++ b/examples/freertos_plus_tcp/CMakeLists.txt @@ -76,5 +76,9 @@ function(add_example name) ) endfunction() +add_example(z_get) +add_example(z_pub_st) add_example(z_pub) add_example(z_scout) +add_example(z_sub_st) +add_example(z_sub) diff --git a/examples/freertos_plus_tcp/z_get.c b/examples/freertos_plus_tcp/z_get.c new file mode 100644 index 000000000..0c33ad279 --- /dev/null +++ b/examples/freertos_plus_tcp/z_get.c @@ -0,0 +1,97 @@ +// +// Copyright (c) 2022 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, +// Błażej Sowa, + +#include + +#include "FreeRTOS.h" + +#define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode +#if CLIENT_OR_PEER == 0 +#define MODE "client" +#define PEER "" // If empty, it will scout +#elif CLIENT_OR_PEER == 1 +#define MODE "peer" +#define PEER "udp/224.0.0.225:7447#iface=en0" +#else +#error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." +#endif + +#define KEYEXPR "demo/example/**" +#define VALUE "" + +void reply_dropper(void *ctx) { + (void)(ctx); + printf(">> Received query final notification\n"); +} + +void reply_handler(z_owned_reply_t *reply, void *ctx) { + (void)(ctx); + if (z_reply_is_ok(reply)) { + z_sample_t sample = z_reply_ok(reply); + z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); + printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, sample.payload.start); + z_drop(z_move(keystr)); + } else { + printf(">> Received an error\n"); + } +} + +void app_main() { + z_owned_config_t config = z_config_default(); + zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); + if (strcmp(PEER, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + } + + printf("Opening session...\n"); + z_owned_session_t s = z_open(z_move(config)); + if (!z_check(s)) { + printf("Unable to open session!\n"); + return; + } + + // Start read and lease tasks for zenoh-pico + if (zp_start_read_task(z_loan(s), NULL) < 0 || zp_start_lease_task(z_loan(s), NULL) < 0) { + printf("Unable to start read and lease tasks\n"); + return; + } + + z_keyexpr_t ke = z_keyexpr(KEYEXPR); + if (!z_check(ke)) { + printf("%s is not a valid key expression\n", KEYEXPR); + return; + } + + printf("Enter any key to pull data or 'q' to quit...\n"); + char c = '\0'; + while (1) { + z_sleep_s(5); + printf("Sending Query '%s'...\n", KEYEXPR); + z_get_options_t opts = z_get_options_default(); + if (strcmp(VALUE, "") != 0) { + opts.value.payload = _z_bytes_wrap((const uint8_t *)VALUE, strlen(VALUE)); + } + z_owned_closure_reply_t callback = z_closure(reply_handler, reply_dropper); + if (z_get(z_loan(s), ke, "", z_move(callback), &opts) < 0) { + printf("Unable to send query.\n"); + return; + } + } + + // Stop read and lease tasks for zenoh-pico + zp_stop_read_task(z_loan(s)); + zp_stop_lease_task(z_loan(s)); + + z_close(z_move(s)); +} \ No newline at end of file diff --git a/examples/freertos_plus_tcp/z_pub_st.c b/examples/freertos_plus_tcp/z_pub_st.c new file mode 100644 index 000000000..78020f1b0 --- /dev/null +++ b/examples/freertos_plus_tcp/z_pub_st.c @@ -0,0 +1,74 @@ +// +// Copyright (c) 2022 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, +// Błażej Sowa, + +#include + +#include "FreeRTOS.h" + +#define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode +#if CLIENT_OR_PEER == 0 +#define MODE "client" +#define PEER "" // If empty, it will scout +#elif CLIENT_OR_PEER == 1 +#define MODE "peer" +#define PEER "udp/224.0.0.225:7447" +#else +#error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." +#endif + +#define KEYEXPR "demo/example/zenoh-pico-pub" +#define VALUE "[FreeRTOS-Plus-TCP] Pub from Zenoh-Pico!" + +void app_main() { + z_owned_config_t config = z_config_default(); + zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); + if (strcmp(PEER, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + } + + printf("Opening session...\n"); + z_owned_session_t s = z_open(z_move(config)); + if (!z_check(s)) { + printf("Unable to open session!\n"); + return; + } + + printf("Declaring publisher for '%s'...\n", KEYEXPR); + z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(KEYEXPR), NULL); + if (!z_check(pub)) { + printf("Unable to declare publisher for key expression!\n"); + return; + } + + char *buf = (char *)pvPortMalloc(256); + z_clock_t now = z_clock_now(); + for (int idx = 0; 1;) { + if (z_clock_elapsed_ms(&now) > 1000) { + snprintf(buf, 256, "[%4d] %s", idx, VALUE); + printf("Putting Data ('%s': '%s')...\n", KEYEXPR, buf); + z_publisher_put(z_loan(pub), (const uint8_t *)buf, strlen(buf), NULL); + ++idx; + + now = z_clock_now(); + } + + zp_read(z_loan(s), NULL); + zp_send_keep_alive(z_loan(s), NULL); + zp_send_join(z_loan(s), NULL); + } + + z_undeclare_publisher(z_move(pub)); + + z_close(z_move(s)); +} diff --git a/examples/freertos_plus_tcp/z_sub.c b/examples/freertos_plus_tcp/z_sub.c new file mode 100644 index 000000000..1f75f25e5 --- /dev/null +++ b/examples/freertos_plus_tcp/z_sub.c @@ -0,0 +1,73 @@ +// +// Copyright (c) 2022 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, +// Błażej Sowa, + +#include + +#define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode +#if CLIENT_OR_PEER == 0 +#define MODE "client" +#define PEER "" // If empty, it will scout +#elif CLIENT_OR_PEER == 1 +#define MODE "peer" +#define PEER "udp/224.0.0.225:7447#iface=en0" +#else +#error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." +#endif + +#define KEYEXPR "demo/example/**" + +void data_handler(const z_sample_t *sample, void *ctx) { + (void)(ctx); + z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, + sample->payload.start); + z_drop(z_move(keystr)); +} + +void app_main() { + z_owned_config_t config = z_config_default(); + zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); + if (strcmp(PEER, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + } + + printf("Opening session...\n"); + z_owned_session_t s = z_open(z_move(config)); + if (!z_check(s)) { + printf("Unable to open session!\n"); + return; + } + + // Start read and lease tasks for zenoh-pico + if (zp_start_read_task(z_loan(s), NULL) < 0 || zp_start_lease_task(z_loan(s), NULL) < 0) { + printf("Unable to start read and lease tasks\n"); + return; + } + + z_owned_closure_sample_t callback = z_closure(data_handler); + printf("Declaring Subscriber on '%s'...\n", KEYEXPR); + z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); + if (!z_check(sub)) { + printf("Unable to declare subscriber.\n"); + return; + } + + z_undeclare_subscriber(z_move(sub)); + + // Stop read and lease tasks for zenoh-pico + zp_stop_read_task(z_loan(s)); + zp_stop_lease_task(z_loan(s)); + + z_close(z_move(s)); +} diff --git a/examples/freertos_plus_tcp/z_sub_st.c b/examples/freertos_plus_tcp/z_sub_st.c new file mode 100644 index 000000000..d212b9011 --- /dev/null +++ b/examples/freertos_plus_tcp/z_sub_st.c @@ -0,0 +1,69 @@ +// +// Copyright (c) 2022 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, +// Błażej Sowa, + +#include + +#define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode +#if CLIENT_OR_PEER == 0 +#define MODE "client" +#define PEER "" // If empty, it will scout +#elif CLIENT_OR_PEER == 1 +#define MODE "peer" +#define PEER "udp/224.0.0.225:7447#iface=en0" +#else +#error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." +#endif + +#define KEYEXPR "demo/example/**" + +void data_handler(const z_sample_t *sample, void *ctx) { + (void)(ctx); + z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, + sample->payload.start); + z_drop(z_move(keystr)); +} + +void app_main() { + z_owned_config_t config = z_config_default(); + zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); + if (strcmp(PEER, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + } + + printf("Opening session...\n"); + z_owned_session_t s = z_open(z_move(config)); + if (!z_check(s)) { + printf("Unable to open session!\n"); + return; + } + + z_owned_closure_sample_t callback = z_closure(data_handler); + printf("Declaring Subscriber on '%s'...\n", KEYEXPR); + z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); + if (!z_check(sub)) { + printf("Unable to declare subscriber.\n"); + return; + } + + while (1) { + zp_read(z_loan(s), NULL); + zp_send_keep_alive(z_loan(s), NULL); + zp_send_join(z_loan(s), NULL); + } + + z_undeclare_subscriber(z_move(sub)); + + z_close(z_move(s)); +} From 1581f377bd27c50f0082c032d154e0a06569ee49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Tue, 29 Aug 2023 09:37:24 +0200 Subject: [PATCH 23/39] Change FreeRTOS-Plus-TCP repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/freertos_plus_tcp/CMakeLists.txt b/examples/freertos_plus_tcp/CMakeLists.txt index 6f3ce2a36..82ab7041b 100644 --- a/examples/freertos_plus_tcp/CMakeLists.txt +++ b/examples/freertos_plus_tcp/CMakeLists.txt @@ -23,8 +23,8 @@ FetchContent_Declare(freertos_kernel ) FetchContent_Declare(freertos_plus_tcp - GIT_REPOSITORY "https://github.com/bjsowa/FreeRTOS-Plus-TCP.git" - GIT_TAG "44289aa" + GIT_REPOSITORY "https://github.com/FreeRTOS/FreeRTOS-Plus-TCP.git" + GIT_TAG "34148c3" GIT_SUBMODULES "" ) From 66e5d1c5dae59a8c875de6b047c57bbcfe5231c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Tue, 29 Aug 2023 09:46:00 +0200 Subject: [PATCH 24/39] Fix building in Release mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- .github/workflows/freertos_plus_tcp.yaml | 1 + examples/freertos_plus_tcp/CMakeLists.txt | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/freertos_plus_tcp.yaml b/.github/workflows/freertos_plus_tcp.yaml index 7f919b52a..1e8ee0fe7 100644 --- a/.github/workflows/freertos_plus_tcp.yaml +++ b/.github/workflows/freertos_plus_tcp.yaml @@ -39,3 +39,4 @@ jobs: cd examples/freertos_plus_tcp cmake -Bbuild -G"Ninja Multi-Config" cmake --build ./build --config Debug + cmake --build ./build --config Release diff --git a/examples/freertos_plus_tcp/CMakeLists.txt b/examples/freertos_plus_tcp/CMakeLists.txt index 82ab7041b..aed4b6912 100644 --- a/examples/freertos_plus_tcp/CMakeLists.txt +++ b/examples/freertos_plus_tcp/CMakeLists.txt @@ -29,10 +29,8 @@ FetchContent_Declare(freertos_plus_tcp ) add_library(freertos_config INTERFACE) -target_include_directories(freertos_config SYSTEM - INTERFACE - include -) +target_include_directories(freertos_config SYSTEM INTERFACE include) +target_compile_options(freertos_config INTERFACE -Wno-error) set(FREERTOS_HEAP "3" CACHE STRING "" FORCE) set(FREERTOS_PORT "GCC_POSIX" CACHE STRING "" FORCE) From 7fc8da0aac0f8fbda3c036f1e5649021bd5c6cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Tue, 29 Aug 2023 12:24:03 +0200 Subject: [PATCH 25/39] Multi-threading initial MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- .../system/platform/freertos_plus_tcp.h | 22 ++++ src/system/freertos_plus_tcp/system.c | 104 ++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/include/zenoh-pico/system/platform/freertos_plus_tcp.h b/include/zenoh-pico/system/platform/freertos_plus_tcp.h index aad78d8af..f5582dee4 100644 --- a/include/zenoh-pico/system/platform/freertos_plus_tcp.h +++ b/include/zenoh-pico/system/platform/freertos_plus_tcp.h @@ -3,6 +3,28 @@ #include "FreeRTOS.h" #include "FreeRTOS_IP.h" +#include "semphr.h" + +#if Z_MULTI_THREAD == 1 +typedef struct { + char *name; + UBaseType_t priority; + size_t stack_depth; +#if (configSUPPORT_STATIC_ALLOCATION == 1) + _Bool static_allocation; + StackType_t *stack_buffer; + StaticTask_t *task_buffer; +#endif /* SUPPORT_STATIC_ALLOCATION */ +} _z_task_attr_t; + +typedef struct { + TaskHandle_t handle; + EventGroupHandle_t join_event; +} _z_task_t; + +typedef SemaphoreHandle_t _z_mutex_t; +typedef void *_z_condvar_t; +#endif // Z_MULTI_THREAD == 1 typedef TickType_t z_clock_t; typedef TickType_t z_time_t; diff --git a/src/system/freertos_plus_tcp/system.c b/src/system/freertos_plus_tcp/system.c index 3b46d3e55..812e458ac 100644 --- a/src/system/freertos_plus_tcp/system.c +++ b/src/system/freertos_plus_tcp/system.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -41,6 +42,109 @@ void *z_realloc(void *ptr, size_t size) { void z_free(void *ptr) { vPortFree(ptr); } +#if Z_MULTI_THREAD == 1 +// In FreeRTOS, tasks created using xTaskCreate must end with vTaskDelete. +// A task function should __not__ simply return. +typedef struct { + void *(*fun)(void *); + void *arg; + EventGroupHandle_t join_event; +} __z_task_arg; + +static void z_task_wrapper(void *arg) { + __z_task_arg *targ = (__z_task_arg *)arg; + targ->fun(targ->arg); + xEventGroupSetBits(targ->join_event, 1); + vTaskDelete(NULL); +} + +static _z_task_attr_t z_default_task_attr = { + .name = "", + .priority = configMAX_PRIORITIES / 2, + .stack_depth = 5120, +#if (configSUPPORT_STATIC_ALLOCATION == 1) + .static_allocation = false, + .stack_buffer = NULL, + .task_buffer = NULL, +#endif /* SUPPORT_STATIC_ALLOCATION */ +}; + +/*------------------ Thread ------------------*/ +int8_t _z_task_init(_z_task_t *task, _z_task_attr_t *attr, void *(*fun)(void *), void *arg) { + __z_task_arg *z_arg = (__z_task_arg *)z_malloc(sizeof(__z_task_arg)); + if (z_arg == NULL) { + return -1; + } + + z_arg->fun = fun; + z_arg->arg = arg; + z_arg->join_event = task->join_event = xEventGroupCreate(); + + if (attr == NULL) { + attr = &z_default_task_attr; + } + +#if (configSUPPORT_STATIC_ALLOCATION == 1) + if (attr->static_allocation) { + task->handle = xTaskCreateStatic(z_task_wrapper, attr->name, attr->stack_depth, z_arg, attr->priority, + attr->stack_buffer, attr->task_buffer); + if (task->handle == NULL) { + return -1; + } + } else { +#endif /* SUPPORT_STATIC_ALLOCATION */ + if (xTaskCreate(z_task_wrapper, attr->name, attr->stack_depth, z_arg, attr->priority, &task->handle) != + pdPASS) { + return -1; + } +#if (configSUPPORT_STATIC_ALLOCATION == 1) + } +#endif /* SUPPORT_STATIC_ALLOCATION */ + + return 0; +} + +int8_t _z_task_join(_z_task_t *task) { + xEventGroupWaitBits(task->join_event, 1, pdFALSE, pdFALSE, portMAX_DELAY); + return 0; +} + +int8_t _z_task_cancel(_z_task_t *task) { + vTaskDelete(task->handle); + return 0; +} + +void _z_task_free(_z_task_t **task) { + z_free((*task)->handle); + z_free((*task)->join_event); + z_free(task); +} + +/*------------------ Mutex ------------------*/ +int8_t _z_mutex_init(_z_mutex_t *m) { + *m = xSemaphoreCreateRecursiveMutex(); + return *m == NULL ? -1 : 0; +} + +int8_t _z_mutex_free(_z_mutex_t *m) { + z_free(*m); + return 0; +} + +int8_t _z_mutex_lock(_z_mutex_t *m) { return xSemaphoreTakeRecursive(*m, portMAX_DELAY) == pdTRUE ? 0 : -1; } + +int8_t _z_mutex_trylock(_z_mutex_t *m) { return xSemaphoreTakeRecursive(*m, 0) == pdTRUE ? 0 : -1; } + +int8_t _z_mutex_unlock(_z_mutex_t *m) { return xSemaphoreGiveRecursive(*m) == pdTRUE ? 0 : -1; } + +/*------------------ CondVar ------------------*/ +// Condition variables not supported in FreeRTOS +int8_t _z_condvar_init(_z_condvar_t *cv) { return -1; } +int8_t _z_condvar_free(_z_condvar_t *cv) { return -1; } +int8_t _z_condvar_signal(_z_condvar_t *cv) { return -1; } +int8_t _z_condvar_wait(_z_condvar_t *cv, _z_mutex_t *m) { return -1; } +#endif // Z_MULTI_THREAD == 1 + /*------------------ Sleep ------------------*/ int z_sleep_us(size_t time) { vTaskDelay(pdMS_TO_TICKS(time / 1000)); From 841924c424ccb601baecd29fef7f186a633b223c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Tue, 29 Aug 2023 12:29:35 +0200 Subject: [PATCH 26/39] Mark UDP Multicast as unsupported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- src/system/freertos_plus_tcp/network.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/system/freertos_plus_tcp/network.c b/src/system/freertos_plus_tcp/network.c index 4000c0052..ec93c2baf 100644 --- a/src/system/freertos_plus_tcp/network.c +++ b/src/system/freertos_plus_tcp/network.c @@ -189,4 +189,8 @@ size_t _z_send_udp_unicast(const _z_sys_net_socket_t sock, const uint8_t *ptr, s const _z_sys_net_endpoint_t rep) { return FreeRTOS_sendto(sock._socket, ptr, len, 0, rep._iptcp->ai_addr, sizeof(struct freertos_sockaddr)); } -#endif \ No newline at end of file +#endif + +#if Z_LINK_UDP_MULTICAST == 1 +#error "UDP Multicast not supported yet on FreeRTOS-Plus-TCP port of Zenoh-Pico" +#endif From 8148874a8b44c36934bb7eade8dba028bd3de63c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Tue, 29 Aug 2023 12:48:51 +0200 Subject: [PATCH 27/39] Fix _z_task_free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- src/system/freertos_plus_tcp/system.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/system/freertos_plus_tcp/system.c b/src/system/freertos_plus_tcp/system.c index 812e458ac..a15c8f442 100644 --- a/src/system/freertos_plus_tcp/system.c +++ b/src/system/freertos_plus_tcp/system.c @@ -115,9 +115,8 @@ int8_t _z_task_cancel(_z_task_t *task) { } void _z_task_free(_z_task_t **task) { - z_free((*task)->handle); z_free((*task)->join_event); - z_free(task); + z_free(*task); } /*------------------ Mutex ------------------*/ From 070b5a6cb2262c7c455df9619ab95092bc009efc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Tue, 29 Aug 2023 12:50:36 +0200 Subject: [PATCH 28/39] Use multi-threading in examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/freertos_plus_tcp/CMakeLists.txt b/examples/freertos_plus_tcp/CMakeLists.txt index aed4b6912..1e2357e03 100644 --- a/examples/freertos_plus_tcp/CMakeLists.txt +++ b/examples/freertos_plus_tcp/CMakeLists.txt @@ -50,7 +50,7 @@ target_link_libraries(zenohpico ) target_compile_definitions(zenohpico PUBLIC - Z_MULTI_THREAD=0 + Z_MULTI_THREAD=1 Z_LINK_TCP=1 Z_SCOUTING_UDP=1 Z_LINK_UDP_UNICAST=1 From daa800d2ae617d520f258742b4fffda24cac04bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Tue, 29 Aug 2023 14:17:58 +0200 Subject: [PATCH 29/39] Add sleep to z_sub example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/z_sub.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/freertos_plus_tcp/z_sub.c b/examples/freertos_plus_tcp/z_sub.c index 1f75f25e5..acdb7c46f 100644 --- a/examples/freertos_plus_tcp/z_sub.c +++ b/examples/freertos_plus_tcp/z_sub.c @@ -63,6 +63,10 @@ void app_main() { return; } + while (1) { + z_sleep_s(5); + } + z_undeclare_subscriber(z_move(sub)); // Stop read and lease tasks for zenoh-pico From 424421de34a834601a86690938972d85e8a70853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Tue, 29 Aug 2023 14:56:09 +0200 Subject: [PATCH 30/39] Allow passing task attributes to read and lease tasks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- include/zenoh-pico/api/types.h | 8 ++++++++ include/zenoh-pico/net/session.h | 4 ++-- src/api/api.c | 32 ++++++++++++++++++++++++++++---- src/net/session.c | 12 ++++++------ 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/include/zenoh-pico/api/types.h b/include/zenoh-pico/api/types.h index f62d495cd..fe0294c92 100644 --- a/include/zenoh-pico/api/types.h +++ b/include/zenoh-pico/api/types.h @@ -342,7 +342,11 @@ typedef struct { * whenever issued via :c:func:`zp_start_read_task`. */ typedef struct { +#if Z_MULTI_THREAD == 1 + _z_task_attr_t *task_attributes; +#else uint8_t __dummy; // Just to avoid empty structures that might cause undefined behavior +#endif } zp_task_read_options_t; /** @@ -350,7 +354,11 @@ typedef struct { * whenever issued via :c:func:`zp_start_lease_task`. */ typedef struct { +#if Z_MULTI_THREAD == 1 + _z_task_attr_t *task_attributes; +#else uint8_t __dummy; // Just to avoid empty structures that might cause undefined behavior +#endif } zp_task_lease_options_t; /** diff --git a/include/zenoh-pico/net/session.h b/include/zenoh-pico/net/session.h index 76e628692..6f708a527 100644 --- a/include/zenoh-pico/net/session.h +++ b/include/zenoh-pico/net/session.h @@ -127,7 +127,7 @@ int8_t _zp_send_join(_z_session_t *z); * Returns: * ``0`` in case of success, ``-1`` in case of failure. */ -int8_t _zp_start_read_task(_z_session_t *z); +int8_t _zp_start_read_task(_z_session_t *z, _z_task_attr_t *attr); /** * Stop the read task. This may result in stopping a thread or a process depending @@ -154,7 +154,7 @@ int8_t _zp_stop_read_task(_z_session_t *z); * Returns: * ``0`` in case of success, ``-1`` in case of failure. */ -int8_t _zp_start_lease_task(_z_session_t *z); +int8_t _zp_start_lease_task(_z_session_t *z, _z_task_attr_t *attr); /** * Stop the lease task. This may result in stopping a thread or a process depending diff --git a/src/api/api.c b/src/api/api.c index f156f60eb..da0608253 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -953,12 +953,24 @@ z_value_t z_reply_err(const z_owned_reply_t *reply) { z_sample_t z_reply_ok(const z_owned_reply_t *reply) { return reply->_value->data.sample; } /**************** Tasks ****************/ -zp_task_read_options_t zp_task_read_options_default(void) { return (zp_task_read_options_t){.__dummy = 0}; } +zp_task_read_options_t zp_task_read_options_default(void) { + return (zp_task_read_options_t) { +#if Z_MULTI_THREAD == 1 + .task_attributes = NULL +#else + .__dummy = 0 +#endif + }; +} int8_t zp_start_read_task(z_session_t zs, const zp_task_read_options_t *options) { (void)(options); #if Z_MULTI_THREAD == 1 - return _zp_start_read_task(zs._val); + zp_task_read_options_t opt = zp_task_read_options_default(); + if (options != NULL) { + opt.task_attributes = options->task_attributes; + } + return _zp_start_read_task(zs._val, opt.task_attributes); #else (void)(zs); return -1; @@ -974,12 +986,24 @@ int8_t zp_stop_read_task(z_session_t zs) { #endif } -zp_task_lease_options_t zp_task_lease_options_default(void) { return (zp_task_lease_options_t){.__dummy = 0}; } +zp_task_lease_options_t zp_task_lease_options_default(void) { + return (zp_task_lease_options_t) { +#if Z_MULTI_THREAD == 1 + .task_attributes = NULL +#else + .__dummy = 0 +#endif + }; +} int8_t zp_start_lease_task(z_session_t zs, const zp_task_lease_options_t *options) { (void)(options); #if Z_MULTI_THREAD == 1 - return _zp_start_lease_task(zs._val); + zp_task_lease_options_t opt = zp_task_lease_options_default(); + if (options != NULL) { + opt.task_attributes = options->task_attributes; + } + return _zp_start_lease_task(zs._val, opt.task_attributes); #else (void)(zs); return -1; diff --git a/src/net/session.c b/src/net/session.c index 76f0e9656..970c54636 100644 --- a/src/net/session.c +++ b/src/net/session.c @@ -163,7 +163,7 @@ int8_t _zp_send_keep_alive(_z_session_t *zn) { return _z_send_keep_alive(&zn->_t int8_t _zp_send_join(_z_session_t *zn) { return _z_send_join(&zn->_tp); } #if Z_MULTI_THREAD == 1 -int8_t _zp_start_read_task(_z_session_t *zn) { +int8_t _zp_start_read_task(_z_session_t *zn, _z_task_attr_t *attr) { int8_t ret = _Z_RES_OK; _z_task_t *task = (_z_task_t *)z_malloc(sizeof(_z_task_t)); @@ -174,7 +174,7 @@ int8_t _zp_start_read_task(_z_session_t *zn) { if (zn->_tp._type == _Z_TRANSPORT_UNICAST_TYPE) { zn->_tp._transport._unicast._read_task = task; zn->_tp._transport._unicast._read_task_running = true; - if (_z_task_init(task, NULL, _zp_unicast_read_task, &zn->_tp._transport._unicast) != _Z_RES_OK) { + if (_z_task_init(task, attr, _zp_unicast_read_task, &zn->_tp._transport._unicast) != _Z_RES_OK) { zn->_tp._transport._unicast._read_task_running = false; ret = _Z_ERR_SYSTEM_TASK_FAILED; z_free(task); @@ -185,7 +185,7 @@ int8_t _zp_start_read_task(_z_session_t *zn) { if (zn->_tp._type == _Z_TRANSPORT_MULTICAST_TYPE) { zn->_tp._transport._multicast._read_task = task; zn->_tp._transport._multicast._read_task_running = true; - if (_z_task_init(task, NULL, _zp_multicast_read_task, &zn->_tp._transport._multicast) != _Z_RES_OK) { + if (_z_task_init(task, attr, _zp_multicast_read_task, &zn->_tp._transport._multicast) != _Z_RES_OK) { zn->_tp._transport._multicast._read_task_running = false; ret = _Z_ERR_SYSTEM_TASK_FAILED; z_free(task); @@ -221,7 +221,7 @@ int8_t _zp_stop_read_task(_z_session_t *zn) { return ret; } -int8_t _zp_start_lease_task(_z_session_t *zn) { +int8_t _zp_start_lease_task(_z_session_t *zn, _z_task_attr_t *attr) { int8_t ret = _Z_RES_OK; _z_task_t *task = (_z_task_t *)z_malloc(sizeof(_z_task_t)); @@ -232,7 +232,7 @@ int8_t _zp_start_lease_task(_z_session_t *zn) { if (zn->_tp._type == _Z_TRANSPORT_UNICAST_TYPE) { zn->_tp._transport._unicast._lease_task = task; zn->_tp._transport._unicast._lease_task_running = true; - if (_z_task_init(task, NULL, _zp_unicast_lease_task, &zn->_tp._transport._unicast) != _Z_RES_OK) { + if (_z_task_init(task, attr, _zp_unicast_lease_task, &zn->_tp._transport._unicast) != _Z_RES_OK) { zn->_tp._transport._unicast._lease_task_running = false; ret = _Z_ERR_SYSTEM_TASK_FAILED; z_free(task); @@ -243,7 +243,7 @@ int8_t _zp_start_lease_task(_z_session_t *zn) { if (zn->_tp._type == _Z_TRANSPORT_MULTICAST_TYPE) { zn->_tp._transport._multicast._lease_task = task; zn->_tp._transport._multicast._lease_task_running = true; - if (_z_task_init(task, NULL, _zp_multicast_lease_task, &zn->_tp._transport._multicast) != _Z_RES_OK) { + if (_z_task_init(task, attr, _zp_multicast_lease_task, &zn->_tp._transport._multicast) != _Z_RES_OK) { zn->_tp._transport._multicast._lease_task_running = false; ret = _Z_ERR_SYSTEM_TASK_FAILED; z_free(task); From 62556f92a8912404d9446571f33a5eb15b7804d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Tue, 29 Aug 2023 15:07:47 +0200 Subject: [PATCH 31/39] Use static tasks in z_pub example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/z_pub.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/examples/freertos_plus_tcp/z_pub.c b/examples/freertos_plus_tcp/z_pub.c index 0dad3a9ac..061c30de0 100644 --- a/examples/freertos_plus_tcp/z_pub.c +++ b/examples/freertos_plus_tcp/z_pub.c @@ -44,8 +44,36 @@ void app_main() { return; } + static StackType_t read_task_stack[1000]; + static StaticTask_t read_task_buffer; + + _z_task_attr_t read_task_attr = { + .name = "ZenohReadTask", + .priority = 10, + .stack_depth = 1000, + .static_allocation = true, + .stack_buffer = read_task_stack, + .task_buffer = &read_task_buffer, + }; + + zp_task_read_options_t read_task_opt = {.task_attributes = &read_task_attr}; + + static StackType_t lease_task_stack[1000]; + static StaticTask_t lease_task_buffer; + + _z_task_attr_t lease_task_attr = { + .name = "ZenohLeaseTask", + .priority = 10, + .stack_depth = 1000, + .static_allocation = true, + .stack_buffer = lease_task_stack, + .task_buffer = &lease_task_buffer, + }; + + zp_task_lease_options_t lease_task_opt = {.task_attributes = &lease_task_attr}; + // Start read and lease tasks for zenoh-pico - if (zp_start_read_task(z_loan(s), NULL) < 0 || zp_start_lease_task(z_loan(s), NULL) < 0) { + if (zp_start_read_task(z_loan(s), &read_task_opt) < 0 || zp_start_lease_task(z_loan(s), &lease_task_opt) < 0) { printf("Unable to start read and lease tasks\n"); return; } From a364a6e3991631c7d92df44ed71c07aff7d19a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Tue, 29 Aug 2023 16:24:35 +0200 Subject: [PATCH 32/39] Remove redundant print MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/z_get.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/freertos_plus_tcp/z_get.c b/examples/freertos_plus_tcp/z_get.c index 0c33ad279..d44b0fb5c 100644 --- a/examples/freertos_plus_tcp/z_get.c +++ b/examples/freertos_plus_tcp/z_get.c @@ -73,8 +73,6 @@ void app_main() { return; } - printf("Enter any key to pull data or 'q' to quit...\n"); - char c = '\0'; while (1) { z_sleep_s(5); printf("Sending Query '%s'...\n", KEYEXPR); From 683a4d8533b6f43048f2faee1f6fa43cfa6abcdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Tue, 29 Aug 2023 16:24:48 +0200 Subject: [PATCH 33/39] Add more examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/CMakeLists.txt | 3 + examples/freertos_plus_tcp/z_pull.c | 79 ++++++++++++++++++++ examples/freertos_plus_tcp/z_put.c | 76 +++++++++++++++++++ examples/freertos_plus_tcp/z_queryable.c | 91 +++++++++++++++++++++++ 4 files changed, 249 insertions(+) create mode 100644 examples/freertos_plus_tcp/z_pull.c create mode 100644 examples/freertos_plus_tcp/z_put.c create mode 100644 examples/freertos_plus_tcp/z_queryable.c diff --git a/examples/freertos_plus_tcp/CMakeLists.txt b/examples/freertos_plus_tcp/CMakeLists.txt index 1e2357e03..65db6b5d2 100644 --- a/examples/freertos_plus_tcp/CMakeLists.txt +++ b/examples/freertos_plus_tcp/CMakeLists.txt @@ -77,6 +77,9 @@ endfunction() add_example(z_get) add_example(z_pub_st) add_example(z_pub) +add_example(z_pull) +add_example(z_put) +add_example(z_queryable) add_example(z_scout) add_example(z_sub_st) add_example(z_sub) diff --git a/examples/freertos_plus_tcp/z_pull.c b/examples/freertos_plus_tcp/z_pull.c new file mode 100644 index 000000000..3226b459e --- /dev/null +++ b/examples/freertos_plus_tcp/z_pull.c @@ -0,0 +1,79 @@ +// +// Copyright (c) 2022 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, +// Błażej Sowa, + +#include + +#define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode +#if CLIENT_OR_PEER == 0 +#define MODE "client" +#define PEER "" // If empty, it will scout +#elif CLIENT_OR_PEER == 1 +#define MODE "peer" +#define PEER "udp/224.0.0.225:7447#iface=en0" +#else +#error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." +#endif + +#define KEYEXPR "demo/example/**" + +void data_handler(const z_sample_t *sample, void *ctx) { + (void)(ctx); + z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, + sample->payload.start); + z_drop(z_move(keystr)); +} + +void app_main() { + z_owned_config_t config = z_config_default(); + zp_config_insert(z_config_loan(&config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); + if (strcmp(PEER, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + } + + printf("Opening session...\n"); + z_owned_session_t s = z_open(z_move(config)); + if (!z_check(s)) { + printf("Unable to open session!\n"); + return; + } + + // Start read and lease tasks for zenoh-pico + if (zp_start_read_task(z_loan(s), NULL) < 0 || zp_start_lease_task(z_loan(s), NULL) < 0) { + printf("Unable to start read and lease tasks\n"); + return; + } + + z_owned_closure_sample_t callback = z_closure(data_handler); + printf("Declaring Subscriber on '%s'...\n", KEYEXPR); + z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); + if (!z_check(sub)) { + printf("Unable to declare subscriber.\n"); + return; + } + + while (1) { + z_sleep_s(5); + printf("Pulling data from '%s'...\n", KEYEXPR); + z_subscriber_pull(z_loan(sub)); + } + + z_undeclare_pull_subscriber(z_move(sub)); + + // Stop read and lease tasks for zenoh-pico + zp_stop_read_task(z_loan(s)); + zp_stop_lease_task(z_loan(s)); + + z_close(z_move(s)); +} diff --git a/examples/freertos_plus_tcp/z_put.c b/examples/freertos_plus_tcp/z_put.c new file mode 100644 index 000000000..75f482e2c --- /dev/null +++ b/examples/freertos_plus_tcp/z_put.c @@ -0,0 +1,76 @@ +// +// Copyright (c) 2022 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, +// Błażej Sowa, + +#include + +#define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode +#if CLIENT_OR_PEER == 0 +#define MODE "client" +#define PEER "" // If empty, it will scout +#elif CLIENT_OR_PEER == 1 +#define MODE "peer" +#define PEER "udp/224.0.0.225:7447" +#else +#error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." +#endif + +#define KEYEXPR "demo/example/zenoh-pico-put" +#define VALUE "[FreeRTOS-Plus-TCP] Pub from Zenoh-Pico!" + +void app_main() { + z_owned_config_t config = z_config_default(); + zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); + if (strcmp(PEER, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + } + + printf("Opening session...\n"); + z_owned_session_t s = z_open(z_move(config)); + if (!z_check(s)) { + printf("Unable to open session!\n"); + return; + } + + // Start read and lease tasks for zenoh-pico + if (zp_start_read_task(z_loan(s), NULL) < 0 || zp_start_lease_task(z_loan(s), NULL) < 0) { + printf("Unable to start read and lease tasks\n"); + return; + } + + printf("Declaring key expression '%s'...\n", KEYEXPR); + z_owned_keyexpr_t ke = z_declare_keyexpr(z_loan(s), z_keyexpr(KEYEXPR)); + if (!z_check(ke)) { + printf("Unable to declare key expression!\n"); + return; + } + + printf("Putting Data ('%s': '%s')...\n", KEYEXPR, VALUE); + z_put_options_t options = z_put_options_default(); + options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); + if (z_put(z_loan(s), z_loan(ke), (const uint8_t *)VALUE, strlen(VALUE), &options) < 0) { + printf("Oh no! Put has failed...\n"); + } + + while (1) { + z_sleep_s(1); + } + + z_undeclare_keyexpr(z_loan(s), z_move(ke)); + + // Stop read and lease tasks for zenoh-pico + zp_stop_read_task(z_loan(s)); + zp_stop_lease_task(z_loan(s)); + + z_close(z_move(s)); +} diff --git a/examples/freertos_plus_tcp/z_queryable.c b/examples/freertos_plus_tcp/z_queryable.c new file mode 100644 index 000000000..44bed3331 --- /dev/null +++ b/examples/freertos_plus_tcp/z_queryable.c @@ -0,0 +1,91 @@ +// +// Copyright (c) 2022 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, +// Błażej Sowa, + +#include + +#define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode +#if CLIENT_OR_PEER == 0 +#define MODE "client" +#define PEER "" // If empty, it will scout +#elif CLIENT_OR_PEER == 1 +#define MODE "peer" +#define PEER "udp/224.0.0.225:7447" +#else +#error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." +#endif + +#define KEYEXPR "demo/example/zenoh-pico-queryable" +#define VALUE "[FreeRTOS-Plus-TCP] Queryable from Zenoh-Pico!" + +void query_handler(const z_query_t *query, void *ctx) { + (void)(ctx); + z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); + z_bytes_t pred = z_query_parameters(query); + z_value_t payload_value = z_query_value(query); + printf(" >> [Queryable handler] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); + if (payload_value.payload.len > 0) { + printf(" with value '%.*s'\n", (int)payload_value.payload.len, payload_value.payload.start); + } + z_query_reply_options_t options = z_query_reply_options_default(); + options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); + z_query_reply(query, z_keyexpr(KEYEXPR), (const unsigned char *)VALUE, strlen(VALUE), &options); + z_drop(z_move(keystr)); +} + +void app_main() { + z_owned_config_t config = z_config_default(); + zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); + if (strcmp(PEER, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + } + + printf("Opening session...\n"); + z_owned_session_t s = z_open(z_move(config)); + if (!z_check(s)) { + printf("Unable to open session!\n"); + return; + } + + // Start read and lease tasks for zenoh-pico + if (zp_start_read_task(z_loan(s), NULL) < 0 || zp_start_lease_task(z_loan(s), NULL) < 0) { + printf("Unable to start read and lease tasks\n"); + return; + } + + z_keyexpr_t ke = z_keyexpr(KEYEXPR); + if (!z_check(ke)) { + printf("%s is not a valid key expression\n", KEYEXPR); + return; + } + + printf("Creating Queryable on '%s'...\n", KEYEXPR); + z_owned_closure_query_t callback = z_closure(query_handler); + z_owned_queryable_t qable = z_declare_queryable(z_loan(s), ke, z_move(callback), NULL); + if (!z_check(qable)) { + printf("Unable to create queryable.\n"); + return; + } + + while (1) { + z_sleep_s(5); + } + + z_undeclare_queryable(z_move(qable)); + + // Stop read and lease tasks for zenoh-pico + zp_stop_read_task(z_loan(s)); + zp_stop_lease_task(z_loan(s)); + + z_close(z_move(s)); +} From 5d92775a03a2e7da6b0244c2e98387e1e7986dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Wed, 30 Aug 2023 14:24:05 +0200 Subject: [PATCH 34/39] Change char* to const char* MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- include/zenoh-pico/system/platform/freertos_plus_tcp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zenoh-pico/system/platform/freertos_plus_tcp.h b/include/zenoh-pico/system/platform/freertos_plus_tcp.h index f5582dee4..6853e9bdc 100644 --- a/include/zenoh-pico/system/platform/freertos_plus_tcp.h +++ b/include/zenoh-pico/system/platform/freertos_plus_tcp.h @@ -7,7 +7,7 @@ #if Z_MULTI_THREAD == 1 typedef struct { - char *name; + const char *name; UBaseType_t priority; size_t stack_depth; #if (configSUPPORT_STATIC_ALLOCATION == 1) From 63c089b5f1f7229b17bd41cfa521b4e598acf282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Wed, 30 Aug 2023 15:50:25 +0200 Subject: [PATCH 35/39] Update license headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- examples/freertos_plus_tcp/CMakeLists.txt | 13 +++++++++++++ .../freertos_plus_tcp/include/FreeRTOSConfig.h | 13 +++++++++++++ .../freertos_plus_tcp/include/FreeRTOSIPConfig.h | 13 +++++++++++++ examples/freertos_plus_tcp/main.c | 13 +++++++++++++ include/zenoh-pico/api/types.h | 1 + include/zenoh-pico/net/session.h | 2 +- include/zenoh-pico/system/platform.h | 2 +- .../system/platform/freertos_plus_tcp.h | 13 +++++++++++++ src/api/api.c | 1 + src/net/session.c | 1 + src/system/freertos_plus_tcp/network.c | 15 +++++++++++++++ src/system/freertos_plus_tcp/system.c | 15 +++++++++++++++ 12 files changed, 100 insertions(+), 2 deletions(-) diff --git a/examples/freertos_plus_tcp/CMakeLists.txt b/examples/freertos_plus_tcp/CMakeLists.txt index 65db6b5d2..eb0799c7b 100644 --- a/examples/freertos_plus_tcp/CMakeLists.txt +++ b/examples/freertos_plus_tcp/CMakeLists.txt @@ -1,3 +1,16 @@ +# +# Copyright (c) 2023 Fictionlab sp. z o.o. +# +# 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: +# Błażej Sowa, + cmake_minimum_required(VERSION 3.20) project(zenohpico_freertos_plus_tcp_examples) diff --git a/examples/freertos_plus_tcp/include/FreeRTOSConfig.h b/examples/freertos_plus_tcp/include/FreeRTOSConfig.h index 98d65e1af..cbd027ce3 100644 --- a/examples/freertos_plus_tcp/include/FreeRTOSConfig.h +++ b/examples/freertos_plus_tcp/include/FreeRTOSConfig.h @@ -1,3 +1,16 @@ +// +// Copyright (c) 2023 Fictionlab sp. z o.o. +// +// 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: +// Błażej Sowa, + #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H diff --git a/examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h b/examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h index 4619fbaa5..2070ad000 100644 --- a/examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h +++ b/examples/freertos_plus_tcp/include/FreeRTOSIPConfig.h @@ -1,3 +1,16 @@ +// +// Copyright (c) 2023 Fictionlab sp. z o.o. +// +// 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: +// Błażej Sowa, + #ifndef FREERTOS_IP_CONFIG_H #define FREERTOS_IP_CONFIG_H diff --git a/examples/freertos_plus_tcp/main.c b/examples/freertos_plus_tcp/main.c index 6985f338f..5d53e7c39 100644 --- a/examples/freertos_plus_tcp/main.c +++ b/examples/freertos_plus_tcp/main.c @@ -1,3 +1,16 @@ +// +// Copyright (c) 2023 Fictionlab sp. z o.o. +// +// 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: +// Błażej Sowa, + #include #include diff --git a/include/zenoh-pico/api/types.h b/include/zenoh-pico/api/types.h index fe0294c92..4fb0121a0 100644 --- a/include/zenoh-pico/api/types.h +++ b/include/zenoh-pico/api/types.h @@ -10,6 +10,7 @@ // // Contributors: // ZettaScale Zenoh Team, +// Błażej Sowa, #ifndef ZENOH_PICO_API_TYPES_H #define ZENOH_PICO_API_TYPES_H diff --git a/include/zenoh-pico/net/session.h b/include/zenoh-pico/net/session.h index 6f708a527..693c99a10 100644 --- a/include/zenoh-pico/net/session.h +++ b/include/zenoh-pico/net/session.h @@ -10,7 +10,7 @@ // // Contributors: // ZettaScale Zenoh Team, -// +// Błażej Sowa, #ifndef ZENOH_PICO_SESSION_NETAPI_H #define ZENOH_PICO_SESSION_NETAPI_H diff --git a/include/zenoh-pico/system/platform.h b/include/zenoh-pico/system/platform.h index 6a76e39a0..e0e56e80b 100644 --- a/include/zenoh-pico/system/platform.h +++ b/include/zenoh-pico/system/platform.h @@ -10,7 +10,7 @@ // // Contributors: // ZettaScale Zenoh Team, -// +// Błażej Sowa, #ifndef ZENOH_PICO_SYSTEM_COMMON_H #define ZENOH_PICO_SYSTEM_COMMON_H diff --git a/include/zenoh-pico/system/platform/freertos_plus_tcp.h b/include/zenoh-pico/system/platform/freertos_plus_tcp.h index 6853e9bdc..c7cf3d3b1 100644 --- a/include/zenoh-pico/system/platform/freertos_plus_tcp.h +++ b/include/zenoh-pico/system/platform/freertos_plus_tcp.h @@ -1,3 +1,16 @@ +// +// Copyright (c) 2023 Fictionlab sp. z o.o. +// +// 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: +// Błażej Sowa, + #ifndef ZENOH_PICO_SYSTEM_FREERTOS_PLUS_TCP_TYPES_H #define ZENOH_PICO_SYSTEM_FREERTOS_PLUS_TCP_TYPES_H diff --git a/src/api/api.c b/src/api/api.c index da0608253..975001099 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -10,6 +10,7 @@ // // Contributors: // ZettaScale Zenoh Team, +// Błażej Sowa, #include #include diff --git a/src/net/session.c b/src/net/session.c index 970c54636..898a37499 100644 --- a/src/net/session.c +++ b/src/net/session.c @@ -10,6 +10,7 @@ // // Contributors: // ZettaScale Zenoh Team, +// Błażej Sowa, #include "zenoh-pico/net/session.h" diff --git a/src/system/freertos_plus_tcp/network.c b/src/system/freertos_plus_tcp/network.c index ec93c2baf..6d7c44cd6 100644 --- a/src/system/freertos_plus_tcp/network.c +++ b/src/system/freertos_plus_tcp/network.c @@ -1,3 +1,18 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// Copyright (c) 2023 Fictionlab sp. z o.o. +// +// 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, +// Błażej Sowa, + #include #include "zenoh-pico/system/platform.h" diff --git a/src/system/freertos_plus_tcp/system.c b/src/system/freertos_plus_tcp/system.c index a15c8f442..a68e3cdf3 100644 --- a/src/system/freertos_plus_tcp/system.c +++ b/src/system/freertos_plus_tcp/system.c @@ -1,3 +1,18 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// Copyright (c) 2023 Fictionlab sp. z o.o. +// +// 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, +// Błażej Sowa, + #include #include #include From 2291ddd9c1d17293dbb3d7384a9040618ae3ac75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Wed, 30 Aug 2023 16:22:00 +0200 Subject: [PATCH 36/39] Update README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f5b725997..61019985d 100644 --- a/README.md +++ b/README.md @@ -24,16 +24,17 @@ It is fully compatible with its main [Rust Zenoh implementation](https://github. Currently, zenoh-pico provides support for the following (RT)OSs and protocols: -| **(RT)OS** | **Transport Layer** | **Network Layer** | **Data Link Layer** | -|:---------------:|:--------------------------------:|:-------------------:|:--------------------------------------------------:| -| **Unix** | UDP (unicast and multicast), TCP | IPv4, IPv6, 6LoWPAN | WiFi, Ethernet, Thread | -| **Windows** | UDP (unicast and multicast), TCP | IPv4, IPv6 | WiFi, Ethernet | -| **Zephyr** | UDP (unicast and multicast), TCP | IPv4, IPv6, 6LoWPAN | WiFi, Ethernet, Thread, Serial | -| **Arduino** | UDP (unicast and multicast), TCP | IPv4, IPv6 | WiFi, Ethernet, Bluetooth (Serial profile), Serial | -| **ESP-IDF** | UDP (unicast and multicast), TCP | IPv4, IPv6 | WiFi, Ethernet, Serial | -| **MbedOS** | UDP (unicast and multicast), TCP | IPv4, IPv6 | WiFi, Ethernet, Serial | -| **OpenCR** | UDP (unicast and multicast), TCP | IPv4 | WiFi | -| **Emscripten** | Websocket | IPv4, IPv6 | WiFi, Ethernet | +| **(RT)OS** | **Transport Layer** | **Network Layer** | **Data Link Layer** | +|:---------------------:|:--------------------------------:|:-------------------:|:--------------------------------------------------:| +| **Unix** | UDP (unicast and multicast), TCP | IPv4, IPv6, 6LoWPAN | WiFi, Ethernet, Thread | +| **Windows** | UDP (unicast and multicast), TCP | IPv4, IPv6 | WiFi, Ethernet | +| **Zephyr** | UDP (unicast and multicast), TCP | IPv4, IPv6, 6LoWPAN | WiFi, Ethernet, Thread, Serial | +| **Arduino** | UDP (unicast and multicast), TCP | IPv4, IPv6 | WiFi, Ethernet, Bluetooth (Serial profile), Serial | +| **ESP-IDF** | UDP (unicast and multicast), TCP | IPv4, IPv6 | WiFi, Ethernet, Serial | +| **MbedOS** | UDP (unicast and multicast), TCP | IPv4, IPv6 | WiFi, Ethernet, Serial | +| **OpenCR** | UDP (unicast and multicast), TCP | IPv4 | WiFi | +| **Emscripten** | Websocket | IPv4, IPv6 | WiFi, Ethernet | +| **FreeRTOS-Plus-TCP** | UDP (unicast), TCP | IPv4 | Ethernet | Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. From 4e81de922d948a1348e442b9ce39583299e5bb00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Thu, 21 Sep 2023 21:59:06 +0200 Subject: [PATCH 37/39] Fix config keys --- examples/freertos_plus_tcp/z_get.c | 8 ++++---- examples/freertos_plus_tcp/z_pub.c | 8 ++++---- examples/freertos_plus_tcp/z_pub_st.c | 8 ++++---- examples/freertos_plus_tcp/z_pull.c | 8 ++++---- examples/freertos_plus_tcp/z_put.c | 8 ++++---- examples/freertos_plus_tcp/z_queryable.c | 8 ++++---- examples/freertos_plus_tcp/z_sub.c | 8 ++++---- examples/freertos_plus_tcp/z_sub_st.c | 8 ++++---- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/examples/freertos_plus_tcp/z_get.c b/examples/freertos_plus_tcp/z_get.c index d44b0fb5c..8a0f74b4f 100644 --- a/examples/freertos_plus_tcp/z_get.c +++ b/examples/freertos_plus_tcp/z_get.c @@ -19,10 +19,10 @@ #define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode #if CLIENT_OR_PEER == 0 #define MODE "client" -#define PEER "" // If empty, it will scout +#define CONNECT "" // If empty, it will scout #elif CLIENT_OR_PEER == 1 #define MODE "peer" -#define PEER "udp/224.0.0.225:7447#iface=en0" +#define CONNECT "udp/224.0.0.225:7447#iface=en0" #else #error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." #endif @@ -50,8 +50,8 @@ void reply_handler(z_owned_reply_t *reply, void *ctx) { void app_main() { z_owned_config_t config = z_config_default(); zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); - if (strcmp(PEER, "") != 0) { - zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + if (strcmp(CONNECT, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_CONNECT_KEY, z_string_make(CONNECT)); } printf("Opening session...\n"); diff --git a/examples/freertos_plus_tcp/z_pub.c b/examples/freertos_plus_tcp/z_pub.c index 061c30de0..969202074 100644 --- a/examples/freertos_plus_tcp/z_pub.c +++ b/examples/freertos_plus_tcp/z_pub.c @@ -19,10 +19,10 @@ #define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode #if CLIENT_OR_PEER == 0 #define MODE "client" -#define PEER "" // If empty, it will scout +#define CONNECT "" // If empty, it will scout #elif CLIENT_OR_PEER == 1 #define MODE "peer" -#define PEER "udp/224.0.0.225:7447" +#define CONNECT "udp/224.0.0.225:7447" #else #error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." #endif @@ -33,8 +33,8 @@ void app_main() { z_owned_config_t config = z_config_default(); zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); - if (strcmp(PEER, "") != 0) { - zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + if (strcmp(CONNECT, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_CONNECT_KEY, z_string_make(CONNECT)); } printf("Opening session...\n"); diff --git a/examples/freertos_plus_tcp/z_pub_st.c b/examples/freertos_plus_tcp/z_pub_st.c index 78020f1b0..f31516b72 100644 --- a/examples/freertos_plus_tcp/z_pub_st.c +++ b/examples/freertos_plus_tcp/z_pub_st.c @@ -19,10 +19,10 @@ #define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode #if CLIENT_OR_PEER == 0 #define MODE "client" -#define PEER "" // If empty, it will scout +#define CONNECT "" // If empty, it will scout #elif CLIENT_OR_PEER == 1 #define MODE "peer" -#define PEER "udp/224.0.0.225:7447" +#define CONNECT "udp/224.0.0.225:7447" #else #error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." #endif @@ -33,8 +33,8 @@ void app_main() { z_owned_config_t config = z_config_default(); zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); - if (strcmp(PEER, "") != 0) { - zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + if (strcmp(CONNECT, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_CONNECT_KEY, z_string_make(CONNECT)); } printf("Opening session...\n"); diff --git a/examples/freertos_plus_tcp/z_pull.c b/examples/freertos_plus_tcp/z_pull.c index 3226b459e..b6d5d84f8 100644 --- a/examples/freertos_plus_tcp/z_pull.c +++ b/examples/freertos_plus_tcp/z_pull.c @@ -17,10 +17,10 @@ #define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode #if CLIENT_OR_PEER == 0 #define MODE "client" -#define PEER "" // If empty, it will scout +#define CONNECT "" // If empty, it will scout #elif CLIENT_OR_PEER == 1 #define MODE "peer" -#define PEER "udp/224.0.0.225:7447#iface=en0" +#define CONNECT "udp/224.0.0.225:7447#iface=en0" #else #error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." #endif @@ -38,8 +38,8 @@ void data_handler(const z_sample_t *sample, void *ctx) { void app_main() { z_owned_config_t config = z_config_default(); zp_config_insert(z_config_loan(&config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); - if (strcmp(PEER, "") != 0) { - zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + if (strcmp(CONNECT, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_CONNECT_KEY, z_string_make(CONNECT)); } printf("Opening session...\n"); diff --git a/examples/freertos_plus_tcp/z_put.c b/examples/freertos_plus_tcp/z_put.c index 75f482e2c..f8913146d 100644 --- a/examples/freertos_plus_tcp/z_put.c +++ b/examples/freertos_plus_tcp/z_put.c @@ -17,10 +17,10 @@ #define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode #if CLIENT_OR_PEER == 0 #define MODE "client" -#define PEER "" // If empty, it will scout +#define CONNECT "" // If empty, it will scout #elif CLIENT_OR_PEER == 1 #define MODE "peer" -#define PEER "udp/224.0.0.225:7447" +#define CONNECT "udp/224.0.0.225:7447" #else #error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." #endif @@ -31,8 +31,8 @@ void app_main() { z_owned_config_t config = z_config_default(); zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); - if (strcmp(PEER, "") != 0) { - zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + if (strcmp(CONNECT, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_CONNECT_KEY, z_string_make(CONNECT)); } printf("Opening session...\n"); diff --git a/examples/freertos_plus_tcp/z_queryable.c b/examples/freertos_plus_tcp/z_queryable.c index 44bed3331..1a9f19514 100644 --- a/examples/freertos_plus_tcp/z_queryable.c +++ b/examples/freertos_plus_tcp/z_queryable.c @@ -17,10 +17,10 @@ #define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode #if CLIENT_OR_PEER == 0 #define MODE "client" -#define PEER "" // If empty, it will scout +#define CONNECT "" // If empty, it will scout #elif CLIENT_OR_PEER == 1 #define MODE "peer" -#define PEER "udp/224.0.0.225:7447" +#define CONNECT "udp/224.0.0.225:7447" #else #error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." #endif @@ -46,8 +46,8 @@ void query_handler(const z_query_t *query, void *ctx) { void app_main() { z_owned_config_t config = z_config_default(); zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); - if (strcmp(PEER, "") != 0) { - zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + if (strcmp(CONNECT, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_CONNECT_KEY, z_string_make(CONNECT)); } printf("Opening session...\n"); diff --git a/examples/freertos_plus_tcp/z_sub.c b/examples/freertos_plus_tcp/z_sub.c index acdb7c46f..62e39ba59 100644 --- a/examples/freertos_plus_tcp/z_sub.c +++ b/examples/freertos_plus_tcp/z_sub.c @@ -17,10 +17,10 @@ #define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode #if CLIENT_OR_PEER == 0 #define MODE "client" -#define PEER "" // If empty, it will scout +#define CONNECT "" // If empty, it will scout #elif CLIENT_OR_PEER == 1 #define MODE "peer" -#define PEER "udp/224.0.0.225:7447#iface=en0" +#define CONNECT "udp/224.0.0.225:7447#iface=en0" #else #error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." #endif @@ -38,8 +38,8 @@ void data_handler(const z_sample_t *sample, void *ctx) { void app_main() { z_owned_config_t config = z_config_default(); zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); - if (strcmp(PEER, "") != 0) { - zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + if (strcmp(CONNECT, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_CONNECT_KEY, z_string_make(CONNECT)); } printf("Opening session...\n"); diff --git a/examples/freertos_plus_tcp/z_sub_st.c b/examples/freertos_plus_tcp/z_sub_st.c index d212b9011..b051ed467 100644 --- a/examples/freertos_plus_tcp/z_sub_st.c +++ b/examples/freertos_plus_tcp/z_sub_st.c @@ -17,10 +17,10 @@ #define CLIENT_OR_PEER 0 // 0: Client mode; 1: Peer mode #if CLIENT_OR_PEER == 0 #define MODE "client" -#define PEER "" // If empty, it will scout +#define CONNECT "" // If empty, it will scout #elif CLIENT_OR_PEER == 1 #define MODE "peer" -#define PEER "udp/224.0.0.225:7447#iface=en0" +#define CONNECT "udp/224.0.0.225:7447#iface=en0" #else #error "Unknown Zenoh operation mode. Check CLIENT_OR_PEER value." #endif @@ -38,8 +38,8 @@ void data_handler(const z_sample_t *sample, void *ctx) { void app_main() { z_owned_config_t config = z_config_default(); zp_config_insert(z_loan(config), Z_CONFIG_MODE_KEY, z_string_make(MODE)); - if (strcmp(PEER, "") != 0) { - zp_config_insert(z_loan(config), Z_CONFIG_PEER_KEY, z_string_make(PEER)); + if (strcmp(CONNECT, "") != 0) { + zp_config_insert(z_loan(config), Z_CONFIG_CONNECT_KEY, z_string_make(CONNECT)); } printf("Opening session...\n"); From d6d757fd029027d459a57f1830395df7428ecc9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Thu, 21 Sep 2023 22:02:14 +0200 Subject: [PATCH 38/39] Fix fprintzid --- examples/freertos_plus_tcp/z_scout.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/freertos_plus_tcp/z_scout.c b/examples/freertos_plus_tcp/z_scout.c index 349a4c6e9..c73785779 100644 --- a/examples/freertos_plus_tcp/z_scout.c +++ b/examples/freertos_plus_tcp/z_scout.c @@ -20,13 +20,14 @@ #include "FreeRTOS.h" -void fprintzid(FILE *stream, z_bytes_t zid) { - if (zid.start == NULL) { +void fprintzid(FILE *stream, z_id_t zid) { + unsigned int zidlen = _z_id_len(zid); + if (zidlen == 0) { fprintf(stream, "None"); } else { fprintf(stream, "Some("); - for (unsigned int i = 0; i < zid.len; i++) { - fprintf(stream, "%02X", (int)zid.start[i]); + for (unsigned int i = 0; i < zidlen; i++) { + fprintf(stream, "%02X", (int)zid.id[i]); } fprintf(stream, ")"); } From 376ed9933efbb277e845bfd9cc9af4f9f912ad92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Sowa?= Date: Thu, 21 Sep 2023 23:04:45 +0200 Subject: [PATCH 39/39] Ignore freertos_plus_tcp port sources when using PlatformIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Błażej Sowa --- extra_script.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extra_script.py b/extra_script.py index 391eb8047..0a8217f6b 100644 --- a/extra_script.py +++ b/extra_script.py @@ -25,6 +25,7 @@ "-", "-", "-", + "-", "-", "-", "-"] @@ -39,6 +40,7 @@ "-", "-", "-", + "-", "-", "-", "-", @@ -53,6 +55,7 @@ "-", "-", "-", + "-", "-", "-", "-", @@ -65,6 +68,7 @@ "-", "-", "-", + "-", "-", "-", "-", @@ -78,6 +82,7 @@ "-", "-", "-", + "-", "-", "-", "-"]