mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-24 03:47:39 +00:00
Improved TSB85 tests, which now check call clearing.
FAX now differentiates properly between <page result code> and <image> <page resuly code> when deciding how to retry.
This commit is contained in:
parent
d886cc12fa
commit
b780371943
libs/spandsp
spandsp
src
tests
@ -33,6 +33,7 @@
|
|||||||
modem CDATA #IMPLIED
|
modem CDATA #IMPLIED
|
||||||
tag CDATA #IMPLIED
|
tag CDATA #IMPLIED
|
||||||
value CDATA #IMPLIED
|
value CDATA #IMPLIED
|
||||||
|
timein CDATA #IMPLIED
|
||||||
timeout CDATA #IMPLIED
|
timeout CDATA #IMPLIED
|
||||||
crc_error CDATA #IMPLIED
|
crc_error CDATA #IMPLIED
|
||||||
pattern CDATA #IMPLIED
|
pattern CDATA #IMPLIED
|
||||||
|
@ -91,6 +91,9 @@
|
|||||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||||
<step dir="T" type="HDLC" tag="DCN" value="FF C8 5F"/>
|
<step dir="T" type="HDLC" tag="DCN" value="FF C8 5F"/>
|
||||||
<step dir="T" type="POSTAMBLE"/>
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
<step dir="T" type="CLEAR"/>
|
||||||
|
<step dir="R" type="CLEAR" timein="0" timeout="100"/>
|
||||||
|
<step type="STATUS" value="RX_DCNDATA"/>
|
||||||
</test>
|
</test>
|
||||||
<test name="V17-12000-V29-9600">
|
<test name="V17-12000-V29-9600">
|
||||||
<!-- Tester calls, trying to provoke a crash seen in some versions of spandsp, when
|
<!-- Tester calls, trying to provoke a crash seen in some versions of spandsp, when
|
||||||
@ -183,6 +186,9 @@
|
|||||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||||
<step dir="T" type="HDLC" tag="DCN" value="FF C8 5F"/>
|
<step dir="T" type="HDLC" tag="DCN" value="FF C8 5F"/>
|
||||||
<step dir="T" type="POSTAMBLE"/>
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
<step dir="T" type="CLEAR"/>
|
||||||
|
<step dir="R" type="CLEAR" timein="0" timeout="100"/>
|
||||||
|
<step type="STATUS" value="OK"/>
|
||||||
</test>
|
</test>
|
||||||
<test name="Phase-D-collision">
|
<test name="Phase-D-collision">
|
||||||
<!-- DUT calls tester and sends 1 IMPRESS and 1 WHITE page. The MCF after the first
|
<!-- DUT calls tester and sends 1 IMPRESS and 1 WHITE page. The MCF after the first
|
||||||
@ -224,6 +230,8 @@
|
|||||||
<step dir="T" type="POSTAMBLE"/>
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
|
||||||
<step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
|
<step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
|
||||||
|
<step dir="R" type="CLEAR" timein="800" timeout="1200"/>
|
||||||
|
<step type="STATUS" value="OK"/>
|
||||||
</test>
|
</test>
|
||||||
</test-group>
|
</test-group>
|
||||||
</fax-tests>
|
</fax-tests>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -181,6 +181,10 @@ struct t30_state_s
|
|||||||
/*! \brief True if the short training sequence should be used. */
|
/*! \brief True if the short training sequence should be used. */
|
||||||
bool short_train;
|
bool short_train;
|
||||||
|
|
||||||
|
/*! \brief True if an image carrier appears to have been received, even if it did not successfully
|
||||||
|
train. */
|
||||||
|
bool image_carrier_attempted;
|
||||||
|
|
||||||
/*! \brief A count of the number of bits in the trainability test. This counts down to zero when
|
/*! \brief A count of the number of bits in the trainability test. This counts down to zero when
|
||||||
sending TCF, and counts up when receiving it. */
|
sending TCF, and counts up when receiving it. */
|
||||||
int tcf_test_bits;
|
int tcf_test_bits;
|
||||||
@ -293,6 +297,8 @@ struct t30_state_s
|
|||||||
partial pages still to come. */
|
partial pages still to come. */
|
||||||
bool ecm_at_page_end;
|
bool ecm_at_page_end;
|
||||||
|
|
||||||
|
/*! \brief The last result for a received non-ECM page - T30_MPS, T30_RTP, or T30_RTN. */
|
||||||
|
int last_rx_page_result;
|
||||||
/*! \brief The transmission step queued to follow the one in progress. */
|
/*! \brief The transmission step queued to follow the one in progress. */
|
||||||
int next_tx_step;
|
int next_tx_step;
|
||||||
/*! \brief The FCF for the next receive step. */
|
/*! \brief The FCF for the next receive step. */
|
||||||
@ -310,11 +316,6 @@ struct t30_state_s
|
|||||||
/*! \brief The current completion status. */
|
/*! \brief The current completion status. */
|
||||||
int current_status;
|
int current_status;
|
||||||
|
|
||||||
/*! \brief The number of RTP events */
|
|
||||||
int rtp_events;
|
|
||||||
/*! \brief The number of RTN events */
|
|
||||||
int rtn_events;
|
|
||||||
|
|
||||||
/*! \brief the FCF2 field of the last PPS message we received. */
|
/*! \brief the FCF2 field of the last PPS message we received. */
|
||||||
uint8_t last_pps_fcf2;
|
uint8_t last_pps_fcf2;
|
||||||
/*! \brief True if all frames of the current received ECM block are now OK */
|
/*! \brief True if all frames of the current received ECM block are now OK */
|
||||||
@ -323,6 +324,11 @@ struct t30_state_s
|
|||||||
deciding whether to continue error correction when PPRs keep repeating. */
|
deciding whether to continue error correction when PPRs keep repeating. */
|
||||||
int ecm_progress;
|
int ecm_progress;
|
||||||
|
|
||||||
|
/*! \brief The number of RTP events */
|
||||||
|
int rtp_events;
|
||||||
|
/*! \brief The number of RTN events */
|
||||||
|
int rtn_events;
|
||||||
|
|
||||||
/*! \brief Error and flow logging control */
|
/*! \brief Error and flow logging control */
|
||||||
logging_state_t logging;
|
logging_state_t logging;
|
||||||
};
|
};
|
||||||
|
@ -173,9 +173,7 @@ enum
|
|||||||
T30_STATE_I,
|
T30_STATE_I,
|
||||||
T30_STATE_II,
|
T30_STATE_II,
|
||||||
T30_STATE_II_Q,
|
T30_STATE_II_Q,
|
||||||
T30_STATE_III_Q_MCF,
|
T30_STATE_III_Q,
|
||||||
T30_STATE_III_Q_RTP,
|
|
||||||
T30_STATE_III_Q_RTN,
|
|
||||||
T30_STATE_IV,
|
T30_STATE_IV,
|
||||||
T30_STATE_IV_PPS_NULL,
|
T30_STATE_IV_PPS_NULL,
|
||||||
T30_STATE_IV_PPS_Q,
|
T30_STATE_IV_PPS_Q,
|
||||||
@ -210,9 +208,7 @@ static const char *state_names[] =
|
|||||||
"I",
|
"I",
|
||||||
"II",
|
"II",
|
||||||
"II_Q",
|
"II_Q",
|
||||||
"III_Q_MCF",
|
"III_Q",
|
||||||
"III_Q_RTP",
|
|
||||||
"III_Q_RTN",
|
|
||||||
"IV",
|
"IV",
|
||||||
"IV_PPS_NULL",
|
"IV_PPS_NULL",
|
||||||
"IV_PPS_Q",
|
"IV_PPS_Q",
|
||||||
@ -3600,7 +3596,7 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
|
|||||||
state, it looks like either:
|
state, it looks like either:
|
||||||
- we didn't see the image data carrier properly, or
|
- we didn't see the image data carrier properly, or
|
||||||
- they didn't see our T30_CFR, and are repeating the DCS/TCF sequence.
|
- they didn't see our T30_CFR, and are repeating the DCS/TCF sequence.
|
||||||
- they didn't see out T30_MCF, and are repeating the end of page message. */
|
- they didn't see our T30_MCF, T30_RTP or T30_RTN and are repeating the end of page message. */
|
||||||
fcf = msg[2] & 0xFE;
|
fcf = msg[2] & 0xFE;
|
||||||
switch (fcf)
|
switch (fcf)
|
||||||
{
|
{
|
||||||
@ -3616,13 +3612,22 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
|
|||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case T30_MPS:
|
case T30_MPS:
|
||||||
/* Treat this as a bad quality page. */
|
if (s->image_carrier_attempted)
|
||||||
if (s->phase_d_handler)
|
{
|
||||||
s->phase_d_handler(s->phase_d_user_data, fcf);
|
/* Treat this as a bad quality page. */
|
||||||
s->next_rx_step = fcf;
|
if (s->phase_d_handler)
|
||||||
queue_phase(s, T30_PHASE_D_TX);
|
s->phase_d_handler(s->phase_d_user_data, fcf);
|
||||||
set_state(s, T30_STATE_III_Q_RTN);
|
s->next_rx_step = fcf;
|
||||||
send_simple_frame(s, T30_RTN);
|
s->last_rx_page_result = T30_RTN;
|
||||||
|
queue_phase(s, T30_PHASE_D_TX);
|
||||||
|
set_state(s, T30_STATE_III_Q);
|
||||||
|
send_simple_frame(s, s->last_rx_page_result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This appears to be a retry, because the far end didn't see our last response */
|
||||||
|
repeat_last_command(s);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case T30_PRI_EOM:
|
case T30_PRI_EOM:
|
||||||
if (s->remote_interrupts_allowed)
|
if (s->remote_interrupts_allowed)
|
||||||
@ -3631,14 +3636,23 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
|
|||||||
/* Fall through */
|
/* Fall through */
|
||||||
case T30_EOM:
|
case T30_EOM:
|
||||||
case T30_EOS:
|
case T30_EOS:
|
||||||
/* Treat this as a bad quality page. */
|
if (s->image_carrier_attempted)
|
||||||
if (s->phase_d_handler)
|
{
|
||||||
s->phase_d_handler(s->phase_d_user_data, fcf);
|
/* Treat this as a bad quality page. */
|
||||||
s->next_rx_step = fcf;
|
if (s->phase_d_handler)
|
||||||
/* Return to phase B */
|
s->phase_d_handler(s->phase_d_user_data, fcf);
|
||||||
queue_phase(s, T30_PHASE_B_TX);
|
s->next_rx_step = fcf;
|
||||||
set_state(s, T30_STATE_III_Q_RTN);
|
s->last_rx_page_result = T30_RTN;
|
||||||
send_simple_frame(s, T30_RTN);
|
/* Return to phase B */
|
||||||
|
queue_phase(s, T30_PHASE_B_TX);
|
||||||
|
set_state(s, T30_STATE_III_Q);
|
||||||
|
send_simple_frame(s, s->last_rx_page_result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This appears to be a retry, because the far end didn't see our last response */
|
||||||
|
repeat_last_command(s);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case T30_PRI_EOP:
|
case T30_PRI_EOP:
|
||||||
if (s->remote_interrupts_allowed)
|
if (s->remote_interrupts_allowed)
|
||||||
@ -3646,13 +3660,22 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
|
|||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case T30_EOP:
|
case T30_EOP:
|
||||||
/* Treat this as a bad quality page. */
|
if (s->image_carrier_attempted)
|
||||||
if (s->phase_d_handler)
|
{
|
||||||
s->phase_d_handler(s->phase_d_user_data, fcf);
|
/* Treat this as a bad quality page. */
|
||||||
s->next_rx_step = fcf;
|
if (s->phase_d_handler)
|
||||||
queue_phase(s, T30_PHASE_D_TX);
|
s->phase_d_handler(s->phase_d_user_data, fcf);
|
||||||
set_state(s, T30_STATE_III_Q_RTN);
|
s->next_rx_step = fcf;
|
||||||
send_simple_frame(s, T30_RTN);
|
s->last_rx_page_result = T30_RTN;
|
||||||
|
queue_phase(s, T30_PHASE_D_TX);
|
||||||
|
set_state(s, T30_STATE_III_Q);
|
||||||
|
send_simple_frame(s, s->last_rx_page_result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This appears to be a retry, because the far end didn't see our last response */
|
||||||
|
repeat_last_command(s);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case T30_DCN:
|
case T30_DCN:
|
||||||
t30_set_status(s, T30_ERR_RX_DCNDATA);
|
t30_set_status(s, T30_ERR_RX_DCNDATA);
|
||||||
@ -3705,18 +3728,18 @@ static void assess_copy_quality(t30_state_t *s, uint8_t fcf)
|
|||||||
{
|
{
|
||||||
case T30_COPY_QUALITY_PERFECT:
|
case T30_COPY_QUALITY_PERFECT:
|
||||||
case T30_COPY_QUALITY_GOOD:
|
case T30_COPY_QUALITY_GOOD:
|
||||||
set_state(s, T30_STATE_III_Q_MCF);
|
s->last_rx_page_result = T30_MCF;
|
||||||
send_simple_frame(s, T30_MCF);
|
|
||||||
break;
|
break;
|
||||||
case T30_COPY_QUALITY_POOR:
|
case T30_COPY_QUALITY_POOR:
|
||||||
set_state(s, T30_STATE_III_Q_RTP);
|
s->last_rx_page_result = T30_RTP;
|
||||||
send_simple_frame(s, T30_RTP);
|
|
||||||
break;
|
break;
|
||||||
case T30_COPY_QUALITY_BAD:
|
case T30_COPY_QUALITY_BAD:
|
||||||
set_state(s, T30_STATE_III_Q_RTN);
|
default:
|
||||||
send_simple_frame(s, T30_RTN);
|
s->last_rx_page_result = T30_RTN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
set_state(s, T30_STATE_III_Q);
|
||||||
|
send_simple_frame(s, s->last_rx_page_result);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -3761,6 +3784,10 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
|
|||||||
queue_phase(s, T30_PHASE_D_TX);
|
queue_phase(s, T30_PHASE_D_TX);
|
||||||
assess_copy_quality(s, fcf);
|
assess_copy_quality(s, fcf);
|
||||||
break;
|
break;
|
||||||
|
case T30_DCS:
|
||||||
|
span_log(&s->logging, SPAN_LOG_FLOW, "DCS received after CFR\n");
|
||||||
|
process_rx_dcs(s, msg, len);
|
||||||
|
break;
|
||||||
case T30_DCN:
|
case T30_DCN:
|
||||||
t30_set_status(s, T30_ERR_RX_DCNFAX);
|
t30_set_status(s, T30_ERR_RX_DCNFAX);
|
||||||
terminate_call(s);
|
terminate_call(s);
|
||||||
@ -3823,6 +3850,7 @@ static void process_state_f_doc_and_post_doc_ecm(t30_state_t *s, const uint8_t *
|
|||||||
case T30_EOM:
|
case T30_EOM:
|
||||||
case T30_EOS:
|
case T30_EOS:
|
||||||
case T30_MPS:
|
case T30_MPS:
|
||||||
|
s->image_carrier_attempted = false;
|
||||||
s->next_rx_step = fcf2;
|
s->next_rx_step = fcf2;
|
||||||
queue_phase(s, T30_PHASE_D_TX);
|
queue_phase(s, T30_PHASE_D_TX);
|
||||||
set_state(s, T30_STATE_F_DOC_ECM);
|
set_state(s, T30_STATE_F_DOC_ECM);
|
||||||
@ -3837,6 +3865,7 @@ static void process_state_f_doc_and_post_doc_ecm(t30_state_t *s, const uint8_t *
|
|||||||
process_rx_pps(s, msg, len);
|
process_rx_pps(s, msg, len);
|
||||||
break;
|
break;
|
||||||
case T30_CTC:
|
case T30_CTC:
|
||||||
|
s->image_carrier_attempted = false;
|
||||||
/* T.30 says we change back to long training here */
|
/* T.30 says we change back to long training here */
|
||||||
s->short_train = false;
|
s->short_train = false;
|
||||||
queue_phase(s, T30_PHASE_D_TX);
|
queue_phase(s, T30_PHASE_D_TX);
|
||||||
@ -4270,7 +4299,7 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static void process_state_iii_q_mcf(t30_state_t *s, const uint8_t *msg, int len)
|
static void process_state_iii_q(t30_state_t *s, const uint8_t *msg, int len)
|
||||||
{
|
{
|
||||||
uint8_t fcf;
|
uint8_t fcf;
|
||||||
|
|
||||||
@ -4283,8 +4312,8 @@ static void process_state_iii_q_mcf(t30_state_t *s, const uint8_t *msg, int len)
|
|||||||
case T30_MPS:
|
case T30_MPS:
|
||||||
/* Looks like they didn't see our signal. Repeat it */
|
/* Looks like they didn't see our signal. Repeat it */
|
||||||
queue_phase(s, T30_PHASE_D_TX);
|
queue_phase(s, T30_PHASE_D_TX);
|
||||||
set_state(s, T30_STATE_III_Q_MCF);
|
set_state(s, T30_STATE_III_Q);
|
||||||
send_simple_frame(s, T30_MCF);
|
send_simple_frame(s, s->last_rx_page_result);
|
||||||
break;
|
break;
|
||||||
case T30_DIS:
|
case T30_DIS:
|
||||||
if (msg[2] == T30_DTC)
|
if (msg[2] == T30_DTC)
|
||||||
@ -4297,78 +4326,8 @@ static void process_state_iii_q_mcf(t30_state_t *s, const uint8_t *msg, int len)
|
|||||||
process_rx_fnv(s, msg, len);
|
process_rx_fnv(s, msg, len);
|
||||||
break;
|
break;
|
||||||
case T30_DCN:
|
case T30_DCN:
|
||||||
terminate_call(s);
|
if (s->last_rx_page_result == T30_RTN)
|
||||||
break;
|
t30_set_status(s, T30_ERR_RX_DCNNORTN);
|
||||||
default:
|
|
||||||
/* We don't know what to do with this. */
|
|
||||||
unexpected_final_frame(s, msg, len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void process_state_iii_q_rtp(t30_state_t *s, const uint8_t *msg, int len)
|
|
||||||
{
|
|
||||||
uint8_t fcf;
|
|
||||||
|
|
||||||
fcf = msg[2] & 0xFE;
|
|
||||||
switch (fcf)
|
|
||||||
{
|
|
||||||
case T30_EOP:
|
|
||||||
case T30_EOM:
|
|
||||||
case T30_EOS:
|
|
||||||
case T30_MPS:
|
|
||||||
/* Looks like they didn't see our signal. Repeat it */
|
|
||||||
queue_phase(s, T30_PHASE_D_TX);
|
|
||||||
set_state(s, T30_STATE_III_Q_RTP);
|
|
||||||
send_simple_frame(s, T30_RTP);
|
|
||||||
break;
|
|
||||||
case T30_DIS:
|
|
||||||
if (msg[2] == T30_DTC)
|
|
||||||
process_rx_dis_dtc(s, msg, len);
|
|
||||||
break;
|
|
||||||
case T30_CRP:
|
|
||||||
repeat_last_command(s);
|
|
||||||
break;
|
|
||||||
case T30_FNV:
|
|
||||||
process_rx_fnv(s, msg, len);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* We don't know what to do with this. */
|
|
||||||
unexpected_final_frame(s, msg, len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*- End of function --------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void process_state_iii_q_rtn(t30_state_t *s, const uint8_t *msg, int len)
|
|
||||||
{
|
|
||||||
uint8_t fcf;
|
|
||||||
|
|
||||||
fcf = msg[2] & 0xFE;
|
|
||||||
switch (fcf)
|
|
||||||
{
|
|
||||||
case T30_EOP:
|
|
||||||
case T30_EOM:
|
|
||||||
case T30_EOS:
|
|
||||||
case T30_MPS:
|
|
||||||
/* Looks like they didn't see our signal. Repeat it */
|
|
||||||
queue_phase(s, T30_PHASE_D_TX);
|
|
||||||
set_state(s, T30_STATE_III_Q_RTN);
|
|
||||||
send_simple_frame(s, T30_RTN);
|
|
||||||
break;
|
|
||||||
case T30_DIS:
|
|
||||||
if (msg[2] == T30_DTC)
|
|
||||||
process_rx_dis_dtc(s, msg, len);
|
|
||||||
break;
|
|
||||||
case T30_CRP:
|
|
||||||
repeat_last_command(s);
|
|
||||||
break;
|
|
||||||
case T30_FNV:
|
|
||||||
process_rx_fnv(s, msg, len);
|
|
||||||
break;
|
|
||||||
case T30_DCN:
|
|
||||||
t30_set_status(s, T30_ERR_RX_DCNNORTN);
|
|
||||||
terminate_call(s);
|
terminate_call(s);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -5090,14 +5049,8 @@ static void process_rx_control_msg(t30_state_t *s, const uint8_t *msg, int len)
|
|||||||
case T30_STATE_II_Q:
|
case T30_STATE_II_Q:
|
||||||
process_state_ii_q(s, msg, len);
|
process_state_ii_q(s, msg, len);
|
||||||
break;
|
break;
|
||||||
case T30_STATE_III_Q_MCF:
|
case T30_STATE_III_Q:
|
||||||
process_state_iii_q_mcf(s, msg, len);
|
process_state_iii_q(s, msg, len);
|
||||||
break;
|
|
||||||
case T30_STATE_III_Q_RTP:
|
|
||||||
process_state_iii_q_rtp(s, msg, len);
|
|
||||||
break;
|
|
||||||
case T30_STATE_III_Q_RTN:
|
|
||||||
process_state_iii_q_rtn(s, msg, len);
|
|
||||||
break;
|
break;
|
||||||
case T30_STATE_IV:
|
case T30_STATE_IV:
|
||||||
process_state_iv(s, msg, len);
|
process_state_iv(s, msg, len);
|
||||||
@ -5315,17 +5268,10 @@ static void repeat_last_command(t30_state_t *s)
|
|||||||
queue_phase(s, T30_PHASE_B_TX);
|
queue_phase(s, T30_PHASE_B_TX);
|
||||||
send_dis_or_dtc_sequence(s, true);
|
send_dis_or_dtc_sequence(s, true);
|
||||||
break;
|
break;
|
||||||
case T30_STATE_III_Q_MCF:
|
case T30_STATE_F_DOC_NON_ECM:
|
||||||
|
case T30_STATE_III_Q:
|
||||||
queue_phase(s, T30_PHASE_D_TX);
|
queue_phase(s, T30_PHASE_D_TX);
|
||||||
send_simple_frame(s, T30_MCF);
|
send_simple_frame(s, s->last_rx_page_result);
|
||||||
break;
|
|
||||||
case T30_STATE_III_Q_RTP:
|
|
||||||
queue_phase(s, T30_PHASE_D_TX);
|
|
||||||
send_simple_frame(s, T30_RTP);
|
|
||||||
break;
|
|
||||||
case T30_STATE_III_Q_RTN:
|
|
||||||
queue_phase(s, T30_PHASE_D_TX);
|
|
||||||
send_simple_frame(s, T30_RTN);
|
|
||||||
break;
|
break;
|
||||||
case T30_STATE_II_Q:
|
case T30_STATE_II_Q:
|
||||||
queue_phase(s, T30_PHASE_D_TX);
|
queue_phase(s, T30_PHASE_D_TX);
|
||||||
@ -5526,9 +5472,7 @@ static void timer_t2_expired(t30_state_t *s)
|
|||||||
span_log(&s->logging, SPAN_LOG_FLOW, "T2 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
|
span_log(&s->logging, SPAN_LOG_FLOW, "T2 expired in phase %s, state %s\n", phase_names[s->phase], state_names[s->state]);
|
||||||
switch (s->state)
|
switch (s->state)
|
||||||
{
|
{
|
||||||
case T30_STATE_III_Q_MCF:
|
case T30_STATE_III_Q:
|
||||||
case T30_STATE_III_Q_RTP:
|
|
||||||
case T30_STATE_III_Q_RTN:
|
|
||||||
case T30_STATE_F_POST_RCP_PPR:
|
case T30_STATE_F_POST_RCP_PPR:
|
||||||
case T30_STATE_F_POST_RCP_MCF:
|
case T30_STATE_F_POST_RCP_MCF:
|
||||||
switch (s->next_rx_step)
|
switch (s->next_rx_step)
|
||||||
@ -5738,6 +5682,7 @@ static void t30_non_ecm_rx_status(void *user_data, int status)
|
|||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
case SIG_STATUS_TRAINING_IN_PROGRESS:
|
||||||
|
s->image_carrier_attempted = true;
|
||||||
break;
|
break;
|
||||||
case SIG_STATUS_TRAINING_FAILED:
|
case SIG_STATUS_TRAINING_FAILED:
|
||||||
s->rx_trained = false;
|
s->rx_trained = false;
|
||||||
@ -6205,6 +6150,8 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status)
|
|||||||
case T30_STATE_F_CFR:
|
case T30_STATE_F_CFR:
|
||||||
if (send_cfr_sequence(s, false))
|
if (send_cfr_sequence(s, false))
|
||||||
{
|
{
|
||||||
|
s->image_carrier_attempted = false;
|
||||||
|
s->last_rx_page_result = -1;
|
||||||
if (s->error_correcting_mode)
|
if (s->error_correcting_mode)
|
||||||
{
|
{
|
||||||
set_state(s, T30_STATE_F_DOC_ECM);
|
set_state(s, T30_STATE_F_DOC_ECM);
|
||||||
@ -6231,9 +6178,8 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status)
|
|||||||
timer_t2_start(s);
|
timer_t2_start(s);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T30_STATE_III_Q_MCF:
|
case T30_STATE_F_DOC_NON_ECM:
|
||||||
case T30_STATE_III_Q_RTP:
|
case T30_STATE_III_Q:
|
||||||
case T30_STATE_III_Q_RTN:
|
|
||||||
case T30_STATE_F_POST_RCP_PPR:
|
case T30_STATE_F_POST_RCP_PPR:
|
||||||
case T30_STATE_F_POST_RCP_MCF:
|
case T30_STATE_F_POST_RCP_MCF:
|
||||||
if (s->step == 0)
|
if (s->step == 0)
|
||||||
@ -6248,6 +6194,7 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status)
|
|||||||
case T30_PRI_MPS:
|
case T30_PRI_MPS:
|
||||||
case T30_MPS:
|
case T30_MPS:
|
||||||
/* We should now start to get another page */
|
/* We should now start to get another page */
|
||||||
|
s->image_carrier_attempted = false;
|
||||||
if (s->error_correcting_mode)
|
if (s->error_correcting_mode)
|
||||||
{
|
{
|
||||||
set_state(s, T30_STATE_F_DOC_ECM);
|
set_state(s, T30_STATE_F_DOC_ECM);
|
||||||
@ -6264,8 +6211,8 @@ SPAN_DECLARE(void) t30_front_end_status(void *user_data, int status)
|
|||||||
case T30_EOM:
|
case T30_EOM:
|
||||||
case T30_EOS:
|
case T30_EOS:
|
||||||
/* See if we get something back, before moving to phase B. */
|
/* See if we get something back, before moving to phase B. */
|
||||||
timer_t2_start(s);
|
|
||||||
set_phase(s, T30_PHASE_D_RX);
|
set_phase(s, T30_PHASE_D_RX);
|
||||||
|
timer_t2_start(s);
|
||||||
break;
|
break;
|
||||||
case T30_PRI_EOP:
|
case T30_PRI_EOP:
|
||||||
case T30_EOP:
|
case T30_EOP:
|
||||||
|
@ -264,32 +264,39 @@ static void parse_tone_set(super_tone_rx_descriptor_t *desc, xmlDocPtr doc, xmlN
|
|||||||
|
|
||||||
static void get_tone_set(super_tone_rx_descriptor_t *desc, const char *tone_file, const char *set_id)
|
static void get_tone_set(super_tone_rx_descriptor_t *desc, const char *tone_file, const char *set_id)
|
||||||
{
|
{
|
||||||
|
xmlParserCtxtPtr ctxt;
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNsPtr ns;
|
xmlNsPtr ns;
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
#if 1
|
|
||||||
xmlValidCtxt valid;
|
|
||||||
#endif
|
|
||||||
xmlChar *x;
|
xmlChar *x;
|
||||||
|
|
||||||
ns = NULL;
|
ns = NULL;
|
||||||
xmlKeepBlanksDefault(0);
|
xmlKeepBlanksDefault(0);
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
if ((doc = xmlParseFile(tone_file)) == NULL)
|
|
||||||
|
if ((ctxt = xmlNewParserCtxt()) == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "No document\n");
|
fprintf(stderr, "Failed to allocate parser context\n");
|
||||||
|
printf("Test failed\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
/*endif*/
|
/* parse the file, activating the DTD validation option */
|
||||||
xmlXIncludeProcess(doc);
|
if ((doc = xmlCtxtReadFile(ctxt, tone_file, NULL, XML_PARSE_XINCLUDE | XML_PARSE_DTDVALID)) == NULL)
|
||||||
#if 1
|
|
||||||
if (!xmlValidateDocument(&valid, doc))
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid document\n");
|
fprintf(stderr, "Failed to read the XML document\n");
|
||||||
|
printf("Test failed\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
/*endif*/
|
if (ctxt->valid == 0)
|
||||||
#endif
|
{
|
||||||
|
fprintf(stderr, "Failed to validate the XML document\n");
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
printf("Test failed\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
|
||||||
/* Check the document is of the right kind */
|
/* Check the document is of the right kind */
|
||||||
if ((cur = xmlDocGetRootElement(doc)) == NULL)
|
if ((cur = xmlDocGetRootElement(doc)) == NULL)
|
||||||
{
|
{
|
||||||
|
@ -203,33 +203,39 @@ static void parse_tone_set(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur)
|
|||||||
|
|
||||||
static void get_tone_set(const char *tone_file, const char *set_id)
|
static void get_tone_set(const char *tone_file, const char *set_id)
|
||||||
{
|
{
|
||||||
|
xmlParserCtxtPtr ctxt;
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNsPtr ns;
|
xmlNsPtr ns;
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
#if 0
|
|
||||||
xmlValidCtxt valid;
|
|
||||||
#endif
|
|
||||||
xmlChar *x;
|
xmlChar *x;
|
||||||
|
|
||||||
ns = NULL;
|
ns = NULL;
|
||||||
xmlKeepBlanksDefault(0);
|
xmlKeepBlanksDefault(0);
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
doc = xmlParseFile(tone_file);
|
|
||||||
if (doc == NULL)
|
if ((ctxt = xmlNewParserCtxt()) == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "No document\n");
|
fprintf(stderr, "Failed to allocate parser context\n");
|
||||||
|
printf("Test failed\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
/*endif*/
|
/* parse the file, activating the DTD validation option */
|
||||||
xmlXIncludeProcess(doc);
|
if ((doc = xmlCtxtReadFile(ctxt, tone_file, NULL, XML_PARSE_XINCLUDE | XML_PARSE_DTDVALID)) == NULL)
|
||||||
#if 0
|
|
||||||
if (!xmlValidateDocument(&valid, doc))
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid document\n");
|
fprintf(stderr, "Failed to read the XML document\n");
|
||||||
|
printf("Test failed\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
/*endif*/
|
if (ctxt->valid == 0)
|
||||||
#endif
|
{
|
||||||
|
fprintf(stderr, "Failed to validate the XML document\n");
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
printf("Test failed\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
|
||||||
/* Check the document is of the right kind */
|
/* Check the document is of the right kind */
|
||||||
if ((cur = xmlDocGetRootElement(doc)) == NULL)
|
if ((cur = xmlDocGetRootElement(doc)) == NULL)
|
||||||
{
|
{
|
||||||
|
@ -92,9 +92,86 @@ t30_exchanged_info_t expected_rx_info;
|
|||||||
|
|
||||||
char next_tx_file[1000];
|
char next_tx_file[1000];
|
||||||
|
|
||||||
|
static int timein_x = -1;
|
||||||
|
static int timeout_x = -1;
|
||||||
|
|
||||||
static int next_step(faxtester_state_t *s);
|
static int next_step(faxtester_state_t *s);
|
||||||
|
|
||||||
static bool test_for_call_drop = false;
|
static bool test_for_call_clear = false;
|
||||||
|
static int call_clear_timer = 0;
|
||||||
|
|
||||||
|
static bool far_end_cleared_call = false;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
const char *tag;
|
||||||
|
int code;
|
||||||
|
} t30_status[] =
|
||||||
|
{
|
||||||
|
{"OK", T30_ERR_OK},
|
||||||
|
{"CEDTONE", T30_ERR_CEDTONE},
|
||||||
|
{"T0_EXPIRED", T30_ERR_T0_EXPIRED},
|
||||||
|
{"T1_EXPIRED", T30_ERR_T1_EXPIRED},
|
||||||
|
{"T3_EXPIRED", T30_ERR_T3_EXPIRED},
|
||||||
|
{"HDLC_CARRIER", T30_ERR_HDLC_CARRIER},
|
||||||
|
{"CANNOT_TRAIN", T30_ERR_CANNOT_TRAIN},
|
||||||
|
{"OPER_INT_FAIL", T30_ERR_OPER_INT_FAIL},
|
||||||
|
{"INCOMPATIBLE", T30_ERR_INCOMPATIBLE},
|
||||||
|
{"RX_INCAPABLE", T30_ERR_RX_INCAPABLE},
|
||||||
|
{"TX_INCAPABLE", T30_ERR_TX_INCAPABLE},
|
||||||
|
{"NORESSUPPORT", T30_ERR_NORESSUPPORT},
|
||||||
|
{"NOSIZESUPPORT", T30_ERR_NOSIZESUPPORT},
|
||||||
|
{"UNEXPECTED", T30_ERR_UNEXPECTED},
|
||||||
|
{"TX_BADDCS", T30_ERR_TX_BADDCS},
|
||||||
|
{"TX_BADPG", T30_ERR_TX_BADPG},
|
||||||
|
{"TX_ECMPHD", T30_ERR_TX_ECMPHD},
|
||||||
|
{"TX_GOTDCN", T30_ERR_TX_GOTDCN},
|
||||||
|
{"TX_INVALRSP", T30_ERR_TX_INVALRSP},
|
||||||
|
{"TX_NODIS", T30_ERR_TX_NODIS},
|
||||||
|
{"TX_PHBDEAD", T30_ERR_TX_PHBDEAD},
|
||||||
|
{"TX_PHDDEAD", T30_ERR_TX_PHDDEAD},
|
||||||
|
{"TX_T5EXP", T30_ERR_TX_T5EXP},
|
||||||
|
{"RX_ECMPHD", T30_ERR_RX_ECMPHD},
|
||||||
|
{"RX_GOTDCS", T30_ERR_RX_GOTDCS},
|
||||||
|
{"RX_INVALCMD", T30_ERR_RX_INVALCMD},
|
||||||
|
{"RX_NOCARRIER", T30_ERR_RX_NOCARRIER},
|
||||||
|
{"RX_NOEOL", T30_ERR_RX_NOEOL},
|
||||||
|
{"RX_NOFAX", T30_ERR_RX_NOFAX},
|
||||||
|
{"RX_T2EXPDCN", T30_ERR_RX_T2EXPDCN},
|
||||||
|
{"RX_T2EXPD", T30_ERR_RX_T2EXPD},
|
||||||
|
{"RX_T2EXPFAX", T30_ERR_RX_T2EXPFAX},
|
||||||
|
{"RX_T2EXPMPS", T30_ERR_RX_T2EXPMPS},
|
||||||
|
{"RX_T2EXPRR", T30_ERR_RX_T2EXPRR},
|
||||||
|
{"RX_T2EXP", T30_ERR_RX_T2EXP},
|
||||||
|
{"RX_DCNWHY", T30_ERR_RX_DCNWHY},
|
||||||
|
{"RX_DCNDATA", T30_ERR_RX_DCNDATA},
|
||||||
|
{"RX_DCNFAX", T30_ERR_RX_DCNFAX},
|
||||||
|
{"RX_DCNPHD", T30_ERR_RX_DCNPHD},
|
||||||
|
{"RX_DCNRRD", T30_ERR_RX_DCNRRD},
|
||||||
|
{"RX_DCNNORTN", T30_ERR_RX_DCNNORTN},
|
||||||
|
{"FILEERROR", T30_ERR_FILEERROR},
|
||||||
|
{"NOPAGE", T30_ERR_NOPAGE},
|
||||||
|
{"BADTIFF", T30_ERR_BADTIFF},
|
||||||
|
{"BADPAGE", T30_ERR_BADPAGE},
|
||||||
|
{"BADTAG", T30_ERR_BADTAG},
|
||||||
|
{"BADTIFFHDR", T30_ERR_BADTIFFHDR},
|
||||||
|
{"NOMEM", T30_ERR_NOMEM},
|
||||||
|
{"RETRYDCN", T30_ERR_RETRYDCN},
|
||||||
|
{"CALLDROPPED", T30_ERR_CALLDROPPED},
|
||||||
|
{"NOPOLL", T30_ERR_NOPOLL},
|
||||||
|
{"IDENT_UNACCEPTABLE", T30_ERR_IDENT_UNACCEPTABLE},
|
||||||
|
{"SUB_UNACCEPTABLE", T30_ERR_SUB_UNACCEPTABLE},
|
||||||
|
{"SEP_UNACCEPTABLE", T30_ERR_SEP_UNACCEPTABLE},
|
||||||
|
{"PSA_UNACCEPTABLE", T30_ERR_PSA_UNACCEPTABLE},
|
||||||
|
{"SID_UNACCEPTABLE", T30_ERR_SID_UNACCEPTABLE},
|
||||||
|
{"PWD_UNACCEPTABLE", T30_ERR_PWD_UNACCEPTABLE},
|
||||||
|
{"TSA_UNACCEPTABLE", T30_ERR_TSA_UNACCEPTABLE},
|
||||||
|
{"IRA_UNACCEPTABLE", T30_ERR_IRA_UNACCEPTABLE},
|
||||||
|
{"CIA_UNACCEPTABLE", T30_ERR_CIA_UNACCEPTABLE},
|
||||||
|
{"ISP_UNACCEPTABLE", T30_ERR_ISP_UNACCEPTABLE},
|
||||||
|
{"CSA_UNACCEPTABLE", T30_ERR_CSA_UNACCEPTABLE},
|
||||||
|
{NULL, -1}
|
||||||
|
};
|
||||||
|
|
||||||
static int phase_b_handler(void *user_data, int result)
|
static int phase_b_handler(void *user_data, int result)
|
||||||
{
|
{
|
||||||
@ -622,6 +699,7 @@ static int next_step(faxtester_state_t *s)
|
|||||||
xmlChar *bad_rows;
|
xmlChar *bad_rows;
|
||||||
xmlChar *crc_error;
|
xmlChar *crc_error;
|
||||||
xmlChar *pattern;
|
xmlChar *pattern;
|
||||||
|
xmlChar *timein;
|
||||||
xmlChar *timeout;
|
xmlChar *timeout;
|
||||||
xmlChar *min_bits;
|
xmlChar *min_bits;
|
||||||
xmlChar *frame_size;
|
xmlChar *frame_size;
|
||||||
@ -638,12 +716,12 @@ static int next_step(faxtester_state_t *s)
|
|||||||
int ecm_frame_size;
|
int ecm_frame_size;
|
||||||
int ecm_block;
|
int ecm_block;
|
||||||
int compression_type;
|
int compression_type;
|
||||||
int timer;
|
|
||||||
int len;
|
int len;
|
||||||
t4_tx_state_t t4_tx_state;
|
t4_tx_state_t t4_tx_state;
|
||||||
t30_state_t *t30;
|
t30_state_t *t30;
|
||||||
|
t30_stats_t t30_stats;
|
||||||
|
|
||||||
test_for_call_drop = false;
|
test_for_call_clear = false;
|
||||||
if (s->cur == NULL)
|
if (s->cur == NULL)
|
||||||
{
|
{
|
||||||
if (!s->final_delayed)
|
if (!s->final_delayed)
|
||||||
@ -677,6 +755,7 @@ static int next_step(faxtester_state_t *s)
|
|||||||
bad_rows = xmlGetProp(s->cur, (const xmlChar *) "bad_rows");
|
bad_rows = xmlGetProp(s->cur, (const xmlChar *) "bad_rows");
|
||||||
crc_error = xmlGetProp(s->cur, (const xmlChar *) "crc_error");
|
crc_error = xmlGetProp(s->cur, (const xmlChar *) "crc_error");
|
||||||
pattern = xmlGetProp(s->cur, (const xmlChar *) "pattern");
|
pattern = xmlGetProp(s->cur, (const xmlChar *) "pattern");
|
||||||
|
timein = xmlGetProp(s->cur, (const xmlChar *) "timein");
|
||||||
timeout = xmlGetProp(s->cur, (const xmlChar *) "timeout");
|
timeout = xmlGetProp(s->cur, (const xmlChar *) "timeout");
|
||||||
min_bits = xmlGetProp(s->cur, (const xmlChar *) "min_bits");
|
min_bits = xmlGetProp(s->cur, (const xmlChar *) "min_bits");
|
||||||
frame_size = xmlGetProp(s->cur, (const xmlChar *) "frame_size");
|
frame_size = xmlGetProp(s->cur, (const xmlChar *) "frame_size");
|
||||||
@ -687,26 +766,31 @@ static int next_step(faxtester_state_t *s)
|
|||||||
|
|
||||||
span_log(&s->logging,
|
span_log(&s->logging,
|
||||||
SPAN_LOG_FLOW,
|
SPAN_LOG_FLOW,
|
||||||
"Dir - %s, type - %s, modem - %s, value - %s, timeout - %s, tag - %s\n",
|
"Dir - %s, type - %s, modem - %s, value - %s, timein - %s, timeout - %s, tag - %s\n",
|
||||||
(dir) ? (const char *) dir : "",
|
(dir) ? (const char *) dir : "",
|
||||||
(type) ? (const char *) type : "",
|
(type) ? (const char *) type : "",
|
||||||
(modem) ? (const char *) modem : "",
|
(modem) ? (const char *) modem : "",
|
||||||
(value) ? (const char *) value : "",
|
(value) ? (const char *) value : "",
|
||||||
|
(timein) ? (const char *) timein : "",
|
||||||
(timeout) ? (const char *) timeout : "",
|
(timeout) ? (const char *) timeout : "",
|
||||||
(tag) ? (const char *) tag : "");
|
(tag) ? (const char *) tag : "");
|
||||||
if (type == NULL)
|
if (type == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
if (timeout)
|
if (timein)
|
||||||
timer = atoi((const char *) timeout);
|
timein_x = atoi((const char *) timein);
|
||||||
else
|
else
|
||||||
timer = -1;
|
timein_x = -1;
|
||||||
|
if (timeout)
|
||||||
|
timeout_x = atoi((const char *) timeout);
|
||||||
|
else
|
||||||
|
timeout_x = -1;
|
||||||
|
|
||||||
if (dir && strcasecmp((const char *) dir, "R") == 0)
|
if (dir && strcasecmp((const char *) dir, "R") == 0)
|
||||||
{
|
{
|
||||||
/* Receive always has a timeout applied. */
|
/* Receive always has a timeout applied. */
|
||||||
if (timer < 0)
|
if (timeout_x < 0)
|
||||||
timer = 7000;
|
timeout_x = 7000;
|
||||||
faxtester_set_timeout(s, timer);
|
faxtester_set_timeout(s, timeout_x);
|
||||||
if (modem)
|
if (modem)
|
||||||
{
|
{
|
||||||
hdlc = (strcasecmp((const char *) type, "PREAMBLE") == 0);
|
hdlc = (strcasecmp((const char *) type, "PREAMBLE") == 0);
|
||||||
@ -801,10 +885,11 @@ static int next_step(faxtester_state_t *s)
|
|||||||
{
|
{
|
||||||
faxtest_set_rx_silence(s);
|
faxtest_set_rx_silence(s);
|
||||||
}
|
}
|
||||||
else if (strcasecmp((const char *) type, "DROPCALL") == 0)
|
else if (strcasecmp((const char *) type, "CLEAR") == 0)
|
||||||
{
|
{
|
||||||
span_log(&s->logging, SPAN_LOG_FLOW, "Far end should drop the call\n");
|
span_log(&s->logging, SPAN_LOG_FLOW, "Far end should drop the call\n");
|
||||||
test_for_call_drop = true;
|
test_for_call_clear = true;
|
||||||
|
call_clear_timer = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -814,7 +899,7 @@ static int next_step(faxtester_state_t *s)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
faxtester_set_timeout(s, timer);
|
faxtester_set_timeout(s, timeout_x);
|
||||||
if (modem)
|
if (modem)
|
||||||
{
|
{
|
||||||
hdlc = (strcasecmp((const char *) type, "PREAMBLE") == 0);
|
hdlc = (strcasecmp((const char *) type, "PREAMBLE") == 0);
|
||||||
@ -1117,9 +1202,35 @@ static int next_step(faxtester_state_t *s)
|
|||||||
span_log(&s->logging, SPAN_LOG_FLOW, "ECM image is %d bytes (min row bits %d)\n", len, min_row_bits);
|
span_log(&s->logging, SPAN_LOG_FLOW, "ECM image is %d bytes (min row bits %d)\n", len, min_row_bits);
|
||||||
faxtester_set_ecm_image_buffer(s, image, len, ecm_block, ecm_frame_size, i);
|
faxtester_set_ecm_image_buffer(s, image, len, ecm_block, ecm_frame_size, i);
|
||||||
}
|
}
|
||||||
else if (strcasecmp((const char *) type, "DROPCALL") == 0)
|
else if (strcasecmp((const char *) type, "CLEAR") == 0)
|
||||||
{
|
{
|
||||||
span_log(&s->logging, SPAN_LOG_FLOW, "Time to drop the call\n");
|
span_log(&s->logging, SPAN_LOG_FLOW, "Time to drop the call\n");
|
||||||
|
t30 = fax_get_t30_state(fax);
|
||||||
|
t30_terminate(t30);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (strcasecmp((const char *) type, "STATUS") == 0)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
for (i = 0; t30_status[i].code >= 0; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(t30_status[i].tag, (const char *) value) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (t30_status[i].code >= 0)
|
||||||
|
delay = t30_status[i].code;
|
||||||
|
else
|
||||||
|
delay = atoi((const char *) value);
|
||||||
|
t30 = fax_get_t30_state(fax);
|
||||||
|
t30_get_transfer_statistics(t30, &t30_stats);
|
||||||
|
span_log(&s->logging, SPAN_LOG_FLOW, "Expect status %d. Got %d\n", delay, t30_stats.current_status);
|
||||||
|
if (delay != t30_stats.current_status)
|
||||||
|
{
|
||||||
|
printf("Test failed\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1211,12 +1322,23 @@ static void exchange(faxtester_state_t *s)
|
|||||||
/*endif*/
|
/*endif*/
|
||||||
}
|
}
|
||||||
/*endif*/
|
/*endif*/
|
||||||
if (test_for_call_drop)
|
if (test_for_call_clear && !far_end_cleared_call)
|
||||||
{
|
{
|
||||||
|
call_clear_timer += len;
|
||||||
if (!t30_call_active(fax_get_t30_state(fax)))
|
if (!t30_call_active(fax_get_t30_state(fax)))
|
||||||
{
|
{
|
||||||
printf("Call dropped\n");
|
span_log(&s->logging, SPAN_LOG_FLOW, "Far end cleared after %dms (limits %dms to %dms)\n", call_clear_timer/8, timein_x, timeout_x);
|
||||||
//break;
|
if (call_clear_timer/8 < timein_x || call_clear_timer/8 > timeout_x)
|
||||||
|
{
|
||||||
|
printf("Test failed\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
span_log(&s->logging, SPAN_LOG_FLOW, "Clear time OK\n");
|
||||||
|
far_end_cleared_call = true;
|
||||||
|
test_for_call_clear = false;
|
||||||
|
while (next_step(s) == 0)
|
||||||
|
;
|
||||||
|
/*endwhile*/
|
||||||
}
|
}
|
||||||
/*endif*/
|
/*endif*/
|
||||||
}
|
}
|
||||||
@ -1297,29 +1419,37 @@ static int parse_test_group(faxtester_state_t *s, xmlDocPtr doc, xmlNsPtr ns, xm
|
|||||||
|
|
||||||
static int get_test_set(faxtester_state_t *s, const char *test_file, const char *test)
|
static int get_test_set(faxtester_state_t *s, const char *test_file, const char *test)
|
||||||
{
|
{
|
||||||
|
xmlParserCtxtPtr ctxt;
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNsPtr ns;
|
xmlNsPtr ns;
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
xmlValidCtxt valid;
|
|
||||||
|
|
||||||
ns = NULL;
|
ns = NULL;
|
||||||
xmlKeepBlanksDefault(0);
|
xmlKeepBlanksDefault(0);
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
if ((doc = xmlParseFile(test_file)) == NULL)
|
|
||||||
|
if ((ctxt = xmlNewParserCtxt()) == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "No document\n");
|
fprintf(stderr, "Failed to allocate parser context\n");
|
||||||
printf("Test failed\n");
|
printf("Test failed\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
/*endif*/
|
/* parse the file, activating the DTD validation option */
|
||||||
xmlXIncludeProcess(doc);
|
if ((doc = xmlCtxtReadFile(ctxt, test_file, NULL, XML_PARSE_XINCLUDE | XML_PARSE_DTDVALID)) == NULL)
|
||||||
if (!xmlValidateDocument(&valid, doc))
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid document\n");
|
fprintf(stderr, "Failed to read the XML document\n");
|
||||||
printf("Test failed\n");
|
printf("Test failed\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
/*endif*/
|
if (ctxt->valid == 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to validate the XML document\n");
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
printf("Test failed\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
|
||||||
/* Check the document is of the right kind */
|
/* Check the document is of the right kind */
|
||||||
if ((cur = xmlDocGetRootElement(doc)) == NULL)
|
if ((cur = xmlDocGetRootElement(doc)) == NULL)
|
||||||
|
@ -38,8 +38,7 @@ done
|
|||||||
#MRGN16 fails because we don't adequately distinguish between receiving a
|
#MRGN16 fails because we don't adequately distinguish between receiving a
|
||||||
#bad image signal and receiving none at all.
|
#bad image signal and receiving none at all.
|
||||||
|
|
||||||
#for TEST in MRGN09 MRGN10 MRGN11 MRGN12 MRGN13 MRGN14 MRGN15 MRGN16 MRGN17
|
for TEST in MRGN09 MRGN10 MRGN11 MRGN12 MRGN13 MRGN14 MRGN15 MRGN16 MRGN17
|
||||||
for TEST in MRGN09 MRGN10 MRGN11 MRGN12 MRGN13 MRGN15 MRGN17
|
|
||||||
do
|
do
|
||||||
run_tsb85_test
|
run_tsb85_test
|
||||||
done
|
done
|
||||||
@ -58,8 +57,7 @@ done
|
|||||||
# MRGX05 is failing because we don't distinguish MPS immediately after MCF from MPS after
|
# MRGX05 is failing because we don't distinguish MPS immediately after MCF from MPS after
|
||||||
# a corrupt image signal.
|
# a corrupt image signal.
|
||||||
|
|
||||||
#for TEST in MRGX01 MRGX02 MRGX03 MRGX04 MRGX05 MRGX06 MRGX07 MRGX08
|
for TEST in MRGX01 MRGX02 MRGX03 MRGX04 MRGX05 MRGX06 MRGX07 MRGX08
|
||||||
for TEST in MRGX01 MRGX02 MRGX04 MRGX06 MRGX07 MRGX08
|
|
||||||
do
|
do
|
||||||
run_tsb85_test
|
run_tsb85_test
|
||||||
done
|
done
|
||||||
|
Loading…
x
Reference in New Issue
Block a user