wdoekes / spandsp-forks

Trying to make sense of spandsp versions
0 stars 0 forks source link

Older problem with infloop during receive on jessie/pre-jessie/pre21 #2

Open wdoekes opened 5 years ago

wdoekes commented 5 years ago

First I get:

  WARNING T.30 Page did not end cleanly

And later, I get a negative byte, which seems odd:

  FLOW T.38 Tx    98: (0) data v21/hdlc-data + -1 byte(s)

Fax is supposedly complete:

  FLOW T.38T FAX exchange complete

But then I get a seemingly endless loop of frames.

First this:

  FLOW T.38T No new frame or end transmission condition.
  FLOW T.38 Tx    99: (0) data v21/hdlc-fcs-OK + 0 byte(s)
  FLOW T.38 Tx    99: IFP c0 01 20
  FLOW T.38 Tx   100: (0) data ???/hdlc-data + 0 byte(s)
  FLOW T.38 Tx   100: IFP fe 01 00
  FLOW T.30 Send complete in phase T30_PHASE_CALL_FINISHED, state 32

Followed by this:

  FLOW T.38T No new frame or end transmission condition.
  FLOW T.38 Tx   101: (0) data ???/hdlc-fcs-OK + 0 byte(s)
  FLOW T.38 Tx   101: IFP fe 01 20
  FLOW T.38 Tx   102: (0) data ???/hdlc-data + 0 byte(s)
  FLOW T.38 Tx   102: IFP fe 01 00

And that last bit continues ad infinitum with increasing Tx sequence numbers.

As far as I can tell this comes from a loop in t38_terminal.c in stream_hdlc() where we're bouncing between these states without ever leaving the function:

  T38_TIMED_STEP_HDLC_MODEM_3 and T38_TIMED_STEP_HDLC_MODEM_4

And because we're never leaving, frames get enqueued in the user process without ever getting handled. That in turn causes the process to run out of memory.

Workaround/fix:

The current fix is to:

   Never have bits_to_us return 0 when the tx_bit_rate is 0.
   The lack of sleep means that the process may continue feeding
   empty packets back to asterisk without having asterisk
   re-gain control. (And commencing abortion of the call.)

Like this:

====

--- a/src/t38_terminal.c
+++ b/src/t38_terminal.c
@@ -606,6 +606,8 @@ static void send_hdlc(void *user_data, const uint8_t *msg, int len)

 static __inline__ int bits_to_us(t38_terminal_state_t *s, int bits)
 {
+    if (s->t38_fe.tx_bit_rate == 0)
+        return 1; /* OSSO/WJD/20130918:infloop_after_fax: break out earlier */
     if (s->t38_fe.ms_per_tx_chunk == 0  ||  s->t38_fe.tx_bit_rate == 0)
         return 0;
     /*endif*/

Other notes:

Rare log messages that ONLY occur for this incident:
- FLOW T.30 Send complete in phase T30_PHASE_D_TX, state 2
- FLOW T.38 Tx    98: (0) data v21/hdlc-data + -1 byte(s)