--- /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;
+ }