bluetoothengine/btaudioman/src/basrvsdpquery.cpp
changeset 0 f63038272f30
child 2 0b192a3a05a4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btaudioman/src/basrvsdpquery.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,392 @@
+/*
+* Copyright (c) 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: 
+*       This class handles asynchronous SDP queries
+*
+*/
+
+
+// INCLUDE FILES
+#include "basrvsdpquery.h"
+#include "btaccTypes.h"
+#include "debug.h"
+
+enum TQueryRequestId
+    {
+    ECreateView = 70,
+    EGetResponse = 71   
+    };
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+CBasrvSdpQuery* CBasrvSdpQuery::NewL(MBasrvSdpQuerier& aQuerier)
+	{
+	CBasrvSdpQuery* self = new (ELeave) CBasrvSdpQuery(aQuerier);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+CBasrvSdpQuery::~CBasrvSdpQuery()
+	{
+	if (iSdpAgent)
+		{
+		iSdpAgent->Cancel();
+		}
+    delete iSdpAgent;
+    delete iSdpSearchPattern;
+    iServiceAttrs.Close();
+    delete iResponse;
+   	iReg.Close();
+    delete iActive;
+   	iRegServ.Close();
+	}
+
+void CBasrvSdpQuery::QueryAccInfoL(const TBTDevAddr& aAddr, TBool aTolerateSdpError)
+    {
+    if (iSdpAgent)
+        {
+		User::Leave(KErrInUse);
+        }
+    iAddr = aAddr;
+    iServiceAttrs.Reset();
+    TBTSdpAttrInt SF;        //TBTSupportedFeature SF; 
+    SF.iAttrValue = 0;
+    SF.iUUID = KAudioSinkUUID;  
+    SF.iAttrID = KSdpAttrIdSupportedFeatures;        
+    iServiceAttrs.Append(SF); // Advanced Audio Distribution Profile - BT Stereo Audio
+    
+    SF.iUUID = 0x111e;   // HFP
+    SF.iAttrID = KSdpAttrIdSupportedFeatures;
+    iServiceAttrs.Append(SF); // BT Handsfree Profile - BT Mono Audio
+    
+    SF.iUUID = 0x1108;   // HSP
+    SF.iAttrID = 0x0302;  // Atti id of remote volume control
+    iServiceAttrs.Append(SF); // BT Headset Profile - BT Mono Audio 
+
+    SF.iUUID = KAVRemoteControlTargetUUID;
+    SF.iAttrID = KSdpAttrIdSupportedFeatures;
+    iServiceAttrs.Append(SF);  // Audio Video Remote Control Profile
+    
+    SF.iUUID = KAVRemoteControlTargetUUID;
+    SF.iAttrID = KSdpAttrIdBluetoothProfileDescriptorList;
+    iServiceAttrs.Append(SF);  // Audio Video Remote Control Profile, to find out avrcp 1.4 support    
+
+    
+    /*****************************************************
+     *   Series 60 Customer
+     *   You may want to consider modifying the following
+     *   code to better meet your needs.
+     *****************************************************/
+    // Perform remote SDP query to find out if information about the exact 
+    // model of the accessory is available in the SDP registry. NOTE that 
+    // this query if using a proprietary UUID which will only exist in some
+    // devices of a certain manufacturer. For other devices this query does
+    // not find a value.
+    //
+    TUUID serviceUuid = TUUID((0x00005555),(0x00001000),(0x80000002),(0xEE000001)); // model number
+    SF.iUUID = serviceUuid;  
+    SF.iAttrID = 0x0300; // Attri id of device model number
+    iServiceAttrs.Append(SF); 
+    iCursor = 0;
+    iTolerateSdpError = aTolerateSdpError;
+    iSdpAgent = CSdpAgent::NewL(*this, iAddr);
+    iSdpSearchPattern = CSdpSearchPattern::NewL();
+    DoNextServiceRecordRequestL();
+    }
+
+void CBasrvSdpQuery::NextRecordRequestComplete(TInt aError,
+                                             TSdpServRecordHandle aHandle,
+                                             TInt aTotalRecordsCount)
+    {
+    TRAP_IGNORE(NextRecordRequestCompleteL(aError, aHandle, aTotalRecordsCount));
+    }
+
+void CBasrvSdpQuery::AttributeRequestResult(
+    TSdpServRecordHandle aHandle,
+    TSdpAttributeID aAttrID,
+    CSdpAttrValue* aAttr)
+    {
+    TRAP_IGNORE(AttributeRequestResultL(aHandle, aAttrID, aAttr));
+    }
+
+void CBasrvSdpQuery::AttributeRequestComplete(TSdpServRecordHandle aHandle, TInt aError)
+    {
+    TRAP_IGNORE(AttributeRequestCompleteL(aHandle, aError));
+    }
+
+void CBasrvSdpQuery::RequestCompletedL(CBasrvActive& aActive)
+    {
+    switch (aActive.RequestId())
+        {
+        case ECreateView:
+            {
+            iResponse = NULL;
+            if (aActive.iStatus > KErrNone)
+                {
+    		    iResponse = CBTRegistryResponse::NewL(iReg);	
+    		    aActive.SetRequestId(EGetResponse);    
+    		    iResponse->Start(aActive.iStatus);
+        	    aActive.GoActive();
+                }
+            else
+                {
+                QueryCompleteL(KErrNone);
+                }
+            break;
+            }
+        case EGetResponse:
+            {
+            QueryCompleteL(KErrNone);
+            break;
+            }
+        }
+    }
+    
+void CBasrvSdpQuery::CancelRequest(CBasrvActive& /*aActive*/)
+    {
+    }
+
+void CBasrvSdpQuery::ConstructL()
+	{
+	}
+
+CBasrvSdpQuery::CBasrvSdpQuery(MBasrvSdpQuerier& aQuerier)
+	: iQuerier(aQuerier)
+	{
+	}
+
+void CBasrvSdpQuery::QueryCompleteL(TInt aErr)
+    {
+    iSdpAgent->Cancel();
+    delete iSdpAgent;
+    iSdpAgent = NULL;
+    delete iSdpSearchPattern;
+    iSdpSearchPattern = NULL;
+    TBTDeviceClass cod = TBTDeviceClass();
+	if ( iResponse && iResponse->Results().Count() > 0 )
+    	{
+    	cod = (iResponse->Results())[0]->DeviceClass();
+    	}
+    if (!aErr)
+        {
+        TAccInfo info;
+        MakeAccInfo(info);
+        iQuerier.GetAccInfoCompletedL(aErr, &info, &cod);
+        }
+    else
+        {
+        iQuerier.GetAccInfoCompletedL(aErr, NULL, &cod);
+        }
+    }
+
+void CBasrvSdpQuery::DoNextServiceRecordRequestL()
+    {
+    if (iCursor >= iServiceAttrs.Count())
+        {
+        TInt err = iRegServ.Connect();
+        if (!err)
+            err = iReg.Open(iRegServ);
+        if (err)
+            {
+            QueryCompleteL(KErrNone);
+            }
+        else
+            {
+            iActive = CBasrvActive::NewL(*this, CActive::EPriorityStandard, ECreateView);
+            TBTRegistrySearch pattern;
+        	pattern.FindAddress(iAddr);
+    	    iReg.CreateView(pattern, iActive->iStatus);
+    	    iActive->GoActive();
+            }
+        }
+    else
+        {
+        iSdpSearchPattern->Reset();
+        iSdpSearchPattern->AddL(iServiceAttrs[iCursor].iUUID);
+        iSdpAgent->SetRecordFilterL(*iSdpSearchPattern);
+        iSdpAgent->NextRecordRequestL();
+        }
+    }
+
+void CBasrvSdpQuery::NextRecordRequestCompleteL(TInt aError,
+                                             TSdpServRecordHandle aHandle,
+                                             TInt aTotalRecordsCount)
+    {
+    TRACE_INFO((_L("NextRecord err <%d>, Handle <0x%x>, Records Count <%d>"), 
+            aError, aHandle, aTotalRecordsCount));
+
+    if(aError == KErrEof || (!aError && aTotalRecordsCount == 0))
+        {
+        iServiceAttrs.Remove(iCursor);
+        DoNextServiceRecordRequestL();
+        }
+    else if(aError)
+        {
+        if (!iTolerateSdpError)
+            {
+            QueryCompleteL(aError);
+            }
+        else
+            {
+            for (TInt i = iServiceAttrs.Count() - 1; i >= iCursor; i--)
+                {
+                iServiceAttrs.Remove(i);
+                }
+            DoNextServiceRecordRequestL();
+            }
+        }
+    else if(aTotalRecordsCount)
+        {
+        iSdpAgent->AttributeRequestL(aHandle, iServiceAttrs[iCursor].iAttrID);
+        }
+    }
+
+void CBasrvSdpQuery::AttributeRequestResultL(
+    TSdpServRecordHandle aHandle,
+    TSdpAttributeID aAttrID,
+    CSdpAttrValue* aAttr)
+    {
+    TRACE_INFO((_L("AttributeRequestResult, attr type %d"), aAttr->Type()));
+    
+    // Adds the attribute values synchronously to the result array.
+    TRAP_IGNORE( aAttr->AcceptVisitorL( *this ) );
+    
+    TRACE_INFO((_L("handle <0x%x>, attr id <0x%04x>, value <%d>"), aHandle, aAttrID, iServiceAttrs[iCursor].iAttrValue));
+    (void) aHandle;
+    (void) aAttrID;
+    delete aAttr;
+    }
+
+void CBasrvSdpQuery::AttributeRequestCompleteL(TSdpServRecordHandle aHandle, TInt aError)
+    {
+    TRACE_INFO((_L("AttributeRequestCompleteL err %d"), aError)); (void) aError;
+    iSdpAgent->Cancel();
+    TInt currentCursor = iCursor;
+    iCursor++;
+    
+    if(iServiceAttrs[currentCursor].iUUID == KAVRemoteControlTargetUUID &&
+       iServiceAttrs[currentCursor].iAttrID == KSdpAttrIdSupportedFeatures)
+        {
+        // We have some other information (avrcp version) in the same record
+        // so lets get the information without quering the same record again.
+        iSdpAgent->AttributeRequestL(aHandle, iServiceAttrs[iCursor].iAttrID);
+        }
+    else
+        {        
+        DoNextServiceRecordRequestL();
+        }
+    }
+
+ void CBasrvSdpQuery::VisitAttributeValueL( CSdpAttrValue &aValue, TSdpElementType aType )
+     {
+     switch ( aType )
+         {
+         case ETypeUint:
+             {
+             TRACE_INFO((_L("attr value %d"), aValue.Uint()));
+             iServiceAttrs[iCursor].iAttrValue = aValue.Uint();
+             break;
+             }
+         case ETypeInt:
+             {
+             TRACE_INFO((_L("attr value %d"), aValue.Int()));
+             iServiceAttrs[iCursor].iAttrValue = aValue.Int();
+             break;
+             }
+         case ETypeBoolean:
+             {
+             TRACE_INFO((_L("attr value %d"), aValue.Bool()));
+             iServiceAttrs[iCursor].iAttrValue = aValue.Bool();
+             break;
+             }
+         }     
+     }
+
+ void CBasrvSdpQuery::StartListL( CSdpAttrValueList &aList )
+     {
+     (void) aList;
+     }
+
+ void CBasrvSdpQuery::EndListL()
+     {
+     
+     }
+
+void CBasrvSdpQuery::MakeAccInfo(TAccInfo& aInfo)
+    {
+    aInfo.SetBDAddress(iAddr);
+    if (iServiceAttrs.Count())
+        {
+        aInfo.SetCapturingSupport(EFalse); // default indication as of CR 403-6409 CMLA change
+        TUUID serviceUuid = TUUID((0x00005555),(0x00001000),(0x80000002),(0xEE000001)); // model number
+        TUint8 suppProfiles = 0x00;
+        for ( TUint ii = 0 ; ii < iServiceAttrs.Count() ; ++ii )
+            {
+            if ( iServiceAttrs[ii].iUUID == KAudioSinkUUID )
+                {
+                TRACE_INFO((_L("Accessory is A2DP Sink.")))
+                suppProfiles |= EStereo;
+                aInfo.SetSupportedFeature((TUint16)iServiceAttrs[ii].iAttrValue, TAccInfo::EStereoIndex);
+                }
+            else if ( iServiceAttrs[ii].iUUID == 0x111e )  // HFP
+                {
+                suppProfiles |= EHFP;
+                TRACE_INFO((_L("Accessory supports Handsfree profile.")))                    
+                aInfo.SetSupportedFeature((TUint16)iServiceAttrs[ii].iAttrValue, TAccInfo::EHFPIndex);
+                }
+            else if ( iServiceAttrs[ii].iUUID == 0x1108 ) // HSP
+                {
+                suppProfiles |= EHSP;
+                TRACE_INFO((_L("Accessory supports Headset profile.")))                                        
+                
+                if (iServiceAttrs[ii].iAttrValue)
+                    {
+                    TRACE_INFO((_L("HSP Remote volume control is supported.")))
+                    // Server is going to feed 0x10 to supported features for headset profile
+                    aInfo.SetSupportedFeature(0x10, TAccInfo::EHSPIndex);
+                    }
+                }
+            else if ( iServiceAttrs[ii].iUUID == KAVRemoteControlTargetUUID )
+                {
+                if(iServiceAttrs[ii].iAttrID == KSdpAttrIdSupportedFeatures)
+                    {
+                    suppProfiles |= ERemConTG; // 0x08 remote control profile
+                    TRACE_INFO((_L("Accessory is AVRCP TG, features 0x%02X"), iServiceAttrs[ii].iAttrValue))                            
+                    aInfo.SetSupportedFeature(iServiceAttrs[ii].iAttrValue, TAccInfo::ERemConTGIndex);  // remote control = Position 3
+                    }
+                else // KSdpAttrIdBluetoothProfileDescriptorList, Avrcp version
+                    {
+                    if(iServiceAttrs[ii].iAttrValue == 0x0104)
+                        {
+                        aInfo.iAvrcpVersion = TAccInfo::EAvrcpVersion14;
+                        }
+                    else
+                        {
+                        aInfo.iAvrcpVersion = TAccInfo::EAvrcpVersionNo14;
+                        }                    
+                    }
+                }
+            else if (iServiceAttrs[ii].iUUID == serviceUuid)
+                {
+                aInfo.SetModel(iServiceAttrs[ii].iAttrValue);    
+                TRACE_INFO((_L("Accessory is proprietary. Model: %d"), iServiceAttrs[ii].iAttrValue ))
+                }
+            }
+        aInfo.SetSuppportedProfiles(suppProfiles);
+        }    
+    }
+