bluetooth/btstack/sdp/sdp.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2000-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 SDP Protocol object
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <bluetooth/logger.h>
       
    19 #include <bt_sock.h>
       
    20 #include <btsdp.h>
       
    21 #include "sdp.h"
       
    22 #include "sdpclient.h"
       
    23 #include "sdpnetdb.h"
       
    24 #include "sdpstackutil.h"
       
    25 #include "sdpconsts.h"
       
    26 #include "bt.h"
       
    27 
       
    28 #ifdef __FLOG_ACTIVE
       
    29 _LIT8(KLogComponent, LOG_COMPONENT_SDP);
       
    30 #endif
       
    31 
       
    32 CSdpProtocol::CSdpProtocol(CBTSecMan& aSecMan, RBTControlPlane& aControlPlane, CBTCodServiceMan& aCodMan)
       
    33 	:CBluetoothProtocolBase(aSecMan, aControlPlane, aCodMan),
       
    34 	iClients(_FOFF(CSdpClient, iLink))
       
    35 /** 
       
    36     Protocol Constructor.
       
    37 **/
       
    38 	{
       
    39 	LOG_FUNC
       
    40 	}
       
    41 
       
    42 CSdpProtocol::~CSdpProtocol()
       
    43 /** 
       
    44     Protocol Destructor.
       
    45     We only clean up the signallers as the NetDbProviders are owned by ESOCK and
       
    46     it is up to it to destroy them.
       
    47 **/
       
    48 	{
       
    49 	LOG_FUNC
       
    50 	while(!iClients.IsEmpty())
       
    51 		{
       
    52 		CSdpClient* c = iClients.First();
       
    53 		c->iLink.Deque();
       
    54 		delete c;
       
    55 		}
       
    56 	if(iLowerProtocol)
       
    57 		iLowerProtocol->Close();  // Matches the bind
       
    58 #ifdef __FLOG_ACTIVE
       
    59 	CLOSE_LOGGER
       
    60 #endif
       
    61 	}
       
    62 
       
    63 CSdpProtocol* CSdpProtocol::NewL(CBTSecMan& aSecMan, RBTControlPlane& aControlPlane, CBTCodServiceMan& aCodMan)
       
    64 	{
       
    65 #ifdef __FLOG_ACTIVE
       
    66 	CONNECT_LOGGER
       
    67 #endif
       
    68 	LOG_STATIC_FUNC
       
    69 	CSdpProtocol* i=new (ELeave) CSdpProtocol(aSecMan, aControlPlane, aCodMan);
       
    70 	return i;
       
    71 	}
       
    72 
       
    73 void CSdpProtocol::InitL(TDesC& /*aTag*/)
       
    74 /**
       
    75 	Pre-binding initialise.
       
    76 	Alloc any stuff we need.
       
    77 
       
    78 	This will only ever be called once during the lifetime of this
       
    79 	protocol.
       
    80 **/
       
    81 	{
       
    82 	LOG_FUNC
       
    83 	// ...nothing required!
       
    84 	}
       
    85 
       
    86 void CSdpProtocol::StartL()
       
    87 /**
       
    88 	Binding complete.
       
    89 **/
       
    90 	{
       
    91 	LOG_FUNC
       
    92 	  // Should check that we're bound now.
       
    93 	__ASSERT_ALWAYS(iLowerProtocol,Panic(ESdpNotBound));
       
    94 	}
       
    95 
       
    96 
       
    97 void CSdpProtocol::BindToL(CProtocolBase* aProtocol)
       
    98 /***
       
    99     Request by Protocol Mgr to bind to the specified protocol.
       
   100     We can only be bound to one lower layer protocol, so the function panics
       
   101     if we are already bound.
       
   102     @param aProtocol The protocol we need to bind to.
       
   103 **/
       
   104 	{
       
   105 	LOG_FUNC
       
   106 	FTRACE(TBuf<255> tmp(aProtocol->Tag()); 
       
   107 		   LOG1(_L("CSdpProtocol::BindToL binding to %S"),
       
   108 				  &tmp));
       
   109 	
       
   110 	if(!iLowerProtocol)
       
   111 		{
       
   112 #ifdef _DEBUG
       
   113 		TServerProtocolDesc prtDesc;
       
   114 		aProtocol->Identify(&prtDesc);
       
   115 
       
   116 		if(prtDesc.iAddrFamily!=KBTAddrFamily ||
       
   117 		   prtDesc.iProtocol!=KL2CAP)
       
   118 			{
       
   119 			User::Leave(KErrBtEskError);
       
   120 			}
       
   121 #endif
       
   122 
       
   123 		iLowerProtocol=static_cast<CBluetoothProtocolBase*>(aProtocol);
       
   124 		iLowerProtocol->BindL(this, KSDPPSM);
       
   125 		iLowerProtocol->Open();
       
   126 		}
       
   127 	else
       
   128 		{
       
   129 	    User::Leave(KErrSdpAlreadyBound);
       
   130 		}
       
   131 	}
       
   132 
       
   133 // Factory functions
       
   134 
       
   135 CNetDBProvdBase* CSdpProtocol::NewNetDatabaseL()
       
   136 /** 
       
   137 	Create a new NetDbProvider.
       
   138 	The NetDbProvider returned is owned by the caller -- this protocol will
       
   139 	not clean it up.  esock uses this function to create a new NetDbProvider,
       
   140 	and esock will delete when it is finished with it.
       
   141 **/
       
   142 	{
       
   143 	LOG_FUNC
       
   144 	return CSdpNetDbProvider::NewL(*this);
       
   145 	}
       
   146 
       
   147 // Query functions
       
   148 
       
   149 void CSdpProtocol::Identify(TServerProtocolDesc *aDesc)const
       
   150 /**
       
   151 	Identify request from SOCKET server
       
   152 **/
       
   153 	{
       
   154 	LOG_FUNC
       
   155 	ProtocolIdentity(aDesc);
       
   156 	}
       
   157 
       
   158 void CSdpProtocol::ProtocolIdentity(TServerProtocolDesc* aDesc)
       
   159 	{
       
   160 	LOG_STATIC_FUNC
       
   161 	_LIT(name,"SDP");
       
   162 	aDesc->iProtocol=KSDP;
       
   163 
       
   164 	aDesc->iName=name;
       
   165 	aDesc->iAddrFamily=KBTAddrFamily;
       
   166 	aDesc->iSockType=1;	// Bogus... but (debug) esock demands non-zero here.
       
   167 	
       
   168 	aDesc->iVersion=TVersion(KBTMajor,KBTMinor,KBTBuild);
       
   169 	aDesc->iByteOrder=EBigEndian;
       
   170 	aDesc->iServiceInfo=0;
       
   171 	aDesc->iNamingServices=KNSInfoDatabase;
       
   172 	aDesc->iSecurity=0;
       
   173 	aDesc->iMessageSize=KSocketMessageSizeUndefined;
       
   174 	aDesc->iServiceTypeInfo=ECantProcessMBufChains;
       
   175 	aDesc->iNumSockets=1;// Bogus... but (debug) esock demands non-zero here.
       
   176 	}
       
   177 
       
   178 void CSdpProtocol::CloseNow()
       
   179 /**
       
   180    Our reference is now zero, so start to close.
       
   181    When SDP server is in place, this'll be far more involved, as we'll
       
   182    want to hang around to service SDP queries, for some (???) length
       
   183    of time.
       
   184    In the mean time, we can just close, as there are now no netdbs left, so
       
   185    even if any SDP clients are still hanging around, they may as well die.
       
   186 **/
       
   187 	{
       
   188 	LOG_FUNC
       
   189 	iClosePending = ETrue;
       
   190 	TryToClose();
       
   191 	}
       
   192 
       
   193 void CSdpProtocol::Open()
       
   194 /**
       
   195    Request to open the protocol.
       
   196    The protocol may be repeatedly opened and closed.  The order of calls is
       
   197    InitL, [Open *n , Close * n,  CloseNow] * m, CanClose(upcall) etc.
       
   198 **/
       
   199      {
       
   200 	LOG_FUNC
       
   201 	 iClosePending = EFalse;
       
   202 	 CProtocolBase::Open();
       
   203      }
       
   204      
       
   205 void CSdpProtocol::Close()
       
   206 /**
       
   207    This is one session closing.
       
   208    Just call default, which decs the ref count.
       
   209    CloseNow will be called when this hits 0.
       
   210 **/
       
   211 	{
       
   212 	LOG_FUNC
       
   213 	CProtocolBase::Close();
       
   214 	}
       
   215 
       
   216 void CSdpProtocol::TryToClose()
       
   217  	{
       
   218 	LOG_FUNC
       
   219  	if (iClosePending && iClients.IsEmpty())
       
   220  		CanClose();	// delete's us!
       
   221  	}
       
   222 
       
   223 void CSdpProtocol::GetClient(CSdpNetDbProvider& aNetDbProvider)
       
   224 /**
       
   225     Find a Client for this NetDbProvider.
       
   226 
       
   227     When a Client is found, the NetDbProvider is notified via the ClientUp() call.
       
   228     Note that if there is no existing Client then it will be created
       
   229     here and the link brought up before the ClientUp() call is made.  This implies
       
   230     that the ClientUp() call on the NetDbProvider can be synchronous or Asynchronous.
       
   231     
       
   232     @param aNetDbProvider  The NetDbProvider that needs a Client.
       
   233 **/
       
   234 	{
       
   235 	LOG_FUNC
       
   236 	CSdpClient* client;
       
   237 	TBool needsL2CAPChannel = EFalse;
       
   238 
       
   239 	client=FindClient(aNetDbProvider.iRemoteDev);
       
   240 	if(!client)
       
   241 		{// Need to create one
       
   242 		needsL2CAPChannel = ETrue;
       
   243 		TRAPD(err, client=CSdpClient::NewL(*this, *iLowerProtocol));
       
   244 		if(err != KErrNone)
       
   245 			{
       
   246 			// Can't create a client, so error the NetDbProvider
       
   247 			aNetDbProvider.Error(err);
       
   248 			return;
       
   249 			}
       
   250 		// Add client to the Q
       
   251 		iClients.AddFirst(*client);
       
   252 		}	
       
   253 	// Take NetDb off the idle Q
       
   254 
       
   255 	// and add it to the client
       
   256 	aNetDbProvider.iClient=client;
       
   257 	client->AddNetDbProvider(aNetDbProvider);
       
   258 
       
   259 	// Bring up the client if needed
       
   260 	if (needsL2CAPChannel)
       
   261 	client->Open(aNetDbProvider.iRemoteDev);  // Will call back through ClientUp()
       
   262 	}
       
   263 
       
   264 CSdpClient* CSdpProtocol::FindClient(const TBTDevAddr& aAddr)
       
   265 /**
       
   266 	Find the existing client for this address.
       
   267 		@return   Pointer to a client for this address, or NULL if it doesn't exist.
       
   268 **/	
       
   269 	{
       
   270 	LOG_FUNC
       
   271 	TDblQueIter<CSdpClient> iter(iClients);
       
   272 	CSdpClient* client;
       
   273 
       
   274 	while(iter)
       
   275 		{
       
   276 		client=iter++;
       
   277 		if(client->iRemoteAddr == aAddr)
       
   278 			{
       
   279 			// We have a client, so return it
       
   280 			return client;
       
   281 			}
       
   282 		}
       
   283 	// No client
       
   284 	return 0;
       
   285 	}
       
   286 
       
   287 void CSdpProtocol::ClientDown(CSdpClient& aClient)
       
   288 	{
       
   289 	LOG_FUNC
       
   290 	aClient.iLink.Deque();
       
   291 	delete &aClient;
       
   292 	TryToClose();
       
   293 	}
       
   294 
       
   295 TInt CSdpProtocol::BearerConnectComplete(const TBTDevAddr& /*aAddr*/, CServProviderBase* /*aSSP*/)
       
   296 	{
       
   297 	LOG_FUNC
       
   298 	// SDP Protocol doesn't do incoming stuff!
       
   299 	Panic(ESdpClientPassiveConnect);
       
   300 	return KErrNotSupported;
       
   301 	}
       
   302