From 19ff9494042fb87bff9ef889e8e13c27136f93f9 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Mon, 13 Mar 2023 11:49:37 +0100 Subject: [PATCH 1/2] cord: include gcoap_req_send returning 0 in error gcoap_req_send returns 0 if it was unable to send the CoAP request. CoRD did not include that case in the return code checks. This changes CoRD to include it and drop the registration if CoAP could not send the request. The old behaviour made the CoRD thread lock up. --- sys/net/application_layer/cord/ep/cord_ep.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/net/application_layer/cord/ep/cord_ep.c b/sys/net/application_layer/cord/ep/cord_ep.c index 36b618c714..4bc13538fa 100644 --- a/sys/net/application_layer/cord/ep/cord_ep.c +++ b/sys/net/application_layer/cord/ep/cord_ep.c @@ -151,8 +151,10 @@ static int _update_remove(unsigned code, gcoap_resp_handler_t handle) ssize_t pkt_len = coap_opt_finish(&pkt, COAP_OPT_FINISH_NONE); /* send request */ - gcoap_req_send(buf, pkt_len, &_rd_remote, handle, NULL); - + ssize_t send_len = gcoap_req_send(buf, pkt_len, &_rd_remote, handle, NULL); + if (send_len <= 0) { + return CORD_EP_ERR; + } /* synchronize response */ return _sync(); } @@ -224,7 +226,7 @@ static int _discover_internal(const sock_udp_ep_t *remote, coap_opt_add_uri_query(&pkt, "rt", "core.rd"); size_t pkt_len = coap_opt_finish(&pkt, COAP_OPT_FINISH_NONE); res = gcoap_req_send(buf, pkt_len, remote, _on_discover, NULL); - if (res < 0) { + if (res <= 0) { return CORD_EP_ERR; } return _sync(); @@ -295,7 +297,7 @@ int cord_ep_register(const sock_udp_ep_t *remote, const char *regif) /* send out the request */ res = gcoap_req_send(buf, pkt_len, remote, _on_register, NULL); - if (res < 0) { + if (res <= 0) { retval = CORD_EP_ERR; goto end; } From dea25437c736f92a3ff346bd38b71413fcd865ee Mon Sep 17 00:00:00 2001 From: Joshua DeWeese Date: Mon, 13 Mar 2023 13:39:16 -0400 Subject: [PATCH 2/2] cpu/stm32/periph/timer: fix clobered IRQ flag The STM32 periph_timer driver reads the timer's status flags, then clears them all. It is possible that a timer interrupt could occur between reading the flag and clearing it. This would lead to a lost interrupt. The timer's status flags can be cleared by software, but can only be set by the hardware. This patch takes advantage of this by only clearing the flags it knows are set. The rest of the flags are set, which doesn't actually change their state. --- cpu/stm32/periph/timer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cpu/stm32/periph/timer.c b/cpu/stm32/periph/timer.c index 6f5004177a..92660fa755 100644 --- a/cpu/stm32/periph/timer.c +++ b/cpu/stm32/periph/timer.c @@ -267,7 +267,12 @@ static inline void irq_handler(tim_t tim) { uint32_t top = dev(tim)->ARR; uint32_t status = dev(tim)->SR & dev(tim)->DIER; - dev(tim)->SR = 0; + + /* clear interrupts which we are about to service */ + /* Note, the flags in the SR register can be cleared by software, but + * setting them has no effect on the register. Only the hardware can set + * them. */ + dev(tim)->SR = ~status; for (unsigned int i = 0; status; i++) { uint32_t msk = TIM_SR_CC1IF << i;