📄 sipdialogp2t.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>*/#include <config.h>#include<assert.h>#include<time.h>#include<libminisip/p2t/SipDialogP2T.h>#include<libmsip/SipDialogContainer.h>//#include<libmsip/SipMessageTransport.h>#include<libmsip/SipTransactionUtils.h>#include<libmsip/SipCommandString.h>#include<libminisip/p2t/RtcpTransactionGetFloor.h>#include<libminisip/p2t/RtcpTransactionGrantFloor.h>#include<libminisip/p2t/RtcpTransactionReleaseFloor.h>#include<libminisip/p2t/RtcpTransactionIdleFloor.h>#include<libminisip/p2t/RtcpTransactionTakenFloor.h>#include<libmsip/SipDialog.h>#include<libminisip/sip/DefaultDialogHandler.h>#include<libmutil/itoa.h>#include<sstream>#include<libmutil/Timestamp.h>#include<libmutil/termmanip.h>#include<libmutil/dbg.h>#include<libmsip/SipSMCommand.h>#include<libmnetutil/IP4Address.h>bool SipDialogP2T::a0_idle_talkreq( const SipSMCommand &command){ //MRef<SipDialogP2T *>vc= (SipDialogP2T *)sipStateMachine; if (transitionMatch(command, "p2tGetFloor")){ //start RtcpTransactionGetFloor #ifdef MINISIP_MEMDEBUG vc.setUser("WARNING - transaction");#endif //time measurement#ifndef _MSC_VER if(/*vc->*/p2tPerformance){ ts.start(); }#endif //increment sequence number /*vc->*/dialogState.seqNo++; //start RtcpTransactionGetFloor for(uint32_t k=0;k</*vc->*/getGroupList()->getAllUser().size();k++){ //filter out own user //if(vc->getGroupList()->getAllUser().at(k)->getUri()==vc->getDialogConfig().inherited->userUri) if(/*vc->*/getGroupList()->getAllUser()[k]->getUri()==/*vc->*/getDialogConfig()->inherited->sipIdentity->getSipUri()) continue; //filter out NOTAVAILABLE users if(/*vc->*/getGroupList()->getAllUser()[k]->getStatus()==P2T::STATUS_NOTAVAILABLE) continue; //start transaction MRef<SipTransaction*> gf = new RtcpTransactionGetFloor(MRef<SipDialog *>(/* *vc*/ this), /*vc->*/dialogState.seqNo, /*vc->*/getGroupList()->getAllUser()[k]->getAddress(), /*vc->*/getGroupList()->getAllUser()[k]->getRTCPport(), dialogState.callId); MRef<RtcpTransactionGetFloor*>gf_casted = MRef<RtcpTransactionGetFloor*>((RtcpTransactionGetFloor*)*gf); gf_casted->setUser(/*vc->*/getGroupList()->getAllUser()[k]->getUri()); /*vc->*/registerTransaction(gf); CommandString cmd(/*vc->*/getCallId(),"p2tSendRequest", itoa(/*vc->*/getGroupList()->getAllUser()[k]->getSSRC()), itoa(/*vc->*/dialogState.seqNo), /*vc->*/getGroupList()->getAllUser()[k]->getUri()); SipSMCommand scmd(cmd, SipSMCommand::TU, SipSMCommand::transaction); /*vc->*/getDialogContainer()->enqueueCommand(scmd, HIGH_PRIO_QUEUE, PRIO_LAST_IN_QUEUE); } return true; }else{ return false; }}bool SipDialogP2T::a1_talkreq_talk( const SipSMCommand &command){ //all users have granted OR not all users have granted but local user is the only with highest prio if (transitionMatch(command, "p2tRequestAnswered")){ //MRef<SipDialogP2T *>vc= (SipDialogP2T *)sipStateMachine; vector<string> users; if(/*vc->*/allAnswered()==false) return false; //merr<<"SipDialogP2T::a1"<<end; //merr<<"checkStates="<<vc->checkStates(P2T::STATUS_GRANT)<<end; //merr<<"Prio="<<vc->highestPrio(P2T::STATUS_COLLISION, users)<<end; //merr<<"empty="<<users.empty()<<end; if(/*vc->*/checkStates(P2T::STATUS_GRANT) ==false){ if(/*vc->*/highestPrio(P2T::STATUS_COLLISION, users)==false) return false; else if(users.empty()==false) return false; } //time measurements if(/*vc->*/p2tPerformance){#ifndef _MSC_VER ts.stop(); merr<<"used time:"<<ts.writeElapsedTime("Push-2-Talk delay")<<end;#endif } //send Floor TAKEN to all for(uint32_t k=0;k</*vc->*/getGroupList()->getAllUser().size();k++){ //filter out own user //if(vc->getGroupList()->getAllUser().at(k)->getUri()==vc->getDialogConfig().inherited->userUri) if(/*vc->*/getGroupList()->getAllUser()[k]->getUri()==/*vc->*/getDialogConfig()->inherited->sipIdentity->getSipUri()) continue; //filter out NOTAVAILABLE users if(/*vc->*/getGroupList()->getAllUser()[k]->getStatus()==P2T::STATUS_NOTAVAILABLE) continue; //start RtcpTransactionTakenFloor MRef<SipTransaction*> gf = new RtcpTransactionTakenFloor(MRef<SipDialog*>(/* *vc */ this), /*vc->*/dialogState.seqNo, /*vc->*/getGroupList()->getAllUser()[k]->getAddress(), /*vc->*/getGroupList()->getAllUser()[k]->getRTCPport(), dialogState.callId, /*vc->*/getGroupList()->getAllUser()[k]->getSSRC()); /*vc->*/registerTransaction(gf); CommandString cmd(/*vc->*/getCallId(), "p2tSendTaken", itoa(/*vc->*/getGroupList()->getAllUser()[k]->getSSRC()), itoa(/*vc->*/dialogState.seqNo)); SipSMCommand scmd(cmd, SipSMCommand::TU, SipSMCommand::transaction); /*vc->*/getDialogContainer()->enqueueCommand(scmd, HIGH_PRIO_QUEUE, PRIO_LAST_IN_QUEUE); } //inform GUI CommandString cmdstr(/*vc->*/getCallId(), "p2tFloorGranted"); /*vc->*/getDialogContainer()->getCallback()->sipcb_handleCommand( cmdstr ); /****** Start SoundSender *******/ //vc->getSoundSender()->start(); return true; }else{ return false; }}bool SipDialogP2T::a2_talk_releasepend( const SipSMCommand &command){ if (transitionMatch(command, "p2tReleaseFloor")){ //start RtcpTransactionReleaseFloor //MRef<SipDialogP2T *>vc= (SipDialogP2T *)sipStateMachine; #ifdef MINISIP_MEMDEBUG vc.setUser("WARNING - transaction");#endif //start RtcpTransactionReleaseFloor for(uint32_t k=0;k</*vc->*/getGroupList()->getAllUser().size();k++){ //filter out own user //if(vc->getGroupList()->getAllUser().at(k)->getUri()==vc->getDialogConfig().inherited->userUri) if(/*vc->*/getGroupList()->getAllUser()[k]->getUri()==/*vc->*/getDialogConfig()->inherited->sipIdentity->getSipUri()) continue; //filter out NOTAVAILABLE users if(/*vc->*/getGroupList()->getAllUser()[k]->getStatus()==P2T::STATUS_NOTAVAILABLE) continue; //set status back for being able to check if the user //answered the RELEASE message /*vc->*/getGroupList()->getAllUser()[k]->setStatus(P2T::STATUS_CONNECTED); //start transaction MRef<SipTransaction*> rf = new RtcpTransactionReleaseFloor(MRef<SipDialog *>(/* *vc */ this), /*vc->*/dialogState.seqNo, /*vc->*/getGroupList()->getAllUser()[k]->getAddress(), /*vc->*/getGroupList()->getAllUser()[k]->getRTCPport(), dialogState.callId, /*vc->*/getGroupList()->getAllUser()[k]->getSSRC()); /*vc->*/registerTransaction(rf); CommandString cmd(/*vc->*/getCallId(),"p2tReleaseFloor", itoa(/*vc->*/getGroupList()->getAllUser()[k]->getSSRC()), itoa(/*vc->*/dialogState.seqNo), /*vc->*/getGroupList()->getAllUser()[k]->getUri()); SipSMCommand scmd(cmd, SipSMCommand::TU, SipSMCommand::transaction); /*vc->*/getDialogContainer()->enqueueCommand(scmd, HIGH_PRIO_QUEUE, PRIO_LAST_IN_QUEUE); } //vc->getSoundSender()->stop(); return true; }else{ return false; }}bool SipDialogP2T::a3_releasepend_idle( const SipSMCommand &command){ if (transitionMatch(command, "p2tFloorReleased")){ //MRef<SipDialogP2T *>vc= (SipDialogP2T *)sipStateMachine; //check if all has answered RELEASE message if(/*vc->*/allAnswered()==false) return false; //inform GUI CommandString cmd(/*vc->*/getCallId(),"p2tFloorReleased", command.getCommandString().getParam()); /*vc->*/getDialogContainer()->getCallback()->sipcb_handleCommand( cmd ); //reset states /*vc->*/setStates(P2T::STATUS_CONNECTED); return true; }else{ return false; }}bool SipDialogP2T::a4_idle_listenreq( const SipSMCommand &command){ //MRef<SipDialogP2T *>vc= (SipDialogP2T *)sipStateMachine; if (transitionMatch(command, "p2tREQUEST") && /*vc->*/p2tCollisioner==false){ //start RtcpTransactionGrantFloor #ifdef MINISIP_MEMDEBUG vc.setUser("WARNING - transaction");#endif //uri string uri = command.getCommandString().getParam3(); //seqNo string p2 = command.getCommandString().getParam2(); //ssrc string p = command.getCommandString().getParam(); int sNo=0; int ssrc=0; for(uint32_t x=0;x<p2.size();x++) sNo = (sNo*10) + (p2[x]-'0'); for(uint32_t k=0;k<p.size();k++) ssrc = (ssrc*10) + (p[k]-'0'); //check if user is participating in the session if (/*vc->*/getGroupList()->isParticipant(uri)){ MRef<GroupListUserElement*> ue = /*vc->*/getGroupList()->getUser(uri); ue->setSSRC(ssrc); ue->setSeqNo(sNo); ue->setStatus(P2T::STATUS_REQUESTING); MRef<SipTransaction*> gf = new RtcpTransactionGrantFloor(MRef<SipDialog*>(/* *vc */ this), sNo, ue->getAddress(), ue->getRTCPport(), dialogState.callId, ssrc); /*vc->*/registerTransaction(gf); CommandString cmd(/*vc->*/getCallId(), "p2tSendGrant", itoa(ssrc), itoa(sNo), uri); SipSMCommand scmd(cmd, SipSMCommand::TU, SipSMCommand::transaction); /*vc->*/getDialogContainer()->enqueueCommand(scmd, HIGH_PRIO_QUEUE, PRIO_LAST_IN_QUEUE); } else{ //unknown user //stay in IDLE return false; } return true; }else{ return false; }}bool SipDialogP2T::a5_listenreq_listen( const SipSMCommand &command){ if (transitionMatch(command, "p2tFloorTaken")){ //MRef<SipDialogP2T *>vc= (SipDialogP2T *)sipStateMachine; //time measurements#ifndef _MSC_VER if(/*vc->*/p2tPerformance){ ts.stop(); merr<<"Used time:"<<ts.writeElapsedTime("Push-2-Talk delay")<<end; }#endif /****** inform GUI *******/ string user=""; int ssrc=0; for(uint32_t k=0;k<command.getCommandString().getParam().size();k++) ssrc = (ssrc*10) + (command.getCommandString().getParam()[k]-'0'); //get user and set STATUS_TALKING in the Group Member List if(/*vc->*/getGroupList()->isParticipant(ssrc)){ user = /*vc->*/getGroupList()->getUser(ssrc)->getUri(); /*vc->*/getGroupList()->getUser(ssrc)->setStatus(P2T::STATUS_TALKING); //inform GUI CommandString cmd(/*vc->*/getCallId(),"p2tFloorTaken", user); /*vc->*/getDialogContainer()->getCallback()->sipcb_handleCommand( cmd ); //start timerRevoke /*vc->*/counterRevoke=0; if(/*vc->*/getGroupList()->getMaxFloorTime()>0) /*vc->*/requestTimeout(/*vc->*/getGroupList()->getMaxFloorTime()*1000, "timerREVOKE"); //start SoundReceiver //vc->getSoundReceiver()->initCrypto(); //vc->getSoundReceiver()->start(); //vc->getSoundReceiver()->flush(); //vc->getSoundReceiver()->registerSoundSource(-2); //FIXME: return true; } else { merr<<"SipDialogP2T:: Error in a5, user that sent TAKEN message was not in GroupList"<<end; return false; } return true; }else{ return false; }}bool SipDialogP2T::a6_listen_idle( const SipSMCommand &command){ if (transitionMatch(command, "p2tRELEASE")){ //MRef<SipDialogP2T *>vc= (SipDialogP2T *)sipStateMachine; //find talking user int talk_ssrc = 0; uint32_t k; for(k=0;k</*vc->*/getGroupList()->getAllUser().size();k++){ if(/*vc->*/getGroupList()->getAllUser()[k]->getStatus()==P2T::STATUS_TALKING) talk_ssrc = /*vc->*/getGroupList()->getAllUser()[k]->getSSRC(); } //start transaction string p = command.getCommandString().getParam(); int ssrc=0; for(k=0;k<p.size();k++) ssrc = (ssrc*10) + (p[k]-'0'); //int sNo=0; //string p2 = command.getCommandString().getParam2(); //for(int x=0;x<p2.size();x++) // sNo = (sNo*10) + (p2[x]-'0'); //check if user is participating in the session if (ssrc==talk_ssrc){ MRef<GroupListUserElement*> ue = /*vc->*/getGroupList()->getUser(ssrc); MRef<SipTransaction*> gf = new RtcpTransactionIdleFloor(MRef<SipDialog*>(/* *vc */ this), ue->getSeqNo(), ue->getAddress(), ue->getRTCPport(), dialogState.callId, ssrc); /*vc->*/registerTransaction(gf); CommandString cmd(/*vc->*/getCallId(), "p2tReleaseFloor", itoa(ssrc), itoa(ue->getSeqNo())); SipSMCommand scmd(cmd, SipSMCommand::TU, SipSMCommand::transaction); /*vc->*/getDialogContainer()->enqueueCommand(scmd, HIGH_PRIO_QUEUE, PRIO_LAST_IN_QUEUE); } //unknown user. else{ //Wrong user sent RELEASE return false; } //cancel REVOKE timer /*vc->*/cancelTimeout("timerREVOKE"); //inform GUI CommandString cmd(/*vc->*/getCallId(),string("p2tFloorReleased"), command.getCommandString().getParam()); /*vc->*/getDialogContainer()->getCallback()->sipcb_handleCommand( cmd ); //reset states /*vc->*/setStates(P2T::STATUS_CONNECTED); //stop listening //vc->getSoundReceiver()->stop(); return true; }else{ return false; }}bool SipDialogP2T::a7_talkreq_listenreq( const SipSMCommand &command){ //Not all users have granted and local user hasn't highest prio. if (transitionMatch(command, "p2tRequestAnswered")){ //MRef<SipDialogP2T *>vc= (SipDialogP2T *)sipStateMachine; vector<string> users; //mdbg<<"SipDialogP2T::a7"<<end; //mdbg<<"allAnswered="<<vc->allAnswered()<<end; if(/*vc->*/allAnswered()==false) return false; //mdbg<<"SipDialogP2T:: a7"<<end; //mdbg<<"checkStates="<<vc->checkStates(P2T::STATUS_GRANT)<<end; //mdbg<<"highestPrio="<<vc->highestPrio(P2T::STATUS_COLLISION, users)<<end; //mdbg<<"users.empty="<<users.empty()<<end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -