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