📄 callagent.cxx
字号:
/* ==================================================================== * The Vovida Software License, Version 1.0 * * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names "VOCAL", "Vovida Open Communication Application Library", * and "Vovida Open Communication Application Library (VOCAL)" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor * may "VOCAL" appear in their name, without prior written * permission of Vovida Networks, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc. For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */static const char* const CallAgent_cxx_Version = "$Id: CallAgent.cxx,v 1.21.2.5 2003/03/13 00:27:42 sprajpat Exp $";#include "ByeMsg.hxx"#include "InviteMsg.hxx"#include "CancelMsg.hxx"#include "SystemInfo.hxx"#include "ControlStateFactory.hxx"#include "UaCallControl.hxx"#include "UaServer.hxx"#include "UaFacade.hxx"#include "SdpHandler.hxx"#include "CallDB.hxx"#include "UaClient.hxx"#include "CallAgent.hxx"#include "UaConfiguration.hxx"#include "SipServer.hxx"#include "SipDiversion.hxx"#include "Authenticate.hxx"#include "FileMediaDevice.hxx"#include "UaCommandLine.hxx"#ifdef USE_VM#include "VmcpDevice.hxx"#endif#ifdef USE_MPEGLIB#include "VideoDevice.hxx"#endif#include "MediaController.hxx"using namespace Vocal;using namespace Vocal::UA;long CallAgent::myRotatingId = 0;CallAgent::CallAgent(Sptr<SipMsg> sipMsg, AgentRole aRole) : BasicAgent(myRotatingId++) , myRole(aRole), myActiveFlg(true){ myState = ControlStateFactory::instance().getState(INIT); ///Create new UserAgent if(aRole == A_CLIENT) { //Create the invite message myInvokee = new UaClient(sipMsg, UaFacade::instance().getSipTransceiver(), this); myState->makeCall(*this); } else { myInvokee = new UaServer(sipMsg, UaFacade::instance().getSipTransceiver(), this); myInvokee->receivedMsg(sipMsg); myState->ringing(*this); myActiveFlg = true; } //Add the callleg in CallDb CallDB::instance().addCallLeg(myInvokee);};Sptr<StatusMsg>CallAgent::doholdresume200OKstuff(const Sptr<SipMsg>& msg, SdpSession& remoteSdp ){ Sptr<StatusMsg> statusMsg; Sptr<SipCommand> sCommand; sCommand.dynamicCast(myInvokee->getRequest()); assert(sCommand != 0); statusMsg = new StatusMsg(*sCommand, 200); // Set Contact header Sptr< SipUrl > myUrl = new SipUrl; myUrl->setUserValue( UaConfiguration::instance().getValue(UserNameTag) ); myUrl->setHost(theSystem.gethostAddress()); myUrl->setPort( UaConfiguration::instance().getValue(LocalSipPortTag) ); SipContact myContact; myContact.setUrl( myUrl ); statusMsg->setNumContact( 0 ); // Clear old contact statusMsg->setContact( myContact ); SipServer lServer("Vovida-SIP-SoftPhone/0.1"); statusMsg->setServer(lServer); Data S_host; if((UaConfiguration::instance().getValue(NATAddressIPTag)).length()) { S_host = UaConfiguration::instance().getValue(NATAddressIPTag); } else { S_host = theSystem.gethostAddress(); } SipSdp localSdp; int sessionId = myInvokee->getLocalSdp()->getSdpDescriptor().getSessionId(); SdpSession localS = MediaController::instance().getSdp(sessionId, remoteSdp); setHost(localS, S_host); localSdp.setSdpDescriptor(localS); statusMsg->setContentData(&localSdp, 0); return statusMsg;}void CallAgent::placeCall(){ cpLog(LOG_DEBUG, "CallAgent::placeCall()"); Sptr<SipMsg> sipMsg = myInvokee->getRequest(); myInvokee->sendMsg(sipMsg); UaFacade::instance().postInfo(sipMsg);}void CallAgent::doBye(){ if(!myState->canBye()){ return; } cpLog(LOG_DEBUG, "CallAgent::doBye()"); Sptr<SipMsg> bMsg = myInvokee->sendBye(); if(bMsg != 0) UaFacade::instance().postInfo(bMsg); endCall(); strstream str; str << "L_HANGUP " << ends; UaFacade::instance().postMsg(str.str()); str.freeze(false);}void CallAgent::endCall(){ if(!myActiveFlg) { cpLog(LOG_INFO, "Call Agent no more active, ignoring endCall()"); return; } cpLog(LOG_DEBUG, "CallAgent::endCall()"); try{ int sessionId = myInvokee->getLocalSdp()->getSdpDescriptor().getSessionId(); MediaController::instance().freeSession(sessionId); UaFacade::instance().releaseMediaDevice(getId()); ///Transit the controller state myState->bye(*this); //-> TEAR_DOWN myState->end(*this); //-> INIT } catch(CInvalidStateException& e) { cpLog(LOG_ERR, "Unexpacted Error ? :(:%s", e.getDescription().c_str()); }}void CallAgent::doCancel(){ cpLog(LOG_DEBUG, "CallAgent::doCancel()"); myState->cancel(*this); myState->end(*this);}voidCallAgent::inCall(){ cpLog(LOG_DEBUG, "CallAgent::inCall()"); myState->inCall(*this);#ifdef USE_MPEGLIB int video = atoi(UaConfiguration::instance().getValue(VideoTag).c_str()); //Even if video mode is on, when running in command line mode force the //non-video option if(video && (!UaCommandLine::instance()->getIntOpt("cmdline"))) { Sptr<VideoDevice> vDevice; vDevice.dynamicCast(UaFacade::instance().getMediaDevice(getId())); assert(vDevice != 0); vDevice->startMedia(myInvokee->getRemoteSdp()->getSdpDescriptor()); } else { startSession(myInvokee->getLocalSdp()->getSdpDescriptor(), myInvokee->getRemoteSdp()->getSdpDescriptor()); }#else startSession(myInvokee->getLocalSdp()->getSdpDescriptor(), myInvokee->getRemoteSdp()->getSdpDescriptor());#endif}voidCallAgent::callFailed(){ cpLog(LOG_DEBUG, "CallAgent::callFailed()"); myState->cancel(*this); myState->end(*this); strstream str; str << "L_HANGUP " << ends; UaFacade::instance().postMsg(str.str()); str.freeze(false);}///void CallAgent::receivedRequest(UaBase& agent, const Sptr<SipMsg>& msg){ //Notify GUI UaFacade::instance().postMsg(msg); myState->recvReq(*this, msg);}///void CallAgent::receivedStatus(UaBase& agent, const Sptr<SipMsg>& msg){ try { myState->recvStatus(*this, msg); Sptr<StatusMsg> statusMsg; statusMsg.dynamicCast(msg); assert(statusMsg != 0); if(statusMsg->getStatusLine().getStatusCode() == 200 && statusMsg->getCSeq().getMethod() == INVITE_METHOD ) { agent.ackStatus(msg); } if(statusMsg->getStatusLine().getStatusCode() == 302) { Sptr<InviteMsg> inviteMsg; inviteMsg.dynamicCast(myInvokee->getRequest()); SipRequestLine& reqLine = inviteMsg->getMutableRequestLine(); SipContactList contactList = statusMsg->getContactList(); SipContactList::iterator iter = contactList.begin(); Sptr < SipUrl > iterSipUrl; iterSipUrl.dynamicCast( ( *iter )->getUrl() ); reqLine.setUrl(iterSipUrl); SipCSeq localseq = agent.getLocalCSeq(); localseq.incrCSeq(); agent.setLocalCSeq(localseq); inviteMsg->setCSeq(localseq); agent.getSipTransceiver()->sendAsync(inviteMsg); } //Notify GUI UaFacade::instance().postMsg(msg); if (msg->getCSeq().getMethod() == CANCEL_METHOD) { UaFacade::instance().postMsg("L_HANGUP "); } } catch(CInvalidStateException& e) { cpLog(LOG_ERR, "Unexpacted status:%s", e.getDescription().c_str()); }}voidCallAgent::sendCancel(){ Sptr<SipCommand> sCommand; sCommand.dynamicCast(myInvokee->getRequest()); Sptr<CancelMsg> cMsg = new CancelMsg(*sCommand); myInvokee->sendMsg(cMsg); UaFacade::instance().postInfo(cMsg);}voidCallAgent::acceptCall(){ //Can only accept call when I am server if(myRole != A_SERVER) return; try { myState->acceptCall(*this); Sptr<StatusMsg> statusMsg; Sptr<SipCommand> sCommand; sCommand.dynamicCast(myInvokee->getRequest()); assert(sCommand != 0); statusMsg = new StatusMsg(*sCommand, 200); // Set Contact header Sptr< SipUrl > myUrl = new SipUrl; myUrl->setUserValue( UaConfiguration::instance().getValue(UserNameTag) ); myUrl->setHost(theSystem.gethostAddress()); myUrl->setPort( UaConfiguration::instance().getValue(LocalSipPortTag) ); SipContact myContact; myContact.setUrl( myUrl ); statusMsg->setNumContact( 0 ); // Clear old contact statusMsg->setContact( myContact ); SipServer lServer("Vovida-SIP-SoftPhone/0.1"); statusMsg->setServer(lServer); Sptr<SipSdp> remoteSdp; remoteSdp.dynamicCast(sCommand->getContentData(0)); if(remoteSdp == 0) { // do something safe
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -