提交 7e79b37c authored 作者: Steve Underwood's avatar Steve Underwood

Make spandsp's T.38 features tolerate the non-compliant inclusion of data

in some T.38 packets from Commetrex and Cisco machines.
上级 744f3ab7
...@@ -396,6 +396,21 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica ...@@ -396,6 +396,21 @@ static int process_rx_indicator(t38_core_state_t *t, void *user_data, int indica
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
static void process_hdlc_data(t31_t38_front_end_state_t *fe, const uint8_t *buf, int len)
{
if (fe->hdlc_rx.len + len <= T31_T38_MAX_HDLC_LEN)
{
bit_reverse(fe->hdlc_rx.buf + fe->hdlc_rx.len, buf, len);
fe->hdlc_rx.len += len;
}
else
{
fe->rx_data_missing = TRUE;
}
/*endif*/
}
/*- End of function --------------------------------------------------------*/
static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, int field_type, const uint8_t *buf, int len) static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, int field_type, const uint8_t *buf, int len)
{ {
t31_state_t *s; t31_state_t *s;
...@@ -451,16 +466,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -451,16 +466,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
/*endif*/ /*endif*/
if (len > 0) if (len > 0)
{ {
if (fe->hdlc_rx.len + len <= T31_T38_MAX_HDLC_LEN) process_hdlc_data(fe, buf, len);
{
bit_reverse(fe->hdlc_rx.buf + fe->hdlc_rx.len, buf, len);
fe->hdlc_rx.len += len;
}
else
{
fe->rx_data_missing = TRUE;
}
/*endif*/
} }
/*endif*/ /*endif*/
fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT); fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT);
...@@ -469,14 +475,15 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -469,14 +475,15 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
if (len > 0) if (len > 0)
{ {
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK!\n"); span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK!\n");
/* The sender has incorrectly included data in this message. It is unclear what we should do /* The sender has incorrectly included data in this message. Cisco implemented inserting
with it, to maximise tolerance of buggy implementations. */ HDLC data here and Commetrex followed for compatibility reasons. We should, too. */
process_hdlc_data(fe, buf, len);
} }
/*endif*/ /*endif*/
/* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK messages, in IFP packets with /* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK messages, in IFP packets with
incrementing sequence numbers, which are actually repeats. They get through to this point because incrementing sequence numbers, which are actually repeats. They get through to this point because
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) if (fe->hdlc_rx.len > 0)
{ {
span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean"); span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean");
if (data_type == T38_DATA_V21) if (data_type == T38_DATA_V21)
...@@ -504,9 +511,9 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -504,9 +511,9 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
hdlc_accept_t38_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing); hdlc_accept_t38_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing);
} }
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
} }
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
fe->rx_data_missing = FALSE; fe->rx_data_missing = FALSE;
fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT); fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT);
break; break;
...@@ -514,14 +521,15 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -514,14 +521,15 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
if (len > 0) if (len > 0)
{ {
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD!\n"); span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD!\n");
/* The sender has incorrectly included data in this message. We can safely ignore it, as the /* The sender has incorrectly included data in this message. Cisco implemented inserting
bad FCS means we will throw away the whole message, anyway. */ HDLC data here and Commetrex followed for compatibility reasons. We should, too. */
process_hdlc_data(fe, buf, len);
} }
/*endif*/ /*endif*/
/* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_BAD messages, in IFP packets with /* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_BAD messages, in IFP packets with
incrementing sequence numbers, which are actually repeats. They get through to this point because incrementing sequence numbers, which are actually repeats. They get through to this point because
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) if (fe->hdlc_rx.len > 0)
{ {
span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean"); span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean");
if (data_type == T38_DATA_V21) if (data_type == T38_DATA_V21)
...@@ -529,9 +537,9 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -529,9 +537,9 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
else else
hdlc_accept_t38_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE); hdlc_accept_t38_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE);
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
} }
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
fe->rx_data_missing = FALSE; fe->rx_data_missing = FALSE;
fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT); fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT);
break; break;
...@@ -539,14 +547,15 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -539,14 +547,15 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
if (len > 0) if (len > 0)
{ {
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK_SIG_END!\n"); span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK_SIG_END!\n");
/* The sender has incorrectly included data in this message. It is unclear what we should do /* The sender has incorrectly included data in this message. Cisco implemented inserting
with it, to maximise tolerance of buggy implementations. */ HDLC data here and Commetrex followed for compatibility reasons. We should, too. */
process_hdlc_data(fe, buf, len);
} }
/*endif*/ /*endif*/
/* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK_SIG_END messages, in IFP packets with /* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK_SIG_END messages, in IFP packets with
incrementing sequence numbers, which are actually repeats. They get through to this point because incrementing sequence numbers, which are actually repeats. They get through to this point because
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) if (fe->hdlc_rx.len > 0)
{ {
span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean"); span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean");
if (data_type == T38_DATA_V21) if (data_type == T38_DATA_V21)
...@@ -568,49 +577,60 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -568,49 +577,60 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
/*endif*/ /*endif*/
crc_itu16_append(fe->hdlc_rx.buf, fe->hdlc_rx.len); crc_itu16_append(fe->hdlc_rx.buf, fe->hdlc_rx.len);
hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing); hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing);
hdlc_rx_status(s, SIG_STATUS_CARRIER_DOWN);
} }
else else
{ {
hdlc_accept_t38_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing); hdlc_accept_t38_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing);
non_ecm_rx_status(s, SIG_STATUS_CARRIER_DOWN);
} }
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
} }
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
fe->rx_data_missing = FALSE; fe->rx_data_missing = FALSE;
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type)
{
if (data_type == T38_DATA_V21)
hdlc_rx_status(s, SIG_STATUS_CARRIER_DOWN);
else
non_ecm_rx_status(s, SIG_STATUS_CARRIER_DOWN);
/*endif*/
}
/*endif*/
fe->timeout_rx_samples = 0; fe->timeout_rx_samples = 0;
break; break;
case T38_FIELD_HDLC_FCS_BAD_SIG_END: case T38_FIELD_HDLC_FCS_BAD_SIG_END:
if (len > 0) if (len > 0)
{ {
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD_SIG_END!\n"); span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD_SIG_END!\n");
/* The sender has incorrectly included data in this message. We can safely ignore it, as the /* The sender has incorrectly included data in this message. Cisco implemented inserting
bad FCS means we will throw away the whole message, anyway. */ HDLC data here and Commetrex followed for compatibility reasons. We should, too. */
process_hdlc_data(fe, buf, len);
} }
/*endif*/ /*endif*/
/* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_BAD_SIG_END messages, in IFP packets with /* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_BAD_SIG_END messages, in IFP packets with
incrementing sequence numbers, which are actually repeats. They get through to this point because incrementing sequence numbers, which are actually repeats. They get through to this point because
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) if (fe->hdlc_rx.len > 0)
{ {
span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean"); span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean");
if (data_type == T38_DATA_V21) if (data_type == T38_DATA_V21)
{
hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE); hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE);
hdlc_rx_status(s, SIG_STATUS_CARRIER_DOWN);
}
else else
{
hdlc_accept_t38_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE); hdlc_accept_t38_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE);
non_ecm_rx_status(s, SIG_STATUS_CARRIER_DOWN);
}
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
} }
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
fe->rx_data_missing = FALSE; fe->rx_data_missing = FALSE;
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type)
{
if (data_type == T38_DATA_V21)
hdlc_rx_status(s, SIG_STATUS_CARRIER_DOWN);
else
non_ecm_rx_status(s, SIG_STATUS_CARRIER_DOWN);
/*endif*/
}
/*endif*/
fe->timeout_rx_samples = 0; fe->timeout_rx_samples = 0;
break; break;
case T38_FIELD_HDLC_SIG_END: case T38_FIELD_HDLC_SIG_END:
......
...@@ -318,6 +318,20 @@ static int fake_rx_indicator(t38_core_state_t *t, t38_terminal_state_t *s, int i ...@@ -318,6 +318,20 @@ static int fake_rx_indicator(t38_core_state_t *t, t38_terminal_state_t *s, int i
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
static void process_hdlc_data(t38_terminal_front_end_state_t *fe, const uint8_t *buf, int len)
{
if (fe->hdlc_rx.len + len <= T38_MAX_HDLC_LEN)
{
bit_reverse(fe->hdlc_rx.buf + fe->hdlc_rx.len, buf, len);
fe->hdlc_rx.len += len;
}
else
{
fe->rx_data_missing = TRUE;
}
}
/*- End of function --------------------------------------------------------*/
static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, int field_type, const uint8_t *buf, int len) static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, int field_type, const uint8_t *buf, int len)
{ {
t38_terminal_state_t *s; t38_terminal_state_t *s;
...@@ -416,16 +430,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -416,16 +430,7 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
/*endif*/ /*endif*/
if (len > 0) if (len > 0)
{ {
if (fe->hdlc_rx.len + len <= T38_MAX_HDLC_LEN) process_hdlc_data(fe, buf, len);
{
bit_reverse(fe->hdlc_rx.buf + fe->hdlc_rx.len, buf, len);
fe->hdlc_rx.len += len;
}
else
{
fe->rx_data_missing = TRUE;
}
/*endif*/
} }
/*endif*/ /*endif*/
fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT); fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT);
...@@ -434,20 +439,21 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -434,20 +439,21 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
if (len > 0) if (len > 0)
{ {
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK!\n"); span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK!\n");
/* The sender has incorrectly included data in this message. It is unclear what we should do /* The sender has incorrectly included data in this message. Cisco implemented inserting
with it, to maximise tolerance of buggy implementations. */ HDLC data here and Commetrex followed for compatibility reasons. We should, too. */
process_hdlc_data(fe, buf, len);
} }
/*endif*/ /*endif*/
/* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK messages, in IFP packets with /* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK messages, in IFP packets with
incrementing sequence numbers, which are actually repeats. They get through to this point because incrementing sequence numbers, which are actually repeats. They get through to this point because
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) if (fe->hdlc_rx.len > 0)
{ {
span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean"); span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean");
hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing); hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing);
fe->hdlc_rx.len = 0;
} }
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
fe->rx_data_missing = FALSE; fe->rx_data_missing = FALSE;
fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT); fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT);
break; break;
...@@ -455,20 +461,21 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -455,20 +461,21 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
if (len > 0) if (len > 0)
{ {
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD!\n"); span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD!\n");
/* The sender has incorrectly included data in this message. We can safely ignore it, as the /* The sender has incorrectly included data in this message. Cisco implemented inserting
bad FCS means we will throw away the whole message, anyway. */ HDLC data here and Commetrex followed for compatibility reasons. We should, too. */
process_hdlc_data(fe, buf, len);
} }
/*endif*/ /*endif*/
/* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_BAD messages, in IFP packets with /* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_BAD messages, in IFP packets with
incrementing sequence numbers, which are actually repeats. They get through to this point because incrementing sequence numbers, which are actually repeats. They get through to this point because
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) if (fe->hdlc_rx.len > 0)
{ {
span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean"); span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean");
hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE); hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE);
fe->hdlc_rx.len = 0;
} }
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
fe->rx_data_missing = FALSE; fe->rx_data_missing = FALSE;
fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT); fe->timeout_rx_samples = fe->samples + ms_to_samples(MID_RX_TIMEOUT);
break; break;
...@@ -476,22 +483,25 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -476,22 +483,25 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
if (len > 0) if (len > 0)
{ {
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK_SIG_END!\n"); span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK_SIG_END!\n");
/* The sender has incorrectly included data in this message. It is unclear what we should do /* The sender has incorrectly included data in this message. Cisco implemented inserting
with it, to maximise tolerance of buggy implementations. */ HDLC data here and Commetrex followed for compatibility reasons. We should, too. */
process_hdlc_data(fe, buf, len);
} }
/*endif*/ /*endif*/
/* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK_SIG_END messages, in IFP packets with /* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK_SIG_END messages, in IFP packets with
incrementing sequence numbers, which are actually repeats. They get through to this point because incrementing sequence numbers, which are actually repeats. They get through to this point because
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) if (fe->hdlc_rx.len > 0)
{ {
span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean"); span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean");
hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing); hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, !fe->rx_data_missing);
hdlc_accept_frame(s, NULL, SIG_STATUS_CARRIER_DOWN, TRUE); fe->hdlc_rx.len = 0;
} }
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
fe->rx_data_missing = FALSE; fe->rx_data_missing = FALSE;
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type)
hdlc_accept_frame(s, NULL, SIG_STATUS_CARRIER_DOWN, TRUE);
/*endif*/
/* Treat this like a no signal indicator has occurred, so if the no signal indicator is missing, we are still OK */ /* Treat this like a no signal indicator has occurred, so if the no signal indicator is missing, we are still OK */
fake_rx_indicator(t, s, T38_IND_NO_SIGNAL); fake_rx_indicator(t, s, T38_IND_NO_SIGNAL);
break; break;
...@@ -499,22 +509,25 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, ...@@ -499,22 +509,25 @@ static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type,
if (len > 0) if (len > 0)
{ {
span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD_SIG_END!\n"); span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD_SIG_END!\n");
/* The sender has incorrectly included data in this message. We can safely ignore it, as the /* The sender has incorrectly included data in this message. Cisco implemented inserting
bad FCS means we will throw away the whole message, anyway. */ HDLC data here and Commetrex followed for compatibility reasons. We should, too. */
process_hdlc_data(fe, buf, len);
} }
/*endif*/ /*endif*/
/* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_BAD_SIG_END messages, in IFP packets with /* Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_BAD_SIG_END messages, in IFP packets with
incrementing sequence numbers, which are actually repeats. They get through to this point because incrementing sequence numbers, which are actually repeats. They get through to this point because
of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */ of the incrementing sequence numbers. We need to filter them here in a context sensitive manner. */
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type) if (fe->hdlc_rx.len > 0)
{ {
span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean"); span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad, sig end (%s)\n", (fe->hdlc_rx.len >= 3) ? t30_frametype(fe->hdlc_rx.buf[2]) : "???", (fe->rx_data_missing) ? "missing octets" : "clean");
hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE); hdlc_accept_frame(s, fe->hdlc_rx.buf, fe->hdlc_rx.len, FALSE);
hdlc_accept_frame(s, NULL, SIG_STATUS_CARRIER_DOWN, TRUE); fe->hdlc_rx.len = 0;
} }
/*endif*/ /*endif*/
fe->hdlc_rx.len = 0;
fe->rx_data_missing = FALSE; fe->rx_data_missing = FALSE;
if (t->current_rx_data_type != data_type || t->current_rx_field_type != field_type)
hdlc_accept_frame(s, NULL, SIG_STATUS_CARRIER_DOWN, TRUE);
/*endif*/
/* Treat this like a no signal indicator has occurred, so if the no signal indicator is missing, we are still OK */ /* Treat this like a no signal indicator has occurred, so if the no signal indicator is missing, we are still OK */
fake_rx_indicator(t, s, T38_IND_NO_SIGNAL); fake_rx_indicator(t, s, T38_IND_NO_SIGNAL);
break; break;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论