telephonyprotocols/pdplayer/src/psdavailabilitylistener.cpp
changeset 0 3553901f7fa8
child 9 962e6306d9d2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyprotocols/pdplayer/src/psdavailabilitylistener.cpp	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,244 @@
+// 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 "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// gprsavailabilitylistener.cpp
+// 
+//
+
+#include <etelmm.h>
+#include <etelpckt.h>
+#include <pcktcs.h>
+#include <comms-infras/es_availability.h>
+#include <comms-infras/ss_mcprnodemessages.h>
+#include "psdavailabilitylistener.h"
+#include <elements/nm_messages_base.h>
+#include <comms-infras/ss_nodemessages_availability.h>
+
+using namespace Messages;
+using namespace ESock;
+
+ void GetPhoneInfoL(RTelServer& aTelServer, const TDesC& aLoadedTsyName, RTelServer::TPhoneInfo& aInfo)
+	{
+	TInt count;
+	User::LeaveIfError(aTelServer.EnumeratePhones(count));
+	if (count<=0)
+		{
+		User::Leave(KErrNotFound);
+		}
+
+	TBool found = EFalse;
+	for (TInt i=0; i < count; i++)
+		{
+		TBuf<KCommsDbSvrMaxFieldLength> currentTsyName;
+		User::LeaveIfError(aTelServer.GetTsyName(i,currentTsyName));
+
+		TInt r=currentTsyName.Locate('.');
+		if (r!=KErrNotFound)
+			{
+			currentTsyName.SetLength(r);
+			}
+		if (currentTsyName.CompareF(aLoadedTsyName)==KErrNone)
+			{
+			User::LeaveIfError(aTelServer.GetPhoneInfo(i,aInfo));
+			found = ETrue;
+			break;
+			}
+		}
+
+	if (!found)
+		{
+		User::Leave(KErrNotFound);
+		}
+	}
+
+CPsdAvailabilityListener* CPsdAvailabilityListener::NewL(const TNodeCtxId& aAvailabilityActivity, const CTSYProvision& aTsyProvision, TUint aApId, TBool aUnavailableDueToContention)
+	{
+	CPsdAvailabilityListener* self = new (ELeave) CPsdAvailabilityListener(aAvailabilityActivity, aTsyProvision, aApId, aUnavailableDueToContention);
+	CleanupStack::PushL(self);
+	self->StartL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+// CActive
+void CPsdAvailabilityListener::RunL()
+	{
+	User::LeaveIfError(iStatus.Int());
+
+	switch (iState)
+		{
+		case EInitialising:
+			//Open packet service
+			User::LeaveIfError(iPacketService.Open(iPhone));
+
+#ifdef _DEBUG
+			// Current version of SIM TSY does not support RPacketService::EAttachWhenPossible
+			if (iTsyProvision->iTsyName == _L("SIM"))
+				iPacketService.SetAttachMode(iStatus, RPacketService::EAttachWhenNeeded);
+			else
+#endif
+			//Put phone is attachwhenpossible mode.
+			//In this mode, the phone will try to attach to the gprs network whenever it can.
+			iPacketService.SetAttachMode(iStatus, RPacketService::EAttachWhenPossible);
+			iState = EChecking;
+			SetActive();
+			break;
+		case EChecking:
+			User::LeaveIfError(iPacketService.GetStatus(iPsdStatus)); // get initial status
+			//Fall through to EAttached / EUnAttached
+		case EAttached:
+		case EUnAttached:
+			if (iPsdStatus == RPacketService::EStatusAttached
+				|| iPsdStatus == RPacketService::EStatusActive)
+				{
+				if (iState!=EAttached) //Could be EUnAttached or EChecking
+					{
+					if (!iUnavailableDueToContention)
+						{
+						TAvailabilityStatus availabilityStatus(TAvailabilityStatus::EMaxAvailabilityScore);
+						RClientInterface::OpenPostMessageClose(Id(), iAvailabilityActivity,
+							TCFAvailabilityControlClient::TAvailabilityNotification(availabilityStatus).CRef());
+						}
+					iState = EAttached;
+					}
+				}
+			else
+				{
+				if (iState!=EUnAttached) //Could be EAttached or EChecking
+					{
+					// Do not report if we have the contention, coz we have already done it
+					if (!iUnavailableDueToContention)
+						{
+						TAvailabilityStatus availabilityStatus(TAvailabilityStatus::EMinAvailabilityScore);
+						RClientInterface::OpenPostMessageClose(Id(), iAvailabilityActivity,
+							TCFAvailabilityControlClient::TAvailabilityNotification(availabilityStatus).CRef());
+						}
+					iState = EUnAttached;
+					}
+				}
+			iPacketService.NotifyStatusChange(iStatus, iPsdStatus);
+			SetActive();
+			break;
+
+		default:
+			ASSERT(EFalse);
+		}
+	}
+
+TInt CPsdAvailabilityListener::RunError(TInt aError)
+	{
+	RClientInterface::OpenPostMessageClose(Id(), iAvailabilityActivity,
+		TEBase::TError(TCFAvailabilityProvider::TAvailabilityNotificationRegistration::Id(), aError).CRef());
+
+	return KErrNone;
+	}
+
+void CPsdAvailabilityListener::DoCancel()
+	{
+	switch (iState)
+		{
+		case EInitialising:
+			iPhone.InitialiseCancel();
+			break;
+		case EChecking:
+			iPacketService.CancelAsyncRequest(EPacketSetAttachMode);
+			//Fall through to EAttached / EUnAttached
+		case EAttached:
+		case EUnAttached:
+			iPacketService.CancelAsyncRequest(EPacketNotifyStatusChange);
+			break;
+		default:
+			ASSERT(EFalse);
+		}
+	}
+
+CPsdAvailabilityListener::~CPsdAvailabilityListener()
+	{
+	Cancel();
+	iPacketService.Close();
+	iPhone.Close();
+	iTelServer.Close();
+	}
+
+CPsdAvailabilityListener::CPsdAvailabilityListener(const TNodeCtxId& aAvailabilityActivity, const CTSYProvision& aTsyProvision, TUint aApId, TBool aUnavailableDueToContention)
+:	CActive(EPriorityNormal),
+	iAvailabilityActivity(aAvailabilityActivity),
+	iTsyProvision(&aTsyProvision),
+	iApId(aApId),
+	iState(EInitialising),
+	iUnavailableDueToContention(aUnavailableDueToContention)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+//We could use asynch variants here as CPsdAvailabilityListener::StartL can currently block for upto a minute..
+void CPsdAvailabilityListener::StartL()
+	{
+	User::LeaveIfError(iTelServer.Connect());
+	User::LeaveIfError(iTelServer.LoadPhoneModule(iTsyProvision->iTsyName));
+	User::LeaveIfError(iTelServer.SetExtendedErrorGranularity(RTelServer::EErrorExtended));
+
+	//Open telephony server
+	RTelServer::TPhoneInfo phoneInfo;
+	GetPhoneInfoL(iTelServer, iTsyProvision->iTsyName, phoneInfo);
+
+	//Open phone
+	User::LeaveIfError(iPhone.Open(iTelServer, phoneInfo.iName));
+
+	RPhone::TStatus phoneStatus;
+	iPhone.GetStatus(phoneStatus);
+
+	if(phoneStatus.iMode==RPhone::EModeUnknown)
+		{
+		iPhone.Initialise(iStatus);
+		}
+	else
+		{
+		TRequestStatus* status = &iStatus;
+		User::RequestComplete(status, KErrNone);
+		}
+	SetActive();
+	}
+
+void CPsdAvailabilityListener::ReceivedL(const TRuntimeCtxId& /*aSender*/, const TNodeId& /*aRecipient*/, TSignatureBase& aMessage)
+	{
+	(void)aMessage;
+	ASSERT(TEBase::ERealmId == aMessage.MessageId().Realm());
+    ASSERT(TEBase::TCancel::EId == aMessage.MessageId().MessageId());
+	delete this;
+	}
+
+void CPsdAvailabilityListener::ReportContentionAvailabilityStatusIfRequired(const TAvailabilityStatus& aAvailabilityStatus)
+	{
+	if (aAvailabilityStatus.Score() == TAvailabilityStatus::EMinAvailabilityScore && !iUnavailableDueToContention)
+		{
+		if (iState == EAttached)
+			{
+			RClientInterface::OpenPostMessageClose(Id(), iAvailabilityActivity,
+				TCFAvailabilityControlClient::TAvailabilityNotification(aAvailabilityStatus).CRef());
+			}
+		iUnavailableDueToContention = ETrue;
+		}
+	else if (aAvailabilityStatus.Score() > TAvailabilityStatus::EMinAvailabilityScore && iUnavailableDueToContention)
+		{
+		if (iState == EAttached)
+			{
+			RClientInterface::OpenPostMessageClose(Id(), iAvailabilityActivity,
+				TCFAvailabilityControlClient::TAvailabilityNotification(aAvailabilityStatus).CRef());
+			}
+		// if iState is not EAttached just reset iUnavailableDueToContention flag, 
+		// the availability will be reported in RunL when network will become available
+		iUnavailableDueToContention = EFalse;
+		}
+	}
+