⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uabuilder.cxx

📁 Vovida 社区开源的 SIP 协议源码
💻 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 UaBuilder_cxx_Version =    "$Id: UaBuilder.cxx,v 1.37 2002/03/19 21:40:17 jason Exp $";#include "global.h"#include <SipEvent.hxx>#include <StatusMsg.hxx>#include "UaBuilder.hxx"#include "UaCallContainer.hxx"#include "UaStateMachine.hxx"#include "UaDeviceEvent.hxx"#include "UaDevice.hxx"#include "UaDigitTimerEvent.hxx"#include "UaTimerEvent.hxx"#include "UaConfiguration.hxx"using namespace Vocal;///UaBuilder::UaBuilder(){    Sptr < UaStateMachine > uaStateMachine = new UaStateMachine;    addFeature( uaStateMachine );}    // UaBuilder::UaBuilder///UaBuilder::~UaBuilder(){}    // UaBuilder::~UaBuilder///voidUaBuilder::process( const Sptr < SipProxyEvent > nextEvent ){    assert ( nextEvent != 0 );    assert ( myCallContainer != 0 );    calls.dynamicCast( myCallContainer );    assert( calls != 0 );    stateMachine.dynamicCast( *( myFeatures.begin() ) );    assert( stateMachine != 0 );    /// Handle the 4 types of events:    /// SipEvent    Sptr < SipEvent > sipEvent;    sipEvent.dynamicCast( nextEvent );    if ( sipEvent != 0 )    {	/** Returning 'true' from a 'process' or 'handle' method causes	 *  UaBuilder to exit without running sendEvent()	 */	if( processSipEvent( sipEvent ) )	{	    cpLog( LOG_DEBUG, "Returning from processSipEvent\n" );	    return;	}	sendEvent( nextEvent );	return;    }    /// UaDeviceEvent    Sptr < UaDeviceEvent > uaDeviceEvent;    uaDeviceEvent.dynamicCast( nextEvent );    if ( uaDeviceEvent != 0 )    {	if( processUaDeviceEvent( uaDeviceEvent ) )	{	    cpLog( LOG_DEBUG, "Returning from processUaDeviceEvent\n" );	    return;	}	sendEvent( nextEvent );	return;    }    /// UaDigitEvent    Sptr < UaDigitTimerEvent > uaDigitEvent;    uaDigitEvent.dynamicCast( nextEvent );    if ( uaDigitEvent != 0 )    {	if( processUaDigitEvent( uaDigitEvent ) )	{	    cpLog( LOG_DEBUG, "Returning from processUaDigitEvent\n" );	    return;	}	sendEvent( nextEvent );	return;    }    /// UaTimerEvent    Sptr < UaTimerEvent > uaTimerEvent;    uaTimerEvent.dynamicCast( nextEvent );    if ( uaTimerEvent != 0 )    {	if( processUaTimerEvent( uaTimerEvent ) )	{	    cpLog( LOG_DEBUG, "Returning from processSipEvent\n" );	    return;	}	sendEvent( nextEvent );	return;    }    /// Event of unknown type    // we shouldn't get to here.    cpLog( LOG_ERR, "Unknown Event" );    assert( 0 );}/** * A parent 'process' method */boolUaBuilder::processSipEvent( const Sptr < SipEvent > sipEvent ){    cpLog( LOG_DEBUG, "SIP message event" );    cpLog( LOG_DEBUG, "In processSipEvent()" );    Sptr < StatusMsg > statusMsg;    statusMsg.dynamicCast( sipEvent->getSipMsg() );    /// If we have a status msg, we handle it    if ( statusMsg != 0 )    {	if( handleStatusMsg( sipEvent ) )	{	    return true;	}    }    /// If we get here, we have a SIP message event    cpLog( LOG_DEBUG, "SIP message event" );    /// Let's check the call info, now    callId = sipEvent->getSipCallLeg()->getCallId();    callInfo = calls->findCall( callId );    if ( callInfo == 0 )    {	cpLog( LOG_DEBUG, "No CallInfo found" );		Sptr < InviteMsg > inviteMsg;	inviteMsg.dynamicCast( sipEvent->getSipMsg() );	if ( inviteMsg == 0 )	{	    cpLog (LOG_DEBUG, "Not an INVITE - Discard event" );	    return true;	}	else	{	    cpLog( LOG_DEBUG, "New INVITE" );	    callInfo = calls->newCall		( sipEvent->getSipCallLeg()->getCallId() );	    assert( callInfo != 0 );	    callInfo->setFeature( stateMachine );	    	    if ( UaConfiguration::instance()->getLoadGenOn() )	    {		/// Assume this is a new call...		/// Also assume that we are not in use.		callInfo->setState		    ( stateMachine->findState( "StateAutoIdle" ) );	    }	    else  // LoadGen is off	    {		/// We're not in loadgen mode		/// Handle call waiting conditions		if( handleCallWaiting( callInfo ) )		{		    cpLog( LOG_ERR, "Returned from handleCallWaiting\n" );		    return true;		}	    }	} // lots of brackets!    }    return false;}  /// UaBuilder::processSipEvent/** * A parent 'process' method */boolUaBuilder::processUaDeviceEvent( const Sptr < UaDeviceEvent > uaDeviceEvent ){    cpLog( LOG_DEBUG, "Device Event" );    /// The following situtation can occur:    ///   1.  user goes onhook    ///   2.  user goes offhook immediately    ///   3.  state machine processes the onhook and removes callid    ///   4.  state machine processes the offhook with original callid    ///   5.  the original callid no longer exists    /// In this case, we will just change the callId in deviceEvent    /// to the one in the device    /// Short term fix only.    bool exit = false;  /// Tells us whether or not to exit UaBuilder    if ( !(uaDeviceEvent->callId == UaDevice::instance()->getCallId()) )    {	uaDeviceEvent->callId = UaDevice::instance()->getCallId();    }    if ( uaDeviceEvent->callId == 0 )    {	if (  ( uaDeviceEvent->type == DeviceEventHookUp ) )	{	    cpLog( LOG_DEBUG, "User Offhook" );	    Sptr < SipCallId > newCallId = new SipCallId;	    	    if ( UaConfiguration::instance()->getCallIdOn() )	    {		// Use callId from config file		Data newId( UaConfiguration::instance()->getCallId() );				newCallId->setLocalId( newId );	    }	    	    callInfo = calls->newCall( *newCallId );	    assert( callInfo != 0 );	    callInfo->setFeature( stateMachine );	    callInfo->setState( stateMachine->findState( "StateIdle" ) );	    UaDevice::instance()->setCallId( newCallId );	    uaDeviceEvent->setSipStack( sipStack );	}	else        // We have no callId & the event is NOT an offhook	{	    cpLog( LOG_ERR, "Missing Call Id for hardware event" );	    exit = true;	    return exit;	}    }    // We must have a valid callId to enter this else statement    else    {	callInfo = calls->findCall( *(uaDeviceEvent->callId) );	uaDeviceEvent->setSipStack( sipStack );	assert( callInfo != 0 );    }    return exit;}/** * A parent 'process' method */boolUaBuilder::processUaDigitEvent( const Sptr < UaDigitTimerEvent >				   uaDigitEvent ){    cpLog( LOG_DEBUG, "ua Digit Event" );    if ( uaDigitEvent->callId == 0 )    {	if ( UaConfiguration::instance()->getLoadGenOn() )	{	    if (uaDigitEvent->getLoadGenSigType() == LoadGenStartCall)	    {		cpLog(LOG_DEBUG, ">>> New Call! <<<" );		Sptr < SipCallId > newCallId = new SipCallId;		uaDigitEvent->callId = newCallId;		callInfo = calls->newCall( *newCallId );		assert( callInfo != 0 );		callInfo->setFeature( stateMachine );				if (UaConfiguration::instance()->getRunMode() == "Calling" )		{		    callInfo->setState			( stateMachine->findState( "StateAutoIdle" ) );		}		else if( UaConfiguration::instance()->getRunMode() == "RSTest")		{		    callInfo->setState			( stateMachine->findState( "StateAutoRS" ) );		}		uaDigitEvent->setSipStack( sipStack );	    }	}	else  // Loadgen is off	{	    cpLog( LOG_DEBUG, "Discarded" );	    return true;	}    }    else  // uaDigitEvent->callId != 0     {	callInfo = calls->findCall( *(uaDigitEvent->callId) );	if ( callInfo == 0 )	{	    cpLog( LOG_DEBUG, "Discard late timer event" );	    return true;	}	uaDigitEvent->setSipStack( sipStack );    }    return false;}/** * A parent 'process' method */boolUaBuilder::processUaTimerEvent( const Sptr < UaTimerEvent > uaTimerEvent ){    Sptr < SipCallId > callId = uaTimerEvent->getCallId();    assert( callId != 0 );    callInfo = calls->findCall( *callId );    assert( callInfo != 0 );    uaTimerEvent->setSipStack( sipStack );    return false;}/** * A child 'handle' method */boolUaBuilder::handleStatusMsg( const Sptr < SipEvent > sipEvent ){    cpLog( LOG_DEBUG, "In handleStatusMsg()" );    /// Pull the StatusMsg out of the SipEvent    Sptr < StatusMsg > statusMsg;    statusMsg.dynamicCast( sipEvent->getSipMsg() );    /// Sanity check; this checked out ok in main process method    assert( statusMsg != 0 );    /// Register    if ( UaConfiguration::instance()->getRegisterOn() &&	 statusMsg->getCSeq().getMethod() == "REGISTER" )    {	if ( statusMsg->getStatusLine().getStatusCode() < 200 )	{	    /// just return, prevents re-registration loop	    cpLog( LOG_DEBUG, "REGISTER response: code %d",                   statusMsg->getStatusLine().getStatusCode() );	    return true;	}	if ( registrationManager->handleRegistrationResponse( *statusMsg ) )	{	    cout << VTime::strftime("%y/%m/%d %H:%M:%S")		 << " Registration OK" << endl;	    cout << "Ready" << endl;	}	else	{	    cpLog( LOG_WARNING, "Registration status code %d",                                statusMsg->getStatusLine().getStatusCode() );	}	return true;    }    /// Subscribe    if ( UaConfiguration::instance()->getSubscribeOn() &&	 statusMsg->getCSeq().getMethod() == "SUBSCRIBE" )    {	if ( subManager == 0 )	{	    cpLog( LOG_ERR, "SubscribeManager is not running" );	}	else	{	    if ( subManager->handleSubscribeResponse( *statusMsg ) )		cout << "Subscribe Ok" << endl;	    else		cpLog( LOG_ERR, "Subscribe failed" );	}	return true;    }    /// Notify    if ( UaConfiguration::instance()->getSubscribeOn() )    {	Sptr < NotifyMsg > notifyMsg;	notifyMsg.dynamicCast( sipEvent->getSipMsg() );	if ( notifyMsg != 0 )	{	    subManager->handleNotify( *notifyMsg );	}    }    return false; // a return to the calling method} /// end handleStatusMsg()/** * A child 'handle' method */boolUaBuilder::handleCallWaiting( Sptr< CallInfo > callInfo  ){    if ( UaConfiguration::instance()->getCallWaitingOn() )    {	cpLog( LOG_DEBUG, "Call Waiting ON" );	/// if call waiting enabled, the new call will ring	/// the set even when there is an active call	HardwareStatusType hdwStatus =	    UaDevice::instance()->getHardwareStatus();#if 0	if ( hdwStatus == HARDWARE_UNAVAILABLE )	{	    cpLog( LOG_DEBUG, "Hardware Unavailabe" );	    /// Device is in use	    callInfo->setState( stateMachine->findState( "StateBusyHere" ) );	}	else	{#endif	    string nextState = "StateIdle";	    	    if ( hdwStatus == HARDWARE_AVAILABLE )	    {		cpLog( LOG_DEBUG, "Hardware Available" );	    }	    else	    {		cpLog( LOG_DEBUG, "Hardware available for call waiting only" );	    }	    Sptr < SipCallId > activeId = UaDevice::instance()->getCallId();	    /// allow call waiting only if the current call	    /// is talking to one party	    if ( activeId != 0 )	    {		Sptr < UaCallInfo > activeCall = calls->findCall( callId );		if ( activeCall != 0 )		{		    if ( activeCall->getContactList()->size() > 1 )			nextState = "StateBusyHere";		    		}	    }	    // New Call	    callInfo->setState( stateMachine->findState( nextState ) );// bug://	    callInfo->setState( stateMachine->findState( "StateIdle" ) );#if 0	}#endif    }    /// Call Waiting is NOT turned on:    else    {	cpLog( LOG_DEBUG, "Call Waiting Off" );	/// if call waiting is disabled, the new call will not ring	/// the set when there is an active call	if ( UaDevice::instance()->getHardwareStatus() == HARDWARE_AVAILABLE )	{	    cpLog( LOG_DEBUG, "Hardware Available" );	    // New Call	    callInfo->setState( stateMachine->findState( "StateIdle" ) );	}	else	{	    cpLog( LOG_DEBUG, "Hardware Unavailable" );	    // Device is in use	    callInfo->setState( stateMachine->findState( "StateBusyHere" ) );	}    }    return false;}/** */voidUaBuilder::sendEvent( const Sptr < SipProxyEvent > nextEvent ){    nextEvent->setCallInfo ( callInfo, calls );    stateMachine->process( nextEvent );    return;}///voidUaBuilder::setSipStack( const Sptr < SipTransceiver > sipstack ){    sipStack = sipstack;}///voidUaBuilder::setSubscribeManager( const Sptr < SubscribeManager > subscribeManager ){    subManager = subscribeManager;}///voidUaBuilder::startRegistration(){    if ( UaConfiguration::instance()->getRegisterOn() )    {        registrationManager = new RegistrationManager( sipStack );        assert( registrationManager != 0 );    }}    // UaBuilder::startRegistration

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -