From bd328237461bb50142abc6fe50d3255d3cce09d9 Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Thu, 11 Jul 2024 11:09:56 +0100 Subject: [PATCH] client-coap.c: Fix client spin loop for NO_SYS == 0 Do not call coap_free_context() from within sigint handler. Always call coap_io_process(). Use sys_arch_sem_wait() for timeouts while waiting for input. --- examples/lwip/client-coap.c | 2 -- examples/lwip/client.c | 4 +-- examples/lwip/config/lwipopts.h | 7 +++++ include/coap3/coap_io_internal.h | 2 ++ src/coap_io_lwip.c | 49 ++++++++++++++++++++++++++++++-- src/coap_net.c | 6 ++++ 6 files changed, 62 insertions(+), 8 deletions(-) diff --git a/examples/lwip/client-coap.c b/examples/lwip/client-coap.c index 55bbd484..7fa7a61d 100644 --- a/examples/lwip/client-coap.c +++ b/examples/lwip/client-coap.c @@ -239,8 +239,6 @@ client_coap_finished(void) { int client_coap_poll(void) { -#if NO_SYS coap_io_process(main_coap_context, 1000); -#endif /* NO_SYS */ return quit; } diff --git a/examples/lwip/client.c b/examples/lwip/client.c index f6787faf..57e3969c 100644 --- a/examples/lwip/client.c +++ b/examples/lwip/client.c @@ -53,9 +53,7 @@ static void handle_sigint(int signum) { (void)signum; - client_coap_finished(); - printf("Client Application finished.\n"); - exit(0); + quit = 1; } /* diff --git a/examples/lwip/config/lwipopts.h b/examples/lwip/config/lwipopts.h index ffe40780..78bdea24 100644 --- a/examples/lwip/config/lwipopts.h +++ b/examples/lwip/config/lwipopts.h @@ -10,6 +10,13 @@ * of use. */ +/* + * NO_SYS = 0 + * Use lwIP OS-awareness (multi threaded, semaphores, mutexes and mboxes). + * + * NO_SYS = 1 + * Use lwIP without OS-awareness (no thread, semaphores, mutexes or mboxes). + */ #define NO_SYS 0 #define LWIP_SOCKET (NO_SYS==0) #define LWIP_NETCONN (NO_SYS==0) diff --git a/include/coap3/coap_io_internal.h b/include/coap3/coap_io_internal.h index f915da2b..5eabc17f 100644 --- a/include/coap3/coap_io_internal.h +++ b/include/coap3/coap_io_internal.h @@ -218,6 +218,8 @@ void coap_packet_get_memmapped(coap_packet_t *packet, #ifdef WITH_LWIP void coap_io_process_timeout(void *arg); +void coap_io_lwip_init(void); +void coap_io_lwip_cleanup(void); #endif struct coap_packet_t { diff --git a/src/coap_io_lwip.c b/src/coap_io_lwip.c index 4d93377b..0e5ca342 100644 --- a/src/coap_io_lwip.c +++ b/src/coap_io_lwip.c @@ -51,9 +51,31 @@ coap_lwip_set_input_wait_handler(coap_context_t *context, context->input_arg = input_arg; } +#if NO_SYS == 0 +sys_sem_t coap_io_timeout_sem; +#endif /* NO_SYS == 0 */ + +void +coap_io_lwip_init(void) { +#if NO_SYS == 0 + if (sys_sem_new(&coap_io_timeout_sem, 0) != ERR_OK) + coap_log_warn("coap_io_lwip_init: Failed to set up semaphore\n"); +#endif /* NO_SYS == 0 */ +} + +void +coap_io_lwip_cleanup(void) { +#if NO_SYS == 0 + sys_sem_free(&coap_io_timeout_sem); +#endif /* NO_SYS == 0 */ +} + void coap_io_process_timeout(void *arg) { (void)arg; +#if NO_SYS == 0 + sys_sem_signal(&coap_io_timeout_sem); +#endif /* NO_SYS == 0 */ } int @@ -102,7 +124,15 @@ coap_io_process_lkd(coap_context_t *context, uint32_t timeout_ms) { UNLOCK_TCPIP_CORE(); if (context->input_wait) { - context->input_wait(context->input_arg, timeout); + coap_lock_callback_release(context, + context->input_wait(context->input_arg, timeout), + return 0); +#if NO_SYS == 0 + } else { + coap_lock_callback_release(context, + sys_arch_sem_wait(&coap_io_timeout_sem, timeout), + return 0); +#endif /* NO_SYS == 0 */ } coap_lock_invert(context, @@ -176,6 +206,9 @@ coap_recvc(void *arg, struct udp_pcb *upcb, struct pbuf *p, coap_dispatch(session->context, session, pdu); coap_lock_unlock(session->context); } +#if NO_SYS == 0 + sys_sem_signal(&coap_io_timeout_sem); +#endif /* NO_SYS == 0 */ coap_delete_pdu(pdu); return; @@ -269,6 +302,9 @@ coap_udp_recvs(void *arg, struct udp_pcb *upcb, struct pbuf *p, coap_delete_pdu(pdu); coap_free_packet(packet); coap_lock_unlock(ep->context); +#if NO_SYS == 0 + sys_sem_signal(&coap_io_timeout_sem); +#endif /* NO_SYS == 0 */ return; error_free_pbuf: @@ -342,8 +378,16 @@ coap_socket_send(coap_socket_t *sock, const coap_session_t *session, UNLOCK_TCPIP_CORE(); pbuf_free(pbuf); - if (err < 0) + if (err < 0) { + if (err == ERR_RTE) { + coap_log_warn("** %s: udp_send: Packet not routable\n", + coap_session_str(session)); + } else { + coap_log_warn("** %s: udp_send: error %d\n", + coap_session_str(session), err); + } return -1; + } } return data_len; } @@ -745,7 +789,6 @@ coap_socket_close(coap_socket_t *sock) { } tcp_close(sock->tcp_pcb); UNLOCK_TCPIP_CORE(); - tcp_close(sock->tcp_pcb); sock->tcp_pcb = NULL; } #endif /* !COAP_DISABLE_TCP */ diff --git a/src/coap_net.c b/src/coap_net.c index ba65f3bf..902a4991 100644 --- a/src/coap_net.c +++ b/src/coap_net.c @@ -4447,6 +4447,9 @@ coap_startup(void) { #endif /* WITH_CONTIKI */ coap_memory_init(); coap_dtls_startup(); +#ifdef WITH_LWIP + coap_io_lwip_init(); +#endif /* WITH_LWIP */ #if COAP_SERVER_SUPPORT static coap_str_const_t well_known = { sizeof(".well-known/core")-1, (const uint8_t *)".well-known/core" @@ -4468,6 +4471,9 @@ coap_cleanup(void) { #elif defined(WITH_CONTIKI) coap_stop_io_process(); #endif +#ifdef WITH_LWIP + coap_io_lwip_cleanup(); +#endif /* WITH_LWIP */ coap_dtls_shutdown(); #if COAP_CONSTRAINED_STACK