accessoryservices/remotecontrolfw/server/src/bulkbearerinterface.cpp
changeset 0 4e1aa6a622a0
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 // Copyright (c) 2008-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 // Bulk Bearer interface.
       
    15 //
       
    16 
       
    17 
       
    18 
       
    19 /**
       
    20  @file
       
    21  @internalComponent
       
    22 */
       
    23 
       
    24 #include "bulkbearerinterface.h"
       
    25 
       
    26 #include <remcon/remconbearerbulkinterface.h>
       
    27 #include <remcon/bearersecurity.h>
       
    28 #include <remcon/clientinfo.h>
       
    29 
       
    30 #include "bulkserver.h"
       
    31 #include "remconmessage.h"
       
    32 #include "utils.h"
       
    33 
       
    34 #include <bluetooth/logger.h>
       
    35 
       
    36 #ifdef __FLOG_ACTIVE
       
    37 _LIT8(KLogComponent, LOG_COMPONENT_REMCON_SERVER);
       
    38 #endif
       
    39 
       
    40 #ifdef _DEBUG
       
    41 PANICCATEGORY("bulkif");
       
    42 #endif // _DEBUG
       
    43 
       
    44 static TBool RemConAddrsMatch(const TRemConAddress& aFirstAddr, const TRemConAddress& aSecondAddr)
       
    45 	{
       
    46 	LOG_STATIC_FUNC
       
    47 	LOG(_L("aFirstAddr = ..."));
       
    48 	LOGHEXDESC(aFirstAddr.Addr());
       
    49 	LOG(_L("aSecondAddr = ..."));
       
    50 	LOGHEXDESC(aSecondAddr.Addr());
       
    51 	return aFirstAddr == aSecondAddr;
       
    52 	}
       
    53 
       
    54 static TUint32 RemConAddrHash(const TRemConAddress& aAddr)
       
    55 	{
       
    56 	LOG_STATIC_FUNC
       
    57 	TBuf8<sizeof(TUid) + TRemConAddress::KMaxAddrSize> buf;
       
    58 	buf.Append(TPckgC<TUid>(aAddr.BearerUid()));
       
    59 	buf.Append(aAddr.Addr());
       
    60 	LOG(_L("Hashing aAddr ..."));
       
    61 	LOGHEXDESC(buf);
       
    62 	TUint32 hash = DefaultHash::Des8(buf);
       
    63 	LOG1(_L("hash = 0x%08x"), hash);
       
    64 	return hash;
       
    65 	}
       
    66 
       
    67 CBulkBearerInterface* CBulkBearerInterface::NewL(CRemConBulkServer& aServer, CBearerManager& aBearerManager)
       
    68 	{
       
    69 	LOG_STATIC_FUNC;
       
    70 	CBulkBearerInterface* self = new(ELeave) CBulkBearerInterface(aServer, aBearerManager);
       
    71 	CleanupStack::PushL(self);
       
    72 	self->ConstructL(aBearerManager);
       
    73 	CleanupStack::Pop(self);
       
    74 	return self;
       
    75 	}
       
    76 
       
    77 CBulkBearerInterface::~CBulkBearerInterface()
       
    78 	{
       
    79 	LOG_FUNC;
       
    80 	
       
    81 	StopBearers();
       
    82 
       
    83 	iAddressedClients.Close();	
       
    84 	iBearerIfs.Close();
       
    85 	}
       
    86 
       
    87 CBulkBearerInterface::CBulkBearerInterface(CRemConBulkServer& aServer, CBearerManager& aBearerManager)
       
    88 	: iAddressedClients(RemConAddrHash, RemConAddrsMatch)
       
    89 	, iSecurityPoliciesIter(aBearerManager.BearerSecurityPolicies())
       
    90 	, iServer(aServer)
       
    91 	{
       
    92 	LOG_FUNC;
       
    93 	}
       
    94 
       
    95 void CBulkBearerInterface::ConstructL(CBearerManager& aBearerManager)
       
    96 	{
       
    97 	LOG_FUNC;
       
    98 	
       
    99 	aBearerManager.BulkInterfacesL(iBearerIfs);
       
   100 	if(iBearerIfs.Count() == 0)
       
   101 		{
       
   102 		LEAVEL(KErrNotSupported);
       
   103 		}
       
   104 	
       
   105 	TInt err = KErrNone;
       
   106 	TBool oneStarted = EFalse;
       
   107 	for(TInt i=0; i<iBearerIfs.Count(); i++)
       
   108 		{
       
   109 		ASSERT_DEBUG(iBearerIfs[i].iIf);
       
   110 		err = iBearerIfs[i].iIf->MrcbbiStartBulk(*this);
       
   111 		// if we couldn't start bulk service this is of no
       
   112 		// use to us.  Throw it in the bin.
       
   113 		if(err)
       
   114 			{
       
   115 			iBearerIfs.Remove(i);
       
   116 			i--;
       
   117 			}
       
   118 		else
       
   119 			{
       
   120 			oneStarted = ETrue;
       
   121 			}
       
   122 		}
       
   123 	if(!oneStarted)
       
   124 		{
       
   125 		LEAVEL(KErrNotSupported);
       
   126 		}
       
   127 	
       
   128 	// Don't store the bearer manager - the less we interact with it the better.
       
   129 	}
       
   130 
       
   131 void CBulkBearerInterface::StopBearers()
       
   132 	{
       
   133 	for(TInt i=0; i<iBearerIfs.Count(); i++)
       
   134 		{
       
   135 		iBearerIfs[i].iIf->MrcbbiStopBulk();
       
   136 		}
       
   137 	}
       
   138 
       
   139 void CBulkBearerInterface::BulkClientAvailable(const TRemConClientId& aClient)
       
   140 	{
       
   141 	LOG_FUNC;
       
   142 	ASSERT_DEBUG(aClient != KNullClientId);
       
   143 	
       
   144 	for(TInt i=0; i<iBearerIfs.Count(); i++)
       
   145 		{
       
   146 		ASSERT_DEBUG(iBearerIfs[i].iIf);
       
   147 		iBearerIfs[i].iIf->MrcbbiBulkClientAvailable(aClient);
       
   148 		}
       
   149 	}
       
   150 
       
   151 void CBulkBearerInterface::BulkClientRemoved(const TRemConClientId& aClient)
       
   152 	{
       
   153 	LOG_FUNC;
       
   154 	ASSERT_DEBUG(aClient != KNullClientId);
       
   155 	
       
   156 	for(TInt i=0; i<iBearerIfs.Count(); i++)
       
   157 		{
       
   158 		ASSERT_DEBUG(iBearerIfs[i].iIf);
       
   159 		iBearerIfs[i].iIf->MrcbbiBulkClientNotAvailable(aClient);
       
   160 		}
       
   161 	// Bearer has been notified so remove the bulk client from any addressing.
       
   162 	// Apologses for the O(n!) code below...it's the only way we can do it
       
   163 	// without allocating memory (and the size of the table shouldn't be big
       
   164 	// enough to cause problems.)
       
   165 	const TRemConClientId* val = NULL;
       
   166 	do
       
   167 		{
       
   168 		THashMapIter<TRemConAddress, TRemConClientId> iter(iAddressedClients);
       
   169 		val = iter.CurrentValue();
       
   170 		do
       
   171 			{
       
   172 			if(val && *val == aClient)
       
   173 				{
       
   174 				const TRemConAddress* key = iter.CurrentKey();
       
   175 				ASSERT_DEBUG(key);
       
   176 				TRemConAddress addr = *key;
       
   177 				iAddressedClients.Remove(addr);
       
   178 				// modified the hash map so we must discard the current iterator.
       
   179 				break;
       
   180 				}
       
   181 			}
       
   182 		while(val = iter.NextValue(), val);
       
   183 		}
       
   184 	while(val);
       
   185 	}
       
   186 
       
   187 MRemConBearerBulkInterface* CBulkBearerInterface::BearerIf(TUid aBearerUid) const
       
   188 	{
       
   189 	LOG_FUNC;
       
   190 	LOG1(_L8("\taBearerUid = 0x%08x"), aBearerUid);
       
   191 
       
   192 	MRemConBearerBulkInterface* bearerIf = NULL;
       
   193 
       
   194 	const TUint numBearerIfs = iBearerIfs.Count();
       
   195 	for ( TUint ii = 0 ; ii < numBearerIfs ; ++ii )
       
   196 		{
       
   197 		if ( iBearerIfs[ii].iBearerUid == aBearerUid )
       
   198 			{
       
   199 			bearerIf = iBearerIfs[ii].iIf;
       
   200 			break;
       
   201 			}
       
   202 		}
       
   203 
       
   204 	LOG1(_L8("\tbearerIf = 0x%08x"), bearerIf);
       
   205 	return bearerIf;
       
   206 	}
       
   207 
       
   208 TBool CBulkBearerInterface::CheckPolicy(TUid aBearerUid, const TClientInfo& aClientInfo)
       
   209 	{
       
   210 	LOG_FUNC;
       
   211 	TBool ret = EFalse;
       
   212 	iSecurityPoliciesIter.SetToFirst();
       
   213 	TBearerSecurity* sec = NULL;
       
   214 	while(sec = iSecurityPoliciesIter++, sec)
       
   215 		{
       
   216 		if(sec->BearerUid() == aBearerUid)
       
   217 			{
       
   218 			if(aClientInfo.Message().IsNull()) // already been complete, so we have to rely on a process handle
       
   219 				{
       
   220 				RProcess process;
       
   221 				TInt err = process.Open(aClientInfo.ProcessId(), EOwnerThread);
       
   222 				if(err == KErrNone)
       
   223 					{
       
   224 					ret = sec->SecurityPolicy().CheckPolicy(process);
       
   225 					}
       
   226 				// else we failed to open the handle...so we cannot do any more - fail check.
       
   227 				process.Close();
       
   228 				}
       
   229 			else
       
   230 				{
       
   231 				ret = sec->SecurityPolicy().CheckPolicy(aClientInfo.Message());
       
   232 				}
       
   233 			break;
       
   234 			}
       
   235 		}
       
   236 	LOG1(_L("\tret = %d"), ret);
       
   237 	return ret;
       
   238 	}
       
   239 
       
   240 
       
   241 TInt CBulkBearerInterface::Send(CRemConMessage& aMsg)
       
   242 	{
       
   243 	LOG_FUNC;
       
   244 	LOG3(_L8("\taMsg.Addr.BearerUid = 0x%08x, aMsg.InterfaceUid = 0x%08x, aMsg.OperationId = 0x%02x"), 
       
   245 		aMsg.Addr().BearerUid(), aMsg.InterfaceUid(), aMsg.OperationId());
       
   246 
       
   247 	MRemConBearerBulkInterface* const bearerIf = BearerIf(aMsg.Addr().BearerUid());
       
   248 	// Unlike the control server, there is no connection oriented nature, and so 
       
   249 	// the messages are all connectionless.  However these should all be in response
       
   250 	// to a message (as only responses are currently supported).
       
   251 	ASSERT_DEBUG(bearerIf);	
       
   252 
       
   253 	TInt ret = KErrNone;
       
   254 
       
   255 	switch ( aMsg.MsgType() )
       
   256 		{
       
   257 	case ERemConResponse:
       
   258 		ret = bearerIf->MrcbbiSendResponse(aMsg.InterfaceUid(), 
       
   259 			aMsg.OperationId(), 
       
   260 			aMsg.TransactionId(),
       
   261 			aMsg.OperationData(), 
       
   262 			aMsg.Addr());
       
   263 		if ( ret == KErrNone )
       
   264 			{
       
   265 			// On success, the bearer takes ownership of the message data.
       
   266 			aMsg.OperationData().Assign(NULL);
       
   267 			}
       
   268 		break;
       
   269 	case ERemConReject:
       
   270 		{
       
   271 		ASSERT_DEBUG(aMsg.OperationData().Length() == 0);
       
   272 		bearerIf->MrcbbiSendReject(aMsg.InterfaceUid(), 
       
   273 			aMsg.OperationId(), 
       
   274 			aMsg.TransactionId(),
       
   275 			aMsg.Addr());
       
   276 		break;
       
   277 		}
       
   278 	default:
       
   279 		DEBUG_PANIC_LINENUM; // the session protects us against this
       
   280 		break;
       
   281 		}
       
   282 
       
   283 	LOG1(_L8("\tret = %d"), ret);
       
   284 	return ret;
       
   285 	}
       
   286 
       
   287 TInt CBulkBearerInterface::MrcbboDoNewCommand(const TRemConAddress& aAddr)
       
   288 	{
       
   289 	LOG_FUNC;
       
   290 	LOG1(_L8("\taAddr.BearerUid = 0x%08x"), aAddr.BearerUid());
       
   291 
       
   292 	TRemConClientId clientId;
       
   293 	TRAPD(err, clientId = iAddressedClients.FindL(aAddr));
       
   294 	
       
   295 	if(err == KErrNone)
       
   296 		{
       
   297 		TRAP(err, NewCommandL(aAddr, clientId));
       
   298 		}
       
   299 
       
   300 	LOG1(_L8("\terr = %d"), err);
       
   301 	return err;
       
   302 	}
       
   303 
       
   304 TInt CBulkBearerInterface::MrcbboDoNewCommand(const TRemConAddress& aAddr, const TRemConClientId& aClient)
       
   305 	{
       
   306 	LOG_FUNC;
       
   307 	LOG1(_L8("\taAddr.BearerUid = 0x%08x"), aAddr.BearerUid());
       
   308 	LOG1(_L8("\taClient = 0x%08x"), aClient);
       
   309 
       
   310 	TRAPD(err, NewCommandL(aAddr, aClient));
       
   311 
       
   312 	LOG1(_L8("\terr = %d"), err);
       
   313 	return err;
       
   314 	}
       
   315 
       
   316 void CBulkBearerInterface::NewCommandL(const TRemConAddress& aAddr, const TRemConClientId& aClient)
       
   317 	{
       
   318 	LOG_FUNC;
       
   319 	LOG1(_L8("\taAddr.BearerUid = 0x%08x"), aAddr.BearerUid());
       
   320 	LOG1(_L8("\taClient = 0x%08x"), aClient);
       
   321 
       
   322 	// Get the calling bearer from aAddr and get the new command from it.
       
   323 	MRemConBearerBulkInterface* const bearerIf = BearerIf(aAddr.BearerUid());
       
   324 	ASSERT_DEBUG(bearerIf);
       
   325 	TUid interfaceUid;
       
   326 	TUint transactionId;
       
   327 	TUint operationId;
       
   328 	RBuf8 data;
       
   329 	TRemConAddress addr;
       
   330 	LEAVEIFERRORL(bearerIf->MrcbbiGetCommand(interfaceUid,
       
   331 		transactionId, 
       
   332 		operationId, 
       
   333 		data, 
       
   334 		addr));
       
   335 	LOG3(_L8("\treceived command with interfaceUid [0x%08x], operationId 0x%02x, data.Length = %d"), 
       
   336 		interfaceUid, operationId, data.Length());
       
   337 	// We now own what's pointed to by 'data'.
       
   338 	CleanupClosePushL(data);
       
   339 
       
   340 	CRemConMessage* msg = CRemConMessage::NewL(
       
   341 		aAddr,
       
   342 		aClient,
       
   343 		ERemConCommand,
       
   344 		ERemConMessageDefault,
       
   345 		interfaceUid,
       
   346 		operationId,
       
   347 		data,
       
   348 		0, // session ID as yet unknown
       
   349 		transactionId);
       
   350 	// 'msg' now has a pointer to the memory pointed to by 'data', and owns 
       
   351 	// it.
       
   352 	CLEANUPSTACK_POP1(&data);
       
   353 	// Give the new command to the server, which takes ownership of it. 
       
   354 	iServer.NewCommand(*msg);
       
   355 	}
       
   356 
       
   357 TUint CBulkBearerInterface::MrcbboDoNewTransactionId()
       
   358 	{
       
   359 	LOG_FUNC;
       
   360 	TUint newId = iRunningTransactionId;
       
   361 
       
   362 	if ( iRunningTransactionId == KMaxTUint )
       
   363 		{
       
   364 		iRunningTransactionId = 0;
       
   365 		}
       
   366 	else
       
   367 		{
       
   368 		++iRunningTransactionId;
       
   369 		}
       
   370 	
       
   371 	LOG1(_L8("CBulkBearerInterface::MrcbboDoNewTransactionId newId = %d"), newId);
       
   372 	return newId;
       
   373 	}
       
   374 
       
   375 void CBulkBearerInterface::MrcbboDoCommandExpired(TUint aTransactionId)
       
   376 	{
       
   377 	LOG_FUNC;
       
   378 	iServer.CommandExpired(aTransactionId);
       
   379 	}
       
   380 
       
   381 TInt CBulkBearerInterface::MrcbboDoSetAddressedClient(const TRemConAddress& aAddr, const TRemConClientId& aClient)
       
   382 	{
       
   383 	LOG_FUNC;
       
   384 	return iAddressedClients.Insert(aAddr, aClient); // hash map should cover uniqueness
       
   385 	}
       
   386 
       
   387 TInt CBulkBearerInterface::MrcbboDoRemoveAddressing(const TRemConAddress& aAddr)
       
   388 	{
       
   389 	LOG_FUNC;
       
   390 	return iAddressedClients.Remove(aAddr);
       
   391 	}
       
   392 
       
   393 
       
   394