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