bluetoothengine/btaudioman/src/basrvaccstatequery.cpp
changeset 0 f63038272f30
child 6 6a29d5ad0713
child 15 00f9ee97d895
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btaudioman/src/basrvaccstatequery.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,230 @@
+/*
+* Copyright (c) 2005-2006 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:  Implementation of Query state.
+*
+*/
+
+
+// INCLUDE FILES
+#include <AccPolGenericIdDefinitions.h>     //device type definitions
+#include "basrvaccstatequery.h"
+#include "basrvaccstateconnect.h"
+#include "basrvaccstatedisconnect.h"
+#include "basrvaccstateattach.h"
+#include "basrvaccstateattached.h"
+#include "debug.h"
+
+// ================= MEMBER FUNCTIONS =======================
+
+CBasrvAccStateQuery* CBasrvAccStateQuery::NewL(CBasrvAcc& aParent, TBool aConnectingRequest)
+    {
+    CBasrvAccStateQuery* self=new(ELeave) CBasrvAccStateQuery(aParent, aConnectingRequest);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CBasrvAccStateQuery::~CBasrvAccStateQuery()
+    {
+    delete iQuery;
+    TRACE_FUNC
+    }
+
+void CBasrvAccStateQuery::EnterL()
+    {
+    StatePrint(_L("Query"));
+    // (NOT iConnecting) -> Headset connects to phone, SDP failure is tolerated. 
+    iQuery->QueryAccInfoL(AccInfo().iAddr, !iConnecting);    
+    Parent().RequestActiveMode();
+    Parent().PreventLowPowerMode();
+    }
+
+CBasrvAccState* CBasrvAccStateQuery::ErrorOnEntry(TInt aReason)
+    {
+    TRACE_FUNC
+    if (iConnecting)
+        {
+        TRAP_IGNORE(Parent().AccMan().ConnectCompletedL(AccInfo().iAddr, aReason, 0));
+        }
+    return NULL;
+    }
+
+TBTEngConnectionStatus CBasrvAccStateQuery::ConnectionStatus() const
+    {
+    return EBTEngConnecting;
+    }
+
+void CBasrvAccStateQuery::CancelConnect()
+    {
+    TRACE_FUNC
+    if (iConnecting)
+        {
+        delete iQuery;
+        iQuery = NULL;
+        TRAP_IGNORE(Parent().ChangeStateL(NULL));
+        }
+    }
+
+void CBasrvAccStateQuery::DisconnectL()
+    {
+    TRACE_FUNC
+    delete iQuery;
+    iQuery = NULL;
+    if (AccInfo().iConnProfiles)
+        {
+        Parent().ChangeStateL(CBasrvAccStateDisconnect::NewL(Parent()));
+        }
+    else
+        {
+        Parent().ChangeStateL(NULL);
+        }
+    }
+    
+void CBasrvAccStateQuery::AccessoryDisconnectedL(TProfiles aProfile)
+    {
+    TRACE_FUNC
+    ProfileDisconnected(aProfile);
+    AccClosedAudio(aProfile);
+    StatePrint(_L("Query"));
+    if (!AccInfo().iConnProfiles && !iConnecting)
+        {
+        delete iQuery;
+        iQuery = NULL;
+        Parent().ChangeStateL(NULL);
+        }
+    }
+
+void CBasrvAccStateQuery::GetAccInfoCompletedL(TInt aErr, const TAccInfo* aAcc, const TBTDeviceClass* aCod)
+    {
+    TRACE_FUNC
+    CBasrvAccState* next = NULL;
+    if ( ( aErr || !aAcc || !(aAcc->iSuppProfiles & EAnyAudioProfiles) ) &&
+        ( iConnecting || !(AccInfo().iConnProfiles ) ))
+        {
+        TInt err = (aErr) ? aErr : KErrNotSupported;
+        Parent().AccMan().ConnectCompletedL(AccInfo().iAddr, err, 0);
+        Parent().ChangeStateL(next);
+        return;
+        }
+
+    if (aAcc)
+        {
+        TInt exist_conns = AccInfo().iConnProfiles;
+        TInt exist_audios = AccInfo().iAudioOpenedProfiles;
+        AccInfo() = *aAcc;
+        AccInfo().iAudioOpenedProfiles = exist_audios;
+        AccInfo().iConnProfiles = exist_conns;
+        AccInfo().iSuppProfiles |= exist_conns;
+        }
+    
+    // Take HFP supported feature from BTMAC if it is not available
+    if ( ( AccInfo().iConnProfiles & EHFP ) && 
+         AccInfo().iSupportedFeatures[TAccInfo::EHFPIndex] == 0 )
+        {
+        CBTAccPlugin* plugin = Parent().AccMan().PluginMan().Plugin(EHFP);;
+        AccInfo().SetSupportedFeature((TUint16)plugin->GetRemoteSupportedFeature(), TAccInfo::EHFPIndex);
+        }
+    
+    // if e.g. A2DP is supported by headset but BTSAC is not in ROM, filter it.
+    Parent().AccMan().FilterProfileSupport(AccInfo());
+
+    RArray<TBTDevAddr> conflicts;
+    CleanupClosePushL(conflicts);
+    ResolveConflicts(conflicts);
+    if (conflicts.Count())
+        {
+        if (iConnecting)
+            {
+            Parent().AccMan().ConnectCompletedL(AccInfo().iAddr, KErrAlreadyExists, 0, &conflicts);
+            }
+        if (AccInfo().iConnProfiles)
+            {
+            next = CBasrvAccStateDisconnect::NewL(Parent());
+            }
+        }
+    else
+        {
+        // Guess if this is a carkit or headset using the CoD info
+    	if (aCod && (aCod->MajorServiceClass() & EMajorServiceAudioService) &&
+                    (aCod->MajorDeviceClass() & EMajorDeviceAudioDevice ))
+        	{
+            if (aCod->MinorDeviceClass() == EMinorDeviceAVHandsfree ||
+                aCod->MinorDeviceClass() == EMinorDeviceAVCarAudio)
+                {
+                AccInfo().SetDeviceType(KDTCarKit);
+                TRACE_INFO((_L("Device is a carkit.")));
+                }
+            else
+                {
+                AccInfo().SetDeviceType(KDTHeadset);
+                TRACE_INFO((_L("Device is a headset.")));
+                }
+        	}
+    	else
+    		{
+    		AccInfo().SetDeviceType(KDTHeadset);
+            TRACE_INFO((_L("Device is a headset.")));
+    		}
+        
+        if (iConnecting)
+            {
+            next = CBasrvAccStateConnect::NewL(Parent());
+            }
+        else if (AccInfo().iConnProfiles)
+            {
+            next = CBasrvAccStateAttach::NewL(Parent(), iConnecting);
+            }
+        }
+    CleanupStack::PopAndDestroy(&conflicts);
+    Parent().ChangeStateL(next);    
+    }
+
+CBasrvAccStateQuery::CBasrvAccStateQuery(CBasrvAcc& aParent, TBool aConnectingRequest)
+    : CBasrvAccState(aParent, NULL), iConnecting(aConnectingRequest)
+    {
+    }
+
+void CBasrvAccStateQuery::ConstructL()
+    {
+    iQuery = CBasrvSdpQuery::NewL(*this);    
+    }
+    
+void CBasrvAccStateQuery::ResolveConflicts(RArray<TBTDevAddr>& aConflicts)
+    {
+    RPointerArray<const TAccInfo> infos;
+    TInt err = Parent().AccMan().AccInfos(infos);
+    
+    if (err == KErrNone)
+        {
+        TInt supportedByThis = AccInfo().iSuppProfiles;
+        
+        // HFP and HSP are mutual exclusive, i.e. can only have one connected at a time.
+        if (supportedByThis & EAnyMonoAudioProfiles)
+            {
+            supportedByThis |= EAnyMonoAudioProfiles;
+            }
+        
+        for (TInt i = 0; i < infos.Count(); i++)
+            {
+            if ((infos[i]->iAddr != AccInfo().iAddr) &&
+                (infos[i]->iSuppProfiles & supportedByThis))
+                {
+                aConflicts.Append(infos[i]->iAddr);
+                }
+            }
+        
+        infos.Close();
+        }
+    }