accessoryservices/remotecontrolfw/server/src/targetsession.cpp
changeset 70 653a8b91b95e
equal deleted inserted replaced
64:61992147389a 70:653a8b91b95e
       
     1 // Copyright (c) 2010 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 the License "Symbian Foundation License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <bluetooth/logger.h>
       
    17 #include <remcon/remconifdetails.h>
       
    18 #include "messagequeue.h"
       
    19 #include "remconmessage.h"
       
    20 #include "remconserver.h"
       
    21 #include "server.h"
       
    22 #include "targetsession.h"
       
    23 #include "utils.h"
       
    24 
       
    25 #ifdef __FLOG_ACTIVE
       
    26 _LIT8(KLogComponent, LOG_COMPONENT_REMCON_SERVER);
       
    27 #endif
       
    28 
       
    29 #ifdef _DEBUG
       
    30 PANICCATEGORY("tgsession");
       
    31 #endif
       
    32 
       
    33 CRemConTargetSession* CRemConTargetSession::NewL(CRemConTargetClientProcess& aClientProcess,
       
    34 	CRemConServer& aServer,
       
    35 	CBearerManager& aBearerManager,
       
    36 	TUint aId)
       
    37 	{
       
    38 	LOG_STATIC_FUNC;
       
    39 	CRemConTargetSession* self = new(ELeave) CRemConTargetSession(aClientProcess, aServer, aBearerManager, aId);
       
    40 	CleanupStack::PushL(self);
       
    41 	self->ConstructL();
       
    42 	CLEANUPSTACK_POP1(self);
       
    43 	return self;
       
    44 	}
       
    45 
       
    46 CRemConTargetSession::~CRemConTargetSession()
       
    47 	{
       
    48 	LOG_FUNC;
       
    49 
       
    50 	// Tell the client process representation we've gone away- it may start its shutdown timer.
       
    51 	iClientProcess.TargetSessionClosed(*this);
       
    52 	}
       
    53 
       
    54 CRemConTargetSession::CRemConTargetSession(CRemConTargetClientProcess& aClientProcess,
       
    55 	CRemConServer& aServer, 
       
    56 	CBearerManager& aBearerManager,
       
    57 	TUint aId)
       
    58 	: CRemConSession(aServer, aBearerManager, aId),
       
    59 	iClientProcess(aClientProcess)
       
    60 	{
       
    61 	LOG_FUNC;
       
    62 	}
       
    63 
       
    64 void CRemConTargetSession::ConstructL()
       
    65 	{
       
    66 	LOG_FUNC;
       
    67 
       
    68 	BaseConstructL(iClientProcess.ClientInfo());
       
    69 
       
    70 	// Tell the client process representation about us (this will in turn inform the server).
       
    71 	LEAVEIFERRORL(iClientProcess.TargetSessionOpened(*this));
       
    72 	
       
    73 	// Set our pointer into the connection history at the current/'Last' item.
       
    74 	// Can't do this til we've told the server we exist
       
    75 	iServer.SetConnectionHistoryPointer(Id());
       
    76 	}
       
    77 
       
    78 TBool CRemConTargetSession::SupportedMessage(const CRemConMessage& aMsg) const
       
    79 	{
       
    80 	LOG_FUNC;
       
    81 
       
    82 	// Return true if the message is for an interface supported by this session
       
    83 	return InterfaceSupported(aMsg.InterfaceUid());
       
    84 	}
       
    85 
       
    86 TBool CRemConTargetSession::InterfaceSupported(TUid aInterfaceUid) const
       
    87 	{
       
    88 	LOG_FUNC;
       
    89 	LOG2(_L("\taInterfaceUid = 0x%08x, iInterestedAPIs = %d"), aInterfaceUid, iInterestedAPIs);
       
    90 
       
    91 	TBool result = iInterestedAPIs ? (FindInterfaceByUid(aInterfaceUid) != NULL) : EFalse;
       
    92 
       
    93 	LOG1(_L("result = %d"), result);
       
    94 	return result;
       
    95 	}
       
    96 
       
    97 void CRemConTargetSession::SetPlayerType(const RMessage2& aMessage)
       
    98 	{
       
    99 	LOG_FUNC;
       
   100 	
       
   101 	TInt err = aMessage.GetDesLength(1);
       
   102 	if (err >= 0)
       
   103 		{
       
   104 		TPlayerTypeInformation playerType;
       
   105 		RBuf8 playerName;
       
   106 	
       
   107 		TRAP(err, GetPlayerTypeAndNameL(aMessage, playerType, playerName));
       
   108 
       
   109 		if (err == KErrBadDescriptor)
       
   110 			{
       
   111 			PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBadDescriptor);
       
   112 			playerName.Close();
       
   113 			return;
       
   114 			}
       
   115 		else if (err == KErrArgument)
       
   116 			{
       
   117 			PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicIllegalIpc);
       
   118 			playerName.Close();
       
   119 			return;			
       
   120 			}
       
   121 		else if (err == KErrNone)
       
   122 			{
       
   123 			// If player type is not set, then update iClientProcess with information.
       
   124 			// If player type is already set, then dont allow this to be changed for the client (panic the client if the information is different).
       
   125 			if (!iClientProcess.HasPlayerInformation())
       
   126 				{
       
   127 				TRAP(err, iClientProcess.SetPlayerInformationL(playerType, playerName));
       
   128 				}
       
   129 			else if (!iClientProcess.PlayerInformationMatches(playerType, playerName))
       
   130 				{
       
   131 				PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicPlayerInfoAlreadySet);
       
   132 				playerName.Close();
       
   133 				return;
       
   134 				}
       
   135 			}
       
   136 
       
   137 		playerName.Close();
       
   138 		}
       
   139 	else if (err == KErrBadDescriptor)
       
   140 		{	
       
   141 		// The additional parameters are optional (i.e. old target clients won't provide them).
       
   142 		err = KErrNone;
       
   143 		}
       
   144 	
       
   145 	CompleteClient(aMessage, err);
       
   146 	}
       
   147 
       
   148 CRemConMessage* CRemConTargetSession::DoPrepareSendMessageL(const RMessage2& aMessage)
       
   149 	{
       
   150 	LOG_FUNC;
       
   151 
       
   152 	// Get the data the client wants to send.
       
   153 	TUid interfaceUid;
       
   154 	TUint operationId;
       
   155 
       
   156 	TRemConMessageSubType messageSubType;
       
   157 	RBuf8 sendDes;
       
   158 	if (!DoGetSendInfoLC(aMessage, interfaceUid, operationId, messageSubType, sendDes))
       
   159 		{
       
   160 		// DoGetSendInfoLC() panicked the message
       
   161 		return NULL;	
       
   162 		}
       
   163 
       
   164 	CRemConMessage* msg = NULL;
       
   165 	
       
   166 	LOG(_L("\tTARGET send"));
       
   167 
       
   168 	msg = CRemConMessage::NewL(
       
   169 		TRemConAddress(), // we don't know which remotes it's going to yet
       
   170 		ERemConResponse, // targets can only send responses
       
   171 		messageSubType,
       
   172 		interfaceUid,
       
   173 		operationId,
       
   174 		sendDes, // msg takes ownership
       
   175 		iClientProcess.Id(), // session id to match this response against the originating command
       
   176 		0, // transaction id not yet known
       
   177 		ETrue);
       
   178 	CLEANUPSTACK_POP1(&sendDes); // now owned by msg
       
   179 	
       
   180 	return msg;
       
   181 	}
       
   182 
       
   183 void CRemConTargetSession::SendUnreliable(const RMessage2& aMessage)
       
   184 	{
       
   185 	LOG_FUNC;
       
   186 
       
   187 	// Check we've had our features set...
       
   188 	if (!ClientAvailable())
       
   189 		{
       
   190 		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicClientFeaturesNotSet);
       
   191 		return;
       
   192 		}
       
   193 
       
   194 	CRemConMessage* msg = NULL;
       
   195 	TRAPD(err, msg = DoCreateUnreliableMessageL(aMessage));
       
   196 	CompleteClient(aMessage, err);
       
   197 	if (err == KErrNone)
       
   198 		{
       
   199 		ASSERT_DEBUG(iSendQueue);
       
   200 		if (iSending || !iSendQueue->IsEmpty())
       
   201 			{
       
   202 			iSendQueue->Append(*msg);
       
   203 			}
       
   204 		else
       
   205 			{
       
   206 			SendToServer(*msg);
       
   207 			}
       
   208 		}
       
   209 	}
       
   210 
       
   211 CRemConMessage* CRemConTargetSession::DoCreateUnreliableMessageL(const RMessage2& aMessage)
       
   212 	{
       
   213 	LOG_FUNC;
       
   214 
       
   215 	// Get the data the client wants to send.
       
   216 	TUid interfaceUid;
       
   217 	TUint operationId;
       
   218 	TRemConMessageSubType messageSubType;
       
   219 	RBuf8 sendDes;
       
   220 	DoGetSendInfoLC(aMessage, interfaceUid, operationId, messageSubType, sendDes);
       
   221 
       
   222 	// Before we ask the server to send, we must set our ClientInfo 
       
   223 	// correctly so the TSP can get information about the client. 
       
   224 	iClientInfo.Message() = aMessage;
       
   225 
       
   226 	CRemConMessage* msg = NULL;
       
   227 	
       
   228 	LOG(_L("\tTARGET send"));
       
   229 
       
   230 	msg = CRemConMessage::NewL(
       
   231 		TRemConAddress(), // we don't know which remotes it's going to yet
       
   232 		ERemConResponse, // targets can only send responses
       
   233 		messageSubType,
       
   234 		interfaceUid,
       
   235 		operationId,
       
   236 		sendDes, // msg takes ownership
       
   237 		iClientProcess.Id(), // session id to match this response against the originating command
       
   238 		0, // transaction id not yet known
       
   239 		EFalse);
       
   240 	CLEANUPSTACK_POP1(&sendDes); // now owned by msg
       
   241 
       
   242 	return msg;
       
   243 	}
       
   244 
       
   245 void CRemConTargetSession::DoSendCancel()
       
   246 	{
       
   247 	LOG_FUNC;
       
   248 
       
   249 	// We do not cancel any pending response messages, so don't need
       
   250 	// to notify the server here.
       
   251 
       
   252 	NumRemotesToTry() = 0;
       
   253 	iSendError = KErrCancel;
       
   254 	CompleteSend();
       
   255 	}
       
   256 
       
   257 void CRemConTargetSession::RegisterInterestedAPIs(const RMessage2& aMessage)
       
   258 	{
       
   259 	LOG_FUNC;
       
   260 	
       
   261 	// Check we haven't had our features set yet
       
   262 	if (ClientAvailable())
       
   263 		{
       
   264 		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicClientFeaturesNotSet);
       
   265 		return;
       
   266 		}
       
   267 
       
   268 	CRemConInterfaceDetailsArray* interfaces = NULL;
       
   269 	TRAPD(err, interfaces = ExtractInterestedAPIsL(aMessage));
       
   270 	
       
   271 	if(err == KErrNone)
       
   272 		{
       
   273 		// Ensure that none of these interfaces have already been registered by the client.
       
   274 		// Also note if bulk server is required.
       
   275 		TInt count = interfaces->Array().Count();
       
   276 		TBool bulkServerRequired = EFalse;
       
   277 		for (TInt ix=0; ix < count; ++ix)
       
   278 			{
       
   279 			CRemConInterfaceDetails* details = interfaces->Array()[ix];
       
   280 			ASSERT_DEBUG(details);
       
   281 			if (iClientProcess.IsInterfaceTypeRegisteredByAnotherSession(*this, details->Uid()))
       
   282 				{
       
   283 				// Destroy new interfaces and panic client.
       
   284 				delete interfaces;
       
   285 				PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicClientInterfaceAlreadyRegistered);
       
   286 				return;
       
   287 				}
       
   288 			else if (details->IsBulk())
       
   289 				{
       
   290 				bulkServerRequired = ETrue;
       
   291 				}
       
   292 			}
       
   293 	
       
   294 		// Interfaces are OK, notify server if bulk server is required.
       
   295 		iInterestedAPIs = interfaces;
       
   296 		iClientProcess.InterfacesRegistered();
       
   297 		if (bulkServerRequired)
       
   298 			{
       
   299 			iServer.BulkServerRequired();
       
   300 			}
       
   301 		}
       
   302 	else
       
   303 		{
       
   304 		ASSERT_DEBUG(interfaces == NULL);
       
   305 		}
       
   306 	
       
   307 	CompleteClient(aMessage, err);
       
   308 	}
       
   309 
       
   310 void CRemConTargetSession::SendToServer(CRemConMessage& aMsg)
       
   311 	{
       
   312 	LOG_FUNC;
       
   313 	
       
   314 	// Set our completion members.
       
   315 	NumRemotes() = 0;
       
   316 	NumRemotesToTry() = 0;
       
   317 	SendError() = KErrNone;
       
   318 
       
   319 	
       
   320 	iSending = (aMsg.IsReliableSend()) ? ESendingReliable: ESendingUnreliable;
       
   321 
       
   322 	iServer.SendResponse(aMsg, iClientProcess);
       
   323 	}
       
   324 
       
   325 void CRemConTargetSession::DoReceive()
       
   326 	{
       
   327 	// Request messages from the server on behalf of the client.
       
   328 	// If there's anything waiting to be given to us, iClientProcess will call 
       
   329 	// back to us with it.
       
   330 	iServer.ReceiveRequest(iClientProcess);
       
   331 	}