/*
* Copyright (c) 2002-2010 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:  In this state, BTSAC is waiting for open audio request.
*
*/




// INCLUDE FILES
#include "btsacStateSuspended.h"
#include "btsacStateListening.h"
#include "btsacStateStreaming.h"
#include "btsacStateConnected.h"
#include "btsacStateAborting.h"
#include "btsacactive.h"
#include "btsacSEPManager.h"
#include "btsacStreamerController.h"
#include "btsacGavdp.h"
#include "debug.h"
#include <e32property.h>
#include "btaudioremconpskeys.h"

// A2DP codec-specific element definitions
// in bluetoothAV.h
using namespace SymbianBluetoothAV;


// ================= MEMBER FUNCTIONS =======================

// -----------------------------------------------------------------------------
// CBtsacSuspended::NewL
// -----------------------------------------------------------------------------
//
CBtsacSuspended* CBtsacSuspended::NewL(CBTSAController& aParent)
    {
    CBtsacSuspended* self = new( ELeave ) CBtsacSuspended(aParent);
    return self;
    }    

// -----------------------------------------------------------------------------
// CBtsacSuspended::CBtsacSuspended
// -----------------------------------------------------------------------------
//
CBtsacSuspended::CBtsacSuspended(CBTSAController& aParent)
:   CBtsacState(aParent, EStateSuspended), iOpenAudioReq(EFalse)
    {
    }
  
// -----------------------------------------------------------------------------
// CBtsacSuspended::~CBtsacSuspended
// -----------------------------------------------------------------------------
//    
CBtsacSuspended::~CBtsacSuspended()
    {
    TRACE_FUNC
    }

// -----------------------------------------------------------------------------
// CBtsacSuspended::EnterL
// -----------------------------------------------------------------------------
//
void CBtsacSuspended::EnterL()
    {
	TRACE_STATE(_L("[BTSAC State] Suspended"))
	_LIT(KName, "CBtsacStateSuspended");
	const TDesC& Name = KName;
	Parent().iGavdp->RegisterObserver(this, Name);
    }

// -----------------------------------------------------------------------------
// CBtsacSuspended::CancelActionL
// -----------------------------------------------------------------------------
//
void CBtsacSuspended::CancelActionL(TInt aError)
	{
	TRACE_FUNC
	Parent().CompletePendingRequests(KOpenAudioReq, aError);
	Parent().ChangeStateL(CBtsacListening::NewL(Parent(), EResetGavdp, aError));
	}
    
// -----------------------------------------------------------------------------
// CBtsacSuspended::OpenAudioLinkL
// -----------------------------------------------------------------------------
//
void CBtsacSuspended::OpenAudioLinkL(const TBTDevAddr& aAddr)
	{  
	TRACE_FUNC
	TAvdtpSEPInfo SEPInfo;
	if (Parent().iRemoteSEPs->GetInfo(Parent().GetSEPIndex(), SEPInfo) || (aAddr != Parent().GetRemoteAddr()))
		{
		TRACE_INFO((_L("CBtsacSuspended::OpenAudioLinkL() Couldn't retrieve SEP Info!")))
		Parent().CompletePendingRequests(KOpenAudioReq, KErrGeneral);
       	return;
		}
	iOpenAudioReq = ETrue;
	Parent().SetRemoteAddr(aAddr);
	TSEID remoteSEPid = SEPInfo.SEID();
	Parent().iGavdp->StartStreams(remoteSEPid);
	}

// -----------------------------------------------------------------------------
// CBtsacSuspended::CancelOpenAudioL
// -----------------------------------------------------------------------------
//
void CBtsacSuspended::CancelOpenAudioL(const TBTDevAddr& /*aAddr*/)
    {
    TRACE_FUNC
	CancelActionL(KErrCancel);
    }
    
// -----------------------------------------------------------------------------
// CBtsacSuspended::DisconnectL
// -----------------------------------------------------------------------------
//
void CBtsacSuspended::DisconnectL()
	{
	TRACE_FUNC
	Parent().CompletePendingRequests(KDisconnectReq, KErrNone);
	CancelActionL(KErrCancel);
	}
	
// -----------------------------------------------------------------------------
// CBtsacSuspended::GAVDP_StartStreamsConfirm()
// -----------------------------------------------------------------------------
//    
void CBtsacSuspended::GAVDP_StartStreamsConfirm()
	{
	TRACE_FUNC
	if ( Parent().iStreamer->StartStream(Parent().iStreamingSockets[0], Parent().iStreamer->FrameLength()) != KErrNone ) 
	 	{
		TRACE_INFO((_L("CBtsacSuspended::GAVDP_StartStreamsConfirm() [ERR] Could not start streaming!")))
		TInt err = Parent().AbortStream();
		if(err)
			{
			TRACE_INFO((_L("CBtsacSuspended::GAVDP_StartStreamsConfirm() Couldn't abort stream.")))
			}
		TRAP_IGNORE(CancelActionL(KErrDisconnected));
	 	}
	 else
	 	{
	 	Parent().CompletePendingRequests(KOpenAudioReq, KErrNone);
		TRAP_IGNORE(Parent().ChangeStateL(CBtsacStreaming::NewL(Parent(), EAudioOpenedByAFW, EFalse)));
	 	}
	}
	
// -----------------------------------------------------------------------------
// CBtsacSuspended::GAVDP_StartIndication
// -----------------------------------------------------------------------------
//      
TInt CBtsacSuspended::GAVDP_StartIndication(TSEID aLocalSEID)
	{
	TRACE_INFO((_L("CBtsacSuspended::GAVDP_StartIndication() aLocalSEID: %d"), aLocalSEID.SEID()))	
	(void)aLocalSEID;
	// Accessory has send this indication.
	// TStateStreaming state can use this indication to start audio automatically then later.
	RProperty::Set(KBTAudioRemCon, KBTAudioPlayerControl, EBTAudioResumePlayer);
	TRAPD(err, Parent().ChangeStateL(CBtsacStreaming::NewL(Parent(), EAudioOpenedByAcc, EFalse)));
	if(err)
		{
		return KErrNoMemory;
		}
	return KErrNone;
	}

// -----------------------------------------------------------------------------
// CBtsacSuspended::GAVDP_ReleaseIndication
// -----------------------------------------------------------------------------
//
void CBtsacSuspended::GAVDP_ReleaseIndication(TSEID aSEID)
	{
	TRACE_INFO((_L("CBtsacSuspended::GAVDP_ReleaseIndication() aSEID:%d"), aSEID.SEID()))	
	(void)aSEID; 
	Parent().AccessoryClosedAudio(Parent().GetRemoteAddr());
	Parent().CleanSockets();
	Parent().CompletePendingRequests(KOpenAudioReq, KErrCancel);
	TRAP_IGNORE(Parent().ChangeStateL(CBtsacConnected::NewL(Parent(), EConnExists)));
	}

// -----------------------------------------------------------------------------
// CBtsacSuspended::HandleGavdpErrorL
// -----------------------------------------------------------------------------
//	
void CBtsacSuspended::HandleGavdpErrorL(TInt aError)
	{
	TRACE_FUNC
	TInt err = KErrNone;
	
	switch (aError)
		{
		case KErrAvdtpRequestTimeout: // -18005
			{
			TRACE_INFO((_L("CBtsacSuspended::HandleGavdpErrorL() Request TIMEOUT")))
			err = Parent().AbortStream();
			if(!err)
				{
				// Complete pending request(s) in Aborting state
				Parent().ChangeStateL(CBtsacAborting::NewL(Parent()));
				}
			else
				{
				CancelActionL(KErrDisconnected);
				}
			break;
			}
		case (KErrAvdtpSignallingErrorBase - EAvdtpBadState): // -18094
			{
			if(iOpenAudioReq)
				{
				err = Parent().AbortStream();
				if(!err)
					{
					// Complete Audio request in Aborting state
					Parent().ChangeStateL(CBtsacAborting::NewL(Parent()));
					}
				else
					{
					CancelActionL(KErrDisconnected);
					}
				}
			else
				{					
				// For some reason remote rejected our suspend command (which was initiated in streaming state).
				// According to the specification it is acceptor's responsibilty to cope with this situation,
				// so we can stay in suspended state.
				// For safety's sake complete close audio request if any.
		        Parent().CompletePendingRequests(KCloseAudioReq, KErrNone);
				}
		    break;
			}
		case KErrHCILinkDisconnection: // -6305
		case KErrDisconnected: // -36
			{
			TRACE_INFO((_L("CBtsacSuspended::HandleGavdpErrorL() Signalling disconnected.")))
			CancelActionL(aError);
			break;
			}
		default:
			{
			// Unknown error. For safety's sake let's disconnect a2dp link and inform btaudioman
			TRACE_INFO((_L("CBtsacSuspended::HandleGavdpErrorL() Unknown error, goes to listening")))
			CancelActionL(KErrDisconnected);
			break;
			}
		}
	}

//  End of File  
