⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tsx_uas_test.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 4 页
字号:
	}

	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 + -