📄 sipdialogvoip.cxx
字号:
/* Copyright (C) 2004-2006 the Minisip Team 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 *//* Copyright (C) 2004 * * Authors: Erik Eliasson <eliasson@it.kth.se> * Johan Bilien <jobi@via.ecp.fr> * Joachim Orrblad <joachim[at]orrblad.com>*//* Name * SipDialogVoip.cxx * Author * Erik Eliasson, eliasson@it.kth.se * Purpose * */#include<config.h>#include<libminisip/sip/SipDialogVoip.h>#include<libmutil/massert.h>//#include<libmsip/SipDialogContainer.h>#include<libmsip/SipTransactionInviteClientUA.h>#include<libmsip/SipTransactionInviteServerUA.h>#include<libmsip/SipTransactionNonInviteClient.h>#include<libmsip/SipTransactionNonInviteServer.h>#include<libmsip/SipTransactionUtils.h>#include<libmsip/SipCommandString.h>#include<libmsip/SipHeaderWarning.h>#include<libmsip/SipHeaderContact.h>#include<libmsip/SipHeaderFrom.h>#include<libmsip/SipHeaderRoute.h>#include<libmsip/SipHeaderRequire.h>#include<libmsip/SipHeaderTo.h>#include<libmsip/SipMIMEContent.h>#include<libmsip/SipMessageContent.h>#include<libmutil/itoa.h>#include<libmcrypto/base64.h>#include<libmutil/Timestamp.h>#include<libmutil/termmanip.h>#include<libmutil/dbg.h>#include<libmsip/SipSMCommand.h>#include <time.h>#include<libminisip/gui/LogEntry.h>#include<libmutil/print_hex.h>#include <iostream>#include<time.h>#ifdef _WIN32_WCE# include"../include/minisip_wce_extra_includes.h"#endifusing namespace std;/* States are named as follows where X and NN is digit numbers a 1 X NN _ "fromstate" _ "tostate" _ "trigger" ^ ^ ^^ | | ++-- Number starting from 1 | +----- Type of functionality 0: in-call commands such as BYE, bye and re-invite | 1: dialog management | 2: locally initiated call transfer | 3: remotely initiated call transfer +------- Actions in this file. SipDialogVoipClient=2, SipDialogVoipServer=3 Example: a1301_incall_transfaskuser_REFER means that it is the transition from the incall state to the transfaskuser state that will happen if it receives a REFER. a1301 means "action 1 in SipDialogVoip that handles remotely initiated call transfer". State Machine: The state machine in this file only deals with a call after it has been set up and is in the "in_call" state. Sub-classes implement call setup so that we get into this state. These states are These states are These states when the local user for a "normal" call. are used when a requests a call in_call is during remote user request transfer. the call. call transfer <----------------> <---------------------> <----------------> transfer a1201:new TReferInit REFER +---------------+ +---------------+ a1301: +---------------+ | |<-------------| |---------->| | | transf_request| | in call |refus/a1303|transf_ask_user| | |------------->| |<----------| | +---------------+ 300-699 +---------------+-------+ +---------------+ | a1203: - | | hangup | accept_transfer | 202 | BYE | a1002:TByeCli | a1302: 202;start new call | a1202: new subscription V a1001:TByeServ| V +---------------+ +---------------+ | +---------------+ | |------------->| |<------+ | | | transf_pending| bye | bye_request | |transf_started | | | a1001 +---| |<----------| | +---------------+ | +---------------+ bye +---------------+ | ^ | | ^ | a1304 | | | | hang_up +------+ | a1003: 2XX-6XX | +----------+ | a1102: call_term_earlyV gui(call_terminated) | NOTIFY | +---------------+ | a1204: - | | | | +-------------->| termwait |<-------------------+ BYE | | BYE a1002 gui(cterm)+---------------+ a1305 gui(call_terminated) v | a1102 | no_transactions V a1304 +---------------+ | | | terminated | | | +---------------+ Why do we inform the GUI that the dialog has ben terminated (in a1101)? --Erik *//** * Helper function that returns the uri in the referto header. */static string getReferredUri(MRef<SipRequest*> req){ string referredUri; MRef<SipHeaderValue*> hval; if (req) hval = req->getHeaderValueNo(SIP_HEADER_TYPE_REFERTO, 0); if (hval) referredUri = hval->getString(); else{ cerr << "WARNING: Referred to uri not found!"<<endl; } return referredUri;}/** * * This transaction is also used a a1001_transfpending_termwait_BYE */bool SipDialogVoip::a1001_incall_termwait_BYE( const SipSMCommand &command){ if (transitionMatch("BYE", command, SipSMCommand::transaction_layer, SipSMCommand::dialog_layer) && dialogState.remoteTag != ""){ MRef<SipRequest*> bye = (SipRequest*) *command.getCommandPacket(); //mdbg << "log stuff"<< end; if( getLogEntry() ){ ((LogEntrySuccess *)(*( getLogEntry() )))->duration = time( NULL ) - getLogEntry()->start; getLogEntry()->handle(); }#if 0 MRef<SipTransaction*> byeresp = new SipTransactionNonInviteServer(sipStack, //MRef<SipDialog*>(this), bye->getCSeq(), bye->getCSeqMethod(), bye->getLastViaBranch(), dialogState.callId); //TODO: remove second argument dispatcher->getLayerTransaction()->addTransaction(byeresp); registerTransactionToDialog(byeresp); SipSMCommand cmd(command); cmd.setDestination(SipSMCommand::transaction_layer); cmd.setSource(command.getSource()); dispatcher->enqueueCommand(cmd, HIGH_PRIO_QUEUE/*, PRIO_LAST_IN_QUEUE*/);#endif sendByeOk(bye, /*byeresp->getBranch()*/"" ); CommandString cmdstr(dialogState.callId, SipCommandString::remote_hang_up); sipStack->getCallback()->handleCommand("gui", cmdstr); getMediaSession()->stop(); signalIfNoTransactions(); return true; }else{ return false; }}#if 0bool SipDialogVoip::a1001_incall_termwait_BYE( const SipSMCommand &command){ if (transitionMatch("BYE", command, SipSMCommand::transaction_layer, SipSMCommand::dialog_layer) && dialogState.remoteTag != ""){ MRef<SipRequest*> bye = (SipRequest*) *command.getCommandPacket(); //mdbg << "log stuff"<< end; if( getLogEntry() ){ ((LogEntrySuccess *)(*( getLogEntry() )))->duration = time( NULL ) - getLogEntry()->start; getLogEntry()->handle(); }#if 0 MRef<SipTransaction*> byeresp = new SipTransactionNonInviteServer(sipStack, //MRef<SipDialog*>(this), bye->getCSeq(), bye->getCSeqMethod(), bye->getLastViaBranch(), dialogState.callId); //TODO: remove second argument dispatcher->getLayerTransaction()->addTransaction(byeresp); registerTransactionToDialog(byeresp); SipSMCommand cmd(command); cmd.setDestination(SipSMCommand::transaction_layer); cmd.setSource(command.getSource()); dispatcher->enqueueCommand(cmd, HIGH_PRIO_QUEUE/*, PRIO_LAST_IN_QUEUE*/);#endif sendByeOk(bye, /*byeresp->getBranch()*/"" ); CommandString cmdstr(dialogState.callId, SipCommandString::remote_hang_up); sipStack->getCallback()->handleCommand("gui", cmdstr); getMediaSession()->stop(); signalIfNoTransactions(); return true; }else{ return false; }}#endif/** * * This transaction is also used a a1001_transfpending_byerequest_hangup */bool SipDialogVoip::a1002_incall_byerequest_hangup( const SipSMCommand &command){ if (transitionMatch(command, SipCommandString::hang_up, SipSMCommand::dialog_layer, SipSMCommand::dialog_layer)){ //int bye_seq_no= requestSeqNo(); ++dialogState.seqNo;/* MRef<SipTransaction*> byetrans( new SipTransactionNonInviteClient(sipStack, //MRef<SipDialog*>(this), dialogState.seqNo, "BYE", dialogState.callId)); dispatcher->getLayerTransaction()->addTransaction(byetrans); //registerTransactionToDialog(byetrans);*/ sendBye(""/*byetrans->getBranch()*/, dialogState.seqNo); if (getLogEntry()){ (dynamic_cast< LogEntrySuccess * >(*( getLogEntry() )))->duration = time( NULL ) - getLogEntry()->start; getLogEntry()->handle(); } getMediaSession()->stop(); signalIfNoTransactions(); return true; }else{ return false; }}///We consume any final response, and consider the session stopped (even if///the response is not 2XX)bool SipDialogVoip::a1003_byerequest_termwait_26( const SipSMCommand &command){ if (transitionMatch(SipResponse::type, command, SipSMCommand::transaction_layer, SipSMCommand::dialog_layer, "2**\n3**\n4**\n5**\n6**") ){/* SipSMCommand cmd( CommandString( dialogState.callId, SipCommandString::call_terminated), SipSMCommand::dialog_layer, SipSMCommand::dispatcher); dispatcher->enqueueCommand( cmd, HIGH_PRIO_QUEUE);*/ /* Tell the GUI */ CommandString cmdstr( dialogState.callId, SipCommandString::call_terminated); sipStack->getCallback()->handleCommand("gui", cmdstr );#ifdef IPSEC_SUPPORT if(ipsecSession){ cerr << "Clearing" << endl; if(ipsecSession->stop() != 0) cerr << "Not all IPSEC parameters were confired cleared. Check and remove manually." << endl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -