natplugins/natpnatfwsdpprovider/src/nspstateconnected.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 16 Apr 2010 15:21:04 +0300
changeset 13 861e78e4e84c
parent 0 1bce908db942
permissions -rw-r--r--
Revision: 201011 Kit: 201015

/*
* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Connected state implementation.
*
*/

#include <sdpdocument.h>
#include "nspstateconnected.h"
#include "nspevents.h"
#include "nspsession.h"
#include "nspactionset.h"
#include "nspsessiondata.h"
#include "nspdefs.h"

// ======== MEMBER FUNCTIONS ========
// ---------------------------------------------------------------------------
// CNSPStateConnected::CNSPStateConnected
// ---------------------------------------------------------------------------
//
CNSPStateConnected::CNSPStateConnected()
    {
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::NewL
// ---------------------------------------------------------------------------
//
CNSPStateConnected* CNSPStateConnected::NewL()
    {
    CNSPStateConnected* self = CNSPStateConnected::NewLC();
    CleanupStack::Pop( self );
    return self;
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::NewLC
// ---------------------------------------------------------------------------
//
CNSPStateConnected* CNSPStateConnected::NewLC()
    {
    CNSPStateConnected* self = new ( ELeave ) CNSPStateConnected;
    CleanupStack::PushL( self );
    return self;
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::~CNSPStateConnected
// ---------------------------------------------------------------------------
//
CNSPStateConnected::~CNSPStateConnected()
    {
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::DoAcceptL
// ---------------------------------------------------------------------------
//
TBool CNSPStateConnected::DoAcceptL( TNSPStateMachineEvent& aEvent )
    {
    TBool accept = ETrue;
    
    User::LeaveIfError(
    		TNSPStateMachineEvent::ENat == aEvent.Request() ||
            TNSPStateMachineEvent::ECreateOffer == aEvent.Request() ||
            TNSPStateMachineEvent::EResolve == aEvent.Request() ||
            TNSPStateMachineEvent::EDecodeAnswer == aEvent.Request() ||
            TNSPStateMachineEvent::EUpdate == aEvent.Request() ||
            TNSPStateMachineEvent::EReservationStatus == aEvent.Request() ||
            TNSPStateMachineEvent::ECloseSession == aEvent.Request() ?
                    KErrNone : KErrTotalLossOfPrecision );
    
    if ( TNSPStateMachineEvent::ENat == aEvent.Request() )
    	{
    	// Events are ignored if return value from this method is 'EFalse'.
    	TNSPStateMachineMediaEvent& event = MEDIAEVENT( aEvent );
    	
    	accept = (
    		MNATFWConnectivityObserver::EReceivingActivated == event.Event() ||
        	MNATFWConnectivityObserver::ESendingActivated == event.Event() ||
        	( MNATFWConnectivityObserver::EGeneralError == event.Event() &&
        			NSP_ERROR( event.Status() ) ) );
    	}
    
    return accept;
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::DoStateEntryL
// ---------------------------------------------------------------------------
//
void CNSPStateConnected::DoStateEntryL( TNSPStateMachineEvent& aEvent )
    {
    CNSPSession& session = aEvent.Session();
    
    session.Actions().UpdateRoundL( session.Data().UpdatedSdp() );
    
    if ( ANSWERER( session.Role() ) )
        {
    	aEvent.Offer() = session.Data().ReleaseOffer();
    	aEvent.CallbackType() = TEventReturnStatus::EOfferReady;
        }
    else if ( OFFERER( session.Role() ) )
        {
    	aEvent.Answer() = session.Data().ReleaseAnswer();
    	aEvent.CallbackType() = TEventReturnStatus::EAnswerReady;
        }
    else
        {
        User::Leave( KErrArgument );
        }
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::DoReverse
// ---------------------------------------------------------------------------
//
void CNSPStateConnected::DoReverse( TNSPStateMachineEvent& aEvent )
    {
    CNSPSession& session = aEvent.Session();
    session.Data().SetOffer( NULL );
    session.Data().SetAnswer( NULL );
    session.Role() = CNSPSession::EUndefined;
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::DoApplyL
// ---------------------------------------------------------------------------
//
void CNSPStateConnected::DoApplyL( TNSPStateMachineEvent& aEvent )
    {
    switch ( aEvent.Request() )
        {
        case TNSPStateMachineEvent::ENat:
        	{
        	ControlMediaL( aEvent );
        	break;
        	}
        
        case TNSPStateMachineEvent::ECreateOffer:
            {
            ApplyCreateOfferL( aEvent );
            break;
            }
        
        case TNSPStateMachineEvent::EResolve:
            {
            ApplyResolveL( aEvent );
            break;
            }
        
        case TNSPStateMachineEvent::EDecodeAnswer:
            {
            ApplyDecodeAnswerL( aEvent );
            break;
            }
        
        case TNSPStateMachineEvent::EUpdate:
            {
            ApplyUpdateL( aEvent );
            break;
            }
        
        case TNSPStateMachineEvent::EReservationStatus:
            {
            aEvent.Status() = KNatReady;
            break;
            }
        
        case TNSPStateMachineEvent::ECloseSession:
            {
            aEvent.NextState() = KStateIndexDeActivating;
            aEvent.Status() = KNatAsync;
            break;
            }
        
        default:
            {
            User::Leave( KErrArgument );
            }
        }
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::DoExitL
// ---------------------------------------------------------------------------
//
void CNSPStateConnected::DoExitL( TNSPStateMachineEvent& aEvent )
    {
    CNSPSession& session = aEvent.Session();
    
    switch ( aEvent.Request() )
        {
        case TNSPStateMachineEvent::EResolve:
            {
            session.Data().SetOffer( aEvent.Offer()->CloneL() );
            session.Data().SetAnswer( aEvent.Answer()->CloneL() );
            session.Role() = CNSPSession::EAnswerer;
            break;
            }
        
        case TNSPStateMachineEvent::EDecodeAnswer:
            {
            session.Data().SetAnswer( aEvent.Answer()->CloneL() );
            session.Role() = CNSPSession::EOfferer;
            break;
            }
        case TNSPStateMachineEvent::ECreateOffer:
        	{
        	session.Data().SetOffer( aEvent.Offer()->CloneL() );
        	session.Role() = CNSPSession::EOfferer;
        	break;
        	}
        case TNSPStateMachineEvent::ECloseSession:
            {
            break;
            }
        
        default:
            {
            User::Leave( KErrArgument );
            }
        }
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::ControlMediaL
// ---------------------------------------------------------------------------
//
void CNSPStateConnected::ControlMediaL( TNSPStateMachineEvent& aEvent ) const
	{
	TNSPStateMachineMediaEvent& event = MEDIAEVENT( aEvent );
    TNatReturnStatus status = event.Session().Actions().ControlMediaL(
    		event.StreamId(), event.Event(), event.Status(), event.Data() );
    
    if ( NSP_TRIGGER( status ) )
    	{
    	// NOP
    	}
    else
    	{
    	event.Status() = status;
    	}
	}


// ---------------------------------------------------------------------------
// CNSPStateConnected::ApplyCreateOfferL
// ---------------------------------------------------------------------------
//
void CNSPStateConnected::ApplyCreateOfferL( TNSPStateMachineEvent& aEvent ) const
    {
    CNSPSession& session = aEvent.Session();
    TNatReturnStatus status = KNatReady;
    
    status = session.Actions().CreateStreamsL( *aEvent.Offer() );
    
    if ( KNatAsync == status )
        {	
        aEvent.NextState() = KStateIndexLocalCand;  	
        }
    else
        {
        session.Actions().LatterRoundL( *aEvent.Offer() );
        }
    aEvent.Status() = status;
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::ApplyResolveL
// ---------------------------------------------------------------------------
//
void CNSPStateConnected::ApplyResolveL( TNSPStateMachineEvent& aEvent ) const
    {
    CNSPSession& session = aEvent.Session();
    TNatReturnStatus status = KNatReady;
    
    status = session.Actions().CreateStreamsL( *aEvent.Answer() );
    
    if ( KNatAsync == status )
        {
        aEvent.NextState() = KStateIndexLocalCand;  	
        // TBD: Adding media streams, goto Localcand state.
        }
    else
        {
        session.Actions().LatterRoundL( *aEvent.Answer() );
        session.Actions().GetSessionConnInfoL( *aEvent.Offer() ); // ret ignored
        session.Actions().LocalRoundL( *aEvent.Offer() );
        }
    
    aEvent.Status() = status;
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::ApplyDecodeAnswerL
// ---------------------------------------------------------------------------
//
void CNSPStateConnected::ApplyDecodeAnswerL( TNSPStateMachineEvent& aEvent ) const
    {
    CNSPSession& session = aEvent.Session();
    
    session.Actions().GetSessionConnInfoL( *aEvent.Answer() );
    session.Actions().LocalRoundL( *aEvent.Answer() );
    }


// ---------------------------------------------------------------------------
// CNSPStateConnected::ApplyUpdateL
// ---------------------------------------------------------------------------
//
void CNSPStateConnected::ApplyUpdateL( TNSPStateMachineEvent& aEvent ) const
    {
    CNSPSession& session = aEvent.Session();
    
    if ( OFFERER( session.Role() ) )
        {
        session.Actions().LocalRoundL( *aEvent.Offer() );
        }
    else
        {
        User::Leave( KErrArgument );
        }
    }

// end of file