accessoryservices/remotecontrolfw/server/src/controllersession.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 "activehelper.h"
hgs
parents:
diff changeset
    18
#include "bearermanager.h"
hgs
parents:
diff changeset
    19
#include "controllersession.h"
hgs
parents:
diff changeset
    20
#include "messagequeue.h"
hgs
parents:
diff changeset
    21
#include "remconmessage.h"
hgs
parents:
diff changeset
    22
#include "remconserver.h"
hgs
parents:
diff changeset
    23
#include "server.h"
hgs
parents:
diff changeset
    24
#include "utils.h"
hgs
parents:
diff changeset
    25
hgs
parents:
diff changeset
    26
#ifdef __FLOG_ACTIVE
hgs
parents:
diff changeset
    27
_LIT8(KLogComponent, LOG_COMPONENT_REMCON_SERVER);
hgs
parents:
diff changeset
    28
#endif
hgs
parents:
diff changeset
    29
hgs
parents:
diff changeset
    30
#ifdef _DEBUG
hgs
parents:
diff changeset
    31
PANICCATEGORY("ctsession");
hgs
parents:
diff changeset
    32
#endif
hgs
parents:
diff changeset
    33
hgs
parents:
diff changeset
    34
hgs
parents:
diff changeset
    35
CRemConControllerSession* CRemConControllerSession::NewL(CRemConServer& aServer,
hgs
parents:
diff changeset
    36
	CBearerManager& aBearerManager,
hgs
parents:
diff changeset
    37
	const TClientInfo& aClientInfo,
hgs
parents:
diff changeset
    38
	TUint aId)
hgs
parents:
diff changeset
    39
	{
hgs
parents:
diff changeset
    40
	LOG_STATIC_FUNC;
hgs
parents:
diff changeset
    41
	CRemConControllerSession* self = new(ELeave) CRemConControllerSession(aServer, aBearerManager, aId);
hgs
parents:
diff changeset
    42
	CleanupStack::PushL(self);
hgs
parents:
diff changeset
    43
	self->ConstructL(aClientInfo);
hgs
parents:
diff changeset
    44
	CLEANUPSTACK_POP1(self);
hgs
parents:
diff changeset
    45
	return self;
hgs
parents:
diff changeset
    46
	}
hgs
parents:
diff changeset
    47
hgs
parents:
diff changeset
    48
CRemConControllerSession::~CRemConControllerSession()
hgs
parents:
diff changeset
    49
	{
hgs
parents:
diff changeset
    50
	LOG_FUNC;
hgs
parents:
diff changeset
    51
hgs
parents:
diff changeset
    52
	delete iPendingMsgProcessor;
hgs
parents:
diff changeset
    53
hgs
parents:
diff changeset
    54
	// we will need to tell the server which bearer this used to be connected to
hgs
parents:
diff changeset
    55
	// this enables the server to not inform a bearer that is already connected
hgs
parents:
diff changeset
    56
	// that its been connected
hgs
parents:
diff changeset
    57
	// Tell the server we've gone away- it may start its shutdown timer.
hgs
parents:
diff changeset
    58
	iServer.ControllerClientClosed(*this, iRemoteAddress.BearerUid());
hgs
parents:
diff changeset
    59
	iPlayerName.Close();
hgs
parents:
diff changeset
    60
	}
hgs
parents:
diff changeset
    61
hgs
parents:
diff changeset
    62
CRemConControllerSession::CRemConControllerSession(CRemConServer& aServer, 
hgs
parents:
diff changeset
    63
	CBearerManager& aBearerManager,
hgs
parents:
diff changeset
    64
	TUint aId)
hgs
parents:
diff changeset
    65
	: CRemConSession(aServer, aBearerManager, aId)
hgs
parents:
diff changeset
    66
	{
hgs
parents:
diff changeset
    67
	LOG_FUNC;
hgs
parents:
diff changeset
    68
	}
hgs
parents:
diff changeset
    69
hgs
parents:
diff changeset
    70
void CRemConControllerSession::ConstructL(const TClientInfo& aClientInfo)
hgs
parents:
diff changeset
    71
	{
hgs
parents:
diff changeset
    72
	LOG_FUNC;
hgs
parents:
diff changeset
    73
	
hgs
parents:
diff changeset
    74
	BaseConstructL(aClientInfo);
hgs
parents:
diff changeset
    75
hgs
parents:
diff changeset
    76
	iPendingMsgProcessor = new (ELeave) CActiveHelper(*this);
hgs
parents:
diff changeset
    77
	
hgs
parents:
diff changeset
    78
	LEAVEIFERRORL(iServer.ControllerClientOpened(*this));
hgs
parents:
diff changeset
    79
hgs
parents:
diff changeset
    80
	// Set our pointer into the connection history at the current/'Last' item.
hgs
parents:
diff changeset
    81
	// Can't do this til we've told the server we exist
hgs
parents:
diff changeset
    82
	iServer.SetConnectionHistoryPointer(Id());
hgs
parents:
diff changeset
    83
	}
hgs
parents:
diff changeset
    84
hgs
parents:
diff changeset
    85
TBool CRemConControllerSession::SupportedMessage(const CRemConMessage& aMsg) const
hgs
parents:
diff changeset
    86
	{
hgs
parents:
diff changeset
    87
	LOG_FUNC;
hgs
parents:
diff changeset
    88
	LOG1(_L("\taMsg.InterfaceUid() = 0x%08x"), aMsg.InterfaceUid());
hgs
parents:
diff changeset
    89
hgs
parents:
diff changeset
    90
	// Return true unless this is a command for an unsupported interface
hgs
parents:
diff changeset
    91
	TBool result = !(aMsg.MsgType() == ERemConCommand && !FindInterfaceByUid(aMsg.InterfaceUid()));
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 CRemConControllerSession::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
	// Controller clients don't provide the additional parameters are optional,
hgs
parents:
diff changeset
   102
	// so we just complete the message with KErrNone.
hgs
parents:
diff changeset
   103
	CompleteClient(aMessage, KErrNone);
hgs
parents:
diff changeset
   104
	}
hgs
parents:
diff changeset
   105
hgs
parents:
diff changeset
   106
void CRemConControllerSession::CompleteConnect(const TRemConAddress& aAddr, TInt aError)
hgs
parents:
diff changeset
   107
	{
hgs
parents:
diff changeset
   108
	LOG_FUNC;
hgs
parents:
diff changeset
   109
	LOG2(_L("\taError = %d, aAddr.BearerUid = 0x%08x"), aError, aAddr.BearerUid());
hgs
parents:
diff changeset
   110
hgs
parents:
diff changeset
   111
	LOG1(_L("\tiRemoteAddress.BearerUid = 0x%08x"), iRemoteAddress.BearerUid());
hgs
parents:
diff changeset
   112
	LOG1(_L("\tiConnectBearerMsg.Handle = %d"), iConnectBearerMsg.Handle());
hgs
parents:
diff changeset
   113
hgs
parents:
diff changeset
   114
	if ( iRemoteAddress == aAddr )
hgs
parents:
diff changeset
   115
		{
hgs
parents:
diff changeset
   116
		if ( iConnectBearerMsg.Handle() )
hgs
parents:
diff changeset
   117
			{
hgs
parents:
diff changeset
   118
			// We are a session that has an outstanding request on this specific 
hgs
parents:
diff changeset
   119
			// connection address.
hgs
parents:
diff changeset
   120
			CompleteClient(iConnectBearerMsg, aError);
hgs
parents:
diff changeset
   121
			}
hgs
parents:
diff changeset
   122
		else 
hgs
parents:
diff changeset
   123
			{
hgs
parents:
diff changeset
   124
			// Connect bearer message is not valid. 
hgs
parents:
diff changeset
   125
			// Check for pending messages.
hgs
parents:
diff changeset
   126
			CheckForPendingMsg();
hgs
parents:
diff changeset
   127
			}
hgs
parents:
diff changeset
   128
		}
hgs
parents:
diff changeset
   129
	}
hgs
parents:
diff changeset
   130
hgs
parents:
diff changeset
   131
void CRemConControllerSession::CompleteDisconnect(const TRemConAddress& aAddr, TInt aError)
hgs
parents:
diff changeset
   132
	{
hgs
parents:
diff changeset
   133
	LOG_FUNC;
hgs
parents:
diff changeset
   134
	LOG2(_L("\taError = %d, aAddr.BearerUid = 0x%08x"), aError, aAddr.BearerUid());
hgs
parents:
diff changeset
   135
hgs
parents:
diff changeset
   136
	LOG1(_L("\tiRemoteAddress.BearerUid = 0x%08x"), iRemoteAddress.BearerUid());
hgs
parents:
diff changeset
   137
	LOG1(_L("\tiDisconnectBearerMsg.Handle = %d"), iDisconnectBearerMsg.Handle());
hgs
parents:
diff changeset
   138
hgs
parents:
diff changeset
   139
	if ( iRemoteAddress == aAddr )
hgs
parents:
diff changeset
   140
		{
hgs
parents:
diff changeset
   141
		if ( iDisconnectBearerMsg.Handle() )
hgs
parents:
diff changeset
   142
			{
hgs
parents:
diff changeset
   143
			// We are a session that has an outstanding request on this specific 
hgs
parents:
diff changeset
   144
			// connection address.
hgs
parents:
diff changeset
   145
			CompleteClient(iDisconnectBearerMsg, aError);
hgs
parents:
diff changeset
   146
			}
hgs
parents:
diff changeset
   147
		else 
hgs
parents:
diff changeset
   148
			{
hgs
parents:
diff changeset
   149
			// Diconnect bearer message is not valid. 
hgs
parents:
diff changeset
   150
			// Check for pending messages.
hgs
parents:
diff changeset
   151
			CheckForPendingMsg();
hgs
parents:
diff changeset
   152
			}
hgs
parents:
diff changeset
   153
hgs
parents:
diff changeset
   154
		}
hgs
parents:
diff changeset
   155
	}
hgs
parents:
diff changeset
   156
hgs
parents:
diff changeset
   157
void CRemConControllerSession::ProcessPendingMsgL()
hgs
parents:
diff changeset
   158
	{
hgs
parents:
diff changeset
   159
	LOG_FUNC;
hgs
parents:
diff changeset
   160
	if (!iPendingMsg.Handle())
hgs
parents:
diff changeset
   161
		{
hgs
parents:
diff changeset
   162
		// This means that the pending connect or disconnect message,
hgs
parents:
diff changeset
   163
		// has been cancelled by the time we got here.
hgs
parents:
diff changeset
   164
		// (It was cancelled between two following calls:
hgs
parents:
diff changeset
   165
		// iPendingMsgProcessor::Complete and iPendingMsgProcessor::RunL
hgs
parents:
diff changeset
   166
		return;
hgs
parents:
diff changeset
   167
		}
hgs
parents:
diff changeset
   168
hgs
parents:
diff changeset
   169
	ServiceL(iPendingMsg);
hgs
parents:
diff changeset
   170
	if (iPendingMsg.Handle())
hgs
parents:
diff changeset
   171
		{
hgs
parents:
diff changeset
   172
		// This means that the pending msg has not been completed in ServiceL call.
hgs
parents:
diff changeset
   173
		// It was stored either in iConnectBearerMsg or iDisconnectBearerMsg member.
hgs
parents:
diff changeset
   174
		// This also means that this message is not "pending" any more 
hgs
parents:
diff changeset
   175
		// (as processing of its copy has been started). 
hgs
parents:
diff changeset
   176
		// However because the copy will get completed we need to 
hgs
parents:
diff changeset
   177
		// clean iPendingMsg.iHandle here
hgs
parents:
diff changeset
   178
		// To supress coverity error for uninitialized use of 'emptyMsg' coverity annotations
hgs
parents:
diff changeset
   179
		// are used as the in-line default constructor of RMessage2 doesn't initialize all member variables.
hgs
parents:
diff changeset
   180
		// coverity[var_decl]
hgs
parents:
diff changeset
   181
		RMessage2 emptyMsg;
hgs
parents:
diff changeset
   182
		iPendingMsg = emptyMsg;
hgs
parents:
diff changeset
   183
		}
hgs
parents:
diff changeset
   184
	}
hgs
parents:
diff changeset
   185
hgs
parents:
diff changeset
   186
void CRemConControllerSession::CheckForPendingMsg() const
hgs
parents:
diff changeset
   187
	{
hgs
parents:
diff changeset
   188
	LOG_FUNC;
hgs
parents:
diff changeset
   189
	if (iPendingMsg.Handle())
hgs
parents:
diff changeset
   190
		{
hgs
parents:
diff changeset
   191
		ASSERT_DEBUG(iPendingMsgProcessor);
hgs
parents:
diff changeset
   192
		iPendingMsgProcessor->Complete();
hgs
parents:
diff changeset
   193
		}
hgs
parents:
diff changeset
   194
	}
hgs
parents:
diff changeset
   195
hgs
parents:
diff changeset
   196
CRemConMessage* CRemConControllerSession::DoPrepareSendMessageL(const RMessage2& aMessage)
hgs
parents:
diff changeset
   197
	{
hgs
parents:
diff changeset
   198
	LOG_FUNC;
hgs
parents:
diff changeset
   199
hgs
parents:
diff changeset
   200
	// Check we don't have a disconnect outstanding- this makes no sense from 
hgs
parents:
diff changeset
   201
	// a client viewpoint (they should cancel the disconnect first).
hgs
parents:
diff changeset
   202
	// [The client is allowed to have a connect request outstanding- the 
hgs
parents:
diff changeset
   203
	// bearer manager makes sure a bearer-level connect is not posted on the 
hgs
parents:
diff changeset
   204
	// same address twice.]
hgs
parents:
diff changeset
   205
	if ( iDisconnectBearerMsg.Handle() )
hgs
parents:
diff changeset
   206
		{
hgs
parents:
diff changeset
   207
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBearerControlOutstanding);
hgs
parents:
diff changeset
   208
		return NULL;
hgs
parents:
diff changeset
   209
		}
hgs
parents:
diff changeset
   210
hgs
parents:
diff changeset
   211
	// Get the data the client wants to send.
hgs
parents:
diff changeset
   212
	TUid interfaceUid;
hgs
parents:
diff changeset
   213
	TUint operationId;
hgs
parents:
diff changeset
   214
hgs
parents:
diff changeset
   215
	TRemConMessageSubType messageSubType;
hgs
parents:
diff changeset
   216
	RBuf8 sendDes;
hgs
parents:
diff changeset
   217
	if (!DoGetSendInfoLC(aMessage, interfaceUid, operationId, messageSubType, sendDes))
hgs
parents:
diff changeset
   218
		{
hgs
parents:
diff changeset
   219
		// DoGetSendInfoLC() panicked the message
hgs
parents:
diff changeset
   220
		return NULL;
hgs
parents:
diff changeset
   221
		}
hgs
parents:
diff changeset
   222
hgs
parents:
diff changeset
   223
	CRemConMessage* msg = NULL;
hgs
parents:
diff changeset
   224
	LOG(_L("\tCONTROLLER send"));
hgs
parents:
diff changeset
   225
	if (  (messageSubType == ERemConNotifyCommandAwaitingInterim)
hgs
parents:
diff changeset
   226
	   || (messageSubType == ERemConNotifyCommandAwaitingChanged)
hgs
parents:
diff changeset
   227
		)
hgs
parents:
diff changeset
   228
		{
hgs
parents:
diff changeset
   229
		LOG(_L("\terror, not allowed to use Send() to send notify command"));
hgs
parents:
diff changeset
   230
		CleanupStack::PopAndDestroy(&sendDes);
hgs
parents:
diff changeset
   231
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicIllegalIpc);
hgs
parents:
diff changeset
   232
		}
hgs
parents:
diff changeset
   233
	else
hgs
parents:
diff changeset
   234
		{
hgs
parents:
diff changeset
   235
		msg = CRemConMessage::NewL(
hgs
parents:
diff changeset
   236
				iRemoteAddress, // either specified (if we're connection-oriented) or null (we're connectionless- this field will be filled in by the TSP)
hgs
parents:
diff changeset
   237
				ERemConCommand, 
hgs
parents:
diff changeset
   238
				messageSubType,
hgs
parents:
diff changeset
   239
				interfaceUid,
hgs
parents:
diff changeset
   240
				operationId,
hgs
parents:
diff changeset
   241
				sendDes, // msg takes ownership
hgs
parents:
diff changeset
   242
				Id(), // session id for when the response comes back
hgs
parents:
diff changeset
   243
				0, // we let the bearer manager invent a new transaction id when the message gets to it
hgs
parents:
diff changeset
   244
				ETrue);
hgs
parents:
diff changeset
   245
		CLEANUPSTACK_POP1(&sendDes); // now owned by msg
hgs
parents:
diff changeset
   246
		}		
hgs
parents:
diff changeset
   247
hgs
parents:
diff changeset
   248
	return msg;
hgs
parents:
diff changeset
   249
	}
hgs
parents:
diff changeset
   250
hgs
parents:
diff changeset
   251
void CRemConControllerSession::SendUnreliable(const RMessage2& aMessage)
hgs
parents:
diff changeset
   252
	{
hgs
parents:
diff changeset
   253
	LOG_FUNC;
hgs
parents:
diff changeset
   254
hgs
parents:
diff changeset
   255
	// Check we've had our features set...
hgs
parents:
diff changeset
   256
	if (!ClientAvailable())
hgs
parents:
diff changeset
   257
		{
hgs
parents:
diff changeset
   258
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicClientFeaturesNotSet);
hgs
parents:
diff changeset
   259
		return;
hgs
parents:
diff changeset
   260
		}
hgs
parents:
diff changeset
   261
hgs
parents:
diff changeset
   262
	// Check we don't have a disconnect outstanding- this makes no sense from 
hgs
parents:
diff changeset
   263
	// a client viewpoint (they should cancel the disconnect first).
hgs
parents:
diff changeset
   264
	// [The client is allowed to have a connect request outstanding- the 
hgs
parents:
diff changeset
   265
	// bearer manager makes sure a bearer-level connect is not posted on the 
hgs
parents:
diff changeset
   266
	// same address twice.]
hgs
parents:
diff changeset
   267
	if ( iDisconnectBearerMsg.Handle() )
hgs
parents:
diff changeset
   268
		{
hgs
parents:
diff changeset
   269
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBearerControlOutstanding);
hgs
parents:
diff changeset
   270
		return;
hgs
parents:
diff changeset
   271
		}
hgs
parents:
diff changeset
   272
hgs
parents:
diff changeset
   273
	CRemConMessage* msg = NULL;
hgs
parents:
diff changeset
   274
	TRAPD(err, msg = DoCreateUnreliableMessageL(aMessage));
hgs
parents:
diff changeset
   275
	CompleteClient(aMessage, err);
hgs
parents:
diff changeset
   276
	if (err == KErrNone)
hgs
parents:
diff changeset
   277
		{
hgs
parents:
diff changeset
   278
		ASSERT_DEBUG(iSendQueue);
hgs
parents:
diff changeset
   279
		if (iSending || !iSendQueue->IsEmpty())
hgs
parents:
diff changeset
   280
			{
hgs
parents:
diff changeset
   281
			iSendQueue->Append(*msg);
hgs
parents:
diff changeset
   282
			}
hgs
parents:
diff changeset
   283
		else
hgs
parents:
diff changeset
   284
			{
hgs
parents:
diff changeset
   285
			SendToServer(*msg);
hgs
parents:
diff changeset
   286
			}
hgs
parents:
diff changeset
   287
		}
hgs
parents:
diff changeset
   288
	}
hgs
parents:
diff changeset
   289
hgs
parents:
diff changeset
   290
CRemConMessage* CRemConControllerSession::DoCreateUnreliableMessageL(const RMessage2& aMessage)
hgs
parents:
diff changeset
   291
	{
hgs
parents:
diff changeset
   292
	LOG_FUNC;
hgs
parents:
diff changeset
   293
hgs
parents:
diff changeset
   294
	// Get the data the client wants to send.
hgs
parents:
diff changeset
   295
	TUid interfaceUid;
hgs
parents:
diff changeset
   296
	TUint operationId;
hgs
parents:
diff changeset
   297
	TRemConMessageSubType messageSubType;
hgs
parents:
diff changeset
   298
	RBuf8 sendDes;
hgs
parents:
diff changeset
   299
	DoGetSendInfoLC(aMessage, interfaceUid, operationId, messageSubType, sendDes);
hgs
parents:
diff changeset
   300
hgs
parents:
diff changeset
   301
	// Before we ask the server to send, we must set our ClientInfo 
hgs
parents:
diff changeset
   302
	// correctly so the TSP can get information about the client. 
hgs
parents:
diff changeset
   303
	iClientInfo.Message() = aMessage;
hgs
parents:
diff changeset
   304
hgs
parents:
diff changeset
   305
	CRemConMessage* msg = NULL;
hgs
parents:
diff changeset
   306
	
hgs
parents:
diff changeset
   307
	LOG(_L("\tCONTROLLER send"));
hgs
parents:
diff changeset
   308
	
hgs
parents:
diff changeset
   309
	// A client is not allowed to send an unreliable notify command.
hgs
parents:
diff changeset
   310
	if	(	(messageSubType == ERemConNotifyCommandAwaitingInterim)
hgs
parents:
diff changeset
   311
		||	(messageSubType == ERemConNotifyCommandAwaitingChanged)
hgs
parents:
diff changeset
   312
		)
hgs
parents:
diff changeset
   313
		{
hgs
parents:
diff changeset
   314
		LOG(_L8("\tNot allowed to send unreliable notify command"));
hgs
parents:
diff changeset
   315
		CleanupStack::PopAndDestroy(&sendDes);
hgs
parents:
diff changeset
   316
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicIllegalIpc);
hgs
parents:
diff changeset
   317
		LEAVEL(KErrBadDescriptor);
hgs
parents:
diff changeset
   318
		}
hgs
parents:
diff changeset
   319
	
hgs
parents:
diff changeset
   320
	msg = CRemConMessage::NewL(
hgs
parents:
diff changeset
   321
		iRemoteAddress, // either specified (if we're connection-oriented) or null (we're connectionless- this field will be filled in by the TSP)
hgs
parents:
diff changeset
   322
		ERemConCommand, // controllers can only send commands
hgs
parents:
diff changeset
   323
		messageSubType,
hgs
parents:
diff changeset
   324
		interfaceUid,
hgs
parents:
diff changeset
   325
		operationId,
hgs
parents:
diff changeset
   326
		sendDes, // msg takes ownership
hgs
parents:
diff changeset
   327
		Id(), // session id for when the response comes back
hgs
parents:
diff changeset
   328
		0, // we let the bearer manager invent a new transaction id when the message gets to it
hgs
parents:
diff changeset
   329
		EFalse);
hgs
parents:
diff changeset
   330
	CLEANUPSTACK_POP1(&sendDes); // now owned by msg
hgs
parents:
diff changeset
   331
hgs
parents:
diff changeset
   332
	return msg;
hgs
parents:
diff changeset
   333
	}
hgs
parents:
diff changeset
   334
hgs
parents:
diff changeset
   335
void CRemConControllerSession::RegisterInterestedAPIs(const RMessage2& aMessage)
hgs
parents:
diff changeset
   336
	{
hgs
parents:
diff changeset
   337
	LOG_FUNC;
hgs
parents:
diff changeset
   338
	// No interfaces should have been registered yet!
hgs
parents:
diff changeset
   339
	ASSERT_DEBUG(iInterestedAPIs == NULL);
hgs
parents:
diff changeset
   340
	
hgs
parents:
diff changeset
   341
	TRAPD(err, iInterestedAPIs = ExtractInterestedAPIsL(aMessage));
hgs
parents:
diff changeset
   342
	
hgs
parents:
diff changeset
   343
	iServer.ControllerClientAvailable();
hgs
parents:
diff changeset
   344
hgs
parents:
diff changeset
   345
	CompleteClient(aMessage, err);
hgs
parents:
diff changeset
   346
	}
hgs
parents:
diff changeset
   347
hgs
parents:
diff changeset
   348
void CRemConControllerSession::GoConnectionOriented(const RMessage2& aMessage)
hgs
parents:
diff changeset
   349
	{
hgs
parents:
diff changeset
   350
	LOG_FUNC;
hgs
parents:
diff changeset
   351
hgs
parents:
diff changeset
   352
	// Check we've had our features set...
hgs
parents:
diff changeset
   353
	if (!ClientAvailable())
hgs
parents:
diff changeset
   354
		{
hgs
parents:
diff changeset
   355
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicClientFeaturesNotSet);
hgs
parents:
diff changeset
   356
		return;
hgs
parents:
diff changeset
   357
		}
hgs
parents:
diff changeset
   358
hgs
parents:
diff changeset
   359
	if ( !iRemoteAddress.IsNull() )
hgs
parents:
diff changeset
   360
		{
hgs
parents:
diff changeset
   361
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicAlreadyConnectionOriented);
hgs
parents:
diff changeset
   362
		return;
hgs
parents:
diff changeset
   363
		}
hgs
parents:
diff changeset
   364
hgs
parents:
diff changeset
   365
	if ( iConnectBearerMsg.Handle() || iDisconnectBearerMsg.Handle() || iSendMsg.Handle())
hgs
parents:
diff changeset
   366
		{
hgs
parents:
diff changeset
   367
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBearerControlOutstanding);
hgs
parents:
diff changeset
   368
		return;
hgs
parents:
diff changeset
   369
		}
hgs
parents:
diff changeset
   370
	if (iSending != ENotSending)
hgs
parents:
diff changeset
   371
		{
hgs
parents:
diff changeset
   372
		DoSendCancel();
hgs
parents:
diff changeset
   373
		}
hgs
parents:
diff changeset
   374
	EmptySendQueue();
hgs
parents:
diff changeset
   375
	
hgs
parents:
diff changeset
   376
	// Get the desired address from the message and check it.
hgs
parents:
diff changeset
   377
	const TUid uid = TUid::Uid(aMessage.Int0());
hgs
parents:
diff changeset
   378
	LOG1(_L("\tuid = 0x%08x"), uid);
hgs
parents:
diff changeset
   379
	// Check the requested bearer exists.
hgs
parents:
diff changeset
   380
	TBool bearerExists = iBearerManager.BearerExists(uid);
hgs
parents:
diff changeset
   381
	if ( !bearerExists)
hgs
parents:
diff changeset
   382
		{
hgs
parents:
diff changeset
   383
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBearerPluginIncorrectInterface);
hgs
parents:
diff changeset
   384
		return;
hgs
parents:
diff changeset
   385
		}
hgs
parents:
diff changeset
   386
	// Check the bearer-specific part of the address.
hgs
parents:
diff changeset
   387
	TBuf8<TRemConAddress::KMaxAddrSize> buf;
hgs
parents:
diff changeset
   388
	TInt err = aMessage.Read(1, buf);
hgs
parents:
diff changeset
   389
	if ( err != KErrNone )
hgs
parents:
diff changeset
   390
		{
hgs
parents:
diff changeset
   391
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBadDescriptor);
hgs
parents:
diff changeset
   392
		return;
hgs
parents:
diff changeset
   393
		}
hgs
parents:
diff changeset
   394
hgs
parents:
diff changeset
   395
	// Do security check- if this client won't be allowed to use the bearer 
hgs
parents:
diff changeset
   396
	// then fail the request. 
hgs
parents:
diff changeset
   397
	// NB This security check (repeated in debug at ConnectBearer and 
hgs
parents:
diff changeset
   398
	// DisconnectBearer time) is all that stands between a connection-oriented 
hgs
parents:
diff changeset
   399
	// client and the bearer, and is all the caps checking that RemCon does!
hgs
parents:
diff changeset
   400
	err = KErrPermissionDenied;
hgs
parents:
diff changeset
   401
	if ( iBearerManager.CheckPolicy(uid, aMessage) )
hgs
parents:
diff changeset
   402
		{
hgs
parents:
diff changeset
   403
		err = KErrNone;
hgs
parents:
diff changeset
   404
		}
hgs
parents:
diff changeset
   405
		
hgs
parents:
diff changeset
   406
		
hgs
parents:
diff changeset
   407
	// if alls well and we're connection oriented then set up as such
hgs
parents:
diff changeset
   408
	if (KErrNone == err)
hgs
parents:
diff changeset
   409
		{
hgs
parents:
diff changeset
   410
		// The client has passed all our checks- set our data member.
hgs
parents:
diff changeset
   411
		iRemoteAddress.BearerUid() = uid;
hgs
parents:
diff changeset
   412
		iRemoteAddress.Addr() = buf;
hgs
parents:
diff changeset
   413
		// tell the server
hgs
parents:
diff changeset
   414
		iServer.ClientGoConnectionOriented(*this,uid);
hgs
parents:
diff changeset
   415
		}
hgs
parents:
diff changeset
   416
				
hgs
parents:
diff changeset
   417
	CompleteClient(aMessage, err);
hgs
parents:
diff changeset
   418
	}
hgs
parents:
diff changeset
   419
hgs
parents:
diff changeset
   420
void CRemConControllerSession::GoConnectionless(const RMessage2& aMessage)
hgs
parents:
diff changeset
   421
	{
hgs
parents:
diff changeset
   422
	LOG_FUNC;
hgs
parents:
diff changeset
   423
hgs
parents:
diff changeset
   424
	// Check we've had our features set...
hgs
parents:
diff changeset
   425
	if (!ClientAvailable())
hgs
parents:
diff changeset
   426
		{
hgs
parents:
diff changeset
   427
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicClientFeaturesNotSet);
hgs
parents:
diff changeset
   428
		return;
hgs
parents:
diff changeset
   429
		}
hgs
parents:
diff changeset
   430
hgs
parents:
diff changeset
   431
	if ( iRemoteAddress.IsNull() )
hgs
parents:
diff changeset
   432
		{
hgs
parents:
diff changeset
   433
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicNotConnectionOriented);
hgs
parents:
diff changeset
   434
		return;
hgs
parents:
diff changeset
   435
		}
hgs
parents:
diff changeset
   436
hgs
parents:
diff changeset
   437
	if ( iConnectBearerMsg.Handle() || iDisconnectBearerMsg.Handle() || iSendMsg.Handle())
hgs
parents:
diff changeset
   438
		{
hgs
parents:
diff changeset
   439
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBearerControlOutstanding);
hgs
parents:
diff changeset
   440
		return;
hgs
parents:
diff changeset
   441
		}
hgs
parents:
diff changeset
   442
	
hgs
parents:
diff changeset
   443
	if (iSending != ENotSending)
hgs
parents:
diff changeset
   444
		{
hgs
parents:
diff changeset
   445
		DoSendCancel();
hgs
parents:
diff changeset
   446
		}
hgs
parents:
diff changeset
   447
	EmptySendQueue();
hgs
parents:
diff changeset
   448
	
hgs
parents:
diff changeset
   449
	// we will need to tell the server which bearer this used to be connected to
hgs
parents:
diff changeset
   450
	// this enables the server to not inform a bearer that is already connected
hgs
parents:
diff changeset
   451
	// that its been connected
hgs
parents:
diff changeset
   452
	TUid oldUid = iRemoteAddress.BearerUid();
hgs
parents:
diff changeset
   453
	
hgs
parents:
diff changeset
   454
	iRemoteAddress.BearerUid() = KNullUid;	
hgs
parents:
diff changeset
   455
hgs
parents:
diff changeset
   456
	// tell the server
hgs
parents:
diff changeset
   457
	iServer.ClientGoConnectionless(*this, oldUid);
hgs
parents:
diff changeset
   458
hgs
parents:
diff changeset
   459
	CompleteClient(aMessage, KErrNone);
hgs
parents:
diff changeset
   460
	}
hgs
parents:
diff changeset
   461
hgs
parents:
diff changeset
   462
void CRemConControllerSession::ConnectBearer(const RMessage2& aMessage)
hgs
parents:
diff changeset
   463
	{
hgs
parents:
diff changeset
   464
	LOG_FUNC;
hgs
parents:
diff changeset
   465
hgs
parents:
diff changeset
   466
	// Check we've had our features set...
hgs
parents:
diff changeset
   467
	if (!ClientAvailable())
hgs
parents:
diff changeset
   468
		{
hgs
parents:
diff changeset
   469
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicClientFeaturesNotSet);
hgs
parents:
diff changeset
   470
		return;
hgs
parents:
diff changeset
   471
		}
hgs
parents:
diff changeset
   472
hgs
parents:
diff changeset
   473
	if ( iConnectBearerMsg.Handle() || iDisconnectBearerMsg.Handle() )
hgs
parents:
diff changeset
   474
		{
hgs
parents:
diff changeset
   475
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBearerControlOutstanding);
hgs
parents:
diff changeset
   476
		return;
hgs
parents:
diff changeset
   477
		}
hgs
parents:
diff changeset
   478
hgs
parents:
diff changeset
   479
	if ( iRemoteAddress.IsNull() )
hgs
parents:
diff changeset
   480
		{
hgs
parents:
diff changeset
   481
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicNotConnectionOriented);
hgs
parents:
diff changeset
   482
		return;
hgs
parents:
diff changeset
   483
		}
hgs
parents:
diff changeset
   484
hgs
parents:
diff changeset
   485
	// Check the requested bearer exists.
hgs
parents:
diff changeset
   486
	TBool bearerExists = iBearerManager.BearerExists(iRemoteAddress.BearerUid());
hgs
parents:
diff changeset
   487
	// This check was done at GoConnectionOriented time.
hgs
parents:
diff changeset
   488
	ASSERT_DEBUG(bearerExists);
hgs
parents:
diff changeset
   489
	// So was this one.
hgs
parents:
diff changeset
   490
	ASSERT_DEBUG(iBearerManager.CheckPolicy(iRemoteAddress.BearerUid(), aMessage));
hgs
parents:
diff changeset
   491
hgs
parents:
diff changeset
   492
	// Check the state of our given connection at the bearer level. If it is: 
hgs
parents:
diff changeset
   493
	// -) disconnected request the connection to come up,
hgs
parents:
diff changeset
   494
	// -) connecting or disconnecting, add message to the queue of pending 
hgs
parents:
diff changeset
   495
	//		messages, and process it once connecting/disconnecting has been completed
hgs
parents:
diff changeset
   496
	// -) connected, complete the client's message,
hgs
parents:
diff changeset
   497
hgs
parents:
diff changeset
   498
	TConnectionState conState;
hgs
parents:
diff changeset
   499
	conState = iServer.ConnectionState(iRemoteAddress);
hgs
parents:
diff changeset
   500
hgs
parents:
diff changeset
   501
	if ( conState == EDisconnected )
hgs
parents:
diff changeset
   502
		{
hgs
parents:
diff changeset
   503
		// The bearer may indicate connection synchronously, so set this 
hgs
parents:
diff changeset
   504
		// message _before_ we ask them
hgs
parents:
diff changeset
   505
		iConnectBearerMsg = aMessage;
hgs
parents:
diff changeset
   506
		TInt err = iBearerManager.Connect(iRemoteAddress);
hgs
parents:
diff changeset
   507
		if ( err != KErrNone )
hgs
parents:
diff changeset
   508
			{
hgs
parents:
diff changeset
   509
			CompleteClient(iConnectBearerMsg, err);
hgs
parents:
diff changeset
   510
			}
hgs
parents:
diff changeset
   511
		}
hgs
parents:
diff changeset
   512
	else if ( conState == EDisconnecting ||  conState == EConnecting )
hgs
parents:
diff changeset
   513
		{
hgs
parents:
diff changeset
   514
		if ( iPendingMsg.Handle() )
hgs
parents:
diff changeset
   515
			{
hgs
parents:
diff changeset
   516
			PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBearerControlOutstanding);
hgs
parents:
diff changeset
   517
			return;
hgs
parents:
diff changeset
   518
			}
hgs
parents:
diff changeset
   519
		// Store the message, it will get processed later.
hgs
parents:
diff changeset
   520
		iPendingMsg = aMessage;
hgs
parents:
diff changeset
   521
		}
hgs
parents:
diff changeset
   522
	else // EConnected
hgs
parents:
diff changeset
   523
		{
hgs
parents:
diff changeset
   524
		CompleteClient(aMessage, KErrNone);
hgs
parents:
diff changeset
   525
		}
hgs
parents:
diff changeset
   526
		
hgs
parents:
diff changeset
   527
	}
hgs
parents:
diff changeset
   528
hgs
parents:
diff changeset
   529
void CRemConControllerSession::ConnectBearerCancel(const RMessage2& aMessage)
hgs
parents:
diff changeset
   530
	{
hgs
parents:
diff changeset
   531
	LOG_FUNC;
hgs
parents:
diff changeset
   532
hgs
parents:
diff changeset
   533
	// Check we've had our features set...
hgs
parents:
diff changeset
   534
	if (!ClientAvailable())
hgs
parents:
diff changeset
   535
		{
hgs
parents:
diff changeset
   536
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicClientFeaturesNotSet);
hgs
parents:
diff changeset
   537
		return;
hgs
parents:
diff changeset
   538
		}
hgs
parents:
diff changeset
   539
hgs
parents:
diff changeset
   540
	if ( iConnectBearerMsg.Handle() )
hgs
parents:
diff changeset
   541
		{
hgs
parents:
diff changeset
   542
		CompleteClient(iConnectBearerMsg, KErrCancel);
hgs
parents:
diff changeset
   543
		}
hgs
parents:
diff changeset
   544
	else if ( iPendingMsg.Handle() && ( iPendingMsg.Function() == ERemConConnectBearer ))
hgs
parents:
diff changeset
   545
		{
hgs
parents:
diff changeset
   546
		CompleteClient(iPendingMsg, KErrCancel);
hgs
parents:
diff changeset
   547
		}
hgs
parents:
diff changeset
   548
		
hgs
parents:
diff changeset
   549
	CompleteClient(aMessage, KErrNone);
hgs
parents:
diff changeset
   550
	// At no point do we make any change to the processes going on underneath
hgs
parents:
diff changeset
   551
	// us- 'Cancel' APIs are just for cancelling interest in an async
hgs
parents:
diff changeset
   552
	// operation.
hgs
parents:
diff changeset
   553
	}
hgs
parents:
diff changeset
   554
hgs
parents:
diff changeset
   555
void CRemConControllerSession::DisconnectBearer(const RMessage2& aMessage)
hgs
parents:
diff changeset
   556
	{
hgs
parents:
diff changeset
   557
	LOG_FUNC;
hgs
parents:
diff changeset
   558
hgs
parents:
diff changeset
   559
	// Check we've had our features set...
hgs
parents:
diff changeset
   560
	if (!ClientAvailable())
hgs
parents:
diff changeset
   561
		{
hgs
parents:
diff changeset
   562
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicClientFeaturesNotSet);
hgs
parents:
diff changeset
   563
		return;
hgs
parents:
diff changeset
   564
		}
hgs
parents:
diff changeset
   565
hgs
parents:
diff changeset
   566
	if ( iDisconnectBearerMsg.Handle() || iConnectBearerMsg.Handle() || iSendMsg.Handle())
hgs
parents:
diff changeset
   567
		{
hgs
parents:
diff changeset
   568
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBearerControlOutstanding);
hgs
parents:
diff changeset
   569
		return;
hgs
parents:
diff changeset
   570
		}
hgs
parents:
diff changeset
   571
hgs
parents:
diff changeset
   572
	if ( iRemoteAddress.IsNull() )
hgs
parents:
diff changeset
   573
		{
hgs
parents:
diff changeset
   574
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicNotConnectionOriented);
hgs
parents:
diff changeset
   575
		return;
hgs
parents:
diff changeset
   576
		}
hgs
parents:
diff changeset
   577
hgs
parents:
diff changeset
   578
	if (iSending != ENotSending)
hgs
parents:
diff changeset
   579
		{
hgs
parents:
diff changeset
   580
		DoSendCancel();
hgs
parents:
diff changeset
   581
		}
hgs
parents:
diff changeset
   582
	EmptySendQueue();
hgs
parents:
diff changeset
   583
	
hgs
parents:
diff changeset
   584
	// Check the requested bearer exists.
hgs
parents:
diff changeset
   585
	TBool bearerExists = iBearerManager.BearerExists(iRemoteAddress.BearerUid());
hgs
parents:
diff changeset
   586
	// This check was done at GoConnectionOriented time.
hgs
parents:
diff changeset
   587
	ASSERT_DEBUG(bearerExists);
hgs
parents:
diff changeset
   588
	// So was this one.
hgs
parents:
diff changeset
   589
	ASSERT_DEBUG(iBearerManager.CheckPolicy(iRemoteAddress.BearerUid(), aMessage));
hgs
parents:
diff changeset
   590
hgs
parents:
diff changeset
   591
	// Check the state of the given connection. If it is:
hgs
parents:
diff changeset
   592
	// -) connected, request connection to go away,
hgs
parents:
diff changeset
   593
	// -) disconnected, compete the client's message,
hgs
parents:
diff changeset
   594
	// -) connecting or disconnecting, add message to the queue of pending 
hgs
parents:
diff changeset
   595
	//		messages, and process it once connecting/disconnecting has been completed
hgs
parents:
diff changeset
   596
hgs
parents:
diff changeset
   597
	TInt err;
hgs
parents:
diff changeset
   598
	TConnectionState conState;
hgs
parents:
diff changeset
   599
	conState = iServer.ConnectionState(iRemoteAddress);
hgs
parents:
diff changeset
   600
hgs
parents:
diff changeset
   601
	if ( conState == EConnected )
hgs
parents:
diff changeset
   602
		{
hgs
parents:
diff changeset
   603
		// The bearer may indicate disconnection synchronously, so set this 
hgs
parents:
diff changeset
   604
		// message _before_ we ask them
hgs
parents:
diff changeset
   605
		iDisconnectBearerMsg = aMessage;
hgs
parents:
diff changeset
   606
		err = iBearerManager.Disconnect(iRemoteAddress);
hgs
parents:
diff changeset
   607
		if ( err != KErrNone )
hgs
parents:
diff changeset
   608
			{
hgs
parents:
diff changeset
   609
			CompleteClient(iDisconnectBearerMsg, err);
hgs
parents:
diff changeset
   610
			}
hgs
parents:
diff changeset
   611
		}
hgs
parents:
diff changeset
   612
	else if ( conState == EDisconnecting ||  conState == EConnecting )
hgs
parents:
diff changeset
   613
		{
hgs
parents:
diff changeset
   614
		if ( iPendingMsg.Handle() )
hgs
parents:
diff changeset
   615
			{
hgs
parents:
diff changeset
   616
			PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBearerControlOutstanding);
hgs
parents:
diff changeset
   617
			return;
hgs
parents:
diff changeset
   618
			}
hgs
parents:
diff changeset
   619
		// Store the message, it will get processed later.
hgs
parents:
diff changeset
   620
		iPendingMsg = aMessage;
hgs
parents:
diff changeset
   621
		}
hgs
parents:
diff changeset
   622
	else //disconnected
hgs
parents:
diff changeset
   623
		{
hgs
parents:
diff changeset
   624
		CompleteClient(aMessage, KErrNone);	
hgs
parents:
diff changeset
   625
		}
hgs
parents:
diff changeset
   626
	}
hgs
parents:
diff changeset
   627
hgs
parents:
diff changeset
   628
void CRemConControllerSession::DisconnectBearerCancel(const RMessage2& aMessage)
hgs
parents:
diff changeset
   629
	{
hgs
parents:
diff changeset
   630
	LOG_FUNC;
hgs
parents:
diff changeset
   631
hgs
parents:
diff changeset
   632
	// Check we've had our features set...
hgs
parents:
diff changeset
   633
	if (!ClientAvailable())
hgs
parents:
diff changeset
   634
		{
hgs
parents:
diff changeset
   635
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicClientFeaturesNotSet);
hgs
parents:
diff changeset
   636
		return;
hgs
parents:
diff changeset
   637
		}
hgs
parents:
diff changeset
   638
hgs
parents:
diff changeset
   639
	if ( iDisconnectBearerMsg.Handle() )
hgs
parents:
diff changeset
   640
		{
hgs
parents:
diff changeset
   641
		CompleteClient(iDisconnectBearerMsg, KErrCancel);
hgs
parents:
diff changeset
   642
		}
hgs
parents:
diff changeset
   643
	else if ( iPendingMsg.Handle() && (iPendingMsg.Function() == ERemConDisconnectBearer ))
hgs
parents:
diff changeset
   644
		{
hgs
parents:
diff changeset
   645
		CompleteClient(iPendingMsg, KErrCancel);
hgs
parents:
diff changeset
   646
		}
hgs
parents:
diff changeset
   647
		
hgs
parents:
diff changeset
   648
	CompleteClient(aMessage, KErrNone);
hgs
parents:
diff changeset
   649
	}
hgs
parents:
diff changeset
   650
hgs
parents:
diff changeset
   651
/**
hgs
parents:
diff changeset
   652
Sends a notify message to the remote device.
hgs
parents:
diff changeset
   653
hgs
parents:
diff changeset
   654
This function is intended for the RemCon controller client to send a notify
hgs
parents:
diff changeset
   655
command to the remote device.
hgs
parents:
diff changeset
   656
*/
hgs
parents:
diff changeset
   657
void CRemConControllerSession::SendNotify(const RMessage2& aMessage)
hgs
parents:
diff changeset
   658
	{
hgs
parents:
diff changeset
   659
	LOG_FUNC;
hgs
parents:
diff changeset
   660
hgs
parents:
diff changeset
   661
	// Check we're not already sending...
hgs
parents:
diff changeset
   662
	if ( iSendMsg.Handle())
hgs
parents:
diff changeset
   663
		{
hgs
parents:
diff changeset
   664
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicSendAlreadyOutstanding);
hgs
parents:
diff changeset
   665
		return;
hgs
parents:
diff changeset
   666
		}
hgs
parents:
diff changeset
   667
	
hgs
parents:
diff changeset
   668
	iSendMsg = aMessage;
hgs
parents:
diff changeset
   669
	
hgs
parents:
diff changeset
   670
	// Check we've had our features set...
hgs
parents:
diff changeset
   671
	if (!ClientAvailable())
hgs
parents:
diff changeset
   672
		{
hgs
parents:
diff changeset
   673
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicClientFeaturesNotSet);
hgs
parents:
diff changeset
   674
		return;
hgs
parents:
diff changeset
   675
		}
hgs
parents:
diff changeset
   676
hgs
parents:
diff changeset
   677
	// Check we don't have a disconnect outstanding- this makes no sense from 
hgs
parents:
diff changeset
   678
	// a client viewpoint (they should cancel the disconnect first).
hgs
parents:
diff changeset
   679
	// [The client is allowed to have a connect request outstanding- the 
hgs
parents:
diff changeset
   680
	// bearer manager makes sure a bearer-level connect is not posted on the 
hgs
parents:
diff changeset
   681
	// same address twice.]
hgs
parents:
diff changeset
   682
	if ( iDisconnectBearerMsg.Handle() )
hgs
parents:
diff changeset
   683
		{
hgs
parents:
diff changeset
   684
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBearerControlOutstanding);
hgs
parents:
diff changeset
   685
		return;
hgs
parents:
diff changeset
   686
		}
hgs
parents:
diff changeset
   687
hgs
parents:
diff changeset
   688
	TRAPD(err, DoSendNotifyL(aMessage));
hgs
parents:
diff changeset
   689
	if ( err != KErrNone )
hgs
parents:
diff changeset
   690
		{
hgs
parents:
diff changeset
   691
		CompleteClient(aMessage, err);
hgs
parents:
diff changeset
   692
		}
hgs
parents:
diff changeset
   693
	}
hgs
parents:
diff changeset
   694
hgs
parents:
diff changeset
   695
/**
hgs
parents:
diff changeset
   696
@see CRemConControllerSession::SendNotify
hgs
parents:
diff changeset
   697
*/
hgs
parents:
diff changeset
   698
void CRemConControllerSession::DoSendNotifyL(const RMessage2& aMessage)
hgs
parents:
diff changeset
   699
	{
hgs
parents:
diff changeset
   700
	LOG_FUNC;
hgs
parents:
diff changeset
   701
hgs
parents:
diff changeset
   702
	// Get the data the client wants to send.
hgs
parents:
diff changeset
   703
	const TUid interfaceUid = TUid::Uid(aMessage.Int0());
hgs
parents:
diff changeset
   704
	LOG1(_L("\tinterfaceUid = 0x%08x"), interfaceUid);
hgs
parents:
diff changeset
   705
hgs
parents:
diff changeset
   706
	if (aMessage.GetDesLengthL(1) != sizeof(TOperationInformation))
hgs
parents:
diff changeset
   707
		{
hgs
parents:
diff changeset
   708
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBadDescriptor);
hgs
parents:
diff changeset
   709
		return;
hgs
parents:
diff changeset
   710
		}
hgs
parents:
diff changeset
   711
hgs
parents:
diff changeset
   712
	TPckgBuf<TOperationInformation> opInfoPckg;	
hgs
parents:
diff changeset
   713
	TInt err= aMessage.Read(
hgs
parents:
diff changeset
   714
			1, // location of the descriptor in the client's message (as we expect them to have set it up)
hgs
parents:
diff changeset
   715
			opInfoPckg, // descriptor to write to from client memory space
hgs
parents:
diff changeset
   716
			0 // offset into our descriptor to put the client's data
hgs
parents:
diff changeset
   717
			);
hgs
parents:
diff changeset
   718
	
hgs
parents:
diff changeset
   719
	if ( err != KErrNone )
hgs
parents:
diff changeset
   720
		{
hgs
parents:
diff changeset
   721
		LOG1(_L("\taMessage.Read = %d"), err);
hgs
parents:
diff changeset
   722
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBadDescriptor);
hgs
parents:
diff changeset
   723
		return;
hgs
parents:
diff changeset
   724
		}	
hgs
parents:
diff changeset
   725
	
hgs
parents:
diff changeset
   726
	const TUint operationId = opInfoPckg().iOperationId;
hgs
parents:
diff changeset
   727
	LOG1(_L("\toperationId = 0x%02x"), operationId);
hgs
parents:
diff changeset
   728
	
hgs
parents:
diff changeset
   729
	const TRemConMessageSubType messageSubType = opInfoPckg().iMessageSubType;
hgs
parents:
diff changeset
   730
	LOG1(_L("\tmessageSubType = 0x%02x"), messageSubType);
hgs
parents:
diff changeset
   731
	
hgs
parents:
diff changeset
   732
	const TUint dataLength = (TUint)aMessage.GetDesLengthL(2);
hgs
parents:
diff changeset
   733
	LOG1(_L("\tdataLength = %d"), dataLength);
hgs
parents:
diff changeset
   734
	
hgs
parents:
diff changeset
   735
	// If the client wanted to send some operation-associated data, read it 
hgs
parents:
diff changeset
   736
	// from them.
hgs
parents:
diff changeset
   737
	RBuf8 sendDes;
hgs
parents:
diff changeset
   738
	if ( dataLength != 0 )
hgs
parents:
diff changeset
   739
		{
hgs
parents:
diff changeset
   740
		sendDes.CreateL(dataLength);
hgs
parents:
diff changeset
   741
		TInt err = aMessage.Read(
hgs
parents:
diff changeset
   742
			2, // location of the descriptor in the client's message (as we expect them to have set it up)
hgs
parents:
diff changeset
   743
			sendDes, // descriptor to write to from client memory space
hgs
parents:
diff changeset
   744
			0 // offset into our descriptor to put the client's data
hgs
parents:
diff changeset
   745
			);
hgs
parents:
diff changeset
   746
		// NB We don't do LEAVEIFERRORL(aMessage.Read) because a bad client 
hgs
parents:
diff changeset
   747
		// descriptor is a panicking offence for them, not an 'error the 
hgs
parents:
diff changeset
   748
		// request' offence.
hgs
parents:
diff changeset
   749
		if ( err != KErrNone )
hgs
parents:
diff changeset
   750
			{
hgs
parents:
diff changeset
   751
			LOG1(_L("\taMessage.Read = %d"), err);
hgs
parents:
diff changeset
   752
			sendDes.Close();
hgs
parents:
diff changeset
   753
			PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicBadDescriptor);
hgs
parents:
diff changeset
   754
			return;
hgs
parents:
diff changeset
   755
			}
hgs
parents:
diff changeset
   756
		}
hgs
parents:
diff changeset
   757
hgs
parents:
diff changeset
   758
	// Before we ask the server to send, we must set our ClientInfo 
hgs
parents:
diff changeset
   759
	// correctly so the TSP can get information about the client. 
hgs
parents:
diff changeset
   760
	iClientInfo.Message() = aMessage;
hgs
parents:
diff changeset
   761
hgs
parents:
diff changeset
   762
	CRemConMessage* msg = NULL;
hgs
parents:
diff changeset
   763
	
hgs
parents:
diff changeset
   764
	if (messageSubType != ERemConNotifyCommandAwaitingInterim)
hgs
parents:
diff changeset
   765
		{
hgs
parents:
diff changeset
   766
		sendDes.Close();
hgs
parents:
diff changeset
   767
		PANIC_MSG(aMessage, KRemConClientPanicCat, ERemConClientPanicIllegalIpc);
hgs
parents:
diff changeset
   768
		return;
hgs
parents:
diff changeset
   769
		}
hgs
parents:
diff changeset
   770
	
hgs
parents:
diff changeset
   771
	CleanupClosePushL(sendDes);
hgs
parents:
diff changeset
   772
	msg = CRemConMessage::NewL(
hgs
parents:
diff changeset
   773
			iRemoteAddress, // either specified (if we're connection-oriented) or null (we're connectionless- this field will be filled in by the TSP)
hgs
parents:
diff changeset
   774
			ERemConNotifyCommand, 
hgs
parents:
diff changeset
   775
			messageSubType,
hgs
parents:
diff changeset
   776
			interfaceUid,
hgs
parents:
diff changeset
   777
			operationId,
hgs
parents:
diff changeset
   778
			sendDes, // msg takes ownership
hgs
parents:
diff changeset
   779
			Id(), // session id for when the response comes back
hgs
parents:
diff changeset
   780
			0, // we let the bearer manager invent a new transaction id when the message gets to it
hgs
parents:
diff changeset
   781
			ETrue);	
hgs
parents:
diff changeset
   782
	CLEANUPSTACK_POP1(&sendDes); // now owned by msg
hgs
parents:
diff changeset
   783
	
hgs
parents:
diff changeset
   784
	LOG(_L("\tCONTROLLER send"));
hgs
parents:
diff changeset
   785
	ASSERT_DEBUG(iSendQueue);
hgs
parents:
diff changeset
   786
	if (iSending != ENotSending || !iSendQueue->IsEmpty())
hgs
parents:
diff changeset
   787
		{
hgs
parents:
diff changeset
   788
		iSendQueue->Append(*msg);
hgs
parents:
diff changeset
   789
		}
hgs
parents:
diff changeset
   790
	else
hgs
parents:
diff changeset
   791
		{
hgs
parents:
diff changeset
   792
		SendToServer(*msg);
hgs
parents:
diff changeset
   793
		}
hgs
parents:
diff changeset
   794
	}
hgs
parents:
diff changeset
   795
hgs
parents:
diff changeset
   796
void CRemConControllerSession::SendToServer(CRemConMessage& aMsg)
hgs
parents:
diff changeset
   797
	{
hgs
parents:
diff changeset
   798
	LOG_FUNC;
hgs
parents:
diff changeset
   799
	
hgs
parents:
diff changeset
   800
	// Set our completion members.
hgs
parents:
diff changeset
   801
	NumRemotes() = 0;
hgs
parents:
diff changeset
   802
	NumRemotesToTry() = 0;
hgs
parents:
diff changeset
   803
	SendError() = KErrNone;
hgs
parents:
diff changeset
   804
hgs
parents:
diff changeset
   805
	
hgs
parents:
diff changeset
   806
	iSending = (aMsg.IsReliableSend()) ? ESendingReliable: ESendingUnreliable;
hgs
parents:
diff changeset
   807
	
hgs
parents:
diff changeset
   808
	iServer.SendCommand(aMsg);
hgs
parents:
diff changeset
   809
	}
hgs
parents:
diff changeset
   810
hgs
parents:
diff changeset
   811
void CRemConControllerSession::EmptySendQueue()
hgs
parents:
diff changeset
   812
	{
hgs
parents:
diff changeset
   813
	LOG_FUNC;
hgs
parents:
diff changeset
   814
hgs
parents:
diff changeset
   815
	ASSERT_DEBUG(!iSendMsg.Handle())
hgs
parents:
diff changeset
   816
	ASSERT_DEBUG(iSendNextCallBack);
hgs
parents:
diff changeset
   817
	iSendNextCallBack->Cancel();
hgs
parents:
diff changeset
   818
	CRemConMessage* msg;
hgs
parents:
diff changeset
   819
	ASSERT_DEBUG(iSendQueue);
hgs
parents:
diff changeset
   820
	TSglQueIter<CRemConMessage>& iter = iSendQueue->SetToFirst();
hgs
parents:
diff changeset
   821
	while ((msg = iter++) != NULL)
hgs
parents:
diff changeset
   822
		{
hgs
parents:
diff changeset
   823
		iSendQueue->RemoveAndDestroy(*msg);
hgs
parents:
diff changeset
   824
		}
hgs
parents:
diff changeset
   825
	}
hgs
parents:
diff changeset
   826
hgs
parents:
diff changeset
   827
void CRemConControllerSession::DoSendCancel()
hgs
parents:
diff changeset
   828
	{
hgs
parents:
diff changeset
   829
	LOG_FUNC;
hgs
parents:
diff changeset
   830
	// We must tell the server, and pull the CRemConMessage from the 
hgs
parents:
diff changeset
   831
	// 'outgoing pending TSP' queue if it's on it. If the TSP is currently 
hgs
parents:
diff changeset
   832
	// processing the CRemConMessage, we must tell it to stop before we 
hgs
parents:
diff changeset
   833
	// can complete the RMessage2 iSendMsg- the TSP might still be 
hgs
parents:
diff changeset
   834
	// dereferencing bits of it. (The TSP is given iSendMsg so it can 
hgs
parents:
diff changeset
   835
	// access the client's secure ID and do a capability check.)
hgs
parents:
diff changeset
   836
	// NB This only matters for commands- responses don't go through the 
hgs
parents:
diff changeset
   837
	// TSP.
hgs
parents:
diff changeset
   838
	// Not also that this processing *stops* this 
hgs
parents:
diff changeset
   839
	// CRemConSession::SendCancel method from being the very simple 'I'm 
hgs
parents:
diff changeset
   840
	// no longer interested in the completion of the asynchronous request' 
hgs
parents:
diff changeset
   841
	// type of API it (and all cancels) should be. It actually does work 
hgs
parents:
diff changeset
   842
	// as well. As long as this work is implemented _synchronously_, we 
hgs
parents:
diff changeset
   843
	// should be OK.
hgs
parents:
diff changeset
   844
	iServer.SendCancel(*this);
hgs
parents:
diff changeset
   845
hgs
parents:
diff changeset
   846
	NumRemotesToTry() = 0;
hgs
parents:
diff changeset
   847
	iSendError = KErrCancel;
hgs
parents:
diff changeset
   848
	CompleteSend();
hgs
parents:
diff changeset
   849
	}
hgs
parents:
diff changeset
   850
hgs
parents:
diff changeset
   851
void CRemConControllerSession::CompleteMessage(const CRemConMessage& aMessage)
hgs
parents:
diff changeset
   852
	{
hgs
parents:
diff changeset
   853
	LOG_FUNC;
hgs
parents:
diff changeset
   854
hgs
parents:
diff changeset
   855
	switch (aMessage.MsgType())
hgs
parents:
diff changeset
   856
		{
hgs
parents:
diff changeset
   857
	case ERemConCommand:
hgs
parents:
diff changeset
   858
	case ERemConResponse:
hgs
parents:
diff changeset
   859
	case ERemConReject:
hgs
parents:
diff changeset
   860
		{
hgs
parents:
diff changeset
   861
		CompleteSend();
hgs
parents:
diff changeset
   862
		break;
hgs
parents:
diff changeset
   863
		}
hgs
parents:
diff changeset
   864
	case ERemConNotifyCommand:
hgs
parents:
diff changeset
   865
		{
hgs
parents:
diff changeset
   866
		CompleteSendNotify();
hgs
parents:
diff changeset
   867
		break;
hgs
parents:
diff changeset
   868
		}
hgs
parents:
diff changeset
   869
	default:
hgs
parents:
diff changeset
   870
		ASSERT_DEBUG(EFalse);
hgs
parents:
diff changeset
   871
		break;
hgs
parents:
diff changeset
   872
		}
hgs
parents:
diff changeset
   873
hgs
parents:
diff changeset
   874
	}
hgs
parents:
diff changeset
   875
hgs
parents:
diff changeset
   876
void CRemConControllerSession::DoReceive()
hgs
parents:
diff changeset
   877
	{
hgs
parents:
diff changeset
   878
	// Request messages from the server for this controller session.
hgs
parents:
diff changeset
   879
	// If there's anything waiting to be given to us, ReceiveRequest will call 
hgs
parents:
diff changeset
   880
	// back to us with it.
hgs
parents:
diff changeset
   881
	iServer.ReceiveRequest(*this);	
hgs
parents:
diff changeset
   882
	}
hgs
parents:
diff changeset
   883
hgs
parents:
diff changeset
   884
void CRemConControllerSession::MrcmsoMessageSendResult(const CRemConMessage& aMessage, TInt aError)
hgs
parents:
diff changeset
   885
	{
hgs
parents:
diff changeset
   886
	LOG_FUNC;
hgs
parents:
diff changeset
   887
hgs
parents:
diff changeset
   888
	// We should not already be sending a message to n remotes
hgs
parents:
diff changeset
   889
	ASSERT_DEBUG(NumRemotesToTry() == 0);
hgs
parents:
diff changeset
   890
hgs
parents:
diff changeset
   891
	SendError() = aError;
hgs
parents:
diff changeset
   892
	CompleteMessage(aMessage);
hgs
parents:
diff changeset
   893
	}
hgs
parents:
diff changeset
   894
hgs
parents:
diff changeset
   895
void CRemConControllerSession::MrcmsoMessageSendOneOrMoreAttempt(const CRemConMessage& /*aMessage*/, TUint aNumRemotes)
hgs
parents:
diff changeset
   896
	{
hgs
parents:
diff changeset
   897
	LOG_FUNC;
hgs
parents:
diff changeset
   898
hgs
parents:
diff changeset
   899
	// We should not already be sending a message
hgs
parents:
diff changeset
   900
	ASSERT_DEBUG(NumRemotesToTry() == 0);
hgs
parents:
diff changeset
   901
hgs
parents:
diff changeset
   902
	NumRemotes() = 0;
hgs
parents:
diff changeset
   903
	NumRemotesToTry() = aNumRemotes;
hgs
parents:
diff changeset
   904
	SendError() = KErrNone;
hgs
parents:
diff changeset
   905
	}
hgs
parents:
diff changeset
   906
hgs
parents:
diff changeset
   907
void CRemConControllerSession::MrcmsoMessageSendOneOrMoreIncremental(const CRemConMessage& /*aMessage*/, TUint /*aNumRemotes*/)
hgs
parents:
diff changeset
   908
	{
hgs
parents:
diff changeset
   909
	LOG_FUNC;
hgs
parents:
diff changeset
   910
hgs
parents:
diff changeset
   911
	// This method should never be called, as it is not required to support controller sessions.
hgs
parents:
diff changeset
   912
	ASSERT_DEBUG(EFalse);
hgs
parents:
diff changeset
   913
	}
hgs
parents:
diff changeset
   914
hgs
parents:
diff changeset
   915
void CRemConControllerSession::MrcmsoMessageSendOneOrMoreAttemptFailed(const CRemConMessage& aMessage, TInt aError)
hgs
parents:
diff changeset
   916
	{
hgs
parents:
diff changeset
   917
	LOG_FUNC;
hgs
parents:
diff changeset
   918
hgs
parents:
diff changeset
   919
	// We should not already be sending a message
hgs
parents:
diff changeset
   920
	ASSERT_DEBUG(NumRemotesToTry() == 0);
hgs
parents:
diff changeset
   921
hgs
parents:
diff changeset
   922
	NumRemotes() = 0;
hgs
parents:
diff changeset
   923
	SendError() = aError;
hgs
parents:
diff changeset
   924
	CompleteMessage(aMessage);
hgs
parents:
diff changeset
   925
	}
hgs
parents:
diff changeset
   926
hgs
parents:
diff changeset
   927
void CRemConControllerSession::MrcmsoMessageSendOneOrMoreResult(const CRemConMessage& aMessage, TInt aError)
hgs
parents:
diff changeset
   928
	{
hgs
parents:
diff changeset
   929
	LOG_FUNC;
hgs
parents:
diff changeset
   930
hgs
parents:
diff changeset
   931
	// Ignore notification if client has been completed
hgs
parents:
diff changeset
   932
	if (NumRemotesToTry() > 0)
hgs
parents:
diff changeset
   933
		{
hgs
parents:
diff changeset
   934
		// Only set error if different from KErrNone
hgs
parents:
diff changeset
   935
		if (aError == KErrNone)
hgs
parents:
diff changeset
   936
			{
hgs
parents:
diff changeset
   937
			++NumRemotes();
hgs
parents:
diff changeset
   938
			}
hgs
parents:
diff changeset
   939
		else
hgs
parents:
diff changeset
   940
			{
hgs
parents:
diff changeset
   941
			SendError() = aError;
hgs
parents:
diff changeset
   942
			}
hgs
parents:
diff changeset
   943
hgs
parents:
diff changeset
   944
		--NumRemotesToTry();
hgs
parents:
diff changeset
   945
		if (NumRemotesToTry() == 0)
hgs
parents:
diff changeset
   946
			{
hgs
parents:
diff changeset
   947
			CompleteMessage(aMessage);
hgs
parents:
diff changeset
   948
			}
hgs
parents:
diff changeset
   949
		}
hgs
parents:
diff changeset
   950
	}
hgs
parents:
diff changeset
   951
hgs
parents:
diff changeset
   952
void CRemConControllerSession::MrcmsoMessageSendOneOrMoreAbandoned(const CRemConMessage& /*aMessage*/)
hgs
parents:
diff changeset
   953
	{
hgs
parents:
diff changeset
   954
	LOG_FUNC;
hgs
parents:
diff changeset
   955
hgs
parents:
diff changeset
   956
	// This method should never be called, as it is not required to support controller sessions.
hgs
parents:
diff changeset
   957
	ASSERT_DEBUG(EFalse);
hgs
parents:
diff changeset
   958
	}