diff -r 000000000000 -r 29b1cd4cb562 bluetooth/btstack/avdtp/avdtpConfigurators.cpp --- /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 +#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(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(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; iAddCapability(caps[i]); // transfer ownership of element + } + } + + return KErrNone; + } +