--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/avdtp/avdtpConfigurators.cpp Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,289 @@
+// 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 configurators
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <bluetooth/logger.h>
+#include "avdtpConfigurators.h"
+#include "avdtpSignallingSession.h"
+#include "avdtpSignallingChannel.h"
+#include "avdtp.h"
+#include "avdtputil.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_AVDTP);
+#endif
+
+CSEPConfigurator::CSEPConfigurator(CSignallingSession& aSignallingSession,
+ CAvdtpProtocol& aProtocol)
+ : iSignallingSession(aSignallingSession), iProtocol(aProtocol)
+ {
+ LOG_FUNC
+ }
+
+
+
+
+CRemoteSEPConfigurator* CRemoteSEPConfigurator::NewL(CSignallingSession& aSignallingSession,
+ CAvdtpProtocol& aProtocol,
+ TSEID aLocalSEID,
+ TSEID aRemoteSEID,
+ TBool aIsReconfigure)
+ {
+ LOG_STATIC_FUNC
+ CRemoteSEPConfigurator* s = new (ELeave) CRemoteSEPConfigurator(aSignallingSession,
+ aProtocol, aIsReconfigure);
+ CleanupStack::PushL(s);
+ s->ConstructL(aLocalSEID, aRemoteSEID);
+ CleanupStack::Pop(s);
+ return s;
+ }
+
+
+void CRemoteSEPConfigurator::ConstructL(TSEID aLocalSEID, TSEID aRemoteSEID)
+ {
+ LOG_FUNC
+ if (aLocalSEID.IsLocal() && !aRemoteSEID.IsLocal() && iProtocol.RemoteSEPCache().Exists(SignallingSession().RemoteAddress(), aRemoteSEID))
+ {
+ // check in cache...(i.e capabilities have been retrieved)
+ // create the store for the configuration
+ iSetConfigBuffer.CreateL(KAvdtpMinSetConfigLength);
+ iLocalSEP = &iSignallingSession.FindLocalSEPL(aLocalSEID);
+ iRemoteSEID = aRemoteSEID;
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+
+CRemoteSEPConfigurator::CRemoteSEPConfigurator(CSignallingSession& aSignallingSession,
+ CAvdtpProtocol& aProtocol,
+ TBool aIsReconfigure)
+ : CSEPConfigurator(aSignallingSession, aProtocol), iIsReconfigure(aIsReconfigure)
+ {
+ LOG_FUNC
+ }
+
+CRemoteSEPConfigurator::~CRemoteSEPConfigurator()
+ {
+ LOG_FUNC
+ iSetConfigBuffer.Close();
+ }
+
+
+TInt CRemoteSEPConfigurator::AddCapability(const TDesC8& aCapability)
+/*
+ Add in caps to SetConf - one per SetOpt
+ When Ioctl comes in we have a complete packet to send to sigch
+*/
+ {
+ LOG_FUNC
+ TInt ret = KErrNone;
+
+ // this has come in from GAVDP in "protocol" form (as an easy way to do IPC)
+ // we sanity check this here before sending
+ // run visitor over it
+ CCapabilitySummaryVisitor* visitor = new CCapabilitySummaryVisitor();
+ if (visitor)
+ {
+ TPtr8 ptr(const_cast<TUint8*>(aCapability.Ptr()), aCapability.Length(), aCapability.Length());
+
+ visitor->Process(ptr);
+ TAvdtpServiceCategories cats = visitor->CapabilitiesPresent();
+
+ if (iIsReconfigure)
+ {
+ if (!(cats.CapabilityPresent(EServiceCategoryMediaCodec) || cats.CapabilityPresent(EServiceCategoryContentProtection)))
+ {
+ // check that if reconfiguring, the capability is reconfigurable (see 8.10.1, AVDTP)
+ ret = KErrArgument;
+ }
+ }
+ else
+ {
+ // check for interesting cases during non-reconfigure
+ if (cats.CapabilityPresent(EServiceCategoryMultiplexing))
+ {
+ ret = KErrArgument; // only stack manage this capability
+ }
+ else if (cats.CapabilityPresent(EServiceCategoryReporting))
+ {
+ // this saves the stream having to reparse the set configuration buffer
+ iReportingConfigured = ETrue;
+ }
+ else if (cats.CapabilityPresent(EServiceCategoryRecovery))
+ {
+ // this saves the stream having to reparse the set configuration buffer
+ iRecoveryConfigured = ETrue;
+ }
+ }
+ }
+ else
+ {
+ ret = KErrNoMemory;
+ }
+
+ if (KErrNone==ret)
+ {
+ // ok to send, grow buffer to take this capability
+ ret = iSetConfigBuffer.ReAlloc(iSetConfigBuffer.Length() + aCapability.Length());
+ if (KErrNone==ret)
+ {
+ iSetConfigBuffer.Append(aCapability);
+ }
+ }
+ delete visitor;
+
+ return ret;
+ }
+
+
+TInt CRemoteSEPConfigurator::Finalise()
+ {
+ LOG_FUNC
+ // the client has now sent all SetOpts for config
+ // we need to finalise - ask stream to finalise out SetConfigBuffer
+ TRAPD(res, SignallingSession().DoConfigureStreamL(iSetConfigBuffer,
+ *iLocalSEP,
+ iRemoteSEID,
+ iReportingConfigured,
+ iRecoveryConfigured));
+
+ if (res!=KErrNone)
+ {
+ iSetConfigBuffer.Close();
+ }
+ else
+ {
+ // for remote seps we really do go async
+ res = KRequestPending;
+ // transferred ownership of iSetConfigBuffer, so don't close, just zero
+ iSetConfigBuffer.Assign(NULL);
+ }
+ return res;
+ }
+
+
+CLocalSEPConfigurator* CLocalSEPConfigurator::NewL(CSignallingSession& aSignallingSession,
+ CAvdtpProtocol& aProtocol,
+ TSEID aSEID)
+ {
+ LOG_STATIC_FUNC
+ CLocalSEPConfigurator* s = new (ELeave) CLocalSEPConfigurator(aSignallingSession,
+ aProtocol);
+ CleanupStack::PushL(s);
+ s->ConstructL(aSEID);
+ CleanupStack::Pop(s);
+ return s;
+ }
+
+void CLocalSEPConfigurator::ConstructL(TSEID aSEID)
+ {
+ LOG_FUNC
+ if (!aSEID.IsLocal())
+ {
+ User::Leave(KErrArgument);
+ }
+ // check in local sep queue (i.e. has been registered)
+ iLocalSEP = &SignallingSession().FindLocalSEPL(aSEID);
+ TAvdtpServiceCategories cats;
+ cats.SetCapability(EAllServiceCategories);
+ iCapabilityParseVisitor = new (ELeave) CCapabilityParseVisitor(cats);
+ }
+
+
+CLocalSEPConfigurator::CLocalSEPConfigurator(CSignallingSession& aSignallingSession,
+ CAvdtpProtocol& aProtocol)
+ : CSEPConfigurator(aSignallingSession, aProtocol)
+ {
+ LOG_FUNC
+ }
+
+CLocalSEPConfigurator::~CLocalSEPConfigurator()
+ {
+ LOG_FUNC
+ delete iCapabilityParseVisitor;
+ }
+
+TInt CLocalSEPConfigurator::AddCapability(const TDesC8& aCapabilityInProtocolForm)
+/*
+Add in caps to SetConf - one per SetOpt
+When finalise Ioctl comes in we have a complete packet to send to sigch
+*/
+ {
+ LOG_FUNC
+ // convert into T-class form to santiy check this is goign to end up as a good configuration
+ TPtr8 ptr(const_cast<TUint8*>(aCapabilityInProtocolForm.Ptr()), aCapabilityInProtocolForm.Length(), aCapabilityInProtocolForm.Length());
+ iCapabilityParseVisitor->Process(ptr);
+
+ return KErrNone;
+ }
+
+TInt CLocalSEPConfigurator::Finalise()
+ {
+ LOG_FUNC
+ // get all the set capabilities
+ TCapabilitiesArray caps = iCapabilityParseVisitor->GetCapabilities();
+
+ // muxing shouldnt be set yet
+ __ASSERT_DEBUG(!caps[EServiceCategoryMultiplexing], Panic(EAvdtpConfiguratorsMultiplexingUnexpectedlySet));
+
+ // at this point we put in support for muxing as all Symbian local SEPs to
+#ifndef __SYMBIAN_AVDTP_HIDE_MUX
+
+ TAvdtpMultiplexingCapability* mux = new TAvdtpMultiplexingCapability;
+ if (mux)
+ {
+ TAvdtpMultiplexingCapabilityHelper helper(*mux, !!caps[EServiceCategoryReporting], !!caps[EServiceCategoryRecovery]);
+ // set all relevant transport ids to zero to request values from INT
+ // see AVDTP spec p90
+ // if we are an INT we'll update this capability later in statespace
+ helper.SetMediaSID(0);
+ helper.SetMediaCID(0);
+
+ if (caps[EServiceCategoryReporting])
+ {
+ helper.SetReportingSID(0);
+ helper.SetReportingCID(0);
+ }
+ // if recovery exposed then set to 0, else leave
+ if (caps[EServiceCategoryRecovery])
+ {
+ helper.SetRecoverySID(0);
+ helper.SetRecoveryCID(0);
+ }
+
+ caps[EServiceCategoryMultiplexing] = mux; // ownership transferred
+ }
+#endif
+ // else forgot about trying to do muxing - it was an optimisation
+
+ for (TInt i=0; i<ENumberOfServiceCategories; i++)
+ {
+ if (caps[i])
+ {
+ iLocalSEP->AddCapability(caps[i]); // transfer ownership of element
+ }
+ }
+
+ return KErrNone;
+ }
+