-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
600 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// | ||
// 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, <[email protected]> | ||
|
||
#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" | ||
#include "event_groups.h" | ||
#include "lwip/ip4_addr.h" | ||
#include "semphr.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#if Z_FEATURE_MULTI_THREAD == 1 | ||
typedef struct { | ||
const 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 struct timespec z_clock_t; | ||
typedef struct timeval z_time_t; | ||
|
||
typedef struct { | ||
union { | ||
#if Z_FEATURE_LINK_TCP == 1 || Z_FEATURE_LINK_UDP_MULTICAST == 1 || Z_FEATURE_LINK_UDP_UNICAST == 1 | ||
int _fd; | ||
#endif | ||
}; | ||
} _z_sys_net_socket_t; | ||
|
||
typedef struct { | ||
union { | ||
#if Z_FEATURE_LINK_TCP == 1 || Z_FEATURE_LINK_UDP_MULTICAST == 1 || Z_FEATURE_LINK_UDP_UNICAST == 1 | ||
struct addrinfo *_iptcp; | ||
#endif | ||
}; | ||
} _z_sys_net_endpoint_t; | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,264 @@ | ||
// | ||
// Copyright (c) 2024 ZettaScale Technology | ||
// | ||
// This program and the accompanying materials are made available under the | ||
// terms of the Eclipse Public License 2.0 which is available at | ||
// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 | ||
// which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
// | ||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
// | ||
// Contributors: | ||
// ZettaScale Zenoh Team, <[email protected]> | ||
|
||
#include <stdlib.h> | ||
|
||
#include "lwip/dns.h" | ||
#include "lwip/ip4_addr.h" | ||
#include "lwip/netdb.h" | ||
#include "lwip/pbuf.h" | ||
#include "lwip/sockets.h" | ||
#include "lwip/udp.h" | ||
#include "zenoh-pico/system/platform.h" | ||
#include "zenoh-pico/utils/logging.h" | ||
#include "zenoh-pico/utils/pointers.h" | ||
#include "zenoh-pico/utils/result.h" | ||
|
||
#if Z_FEATURE_LINK_TCP == 1 | ||
/*------------------ TCP sockets ------------------*/ | ||
z_result_t _z_create_endpoint_tcp(_z_sys_net_endpoint_t *ep, const char *s_address, const char *s_port) { | ||
z_result_t ret = _Z_RES_OK; | ||
|
||
struct addrinfo hints; | ||
(void)memset(&hints, 0, sizeof(hints)); | ||
hints.ai_family = PF_UNSPEC; // Allow IPv4 or IPv6 | ||
hints.ai_socktype = SOCK_STREAM; | ||
hints.ai_flags = 0; | ||
hints.ai_protocol = IPPROTO_TCP; | ||
|
||
if (getaddrinfo(s_address, s_port, &hints, &ep->_iptcp) < 0) { | ||
ret = _Z_ERR_GENERIC; | ||
} | ||
|
||
_Z_DEBUG("_z_create_endpoint_tcp: %s:%s -> %li", s_address, s_port, ep->_iptcp->ai_addrlen); | ||
return ret; | ||
} | ||
|
||
void _z_free_endpoint_tcp(_z_sys_net_endpoint_t *ep) { freeaddrinfo(ep->_iptcp); } | ||
|
||
z_result_t _z_open_tcp(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t rep, uint32_t tout) { | ||
z_result_t ret = _Z_RES_OK; | ||
|
||
sock->_fd = socket(rep._iptcp->ai_family, rep._iptcp->ai_socktype, rep._iptcp->ai_protocol); | ||
if (sock->_fd != -1) { | ||
// TODO: check what options not supported | ||
/* | ||
z_time_t tv; | ||
tv.tv_sec = tout / (uint32_t)1000; | ||
tv.tv_usec = (tout % (uint32_t)1000) * (uint32_t)1000; | ||
if ((ret == _Z_RES_OK) && (setsockopt(sock->_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) < 0)) { | ||
ret = _Z_ERR_GENERIC; | ||
} | ||
int flags = 1; | ||
if ((ret == _Z_RES_OK) && | ||
(setsockopt(sock->_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags)) < 0)) { | ||
ret = _Z_ERR_GENERIC; | ||
} | ||
#if Z_FEATURE_TCP_NODELAY == 1 | ||
if ((ret == _Z_RES_OK) && | ||
(setsockopt(sock->_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags)) < 0)) { | ||
ret = _Z_ERR_GENERIC; | ||
} | ||
#endif | ||
struct linger ling; | ||
ling.l_onoff = 1; | ||
ling.l_linger = Z_TRANSPORT_LEASE / 1000; | ||
if ((ret == _Z_RES_OK) && | ||
(setsockopt(sock->_fd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(struct linger)) < 0)) { | ||
ret = _Z_ERR_GENERIC; | ||
} | ||
*/ | ||
struct addrinfo *it = NULL; | ||
for (it = rep._iptcp; it != NULL; it = it->ai_next) { | ||
if ((ret == _Z_RES_OK) && (connect(sock->_fd, it->ai_addr, it->ai_addrlen) < 0)) { | ||
if (it->ai_next == NULL) { | ||
ret = _Z_ERR_GENERIC; | ||
break; | ||
} | ||
} else { | ||
break; | ||
} | ||
} | ||
|
||
if (ret != _Z_RES_OK) { | ||
close(sock->_fd); | ||
} | ||
} else { | ||
ret = _Z_ERR_GENERIC; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
z_result_t _z_listen_tcp(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t lep) { | ||
z_result_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) { | ||
shutdown(sock->_fd, SHUT_RDWR); | ||
close(sock->_fd); | ||
} | ||
|
||
size_t _z_read_tcp(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t len) { | ||
ssize_t rb = recv(sock._fd, ptr, len, 0); | ||
if (rb < (ssize_t)0) { | ||
return SIZE_MAX; | ||
} | ||
|
||
return (size_t)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) { | ||
#if defined(ZENOH_LINUX) | ||
return (size_t)send(sock._fd, ptr, len, MSG_NOSIGNAL); | ||
#else | ||
return send(sock._fd, ptr, len, 0); | ||
#endif | ||
} | ||
#endif | ||
|
||
#if Z_FEATURE_LINK_UDP_UNICAST == 1 || Z_FEATURE_LINK_UDP_MULTICAST == 1 | ||
/*------------------ UDP sockets ------------------*/ | ||
z_result_t _z_create_endpoint_udp(_z_sys_net_endpoint_t *ep, const char *s_address, const char *s_port) { | ||
z_result_t ret = _Z_RES_OK; | ||
|
||
struct addrinfo hints; | ||
(void)memset(&hints, 0, sizeof(hints)); | ||
hints.ai_family = PF_UNSPEC; // Allow IPv4 or IPv6 | ||
hints.ai_socktype = SOCK_DGRAM; | ||
hints.ai_flags = 0; | ||
hints.ai_protocol = IPPROTO_UDP; | ||
|
||
if (getaddrinfo(s_address, s_port, &hints, &ep->_iptcp) < 0) { | ||
ret = _Z_ERR_GENERIC; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
void _z_free_endpoint_udp(_z_sys_net_endpoint_t *ep) { freeaddrinfo(ep->_iptcp); } | ||
#endif | ||
|
||
#if Z_FEATURE_LINK_UDP_UNICAST == 1 | ||
z_result_t _z_open_udp_unicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t rep, uint32_t tout) { | ||
z_result_t ret = _Z_RES_OK; | ||
|
||
sock->_fd = socket(rep._iptcp->ai_family, rep._iptcp->ai_socktype, rep._iptcp->ai_protocol); | ||
if (sock->_fd != -1) { | ||
z_time_t tv; | ||
tv.tv_sec = tout / (uint32_t)1000; | ||
tv.tv_usec = (tout % (uint32_t)1000) * (uint32_t)1000; | ||
if ((ret == _Z_RES_OK) && (setsockopt(sock->_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) < 0)) { | ||
ret = _Z_ERR_GENERIC; | ||
} | ||
|
||
if (ret != _Z_RES_OK) { | ||
close(sock->_fd); | ||
} | ||
} else { | ||
ret = _Z_ERR_GENERIC; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
z_result_t _z_listen_udp_unicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t lep, uint32_t tout) { | ||
(void)sock; | ||
(void)lep; | ||
(void)tout; | ||
|
||
// @TODO: To be implemented | ||
ret = _Z_ERR_GENERIC; | ||
|
||
return ret; | ||
} | ||
|
||
void _z_close_udp_unicast(_z_sys_net_socket_t *sock) { close(sock->_fd); } | ||
|
||
size_t _z_read_udp_unicast(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t len) { | ||
struct sockaddr_storage raddr; | ||
unsigned int addrlen = sizeof(struct sockaddr_storage); | ||
|
||
ssize_t rb = recvfrom(sock._fd, ptr, len, 0, (struct sockaddr *)&raddr, &addrlen); | ||
if (rb < (ssize_t)0) { | ||
return SIZE_MAX; | ||
} | ||
return (size_t)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, (ptrdiff_t)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 (size_t)sendto(sock._fd, ptr, len, 0, rep._iptcp->ai_addr, rep._iptcp->ai_addrlen); | ||
} | ||
#endif | ||
|
||
#if Z_FEATURE_LINK_UDP_MULTICAST == 1 | ||
#error "UDP Multicast not supported yet on Raspberry Pico W port of Zenoh-Pico" | ||
#endif | ||
|
||
#if Z_FEATURE_LINK_BLUETOOTH == 1 | ||
#error "Bluetooth not supported yet on Raspberry Pico W port of Zenoh-Pico" | ||
#endif | ||
|
||
#if Z_FEATURE_LINK_SERIAL == 1 | ||
#error "Serial not supported yet on Raspberry Pico W port of Zenoh-Pico" | ||
#endif | ||
|
||
#if Z_FEATURE_RAWETH_TRANSPORT == 1 | ||
#error "Raw ethernet transport not supported yet on Raspberry Pico W port of Zenoh-Pico" | ||
#endif |
Oops, something went wrong.