bluetoothengine/btsac/src/btsacStateConfiguring.cpp
changeset 0 f63038272f30
child 1 6a1fe72036e3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btsac/src/btsacStateConfiguring.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,319 @@
+/*
+* 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, a stereo audio accessory is configuring us.
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "btsacStateConfiguring.h"
+#include "btsacStateConfigured.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;   
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::NewL
+// -----------------------------------------------------------------------------
+//
+CBtsacConfiguring* CBtsacConfiguring::NewL(CBTSAController& aParent, TSEID aLocalSEID, TSEID aRemoteSEID)
+    {
+   	CBtsacConfiguring* self = new( ELeave ) CBtsacConfiguring(aParent, aLocalSEID, aRemoteSEID);
+    return self;
+   	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::CBtsacConfiguring
+// -----------------------------------------------------------------------------
+//
+CBtsacConfiguring::CBtsacConfiguring(CBTSAController& aParent, TSEID aLocalSEID, TSEID aRemoteSEID)
+:   CBtsacState(aParent, EStateConfiguring), iLocalSEID(aLocalSEID), iRemoteSEID(aRemoteSEID),
+	iSEPFound(EFalse), iRemoteSEPIndex(0), iAudioOpenedBy(EAudioOpenedByNone)
+    {
+    }
+  
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::~CBtsacConfiguring
+// -----------------------------------------------------------------------------
+//    
+CBtsacConfiguring::~CBtsacConfiguring()
+    {
+    TRACE_FUNC
+    }
+
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::EnterL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConfiguring::EnterL()
+    {
+	TRACE_STATE(_L("[BTSAC State] Configuring"))
+	_LIT(KName, "CBtsacStateConfiguring");
+	const TDesC& Name = KName;
+	Parent().iGavdp->RegisterObserver(this, Name);
+	
+	if ( iLocalSEID.SEID() != 1)	// we have only one local SEP, SBC
+		{
+		TRACE_INFO((_L("CBtsacConfiguring::EnterL() Wrong Local SEP being configured !!!")))
+		}
+	
+	// we have registered only one local SBC SEP, so aRemoteSEID should be a SBC Audio SEP, 
+	// atleast we assume that. So stash it as SBC Audio SEP
+	TAvdtpSEPInfo info = TAvdtpSEPInfo();
+	info.SetIsSink(ETrue); 
+	info.SetMediaType(EAvdtpMediaTypeAudio);
+	info.SetSEID(iRemoteSEID);
+	TRAPD(err, Parent().iRemoteSEPs->NewSEPL(info));
+	if (!err)
+		{
+		Parent().iRemoteSEPs->SetState(info.SEID(), CBTSACStreamEndPoint::EDiscoveredRemote, &info);
+		}
+	else // internal problem
+		{
+  		CancelActionL(KErrCancel, EGavdpResetReasonGeneral);
+		}
+    }
+
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::CancelActionL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConfiguring::CancelActionL(TInt aError, TBTSACGavdpResetReason aGavdpReset)
+    {
+    TRACE_FUNC
+	Parent().CompletePendingRequests((KConnectReq | KOpenAudioReq), aError);
+    Parent().ChangeStateL(CBtsacListening::NewL(Parent(), aGavdpReset, aError));
+    }
+
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::CancelConnectL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConfiguring::CancelConnectL()
+    {
+    TRACE_FUNC
+	CancelActionL(KErrCancel, EGavdpResetReasonGeneral); // do no cancel till gavdp_error call back recieved
+    }
+
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::OpenAudioLinkL
+// -----------------------------------------------------------------------------
+//    
+void CBtsacConfiguring::OpenAudioLinkL(const TBTDevAddr& /*aAddr*/)
+	{  
+	TRACE_FUNC
+	// Handle open audio completion later, after configuration is ready (completion will happen
+	// in CBtsacConfigured state after we receive GAVDP_StartIndication).
+	}
+	
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::DisconnectL
+// -----------------------------------------------------------------------------
+//
+void CBtsacConfiguring::DisconnectL()	
+	{
+	TRACE_FUNC
+	Parent().CompletePendingRequests(KDisconnectReq, KErrNone);
+	CancelActionL(KErrCancel, EGavdpResetReasonGeneral);
+	}	
+
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::GAVDP_BearerReady
+// -----------------------------------------------------------------------------
+//
+void CBtsacConfiguring::GAVDP_BearerReady(RSocket aNewSocket, const TAvdtpSockAddr& aAddr)
+	{
+	TRACE_INFO((_L("CBtsacConfiguring::GAVDP_BearerReady() SEID: %d"), aAddr.SEID().SEID()))
+	(void) aAddr.SEID(); 
+	Parent().NewAccessory(Parent().GetRemoteAddr());
+	
+	// If there is pending connect request, complete it.
+	Parent().CompletePendingRequests(KConnectReq, KErrNone);
+	
+	// only one socket in this implementation at the moment, 
+	// as we dont have recovery and reporting yet
+	TRAP_IGNORE(Parent().ChangeStateL(CBtsacConfigured::NewL(Parent(), aNewSocket, iAudioOpenedBy, EStreamConfiguredBySink)));
+	}
+
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::GAVDP_ConfigurationIndication
+// -----------------------------------------------------------------------------
+//
+TInt CBtsacConfiguring::GAVDP_ConfigurationIndication(TAvdtpServiceCapability* aCapability)
+	{
+	TRACE_FUNC
+	Parent().iRemoteSEPs->StoreCaps(iRemoteSEPIndex, aCapability);
+	if ( aCapability->Category() == EServiceCategoryMediaCodec )
+		{
+		TAvdtpMediaCodecCapabilities& codecCaps = static_cast<TAvdtpMediaCodecCapabilities&>(*aCapability);
+		if ( codecCaps.MediaCodecType() == EAudioCodecSBC ) // found SEP that we are interested in
+			{
+			TRACE_INFO((_L("CBtsacConfiguring::GAVDP_SEPCapability() Found SBC Audio Sink SEP !!!")))
+			iSEPFound = ETrue;
+			Parent().SetSEPIndex(iRemoteSEPIndex);
+			}
+		}
+	return KErrNone;
+	}
+	
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::GAVDP_ConfigurationEndIndication
+// -----------------------------------------------------------------------------
+//	
+TInt CBtsacConfiguring::GAVDP_ConfigurationEndIndication()
+	{
+	TRACE_FUNC
+	if ( iSEPFound ) // proposed SEP has SBC (and media transport!) caps
+		{
+		RPointerArray<TAvdtpServiceCapability> SEPCapabilities;
+	    if ((Parent().iRemoteSEPs->GetCaps(Parent().GetSEPIndex(), SEPCapabilities)) )
+			{
+			TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() Couldn't retrieve Capabilities !")))
+		   	SEPCapabilities.Close();
+		   	TRAPD(err, CancelActionL(KErrCancel, EGavdpResetReasonGeneral));
+		   	if(err)
+		   		{
+		   		return KErrNoMemory;
+		   		}
+			return KErrGeneral; 
+			}
+		TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() 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("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() SBC Caps retrieved.")))
+				}
+			else if ( cat == EServiceCategoryMediaTransport )
+				{
+				MedTransCaps = static_cast<TAvdtpMediaTransportCapabilities&>(*cap);
+				TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() Media Transport Caps retrieved.")))
+				}
+	   		}
+	   	SEPCapabilities.Close();
+		
+		//Parent().StoreAccInfo();  // stores iRemoteSEPs (SEPManager) into database
+		
+		// Check if headset's capabilities suits us			
+		TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() Accessory Sampling Frequencies: %d"), SBCCaps.SamplingFrequencies()))
+		TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() Accessory Channel modes: %d"), SBCCaps.ChannelModes()))
+		TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() Accessory Blocks: %d"), SBCCaps.BlockLengths()))
+		TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() Accessory SubBands: %d"), SBCCaps.Subbands()))
+		TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() Accessory Alloc method: %d"), SBCCaps.AllocationMethods()))
+		TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() Accessory Max bitpool: %d"), SBCCaps.MaxBitpoolValue()))
+		TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() Accessory Min bitpool: %d"), SBCCaps.MinBitpoolValue()))
+		if (Parent().iStreamer->ConfigureSEP(SBCCaps) )
+			{
+	   		TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() Streamer couldn't configure SEP !")))
+	        TRAPD(err, CancelActionL(KErrCancel, EGavdpResetReasonGeneral));
+	        if(err)
+	        	{
+	        	return KErrNoMemory;
+	        	}
+	        return KErrGeneral;   // capabilites doesn't suit us
+			}
+		// Everyting has been done on behalf of us, let's wait GAVDP_BearerReady indication.
+		TRACE_INFO((_L("CBtsacConfiguring::GAVDP_ConfigurationEndIndication() completed")))
+		return KErrNone;
+		}
+	else 
+	 	{
+	 	return KErrNotFound; // remote is missing SBC (or media transport!) caps in SEP it proposed
+	 	}
+	}
+
+// -------------------------------------------------------------
+// CBtsacConfiguring::GAVDP_StartIndication
+// -------------------------------------------------------------
+//
+TInt CBtsacConfiguring::GAVDP_StartIndication(TSEID aLocalSEID)
+	{
+	TRACE_INFO((_L("CBtsacConfiguring::GAVDP_StartIndication(), LocalSEID:%d"), aLocalSEID.SEID()))
+	(void)aLocalSEID;
+	
+	// accessory has send this indication right after GAVDP_ConfigurationEndIndication
+	// but we must be waiting for Gavdp_BearerReady. In order to solve this, just flag 
+	// our indication that an open audio request exists
+	// CBtsacConfigured state can use this indication to start audio automatically then later
+	
+	// If we have already audio open request pending (from accessory FW), let keep it that way.
+	// We have to complete open audio request later
+	if(!Parent().IsOpenAudioReqFromAccFWPending())
+		{		
+		iAudioOpenedBy = EAudioOpenedByAcc;
+		}
+	return KErrNone;
+	}
+    
+// -----------------------------------------------------------------------------
+// CBtsacConfiguring::HandleGavdpErrorL
+// -----------------------------------------------------------------------------
+//	
+void CBtsacConfiguring::HandleGavdpErrorL(TInt aError)
+	{
+	TRACE_FUNC
+	switch(aError)
+		{
+		case KErrAvdtpRequestTimeout: // -18005
+			{
+			TRACE_INFO((_L("CBtsacConfiguring::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("CBtsacConfiguring::HandleGavdpErrorL() Signalling disconnected.")))
+			// for both outgoing or incoming connection, if we have an error, 
+			// this means there is disconnection
+			CancelActionL(aError, EGavdpResetReasonNone);
+			break;
+			}
+		
+		default:			
+		//case KErrNotReady: // -18
+		//case KErrInUse: // -14
+			{
+			CancelActionL(KErrDisconnected, EGavdpResetReasonGeneral);
+			break;
+			}
+		}
+	}
+    
+//  End of File