lbs/lbstestchannel/src/tlbschannel.cpp
branchSymbian2
changeset 1 8758140453c0
child 6 c108117318cb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lbs/lbstestchannel/src/tlbschannel.cpp	Thu Jan 21 12:53:44 2010 +0000
@@ -0,0 +1,247 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// @file T_Lbschannel.cpp
+// This is the Cpp file which contains the channel for communication between
+// the test harness and the test AGps module.
+// 
+//
+
+// User includes
+#include "tlbschannel.h"
+
+const TInt KLbsChannelIdMax = RT_LbsChannel::EChannelTAGPS2TH;
+//const TInt KCategoryKeyIndex	 = 0;
+const TInt KReadPropKeyIndex 	 = 1;
+const TInt KReadPropAckKeyIndex  = 2;
+const TInt KWritePropKeyIndex 	 = 3;
+const TInt KWritePropAckKeyIndex = 4;
+
+/** The array contains description (property size, keys and Ids) of all the channels supported by 
+    the RT_LbsChannel interface */
+const TUint KPropTable[KLbsChannelIdMax+1][5]=
+	{
+	{0, KTH2TAGPSMessageKey, KTH2TAGPSMessageReadAckKey, KTAGPS2THMessageKey, KTAGPS2THMessageReadAckKey}, 
+	{0, KTAGPS2THMessageKey, KTAGPS2THMessageReadAckKey, KTH2TAGPSMessageKey, KTH2TAGPSMessageReadAckKey}, 
+	};
+
+///////////////////////////////////////////////////////////////////////////////
+// RT_LbsChannel
+///////////////////////////////////////////////////////////////////////////////
+
+EXPORT_C void RT_LbsChannel::InitializeL(TT_LbsChannelId aChannelId)
+	{
+	const TSecurityPolicy KReadPolicy(ECapability_None);
+	const TSecurityPolicy KWritePolicy(ECapabilityWriteDeviceData);
+	
+	TInt err = RProperty::Define(KUidSystemCategory,
+								 KPropTable[aChannelId][KWritePropKeyIndex],
+								 RProperty::ELargeByteArray, 
+								 KReadPolicy, KWritePolicy, 
+								 sizeof(TT_LbsMsgBase));
+	if (err != KErrNone && err != KErrAlreadyExists)
+		{
+		User::Leave(err);
+		}
+						 
+	err = RProperty::Define(KUidSystemCategory,
+							KPropTable[aChannelId][KWritePropAckKeyIndex],
+							RProperty::EInt,
+							KReadPolicy, KWritePolicy);
+	if (err != KErrNone && err != KErrAlreadyExists)
+		{
+		User::Leave(err);
+		}
+										 
+	User::LeaveIfError(RProperty::Set(KUidSystemCategory, KPropTable[aChannelId][KWritePropAckKeyIndex], 0));
+	}
+
+
+EXPORT_C void RT_LbsChannel::ShutDownL(TT_LbsChannelId aChannelId)
+	{
+	User::LeaveIfError(RProperty::Delete(KPropTable[aChannelId][KWritePropKeyIndex]));
+	User::LeaveIfError(RProperty::Delete(KPropTable[aChannelId][KWritePropAckKeyIndex]));
+	}
+
+
+EXPORT_C RT_LbsChannel::RT_LbsChannel()
+	{
+	}
+	
+
+/** 
+
+The channel must first be initialised before this is called, otherwise the
+resources needed by the channel will not have been allocated.
+
+@param aObserver Reference to the observer class used to notify of new messages. 
+@param aChannelId Uid of the RProperty category used for this channel.
+
+@leave
+*/
+EXPORT_C void RT_LbsChannel::OpenL(TT_LbsChannelId aChannelId, MT_LbsChannelObserver& aObserver)
+	{	
+	__ASSERT_DEBUG(iSendProperty.Handle()==NULL, User::Invariant());
+	__ASSERT_DEBUG(iSendMsgReadProperty.Handle()==NULL, User::Invariant());
+	
+	User::LeaveIfError(iSendProperty.Attach(KUidSystemCategory, KPropTable[aChannelId][KWritePropKeyIndex]));
+	User::LeaveIfError(iSendMsgReadProperty.Attach(KUidSystemCategory, KPropTable[aChannelId][KWritePropAckKeyIndex]));
+	
+	iMonitor = CT_ChannelMonitor::NewL(aObserver, aChannelId, KUidSystemCategory, 
+										KPropTable[aChannelId][KReadPropKeyIndex], 
+										KPropTable[aChannelId][KReadPropAckKeyIndex]);
+	}
+
+/** Close the connection.
+
+This function closes the connection and frees any resources 
+created in RTbsChannel::OpenL().
+*/	
+EXPORT_C void RT_LbsChannel::Close()
+	{
+	CancelSendMessageNotification();
+	
+	delete iMonitor;
+	iSendProperty.Close();
+	iSendMsgReadProperty.Close();
+	}
+
+/** Send a message through the channel.
+    
+This is an asynchronous function that only completes when the message 
+has been read. 
+
+If another call is made to this function before a previous one has 
+completed then aStatus will be completed straight away, with the 
+completion code KErrInUse.
+    
+@param aMessage The message to be sent.
+@param aStatus Request status that is completed when the message has
+			   been read. If there is an error sending the message
+			   it will be stored in aStatus.Int().
+*/
+EXPORT_C void RT_LbsChannel::SendMessage(const TT_LbsMsgBase& aMessage, 
+												 TRequestStatus& aStatus)
+	{
+	// Must check that the previous message was read
+	TInt sendAck;
+	iSendMsgReadProperty.Get(sendAck);
+	if (sendAck == 1)
+		{
+		// Pending message has not been read yet; flag an error
+		TRequestStatus* statPtr = &aStatus;
+		User::RequestComplete(statPtr, KErrInUse);
+		}
+	else
+		{
+		// Publish the new message
+		iSendMsgReadProperty.Set(1);
+		iSendMsgReadProperty.Subscribe(aStatus);
+		TPckgC<TT_LbsMsgBase> pckg(aMessage);
+		iSendProperty.Set(pckg);
+		}	
+	}
+			
+/** Cancel the current request status for SendMessage().
+*/
+EXPORT_C void RT_LbsChannel::CancelSendMessageNotification()
+	{
+	iSendMsgReadProperty.Cancel();
+	}	
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CT_ChannelMonitor - used to listen for incoming messages 
+///////////////////////////////////////////////////////////////////////////////
+CT_ChannelMonitor* CT_ChannelMonitor::NewL(MT_LbsChannelObserver& aObserver, RT_LbsChannel::TT_LbsChannelId aChannelId, TUid aPropId, TUint aPropKey, TUint aAckPropKey)
+	{
+	CT_ChannelMonitor* self = new (ELeave) CT_ChannelMonitor(aObserver, aChannelId);
+	CleanupStack::PushL(self);
+	self->ConstructL(aPropId, aPropKey, aAckPropKey);
+	CleanupStack::Pop();
+	return self;
+	}
+
+CT_ChannelMonitor::CT_ChannelMonitor(MT_LbsChannelObserver& aObserver, RT_LbsChannel::TT_LbsChannelId aChannelId) :
+	CActive(EPriorityStandard),
+	iObserver(aObserver),
+	iChannelId(aChannelId)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CT_ChannelMonitor::~CT_ChannelMonitor()
+	{
+	Cancel();
+	iReceiveProperty.Close();
+	iReceiveMsgReadProperty.Close();	
+	}
+
+void CT_ChannelMonitor::ConstructL(TUid aPropId, TUint aPropKey, TUint aAckPropKey)
+	{
+	__ASSERT_DEBUG(iReceiveProperty.Handle()==NULL, User::Invariant());		//Handle open.
+	__ASSERT_DEBUG(iReceiveMsgReadProperty.Handle()==NULL, User::Invariant());		//Handle open.
+	
+	User::LeaveIfError(iReceiveProperty.Attach(aPropId, aPropKey));
+	User::LeaveIfError(iReceiveMsgReadProperty.Attach(aPropId, aAckPropKey));
+	
+	NotifyChannelMessage();
+	// flag we are ready for receiving messages
+	iReceiveMsgReadProperty.Set(0);
+	}
+	
+void CT_ChannelMonitor::NotifyChannelMessage()
+	{
+	iReceiveProperty.Subscribe(iStatus);
+	SetActive();	
+	}
+
+void CT_ChannelMonitor::RunL()
+	{
+	TInt result = iStatus.Int();
+	switch (result)
+		{
+		case KErrNone:
+			{
+			// Read property
+			TT_LbsMsgBase msg;
+			TPckg<TT_LbsMsgBase> pckg(msg);
+			iReceiveProperty.Get(pckg);
+			
+			// resubscribe for further messages
+			NotifyChannelMessage();
+			
+			// Notify observer
+			iObserver.ProcessChannelMessage(iChannelId, msg);
+
+			// flag message as read
+			iReceiveMsgReadProperty.Set(0);
+			break;	
+			}
+		default:
+			{
+			User::Leave(result);
+			break;
+			}
+		}
+	}
+	
+void CT_ChannelMonitor::DoCancel()
+	{
+	iReceiveProperty.Cancel();
+	}
+	
+TInt CT_ChannelMonitor::RunError(TInt /*aError*/)
+	{
+	return KErrNone;
+	}