📄 tsx_uas_test.c
字号:
}
if (now.sec > timeout.sec) {
if (!expecting_timeout)
PJ_LOG(3,(THIS_FILE, " Error: test has timed out"));
pjsip_tx_data_dec_ref(tdata);
return TEST_TIMEOUT_ERROR;
}
}
if (test_complete < 0) {
pjsip_transaction *tsx;
tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
if (tsx) {
pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED);
pj_mutex_unlock(tsx->mutex);
flush_events(1000);
}
pjsip_tx_data_dec_ref(tdata);
return test_complete;
}
/* Allow transaction to destroy itself */
flush_events(500);
/* Make sure transaction has been destroyed. */
if (pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE) != NULL) {
PJ_LOG(3,(THIS_FILE, " Error: transaction has not been destroyed"));
pjsip_tx_data_dec_ref(tdata);
return -40;
}
/* Check tdata reference counter. */
if (pj_atomic_get(tdata->ref_cnt) != 1) {
PJ_LOG(3,(THIS_FILE, " Error: tdata reference counter is %d",
pj_atomic_get(tdata->ref_cnt)));
pjsip_tx_data_dec_ref(tdata);
return -50;
}
/* Destroy txdata */
pjsip_tx_data_dec_ref(tdata);
return PJ_SUCCESS;
}
/*****************************************************************************
**
** TEST1_BRANCH_ID: Basic 2xx final response
** TEST2_BRANCH_ID: Basic non-2xx final response
**
*****************************************************************************
*/
static int tsx_basic_final_response_test(void)
{
unsigned duration;
int status;
PJ_LOG(3,(THIS_FILE," test1: basic sending 2xx final response"));
/* Test duration must be greater than 32 secs if unreliable transport
* is used.
*/
duration = (tp_flag & PJSIP_TRANSPORT_RELIABLE) ? 1 : 33;
status = perform_test(TARGET_URI, FROM_URI, TEST1_BRANCH_ID,
duration, &pjsip_options_method, 1, 0, 0);
if (status != 0)
return status;
PJ_LOG(3,(THIS_FILE," test2: basic sending non-2xx final response"));
status = perform_test(TARGET_URI, FROM_URI, TEST2_BRANCH_ID,
duration, &pjsip_options_method, 1, 0, 0);
if (status != 0)
return status;
return 0;
}
/*****************************************************************************
**
** TEST3_BRANCH_ID: Sending provisional response
**
*****************************************************************************
*/
static int tsx_basic_provisional_response_test(void)
{
unsigned duration;
int status;
PJ_LOG(3,(THIS_FILE," test3: basic sending 2xx final response"));
duration = (tp_flag & PJSIP_TRANSPORT_RELIABLE) ? 1 : 33;
duration += 2;
status = perform_test(TARGET_URI, FROM_URI, TEST3_BRANCH_ID, duration,
&pjsip_options_method, 1, 0, 0);
return status;
}
/*****************************************************************************
**
** TEST4_BRANCH_ID: Absorbs retransmissions in TRYING state
** TEST5_BRANCH_ID: Absorbs retransmissions in PROCEEDING state
** TEST6_BRANCH_ID: Absorbs retransmissions in COMPLETED state
**
*****************************************************************************
*/
static int tsx_retransmit_last_response_test(const char *title,
char *branch_id,
int request_cnt,
int status_code)
{
int status;
PJ_LOG(3,(THIS_FILE," %s", title));
status = perform_test(TARGET_URI, FROM_URI, branch_id, 5,
&pjsip_options_method,
request_cnt, 1000, 1);
if (status && status != TEST_TIMEOUT_ERROR)
return status;
if (!status) {
PJ_LOG(3,(THIS_FILE, " error: expecting timeout"));
return -31;
}
terminate_our_tsx(status_code);
flush_events(100);
if (test_complete != 1)
return test_complete;
flush_events(100);
return 0;
}
/*****************************************************************************
**
** TEST7_BRANCH_ID: INVITE non-2xx final response retransmission test
** TEST8_BRANCH_ID: INVITE 2xx final response retransmission test
**
*****************************************************************************
*/
static int tsx_final_response_retransmission_test(void)
{
int status;
PJ_LOG(3,(THIS_FILE,
" test7: INVITE non-2xx final response retransmission"));
status = perform_test(TARGET_URI, FROM_URI, TEST7_BRANCH_ID,
33, /* Test duration must be greater than 32 secs */
&pjsip_invite_method, 1, 0, 0);
if (status != 0)
return status;
PJ_LOG(3,(THIS_FILE,
" test8: INVITE 2xx final response retransmission"));
status = perform_test(TARGET_URI, FROM_URI, TEST8_BRANCH_ID,
33, /* Test duration must be greater than 32 secs */
&pjsip_invite_method, 1, 0, 0);
if (status != 0)
return status;
return 0;
}
/*****************************************************************************
**
** TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
** cease when ACK is received
**
*****************************************************************************
*/
static int tsx_ack_test(void)
{
int status;
PJ_LOG(3,(THIS_FILE,
" test9: receiving ACK for non-2xx final response"));
status = perform_test(TARGET_URI, FROM_URI, TEST9_BRANCH_ID,
20, /* allow 5 retransmissions */
&pjsip_invite_method, 1, 0, 0);
if (status != 0)
return status;
return 0;
}
/*****************************************************************************
**
** TEST10_BRANCH_ID: test transport failure in TRYING state.
** TEST11_BRANCH_ID: test transport failure in PROCEEDING state.
** TEST12_BRANCH_ID: test transport failure in CONNECTED state.
** TEST13_BRANCH_ID: test transport failure in CONFIRMED state.
**
*****************************************************************************
*/
static int tsx_transport_failure_test(void)
{
struct test_desc
{
int transport_delay;
int fail_delay;
char *branch_id;
char *title;
} tests[] =
{
{ 0, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (no delay)" },
{ 50, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (50 ms delay)" },
{ 0, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (no delay)" },
{ 50, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (50 ms delay)" },
{ 0, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (no delay)" },
{ 50, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (50 ms delay)" },
};
int i, status;
for (i=0; i<PJ_ARRAY_SIZE(tests); ++i) {
pj_time_val fail_time, end_test, now;
PJ_LOG(3,(THIS_FILE, " %s", tests[i].title));
pjsip_loop_set_failure(loop, 0, NULL);
pjsip_loop_set_delay(loop, tests[i].transport_delay);
status = perform_test(TARGET_URI, FROM_URI, tests[i].branch_id,
0, &pjsip_invite_method, 1, 0, 1);
if (status && status != TEST_TIMEOUT_ERROR)
return status;
if (!status) {
PJ_LOG(3,(THIS_FILE, " error: expecting timeout"));
return -40;
}
pj_gettimeofday(&fail_time);
fail_time.msec += tests[i].fail_delay;
pj_time_val_normalize(&fail_time);
do {
pj_time_val interval = { 0, 1 };
pj_gettimeofday(&now);
pjsip_endpt_handle_events(endpt, &interval);
} while (PJ_TIME_VAL_LT(now, fail_time));
pjsip_loop_set_failure(loop, 1, NULL);
end_test = now;
end_test.sec += 5;
do {
pj_time_val interval = { 0, 1 };
pj_gettimeofday(&now);
pjsip_endpt_handle_events(endpt, &interval);
} while (!test_complete && PJ_TIME_VAL_LT(now, end_test));
if (test_complete == 0) {
PJ_LOG(3,(THIS_FILE, " error: test has timed out"));
return -41;
}
if (test_complete != 1)
return test_complete;
}
return 0;
}
/*****************************************************************************
**
** UAS Transaction Test.
**
*****************************************************************************
*/
int tsx_uas_test(struct tsx_test_param *param)
{
pj_sockaddr_in addr;
pj_status_t status;
test_param = param;
tp_flag = pjsip_transport_get_flag_from_type(param->type);
pj_ansi_sprintf(TARGET_URI, "sip:bob@127.0.0.1:%d;transport=%s",
param->port, param->tp_type);
pj_ansi_sprintf(FROM_URI, "sip:alice@127.0.0.1:%d;transport=%s",
param->port, param->tp_type);
/* Check if loop transport is configured. */
status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM,
&addr, sizeof(addr), NULL, &loop);
if (status != PJ_SUCCESS) {
PJ_LOG(3,(THIS_FILE, " Error: loop transport is not configured!"));
return -10;
}
/* Register modules. */
status = pjsip_endpt_register_module(endpt, &tsx_user);
if (status != PJ_SUCCESS) {
app_perror(" Error: unable to register module", status);
return -3;
}
status = pjsip_endpt_register_module(endpt, &msg_sender);
if (status != PJ_SUCCESS) {
app_perror(" Error: unable to register module", status);
return -4;
}
/* TEST1_BRANCH_ID: Basic 2xx final response.
* TEST2_BRANCH_ID: Basic non-2xx final response.
*/
status = tsx_basic_final_response_test();
if (status != 0)
return status;
/* TEST3_BRANCH_ID: with provisional response
*/
status = tsx_basic_provisional_response_test();
if (status != 0)
return status;
/* TEST4_BRANCH_ID: absorbs retransmissions in TRYING state
*/
status = tsx_retransmit_last_response_test(TEST4_TITLE,
TEST4_BRANCH_ID,
TEST4_REQUEST_COUNT,
TEST4_STATUS_CODE);
if (status != 0)
return status;
/* TEST5_BRANCH_ID: retransmit last response in PROCEEDING state
*/
status = tsx_retransmit_last_response_test(TEST5_TITLE,
TEST5_BRANCH_ID,
TEST5_REQUEST_COUNT,
TEST5_STATUS_CODE);
if (status != 0)
return status;
/* TEST6_BRANCH_ID: retransmit last response in COMPLETED state
* This only applies to non-reliable transports,
* since UAS transaction is destroyed as soon
* as final response is sent for reliable transports.
*/
if ((tp_flag & PJSIP_TRANSPORT_RELIABLE) == 0) {
status = tsx_retransmit_last_response_test(TEST6_TITLE,
TEST6_BRANCH_ID,
TEST6_REQUEST_COUNT,
TEST6_STATUS_CODE);
if (status != 0)
return status;
}
/* TEST7_BRANCH_ID: INVITE non-2xx final response retransmission test
* TEST8_BRANCH_ID: INVITE 2xx final response retransmission test
*/
status = tsx_final_response_retransmission_test();
if (status != 0)
return status;
/* TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
* cease when ACK is received
* Only applicable for non-reliable transports.
*/
if ((tp_flag & PJSIP_TRANSPORT_RELIABLE) == 0) {
status = tsx_ack_test();
if (status != 0)
return status;
}
/* TEST10_BRANCH_ID: test transport failure in TRYING state.
* TEST11_BRANCH_ID: test transport failure in PROCEEDING state.
* TEST12_BRANCH_ID: test transport failure in CONNECTED state.
* TEST13_BRANCH_ID: test transport failure in CONFIRMED state.
*/
/* Only valid for loop-dgram */
if (param->type == PJSIP_TRANSPORT_LOOP_DGRAM) {
status = tsx_transport_failure_test();
if (status != 0)
return status;
}
/* Register modules. */
status = pjsip_endpt_unregister_module(endpt, &tsx_user);
if (status != PJ_SUCCESS) {
app_perror(" Error: unable to unregister module", status);
return -8;
}
status = pjsip_endpt_unregister_module(endpt, &msg_sender);
if (status != PJ_SUCCESS) {
app_perror(" Error: unable to unregister module", status);
return -9;
}
if (loop)
pjsip_transport_dec_ref(loop);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -