bluetoothengine/btsac/src/btsacStateConnected.cpp
changeset 0 f63038272f30
child 1 6a1fe72036e3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btsac/src/btsacStateConnected.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,690 @@
+/*
+* Copyright (c) 2002-2005 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 listening for remote connection
+*								 from a stereo audio accessory
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "btsacStateConnected.h"
+#include "btsacStateConfigured.h"
+#include "btsacStateConfiguring.h"
+#include "btsacStateListening.h"
+#include "btsacStateAborting.h"
+#include "btsacactive.h"
+#include "btsacGavdp.h"
+#include "btsacSEPManager.h"
+#include "btsacStreamerController.h"
+#include "debug.h"
+
+// A2DP codec-specific element definitions
+// in bluetoothAV.h
+using namespace SymbianBluetoothAV;   
+
+// Subband codec-specific values
+// in bluetoothAV.h
+using namespace SymbianSBC;   
+
+const TInt KSEPDiscoverResponseDelay = 5000000; 	// 5 sec
+const TInt KGetCapabilitiesResponseDelay = 4000000; // 4 sec
+const TInt KSEPConfigureResponseDelay = 4000000; 	// 4 sec
+const TInt KCreateBearersResponseDelay = 5000000; 	// 5 sec
+const TInt KWaitConfStartIndicationDelay = 3000000; // 3 sec
+const TInt KOneSecondDelay = 1000000; 				// 1 sec
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::NewL
+// -----------------------------------------------------------------------------
+//
+CBtsacConnected* CBtsacConnected::NewL(CBTSAController& aParent, TBTConnType aConnType)
+    {
+    CBtsacConnected* self = new( ELeave ) CBtsacConnected(aParent, aConnType);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::CBtsacConnected
+// -----------------------------------------------------------------------------
+//
+CBtsacConnected::CBtsacConnected(CBTSAController& aParent, TBTConnType aConnType)
+:	CBtsacState(aParent, EStateConnected), iSuitableSEPFoundAlready(EFalse), iConnType(aConnType),
+	iSEPFound(ESEPNotInitialized), iRemoteSEPIndex(0), iBearersQuery(EFalse), iCancelConnectReq(EFalse),
+	iAudioOpenedBy(EAudioOpenedByNone)
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::ConstructL()
+	{
+	iTimerActive = CBtsacActive::NewL(*this, CActive::EPriorityStandard, KRequestIdTimer);
+	iTimer.CreateLocal();
+	}
+    
+// -----------------------------------------------------------------------------
+// CBtsacConnected::~CBtsacConnected
+// -----------------------------------------------------------------------------
+//    
+CBtsacConnected::~CBtsacConnected()
+    {
+    TRACE_FUNC_ENTRY
+    delete iTimerActive;
+    iTimerActive = NULL;
+    iTimer.Close();
+    TRACE_FUNC_EXIT
+    }
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::EnterL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::EnterL()
+    {
+	TRACE_STATE(_L("[BTSAC State] Connected"))	
+	_LIT(KName, "CBtsacStateConnected");
+	const TDesC& Name = KName;
+	Parent().iGavdp->RegisterObserver(this, Name);
+
+	switch(iConnType)
+		{
+		case EOutgoingConnWithAudio:
+		case EOutgoingConn:
+			{
+			if(iConnType == EOutgoingConnWithAudio)
+				{
+				iAudioOpenedBy = EAudioOpenedByAFW;
+				}
+			StartTimer(KSEPDiscoverResponseDelay, KRequestIdTimer);
+			Parent().iGavdp->DiscoverSEPs(); // start with SEP discovery			
+			break;
+			}
+		case EOutgoingConnWithAudioNoDiscovery:
+		case EOutgoingConnNoDiscovery:
+			{
+			if(iConnType == EOutgoingConnWithAudioNoDiscovery)
+				{
+				iAudioOpenedBy = EAudioOpenedByAFW;
+				}
+			ConfigureL();
+			break;
+			}
+		case EIncomingConn:
+			{
+			Parent().NewAccessory(Parent().GetRemoteAddr());
+			break;
+			}
+		case EConnExists:
+			break;
+		}
+    }
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::StartTimer
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::StartTimer(TTimeIntervalMicroSeconds32 aTimeout, TInt aRequestId)
+	{
+	TRACE_FUNC
+	if (iTimerActive)
+    	{
+	    if(!iTimerActive->IsActive())
+		    {	    	
+	        iTimerActive->SetRequestId(aRequestId);
+	        iTimer.After(iTimerActive->iStatus, aTimeout);
+	        iTimerActive->GoActive();
+		    }
+        }
+    else
+    	{
+    	TRACE_INFO((_L("CBtsacConnected::StartTimer, Timer Active doesn't exist.")))
+    	}
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::StopTimer
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::StopTimer()
+	{
+	TRACE_FUNC
+	if (iTimerActive)
+    	{
+		iTimerActive->Cancel();
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::CancelActionL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::CancelActionL(TInt aError, TBTSACGavdpResetReason aGavdpReset)
+    {
+    TRACE_FUNC
+    StopTimer();
+	Parent().CompletePendingRequests((KConnectReq | KOpenAudioReq), aError);
+	Parent().ChangeStateL(CBtsacListening::NewL(Parent(), aGavdpReset, aError));
+    }
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::OpenAudioLinkL
+// -----------------------------------------------------------------------------
+//    
+void CBtsacConnected::OpenAudioLinkL(const TBTDevAddr& aAddr)
+	{  
+	TRACE_FUNC	
+	
+	if (Parent().GetRemoteAddr() != aAddr)
+		{
+		TRACE_INFO((_L("CBtsacConnected::OpenAudio, Error!")))
+		CancelActionL(KErrNotFound, EGavdpResetReasonGeneral);
+		return;
+		}
+	iAudioOpenedBy = EAudioOpenedByAFW;
+	Parent().SetRemoteAddr(aAddr);
+	
+	if(iConnType == EIncomingConn)
+		{
+		// Accessory has created connection to us. Don't open audio immediately, 
+		// let's wait for a while if accessory starts configuration. This way
+		// we can avoid configure collision.
+		StartTimer(KOneSecondDelay, KRequestIdWaitRemoteConfStart);
+		}
+	else
+		{
+		StartConfigurationL();
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::CancelOpenAudioLinkL()
+// -----------------------------------------------------------------------------
+//    
+void CBtsacConnected::CancelOpenAudioLinkL()
+    {
+    TRACE_FUNC
+	CancelActionL(KErrCancel, EGavdpResetReasonGeneral);
+    }
+	
+// -----------------------------------------------------------------------------
+// CBtsacConnected::DisconnectL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::DisconnectL()
+	{
+	TRACE_FUNC
+	Parent().CompletePendingRequests(KDisconnectReq, KErrNone);
+	CancelActionL(KErrCancel, EGavdpResetReasonDisconnect);
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::CancelConnectL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::CancelConnectL()
+    {
+    TRACE_FUNC
+    if(!iBearersQuery)
+    	{
+		CancelActionL(KErrCancel, EGavdpResetReasonGeneral);
+    	}
+    else
+    	{
+    	// We have to wait bearers to be completed
+    	TRACE_INFO((_L("CBtsacConnected::CancelConnectL() Wait for BearerReady.")))
+    	iCancelConnectReq = ETrue;
+    	}
+    }
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::StartConfigurationL()
+// -----------------------------------------------------------------------------
+//    
+void CBtsacConnected::StartConfigurationL()
+	{
+	TRACE_FUNC
+	if (!Parent().iRemoteSEPs->NoOfSEPs())	// if accessory info not stored already
+		{
+		iRemoteSEPIndex = 0;
+		Parent().InitializeSEPManager();
+		StartTimer(KSEPDiscoverResponseDelay, KRequestIdTimer);
+		Parent().iGavdp->DiscoverSEPs();		// start with SEP discovery
+		}
+	else	// otherwise we have explored this accessory before - go straight to configure 
+		{
+		ConfigureL();
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::ConfigureL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::ConfigureL()
+    {
+    TRACE_FUNC
+   
+ 	RPointerArray<TAvdtpServiceCapability> SEPCapabilities;
+    if ((Parent().iRemoteSEPs->GetCaps(Parent().GetSEPIndex(), SEPCapabilities)) )
+		{
+		TRACE_INFO((_L("CBtsacConnected::Configure() Couldn't retrieve Capabilities !")))
+		CancelActionL(KErrCancel, EGavdpResetReasonGeneral);
+	   	SEPCapabilities.Close();
+		return; 
+		}   
+    
+	TRACE_INFO((_L("CBtsacConnected::Configure() Retrieve %d capabilities"), SEPCapabilities.Count()))
+   	// loop through all capablities to find sbc codec capablities
+   	TSBCCodecCapabilities SBCCaps; 
+   	TAvdtpMediaTransportCapabilities MedTransCaps; 
+   	for (TInt index=0; index < SEPCapabilities.Count(); index++)		
+   		{
+		TAvdtpServiceCapability* cap = SEPCapabilities[index];
+		TAvdtpServiceCategory cat = cap->Category();
+		if ( cat == EServiceCategoryMediaCodec )
+			{
+		    SBCCaps = static_cast<TSBCCodecCapabilities&>(*cap);	
+		    TRACE_INFO((_L("CBtsacConnected::Configure() SBC Caps retrieved.")))
+			}
+		else if ( cat == EServiceCategoryMediaTransport )
+			{
+			MedTransCaps = static_cast<TAvdtpMediaTransportCapabilities&>(*cap);
+			TRACE_INFO((_L("CBtsacConnected::Configure() Media Transport Caps retrieved.")))
+			}
+   		}
+   	SEPCapabilities.Close();
+
+   // Check if headset's capabilities suits us				
+	TRACE_INFO((_L("CBtsacConnected::Configure() Accessory Sampling Frequencies: %d"), SBCCaps.SamplingFrequencies()))
+	TRACE_INFO((_L("CBtsacConnected::Configure() Accessory Channel modes: %d"), SBCCaps.ChannelModes()))
+	TRACE_INFO((_L("CBtsacConnected::Configure() Accessory Blocks: %d"), SBCCaps.BlockLengths()))
+	TRACE_INFO((_L("CBtsacConnected::Configure() Accessory SubBands: %d"), SBCCaps.Subbands()))
+	TRACE_INFO((_L("CBtsacConnected::Configure() Accessory Alloc method: %d"), SBCCaps.AllocationMethods()))
+	TRACE_INFO((_L("CBtsacConnected::Configure() Accessory Max bitpool: %d"), SBCCaps.MaxBitpoolValue()))
+	TRACE_INFO((_L("CBtsacConnected::Configure() Accessory Min bitpool: %d"), SBCCaps.MinBitpoolValue()))
+	
+	if (Parent().iStreamer->ConfigureSEP(SBCCaps) )
+		{
+   		TRACE_INFO((_L("CBtsacConnected::Configure() Streamer couldn't configure SEP !")))
+        CancelActionL(KErrCancel, EGavdpResetReasonGeneral); 
+        return;   // capabilites doesn't suit us
+		}
+		
+	TAvdtpSEPInfo SEPInfo;
+	if (Parent().iRemoteSEPs->GetInfo(Parent().GetSEPIndex(), SEPInfo))
+		{
+		TRACE_INFO((_L("CBtsacConnected::Configure() Couldn't retrieve SEP Info !")))
+		CancelActionL(KErrCancel, EGavdpResetReasonGeneral); 
+        return;   // capabilites doesn't suit us
+		}
+	TSEID remoteSEPid = SEPInfo.SEID(); 	
+	// local sep index is hard coded cause current implementation is only sbc encoded
+	TSEID localSEPid = TSEID(1, ETrue);
+ 	
+ 	StartTimer(KSEPConfigureResponseDelay, KRequestIdTimer);
+	if ( Parent().iGavdp->ConfigureSEP(localSEPid, remoteSEPid , SBCCaps, MedTransCaps ) )
+		{
+		TRACE_INFO((_L("CBtsacConnected::Configure() ConfigureSEP returned Error !!!")))
+		CancelActionL(KErrCancel, EGavdpResetReasonGeneral);
+		}
+    }
+    
+// -----------------------------------------------------------------------------
+// CBtsacConnected::GetCapabilitiesOfAllSEPs
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::GetCapabilitiesOfAllSEPs()
+	{
+	TRACE_INFO((_L("CBtsacConnected::GetCapabilitiesOfAllSEPs() CurrentSEP:%d"), iRemoteSEPIndex))
+	TRACE_INFO((_L("CBtsacConnected::GetCapabilitiesOfAllSEPs() Total Remote SEPs registered:%d"), Parent().iRemoteSEPs->NoOfSEPs()))
+
+	if ( iRemoteSEPIndex < Parent().iRemoteSEPs->NoOfSEPs() )
+		{
+		TAvdtpSEPInfo SEPInfo;
+		if (!Parent().iRemoteSEPs->GetInfo(iRemoteSEPIndex, SEPInfo))
+			{
+			TSEID id = SEPInfo.SEID(); 
+			Parent().iGavdp->GetCapabilities(id);	
+			}
+		}
+	else // we have covered all SEPs
+		{
+		StopTimer();
+		// store all info in our db
+		//Parent().StoreAccInfo();  // stores iRemoteSEPs (SEPManager) into database
+		iSuitableSEPFoundAlready = EFalse;
+		
+		if ( iSEPFound == ESEPConfigure ) 
+			{
+			TRAP_IGNORE(ConfigureL());
+			}
+		else if ( iSEPFound == ESEPInUse )
+			{
+			// We have open audio or connect request pending but do not complete it yet. We expect that
+			// accessory will start configure us. We should receive GAVDP_ConfigurationStartIndication
+			// from the remote and remote will configure us. Eventually acc FW's open audio request
+			// will be completed in CBTsacConfigured state and connect request will be completed in
+			// CBTsacConfiguring state.
+
+			// For safety's sake start timer to protect the situation where we do not receive
+			// GAVDP_ConfigurationStartIndication.
+			StartTimer(KWaitConfStartIndicationDelay, KRequestIdTimer);
+			}
+		else // no audio sbc sink sep found
+			{
+			TRAP_IGNORE(CancelActionL(KErrCancel, EGavdpResetReasonGeneral));
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::GAVDP_SEPDiscovered
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::GAVDP_SEPDiscovered(const TAvdtpSEPInfo& aSEPInfo)
+	{
+	TRACE_INFO((_L("CBtsacConnected:::GAVDP_SEPDiscovered() SEID: %d  InUse: %d  MediaType: %d  IsSink: %d"),
+				aSEPInfo.SEID().SEID(), aSEPInfo.InUse(), aSEPInfo.MediaType(), aSEPInfo.IsSink()))
+	
+	// BTSAC cares only about audio SEPs which are sink
+     if (aSEPInfo.MediaType() == EAvdtpMediaTypeAudio && aSEPInfo.IsSink() )
+     	{
+  		TRAPD(err, Parent().iRemoteSEPs->NewSEPL(aSEPInfo))
+		if (!err)
+			{
+			Parent().iRemoteSEPs->SetState(aSEPInfo.SEID(), CBTSACStreamEndPoint::EDiscoveredRemote, &aSEPInfo);
+			}
+		else // internal problem
+			{
+  			TRAP_IGNORE(CancelActionL(KErrCancel, EGavdpResetReasonGeneral));
+			}
+     	}
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::GAVDP_SEPDiscoveryComplete
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::GAVDP_SEPDiscoveryComplete()
+	{
+	TRACE_FUNC
+	StopTimer();
+	if ( Parent().iRemoteSEPs->NoOfSEPs() )
+		{
+		StartTimer(KGetCapabilitiesResponseDelay, KRequestIdTimer);
+		GetCapabilitiesOfAllSEPs();
+		}
+	else // remote A2DP has no 'audio' 'sink' SEPs ! naughty remote
+		{
+		TRACE_INFO((_L("CBtsacConnected::GAVDP_SEPDiscoveryComplete() Remote A2dP has no 'audio' 'sink' SEPs !")))
+		TRAP_IGNORE(CancelActionL(KErrCancel, EGavdpResetReasonGeneral));
+		}
+	}
+	
+// -----------------------------------------------------------------------------
+// CBtsacConnected::GAVDP_SEPCapability
+// -----------------------------------------------------------------------------
+//	
+void CBtsacConnected::GAVDP_SEPCapability(TAvdtpServiceCapability* aCapability)
+	{
+	TRACE_INFO((_L("CBtsacConnected::GAVDP_SEPCapability(%d)"), aCapability->Category()))
+
+	Parent().iRemoteSEPs->StoreCaps(iRemoteSEPIndex, aCapability);
+	
+	if( iSuitableSEPFoundAlready )
+		{
+		return; 
+		}
+
+	if ( aCapability->Category() == EServiceCategoryMediaCodec )
+		{
+		TAvdtpMediaCodecCapabilities& codecCaps = static_cast<TAvdtpMediaCodecCapabilities&>(*aCapability);
+		TAvdtpSEPInfo SEPInfo;
+		TBool InUse = EFalse;
+
+		if ( !Parent().iRemoteSEPs->GetInfo(iRemoteSEPIndex, SEPInfo))
+			{
+			InUse = SEPInfo.InUse();
+			}
+		else
+			{
+			TRACE_INFO((_L("CBtsacConnected::GAVDP_SEPCapability() Couldn't retrieve SEP Info !")))
+			return;
+			}
+
+		if ( (codecCaps.MediaCodecType() == EAudioCodecSBC) && !InUse) // found SEP that we are interested in
+			{
+			TRACE_INFO((_L("CBtsacConnected::GAVDP_SEPCapability() Found SBC Audio Sink SEP !!!")))
+			iSuitableSEPFoundAlready = ETrue;
+			iSEPFound = ESEPConfigure;
+			Parent().SetSEPIndex(iRemoteSEPIndex);
+			}
+		else
+			{
+			TRACE_INFO((_L("CBtsacConnected::GAVDP_SEPCapability() Remote SEP In Use or Codec Type not suitable !!!")))
+			iSEPFound = InUse ? ESEPInUse : ESEPCodecTypeNotAllowed;
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::GAVDP_SEPCapabilityComplete
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::GAVDP_SEPCapabilityComplete()
+	{
+	TRACE_FUNC
+	iRemoteSEPIndex++;	
+	GetCapabilitiesOfAllSEPs();
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::GAVDP_ConfigurationConfirm
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::GAVDP_ConfigurationConfirm()
+	{
+	TRACE_FUNC
+	StopTimer();
+	TAvdtpSEPInfo SEPInfo;
+	if (Parent().iRemoteSEPs->GetInfo(Parent().GetSEPIndex(), SEPInfo))
+		{
+		TRACE_INFO((_L("CBtsacConnected::GAVDP_ConfigurationConfirm Couldn't retrieve SEP Info !")))
+		TRAP_IGNORE(CancelActionL(KErrCancel, EGavdpResetReasonGeneral));
+       	return;   // cannot get remote SEP capabilites 
+		}
+	TSEID remoteSEPid = SEPInfo.SEID();
+	TRACE_INFO((_L("CBtsacConnected::GAVDP_ConfigurationConfirm() Asking for bearer for remote SEID(%d)"), remoteSEPid.SEID()))	
+	iBearersQuery = ETrue;
+	StartTimer(KCreateBearersResponseDelay, KRequestIdTimer);
+	Parent().iGavdp->CreateBearers(remoteSEPid);
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::GAVDP_BearerReady
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::GAVDP_BearerReady(RSocket aNewSocket, const TAvdtpSockAddr& aAddr)
+	{
+	TRACE_FUNC
+	TRACE_INFO((_L("CBtsacConnected::GAVDP_BearerReady() SEID: %d"), aAddr.SEID().SEID()))
+	(void)aAddr.SEID(); 	
+	StopTimer();
+	if(!iCancelConnectReq)
+		{		
+		if(iConnType != EIncomingConn)
+			{
+			// New accessory has been already informed if connection type is incoming,
+			// otherwise tell about new accessory
+		    Parent().NewAccessory(Parent().GetRemoteAddr());
+			}
+		
+		if(iConnType == EOutgoingConn || iConnType == EOutgoingConnNoDiscovery)
+			{
+			// If connection is without audio, just complete pending connect request if any.
+			// Otherwise pending request(s) is/are completed in configured state.
+			Parent().CompletePendingRequests(KConnectReq, KErrNone);
+			}			
+		TRAP_IGNORE(Parent().ChangeStateL(CBtsacConfigured::NewL(Parent(), aNewSocket, iAudioOpenedBy, EStreamConfiguredBySrc)));
+		}
+	else
+		{
+		TRACE_ASSERT(Parent().iStreamingSockets.Count() == 0, EBTPanicSocketExists)
+		TRACE_INFO((_L("[SOCKET] created.")))
+		Parent().iStreamingSockets.Append(aNewSocket);
+		Parent().CompletePendingRequests(KCompleteAllReqs, KErrCancel);
+		TRAP_IGNORE(Parent().ChangeStateL(CBtsacListening::NewL(Parent(), EGavdpResetReasonGeneral, KErrNone)));
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::GAVDP_AbortIndication
+// -----------------------------------------------------------------------------
+//	
+void CBtsacConnected::GAVDP_AbortIndication(TSEID aSEID)
+	{
+	TRACE_INFO((_L("CBtsacConnected::GAVDP_AbortIndication() SEID:%d"), aSEID.SEID()))
+	(void)aSEID;
+	TRAP_IGNORE(CancelActionL(KErrDisconnected, EGavdpResetReasonNone));
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::GAVDP_ConfigurationStartIndication
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::GAVDP_ConfigurationStartIndication(TSEID aLocalSEID, TSEID aRemoteSEID)
+	{
+    TRACE_INFO((_L("CBtsacConnected::GAVDP_ConfigurationStartIndication() LocalSEID: %d, RemoteSEID: %d"), aLocalSEID.SEID(), aRemoteSEID.SEID()))
+    StopTimer();
+	Parent().InitializeSEPManager();
+	TRAP_IGNORE(Parent().ChangeStateL(CBtsacConfiguring::NewL(Parent(), aLocalSEID, aRemoteSEID)));
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::RequestCompletedL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::RequestCompletedL(CBtsacActive& aActive)
+    {
+	TRACE_FUNC
+	switch(aActive.RequestId())
+		{
+		case KRequestIdTimer:
+			{
+			if(!iBearersQuery)
+				{				
+			// Go to listening state, gavdp will be shutdown in listening state
+			CancelActionL(KErrCancel, EGavdpResetReasonNone);
+				}
+			else
+				{
+				// If bearers query timer has expired, lets handle it separately.		
+				Parent().iGavdp->Cancel();
+				TInt err = Parent().AbortStream();
+				if(!err)
+					{
+					Parent().ChangeStateL(CBtsacAborting::NewL(Parent()));
+					}
+				else
+					{
+					CancelActionL(KErrCancel, EGavdpResetReasonGeneral);
+					}
+				}
+			break;
+			}
+		case KRequestIdWaitRemoteConfStart:
+			{
+			// Remote didn't configure us and we have open audio request from acc fw.
+			// Let's configure the link and open audio by our selves.
+			StartConfigurationL();
+			break;
+			}
+		default:
+			{
+			TRACE_INFO((_L("CBtsacConnected::RequestCompletedL() Unknown request")))
+			break;
+			}				
+		}
+    }
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::CancelRequest
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::CancelRequest(CBtsacActive& aActive)
+	{
+	TRACE_FUNC
+	(void)aActive;
+	iTimer.Cancel();
+	}    
+
+// -----------------------------------------------------------------------------
+// CBtsacConnected::HandleGavdpErrorL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConnected::HandleGavdpErrorL(TInt aError)
+	{
+	TRACE_FUNC
+	StopTimer();
+	switch (aError)
+		{
+		case KErrAvdtpRequestTimeout: // -18005
+			{
+			TRACE_INFO((_L("CBtsacConnected::HandleGavdpErrorL() Request TIMEOUT")))
+			// Go to listening state, gavdp will be shutdown in listening state
+			CancelActionL(KErrDisconnected, EGavdpResetReasonNone);
+			break;
+			}
+			
+		case KErrHCILinkDisconnection: // -6305
+		case KErrDisconnected: // -36
+			{
+			TRACE_INFO((_L("CBtsacConnected::HandleGavdpErrorL() Signalling disconnected.")))
+			// for both outgoing or incoming connection, if we have an error, 
+			// this means there is disconnection
+			CancelActionL(aError, EGavdpResetReasonGeneral);
+			break;
+			}	
+
+		case (KErrAvdtpSignallingErrorBase - EAvdtpSEPInUse): // -18064 
+			{
+			// Remote SEP is in use.
+			// Wait for a while, accessory might configure us. If we don't receive 
+			// start ind during KOneSecondDelay, go to listening state.
+    		StartTimer(KOneSecondDelay, KRequestIdTimer);
+			break;
+			}
+		
+		default:
+		// KErrNotReady -18
+		// KErrInUse -14
+		// KErrCorrupt -20
+		// (KErrAvdtpSignallingErrorBase - EAvdtpBadState) -18094
+			{
+			CancelActionL(KErrDisconnected, EGavdpResetReasonGeneral);
+			}
+		}
+	}
+
+//  End of File