📄 siptransactioninviteclient.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 * SipTransactionIntiveInitiator.cxx * Author * Erik Eliasson, eliasson@it.kth.se * Purpose * *//* ostart | |INVITE from TU Timer A fires |a0.INVITE sent a1.Reset A, V Timer B fires INVITE sent +-----------+ or Transport Err. +---------| |---------------+a4.inform TU | | Calling | | +-------->| |-------------->| +-----------+ 2xx | | | a5.2xx to TU | | | | 300-699 +---------------+ |a2. 1xx to TU |a3.ACK sent | | |resp. to TU | 1xx V | |a6.1xx to TU+-----------+ | | +---------| | | | | |Proceeding |-------------->| | +-------->| | 2xx | | +-----------+ a7.2xx to TU | | 300-699 | | | a8.ACK sent, | | | resp. to TU| | | | | NOTE: | 300-699 V | | a9.ACK sent+-----------+Transport Err. | transitions | +---------| |a10.Inform TU | labeled with | | | Completed |-------------->| the event | +-------->| | | over the action | +-----------+ | to take | ^ | | | | | Timer D fires | +--------------+ | a11. - | V | +-----------+ | | | | | Terminated|<--------------+ | | +-----------+ Figure 5: INVITE client transaction*/ #include<config.h>#include<libmsip/SipTransactionInviteClient.h>#include<libmsip/SipTransactionNonInviteClient.h>#include<libmsip/SipResponse.h>#include<libmsip/SipHeaderRoute.h>#include<libmsip/SipTransactionUtils.h>#include<libmsip/SipCommandDispatcher.h>#include<libmsip/SipSMCommand.h>#include<libmsip/SipCommandString.h>#include<libmsip/SipDialog.h>#include<libmsip/SipTimers.h>#include<libmsip/SipDialogConfig.h>#include<libmsip/SipHeaderCSeq.h>#include<libmutil/MemObject.h>#include<libmutil/CommandString.h>#include<libmsip/SipHeaderRequire.h>#include<libmutil/dbg.h>/*void SipTransactionInviteClient::rel1xxProcessing(MRef<SipResponse*> resp){ // If the server requests PRACK, then we need to start a // client transaction to transmit it. int statusCode = resp->getStatusCode(); if (statusCode>100 && statusCode<200 && resp->requires("100rel")){ dialog->dialogState.seqNo++; MRef<SipTransaction*> trans = new SipTransactionNonInviteClient(sipStack, dialog, dialog->dialogState.seqNo, "PRACK", dialog->dialogState.callId); dialog->registerTransaction(trans); sendAck(resp,trans->getBranch(), true); //last argument means that yes, we are ack:ing a 1xx -> PRACK }}*/bool SipTransactionInviteClient::a0_start_calling_INVITE( const SipSMCommand &command){ if (transitionMatch("INVITE", command, SipSMCommand::dialog_layer, SipSMCommand::transaction_layer)){ lastInvite = (SipRequest*) *command.getCommandPacket(); if( isUnreliable() ) { // retx timer timerA = sipStack->getTimers()->getA(); requestTimeout( timerA , "timerA" ); } requestTimeout( sipStack->getTimers()->getB(), "timerB" ); //transaction timeout/* TODO/FIXME: re-implement this functionality if( getConfig()->sipIdentity->getSipProxy()->sipProxyAddressString.size()>0 ){ MRef<SipHeaderValue*> hdr; hdr = lastInvite->getHeaderValueNo( SIP_HEADER_TYPE_ROUTE, 0 ); if( !hdr ){ lastInvite->addRoute( getConfig()->sipIdentity->getSipProxy()->sipProxyAddressString, port, transport ); } }*/ send( command.getCommandPacket(), true ); // add via header return true; }else{ return false; }}bool SipTransactionInviteClient::a1_calling_calling_timerA( const SipSMCommand &command){ if (transitionMatch(command, "timerA",SipSMCommand::transaction_layer,SipSMCommand::transaction_layer)){ timerA *= 2; //no upper limit ... well ... timer B sets it requestTimeout( timerA, "timerA" ); send(MRef<SipMessage*>((SipMessage*)* lastInvite), false); return true; }else{ return false; }}bool SipTransactionInviteClient::a2_calling_proceeding_1xx( const SipSMCommand &command){ if (transitionMatch(SipResponse::type, command, SipSMCommand::transport_layer, SipSMCommand::transaction_layer, "1**")){ cancelTimeout("timerA"); cancelTimeout("timerB"); SipSMCommand cmd( command.getCommandPacket(), SipSMCommand::transaction_layer, SipSMCommand::dialog_layer); dispatcher->enqueueCommand( cmd, HIGH_PRIO_QUEUE/*, PRIO_LAST_IN_QUEUE*/ ); MRef<SipResponse*> resp =(SipResponse *)*command.getCommandPacket(); //assert(dialog); //TODO/XXX/FIXME: Do this in the TU instead //dialog->dialogState.updateState( resp ); //rel1xxProcessing(resp); return true; }else{ return false; }}bool SipTransactionInviteClient::a3_calling_completed_resp36( const SipSMCommand &command){ if (transitionMatch(SipResponse::type, command, SipSMCommand::transport_layer, SipSMCommand::transaction_layer, "3**\n4**\n5**\n6**")){ MRef<SipResponse*> resp( (SipResponse*) *command.getCommandPacket() ); cancelTimeout("timerA"); cancelTimeout("timerB"); if( isUnreliable() ) requestTimeout(sipStack->getTimers()->getD(),"timerD"); else requestTimeout( 0,"timerD"); SipSMCommand cmd( command.getCommandPacket(), SipSMCommand::transaction_layer, SipSMCommand::dialog_layer); dispatcher->enqueueCommand( cmd, HIGH_PRIO_QUEUE/*, PRIO_LAST_IN_QUEUE*/ ); //assert(dialog); //TODO/XXX/FIXME: Do this in the TU instead //dialog->dialogState.updateState( resp ); sendAck(resp); return true; }else{ return false; }}bool SipTransactionInviteClient::a4_calling_terminated_ErrOrTimerB( const SipSMCommand &command){ if ( transitionMatch(command, SipCommandString::transport_error, SipSMCommand::transport_layer, SipSMCommand::transaction_layer) || transitionMatch(command, "timerB", SipSMCommand::transaction_layer, SipSMCommand::transaction_layer)){ cancelTimeout("timerA"); cancelTimeout("timerB"); 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 SipTransactionInviteClient::a5_calling_terminated_2xx( const SipSMCommand &command){ if (transitionMatch(SipResponse::type, command, SipSMCommand::transport_layer, SipSMCommand::transaction_layer, "2**")){ cancelTimeout("timerA"); cancelTimeout("timerB"); SipSMCommand cmd( command.getCommandPacket(), SipSMCommand::transaction_layer, SipSMCommand::dialog_layer); dispatcher->enqueueCommand( cmd, HIGH_PRIO_QUEUE/*, PRIO_LAST_IN_QUEUE*/ ); //FIXME/XXX/TODO: Implement setDialogRouteSet in TU instead //-EE //update dialogs route set ... needed to add route headers to the ACK we are going to send //setDialogRouteSet( (SipResponse*)*command.getCommandPacket() ); //assert(dialog); //dialog->dialogState.updateState( (MRef<SipResponse*>((SipResponse *)*command.getCommandPacket()) ) ); 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 SipTransactionInviteClient::a6_proceeding_proceeding_1xx( const SipSMCommand &command){ if (transitionMatch(SipResponse::type, command, SipSMCommand::transport_layer, SipSMCommand::transaction_layer, "1**")){ SipSMCommand cmd( command.getCommandPacket(), SipSMCommand::transaction_layer, SipSMCommand::dialog_layer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -