You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ja...@apache.org on 2026/10/26 12:00:51 UTC

(mynewt-core) 03/05: mgmt/smp_uart: Queue received lines

This is an automated email from the ASF dual-hosted git repository.

sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit f86369b509beafce6aeb00f6470ea67a6cbddfba
Author: Szymon Janc <sz...@codecoup.pl>
AuthorDate: Sun Oct 25 22:30:31 2026 +0100

    mgmt/smp_uart: Queue received lines
    
    Received line was handed over to the mgmt task in a single slot and
    assert checked that previous line was already processed. Frames of a
    packet longer than one line are sent back to back, so it was enough
    for the mgmt task to be busy for a moment, e.g. when processing a
    previous request, to hit the assert. Two newline characters sent
    quickly were enough to trigger it on purpose.
    
    Queue received lines and process all of them in mgmt task. Also
    initialize the queue and the event callback before opening UART as
    data may be received as soon as UART is opened.
    
    Assisted-by: Claude:claude-opus-5-5
---
 mgmt/smp/transport/smp_uart/src/smp_uart.c | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/mgmt/smp/transport/smp_uart/src/smp_uart.c b/mgmt/smp/transport/smp_uart/src/smp_uart.c
index a1cf1f281..9169f69ce 100644
--- a/mgmt/smp/transport/smp_uart/src/smp_uart.c
+++ b/mgmt/smp/transport/smp_uart/src/smp_uart.c
@@ -53,7 +53,7 @@ struct smp_uart_state {
     struct os_mbuf *sus_tx;
     int sus_tx_off;
     struct os_mbuf_pkthdr *sus_rx_pkt;
-    struct os_mbuf_pkthdr *sus_rx_q;
+    STAILQ_HEAD(, os_mbuf_pkthdr) sus_rx_q;
     struct os_mbuf_pkthdr *sus_rx;
 };
 
@@ -307,11 +307,16 @@ smp_uart_rx_frame(struct os_event *ev)
     struct os_mbuf_pkthdr *m;
     int sr;
 
-    OS_ENTER_CRITICAL(sr);
-    m = sus->sus_rx_q;
-    sus->sus_rx_q = NULL;
-    OS_EXIT_CRITICAL(sr);
-    if (m) {
+    while (1) {
+        OS_ENTER_CRITICAL(sr);
+        m = STAILQ_FIRST(&sus->sus_rx_q);
+        if (m) {
+            STAILQ_REMOVE_HEAD(&sus->sus_rx_q, omp_next);
+        }
+        OS_EXIT_CRITICAL(sr);
+        if (!m) {
+            break;
+        }
         smp_uart_rx_pkt(sus, m);
     }
 }
@@ -345,10 +350,10 @@ smp_uart_rx_char(void *arg, uint8_t data)
     m = OS_MBUF_PKTHDR_TO_MBUF(sus->sus_rx);
     if (data == '\n') {
         /*
-         * Full line of input. Process it outside interrupt context.
+         * Full line of input. Process it outside interrupt context. More
+         * lines may be received before previous ones are processed.
          */
-        assert(!sus->sus_rx_q);
-        sus->sus_rx_q = sus->sus_rx;
+        STAILQ_INSERT_TAIL(&sus->sus_rx_q, sus->sus_rx, omp_next);
         sus->sus_rx = NULL;
         os_eventq_put(mgmt_evq_get(), &sus->sus_cb_ev);
         return 0;
@@ -388,11 +393,12 @@ smp_uart_pkg_init(void)
     rc = smp_transport_init(&sus->sus_transport, smp_uart_out, smp_uart_mtu);
     assert(rc == 0);
 
+    STAILQ_INIT(&sus->sus_rx_q);
+    sus->sus_cb_ev.ev_cb = smp_uart_rx_frame;
+
     sus->sus_dev =
       (struct uart_dev *)os_dev_open(MYNEWT_VAL(SMP_UART), 0, &uc);
     assert(sus->sus_dev);
-
-    sus->sus_cb_ev.ev_cb = smp_uart_rx_frame;
 }
 
 /**