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

📄 tsx_uas_test.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $Id: tsx_uas_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_uas_test.c"/***************************************************************************** ** ** UAS 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 **	Test that non-INVITE transaction returns 2xx response to the correct **	transport and correctly terminates the transaction. **	This also checks that transaction is destroyed immediately after **	it sends final response when reliable transport is used. ** ** TEST2_BRANCH_ID **	As above, for non-2xx final response. ** ** TEST3_BRANCH_ID **	Transaction correctly progressing to PROCEEDING state when provisional **	response is sent. ** ** TEST4_BRANCH_ID **	Transaction retransmits last response (if any) without notifying  **	transaction user upon receiving request  retransmissions on TRYING **	state ** ** TEST5_BRANCH_ID **	As above, in PROCEEDING state. ** ** TEST6_BRANCH_ID **	As above, in COMPLETED state, with first sending provisional response. **	(Only applicable for non-reliable transports). ** ** TEST7_BRANCH_ID **	INVITE transaction MUST retransmit non-2xx final response. ** ** TEST8_BRANCH_ID **	As above, for INVITE's 2xx final response (this is PJSIP specific). ** ** TEST9_BRANCH_ID **	INVITE transaction MUST cease retransmission of final response when **	ACK is received. (Note: PJSIP also retransmit 2xx final response  **	until it's terminated by user). **     Transaction also MUST terminate in T4 seconds. **	(Only applicable for non-reliable transports). ** ** TEST11_BRANCH_ID **	Test scenario where transport fails before response is sent (i.e. **	in TRYING state). ** ** TEST12_BRANCH_ID **	As above, after provisional response is sent but before final **	response is sent (i.e. in PROCEEDING state). ** ** TEST13_BRANCH_ID **	As above, for INVITE, after final response has been sent but before **	ACK is received (i.e. in CONNECTED state). ** ** TEST14_BRANCH_ID **	When UAS failed to deliver the response with the selected transport, **	it should try contacting the client with other transport or begin **	RFC 3263 server resolution procedure. **	This should be tested on: **	    a. TRYING state (when delivering first response). **	    b. PROCEEDING state (when failed to retransmit last response **	       upon receiving request retransmission). **	    c. COMPLETED state. ** **/static char *TEST1_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test1";static char *TEST2_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test2";static char *TEST3_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test3";static char *TEST4_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test4";static char *TEST5_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test5";static char *TEST6_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test6";static char *TEST7_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test7";static char *TEST8_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test8";static char *TEST9_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test9";static char *TEST10_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test10";static char *TEST11_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test11";static char *TEST12_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test12";//static char *TEST13_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test13";#define TEST1_STATUS_CODE	200#define TEST2_STATUS_CODE	301#define TEST3_PROVISIONAL_CODE	PJSIP_SC_QUEUED#define TEST3_STATUS_CODE	202#define TEST4_STATUS_CODE	200#define TEST4_REQUEST_COUNT	2#define TEST5_PROVISIONAL_CODE	100#define TEST5_STATUS_CODE	200	#define TEST5_REQUEST_COUNT	2#define TEST5_RESPONSE_COUNT	2#define TEST6_PROVISIONAL_CODE	100#define TEST6_STATUS_CODE	200	/* Must be final */#define TEST6_REQUEST_COUNT	2#define TEST6_RESPONSE_COUNT	3#define TEST7_STATUS_CODE	301#define TEST8_STATUS_CODE	302#define TEST9_STATUS_CODE	301#define TEST4_TITLE "test4: absorbing request retransmission"#define TEST5_TITLE "test5: retransmit last response in PROCEEDING state"#define TEST6_TITLE "test6: retransmit last response in COMPLETED state"static char TARGET_URI[128];static char FROM_URI[128];static struct tsx_test_param *test_param;static unsigned tp_flag;#define TEST_TIMEOUT_ERROR	-30#define MAX_ALLOWED_DIFF	150static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e);static pj_bool_t on_rx_message(pjsip_rx_data *rdata);/* UAC transaction user module. */static pjsip_module tsx_user = {    NULL, NULL,				/* prev and next	*/    { "Tsx-UAS-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 send request. */static pjsip_module msg_sender = {    NULL, NULL,				/* prev and next	*/    { "Msg-Sender", 10},		/* Name.		*/    -1,					/* Id			*/    PJSIP_MOD_PRIORITY_APPLICATION-1,	/* Priority		*/    NULL,				/* load()		*/    NULL,				/* start()		*/    NULL,				/* stop()		*/    NULL,				/* unload()		*/    &on_rx_message,			/* on_rx_request()	*/    &on_rx_message,			/* 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;/* UAS transaction key. */static char key_buf[64];static pj_str_t tsx_key = { key_buf, 0 };/* General timer entry to be used by tests. *///static pj_timer_entry timer;/* Timer to send response via transaction. */struct response{    pj_str_t	     tsx_key;    pjsip_tx_data   *tdata;};/* Timer callback to send response. */static void send_response_timer( pj_timer_heap_t *timer_heap,				 struct pj_timer_entry *entry){    pjsip_transaction *tsx;    struct response *r = entry->user_data;    pj_status_t status;    tsx = pjsip_tsx_layer_find_tsx(&r->tsx_key, PJ_TRUE);    if (!tsx) {	PJ_LOG(3,(THIS_FILE,"    error: timer unable to find transaction"));	pjsip_tx_data_dec_ref(r->tdata);	return;    }    status = pjsip_tsx_send_msg(tsx, r->tdata);    if (status != PJ_SUCCESS) {	// Some tests do expect failure!	//PJ_LOG(3,(THIS_FILE,"    error: timer unable to send response"));	pj_mutex_unlock(tsx->mutex);	pjsip_tx_data_dec_ref(r->tdata);	return;    }    pj_mutex_unlock(tsx->mutex);}/* Utility to send response. */static void send_response( pjsip_rx_data *rdata,			   pjsip_transaction *tsx,			   int status_code ){    pj_status_t status;    pjsip_tx_data *tdata;    status = pjsip_endpt_create_response( endpt, rdata, status_code, NULL, 					  &tdata);    if (status != PJ_SUCCESS) {	app_perror("    error: unable to create response", status);	test_complete = -196;	return;    }    status = pjsip_tsx_send_msg(tsx, tdata);    if (status != PJ_SUCCESS) {	pjsip_tx_data_dec_ref(tdata);	// Some tests do expect failure!	//app_perror("    error: unable to send response", status);	//test_complete = -197;	return;    }}/* Schedule timer to send response for the specified UAS transaction */static void schedule_send_response( pjsip_rx_data *rdata,				    const pj_str_t *tsx_key,				    int status_code,				    int msec_delay ){    pj_status_t status;    pjsip_tx_data *tdata;    pj_timer_entry *t;    struct response *r;    pj_time_val delay;    status = pjsip_endpt_create_response( endpt, rdata, status_code, NULL, 					  &tdata);    if (status != PJ_SUCCESS) {	app_perror("    error: unable to create response", status);	test_complete = -198;	return;    }    r = pj_pool_alloc(tdata->pool, sizeof(*r));    pj_strdup(tdata->pool, &r->tsx_key, tsx_key);    r->tdata = tdata;    delay.sec = 0;    delay.msec = msec_delay;    pj_time_val_normalize(&delay);    t = pj_pool_zalloc(tdata->pool, sizeof(*t));    t->user_data = r;    t->cb = &send_response_timer;    status = pjsip_endpt_schedule_timer(endpt, t, &delay);    if (status != PJ_SUCCESS) {	pjsip_tx_data_dec_ref(tdata);	app_perror("    error: unable to schedule timer", status);	test_complete = -199;	return;    }}/* Find and terminate tsx with the specified key. */static void terminate_our_tsx(int status_code){    pjsip_transaction *tsx;    tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);    if (!tsx) {	PJ_LOG(3,(THIS_FILE,"    error: timer unable to find transaction"));	return;    }    pjsip_tsx_terminate(tsx, status_code);    pj_mutex_unlock(tsx->mutex);}#if 0	/* Unused for now *//* Timer callback to terminate transaction. */static void terminate_tsx_timer( pj_timer_heap_t *timer_heap,				 struct pj_timer_entry *entry){    terminate_our_tsx(entry->id);}/* Schedule timer to terminate transaction. */static void schedule_terminate_tsx( pjsip_transaction *tsx,				    int status_code,				    int msec_delay ){    pj_time_val delay;    delay.sec = 0;    delay.msec = msec_delay;    pj_time_val_normalize(&delay);    pj_assert(pj_strcmp(&tsx->transaction_key, &tsx_key)==0);    timer.user_data = NULL;    timer.id = status_code;    timer.cb = &terminate_tsx_timer;    pjsip_endpt_schedule_timer(endpt, &timer, &delay);}#endif/* * 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 ||	pj_strcmp2(&tsx->branch, TEST2_BRANCH_ID)==0)     {	/*	 * TEST1_BRANCH_ID tests that non-INVITE transaction transmits final	 * response using correct transport and terminates transaction after	 * T4 (PJSIP_T4_TIMEOUT, 5 seconds).	 *	 * TEST2_BRANCH_ID does similar test for non-2xx final response.	 */	int status_code = (pj_strcmp2(&tsx->branch, TEST1_BRANCH_ID)==0) ?			  TEST1_STATUS_CODE : TEST2_STATUS_CODE;	if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {	    test_complete = 1;	    /* Check that status code is status_code. */	    if (tsx->status_code != status_code) {		PJ_LOG(3,(THIS_FILE, "    error: incorrect status code"));		test_complete = -100;	    }	    	    /* Previous state must be completed. */	    if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {		PJ_LOG(3,(THIS_FILE, "    error: incorrect prev_state"));		test_complete = -101;	    }	} else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {	    /* Previous state must be TRYING. */	    if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {		PJ_LOG(3,(THIS_FILE, "    error: incorrect prev_state"));		test_complete = -102;	    }	}    }    else    if (pj_strcmp2(&tsx->branch, TEST3_BRANCH_ID)==0) {	/*	 * TEST3_BRANCH_ID tests sending provisional response.	 */	if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {	    test_complete = 1;	    /* Check that status code is status_code. */	    if (tsx->status_code != TEST3_STATUS_CODE) {		PJ_LOG(3,(THIS_FILE, "    error: incorrect status code"));		test_complete = -110;	    }	    	    /* Previous state must be completed. */	    if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {		PJ_LOG(3,(THIS_FILE, "    error: incorrect prev_state"));		test_complete = -111;	    }	} else if (tsx->state == PJSIP_TSX_STATE_PROCEEDING) {	    /* Previous state must be TRYING. */

⌨️ 快捷键说明

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