bluetooth/btstack/avdtp/avdtpConfigurators.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implements the avdtp configurators
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #include <bluetooth/logger.h>
       
    24 #include "avdtpConfigurators.h"
       
    25 #include "avdtpSignallingSession.h"
       
    26 #include "avdtpSignallingChannel.h"
       
    27 #include "avdtp.h"
       
    28 #include "avdtputil.h"
       
    29 
       
    30 #ifdef __FLOG_ACTIVE
       
    31 _LIT8(KLogComponent, LOG_COMPONENT_AVDTP);
       
    32 #endif
       
    33 
       
    34 CSEPConfigurator::CSEPConfigurator(CSignallingSession& aSignallingSession,
       
    35 						 		   CAvdtpProtocol& aProtocol)
       
    36 	: iSignallingSession(aSignallingSession), iProtocol(aProtocol)
       
    37 	{
       
    38 	LOG_FUNC
       
    39 	}
       
    40 
       
    41 
       
    42 
       
    43 
       
    44 CRemoteSEPConfigurator* CRemoteSEPConfigurator::NewL(CSignallingSession& aSignallingSession,
       
    45 													 CAvdtpProtocol& aProtocol,
       
    46 													 TSEID aLocalSEID,
       
    47 													 TSEID aRemoteSEID,
       
    48 													 TBool aIsReconfigure)
       
    49 	{
       
    50 	LOG_STATIC_FUNC
       
    51 	CRemoteSEPConfigurator* s = new (ELeave) CRemoteSEPConfigurator(aSignallingSession,
       
    52 																	aProtocol, aIsReconfigure);
       
    53 	CleanupStack::PushL(s);
       
    54 	s->ConstructL(aLocalSEID, aRemoteSEID);
       
    55 	CleanupStack::Pop(s);
       
    56 	return s;	
       
    57 	}
       
    58 	
       
    59 	
       
    60 void CRemoteSEPConfigurator::ConstructL(TSEID aLocalSEID, TSEID aRemoteSEID)
       
    61 	{
       
    62 	LOG_FUNC
       
    63 	if (aLocalSEID.IsLocal() && !aRemoteSEID.IsLocal() && iProtocol.RemoteSEPCache().Exists(SignallingSession().RemoteAddress(), aRemoteSEID))
       
    64 		{
       
    65 		// check in cache...(i.e capabilities have been retrieved)
       
    66 		// create the store for the configuration
       
    67 		iSetConfigBuffer.CreateL(KAvdtpMinSetConfigLength);
       
    68 		iLocalSEP = &iSignallingSession.FindLocalSEPL(aLocalSEID);
       
    69 		iRemoteSEID = aRemoteSEID;	
       
    70 		}
       
    71 	else
       
    72 		{
       
    73 		User::Leave(KErrArgument);
       
    74 		}
       
    75 	}
       
    76 
       
    77 CRemoteSEPConfigurator::CRemoteSEPConfigurator(CSignallingSession& aSignallingSession,
       
    78 						 		  			   CAvdtpProtocol& aProtocol,
       
    79 												TBool aIsReconfigure)
       
    80 	: CSEPConfigurator(aSignallingSession, aProtocol), iIsReconfigure(aIsReconfigure)
       
    81 	{
       
    82 	LOG_FUNC
       
    83 	}
       
    84 
       
    85 CRemoteSEPConfigurator::~CRemoteSEPConfigurator()
       
    86 	{
       
    87 	LOG_FUNC
       
    88 	iSetConfigBuffer.Close();
       
    89 	}
       
    90 
       
    91 
       
    92 TInt CRemoteSEPConfigurator::AddCapability(const TDesC8& aCapability)
       
    93 /*
       
    94 	Add in caps to SetConf - one per SetOpt
       
    95 	When Ioctl comes in we have a complete packet to send to sigch
       
    96 */
       
    97 	{
       
    98 	LOG_FUNC
       
    99 	TInt ret = KErrNone;
       
   100 	
       
   101 	// this has come in from GAVDP in "protocol" form (as an easy way to do IPC)
       
   102 	// we sanity check this here before sending
       
   103 	// run visitor over it
       
   104 	CCapabilitySummaryVisitor* visitor = new CCapabilitySummaryVisitor();
       
   105 	if (visitor)
       
   106 		{
       
   107 		TPtr8 ptr(const_cast<TUint8*>(aCapability.Ptr()), aCapability.Length(), aCapability.Length());
       
   108 
       
   109 		visitor->Process(ptr);
       
   110 		TAvdtpServiceCategories cats = visitor->CapabilitiesPresent();
       
   111 		
       
   112 		if (iIsReconfigure)
       
   113 			{
       
   114 			if (!(cats.CapabilityPresent(EServiceCategoryMediaCodec) || cats.CapabilityPresent(EServiceCategoryContentProtection)))
       
   115 				{
       
   116 				// check that if reconfiguring, the capability is reconfigurable (see 8.10.1, AVDTP)
       
   117 				ret = KErrArgument;
       
   118 				}
       
   119 			}
       
   120 		else
       
   121 			{
       
   122 			// check for interesting cases during non-reconfigure
       
   123 			if (cats.CapabilityPresent(EServiceCategoryMultiplexing))
       
   124 				{
       
   125 				ret = KErrArgument; // only stack manage this capability
       
   126 				}
       
   127 			else if (cats.CapabilityPresent(EServiceCategoryReporting))
       
   128 				{
       
   129 				// this saves the stream having to reparse the set configuration buffer
       
   130 				iReportingConfigured = ETrue;
       
   131 				}
       
   132 			else if (cats.CapabilityPresent(EServiceCategoryRecovery))
       
   133 				{
       
   134 				// this saves the stream having to reparse the set configuration buffer
       
   135 				iRecoveryConfigured = ETrue;
       
   136 				}
       
   137 			}
       
   138 		}
       
   139 	else
       
   140 		{
       
   141 		ret = KErrNoMemory;
       
   142 		}
       
   143 		
       
   144 	if (KErrNone==ret)
       
   145 		{
       
   146 		// ok to send, grow buffer to take this capability
       
   147 		ret = iSetConfigBuffer.ReAlloc(iSetConfigBuffer.Length() + aCapability.Length());
       
   148 		if (KErrNone==ret)
       
   149 			{
       
   150 			iSetConfigBuffer.Append(aCapability);
       
   151 			}
       
   152 		}
       
   153 	delete visitor;
       
   154 
       
   155 	return ret;
       
   156 	}
       
   157 	
       
   158 	
       
   159 TInt CRemoteSEPConfigurator::Finalise()
       
   160 	{
       
   161 	LOG_FUNC
       
   162 	// the client has now sent all SetOpts for config
       
   163 	// we need to finalise - ask stream to finalise out SetConfigBuffer
       
   164 	TRAPD(res, SignallingSession().DoConfigureStreamL(iSetConfigBuffer,
       
   165 														*iLocalSEP,
       
   166 														iRemoteSEID,
       
   167 														iReportingConfigured,
       
   168 														iRecoveryConfigured));
       
   169 		
       
   170 	if (res!=KErrNone)
       
   171 		{
       
   172 		iSetConfigBuffer.Close();
       
   173 		}
       
   174 	else
       
   175 		{
       
   176 		// for remote seps we really do go async
       
   177 		res = KRequestPending;
       
   178 		// transferred ownership of iSetConfigBuffer, so don't close, just zero
       
   179 		iSetConfigBuffer.Assign(NULL);
       
   180 		}
       
   181 	return res;
       
   182 	}
       
   183 	
       
   184 
       
   185 CLocalSEPConfigurator* CLocalSEPConfigurator::NewL(CSignallingSession& aSignallingSession,
       
   186 													 CAvdtpProtocol& aProtocol,
       
   187 													 TSEID aSEID)
       
   188 	{
       
   189 	LOG_STATIC_FUNC
       
   190 	CLocalSEPConfigurator* s = new (ELeave) CLocalSEPConfigurator(aSignallingSession,
       
   191 																	aProtocol);
       
   192 	CleanupStack::PushL(s);
       
   193 	s->ConstructL(aSEID);
       
   194 	CleanupStack::Pop(s);
       
   195 	return s;	
       
   196 	}
       
   197 
       
   198 void CLocalSEPConfigurator::ConstructL(TSEID aSEID)
       
   199 	{
       
   200 	LOG_FUNC
       
   201 	if (!aSEID.IsLocal())
       
   202 		{
       
   203 		User::Leave(KErrArgument);
       
   204 		}
       
   205 	// check in local sep queue (i.e. has been registered)
       
   206 	iLocalSEP = &SignallingSession().FindLocalSEPL(aSEID);
       
   207 	TAvdtpServiceCategories cats;
       
   208 	cats.SetCapability(EAllServiceCategories);
       
   209 	iCapabilityParseVisitor = new (ELeave) CCapabilityParseVisitor(cats);
       
   210 	}
       
   211 
       
   212 
       
   213 CLocalSEPConfigurator::CLocalSEPConfigurator(CSignallingSession& aSignallingSession,
       
   214 						   CAvdtpProtocol& aProtocol)
       
   215 	: CSEPConfigurator(aSignallingSession, aProtocol)
       
   216 	{
       
   217 	LOG_FUNC
       
   218 	}
       
   219 	
       
   220 CLocalSEPConfigurator::~CLocalSEPConfigurator()
       
   221 	{
       
   222 	LOG_FUNC
       
   223 	delete iCapabilityParseVisitor;
       
   224 	}
       
   225 
       
   226 TInt CLocalSEPConfigurator::AddCapability(const TDesC8& aCapabilityInProtocolForm)
       
   227 /*
       
   228 Add in caps to SetConf - one per SetOpt
       
   229 When finalise Ioctl comes in we have a complete packet to send to sigch
       
   230 */
       
   231 	{
       
   232 	LOG_FUNC
       
   233 	// convert into T-class form to santiy check this is goign to end up as a good configuration
       
   234 	TPtr8 ptr(const_cast<TUint8*>(aCapabilityInProtocolForm.Ptr()), aCapabilityInProtocolForm.Length(), aCapabilityInProtocolForm.Length());
       
   235 	iCapabilityParseVisitor->Process(ptr);
       
   236 
       
   237 	return KErrNone;
       
   238 	}
       
   239 	
       
   240 TInt CLocalSEPConfigurator::Finalise()
       
   241 	{
       
   242 	LOG_FUNC
       
   243 	// get all the set capabilities
       
   244 	TCapabilitiesArray caps = iCapabilityParseVisitor->GetCapabilities();
       
   245 	
       
   246 	 // muxing shouldnt be set yet
       
   247 	__ASSERT_DEBUG(!caps[EServiceCategoryMultiplexing], Panic(EAvdtpConfiguratorsMultiplexingUnexpectedlySet));
       
   248 	
       
   249 	// at this point we put in support for muxing as all Symbian local SEPs to
       
   250 #ifndef __SYMBIAN_AVDTP_HIDE_MUX 
       
   251 
       
   252 	TAvdtpMultiplexingCapability* mux = new TAvdtpMultiplexingCapability;
       
   253 	if (mux)
       
   254 		{
       
   255 		TAvdtpMultiplexingCapabilityHelper helper(*mux, !!caps[EServiceCategoryReporting], !!caps[EServiceCategoryRecovery]);
       
   256 		// set all relevant transport ids to zero to request values from INT
       
   257 		// see AVDTP spec p90
       
   258 		// if we are an INT we'll update this capability later in statespace
       
   259 		helper.SetMediaSID(0);
       
   260 		helper.SetMediaCID(0);
       
   261 		
       
   262 		if (caps[EServiceCategoryReporting])
       
   263 			{
       
   264 			helper.SetReportingSID(0);
       
   265 			helper.SetReportingCID(0);
       
   266 			}
       
   267 		// if recovery exposed then set to 0, else leave
       
   268 		if (caps[EServiceCategoryRecovery])
       
   269 			{
       
   270 			helper.SetRecoverySID(0);
       
   271 			helper.SetRecoveryCID(0);
       
   272 			}
       
   273 
       
   274 		caps[EServiceCategoryMultiplexing] = mux; // ownership transferred	
       
   275 		}
       
   276 #endif
       
   277 	// else forgot about trying to do muxing - it was an optimisation
       
   278 	
       
   279 	for (TInt i=0; i<ENumberOfServiceCategories; i++)
       
   280 		{
       
   281 		if (caps[i])
       
   282 			{
       
   283 			iLocalSEP->AddCapability(caps[i]); // transfer ownership of element
       
   284 			}
       
   285 		}
       
   286 		
       
   287 	return KErrNone;
       
   288 	}
       
   289