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

📄 siptransactionnoninviteclient.cxx

📁 MiniSip Client with DomainKeys Authentication, Sip, Audio communications, Echo Cancel
💻 CXX
字号:
/*  Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien    This library is free software; you can redistribute it and/or  modify it under the terms of the GNU Lesser General Public  License as published by the Free Software Foundation; either  version 2.1 of the License, or (at your option) any later version.  This library 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  Lesser General Public License for more details.  You should have received a copy of the GNU Lesser General Public  License along with this library; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* * Authors: Erik Eliasson <eliasson@it.kth.se> *          Johan Bilien <jobi@via.ecp.fr>*//* Name * 	SipTransactionNonInviteClient.cxx * Author * 	Erik Eliasson, eliasson@it.kth.se * Purpose * */#include<config.h>#include<libmutil/massert.h>#include<libmsip/SipTransactionNonInviteClient.h>#include<libmsip/SipCommandDispatcher.h>#include<libmsip/SipResponse.h>#include<libmsip/SipTransactionUtils.h>#include<libmsip/SipCommandString.h>#include<libmsip/SipDialog.h>#include<libmsip/SipDialogConfig.h>#include<libmsip/SipTimers.h>#ifdef DEBUG_OUTPUT#include<libmutil/dbg.h>#endifusing namespace std;bool SipTransactionNonInviteClient::a0_start_trying_request( const SipSMCommand &command) {	if (transitionMatch(SipMessage::anyType, command, SipSMCommand::dialog_layer, SipSMCommand::transaction_layer)){#ifdef DEBUG_OUTPUT		setDebugTransType(command.getCommandPacket()->getType() );#endif		lastRequest = dynamic_cast<SipRequest*>(*command.getCommandPacket());		if( isUnreliable() ) {			timerE = sipStack->getTimers()->getE();			requestTimeout(timerE, "timerE");		}		requestTimeout(sipStack->getTimers()->getF(), "timerF");/* TODO/FIXME: This is a bit tricky - we don't know which identity is * currently being used (the getConfig() one will have a null one if * not within a dialog). Maybe the creator of the transaction should * explicitely add a route set instead of implicitely specifying it always? * -EE 		massert(getConfig());		massert(getConfig()->sipIdentity);		MRef<SipProxy*> proxy = getConfig()->sipIdentity->getSipProxy();				if( proxy->sipProxyAddressString.size()>0){			MRef<SipHeaderValue*> hdr;			hdr = lastRequest->getHeaderValueNo( SIP_HEADER_TYPE_ROUTE, 0 );			if( !hdr ){				lastRequest->addRoute( proxy->sipProxyAddressString,						       proxy->sipProxyPort, 						       proxy->getTransport() );			}		}*/		send(*lastRequest,true);				return true;	}else{		return false;	}}bool SipTransactionNonInviteClient::a1_trying_proceeding_1xx( const SipSMCommand &command){		if (transitionMatch(SipResponse::type, command, SipSMCommand::transport_layer,/*IGN*/ SipSMCommand::transaction_layer, "1**")){		cancelTimeout("timerE");		cancelTimeout("timerF");		SipSMCommand cmd(				command.getCommandPacket(), 				SipSMCommand::transaction_layer, 				SipSMCommand::dialog_layer );		dispatcher->enqueueCommand(cmd, HIGH_PRIO_QUEUE/*, PRIO_LAST_IN_QUEUE*/);				return true;	}else{				return false;	}}bool SipTransactionNonInviteClient::a2_trying_terminated_TimerFOrErr( const SipSMCommand &command){		if (transitionMatch(command, SipCommandString::transport_error, SipSMCommand::transport_layer, SipSMCommand::transaction_layer) 			|| transitionMatch(command, "timerF", SipSMCommand::transaction_layer, SipSMCommand::transaction_layer)){		cancelTimeout("timerE");		cancelTimeout("timerF");				SipSMCommand cmd(				CommandString( callId, SipCommandString::transport_error),				SipSMCommand::transaction_layer, 				SipSMCommand::dialog_layer);		dispatcher->enqueueCommand(cmd, HIGH_PRIO_QUEUE/*, PRIO_LAST_IN_QUEUE*/);		SipSMCommand cmdterminated(			CommandString( callId, SipCommandString::transaction_terminated),			SipSMCommand::transaction_layer,			SipSMCommand::dispatcher);		dispatcher->enqueueCommand( cmdterminated, HIGH_PRIO_QUEUE/*, PRIO_FIRST_IN_QUEUE */);						return true;	}else{				return false;	}}bool SipTransactionNonInviteClient::a3_proceeding_completed_non1xxresp( const SipSMCommand &command){	if (transitionMatch(SipResponse::type, command, SipSMCommand::transport_layer, SipSMCommand::transaction_layer, "2**\n3**\n4**\n5**\n6**")){				MRef<SipResponse*> pack((SipResponse *)*command.getCommandPacket());		cancelTimeout("timerE"); //no more retx of the request		if( isUnreliable() ) //response re-tx timer			requestTimeout(sipStack->getTimers()->getT4(),"timerK");		else			requestTimeout(0,"timerK");				//forward to TU		MRef<SipMessage*> pref(*pack);		SipSMCommand cmd(pref, 				SipSMCommand::transaction_layer, 				SipSMCommand::dialog_layer);		dispatcher->enqueueCommand(cmd, HIGH_PRIO_QUEUE/*, PRIO_LAST_IN_QUEUE*/);				return true;	}else{				return false;	}}bool SipTransactionNonInviteClient::a4_proceeding_proceeding_timerE( const SipSMCommand &command){		if (transitionMatch(command, "timerE",SipSMCommand::transaction_layer,SipSMCommand::transaction_layer)){		timerE *= 2;		if( timerE > sipStack->getTimers()->getT2() ) 			timerE = sipStack->getTimers()->getT2();		requestTimeout(timerE,"timerE");		massert(!lastRequest.isNull());		timerE = sipStack->getTimers()->getT2();		requestTimeout(timerE,"timerE");		lastRequest->removeAllViaHeaders();		send( *lastRequest, true);	//add via, we have removed all from previous request				return true;	}else{				return false;	}}bool SipTransactionNonInviteClient::a5_proceeding_proceeding_1xx( const SipSMCommand &command){		if (transitionMatch(SipResponse::type, command, SipSMCommand::transport_layer, SipSMCommand::transaction_layer, "1**")){		MRef<SipResponse*> pack((SipResponse *)*command.getCommandPacket());		MRef<SipMessage*> pref(*pack);		SipSMCommand cmd( pref, 				SipSMCommand::transaction_layer, 				SipSMCommand::dialog_layer);		cancelTimeout("timerE");		dispatcher->enqueueCommand( cmd, HIGH_PRIO_QUEUE/*, PRIO_LAST_IN_QUEUE*/ );				return true;	}else{				return false;	}}//TODO: make sure  transport_error is sent when it should bebool SipTransactionNonInviteClient::a6_proceeding_terminated_transperrOrTimerF( const SipSMCommand &command){			if (		transitionMatch(command, 				SipCommandString::transport_error,				SipSMCommand::transport_layer,				SipSMCommand::transaction_layer) 			|| transitionMatch(command, 				"timerF",				SipSMCommand::transaction_layer,				SipSMCommand::transaction_layer)){		SipSMCommand cmd(				CommandString(callId,SipCommandString::transport_error), 				SipSMCommand::transaction_layer, 				SipSMCommand::dialog_layer);		dispatcher->enqueueCommand( cmd, HIGH_PRIO_QUEUE/*, PRIO_LAST_IN_QUEUE*/ );		SipSMCommand cmdterminated(				CommandString( callId, SipCommandString::transaction_terminated),				SipSMCommand::transaction_layer,				SipSMCommand::dispatcher);		dispatcher->enqueueCommand( cmdterminated, HIGH_PRIO_QUEUE/*, PRIO_FIRST_IN_QUEUE*/ );				return true;	}else{				return false;	}}bool SipTransactionNonInviteClient::a7_trying_completed_non1xxresp( const SipSMCommand &command) {	if (transitionMatch(SipResponse::type, command, SipSMCommand::transport_layer, SipSMCommand::transaction_layer, "2**\n3**\n4**\n5**\n6**")){				cancelTimeout("timerE");		cancelTimeout("timerF");		//send command to TU		SipSMCommand cmd(				command.getCommandPacket(), 				SipSMCommand::transaction_layer, 				SipSMCommand::dialog_layer);		dispatcher->enqueueCommand( cmd, HIGH_PRIO_QUEUE/*, PRIO_LAST_IN_QUEUE*/ );				if( isUnreliable() ) 			requestTimeout(sipStack->getTimers()->getK(), "timerK");		else 			requestTimeout( 0, "timerK");							return true;	}else{				return false;	}}bool SipTransactionNonInviteClient::a8_trying_trying_timerE( const SipSMCommand &command) {			if (transitionMatch(command, 				"timerE",				SipSMCommand::transaction_layer,				SipSMCommand::transaction_layer)){		//no need to check if isUnreliable() ... timerE will never be started anyway		timerE *= 2;		if( timerE > sipStack->getTimers()->getT2() ) 			timerE = sipStack->getTimers()->getT2();		requestTimeout(timerE,"timerE");				massert( !lastRequest.isNull());		lastRequest->removeAllViaHeaders();		send( *lastRequest, true);	// add via header because we have removed all previous ones				return true;	}else{				return false;	}}bool SipTransactionNonInviteClient::a9_completed_terminated_timerK( const SipSMCommand &command) {	if (transitionMatch(command, 				"timerK",				SipSMCommand::transaction_layer,				SipSMCommand::transaction_layer)){		SipSMCommand cmd(			CommandString( callId, SipCommandString::transaction_terminated),			SipSMCommand::transaction_layer,			SipSMCommand::dispatcher);		dispatcher->enqueueCommand( cmd, HIGH_PRIO_QUEUE/*, PRIO_FIRST_IN_QUEUE*/ );				return true;	}else{				return false;	}}void SipTransactionNonInviteClient::setUpStateMachine(){		State<SipSMCommand,string> *s_start=new State<SipSMCommand,string>(this,"start");	addState(s_start);	State<SipSMCommand,string> *s_trying=new State<SipSMCommand,string>(this,"trying");	addState(s_trying);	State<SipSMCommand,string> *s_proceeding=new State<SipSMCommand,string>(this,"proceeding");	addState(s_proceeding);	State<SipSMCommand,string> *s_completed=new State<SipSMCommand,string>(this,"completed");	addState(s_completed);	State<SipSMCommand,string> *s_terminated=new State<SipSMCommand,string>(this,"terminated");	addState(s_terminated);		///Set up transitions to enable cancellation of this transaction	new StateTransition<SipSMCommand,string>(this, "transition_cancel_transaction",			(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipTransaction::a1000_anyState_terminated_canceltransaction, 			StateMachine<SipSMCommand,string>::anyState, s_terminated);		new StateTransition<SipSMCommand,string>(this, "transition_start_trying_request",			(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipTransactionNonInviteClient::a0_start_trying_request, 			s_start, s_trying);		new StateTransition<SipSMCommand,string>(this, "transition_trying_proceeding_1xx",			(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipTransactionNonInviteClient::a1_trying_proceeding_1xx, 			s_trying, s_proceeding);	new StateTransition<SipSMCommand,string>(this, "transition_trying_terminated_TimerFOrErr",			(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipTransactionNonInviteClient::a2_trying_terminated_TimerFOrErr, 			s_trying, s_terminated);	new StateTransition<SipSMCommand,string>(this, "transition_proceeding_completed_non1xxresp",			(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipTransactionNonInviteClient::a3_proceeding_completed_non1xxresp, 			s_proceeding, s_completed);	new StateTransition<SipSMCommand,string>(this, "transition_proceeding_proceeding_timerE",			(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipTransactionNonInviteClient::a4_proceeding_proceeding_timerE,			s_proceeding, s_proceeding);	new StateTransition<SipSMCommand,string>(this, "transition_proceeding_proceeding_1xx",			(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipTransactionNonInviteClient::a5_proceeding_proceeding_1xx,			s_proceeding, s_proceeding);	new StateTransition<SipSMCommand,string>(this, "transition_proceeding_terminated_transperrOrTimerF",			(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipTransactionNonInviteClient::a6_proceeding_terminated_transperrOrTimerF,			s_proceeding, s_terminated);	new StateTransition<SipSMCommand,string>(this, "transition_trying_completed_non1xxresp",			(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipTransactionNonInviteClient::a7_trying_completed_non1xxresp,			s_trying, s_completed);	new StateTransition<SipSMCommand,string>(this, "transition_trying_trying_timerE",			(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipTransactionNonInviteClient::a8_trying_trying_timerE,			s_trying, s_trying);	new StateTransition<SipSMCommand,string>(this, "transition_completed_terminated_timerK",			(bool (StateMachine<SipSMCommand,string>::*)(const SipSMCommand&)) &SipTransactionNonInviteClient::a9_completed_terminated_timerK,			s_completed, s_terminated);	setCurrentState(s_start);}SipTransactionNonInviteClient::SipTransactionNonInviteClient(		MRef<SipStack *> stack,		//MRef<SipDialog*> d, 		int seq_no, 		const string &cSeqMethod, 		const string &callid) : 			SipTransactionClient(stack, /*d,*/ seq_no, cSeqMethod, "", callid),			lastRequest(NULL){		//timers are set in the initial transition//	MRef<SipCommonConfig *> conf = getConfig(); //	if (dialog){//		conf = dialog->getDialogConfig()->inherited;//	}else{//		conf = sipStack->getStackConfig();//	}//	if( !conf ) { cerr << "SipTranNonInvCli: conf null" << endl; massert (0);}//	if( !conf->sipIdentity ) { cerr << "SipTranNonInvCli: identity null" << endl; massert (0);}//	if( conf->sipIdentity->getSipProxy()->sipProxyAddressString.size()<=0 ) { cerr << "SipTranNonInvCli: no ipaddr" << endl; massert (0);}//	toaddr = conf->sipIdentity->getSipProxy()->sipProxyIpAddr->clone();	//port = conf->sipIdentity->getSipProxy()->sipProxyPort;	setUpStateMachine();}SipTransactionNonInviteClient::~SipTransactionNonInviteClient(){}

⌨️ 快捷键说明

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