📄 multilegcallcontrol.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 MultiLegCallControl_cxx_Version = "$Id: MultiLegCallControl.cxx,v 1.22.2.1 2003/03/13 18:11:36 chok Exp $";#include "SipEvent.hxx" #include "SystemInfo.hxx" #include "AAAEvent.hxx" #include "AuthAgent.hxx" #include "CallTimerEvent.hxx" #include "CallDB.hxx" #include "B2bFacade.hxx" #include "B2bConfig.hxx" #include "MultiLegCallControl.hxx" #include "RegistrationAgent.hxx" using namespace Vocal;using namespace Vocal::UA;MultiLegCallControl* MultiLegCallControl::myInstance = 0;void MultiLegCallControl::receivedRequest(UaBase& agent, const Sptr<SipMsg>& msg){ //Find the agent's peer and send status to all peers current Sptr<ContactData> cData; switch(msg->getType()) { case SIP_BYE: { //Done with the contact, remove from the contact list cData = agent.popContact(); } break; case SIP_ACK: { //Check if the message has SDP data, if so update the SDP data in agent Sptr<SipSdp> sdp; sdp.dynamicCast(msg->getContentData(0)); if(sdp != 0) agent.setRemoteSdp(sdp); //Follow through to do the rest } default: { cData = agent.getContactData(); } break; } if(cData != 0) { const ContactData::CallPeerList& pList = cData->getPeerList(); for(ContactData::CallPeerList::const_iterator itr = pList.begin(); itr != pList.end(); itr++) { Sptr<UaBase> pAgent; pAgent.dynamicCast(*itr); assert(pAgent != 0); //Remove the peer from the peer list if(msg->getType() == SIP_BYE) { int nPeers = CallDB::instance().removePeer(*pAgent, agent); //If this was the last peer, send bye msg if(nPeers == 0) { //Send the call-leg pAgent->sendMsg(msg); } } else { //Send the call-leg pAgent->sendMsg(msg); } } } if(msg->getType() == SIP_BYE) { CallDB::instance().removeCallData(agent); }}void MultiLegCallControl::receivedStatus(UaBase& agent, const Sptr<SipMsg>& msg){ Sptr<StatusMsg> statusMsg; statusMsg.dynamicCast(msg); assert(statusMsg != 0); if(msg->getCSeq().getMethod() == CANCEL_METHOD) { //do Nothing return; } //Find the agent's peer and send status to all peers Sptr<ContactData> cData = agent.getContactData(); assert(cData != 0); const ContactData::CallPeerList& pList = cData->getPeerList(); for(ContactData::CallPeerList::const_iterator itr = pList.begin(); itr != pList.end(); itr++) { Sptr<UaBase> pAgent; pAgent.dynamicCast(*itr); assert(pAgent != 0); pAgent->sendMsg(msg); } if(msg->getCSeq().getMethod() == BYE_METHOD) { CallDB::instance().removePeer(agent); }}bool MultiLegCallControl::processEvent(const Sptr<SipProxyEvent>& event){ Sptr<SipEvent> sipEvent; sipEvent.dynamicCast(event); if(sipEvent != 0) { Sptr<SipMsg> sipMsg = sipEvent->getSipMsg(); cpLog(LOG_DEBUG, "Received event with message:%s", sipMsg->encode().logData()); assert(sipMsg != 0); if(sipMsg->getType() != SIP_INVITE) { //Handle Cancel and BYE messages and return. switch(sipMsg->getType()) { case SIP_CANCEL: case SIP_BYE: { Sptr<SipCommand> sipCmd; sipCmd.dynamicCast(sipMsg); if(sipCmd != 0) { Sptr<StatusMsg> sMsg = new StatusMsg(*sipCmd, 200); cpLog(LOG_DEBUG, "Sending reply :%s", sMsg->encode().logData()); B2bFacade::instance().getSipTransceiver()->sendReply(sMsg); } } break; case SIP_REGISTER: { Sptr<RegisterMsg> rMsg; rMsg.dynamicCast(sipMsg); RegistrationAgent::instance().processRegister(rMsg); } break; case SIP_OPTIONS: case SIP_SUBSCRIBE: case SIP_NOTIFY: case SIP_MESSAGE: { proxyIt(sipMsg); } break; case SIP_STATUS: { if(sipMsg->getCSeq().getMethod() == REGISTER_METHOD) { Sptr<StatusMsg> sMsg; sMsg.dynamicCast(sipMsg); RegistrationAgent::instance().processResponse(sMsg); } if(sipMsg->getCSeq().getMethod() == INVITE_METHOD) { proxyIt(sipMsg); } } default: break; } return true; } //Do authentication Sptr<AuthAgent> authAgent = new AuthAgent(getNextSessionId(), sipMsg); myCallMap[authAgent->getId()] = authAgent; authAgent->doAuth(); return true; } Sptr<AAAEvent> authEvent; authEvent.dynamicCast(event); if(authEvent != 0) { AuthAgent* authAgent = authEvent->getAuthAgent(); cpLog(LOG_DEBUG, "Received AAA response for id: %ld", authAgent->getId()); authAgent->authDone(authEvent); return true; } Sptr<CallTimerEvent> timerEvent; timerEvent.dynamicCast(event); if(timerEvent != 0) { (timerEvent->getAgent())->timerExpired(); } return true;}MultiLegCallControl& MultiLegCallControl::instance(){ if(myInstance == 0) { myInstance = new MultiLegCallControl(); } return *myInstance;}voidMultiLegCallControl::destroy(void){ cpLog(LOG_DEBUG, "MultiLegCallControl::destroy"); delete MultiLegCallControl::myInstance; MultiLegCallControl::myInstance = 0;}MultiLegCallControl::~MultiLegCallControl(){}MultiLegCallControl::MultiLegCallControl() : CallControl(){ //Initialze the value to be the unix seconds at the time of creation time_t t; mySessionId = time(&t);}voidMultiLegCallControl::proxyIt(Sptr<SipMsg> sMsg){ cpLog(LOG_INFO, "Can not handle the message %s, proxying it", sMsg->encode().logData()); //Get the transceiver and sen it to the next hop //string outboundProxyAddr = B2bConfig::instance().getStr(B2bConfig::SIP_PROXY_ADDR); //int outboundProxyPort = B2bConfig::instance().getInt(B2bConfig::SIP_PROXY_PORT); if(sMsg->getType() == SIP_STATUS) { Sptr<StatusMsg> statusMsg; statusMsg.dynamicCast(sMsg); B2bFacade::instance().getSipTransceiver()->sendReply(statusMsg); } else { Sptr<SipCommand> sipCmd; sipCmd.dynamicCast(sMsg); SipRequestLine& rLine = sipCmd->getMutableRequestLine(); string useTransport = B2bConfig::instance().getStr(B2bConfig::SIP_LOCAL_TRANSPORT); rLine.setTransportParam(useTransport); B2bFacade::instance().getSipTransceiver()->sendAsync(sipCmd); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -