--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/avdtp/avdtpSEPCache.cpp Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,284 @@
+// Copyright (c) 2003-2009 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:
+// Implements the avdtp SEP cache
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <bluetooth/logger.h>
+#include <bluetoothav.h>
+#include "avdtpSEPCache.h"
+#include "gavdpinterface.h"
+#include "avdtpSignallingMessages.h"
+#include "avdtputil.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_AVDTP);
+#endif
+
+CRemoteSEP* CRemoteSEP::NewL(const TBTDevAddr& aAddr, const TAvdtpSEPInfo& aInfo)
+ {
+ LOG_STATIC_FUNC
+ CRemoteSEP* s = new (ELeave) CRemoteSEP(aAddr, aInfo);
+ CleanupStack::PushL(s);
+ s->ConstructL();
+ CleanupStack::Pop(s);
+ return s;
+ }
+
+CRemoteSEP::CRemoteSEP(const TBTDevAddr& aAddr, const TAvdtpSEPInfo& aInfo)
+: iRemoteDev(aAddr), iInfo(aInfo)
+ {
+ LOG_FUNC
+ // age already set to zero
+ // only store remote sep details in the cache
+ __ASSERT_DEBUG(!aInfo.SEID().IsLocal(), Panic(EAvdtpSEIDHasWrongDomain));
+ }
+
+CRemoteSEP::~CRemoteSEP()
+ {
+ LOG_FUNC
+ delete iCapabilitiesBuf;
+ }
+
+
+void CRemoteSEP::ConstructL()
+ {
+ LOG_FUNC
+ }
+
+void CRemoteSEP::UpdateInfo(const TAvdtpSEPInfo& aInfo)
+ {
+ iInfo = aInfo;
+ }
+
+TBool CRemoteSEP::HasCapability(TAvdtpServiceCategory aCat)
+ {
+ LOG_FUNC
+ TBool ret = EFalse;
+
+ if (iCapabilitiesBuf)
+ {
+ CCapabilityPresentVisitor* presVisitor = new CCapabilityPresentVisitor(aCat);
+
+ if (presVisitor)
+ {
+ TPtr8 ptr = iCapabilitiesBuf->Des();
+ presVisitor->Process(ptr);
+ ret = presVisitor->IsPresent();
+ delete presVisitor;
+ }
+ }
+ return ret;
+ }
+
+
+/*
+Returns a pointer descriptor to SEP capability *in the protocol domain*
+It is upto a client to get this parsed as needed
+Motivation - to push more easilythrough ESOCK AND save unneccasry parsing
+*/
+TPtrC8 CRemoteSEP::GetCapabilityL(TAvdtpServiceCategory aCat)
+ {
+ LOG_FUNC
+ // use visitor to extract relevant bit
+ CCapabilityExtractorVisitor* extractor = new (ELeave) CCapabilityExtractorVisitor(aCat);
+ TPtr8 ptr = iCapabilitiesBuf->Des();
+ extractor->Process(ptr);
+
+ TPtrC8 cap = extractor->GetCapability();
+ delete extractor;
+ return cap;
+ }
+
+
+void CRemoteSEP::SetCapabilities(HBufC8* aCapsAsProtocol)
+ {
+ LOG_FUNC
+ delete iCapabilitiesBuf;
+ iCapabilitiesBuf = aCapsAsProtocol; // takes ownership
+
+ // set a visitor on it now to summarise caps
+ CCapabilitySummaryVisitor* summariser = new CCapabilitySummaryVisitor;
+ if (summariser)
+ {
+ TPtr8 des = iCapabilitiesBuf->Des();
+ summariser->Process(des);
+ iKnownCaps = summariser->CapabilitiesPresent();
+ delete summariser;
+ }
+ }
+
+CRemoteSEPCache* CRemoteSEPCache::NewL()
+ {
+ LOG_STATIC_FUNC
+ CRemoteSEPCache* s = new (ELeave) CRemoteSEPCache();
+ return s;
+ }
+
+/**
+Modifies SEP if already exists
+*/
+TInt CRemoteSEPCache::AddSEP(const TBTDevAddr& aAddr, const TAvdtpSEPInfo& aInfo)
+ {
+ LOG_FUNC
+ TInt err = KErrNone;
+
+ CRemoteSEP* sep = FindSEP(aAddr, aInfo.SEID());
+ if (!sep)
+ {
+ TRAP(err, sep = CRemoteSEP::NewL(aAddr, aInfo));
+ if (!err)
+ {
+ err = iRemoteSEPs.Append(sep);
+ if (err)
+ {
+ delete sep;
+ }
+ }
+ }
+ else
+ {
+ // modify the one there
+ sep->UpdateInfo(aInfo);
+ }
+ return err;
+ }
+
+TPtrC8 CRemoteSEPCache::GetCapabilityL(const TBTDevAddr& aAddr, TSEID aSEID, TAvdtpServiceCategory aCat)
+ {
+ LOG_FUNC
+ CRemoteSEP* sep = FindSEP(aAddr, aSEID);
+
+ if (sep)
+ {
+ return sep->GetCapabilityL(aCat);
+ }
+
+ User::Leave(KErrNotFound);
+ return KNullDesC8();// never reached
+ }
+
+
+TAvdtpServiceCategories CRemoteSEPCache::GetCapabilitiesL(const TBTDevAddr& aAddr, TSEID aSEID) const
+ {
+ LOG_FUNC
+ CRemoteSEP* sep = FindSEP(aAddr, aSEID);
+
+ if (sep)
+ {
+ return sep->GetCapabilities();
+ }
+
+ User::Leave(KErrNotFound);
+ return TAvdtpServiceCategories();
+ }
+
+
+TBool CRemoteSEPCache::HasCapability(const TBTDevAddr& aAddr, TSEID aSEID, TAvdtpServiceCategory aCat)
+ {
+ LOG_FUNC
+ CRemoteSEP* sep = FindSEP(aAddr, aSEID);
+
+ if (sep)
+ {
+ return sep->HasCapability(aCat);
+ }
+
+ return EFalse; // unknown => false
+ }
+
+
+
+void CRemoteSEPCache::SetCapabilities(const TBTDevAddr& aAddr, TSEID aSEID, HBufC8* aCapabilitiesAsProtocol)
+/**
+Sets capabilites from the RMBufChain passed in on the relevant CRemoteSEP in our
+cache.
+
+@return a bitmask of the service categories we saw.
+*/
+ {
+ LOG_FUNC
+ CRemoteSEP* sep = FindSEP(aAddr, aSEID);
+
+ if (sep)
+ {
+ sep->SetCapabilities(aCapabilitiesAsProtocol);
+ }
+ else
+ {
+ // would be nice to cache this, but if we don't know the SEP at this point
+ // the user hadn't done a Discover - which is ok for them, but for us we don't know if the
+ // SEP is in use or Audio/Video etc....We keep the capabilities as the stack finds
+ // them useful later
+ TAvdtpSEPInfo info;
+ info.SetSEID(aSEID);
+ if (AddSEP(aAddr, info)==KErrNone)
+ {
+ SetCapabilities(aAddr, aSEID, aCapabilitiesAsProtocol);
+ }
+ }
+ }
+
+CRemoteSEPCache::~CRemoteSEPCache()
+ {
+ LOG_FUNC
+ iRemoteSEPs.ResetAndDestroy();
+ }
+
+TBool CRemoteSEPCache::Exists(const TBTDevAddr& aAddr, TSEID aSEID) const
+ {
+ LOG_FUNC
+ return (FindSEP(aAddr, aSEID)!=NULL);
+ }
+
+CRemoteSEP* CRemoteSEPCache::FindSEP(const TBTDevAddr& aAddr, TSEID aSEID) const
+ {
+ LOG_FUNC
+ __ASSERT_DEBUG(!aSEID.IsLocal(), Panic(EAvdtpSEIDHasWrongDomain));
+
+ for (TInt i=0; i<iRemoteSEPs.Count(); i++)
+ {
+ CRemoteSEP& sep = *iRemoteSEPs[i];
+ if (sep.iInfo.SEID() == aSEID && sep.iRemoteDev == aAddr)
+ {
+ return iRemoteSEPs[i]; // does not transfer ownership
+ }
+ }
+ return NULL;
+ }
+
+void CRemoteSEPCache::InvalidateSEPs(const TBTDevAddr& aAddr)
+ {
+ LOG_FUNC
+ // typically called when signalling channel has gone down
+ // in future we could age the seps and save doing a GetCaps, but this does
+ // risk the use of invalid capabilities (but would still be compliant with GAVDP)
+ CRemoteSEP* sep = NULL;
+ for (TInt i=0; i<iRemoteSEPs.Count(); i++)
+ {
+ sep = iRemoteSEPs[i];
+ if (sep->iRemoteDev == aAddr)
+ {
+ iRemoteSEPs.Remove(i);
+ delete sep;
+ sep = NULL;
+ }
+ }
+ }
+