LwIP: Support TCP

If LWIP_TCP is set, then CoAP TCP support is compiled in.
This commit is contained in:
Jon Shallow authored and Jon Shallow committed 2023-11-11 10:24:08 +00:00
1 parent fa88e3235b
commit 805d148dd0
15 files changed
+377 -83

No files matched your search

+9 -11
View File
@@ -76,7 +76,7 @@ nack_handler(coap_session_t *session COAP_UNUSED,
static int
resolve_address(const char *host, const char *service, coap_address_t *dst,
int scheme_hint_bits) {
coap_proto_t *proto, int scheme_hint_bits) {
coap_addr_info_t *addr_info;
coap_str_const_t str_host;
@@ -92,6 +92,7 @@ resolve_address(const char *host, const char *service, coap_address_t *dst,
if (addr_info) {
ret = 1;
*dst = addr_info->addr;
*proto = addr_info->proto;
}
coap_free_address_info(addr_info);
@@ -118,6 +119,7 @@ client_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg,
const char *use_psk = "secretPSK";
const char *use_id = "abc";
coap_pdu_type_t pdu_type = COAP_MESSAGE_CON;
coap_proto_t proto;
/* Initialize libcoap library */
coap_startup();
@@ -155,17 +157,12 @@ client_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg,
/* Parse the URI */
len = coap_split_uri((const unsigned char *)use_uri, strlen(use_uri), &uri);
LWIP_ASSERT("Failed to parse uri", len == 0);
LWIP_ASSERT("Unsupported URI type", uri.scheme == COAP_URI_SCHEME_COAP ||
uri.scheme == COAP_URI_SCHEME_COAPS);
if (uri.scheme == COAP_URI_SCHEME_COAPS) {
LWIP_ASSERT("DTLS not supported", coap_dtls_is_supported());
}
snprintf(portbuf, sizeof(portbuf), "%d", uri.port);
snprintf((char *)buf, sizeof(buf), "%*.*s", (int)uri.host.length,
(int)uri.host.length, (const char *)uri.host.s);
/* resolve destination address where server should be sent */
len = resolve_address((const char *)buf, portbuf, &dst, 1 << uri.scheme);
len = resolve_address((const char *)buf, portbuf, &dst, &proto, 1 << uri.scheme);
LWIP_ASSERT("Failed to resolve address", len > 0);
main_coap_context = coap_new_context(NULL);
@@ -174,10 +171,8 @@ client_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg,
coap_context_set_block_mode(main_coap_context, COAP_BLOCK_USE_LIBCOAP);
coap_lwip_set_input_wait_handler(main_coap_context, input_wait, input_arg);
if (uri.scheme == COAP_URI_SCHEME_COAP) {
session = coap_new_client_session(main_coap_context, NULL, &dst,
COAP_PROTO_UDP);
} else {
if (proto == COAP_PROTO_DTLS || proto == COAP_PROTO_TLS ||
proto == COAP_PROTO_WSS) {
static coap_dtls_cpsk_t dtls_psk;
static char client_sni[256];
@@ -197,6 +192,9 @@ client_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg,
session = coap_new_client_session_psk2(main_coap_context, NULL, &dst,
COAP_PROTO_DTLS, &dtls_psk);
} else {
session = coap_new_client_session(main_coap_context, NULL, &dst,
proto);
}
LWIP_ASSERT("Failed to create session", session != NULL);
+16 -2
View File
@@ -33,7 +33,11 @@
#ifndef COAP_DISABLE_TCP
/* Define to 1 to build without TCP support. */
#if LWIP_TCP
#define COAP_DISABLE_TCP 0
#else /* ! LWIP_TCP */
#define COAP_DISABLE_TCP 1
#endif /* ! LWIP_TCP */
#endif
#ifndef COAP_ASYNC_SUPPORT
@@ -56,11 +60,21 @@
#define COAP_Q_BLOCK_SUPPORT 0
#endif
#ifndef PACKAGE_NAME
#define PACKAGE_NAME "libcoap"
#define PACKAGE_VERSION "4.3.4"
#define PACKAGE_STRING "libcoap 4.3.4"
#endif /* PACKAGE_NAME */
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "4.3.4"
#endif /* PACKAGE_VERSION */
#ifndef PACKAGE_STRING
#define PACKAGE_STRING "libcoap 4.3.4"
#endif /* PACKAGE_STRING */
#ifndef assert
#define assert(x) LWIP_ASSERT("CoAP assert failed", x)
#endif /* assert */
/* it's just provided by libc. i hope we don't get too many of those, as
* actually we'd need autotools again to find out what environment we're
+16 -2
View File
@@ -33,7 +33,11 @@
#ifndef COAP_DISABLE_TCP
/* Define to 1 to build without TCP support. */
#if LWIP_TCP
#define COAP_DISABLE_TCP 0
#else /* ! LWIP_TCP */
#define COAP_DISABLE_TCP 1
#endif /* ! LWIP_TCP */
#endif
#ifndef COAP_ASYNC_SUPPORT
@@ -56,11 +60,21 @@
#define COAP_Q_BLOCK_SUPPORT 0
#endif
#ifndef PACKAGE_NAME
#define PACKAGE_NAME "@PACKAGE_NAME@"
#define PACKAGE_VERSION "@PACKAGE_VERSION@"
#define PACKAGE_STRING "@PACKAGE_STRING@"
#endif /* PACKAGE_NAME */
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "@PACKAGE_VERSION@"
#endif /* PACKAGE_VERSION */
#ifndef PACKAGE_STRING
#define PACKAGE_STRING "@PACKAGE_STRING@"
#endif /* PACKAGE_STRING */
#ifndef assert
#define assert(x) LWIP_ASSERT("CoAP assert failed", x)
#endif /* assert */
/* it's just provided by libc. i hope we don't get too many of those, as
* actually we'd need autotools again to find out what environment we're
+5
View File
@@ -23,6 +23,9 @@
#define LWIP_IPV6_MLD 0
#define LWIP_ICMP6 (LWIP_IPV6==1)
/* Set to 1 if TCP support is required */
#define LWIP_TCP 0
#ifndef LWIP_RAND
#define LWIP_RAND() ((u32_t)rand())
#endif
@@ -36,6 +39,8 @@
#define UNLOCK_TCPIP_CORE()
#endif
#define MEMP_NUM_SYS_TIMEOUT 10
#define MEMP_USE_CUSTOM_POOLS 1
#define MEM_SIZE (4 * 1024)
/* Support a 1500 MTU packet */
+12
View File
@@ -43,11 +43,19 @@ typedef struct l_coap_tiny_context_t {
#endif
#ifndef MEMP_NUM_COAPENDPOINT
#if COAP_DISABLE_TCP
#ifdef COAP_WITH_LIBTINYDTLS
#define MEMP_NUM_COAPENDPOINT 2
#else /* ! COAP_WITH_LIBTINYDTLS */
#define MEMP_NUM_COAPENDPOINT 1
#endif /* ! COAP_WITH_LIBTINYDTLS */
#else /* ! COAP_DISABLE_TCP */
#ifdef COAP_WITH_LIBTINYDTLS
#define MEMP_NUM_COAPENDPOINT 4
#else /* ! COAP_WITH_LIBTINYDTLS */
#define MEMP_NUM_COAPENDPOINT 2
#endif /* ! COAP_WITH_LIBTINYDTLS */
#endif /* ! COAP_DISABLE_TCP */
#endif
/* 1 is sufficient as this is very short-lived */
@@ -92,7 +100,11 @@ typedef struct l_coap_tiny_context_t {
#endif
#ifndef MEMP_LEN_COAPSTRING
#ifdef COAP_WITH_LIBTINYDTLS
#define MEMP_LEN_COAPSTRING 120
#else /* COAP_WITH_TINYDTLS */
#define MEMP_LEN_COAPSTRING 40
#endif /* COAP_WITH_TINYDTLS */
#endif
#ifndef MEMP_NUM_COAPCACHE_KEYS
+6 -1
View File
@@ -33,7 +33,12 @@ struct uip_udp_conn;
struct coap_socket_t {
#if defined(WITH_LWIP)
struct udp_pcb *pcb;
struct pbuf *p;
struct udp_pcb *udp_pcb;
#if ! COAP_DISABLE_TCP
struct tcp_pcb *tcp_pcb;
#endif /* ! COAP_DISABLE_TCP */
#elif defined(WITH_CONTIKI)
struct uip_udp_conn *udp_conn;
coap_context_t *context;
+13
View File
@@ -143,13 +143,26 @@ coap_free(void *object) {
COAP_STATIC_INLINE void
coap_memory_init(void) {}
#if MEMP_STATS
COAP_STATIC_INLINE void *
coap_malloc_error(uint16_t *err) {
(*err)++;
return NULL;
}
#endif /* MEMP_STATS */
/* It would be nice to check that size equals the size given at the memp
* declaration, but i currently don't see a standard way to check that without
* sourcing the custom memp pools and becoming dependent of its syntax
*/
#if MEMP_STATS
#define coap_malloc_type(type, asize) \
(((asize) <= memp_pools[MEMP_ ## type]->size) ? \
memp_malloc(MEMP_ ## type) : coap_malloc_error(&memp_pools[MEMP_ ## type]->stats->err))
#else /* ! MEMP_STATS */
#define coap_malloc_type(type, asize) \
(((asize) <= memp_pools[MEMP_ ## type]->size) ? \
memp_malloc(MEMP_ ## type) : NULL)
#endif /* ! MEMP_STATS */
#define coap_free_type(type, p) memp_free(MEMP_ ## type, p)
/* As these are fixed size, return value if already defined */
+3 -1
View File
@@ -128,10 +128,12 @@ int coap_netif_strm_listen(coap_endpoint_t *endpoint,
*
* @param endpoint Endpoint to to do the accept on.
* @param session Session to to do the accept update on.
* @param extra Available for use by any underlying network stack.
*
* @return @c 1 OK, 0 on failure.
*/
int coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session);
int coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session,
void *extra);
/**
* Layer function interface for Netif stream connect (tcp).
+8 -4
View File
@@ -309,14 +309,14 @@ int coap_session_refresh_psk_identity(coap_session_t *session,
* Creates a new server session for the specified endpoint.
* @param ctx The CoAP context.
* @param ep An endpoint where an incoming connection request is pending.
* @param extra Available for use by any underlying network stack.
*
* @return A new CoAP session or NULL if failed. Call coap_session_release to
* add to unused queue.
*/
coap_session_t *coap_new_server_session(
coap_context_t *ctx,
coap_endpoint_t *ep
);
coap_session_t *coap_new_server_session(coap_context_t *ctx,
coap_endpoint_t *ep,
void *extra);
#endif /* COAP_SERVER_SUPPORT */
/**
@@ -384,6 +384,10 @@ coap_session_t *coap_session_new_dtls_session(coap_session_t *session,
void coap_session_free(coap_session_t *session);
void coap_session_mfree(coap_session_t *session);
void coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now);
void coap_connect_session(coap_session_t *session, coap_tick_t now);
#define COAP_SESSION_REF(s) ((s)->ref
/* RFC7252 */
+3 -1
View File
@@ -93,13 +93,15 @@ int coap_socket_bind_tcp(coap_socket_t *sock,
* session information
* @param local_addr Filled in with the local address
* @param remote_addr Filled in with the remote address
* @param extra Available for use by any underlying network stack.
*
* @return @c 1 if succesful, @c 0 if failure of some sort
*/
int coap_socket_accept_tcp(coap_socket_t *server,
coap_socket_t *new_client,
coap_address_t *local_addr,
coap_address_t *remote_addr);
coap_address_t *remote_addr,
void *extra);
#endif /* !COAP_DISABLE_TCP */
+268 -46
View File
@@ -202,7 +202,7 @@ coap_free_packet(coap_packet_t *packet) {
coap_free_type(COAP_PACKET, packet);
}
/** Callback from lwIP when a package was received for a server.
/** Callback from lwIP when a UDP packet was received for a server.
*
* The current implementation deals this to coap_dispatch immediately, but
* other mechanisms (as storing the package in a queue and later fetching it
@@ -211,8 +211,8 @@ coap_free_packet(coap_packet_t *packet) {
* It handles everything coap_io_do_io does on other implementations.
*/
static void
coap_recvs(void *arg, struct udp_pcb *upcb, struct pbuf *p,
const ip_addr_t *addr, u16_t port) {
coap_udp_recvs(void *arg, struct udp_pcb *upcb, struct pbuf *p,
const ip_addr_t *addr, u16_t port) {
coap_endpoint_t *ep = (coap_endpoint_t *)arg;
coap_pdu_t *pdu = NULL;
coap_session_t *session = NULL;
@@ -304,7 +304,7 @@ coap_socket_send_pdu(coap_socket_t *sock, coap_session_t *session,
pbuf = pbuf_clone(PBUF_TRANSPORT, PBUF_RAM, pdu->pbuf);
if (pbuf == NULL)
return -1;
err = udp_sendto(sock->pcb, pbuf, &session->addr_info.remote.addr,
err = udp_sendto(sock->udp_pcb, pbuf, &session->addr_info.remote.addr,
session->addr_info.remote.port);
pbuf_free(pbuf);
if (err < 0)
@@ -332,7 +332,7 @@ coap_socket_send(coap_socket_t *sock, const coap_session_t *session,
LOCK_TCPIP_CORE();
err = udp_sendto(sock->pcb, pbuf, &session->addr_info.remote.addr,
err = udp_sendto(sock->udp_pcb, pbuf, &session->addr_info.remote.addr,
session->addr_info.remote.port);
UNLOCK_TCPIP_CORE();
@@ -352,19 +352,19 @@ coap_socket_bind_udp(coap_socket_t *sock,
int err;
coap_address_t l_listen = *listen_addr;
sock->pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
if (sock->pcb == NULL)
sock->udp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
if (sock->udp_pcb == NULL)
return 0;
#if LWIP_IPV6 && LWIP_IPV4
if (l_listen.addr.type == IPADDR_TYPE_V6)
l_listen.addr.type = IPADDR_TYPE_ANY;
#endif /* LWIP_IPV6 && LWIP_IPV4 */
udp_recv(sock->pcb, coap_recvs, (void *)sock->endpoint);
err = udp_bind(sock->pcb, &l_listen.addr, l_listen.port);
udp_recv(sock->udp_pcb, coap_udp_recvs, (void *)sock->endpoint);
err = udp_bind(sock->udp_pcb, &l_listen.addr, l_listen.port);
if (err) {
udp_remove(sock->pcb);
sock->pcb = NULL;
udp_remove(sock->udp_pcb);
sock->udp_pcb = NULL;
}
*bound_addr = l_listen;
return err ? 0 : 1;
@@ -413,9 +413,9 @@ coap_socket_connect_udp(coap_socket_t *sock,
pcb->local_ip.type = pcb->remote_ip.type;
#endif /* LWIP_IPV6 && LWIP_IPV4 */
sock->pcb = pcb;
sock->udp_pcb = pcb;
udp_recv(sock->pcb, coap_recvc, (void *)sock->session);
udp_recv(sock->udp_pcb, coap_recvc, (void *)sock->session);
UNLOCK_TCPIP_CORE();
@@ -431,6 +431,77 @@ err_unlock:
#endif /* ! COAP_CLIENT_SUPPORT */
#if ! COAP_DISABLE_TCP
#include <lwip/tcp.h>
static void
do_tcp_err(void *arg, err_t err) {
coap_session_t *session = (coap_session_t *)arg;
(void)err;
coap_handle_event(session->context, COAP_EVENT_TCP_FAILED, session);
/*
* as per tcp_err() documentation, the corresponding pcb is already freed
* when this callback is called. So, stop a double free when
* coap_session_disconnected() eventually coap_socket_close() is called.
*/
session->sock.tcp_pcb = NULL;
coap_session_disconnected(session, COAP_NACK_NOT_DELIVERABLE);
}
/** Callback from lwIP when a TCP packet is received.
*
* The current implementation invokes coap_read_session() to do the bulk of the
* work.
*/
static err_t
coap_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
coap_session_t *session = (coap_session_t *)arg;
coap_socket_t *sock = &session->sock;
coap_tick_t now;
(void)tpcb;
if (p == NULL) {
/* remote host closed connection */
tcp_arg(sock->tcp_pcb, NULL);
tcp_recv(sock->tcp_pcb, NULL);
tcp_close(sock->tcp_pcb);
sock->tcp_pcb = NULL;
coap_session_disconnected(session, COAP_NACK_NOT_DELIVERABLE);
return ERR_OK;
} else if (err != ERR_OK) {
/* cleanup, for unknown reason */
if (p != NULL) {
pbuf_free(p);
}
return err;
}
sock->p = p;
coap_ticks(&now);
coap_read_session(session->context, session, now);
return ERR_OK;
}
#if COAP_CLIENT_SUPPORT
static err_t
do_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t err) {
coap_session_t *session = (coap_session_t *)arg;
coap_tick_t now;
if (err)
return err;
session->sock.flags |= COAP_SOCKET_CONNECTED;
session->addr_info.local.addr = tpcb->local_ip;
session->addr_info.local.port = tpcb->local_port;
tcp_recv(tpcb, coap_tcp_recv);
coap_ticks(&now);
coap_connect_session(session, now);
return ERR_OK;
}
int
coap_socket_connect_tcp1(coap_socket_t *sock,
const coap_address_t *local_if,
@@ -438,13 +509,45 @@ coap_socket_connect_tcp1(coap_socket_t *sock,
int default_port,
coap_address_t *local_addr,
coap_address_t *remote_addr) {
(void)sock;
(void)local_if;
(void)server;
(void)default_port;
coap_address_t connect_addr;
err_t err;
(void)local_addr;
(void)remote_addr;
return 0;
sock->flags &= ~(COAP_SOCKET_WANT_CONNECT | COAP_SOCKET_CONNECTED);
sock->tcp_pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
if (sock->tcp_pcb == NULL)
return 0;
tcp_arg(sock->tcp_pcb, sock->session);
tcp_recv(sock->tcp_pcb, coap_tcp_recv);
tcp_err(sock->tcp_pcb, do_tcp_err);
if (local_if) {
coap_address_t l_local_if = *local_if;
#if LWIP_IPV6 && LWIP_IPV4
if (l_local_if.addr.type == IPADDR_TYPE_V6)
l_local_if.addr.type = IPADDR_TYPE_ANY;
#endif /* LWIP_IPV6 && LWIP_IPV4 */
err = tcp_bind(sock->tcp_pcb, &l_local_if.addr, l_local_if.port);
if (err != ERR_OK) {
tcp_arg(sock->tcp_pcb, NULL);
tcp_recv(sock->tcp_pcb, NULL);
tcp_close(sock->tcp_pcb);
sock->tcp_pcb = NULL;
return 0;
}
}
coap_address_copy(&connect_addr, server);
if (connect_addr.port == 0)
connect_addr.port = htons(default_port);
err = tcp_connect(sock->tcp_pcb, &connect_addr.addr, connect_addr.port,
do_tcp_connected);
if (err == ERR_OK)
sock->flags |= COAP_SOCKET_WANT_CONNECT | COAP_SOCKET_CONNECTED;
return err ? 0 : 1;
}
int
@@ -454,55 +557,174 @@ coap_socket_connect_tcp2(coap_socket_t *sock,
(void)sock;
(void)local_addr;
(void)remote_addr;
return 0;
sock->flags &= ~(COAP_SOCKET_WANT_CONNECT | COAP_SOCKET_CAN_CONNECT);
return 1;
}
#endif /* COAP_CLIENT_SUPPORT */
#if COAP_SERVER_SUPPORT
static err_t
do_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
coap_endpoint_t *endpoint = arg;
coap_session_t *session;
coap_tick_t now;
err_t ret_err = ERR_OK;
if ((err != ERR_OK) || (newpcb == NULL)) {
return ERR_VAL;
}
coap_ticks(&now);
session = coap_new_server_session(endpoint->context, endpoint, newpcb);
if (session) {
session->sock.tcp_pcb = newpcb;
session->last_rx_tx = now;
tcp_arg(newpcb, session);
tcp_setprio(newpcb, TCP_PRIO_MIN);
tcp_recv(newpcb, coap_tcp_recv);
tcp_err(newpcb, do_tcp_err);
} else {
ret_err = ERR_MEM;
}
return ret_err;
}
int
coap_socket_bind_tcp(coap_socket_t *sock,
const coap_address_t *listen_addr,
coap_address_t *bound_addr) {
(void)sock;
(void)listen_addr;
(void)bound_addr;
return 0;
int err;
coap_address_t l_listen = *listen_addr;
struct tcp_pcb *tcp_pcb;
sock->tcp_pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
if (sock->tcp_pcb == NULL)
return 0;
#if LWIP_IPV6 && LWIP_IPV4
if (l_listen.addr.type == IPADDR_TYPE_V6)
l_listen.addr.type = IPADDR_TYPE_ANY;
#endif /* LWIP_IPV6 && LWIP_IPV4 */
tcp_arg(sock->tcp_pcb, sock->endpoint);
err = tcp_bind(sock->tcp_pcb, &l_listen.addr, l_listen.port);
if (err != ERR_OK) {
tcp_arg(sock->tcp_pcb, NULL);
tcp_recv(sock->tcp_pcb, NULL);
tcp_close(sock->tcp_pcb);
sock->tcp_pcb = NULL;
return 0;
} else {
tcp_pcb = tcp_listen(sock->tcp_pcb);
if (tcp_pcb) {
sock->tcp_pcb = tcp_pcb;
tcp_accept(sock->tcp_pcb, do_tcp_accept);
} else {
tcp_arg(sock->tcp_pcb, NULL);
tcp_recv(sock->tcp_pcb, NULL);
tcp_close(sock->tcp_pcb);
sock->tcp_pcb = NULL;
return 0;
}
}
*bound_addr = l_listen;
return err ? 0 : 1;
}
int
coap_socket_accept_tcp(coap_socket_t *server,
coap_socket_t *new_client,
coap_address_t *local_addr,
coap_address_t *remote_addr) {
coap_address_t *remote_addr,
void *extra) {
struct tcp_pcb *tcp_pcb = (struct tcp_pcb *)extra;
(void)server;
(void)new_client;
(void)local_addr;
(void)remote_addr;
new_client->tcp_pcb = tcp_pcb;
local_addr->addr = tcp_pcb->local_ip;
local_addr->port = tcp_pcb->local_port;
remote_addr->addr = tcp_pcb->remote_ip;
remote_addr->port = tcp_pcb->remote_port;
return 1;
}
#endif /* COAP_SERVER_SUPPORT */
/*
* strm
* return +ve Number of bytes written.
* -1 Error error in errno).
*/
ssize_t
coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len) {
struct pbuf *pbuf;
int err;
pbuf = pbuf_alloc(PBUF_TRANSPORT, data_len, PBUF_RAM);
if (pbuf == NULL)
return -1;
memcpy(pbuf->payload, data, data_len);
LOCK_TCPIP_CORE();
err = tcp_write(sock->tcp_pcb, pbuf->payload, pbuf->len, 1);
UNLOCK_TCPIP_CORE();
pbuf_free(pbuf);
if (err < 0)
return -1;
return data_len;
}
/*
* strm
* return >=0 Number of bytes read.
* -1 Error error in errno).
*/
ssize_t
coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len) {
if (sock->p) {
if (data_len < sock->p->len) {
uint8_t *ptr = (uint8_t *)sock->p->payload;
/* Handle partial read of data request */
memcpy(data, sock->p->payload, data_len);
sock->p->payload = &ptr[data_len];
sock->p->len -= data_len;
return data_len;
} else {
data_len = sock->p->len;
memcpy(data, sock->p->payload, sock->p->len);
pbuf_free(sock->p);
sock->p = NULL;
return data_len;
}
}
return 0;
}
#endif /* !COAP_DISABLE_TCP */
ssize_t
coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len) {
(void)sock;
(void)data;
(void)data_len;
return -1;
}
ssize_t
coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len) {
(void)sock;
(void)data;
(void)data_len;
return -1;
}
void
coap_socket_close(coap_socket_t *sock) {
if (sock->pcb) {
if (sock->udp_pcb) {
LOCK_TCPIP_CORE();
udp_remove(sock->pcb);
udp_remove(sock->udp_pcb);
UNLOCK_TCPIP_CORE();
sock->udp_pcb = NULL;
}
sock->pcb = NULL;
#if ! COAP_DISABLE_TCP
if (sock->tcp_pcb) {
tcp_arg(sock->tcp_pcb, NULL);
#if COAP_SERVER_SUPPORT
if (!sock->endpoint)
#endif /* COAP_SERVER_SUPPORT */
tcp_recv(sock->tcp_pcb, NULL);
tcp_close(sock->tcp_pcb);
sock->tcp_pcb = NULL;
}
#endif /* !COAP_DISABLE_TCP */
return;
}
+6 -6
View File
@@ -1761,7 +1761,7 @@ coap_handle_dgram_for_proto(coap_context_t *ctx, coap_session_t *session, coap_p
}
#if COAP_CLIENT_SUPPORT
static void
void
coap_connect_session(coap_session_t *session, coap_tick_t now) {
#if COAP_DISABLE_TCP
(void)now;
@@ -1808,7 +1808,7 @@ coap_write_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now
}
}
static void
void
coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now) {
#if COAP_CONSTRAINED_STACK
/* payload and packet protected by mutex m_read_session */
@@ -2061,8 +2061,8 @@ coap_write_endpoint(coap_context_t *ctx, coap_endpoint_t *endpoint, coap_tick_t
#if !COAP_DISABLE_TCP
static int
coap_accept_endpoint(coap_context_t *ctx, coap_endpoint_t *endpoint,
coap_tick_t now) {
coap_session_t *session = coap_new_server_session(ctx, endpoint);
coap_tick_t now, void *extra) {
coap_session_t *session = coap_new_server_session(ctx, endpoint, extra);
if (session)
session->last_rx_tx = now;
return session != NULL;
@@ -2088,7 +2088,7 @@ coap_io_do_io(coap_context_t *ctx, coap_tick_t now) {
coap_write_endpoint(ctx, ep, now);
#if !COAP_DISABLE_TCP
if ((ep->sock.flags & COAP_SOCKET_CAN_ACCEPT) != 0)
coap_accept_endpoint(ctx, ep, now);
coap_accept_endpoint(ctx, ep, now, NULL);
#endif /* !COAP_DISABLE_TCP */
SESSIONS_ITER_SAFE(ep->sessions, s, rtmp) {
/* Make sure the session object is not deleted in one of the callbacks */
@@ -2168,7 +2168,7 @@ coap_io_do_epoll(coap_context_t *ctx, struct epoll_event *events, size_t nevents
if ((sock->flags & COAP_SOCKET_WANT_ACCEPT) &&
(events[j].events & EPOLLIN)) {
sock->flags |= COAP_SOCKET_CAN_ACCEPT;
coap_accept_endpoint(endpoint->context, endpoint, now);
coap_accept_endpoint(endpoint->context, endpoint, now, NULL);
}
#endif /* !COAP_DISABLE_TCP */
+2 -2
View File
@@ -167,10 +167,10 @@ coap_netif_strm_listen(coap_endpoint_t *endpoint,
}
int
coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session) {
coap_netif_strm_accept(coap_endpoint_t *endpoint, coap_session_t *session, void *extra) {
if (!coap_socket_accept_tcp(&endpoint->sock, &session->sock,
&session->addr_info.local,
&session->addr_info.remote)) {
&session->addr_info.remote, extra)) {
return 0;
}
session->sock.flags |= COAP_SOCKET_NOT_EMPTY | COAP_SOCKET_CONNECTED |
+4 -3
View File
@@ -492,7 +492,8 @@ coap_session_mfree(coap_session_t *session) {
if (session->partial_pdu)
coap_delete_pdu(session->partial_pdu);
session->sock.lfunc[COAP_LAYER_SESSION].l_close(session);
if (session->sock.lfunc[COAP_LAYER_SESSION].l_close)
session->sock.lfunc[COAP_LAYER_SESSION].l_close(session);
if (session->psk_identity)
coap_delete_bin_const(session->psk_identity);
if (session->psk_key)
@@ -1529,7 +1530,7 @@ coap_new_client_session_pki(coap_context_t *ctx,
#if COAP_SERVER_SUPPORT
#if !COAP_DISABLE_TCP
coap_session_t *
coap_new_server_session(coap_context_t *ctx, coap_endpoint_t *ep) {
coap_new_server_session(coap_context_t *ctx, coap_endpoint_t *ep, void *extra) {
coap_session_t *session;
session = coap_make_session(ep->proto, COAP_SESSION_TYPE_SERVER,
NULL, NULL, NULL, 0, ctx, ep);
@@ -1537,7 +1538,7 @@ coap_new_server_session(coap_context_t *ctx, coap_endpoint_t *ep) {
goto error;
memcpy(session->sock.lfunc, ep->sock.lfunc, sizeof(session->sock.lfunc));
if (!coap_netif_strm_accept(ep, session))
if (!coap_netif_strm_accept(ep, session, extra))
goto error;
coap_make_addr_hash(&session->addr_hash, session->proto, &session->addr_info);
+6 -4
View File
@@ -38,7 +38,7 @@ coap_tcp_is_supported(void) {
return !COAP_DISABLE_TCP;
}
#if !COAP_DISABLE_TCP
#if !COAP_DISABLE_TCP && !defined(WITH_LWIP)
int
coap_socket_connect_tcp1(coap_socket_t *sock,
const coap_address_t *local_if,
@@ -176,12 +176,12 @@ coap_socket_connect_tcp2(coap_socket_t *sock,
if (getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, OPTVAL_GT(&error),
&optlen) == COAP_SOCKET_ERROR) {
coap_log_warn("coap_socket_finish_connect_tcp: getsockopt: %s\n",
coap_log_warn("coap_socket_connect_tcp2: getsockopt: %s\n",
coap_socket_strerror());
}
if (error) {
coap_log_warn("coap_socket_finish_connect_tcp: connect failed: %s\n",
coap_log_warn("coap_socket_connect_tcp2: connect failed: %s\n",
coap_socket_format_errno(error));
coap_socket_close(sock);
return 0;
@@ -299,7 +299,8 @@ int
coap_socket_accept_tcp(coap_socket_t *server,
coap_socket_t *new_client,
coap_address_t *local_addr,
coap_address_t *remote_addr) {
coap_address_t *remote_addr,
void *extra) {
#ifndef RIOT_VERSION
#ifdef _WIN32
u_long u_on = 1;
@@ -307,6 +308,7 @@ coap_socket_accept_tcp(coap_socket_t *server,
int on = 1;
#endif
#endif /* RIOT_VERSION */
(void)extra;
server->flags &= ~COAP_SOCKET_CAN_ACCEPT;