99#include <zephyr/modem/pipe.h>
1010#include <modem/nrf_modem_lib_trace.h>
1111#include <modem/trace_backend.h>
12- #include "sm_cmux .h"
12+ #include "sm_util .h"
1313
1414LOG_MODULE_REGISTER (modem_trace_backend , CONFIG_MODEM_TRACE_BACKEND_LOG_LEVEL );
1515
1616static K_SEM_DEFINE (tx_idle_sem , 0 , 1 ) ;
1717
1818static trace_backend_processed_cb trace_processed_callback ;
19+ static struct modem_pipe * trace_pipe ;
1920
2021static void modem_pipe_event_handler (struct modem_pipe * pipe ,
2122 enum modem_pipe_event event , void * user_data )
@@ -25,7 +26,14 @@ static void modem_pipe_event_handler(struct modem_pipe *pipe,
2526 case MODEM_PIPE_EVENT_TRANSMIT_IDLE :
2627 k_sem_give (& tx_idle_sem );
2728 break ;
28-
29+ case MODEM_PIPE_EVENT_CLOSED :
30+ LOG_INF ("Trace pipe closed" );
31+ trace_pipe = NULL ;
32+ break ;
33+ case MODEM_PIPE_EVENT_OPENED :
34+ LOG_INF ("Trace pipe opened" );
35+ trace_pipe = pipe ;
36+ break ;
2937 default :
3038 break ;
3139 }
@@ -38,58 +46,73 @@ int trace_backend_init(trace_backend_processed_cb trace_processed_cb)
3846 }
3947
4048 trace_processed_callback = trace_processed_cb ;
49+ trace_pipe = NULL ;
4150
4251 return 0 ;
4352}
4453
4554int trace_backend_deinit (void )
4655{
47- sm_cmux_release (CMUX_MODEM_TRACE_CHANNEL );
48-
56+ if (trace_pipe ) {
57+ modem_pipe_release (trace_pipe );
58+ trace_pipe = NULL ;
59+ }
4960 return 0 ;
5061}
5162
63+ void sm_trace_backend_attach (struct modem_pipe * pipe )
64+ {
65+ modem_pipe_attach (pipe , modem_pipe_event_handler , NULL );
66+ }
67+
68+ void sm_trace_backend_detach (void )
69+ {
70+ if (trace_pipe ) {
71+ modem_pipe_release (trace_pipe );
72+ trace_pipe = NULL ;
73+ }
74+ }
75+
5276int trace_backend_write (const void * data , size_t len )
5377{
54- struct modem_pipe * pipe = sm_cmux_reserve (CMUX_MODEM_TRACE_CHANNEL );
55- const uint8_t * buf = (const uint8_t * )data ;
56- size_t sent_len = 0 ;
5778 int ret = 0 ;
5879
59- if (!sm_cmux_dlci_is_open ( CMUX_MODEM_TRACE_CHANNEL )) {
60- LOG_DBG ( "Dropped %u bytes." , len );
80+ if (!trace_pipe || ! sm_pipe_is_open ( trace_pipe )) {
81+ LOG_DBG_RATELIMIT ( "Pipe closed, dropped %u bytes." , len );
6182 trace_processed_callback (len );
6283 return len ;
6384 }
6485
65- modem_pipe_attach (pipe , modem_pipe_event_handler , NULL );
66-
67- while (sent_len < len ) {
68- ret = modem_pipe_transmit (pipe , buf , len - sent_len );
69- if (ret < 0 ) {
70- LOG_WRN ("TX error (%d). Dropped %u bytes." , ret , len - sent_len );
86+ /* No need to retry here.
87+ * The nrf_modem_lib_trace.c:trace_fragment_write() handles
88+ * retrying if the backend returns -EAGAIN.
89+ *
90+ * It is important to call trace_processed_callback(len) for
91+ * every fragment written to ensure the trace fifos are not
92+ * overflowing. Even if we drop the fragment.
93+ */
94+
95+ if (k_sem_take (& tx_idle_sem , K_MSEC (CONFIG_SM_MODEM_TRACE_CMUX_TX_TIMEOUT_MS )) != 0 ) {
96+ if (IS_ENABLED (CONFIG_SM_MODEM_TRACE_DROP_ON_TIMEOUT )) {
97+ LOG_WRN_RATELIMIT ("Timeout, dropping %u bytes." , len );
7198 trace_processed_callback (len );
72- return ret ;
73- } else if (ret == 0 ) {
74- if (k_sem_take (& tx_idle_sem , K_SECONDS (1 )) != 0 ) {
75- LOG_WRN ("TX timeout." );
76- break ;
77- }
78- } else {
79- sent_len += ret ;
80- buf += ret ;
99+ return len ;
81100 }
101+ LOG_WRN_RATELIMIT ("TX timeout." );
102+ return - EAGAIN ;
82103 }
83104
84- if (sent_len ) {
85- trace_processed_callback (sent_len );
86- }
87-
88- if (sent_len < len ) {
89- LOG_DBG ("Sent %u out of %u bytes." , sent_len , len );
105+ ret = modem_pipe_transmit (trace_pipe , data , len );
106+ if (ret < 0 ) {
107+ LOG_WRN ("TX error (%d). Dropped %u bytes." , ret , len );
108+ trace_processed_callback (len );
109+ return ret ;
110+ } else if (ret == 0 ) {
111+ return - EAGAIN ;
90112 }
113+ trace_processed_callback (ret );
91114
92- return sent_len ;
115+ return ret ;
93116}
94117
95118struct nrf_modem_lib_trace_backend trace_backend = {
0 commit comments