diff -r 000000000000 -r 29b1cd4cb562 bluetooth/btstack/sdp/sdp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetooth/btstack/sdp/sdp.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,302 @@ +// Copyright (c) 2000-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 SDP Protocol object +// +// + +#include +#include +#include +#include "sdp.h" +#include "sdpclient.h" +#include "sdpnetdb.h" +#include "sdpstackutil.h" +#include "sdpconsts.h" +#include "bt.h" + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, LOG_COMPONENT_SDP); +#endif + +CSdpProtocol::CSdpProtocol(CBTSecMan& aSecMan, RBTControlPlane& aControlPlane, CBTCodServiceMan& aCodMan) + :CBluetoothProtocolBase(aSecMan, aControlPlane, aCodMan), + iClients(_FOFF(CSdpClient, iLink)) +/** + Protocol Constructor. +**/ + { + LOG_FUNC + } + +CSdpProtocol::~CSdpProtocol() +/** + Protocol Destructor. + We only clean up the signallers as the NetDbProviders are owned by ESOCK and + it is up to it to destroy them. +**/ + { + LOG_FUNC + while(!iClients.IsEmpty()) + { + CSdpClient* c = iClients.First(); + c->iLink.Deque(); + delete c; + } + if(iLowerProtocol) + iLowerProtocol->Close(); // Matches the bind +#ifdef __FLOG_ACTIVE + CLOSE_LOGGER +#endif + } + +CSdpProtocol* CSdpProtocol::NewL(CBTSecMan& aSecMan, RBTControlPlane& aControlPlane, CBTCodServiceMan& aCodMan) + { +#ifdef __FLOG_ACTIVE + CONNECT_LOGGER +#endif + LOG_STATIC_FUNC + CSdpProtocol* i=new (ELeave) CSdpProtocol(aSecMan, aControlPlane, aCodMan); + return i; + } + +void CSdpProtocol::InitL(TDesC& /*aTag*/) +/** + Pre-binding initialise. + Alloc any stuff we need. + + This will only ever be called once during the lifetime of this + protocol. +**/ + { + LOG_FUNC + // ...nothing required! + } + +void CSdpProtocol::StartL() +/** + Binding complete. +**/ + { + LOG_FUNC + // Should check that we're bound now. + __ASSERT_ALWAYS(iLowerProtocol,Panic(ESdpNotBound)); + } + + +void CSdpProtocol::BindToL(CProtocolBase* aProtocol) +/*** + Request by Protocol Mgr to bind to the specified protocol. + We can only be bound to one lower layer protocol, so the function panics + if we are already bound. + @param aProtocol The protocol we need to bind to. +**/ + { + LOG_FUNC + FTRACE(TBuf<255> tmp(aProtocol->Tag()); + LOG1(_L("CSdpProtocol::BindToL binding to %S"), + &tmp)); + + if(!iLowerProtocol) + { +#ifdef _DEBUG + TServerProtocolDesc prtDesc; + aProtocol->Identify(&prtDesc); + + if(prtDesc.iAddrFamily!=KBTAddrFamily || + prtDesc.iProtocol!=KL2CAP) + { + User::Leave(KErrBtEskError); + } +#endif + + iLowerProtocol=static_cast(aProtocol); + iLowerProtocol->BindL(this, KSDPPSM); + iLowerProtocol->Open(); + } + else + { + User::Leave(KErrSdpAlreadyBound); + } + } + +// Factory functions + +CNetDBProvdBase* CSdpProtocol::NewNetDatabaseL() +/** + Create a new NetDbProvider. + The NetDbProvider returned is owned by the caller -- this protocol will + not clean it up. esock uses this function to create a new NetDbProvider, + and esock will delete when it is finished with it. +**/ + { + LOG_FUNC + return CSdpNetDbProvider::NewL(*this); + } + +// Query functions + +void CSdpProtocol::Identify(TServerProtocolDesc *aDesc)const +/** + Identify request from SOCKET server +**/ + { + LOG_FUNC + ProtocolIdentity(aDesc); + } + +void CSdpProtocol::ProtocolIdentity(TServerProtocolDesc* aDesc) + { + LOG_STATIC_FUNC + _LIT(name,"SDP"); + aDesc->iProtocol=KSDP; + + aDesc->iName=name; + aDesc->iAddrFamily=KBTAddrFamily; + aDesc->iSockType=1; // Bogus... but (debug) esock demands non-zero here. + + aDesc->iVersion=TVersion(KBTMajor,KBTMinor,KBTBuild); + aDesc->iByteOrder=EBigEndian; + aDesc->iServiceInfo=0; + aDesc->iNamingServices=KNSInfoDatabase; + aDesc->iSecurity=0; + aDesc->iMessageSize=KSocketMessageSizeUndefined; + aDesc->iServiceTypeInfo=ECantProcessMBufChains; + aDesc->iNumSockets=1;// Bogus... but (debug) esock demands non-zero here. + } + +void CSdpProtocol::CloseNow() +/** + Our reference is now zero, so start to close. + When SDP server is in place, this'll be far more involved, as we'll + want to hang around to service SDP queries, for some (???) length + of time. + In the mean time, we can just close, as there are now no netdbs left, so + even if any SDP clients are still hanging around, they may as well die. +**/ + { + LOG_FUNC + iClosePending = ETrue; + TryToClose(); + } + +void CSdpProtocol::Open() +/** + Request to open the protocol. + The protocol may be repeatedly opened and closed. The order of calls is + InitL, [Open *n , Close * n, CloseNow] * m, CanClose(upcall) etc. +**/ + { + LOG_FUNC + iClosePending = EFalse; + CProtocolBase::Open(); + } + +void CSdpProtocol::Close() +/** + This is one session closing. + Just call default, which decs the ref count. + CloseNow will be called when this hits 0. +**/ + { + LOG_FUNC + CProtocolBase::Close(); + } + +void CSdpProtocol::TryToClose() + { + LOG_FUNC + if (iClosePending && iClients.IsEmpty()) + CanClose(); // delete's us! + } + +void CSdpProtocol::GetClient(CSdpNetDbProvider& aNetDbProvider) +/** + Find a Client for this NetDbProvider. + + When a Client is found, the NetDbProvider is notified via the ClientUp() call. + Note that if there is no existing Client then it will be created + here and the link brought up before the ClientUp() call is made. This implies + that the ClientUp() call on the NetDbProvider can be synchronous or Asynchronous. + + @param aNetDbProvider The NetDbProvider that needs a Client. +**/ + { + LOG_FUNC + CSdpClient* client; + TBool needsL2CAPChannel = EFalse; + + client=FindClient(aNetDbProvider.iRemoteDev); + if(!client) + {// Need to create one + needsL2CAPChannel = ETrue; + TRAPD(err, client=CSdpClient::NewL(*this, *iLowerProtocol)); + if(err != KErrNone) + { + // Can't create a client, so error the NetDbProvider + aNetDbProvider.Error(err); + return; + } + // Add client to the Q + iClients.AddFirst(*client); + } + // Take NetDb off the idle Q + + // and add it to the client + aNetDbProvider.iClient=client; + client->AddNetDbProvider(aNetDbProvider); + + // Bring up the client if needed + if (needsL2CAPChannel) + client->Open(aNetDbProvider.iRemoteDev); // Will call back through ClientUp() + } + +CSdpClient* CSdpProtocol::FindClient(const TBTDevAddr& aAddr) +/** + Find the existing client for this address. + @return Pointer to a client for this address, or NULL if it doesn't exist. +**/ + { + LOG_FUNC + TDblQueIter iter(iClients); + CSdpClient* client; + + while(iter) + { + client=iter++; + if(client->iRemoteAddr == aAddr) + { + // We have a client, so return it + return client; + } + } + // No client + return 0; + } + +void CSdpProtocol::ClientDown(CSdpClient& aClient) + { + LOG_FUNC + aClient.iLink.Deque(); + delete &aClient; + TryToClose(); + } + +TInt CSdpProtocol::BearerConnectComplete(const TBTDevAddr& /*aAddr*/, CServProviderBase* /*aSSP*/) + { + LOG_FUNC + // SDP Protocol doesn't do incoming stuff! + Panic(ESdpClientPassiveConnect); + return KErrNotSupported; + } +