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

📄 tsx_uac_test.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: tsx_uac_test.c 974 2007-02-19 01:13:53Z bennylp $ */
/* 
 * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */

#include "test.h"
#include <pjsip.h>
#include <pjlib.h>

#define THIS_FILE   "tsx_uac_test.c"


/*****************************************************************************
 **
 ** UAC tests.
 **
 ** This file performs various tests for UAC transactions. Each test will have
 ** a different Via branch param so that message receiver module and 
 ** transaction user module can identify which test is being carried out.
 **
 ** TEST1_BRANCH_ID
 **	Perform basic retransmission and timeout test. Message receiver will
 **	verify that retransmission is received at correct time.
 **     This test verifies the following requirements:
 **	    - retransmit timer doubles for INVITE
 **	    - retransmit timer doubles and caps off for non-INVITE
 **	    - retransmit timer timer is precise
 **	    - correct timeout and retransmission count
 **     Requirements not tested:
 **	    - retransmit timer only starts after resolving has completed.
 **
 ** TEST2_BRANCH_ID
 **	Test scenario where resolver is unable to resolve destination host.
 **
 ** TEST3_BRANCH_ID
 **	Test scenario where transaction is terminated while resolver is still
 **	running.
 **
 ** TEST4_BRANCH_ID
 **	Test scenario where transport failed after several retransmissions.
 **
 ** TEST5_BRANCH_ID
 **	Test scenario where transaction is terminated by user after several
 **	retransmissions.
 **
 ** TEST6_BRANCH_ID
 **	Test successfull non-INVITE transaction.
 **     It tests the following requirements:
 **	    - transaction correctly moves to COMPLETED state.
 **	    - retransmission must cease.
 **	    - tx_data must be maintained until state is terminated.
 **
 ** TEST7_BRANCH_ID
 **	Test successfull non-INVITE transaction, with provisional response.
 **
 ** TEST8_BRANCH_ID
 **	Test failed INVITE transaction (e.g. ACK must be received)
 **
 ** TEST9_BRANCH_ID
 **	Test failed INVITE transaction with provisional response.
 **
 **	
 *****************************************************************************
 */

static char *TEST1_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAC-Test1";
static char *TEST2_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAC-Test2";
static char *TEST3_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAC-Test3";
static char *TEST4_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAC-Test4";
static char *TEST5_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAC-Test5";
static char *TEST6_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAC-Test6";
static char *TEST7_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAC-Test7";
static char *TEST8_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAC-Test8";
static char *TEST9_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAC-Test9";

#define      TEST1_ALLOWED_DIFF	    (150)
#define      TEST4_RETRANSMIT_CNT   3
#define	     TEST5_RETRANSMIT_CNT   3

static char TARGET_URI[128];
static char FROM_URI[128];
static unsigned tp_flag;
static struct tsx_test_param *test_param;

static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e);
static pj_bool_t msg_receiver_on_rx_request(pjsip_rx_data *rdata);

/* UAC transaction user module. */
static pjsip_module tsx_user = 
{
    NULL, NULL,				/* prev and next	*/
    { "Tsx-UAC-User", 12},		/* Name.		*/
    -1,					/* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION-1,	/* Priority		*/
    NULL,				/* load()		*/
    NULL,				/* start()		*/
    NULL,				/* stop()		*/
    NULL,				/* unload()		*/
    NULL,				/* on_rx_request()	*/
    NULL,				/* on_rx_response()	*/
    NULL,				/* on_tx_request()	*/
    NULL,				/* on_tx_response()	*/
    &tsx_user_on_tsx_state,		/* on_tsx_state()	*/
};

/* Module to receive the loop-backed request. */
static pjsip_module msg_receiver = 
{
    NULL, NULL,				/* prev and next	*/
    { "Msg-Receiver", 12},		/* Name.		*/
    -1,					/* Id			*/
    PJSIP_MOD_PRIORITY_APPLICATION-1,	/* Priority		*/
    NULL,				/* load()		*/
    NULL,				/* start()		*/
    NULL,				/* stop()		*/
    NULL,				/* unload()		*/
    &msg_receiver_on_rx_request,	/* on_rx_request()	*/
    NULL,				/* on_rx_response()	*/
    NULL,				/* on_tx_request()	*/
    NULL,				/* on_tx_response()	*/
    NULL,				/* on_tsx_state()	*/
};

/* Static vars, which will be reset on each test. */
static int recv_count;
static pj_time_val recv_last;
static pj_bool_t test_complete;

/* Loop transport instance. */
static pjsip_transport *loop;

/* General timer entry to be used by tests. */
static struct my_timer
{
    pj_timer_entry  entry;
    char	    key_buf[1024];
    pj_str_t	    tsx_key;
} timer;

/*
 * This is the handler to receive state changed notification from the
 * transaction. It is used to verify that the transaction behaves according
 * to the test scenario.
 */
static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
{
    if (pj_strcmp2(&tsx->branch, TEST1_BRANCH_ID)==0) {
	/*
	 * Transaction with TEST1_BRANCH_ID should terminate with transaction
	 * timeout status.
	 */
	if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {

	    if (test_complete == 0)
		test_complete = 1;

	    /* Test the status code. */
	    if (tsx->status_code != PJSIP_SC_TSX_TIMEOUT) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: status code is %d instead of %d",
			  tsx->status_code, PJSIP_SC_TSX_TIMEOUT));
		test_complete = -710;
	    }


	    /* If transport is reliable, then there must not be any
	     * retransmissions.
	     */
	    if (tp_flag & PJSIP_TRANSPORT_RELIABLE) {
		if (recv_count != 1) {
		    PJ_LOG(3,(THIS_FILE, 
			   "    error: there were %d (re)transmissions",
			   recv_count));
		    test_complete = -715;
		}
	    } else {
		/* Check the number of transmissions, which must be
		 * 6 for INVITE and 10 for non-INVITE 
		 */
		if (tsx->method.id==PJSIP_INVITE_METHOD && recv_count != 7) {
		    PJ_LOG(3,(THIS_FILE, 
			   "    error: there were %d (re)transmissions",
			   recv_count));
		    test_complete = -716;
		} else
		if (tsx->method.id==PJSIP_OPTIONS_METHOD && recv_count != 11) {
		    PJ_LOG(3,(THIS_FILE, 
			   "    error: there were %d (re)transmissions",
			   recv_count));
		    test_complete = -717;
		} else
		if (tsx->method.id!=PJSIP_INVITE_METHOD && 
		    tsx->method.id!=PJSIP_OPTIONS_METHOD)
		{
		    PJ_LOG(3,(THIS_FILE, "    error: unexpected method"));
		    test_complete = -718;
		}
	    }
	}

    } else if (pj_strcmp2(&tsx->branch, TEST2_BRANCH_ID)==0) {
	/*
	 * Transaction with TEST2_BRANCH_ID should terminate with transport error.
	 */
	if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {

	    /* Test the status code. */
	    if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: status code is %d instead of %d",
			  tsx->status_code, PJSIP_SC_TSX_TRANSPORT_ERROR));
		test_complete = -720;
	    }

	    if (test_complete == 0)
		test_complete = 1;
	}

    } else if (pj_strcmp2(&tsx->branch, TEST3_BRANCH_ID)==0) {
	/*
	 * This test terminates the transaction while resolver is still
	 * running. 
	 */
	if (tsx->state == PJSIP_TSX_STATE_CALLING) {

	    /* Terminate the transaction. */
	    pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED);

	} else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {

	    /* Check if status code is correct. */
	    if (tsx->status_code != PJSIP_SC_REQUEST_TERMINATED) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: status code is %d instead of %d",
			  tsx->status_code, PJSIP_SC_REQUEST_TERMINATED));
		test_complete = -730;
	    }

	    if (test_complete == 0)
		test_complete = 1;

	}

    } else if (pj_strcmp2(&tsx->branch, TEST4_BRANCH_ID)==0) {
	/* 
	 * This test simulates transport failure after several 
	 * retransmissions.
	 */
	if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {

	    /* Status code must be transport error. */
	    if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: status code is %d instead of %d",
			  tsx->status_code, PJSIP_SC_TSX_TRANSPORT_ERROR));
		test_complete = -730;
	    }

	    /* Must have correct retransmission count. */
	    if (tsx->retransmit_count != TEST4_RETRANSMIT_CNT) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: retransmit cnt is %d instead of %d",
			  tsx->retransmit_count, TEST4_RETRANSMIT_CNT));
		test_complete = -731;
	    }

	    if (test_complete == 0)
		test_complete = 1;
	}


    } else if (pj_strcmp2(&tsx->branch, TEST5_BRANCH_ID)==0) {
	/* 
	 * This test simulates transport failure after several 
	 * retransmissions.
	 */
	if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {

	    /* Status code must be PJSIP_SC_REQUEST_TERMINATED. */
	    if (tsx->status_code != PJSIP_SC_REQUEST_TERMINATED) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: status code is %d instead of %d",
			  tsx->status_code, PJSIP_SC_REQUEST_TERMINATED));
		test_complete = -733;
	    }

	    /* Must have correct retransmission count. */
	    if (tsx->retransmit_count != TEST5_RETRANSMIT_CNT) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: retransmit cnt is %d instead of %d",
			  tsx->retransmit_count, TEST5_RETRANSMIT_CNT));
		test_complete = -734;
	    }

	    if (test_complete == 0)
		test_complete = 1;
	}


    } else if (pj_strcmp2(&tsx->branch, TEST6_BRANCH_ID)==0) {
	/* 
	 * Successfull non-INVITE transaction.
	 */
	if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {

	    /* Status code must be 202. */
	    if (tsx->status_code != 202) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: status code is %d instead of %d",
			  tsx->status_code, 202));
		test_complete = -736;
	    }

	    /* Must have correct retransmission count. */
	    if (tsx->retransmit_count != 0) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: retransmit cnt is %d instead of %d",
			  tsx->retransmit_count, 0));
		test_complete = -737;
	    }

	    /* Must still keep last_tx */
	    if (tsx->last_tx == NULL) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: transaction lost last_tx"));
		test_complete = -738;
	    }

	    if (test_complete == 0) {
		test_complete = 1;
		pjsip_tsx_terminate(tsx, 202);
	    }

	} else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {

	    /* Previous state must be COMPLETED. */
	    if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
		test_complete = -7381;
	    }

	}

    } else if (pj_strcmp2(&tsx->branch, TEST7_BRANCH_ID)==0) {
	/* 
	 * Successfull non-INVITE transaction.
	 */
	if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {

	    /* Check prev state. */
	    if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_PROCEEDING) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: prev state is %s instead of %s",
			  pjsip_tsx_state_str(e->body.tsx_state.prev_state),
			  pjsip_tsx_state_str(PJSIP_TSX_STATE_PROCEEDING)));
		test_complete = -739;
	    }

	    /* Status code must be 202. */
	    if (tsx->status_code != 202) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: status code is %d instead of %d",
			  tsx->status_code, 202));
		test_complete = -740;
	    }

	    /* Must have correct retransmission count. */
	    if (tsx->retransmit_count != 0) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: retransmit cnt is %d instead of %d",
			  tsx->retransmit_count, 0));
		test_complete = -741;
	    }

	    /* Must still keep last_tx */
	    if (tsx->last_tx == NULL) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: transaction lost last_tx"));
		test_complete = -741;
	    }

	    if (test_complete == 0) {
		test_complete = 1;
		pjsip_tsx_terminate(tsx, 202);
	    }

	} else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {

	    /* Previous state must be COMPLETED. */
	    if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
		test_complete = -742;
	    }

	}


    } else if (pj_strcmp2(&tsx->branch, TEST8_BRANCH_ID)==0) {
	/* 
	 * Failed INVITE transaction.
	 */
	if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {

	    /* Status code must be 301. */
	    if (tsx->status_code != 301) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: status code is %d instead of %d",
			  tsx->status_code, 301));
		test_complete = -745;
	    }

	    /* Must have correct retransmission count. */
	    if (tsx->retransmit_count != 0) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: retransmit cnt is %d instead of %d",
			  tsx->retransmit_count, 0));
		test_complete = -746;
	    }

	    /* Must still keep last_tx */
	    if (tsx->last_tx == NULL) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: transaction lost last_tx"));
		test_complete = -747;
	    }

	    /* last_tx MUST be the INVITE request
	     * (authorization depends on this behavior)
	     */
	    if (tsx->last_tx && tsx->last_tx->msg->line.req.method.id !=
		PJSIP_INVITE_METHOD)
	    {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: last_tx is not INVITE"));
		test_complete = -748;
	    }
	}
	else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {

	    test_complete = 1;

	    /* Previous state must be COMPLETED. */
	    if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
		test_complete = -750;
	    }

	    /* Status code must be 301. */
	    if (tsx->status_code != 301) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: status code is %d instead of %d",
			  tsx->status_code, 301));
		test_complete = -751;
	    }

	}


    } else if (pj_strcmp2(&tsx->branch, TEST9_BRANCH_ID)==0) {
	/* 
	 * Failed INVITE transaction with provisional response.
	 */
	if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {

	    /* Previous state must be PJSIP_TSX_STATE_PROCEEDING. */
	    if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_PROCEEDING) {
		test_complete = -760;
	    }

	    /* Status code must be 302. */
	    if (tsx->status_code != 302) {
		PJ_LOG(3,(THIS_FILE, 
			  "    error: status code is %d instead of %d",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -