--- a/telephonyserverplugins/multimodetsy/hayes/CALL.CPP Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/multimodetsy/hayes/CALL.CPP Thu May 06 15:10:38 2010 +0100
@@ -1,2050 +1,2050 @@
-// Copyright (c) 1997-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:
-//
-
-#include <commsdattypesv1_1.h>
-#include "CALL.H" // Header file for this source file
-#include "NOTIFY.H"
-#include "ATDIAL.H"
-#include "ATANSWER.H"
-#include "ATCONNCT.H"
-#include "ATHANGUP.H"
-#include "ATO.H"
-#include "ATNOCARR.H"
-#include "LINE.H"
-#include "ATINIT.H"
-#include "mSLOGGER.H" // for LOGTEXT untilities
-#include "ATIO.H" // For CATIO class
-#include "PHONE.H"
-#include <et_clsvr.h>
-#include "ATBASE.H"
-#include "Matstd.h" // For AT command string constants
-#include "set_cbst.h" // for CATSetCBST class
-#include "et_struct.h"
-
-
-//
-// CAcquireEntry class
-//
-CAcquireEntry* CAcquireEntry::NewL(const TTsyReqHandle aTsyReqHandle)
-//
-// Create new request entry
-//
- {
- return new(ELeave) CAcquireEntry(aTsyReqHandle);
- }
-
-CAcquireEntry::CAcquireEntry(const TTsyReqHandle aTsyReqHandle)
-//
-// Constructor
-//
- {
- iTsyReqHandle=aTsyReqHandle;
- }
-
-CAcquireEntry::~CAcquireEntry()
-//
-// Destructor
-//
- {}
-
-void CAcquireEntry::Deque()
-//
-// Deque List
-//
- {
- iLink.Deque();
- iLink.iPrev=iLink.iNext=NULL;
- }
-
-CAcquireOwnerList::CAcquireOwnerList()
- {}
-
-CAcquireOwnerList::~CAcquireOwnerList()
- {}
-
-CAcquireOwnerList* CAcquireOwnerList::NewL()
-//
-// Static function to create new acquire owner list
-//
- {
- CAcquireOwnerList* self=new(ELeave) CAcquireOwnerList();
- CleanupStack::PushL(self);
- self->ConstructL();
- CleanupStack::Pop(self);
- return self;
- }
-
-void CAcquireOwnerList::ConstructL()
- {
- iAcquireList.SetOffset(_FOFF(CAcquireEntry,iLink));
- }
-
-CAcquireEntry* CAcquireOwnerList::FindByTsyReqHandle(const TTsyReqHandle aTsyReqHandle)
-//
-// Searches for client interested in taking ownership of call, by its TsyReqHandle
-//
- {
- CAcquireEntry* entry;
- TDblQueIter<CAcquireEntry> iter(iAcquireList);
- while(entry = iter++, entry!=NULL)
- {
- if(entry->iTsyReqHandle==aTsyReqHandle)
- return entry;
- }
- return NULL;
- }
-
-void CAcquireOwnerList::Remove(CAcquireEntry* aEntry)
- {
- aEntry->Deque();
- delete aEntry;
- }
-
-//
-// CHeartbeatRunner - periodic class to count seconds from beginning of call
-//
-CHeartbeatRunner* CHeartbeatRunner::NewL(CCallHayes* aCallHayes,CNotifications* aNotificationStore)
- {
- CHeartbeatRunner* self=new (ELeave) CHeartbeatRunner(aCallHayes,aNotificationStore);
- CleanupStack::PushL(self);
- self->ConstructL();
- CleanupStack::Pop();
- return self;
- }
-
-CHeartbeatRunner::CHeartbeatRunner(CCallHayes* aCallHayes,CNotifications* aNotificationStore)
- :iCallHayes(aCallHayes), iNotificationStore(aNotificationStore)
- {}
-
-void CHeartbeatRunner::ConstructL()
- {
- iHeartbeat=CHeartbeat::NewL(0); // neutral priority
- }
-
-CHeartbeatRunner::~CHeartbeatRunner()
- {
- if (iHeartbeat != NULL)
- iHeartbeat->Cancel();
- delete iHeartbeat;
- }
-
-void CHeartbeatRunner::Start()
- {
- iStartTime.UniversalTime();
- iHeartbeat->Start(ETwelveOClock,this);
- }
-
-void CHeartbeatRunner::Stop()
- {
- iHeartbeat->Cancel();
- iTicks=0;
- }
-
-TTimeIntervalSeconds CHeartbeatRunner::CallDuration() const
- {
- TTimeIntervalSeconds duration(iTicks);
- return duration;
- }
-
-// private functions
-
-void CHeartbeatRunner::Beat()
- {
- iTicks++;
- iNotificationStore->CheckNotification(iCallHayes,ETimePeriodElapsed);
- }
-
-void CHeartbeatRunner::Synchronize()
- {
- TInt ticksMissed = 0;
- TTime desiredTime = iStartTime + TTimeIntervalMicroSeconds(iTicks * KCallTimerInterval);
- TTime currentTime; // set current time to now
- currentTime.UniversalTime();
- TTimeIntervalMicroSeconds missedTime = currentTime.MicroSecondsFrom(desiredTime);
- // Calculate the ticks missed (quickly!)
- TInt64 missedTimeInt = missedTime.Int64(); // convert the missed time interval to an Int64
- ticksMissed = I64INT(missedTimeInt / KCallTimerInterval);
- // The following loop increments the ticks missed by the same amount, but takes much longer
- // while (desiredTime < currentTime)
- // {
- // desiredTime = desiredTime - TTimeIntervalMicroSeconds(iTickInterval);
- // ticksMissed++;
- // }
- iTicks = iTicks + ticksMissed;
- LOGTEXT3(_L8("Heartbeat function synchronising - from %d to %d"),iTicks-ticksMissed,iTicks);
- if (ticksMissed!=0)
- iNotificationStore->CheckNotification(iCallHayes,ETimePeriodElapsed);
- }
-
-//
-// CCallHayes - General Call Functionality
-//
-void CCallHayes::CloseCall(TAny* aObj)
-//
-// Utility func for cleanup stack
-//
- {
- ((CObject*)aObj)->Close();
- }
-
-CCallHayes::CCallHayes(CATIO* aIo,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
- : iPhoneGlobals(aPhoneGlobals),iIo(aIo),iInit(aInit)
- {}
-
-void CCallHayes::ConstructL(const TName& aName)
-//
-// Initialise Call Information
-//
- {
- LOGTEXT(_L8("Entered CCallHayes::ConstructL()"));
- iCallInfo.iCallName = aName;
- iCallInfo.iBearerService.iBearerCaps = RCall::KBearerCapsCompressionUnknown | RCall::KBearerCapsProtocolUnknown;
- iCallInfo.iBearerService.iBearerSpeed = RCall::EBearerDataUnknown;
- iCallInfo.iHookStatus = RCall::EHookStatusOn;
- iCallInfo.iClientPanicOccurred = ENoPanicOccurred;
- // Read default call preferences from database
- GetDefaultCallParams();
- iCallInfo.iLoanedToClient = EFalse;
- if (iPhoneGlobals->iPhoneStatus.iLineStatus == RCall::EStatusRinging)
- {
- iCallInfo.iMobileStatus = RMobileCall::EStatusRinging;
- }
- else
- {
- iCallInfo.iMobileStatus = RMobileCall::EStatusIdle;
- }
-
- iQuickInit=CATQuickInit::NewL(iIo,this,iPhoneGlobals);
- iWaitForNoCarrier=CATWaitForNoCarrier::NewL(iIo,this,iPhoneGlobals);
- iList=CAcquireOwnerList::NewL();
- iCallTimer = CHeartbeatRunner::NewL(this,iPhoneGlobals->iNotificationStore);
- LOGTEXT2(_L8("iCallTimer = %x"),iCallTimer);
- }
-
-CCallHayes::~CCallHayes()
- {
- LOGTEXT(_L8("Entered CCallHayes destructor"));
- if (Owner())
- REINTERPRET_CAST(CLineHayes*,Owner())->RemoveCall(this);
- iPhoneGlobals->iNotificationStore->RemoveClientFromLastEvents(this);
- delete iWaitForNoCarrier;
- delete iList;
- delete iQuickInit;
- delete iCallTimer;
- }
-
-CTelObject::TReqMode CCallHayes::ReqModeL(const TInt aIpc)
- {
- TReqMode reqMode = CCallBase::ReqModeL(aIpc);
- if ((reqMode & KReqModeFlowControlObeyed || aIpc==EEtelCallAnswer) && iPhoneGlobals->iPhoneStatus.iDataPortLoaned)
- {
- LOGTEXT2(_L8("ReqModeL Leaving with KErrInUse as data port is loaned (aIpc=%d)"),aIpc);
- User::Leave(KErrInUse);
- }
- return reqMode;
- }
-
-TInt CCallHayes::RegisterNotification(const TInt /*aIpc*/)
- {
- return KErrNone;
- }
-TInt CCallHayes::DeregisterNotification(const TInt /*aIpc*/)
- {
- return KErrNone;
- }
-
-
-void CCallHayes::Init()
-//
-// Only CPhoneHayes::Init() is implemented as that is called first
-//
- {}
-
-
-TInt CCallHayes::NotifyCapsChange(const TTsyReqHandle aTsyReqHandle, RCall::TCaps* aCaps)
- {
- LOGTEXT(_L8("Call:\tCaps Change Notification lodged"));
- iPhoneGlobals->iNotificationStore->RegisterNotification(ECallCaps,aTsyReqHandle,this,aCaps);
- return KErrNone;
- }
-
-TInt CCallHayes::NotifyCapsChangeCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGTEXT(_L8("Call:\tCaps Change Notification cancelled"));
- iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
- return KErrNone;
- }
-
-TInt CCallHayes::NotifyHookChange(const TTsyReqHandle aTsyReqHandle, RCall::THookStatus* aHookStatus)
- {
- LOGTEXT(_L8("Call:\tHook Change Notification lodged"));
- iPhoneGlobals->iNotificationStore->RegisterNotification(ECallHookChange,aTsyReqHandle,this,aHookStatus);
- return KErrNone;
- }
-
-TInt CCallHayes::NotifyHookChangeCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGTEXT(_L8("Call:\tHook Change Notification cancelled"));
- iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
- return KErrNone;
- }
-
-TInt CCallHayes::NotifyStatusChange(const TTsyReqHandle aTsyReqHandle,RCall::TStatus* aStatus)
- {
- LOGTEXT(_L8("Call:\tStatus Change Notification lodged"));
- iPhoneGlobals->iNotificationStore->RegisterNotification(ECallStatusChange,aTsyReqHandle,this,aStatus);
- return KErrNone;
- }
-
-TInt CCallHayes::NotifyStatusChangeCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGTEXT(_L8("Call:\tStatus Change Notification cancelled"));
- iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
- return KErrNone;
- }
-
-TInt CCallHayes::NotifyDurationChange(const TTsyReqHandle aTsyReqHandle,TTimeIntervalSeconds* aTime)
- {
- LOGTEXT(_L8("Call:\tDuration Change Notification lodged"));
- iPhoneGlobals->iNotificationStore->RegisterNotification(ECallDurationChange,aTsyReqHandle,this,aTime);
- return KErrNone;
- }
-
-TInt CCallHayes::NotifyDurationChangeCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGTEXT(_L8("Call:\tDuration Change Notification cancelled"));
- iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
- return KErrNone;
- }
-
-TInt CCallHayes::GetInfo(const TTsyReqHandle aTsyReqHandle, RCall::TCallInfo* aCallInfo)
- {
- aCallInfo->iCallName = iCallInfo.iCallName;
- aCallInfo->iStatus = GetCoreCallStatus();
- aCallInfo->iHookStatus = iCallInfo.iHookStatus;
- aCallInfo->iLineName = Owner()->Name();
- GetCallDuration(aCallInfo->iDuration);
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CCallHayes::GetStatus(const TTsyReqHandle aTsyReqHandle, RCall::TStatus* aCallStatus)
- {
- LOGTEXT(_L8("Call:\tGetStatus() called"));
- *aCallStatus = GetCoreCallStatus();
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CCallHayes::TransferOwnership(const TTsyReqHandle aTsyReqHandle)
-//
-// Transfer call ownership
-//
- {
- LOGTEXT(_L8("Call:\tTransferOwnership called"));
- if (CheckOwnership(aTsyReqHandle)!=CCallBase::EOwnedTrue)
- {
- ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner);
- return KErrNone;
- }
-
- if(iList->iAcquireList.IsEmpty()) // no one interested in this call !
- {
- ReqCompleted(aTsyReqHandle,KErrEtelNoClientInterestedInThisCall);
- return KErrNone;
- }
-
- CAcquireEntry* entry=iList->iAcquireList.First();
- if (entry) // someone interested in this call
- {
- LOGTEXT(_L8("Call:\tTransferOwnership successful"));
- (void)SetOwnership(entry->iTsyReqHandle);
- ReqCompleted(entry->iTsyReqHandle,KErrNone);
- iList->Remove(entry);
- ReqCompleted(aTsyReqHandle,KErrNone);
- }
- return KErrNone;
- }
-
-TInt CCallHayes::AcquireOwnership(const TTsyReqHandle aTsyReqHandle)
-//
-// Acquire call Ownership (server has already checked client does not own it)
-// If call is unowned and idle, this request is completed with CallNotActive.
-// A call must never be owned and idle concurrently.
-//
- {
- LOGTEXT(_L8("Call:\tAcquireOwnership called"));
- if (CheckOwnership(aTsyReqHandle)==CCallBase::EOwnedUnowned)
- {
- LOGTEXT(_L8("Call:\tAcquireOwnership unsuccessful as call is not owned already"));
- ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive);
- }
- else
- {
- if(iList->iAcquireList.IsEmpty())
- // List is empty. Client is the first one to request ownership of the call.
- {
- CAcquireEntry* entry=NULL;
- TRAPD(err,entry=CAcquireEntry::NewL(aTsyReqHandle));
- if(err==KErrNone)
- iList->iAcquireList.AddLast(*entry);
- else
- return err;
- }
- else
- // List is not empty. Another client has already requested to acquire ownership of the call.
- // Only one client can be waiting to acquire ownership at any one time.
- return KErrInUse;
- }
- return KErrNone;
- }
-
-TInt CCallHayes::AcquireOwnershipCancel(const TTsyReqHandle aTsyReqHandle)
-//
-// Cancel Acquire call Ownership
-//
- {
- CAcquireEntry* entry=iList->FindByTsyReqHandle(aTsyReqHandle);
- __ASSERT_ALWAYS(entry!=NULL,Panic(EAcquirerNotFound));
- if (entry != NULL)
- {
- iList->Remove(entry);
- ReqCompleted(aTsyReqHandle, KErrCancel);
- }
- else
- {
- ReqCompleted(aTsyReqHandle, KErrNotFound);
- }
- return KErrNone;
- }
-
-TInt CCallHayes::GetBearerServiceInfo(const TTsyReqHandle aTsyReqHandle,RCall::TBearerService* aBearerService)
- {
- *aBearerService = iCallInfo.iBearerService;
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CCallHayes::GetCallParams(const TTsyReqHandle aTsyReqHandle, TDes8* aParams)
-//
-// Call parameters are only set when connecting a call, so there have no meaning when a
-// call is not in progress.
-//
- {
- if (RMobileCall::EStatusIdle != iCallInfo.iMobileStatus &&
- RMobileCall::EStatusUnknown != iCallInfo.iMobileStatus )
- {
- TPckg<RCall::TCallParams>* paramsPckg = (TPckg<RCall::TCallParams>*)aParams;
- RCall::TCallParams& callparams = (*paramsPckg)();
-
- //
- // Configure basic TCallParams parameters
- callparams.iSpeakerControl = iCallInfo.iSpeakerControl;
- callparams.iSpeakerVolume = iCallInfo.iSpeakerVolume;
- callparams.iInterval = iCallInfo.iInterval;
- callparams.iWaitForDialTone = iCallInfo.iWaitForDialTone;
-
- //
- // Configure additional params as required
- if(callparams.ExtensionId()==RMobileCall::KETelMobileCallParamsV1)
- {
- //
- // Configure RMobileCall::TMobileCallParamsV1 parameters
- RMobileCall::TMobileCallParamsV1Pckg* pckg = (RMobileCall::TMobileCallParamsV1Pckg*)aParams;
- RMobileCall::TMobileCallParamsV1& params = (*pckg)();
- params.iIdRestrict=iCallInfo.iCallParams.iIdRestrict;
- params.iCug=iCallInfo.iCallParams.iCug;
- params.iAutoRedial=iCallInfo.iCallParams.iAutoRedial;
- }
- else if(callparams.ExtensionId()==RMobileCall::KETelMobileDataCallParamsV1)
- {
- //
- // Configure RMobileCall::TMobileDataCallParamsV1 parameters
- RMobileCall::TMobileDataCallParamsV1Pckg* pckg = (RMobileCall::TMobileDataCallParamsV1Pckg*)aParams;
- RMobileCall::TMobileDataCallParamsV1& params = (*pckg)();
- params.iService=iCallInfo.iCallParams.iService;
- params.iSpeed=iCallInfo.iCallParams.iSpeed;
- params.iProtocol=iCallInfo.iCallParams.iProtocol;
- params.iQoS=iCallInfo.iCallParams.iQoS;
- params.iRLPVersion=iCallInfo.iCallParams.iRLPVersion;
- params.iModemToMSWindowSize=iCallInfo.iCallParams.iModemToMSWindowSize;
- params.iMSToModemWindowSize=iCallInfo.iCallParams.iMSToModemWindowSize;
- params.iAckTimer=iCallInfo.iCallParams.iAckTimer;
- params.iRetransmissionAttempts=iCallInfo.iCallParams.iRetransmissionAttempts;
- params.iResequencingPeriod=iCallInfo.iCallParams.iResequencingPeriod;
- params.iV42bisReq=iCallInfo.iCallParams.iV42bisReq;
- params.iV42bisCodewordsNum=iCallInfo.iCallParams.iV42bisCodewordsNum;
- params.iV42bisMaxStringLength=iCallInfo.iCallParams.iV42bisMaxStringLength;
- }
- else if(callparams.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1)
- {
- //
- // Configure RMobileCall::TMobileHscsdCallParamsV1 parameters
- RMobileCall::TMobileHscsdCallParamsV1Pckg* pckg = (RMobileCall::TMobileHscsdCallParamsV1Pckg*)aParams;
- RMobileCall::TMobileHscsdCallParamsV1& params = (*pckg)();
- params.iWantedAiur=iCallInfo.iCallParams.iWantedAiur;
- params.iWantedRxTimeSlots=iCallInfo.iCallParams.iWantedRxTimeSlots;
- params.iMaxTimeSlots=iCallInfo.iCallParams.iMaxTimeSlots;
- params.iCodings=iCallInfo.iCallParams.iCodings;
- params.iAsymmetry=iCallInfo.iCallParams.iAsymmetry;
- params.iUserInitUpgrade=iCallInfo.iCallParams.iUserInitUpgrade;
- }
-
- //
- // Complete the clients request
- ReqCompleted(aTsyReqHandle,KErrNone);
- }
- else
- {
- ReqCompleted(aTsyReqHandle,KErrUnknown);
- }
- return KErrNone;
- }
-
-TInt CCallHayes::GetCallDuration(const TTsyReqHandle aTsyReqHandle, TTimeIntervalSeconds* aTime)
- {
- if ( RMobileCall::EStatusConnected != iCallInfo.iMobileStatus &&
- RMobileCall::EStatusDisconnecting != iCallInfo.iMobileStatus)
- {
- ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive);
- return KErrNone;
- }
- *aTime = iCallTimer->CallDuration();
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-void CCallHayes::GetCallDuration(TTimeIntervalSeconds& aTime) const
- {
- aTime = iCallTimer->CallDuration();
- }
-
-void CCallHayes::GetDefaultCallParams()
- {
- iPhoneGlobals->iConfiguration->GetIntervalPref(iCallInfo.iInterval);
- iPhoneGlobals->iConfiguration->GetSpeakerSettingPref(iCallInfo.iSpeakerControl);
- iPhoneGlobals->iConfiguration->GetSpeakerVolumePref(iCallInfo.iSpeakerVolume);
- iPhoneGlobals->iConfiguration->GetWaitForDialTonePref(iCallInfo.iWaitForDialTone);
- }
-
-void CCallHayes::SetCallParams(const TDesC8* aParams)
- {
- if ((*aParams).Length()==0)
- // Always returns KErrNone
- GetDefaultCallParams();
- else
- {
- TPckg<RCall::TCallParams>* paramsPckg = (TPckg<RCall::TCallParams>*)aParams;
- RCall::TCallParams& callparams = (*paramsPckg)();
- iCallInfo.iSpeakerControl = callparams.iSpeakerControl;
- iCallInfo.iSpeakerVolume = callparams.iSpeakerVolume;
- iCallInfo.iInterval = callparams.iInterval;
- iCallInfo.iWaitForDialTone = callparams.iWaitForDialTone;
- }
- }
-
-TInt CCallHayes::ValidateRequest(const TTsyReqHandle aTsyReqHandle, RCall::TStatus aLineStatus)
-//
-// Validating a request
-//
- {
- CCallBase::TCallOwnership owned = CheckOwnership(aTsyReqHandle);
- if (owned==CCallBase::EOwnedFalse) // call owned by another client
- {
- return KErrEtelNotCallOwner;
- }
- if (iPhoneGlobals->iPhoneStatus.iLineStatus != aLineStatus)
- {
- if (aLineStatus==RCall::EStatusIdle)
- // implies that this call is already active (assuming an owned call is
- // an active call) or ringing or unknown
- {
- return KErrInUse;
- }
- else if (aLineStatus==RCall::EStatusRinging)
- {
- return KErrNotReady;
- }
- }
- return KErrNone;
- }
-
-
-RCall::TStatus CCallHayes::GetCoreCallStatus()
- {
- RCall::TStatus coreStatus;
- if (iCallInfo.iMobileStatus <= RMobileCall::EStatusDisconnecting)
- //coreStatus = static_cast<RCall::TStatus>(iCallInfo.iMobileStatus);
- coreStatus = (RCall::TStatus)iCallInfo.iMobileStatus;
- else
- switch (iCallInfo.iMobileStatus)
- {
- case RMobileCall::EStatusReconnectPending:
- case RMobileCall::EStatusHold:
- coreStatus = RCall::EStatusConnected;
- break;
- case RMobileCall::EStatusWaitingAlternatingCallSwitch:
- coreStatus = RCall::EStatusIdle;
- break;
- default:
- coreStatus = RCall::EStatusUnknown;
- break;
- }
- return coreStatus;
- }
-
-TInt CCallHayes::ChangeCallStatus(RMobileCall::TMobileCallStatus aCallStatus)
- {
- if (iCallInfo.iMobileStatus != aCallStatus)
- {
- iCallInfo.iMobileStatus = aCallStatus;
-
- if (aCallStatus == RMobileCall::EStatusIdle)
- {
- iCallInfo.iHookStatus = RCall::EHookStatusOn;
- iPhoneGlobals->iNotificationStore->CheckNotification(this,EBecomeIdle);
- }
- else if (aCallStatus != RMobileCall::EStatusUnknown && aCallStatus != RMobileCall::EStatusRinging)
- {
- iCallInfo.iHookStatus = RCall::EHookStatusOff;
- }
- if (aCallStatus == RMobileCall::EStatusConnected)
- {
- iPhoneGlobals->iNotificationStore->CheckNotification(this,EConnected);
- iIo->Cancel();
- TCommConfig aConfigPckg;
- TInt ret = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeConnect);
- if (ret==KErrNone)
- ret = iIo->ConfigurePort(aConfigPckg);
-// if (!(iIo->ReadPending()))
-// iIo->Read();
- iCallInfo.iTimeCallBegan.UniversalTime();
- return ret;
- }
- }
- return KErrNone;
- }
-
-void CCallHayes::ChangeLineStatus(RCall::TStatus aLineStatus)
- {
- iPhoneGlobals->iPhoneStatus.iLineStatus = aLineStatus;
- }
-
-void CCallHayes::SetToIdle()
- {
- iWaitForNoCarrier->StopWait();
- // Always returns KErrNone
- (void)SetUnowned();
- iPhoneGlobals->iPhoneStatus.iMode = RPhone::EModeIdle;
- ChangeLineStatus(RCall::EStatusIdle); // line status should be changed first because
- // ChangeCallStatus is the function which sends
- // the new event to the Notification Handler,
- // and this will complete both line and call status
- // notifications, taking the new statuses from the
- // CLineHayes and CCallHayes objects.
- // EStatusIdle always results in KErrNone return value
- (void)ChangeCallStatus(RMobileCall::EStatusIdle);
- StopCallTicker();
- }
-
-void CCallHayes::SetToIdleAndCompleteReq(TTsyReqHandle aTsyReqHandle,TInt aStatus)
- {
- SetToIdle();
- ReqCompleted(aTsyReqHandle, aStatus);
- }
-
-void CCallHayes::GetCallInfo(TCallInfoIndex* aCallInfoIndex)
-//
-// Copied field by field since TCallInfoTSY is different to TCallInfoIndex
-//
- {
- aCallInfoIndex->iInfo.iCallName = iCallInfo.iCallName;
- aCallInfoIndex->iInfo.iStatus = GetCoreCallStatus();
- aCallInfoIndex->iInfo.iCallCapsFlags = 0;
- }
-
-TBool CCallHayes::CheckName(const TDesC& aName) const
-//
-// Return TRUE if name is the same as the name of this call
- {
- if (iCallInfo.iCallName.CompareF(aName))
- return EFalse;
- else
- return ETrue;
- }
-
-TCallInfoTSY* CCallHayes::CallInfo()
- {
- return &iCallInfo;
- }
-
-void CCallHayes::StartCallTicker() const
- {
- iCallTimer->Start();
- }
-
-void CCallHayes::StopCallTicker() const
- {
- iCallTimer->Stop();
- }
-
-void CCallHayes::ResetIsForIncomingCall()
- {
- iIsForIncomingCall=EFalse;
- }
-
-TBool CCallHayes::IsForIncomingCall() const
- {
- return iIsForIncomingCall;
- }
-
-void CCallHayes::SetOwnedByTSY()
- {
- iIsOwnedByTSY=ETrue;
- }
-
-void CCallHayes::SetUnownedByTSY()
- {
- iIsOwnedByTSY=EFalse;
- }
-
-TBool CCallHayes::IsOwnedByTSY() const
- {
- return iIsOwnedByTSY;
- }
-
-
-//
-// Functions which are supported in one line but not the other
-//
-TInt CCallHayes::LoanDataPort(const TTsyReqHandle,RCall::TCommPort*)
- {
- return KErrNotSupported;
- }
-
-TInt CCallHayes::LoanDataPortCancel(const TTsyReqHandle)
- {
- return KErrNotSupported;
- }
-
-TInt CCallHayes::RecoverDataPort(const TTsyReqHandle)
- {
- return KErrNotSupported;
- }
-
-TInt CCallHayes::RecoverDataPortAndRelinquishOwnership()
- {
- return KErrNotSupported;
- }
-
-TInt CCallHayes::GetFaxSettings(const TTsyReqHandle,RCall::TFaxSessionSettings*)
- {
- return KErrNotSupported;
- }
-
-TInt CCallHayes::SetFaxSettings(const TTsyReqHandle,const RCall::TFaxSessionSettings*)
- {
- return KErrNotSupported;
- }
-
-CTelObject* CCallHayes::OpenNewObjectByNameL(const TDesC& /*aName*/)
- {
- User::Leave(KErrNotSupported);
- return NULL;
- }
-
-CTelObject* CCallHayes::OpenNewObjectL(TDes& /*aNewName*/)
- {
- User::Leave(KErrNotSupported);
- return NULL;
- }
-
-TInt CCallHayes::CheckAndSetRegistrationParams(const TInt /*aIpc*/,const TDes8* /*aDes1*/,const TDes8* /*aDes2*/)
- {
- return KErrNone;
- }
-
-TInt CCallHayes::ExtFunc(const TTsyReqHandle,const TInt, const TDataPackage&)
-//
-// Unsupported in this TSY
-//
- {
- return KErrNotSupported;
- }
-
-/*
- * CCallMobile class that implements Multimode ETel Mobile Call requests
- */
-
-CCallMobile::CCallMobile(CATIO* aIo,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
- : CCallHayes(aIo, aInit, aPhoneGlobals)
- {
- }
-
-CCallMobile::~CCallMobile()
- {
- }
-
-CTelObject::TReqMode CCallMobile::ReqModeL(const TInt aIpc)
- {
- // ReqModeL is called from the server's CTelObject::ReqAnalyserL
- // in order to check the type of request it has
-
- CTelObject::TReqMode ret=0;
- switch (aIpc)
- {
-//
-// No Flow Control NOR Multiple Completion
-//
- case EMobileCallGetMobileCallCaps:
- case EMobileCallGetMobileCallStatus:
- break;
-
- case EMobileCallGetMobileDataCallCaps:
- break;
-//
-// Multiple Completion Services with Immediate Server Repost
-// (Usually Notifications)
-//
- case EMobileCallNotifyMobileCallStatusChange:
- case EMobileCallNotifyMobileCallCapsChange:
-
- ret=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
- break;
-//
-//
-//
- default:
- ret=CCallHayes::ReqModeL(aIpc);
- break;
- }
-
- return ret;
- }
-
-
-TInt CCallMobile::NumberOfSlotsL(const TInt aIpc)
- {
- // NumberOfSlotsL is called by the server when it is registering a new notification
- // It enables the TSY to tell the server how many buffer slots to allocate for
- // "repost immediately" notifications that may trigger before clients collect them
-
- TInt numberOfSlots=1;
- switch (aIpc)
- {
- case EMobileCallNotifyMobileCallStatusChange:
- case EMobileCallNotifyMobileCallCapsChange:
- LOGTEXT(_L8("CCallMobile: Registered with 5 slots"));
- numberOfSlots=5;
- break;
- default:
- numberOfSlots = CCallBase::NumberOfSlotsL(aIpc);
- break;
- }
- return numberOfSlots;
- }
-
-
-TInt CCallMobile::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc,
- const TDataPackage& aPackage)
- {
- // ExtFunc is called by the server when it has a "extended", i.e. non-core ETel request
- // for the TSY to process
- // A request handle, request type and request data are passed to the TSY
-
- TAny* dataPtr=aPackage.Ptr1();
-
- // The request data has to extracted from TDataPackage and the TAny* pointers have to
- // be "cast" to the expected request data type
-
- switch (aIpc)
- {
-//
-// No Flow Control NOR Multiple Completion
-//
- case EMobileCallGetMobileCallCaps:
- return GetMobileCallCaps(aTsyReqHandle, aPackage.Des1n());
-
- case EMobileCallGetMobileCallStatus:
- return GetMobileCallStatus(aTsyReqHandle,
- REINTERPRET_CAST(RMobileCall::TMobileCallStatus*,dataPtr));
-//
-// Multiple Completion Services with Immediate Server Repost
-// (Usually Notifications)
-//
- case EMobileCallNotifyMobileCallStatusChange:
- return NotifyMobileCallStatusChange(aTsyReqHandle,
- REINTERPRET_CAST(RMobileCall::TMobileCallStatus*, dataPtr));
-
- case EMobileCallNotifyMobileCallCapsChange:
- return NotifyMobileCallCapsChange(aTsyReqHandle, aPackage.Des1n());
-
-//
-// Cancels
-//
- case EMobileCallNotifyMobileCallStatusChangeCancel:
- return NotifyMobileCallStatusChangeCancel(aTsyReqHandle);
-
- case EMobileCallNotifyMobileCallCapsChangeCancel:
- return NotifyMobileCallCapsChangeCancel(aTsyReqHandle);
-
- default:
- return KErrNotSupported;
- }
- }
-
-TInt CCallMobile::CancelService(const TInt aIpc, const TTsyReqHandle aTsyReqHandle)
- {
- // CancelService is called by the server when it is "cleaning-up" any still outstanding
- // asynchronous requests before closing a client's sub-session.
- // This will happen if a client closes its R-class handle without cancelling outstanding
- // asynchronous requests.
-
- switch (aIpc)
- {
- case EMobileCallNotifyMobileCallStatusChange:
- return NotifyMobileCallStatusChangeCancel(aTsyReqHandle);
- case EMobileCallNotifyMobileCallCapsChange:
- return NotifyMobileCallCapsChangeCancel(aTsyReqHandle);
- default:
- return CCallBase::CancelService(aIpc,aTsyReqHandle);
- }
- }
-
-TInt CCallMobile::GetMobileCallCaps(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
- {
- LOGTEXT(_L8("CCallMobile: :GetMobileCallCaps called"));
-
- RMobileCall::TMobileCallCapsV1Pckg *capsPckg = REINTERPRET_CAST(RMobileCall::TMobileCallCapsV1Pckg *,aCaps);
- RMobileCall::TMobileCallCapsV1& caps = (*capsPckg)();
- // Always returns KErrNone
- (void)CollateCurrentMobileCaps(aTsyReqHandle, &caps.iCallControlCaps);
- caps.iCallEventCaps=0; // no call events are supported
-
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CCallMobile::GetCaps(const TTsyReqHandle aTsyReqHandle,RCall::TCaps* aCallCaps)
- {
- (void)CollateCurrentCoreCaps(aTsyReqHandle, reinterpret_cast<TUint32*>(&aCallCaps->iFlags));
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-TBool CCallMobile::CollateCurrentMobileCaps(const TTsyReqHandle aTsyReqHandle, TUint32* aCallCaps)
- {
- CollateCoreCaps(aTsyReqHandle, aCallCaps);
- if (iMobileCaps.iCallControlCaps != *aCallCaps)
- {
- iMobileCaps.iCallControlCaps = *aCallCaps;
- return ETrue;
- }
- return EFalse;
- }
-
-TBool CCallMobile::CollateCurrentCoreCaps(const TTsyReqHandle aTsyReqHandle, TUint32* aCallCaps)
- {
- CollateCoreCaps(aTsyReqHandle, aCallCaps);
- if (iCaps.iFlags != *aCallCaps)
- {
- iCaps.iFlags = *aCallCaps;
- return ETrue;
- }
- return EFalse;
- }
-
-TInt CCallMobile::NotifyMobileCallCapsChange(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
- {
- LOGTEXT(_L8("CCallMobile::NotifyMobileCallCapsChange lodged"));
- iPhoneGlobals->iNotificationStore->RegisterNotification(ECallMobileCaps,aTsyReqHandle,this,aCaps);
- return KErrNone;
- }
-
-TInt CCallMobile::NotifyMobileCallCapsChangeCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGTEXT(_L8("CCallMobile::NotifyMobileCallCapsChangeCancel called"));
- iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
- return KErrNone;
- }
-
-TInt CCallMobile::GetMobileCallStatus(const TTsyReqHandle aTsyReqHandle,RMobileCall::TMobileCallStatus* aStatus)
- {
- LOGTEXT(_L8("CCallMobile::GetMobileCallStatus called"));
- *aStatus=iCallInfo.iMobileStatus;
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-TInt CCallMobile::NotifyMobileCallStatusChange(const TTsyReqHandle aTsyReqHandle,RMobileCall::TMobileCallStatus* aStatus)
- {
- LOGTEXT(_L8("CCallMobile::NotifyMobileCallStatusChange lodged"));
- iPhoneGlobals->iNotificationStore->RegisterNotification(EMobileCallStatusChange,aTsyReqHandle,this,aStatus);
- return KErrNone;
- }
-
-TInt CCallMobile::NotifyMobileCallStatusChangeCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGTEXT(_L8("CCallMobile::NotifyMobileCallStatusChangeCancel called"));
- iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
- return KErrNone;
- }
-
-//
-// CCallMobileVoice - Voice Specific Call Functionality
-//
-
-CCallMobileVoice* CCallMobileVoice::NewL(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals,const TName& aName)
- {
- CCallMobileVoice* voiceCall=new(ELeave) CCallMobileVoice(aATIO,aInit,aPhoneGlobals);
- TCleanupItem newCallVoiceHayesClose(CloseCall,voiceCall);
- CleanupStack::PushL(newCallVoiceHayesClose);
- voiceCall->ConstructL(aName);
- CleanupStack::Pop();
- return voiceCall;
- }
-
-CCallMobileVoice::CCallMobileVoice(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
- : CCallMobile(aATIO,aInit,aPhoneGlobals)
- {}
-
-void CCallMobileVoice::ConstructL(const TName& aName)
- {
- CCallHayes::ConstructL(aName);
- iCallInfo.iLineOwnerName = KVoiceLineName;
- iDialVoice=CATDialVoice::NewL(iIo,this,iInit,iPhoneGlobals);
- iAnswerVoice=CATAnswerVoice::NewL(iIo,this,iInit,iPhoneGlobals);
- iHangUpVoice=CATHangUpVoice::NewL(iIo,this,iInit,iPhoneGlobals);
- }
-
-CCallMobileVoice::~CCallMobileVoice()
-//
-// Removes itself from array of calls in CLineMobileVoice
-//
- {
- delete iDialVoice;
- delete iAnswerVoice;
- delete iHangUpVoice;
- }
-
-void CCallMobileVoice::CollateCoreCaps(const TTsyReqHandle /*aTsyReqHandle*/, TUint32* aCallCaps)
- {
- *aCallCaps = RCall::KCapsVoice;
-
- // Voice calls can be manipulated by any client, not just owner so set as many caps as possible
- if (iPhoneGlobals->iPhoneStatus.iModemDetected==RPhone::EDetectedPresent)
- {
- *aCallCaps |= (RCall::KCapsDial | RCall::KCapsConnect);
-
- TInt ret=KErrNone;
- if (!iIsForIncomingCall)
- {
- if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer())
- ret=KErrEtelAnswerAlreadyOutstanding;
- }
- else
- ret=KErrEtelAnswerAlreadyOutstanding;
-
- if (ret==KErrNone && (iCallInfo.iMobileStatus==RMobileCall::EStatusIdle || iCallInfo.iMobileStatus==RMobileCall::EStatusRinging))
- *aCallCaps |= RCall::KCapsAnswer;
-
- if (iCallInfo.iMobileStatus==RMobileCall::EStatusConnected)
- *aCallCaps |= RCall::KCapsHangUp;
- }
- }
-
-TInt CCallMobileVoice::Dial(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams,TDesC* aTelNumber)
-//
-// Dial a voice call
-//
- {
- SetCallParams(aCallParams);
- LOGTEXT(_L8("VoiceCall:\tSubmitting Dial command for Voice call"));
- if (iPhoneGlobals->iPhoneStatus.iLineStatus == RCall::EStatusIdle)
- {
- (void)SetOwnership(aTsyReqHandle);
- iDialVoice->ExecuteCommand(aTsyReqHandle,aTelNumber,&iCallInfo);
- return KErrNone;
- }
- else
- {
- return KErrInUse;
- }
- }
-
-TInt CCallMobileVoice::DialCancel(const TTsyReqHandle aTsyReqHandle)
-/**
- * Cancel the dial request if possible
- */
- {
- LOGTEXT(_L8("VoiceCall:\tSubmitting Cancel Dial command for Voice call"));
- iDialVoice->CancelCommand(aTsyReqHandle);
- return KErrNone;
- }
-
-TInt CCallMobileVoice::AnswerIncomingCall(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams)
-/**
- * If there is no waiting call, will wait for one and then answer it. If there is, it will
- * answer immediately.
- */
- {
- CCallBase::TCallOwnership owned = CheckOwnership(aTsyReqHandle);
- TInt ret=KErrNone;
- if (owned==CCallBase::EOwnedFalse) // call owned by another client
- {
- ret=KErrEtelNotCallOwner;
- }
- else
- {
- if (!iIsForIncomingCall)
- {
- if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer())
- ret=KErrEtelAnswerAlreadyOutstanding;
- }
- else
- ret=KErrEtelAnswerAlreadyOutstanding;
- }
- if (ret==KErrNone)
- {
- CLineHayes* line = STATIC_CAST(CLineHayes*,Owner());
- STATIC_CAST(CPhoneHayes*,line->Owner())->CancelOtherRingingCall(line);
- line->FreePreAllocCallIfNecessary();
- SetCallParams(aCallParams);
- if (iCallInfo.iMobileStatus==RMobileCall::EStatusRinging)
- {
- (void)SetOwnership(aTsyReqHandle);
- LOGTEXT(_L8("VoiceCall:\tSubmitting Answer command"));
- iAnswerVoice->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
- }
- else // This call is now a client-designated Incoming Call object.
- {
- iIsForIncomingCall=ETrue;
- iAnswerTsyReqHandle = aTsyReqHandle;
- }
- return KErrNone;
- }
- ReqCompleted(aTsyReqHandle,ret);
- return KErrNone;
- }
-
-
-TInt CCallMobileVoice::AnswerIncomingCallCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGTEXT(_L8("VoiceCall:\tSubmitting Cancel Answer command"));
- if (iIsForIncomingCall)
- {
- iIsForIncomingCall=EFalse;
- ReqCompleted(aTsyReqHandle,KErrCancel);
- }
- else
- iAnswerVoice->CancelCommand(aTsyReqHandle);
- return KErrNone;
- }
-
-void CCallMobileVoice::AnswerImmediately()
- {
- (void)SetOwnership(iAnswerTsyReqHandle);
- // EStatusRinging always results in KErrNone return value
- (void) ChangeCallStatus(RMobileCall::EStatusRinging);
- iPhoneGlobals->iNotificationStore->CheckNotification(this,ERingOccurred);
- iIsForIncomingCall=EFalse;
- // this must be after the check notification as CNotifications
- // asks line for info about the call which Is For Incoming Call
- LOGTEXT(_L8("VoiceCall:\tSubmitting Answer command"));
- iAnswerVoice->ExecuteCommand(iAnswerTsyReqHandle,NULL,&iCallInfo);
- }
-
-TInt CCallMobileVoice::Connect(const TTsyReqHandle aTsyReqHandle,const TDesC8* /*aCallParams*/)
- {
- ReqCompleted(aTsyReqHandle,KErrNotSupported);
- return KErrNone;
- }
-
-TInt CCallMobileVoice::ConnectCancel(const TTsyReqHandle aTsyReqHandle)
- {
- ReqCompleted(aTsyReqHandle,KErrNotSupported);
- return KErrNone;
- }
-
-TInt CCallMobileVoice::HangUp(const TTsyReqHandle aTsyReqHandle)
- {
- if (CheckOwnership(aTsyReqHandle)==CCallBase::EOwnedFalse)
- {
- ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner);
- return KErrNone;
- }
- if ((iCallInfo.iMobileStatus!=RMobileCall::EStatusIdle) &&
- (iCallInfo.iMobileStatus!=RMobileCall::EStatusDisconnecting))
- {
- LOGTEXT(_L8("VoiceCall:\tSubmitting Hang Up command"));
- iHangUpVoice->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
- return KErrNone;
- }
- else
- {
- // Call not in a state to be terminated - but return KErrNone
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
- }
-
-TInt CCallMobileVoice::HangUpCancel(const TTsyReqHandle aTsyReqHandle)
-//
-// Cancel the hang up command.
-//
- {
- LOGTEXT(_L8("VoiceCall:\tSubmitting Cancel Hang Up command"));
- iHangUpVoice->Stop(aTsyReqHandle);
- return KErrNone;
- }
-
-TInt CCallMobileVoice::RelinquishOwnership()
- {
-//
-// Called by server to tell TSY to either pass ownership on to another interested client
-// or hang up immediately. If call is currently connecting, RelinquishOwnershipComplete
-// will be called once cancelling has finished.
-//
- LOGTEXT(_L8("VoiceCall:\tRelinquish Ownership"));
- if(iList->iAcquireList.IsEmpty())
- {
- if (iDialVoice->IsPreConnectInProgress())
- {
- iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
- return KErrNone;
- }
- switch(iCallInfo.iMobileStatus)
- {
- case RMobileCall::EStatusConnected:
- iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
- iHangUpVoice->ExecuteCommand(0, NULL, &iCallInfo);
- break;
- case RMobileCall::EStatusDialling:
- case RMobileCall::EStatusConnecting:
- case RMobileCall::EStatusAnswering:
- case RMobileCall::EStatusDisconnecting:
- iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
- break;
- default:
- if (iPhoneGlobals->iPhoneStatus.iInitStatus==EPhoneInitialising)
- iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
- else
- RelinquishOwnershipCompleted(KErrNone);
- break;
- }
- return KErrNone;
- }
- CAcquireEntry* entry=iList->iAcquireList.First();
- if (entry)
- {
- (void)SetOwnership(entry->iTsyReqHandle);
- ReqCompleted(entry->iTsyReqHandle,KErrNone);
- iList->Remove(entry);
- }
- RelinquishOwnershipCompleted(KErrNone);
- return KErrNone;
- }
-
-TInt CCallMobileVoice::RecoverDataPortAndRelinquishOwnership()
- {
- RecoverDataPortAndRelinquishOwnershipCompleted(KErrNotSupported);
- return KErrNone;
- }
-
-TInt CCallMobileVoice::LoanDataPort(const TTsyReqHandle aTsyReqHandle, RCall::TCommPort* /* aCommPort*/)
- {
- ReqCompleted(aTsyReqHandle,KErrNotSupported);
- return KErrNone;
- }
-
-TInt CCallMobileVoice::LoanDataPortCancel(const TTsyReqHandle aTsyReqHandle)
- {
- ReqCompleted(aTsyReqHandle,KErrNotSupported);
- return KErrNone;
- }
-
-TInt CCallMobileVoice::RecoverDataPort(const TTsyReqHandle aTsyReqHandle)
- {
- ReqCompleted(aTsyReqHandle,KErrNotSupported);
- return KErrNone;
- }
-
-
-//
-//
-// CCallMobileData - Data Specific Call Functionality
-//
-//
-
-CCallMobileData* CCallMobileData::NewL(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals,const TName& aName)
- {
- CCallMobileData* dataCall=new(ELeave) CCallMobileData(aATIO,aInit,aPhoneGlobals);
- TCleanupItem newCallDataHayesClose(CloseCall,dataCall);
- CleanupStack::PushL(newCallDataHayesClose);
- dataCall->ConstructL(aName);
- CleanupStack::Pop();
- return dataCall;
- }
-
-CCallMobileData::CCallMobileData(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
- : CCallMobile(aATIO,aInit,aPhoneGlobals)
- {}
-
-void CCallMobileData::ConstructL(const TName& aName)
- {
- CCallHayes::ConstructL(aName);
- iCallInfo.iLineOwnerName = KDataLineName;
- iDialData=CATDialData::NewL(iIo,this,iInit,iPhoneGlobals);
- iAnswerData=CATAnswerData::NewL(iIo,this,iInit,iPhoneGlobals);
- iSetCBST=CATSetCBST::NewL(iIo,this,iInit,iPhoneGlobals);
- iConnectData=CATConnectData::NewL(iIo,this,iInit,iPhoneGlobals);
- iHangUpData=CATHangUpData::NewL(iIo,this,iInit,iPhoneGlobals);
- iATSetToOnlineDataMode=CATSetToOnlineDataMode::NewL(iIo,this,iInit,iPhoneGlobals);
- }
-
-CCallMobileData::~CCallMobileData()
-//
-// Removes itself from array of calls in CLineMobileData
-//
- {
- delete iDialData;
- delete iSetCBST;
- delete iAnswerData;
- delete iConnectData;
- delete iHangUpData;
- delete iATSetToOnlineDataMode;
- }
-
-TInt CCallMobileData::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc,
- const TDataPackage& aPackage)
-/**
- * Process the IPC locally, otherwise delegate to our base class.
- */
- {
- switch (aIpc)
- {
- case EMobileCallGetMobileDataCallCaps:
- return GetMobileDataCallCaps(aTsyReqHandle, aPackage.Des1n());
- default:
- // Delegate the processing of the IPC to our base class
- return CCallMobile::ExtFunc(aTsyReqHandle,aIpc,aPackage);
- }
- }
-
-
-TInt CCallMobileData::GetMobileDataCallCaps(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
- {
- LOGTEXT(_L8("CCallMobileData::GetMobileDataCallCaps called"));
-
- //
- // This is a synchronous client request so this method must complete quickly.
- // The call caps returned are those which were discovered during the
- // intialisation of the TSY (see ATINIT.CPP).
- TPckg<RMobileCall::TMobileCallDataCapsV1>* pckg = (TPckg<RMobileCall::TMobileCallDataCapsV1>*)aCaps;
- RMobileCall::TMobileCallDataCapsV1& caps = (*pckg)();
- caps=iPhoneGlobals->iCallDataCaps;
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
-
-void CCallMobileData::CollateCoreCaps(const TTsyReqHandle aTsyReqHandle, TUint32* aCallCaps)
- {
- *aCallCaps = RCall::KCapsData;
- if (iPhoneGlobals->iPhoneStatus.iModemDetected==RPhone::EDetectedPresent)
- {
- CCallBase::TCallOwnership owner = CheckOwnership(aTsyReqHandle);
- if (ValidateRequest(aTsyReqHandle,RCall::EStatusIdle)==KErrNone)
- *aCallCaps |= (RCall::KCapsDial | RCall::KCapsConnect);
- TInt ret=KErrNone;
- if (owner==CCallBase::EOwnedFalse) // call owned by another client
- ret=KErrEtelNotCallOwner;
- else
- {
- if (!iIsForIncomingCall)
- {
- if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer())
- ret=KErrEtelAnswerAlreadyOutstanding;
- }
- else
- ret=KErrEtelAnswerAlreadyOutstanding;
- }
- if (ret==KErrNone && (iCallInfo.iMobileStatus==RMobileCall::EStatusIdle || iCallInfo.iMobileStatus==RMobileCall::EStatusRinging))
- *aCallCaps |= RCall::KCapsAnswer;
- if ((owner==CCallBase::EOwnedTrue || owner==CCallBase::EOwnedPriorityClient)
- && iCallInfo.iMobileStatus==RMobileCall::EStatusConnected)
- {
- *aCallCaps |= RCall::KCapsHangUp;
- if (iCallInfo.iLoanedToClient==EFalse)
- *aCallCaps |= RCall::KCapsLoanDataPort;
- else
- *aCallCaps |= RCall::KCapsRecoverDataPort;
- }
- }
- }
-
-TInt CCallMobileData::AssembleCBSTSetString(TBuf8<KGenericBufferSize>& aTxBuffer)
-/**
- * This funciton assembles a +CBST= string ready to be sent to the modem using
- * the values from CCallHayes::iCallInfo.
- * This utility funciton is used by objects created and owned by this class.
- * This has been done to reduce code size.
- * @return KErrNone if and only if CBST string assembled
- */
- {
- TInt ret(KErrNone); // Return value of this function
-
- TInt speed(0); // these are the names that etsi use
- TInt name(0); // these are the names that etsi use
- TInt ce(0); // these are the names that etsi use
- TBool speedSet(ETrue);
- TBool nameSet(ETrue);
- TBool ceSet(ETrue);
-
- switch (iCallInfo.iCallParams.iService)
- {
- case RMobileCall::EServiceDataCircuitAsync:
- name = 0;
- break;
- case RMobileCall::EServiceDataCircuitAsyncRdi:
- name = 4;
- break;
- case RMobileCall::EServiceDataCircuitSync:
- name = 1;
- break;
- case RMobileCall::EServiceDataCircuitSyncRdi:
- name = 5;
- break;
- case RMobileCall::EServicePADAsyncUDI:
- name = 2;
- break;
- case RMobileCall::EServicePADAsyncRDI:
- name = 6;
- break;
- case RMobileCall::EServicePacketAccessSyncUDI:
- name = 3;
- break;
- case RMobileCall::EServicePacketAccessSyncRDI:
- name = 7;
- break;
- case RMobileCall::EServiceUnspecified: // taking the default value of 0
- default:
- nameSet=EFalse;
- break;
- }
-
- switch(iCallInfo.iCallParams.iQoS)
- {
- case RMobileCall::EQoSTransparent:
- ce = 0;
- break;
- case RMobileCall::EQosTransparentPreferred:
- ce = 2;
- break;
- case RMobileCall::EQoSNonTransparent:
- ce = 1;
- break;
- case RMobileCall::EQosNonTransparentPreferred:
- ce = 3;
- break;
- case RMobileCall::EQoSUnspecified:
- default:
- ceSet=EFalse;
- break;
- }
-
- switch(iCallInfo.iCallParams.iSpeed)
- {
- case RMobileCall::ESpeedAutobauding:
- speed = 0;
- break;
-
- case RMobileCall::ESpeed2400:
- {
- if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV22bis)
- speed = 4;
- else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
- speed = 36;
- else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
- (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
- speed = 68;
- else
- speedSet=EFalse;
- break;
- }
- case RMobileCall::ESpeed4800:
- {
- if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV32)
- speed = 6;
- else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
- speed = 38;
- else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
- (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
- speed = 70;
- else
- speedSet=EFalse;
- break;
- }
- case RMobileCall::ESpeed9600:
- {
- if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV32)
- speed = 7;
- else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34)
- speed = 12;
- else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
- speed = 39;
- else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
- (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
- speed = 71;
- else
- speedSet=EFalse;
- break;
- }
- case RMobileCall::ESpeed14400:
- {
- if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34)
- speed = 14;
- else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
- speed = 43;
- else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
- (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
- speed = 75;
- else
- speedSet=EFalse;
- break;
- }
- case RMobileCall::ESpeed19200:
- {
- if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34)
- speed = 15;
- else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
- speed = 47;
- else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
- (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
- speed = 79;
- else
- speedSet=EFalse;
- break;
- }
- case RMobileCall::ESpeed28800:
- {
- if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34)
- speed = 16;
- else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
- speed = 48;
- else if ((iCallInfo.iCallParams.iProtocol ==RMobileCall:: EProtocolV110) ||
- (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
- speed = 80;
- else
- speedSet=EFalse;
- break;
- }
- case RMobileCall::ESpeed38400:
- {
- if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
- (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
- speed = 81;
- else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
- speed = 49;
- else
- speedSet=EFalse;
- break;
- }
- case RMobileCall::ESpeed48000:
- if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
- speed = 50;
- else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
- (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
- speed = 82;
- else
- speedSet=EFalse;
- break;
- case RMobileCall::ESpeed56000:
- if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
- speed = 51;
- else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
- (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
- speed = 83;
- else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolBitTransparent)
- speed = 115;
- else
- speedSet=EFalse;
- break;
- case RMobileCall::ESpeed64000:
- if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolBitTransparent)
- speed = 116;
- else
- speedSet=EFalse;
- break;
-
- case RMobileCall::ESpeed33600: // this baud rate is not currently used in the etsi table
- case RMobileCall::ESpeedUnspecified:
- default:
- speedSet=EFalse;
- break;
- }
-
- //
- // Try to assemble as much of the +CBST= command as we can.
- // If we do not have a <speed> value we can not send the command.
- // If we do not have a <ce> value then we can send a command giving only <speed> and <name>.
- // etc...
- if(speedSet)
- {
- aTxBuffer.Zero(); // Clear tx buffer
-
- // Append +CBST= and the <speed> parameter
- aTxBuffer.Append(KDataCallBearerServiceType);
- aTxBuffer.AppendNum(speed);
-
- if(nameSet)
- {
- // Append the <name> parameter
- aTxBuffer.Append(TChar(','));
- aTxBuffer.AppendNum(name);
-
- if(ceSet)
- {
- // Append the <ce> parameter
- aTxBuffer.Append(TChar(','));
- aTxBuffer.AppendNum(ce);
- }
- }
-
- // Append final \r char to AT command
- aTxBuffer.Append(TChar('\r'));
- }
- else
- {
- // We have not have enough info to create a +CBST= string
- ret=KErrArgument;
- }
-
- return ret;
- }
-
-
-
-TInt CCallMobileData::Dial(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams,TDesC* aTelNumber)
-//
-// Dial a data call
-//
- {
- TInt ret(KErrNone);
-
- SetDataCallParams(aCallParams);
-
- ret=ValidateRequest(aTsyReqHandle,RCall::EStatusIdle);
- if (ret==KErrNone)
- {
- (void)SetOwnership(aTsyReqHandle);
- LOGTEXT(_L8("DataCall:\tSubmitting Dial command for Data call"));
- iDialData->ExecuteCommand(aTsyReqHandle,aTelNumber,&iCallInfo);
- }
- else
- ReqCompleted(aTsyReqHandle,ret); // An error occurred
-
- return KErrNone; // Real return code is returned to client thru request completion
- }
-
-
-TInt CCallMobileData::DialCancel(const TTsyReqHandle aTsyReqHandle)
-//
-// Cancel the dial request if possible
-//
- {
- LOGTEXT(_L8("DataCall:\tSubmitting Cancel Dial command for Data call"));
- iDialData->CancelCommand(aTsyReqHandle);
- return KErrNone;
- }
-
-
-void CCallMobileData::SetDataCallParams(const TDesC8* aCallParams)
-/**
- * Utility function which unpacks the call parameters supplied by the client
- * and saves their values in iPhoneGlobals.
- * If the client did not supply parameters then default ones are used.
- */
- {
- if(aCallParams->Length()==0)
- {
- //
- // Client did not supply parameters, so we use default ones
- LOGTEXT(_L8("CCallMobileData::SetDataCallParams Using default parameters"));
- CCallHayes::SetCallParams(aCallParams);
-
- //
- // Ensure the speed parameter is undefined so that we prevent the
- // +CBST=... command being sent to the phone when dialling a CSD data call.
- iCallInfo.iCallParams.iService = RMobileCall::EServiceUnspecified;
- }
- else
- {
- //
- // Use call parameters that client supplied us
- LOGTEXT(_L8("CCallMobileData::SetDataCallParams Using clients parameters"));
- RCall::TCallParamsPckg* paramsPckgV1 = (RCall::TCallParamsPckg*)aCallParams;
- RCall::TCallParams& paramsV1 = (*paramsPckgV1)();
-
- CCallHayes::SetCallParams(aCallParams);
- if (paramsV1.ExtensionId()==RMobileCall::KETelMobileCallParamsV1)
- {
- RMobileCall::TMobileCallParamsV1Pckg* mmParamsPckgV1 = (RMobileCall::TMobileCallParamsV1Pckg*)aCallParams;
- RMobileCall::TMobileCallParamsV1& mmParamsV1 = (*mmParamsPckgV1)();
- iCallInfo.iCallParams.iIdRestrict = mmParamsV1.iIdRestrict;
- iCallInfo.iCallParams.iCug = mmParamsV1.iCug;
- iCallInfo.iCallParams.iAutoRedial = mmParamsV1.iAutoRedial;
- }
-
- if((paramsV1.ExtensionId()==RMobileCall::KETelMobileDataCallParamsV1) ||
- (paramsV1.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1))
- {
- RMobileCall::TMobileDataCallParamsV1Pckg* dataParamsPckgV1 = (RMobileCall::TMobileDataCallParamsV1Pckg*)aCallParams;
- RMobileCall::TMobileDataCallParamsV1& dataParamsV1 = (*dataParamsPckgV1)();
- iCallInfo.iCallParams.iService=dataParamsV1.iService;
- iCallInfo.iCallParams.iSpeed=dataParamsV1.iSpeed;
- iCallInfo.iCallParams.iProtocol=dataParamsV1.iProtocol;
- iCallInfo.iCallParams.iQoS=dataParamsV1.iQoS;
- iCallInfo.iCallParams.iRLPVersion=dataParamsV1.iRLPVersion;
- iCallInfo.iCallParams.iModemToMSWindowSize=dataParamsV1.iModemToMSWindowSize;
- iCallInfo.iCallParams.iMSToModemWindowSize=dataParamsV1.iMSToModemWindowSize;
- iCallInfo.iCallParams.iAckTimer=dataParamsV1.iAckTimer;
- iCallInfo.iCallParams.iRetransmissionAttempts=dataParamsV1.iRetransmissionAttempts;
- iCallInfo.iCallParams.iResequencingPeriod=dataParamsV1.iResequencingPeriod;
- iCallInfo.iCallParams.iV42bisReq=dataParamsV1.iV42bisReq;
- iCallInfo.iCallParams.iV42bisCodewordsNum=dataParamsV1.iV42bisCodewordsNum;
- iCallInfo.iCallParams.iV42bisMaxStringLength=dataParamsV1.iV42bisMaxStringLength;
- }
-
- if (paramsV1.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1)
- {
- RMobileCall::TMobileHscsdCallParamsV1Pckg* hscsdParamsPckgV1 = (RMobileCall::TMobileHscsdCallParamsV1Pckg*)aCallParams;
- RMobileCall::TMobileHscsdCallParamsV1& hscsdParamsV1 = (*hscsdParamsPckgV1)();
- iCallInfo.iCallParams.iWantedAiur = hscsdParamsV1.iWantedAiur;
- iCallInfo.iCallParams.iWantedRxTimeSlots = hscsdParamsV1.iWantedRxTimeSlots;
- iCallInfo.iCallParams.iMaxTimeSlots = hscsdParamsV1.iMaxTimeSlots;
- iCallInfo.iCallParams.iCodings = hscsdParamsV1.iCodings;
- iCallInfo.iCallParams.iAsymmetry = hscsdParamsV1.iAsymmetry;
- iCallInfo.iCallParams.iUserInitUpgrade = hscsdParamsV1.iUserInitUpgrade;
- }
- }
- }
-
-TInt CCallMobileData::AnswerIncomingCall(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams)
-/**
- * If there is no waiting call, will wait for one and then answer it.
- * If there is a waiting call, will answer immediatly.
- * Regardless of if there is a waiting call or not, the +CBST= command is sent immediatly.
- */
- {
- const CCallBase::TCallOwnership owned = CheckOwnership(aTsyReqHandle);
- TInt ret=KErrNone;
- if (owned==CCallBase::EOwnedFalse) // call owned by another client
- {
- ret=KErrEtelNotCallOwner;
- }
- else
- {
- if (!iIsForIncomingCall)
- {
- if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer())
- ret=KErrEtelAnswerAlreadyOutstanding;
- }
- else
- ret=KErrEtelAnswerAlreadyOutstanding;
- }
-
- if (ret==KErrNone)
- {
- CLineHayes* line = STATIC_CAST(CLineHayes*,Owner());
- STATIC_CAST(CPhoneHayes*,line->Owner())->CancelOtherRingingCall(line);
- line->FreePreAllocCallIfNecessary();
- SetDataCallParams(aCallParams);
- if (iCallInfo.iMobileStatus==RMobileCall::EStatusRinging)
- {
- (void)SetOwnership(aTsyReqHandle);
- LOGTEXT(_L8("DataCall:\tSubmitting Answer command"));
-
- // Start the 'send CBST to phone' AT machine and pass the
- // CATAnswerData object, so that the call is answered after
- // the CBST is sent.
- iSetCBST->ExecuteCommand(aTsyReqHandle,iAnswerData,&iCallInfo);
- }
- else // This call is now a client-designated Incoming Call object.
- {
- iIsForIncomingCall=ETrue;
- iAnswerTsyReqHandle = aTsyReqHandle;
-
- // Start the 'send CBST to phone' AT machine. This state machine
- // will not complete any client request.
- iSetCBST->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
- }
- return KErrNone;
- }
-
- ReqCompleted(aTsyReqHandle,ret);
- return KErrNone;
- }
-
-
-TInt CCallMobileData::AnswerIncomingCallCancel(const TTsyReqHandle aTsyReqHandle)
- {
- LOGTEXT(_L8("DataCall:\tSubmitting Cancel Answer command"));
- if (iIsForIncomingCall)
- {
- iIsForIncomingCall=EFalse;
- ReqCompleted(aTsyReqHandle,KErrCancel);
- }
- else
- iAnswerData->CancelCommand(aTsyReqHandle);
- return KErrNone;
- }
-
-void CCallMobileData::AnswerImmediately()
- {
- (void)SetOwnership(iAnswerTsyReqHandle);
- // EStatusRinging always results in KErrNone return
- (void) ChangeCallStatus(RMobileCall::EStatusRinging); // new 14/1/99
- iPhoneGlobals->iNotificationStore->CheckNotification(this,ERingOccurred);
- iIsForIncomingCall=EFalse; // this must be after the check notification as CNotifications
- // asks line for info about the call which Is For Incoming Call
- LOGTEXT(_L8("DataCall:\tSubmitting Answer command"));
- iAnswerData->ExecuteCommand(iAnswerTsyReqHandle,NULL,&iCallInfo);
- }
-
-TInt CCallMobileData::Connect(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams)
-//
-// Connect to an already dialled call
-//
- {
- TInt ret = ValidateRequest(aTsyReqHandle,RCall::EStatusIdle);
- if (ret==KErrNone)
- {
- (void)SetOwnership(aTsyReqHandle);
- SetCallParams(aCallParams);
- LOGTEXT(_L8("DataCall:\tSubmitting Immediate Connect command"));
- iConnectData->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
- }
- else
- ReqCompleted(aTsyReqHandle,ret);
- return KErrNone;
- }
-
-TInt CCallMobileData::ConnectCancel(const TTsyReqHandle aTsyReqHandle)
-//
-// Cancel immediate connect command
-//
- {
- LOGTEXT(_L8("DataCall:\tSubmitting Cancel Connect command"));
- iConnectData->CancelCommand(aTsyReqHandle);
- return KErrNone;
- }
-
-TInt CCallMobileData::HangUp(const TTsyReqHandle aTsyReqHandle)
-//
-// Terminate a data call. If someone else owns call complete with error, but if no-one owns
-// it send an ATH anyway, as the connection may have failed and the user wants to ensure
-// call has hung up. Call Start() instead of ExecuteCommand() because there is no need to
-// initialise before doing this or to send the escape sequence - the hang up sequence drops
-// DTR anyway.
-//
- {
- if (CheckOwnership(aTsyReqHandle)==CCallBase::EOwnedFalse)
- {
- ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner);
- return KErrNone;
- }
- if ((iCallInfo.iMobileStatus!=RMobileCall::EStatusIdle) &&
- (iCallInfo.iMobileStatus!=RMobileCall::EStatusDisconnecting))
- {
- LOGTEXT(_L8("DataCall:\tSubmitting Hang Up command"));
- iHangUpData->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
- return KErrNone;
- }
- else
- {
- // Call not in a state to be terminated - but return KErrNone
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
- }
-
-TInt CCallMobileData::HangUpCancel(const TTsyReqHandle aTsyReqHandle)
-//
-// Cancel the hang up command.
-//
- {
- LOGTEXT(_L8("DataCall:\tSubmitting Cancel Hang Up command"));
- iHangUpData->Stop(aTsyReqHandle);
- return KErrNone;
- }
-
-TInt CCallMobileData::RelinquishOwnership()
-//
-// Called by server to tell TSY to either pass ownership on to another interested client
-// or hang up immediately. If call is currently connecting, RelinquishOwnershipComplete
-// will be called once cancelling has finished.
-//
- {
- LOGTEXT(_L8("DataCall:\tRelinquish Ownership"));
- if(iList->iAcquireList.IsEmpty())
- {
- if (iDialData->IsPreConnectInProgress() ||
- iConnectData->IsPreConnectInProgress() ||
- iAnswerData->IsPreConnectInProgress())
- {
- iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
- return KErrNone;
- }
- switch(iCallInfo.iMobileStatus)
- {
- case RMobileCall::EStatusConnected:
- iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
- //iHangUpData->ExecuteCommand(0,NULL,&iCallInfo);
- iQuickInit->CancelAndHangUp(&iCallInfo,iHangUpData);
- break;
- case RMobileCall::EStatusDialling:
- case RMobileCall::EStatusConnecting:
- case RMobileCall::EStatusAnswering:
- case RMobileCall::EStatusDisconnecting:
- iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
- break;
- default:
- if (iPhoneGlobals->iPhoneStatus.iInitStatus==EPhoneInitialising)
- iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
- else
- RelinquishOwnershipCompleted(KErrNone);
- break;
- }
- return KErrNone;
- }
- CAcquireEntry* entry=iList->iAcquireList.First();
- if (entry)
- {
- (void)SetOwnership(entry->iTsyReqHandle);
- ReqCompleted(entry->iTsyReqHandle,KErrNone);
- iList->Remove(entry);
- }
- RelinquishOwnershipCompleted(KErrNone);
- return KErrNone;
- }
-
-TInt CCallMobileData::RecoverDataPortAndRelinquishOwnership()
-//
-// Called by server to tell TSY to either pass ownership on to another interested client
-// after regaining control of the port and performing a swift initialisation,
-// or hang up immediately
-//
- {
- LOGTEXT(_L8("DataPort Recover and Relinquish Ownership"));
- iCallInfo.iLoanedToClient=EFalse;
- iPhoneGlobals->iPhoneStatus.iDataPortLoaned = EFalse;
- if(iList->iAcquireList.IsEmpty())
- {
- (void)SetUnowned();
- iCallInfo.iClientPanicOccurred = EPanicOccurredDuringDataPortLoan;
- iIo->Read();
- iHangUpData->ExecuteCommand(0,NULL,&iCallInfo);
- return KErrNone;
- }
- CAcquireEntry* entry=iList->iAcquireList.First();
- if (entry)
- {
- (void)SetOwnership(entry->iTsyReqHandle);
- ReqCompleted(entry->iTsyReqHandle,KErrNone);
- iList->Remove(entry);
- iQuickInit->StartQuickInit();
- }
- RecoverDataPortAndRelinquishOwnershipCompleted(KErrNone);
- return KErrNone;
- }
-
-TInt CCallMobileData::LoanDataPort(const TTsyReqHandle aTsyReqHandle, RCall::TCommPort* aCommPort)
-//
-// Get the port info
-//
- {
- LOGTEXT(_L8(" DataPort Loan"));
- if (CheckOwnership(aTsyReqHandle)!=CCallBase::EOwnedTrue)
- {
- ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner);
- return KErrNone;
- }
- if (iCallInfo.iMobileStatus != RMobileCall::EStatusConnected)
- {
- ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive);
- return KErrNone;
- }
- TInt ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameCsyName),aCommPort->iCsy);
- if (!ret)
- {
- ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNamePortName),aCommPort->iPort);
- }
- if (ret)
- {
- ReqCompleted(aTsyReqHandle,ret);
- return KErrNone;
- }
- iCallInfo.iLoanedToClient = ETrue;
- iPhoneGlobals->iPhoneStatus.iDataPortLoaned = ETrue;
- iPhoneGlobals->iNotificationStore->CheckNotification(this,EDataPortLoaned);
- iWaitForNoCarrier->StopWait();
- if (iPhoneGlobals->iPhoneStatus.iMode==RPhone::EModeOnlineCommand)
- iATSetToOnlineDataMode->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
- else
- {
- iIo->Cancel();
- TCommConfig aConfigPckg;
- TInt ret = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeFull);
- if (ret==KErrNone)
- ret = iIo->ConfigurePort(aConfigPckg);
- ReqCompleted(aTsyReqHandle,ret);
- }
- return KErrNone;
- }
-
-TInt CCallMobileData::LoanDataPortCancel(const TTsyReqHandle aTsyReqHandle)
- {
- iATSetToOnlineDataMode->CancelCommand(aTsyReqHandle);
- return KErrNone;
- }
-
-TInt CCallMobileData::RecoverDataPort(const TTsyReqHandle aTsyReqHandle)
-//
-// Take back control of data port
-// Check that call had been loaned to client
-//
- {
- if (iCallInfo.iLoanedToClient==EFalse)
- {
- ReqCompleted(aTsyReqHandle,KErrEtelPortNotLoanedToClient);
- return KErrNone;
- }
- TCallOwnership owner = CheckOwnership(aTsyReqHandle);
- if (owner!=CCallBase::EOwnedTrue && owner!=CCallBase::EOwnedPriorityClient)
- {
- ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner);
- return KErrNone;
- }
- LOGTEXT(_L8("DataPort Recover"));
- iCallInfo.iLoanedToClient=EFalse;
- iPhoneGlobals->iPhoneStatus.iDataPortLoaned = EFalse;
- LOGTEXT2(_L8("Comm signals : %x"),iIo->Signals());
- iIo->ResetReadAndWriteBuffers(); // in case client has left RxBuffer non-empty
- LOGTEXT2(_L8("Comm signals after ResetBuffers : %x"),iIo->Signals());
- FlowControlSuspend(); // Defect fix for MPO-4ZECUN
- iQuickInit->StartQuickInit();
- ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
+// Copyright (c) 1997-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:
+//
+
+#include <commsdattypesv1_1.h>
+#include "CALL.H" // Header file for this source file
+#include "NOTIFY.H"
+#include "ATDIAL.H"
+#include "ATANSWER.H"
+#include "ATCONNCT.H"
+#include "ATHANGUP.H"
+#include "ATO.H"
+#include "ATNOCARR.H"
+#include "LINE.H"
+#include "ATINIT.H"
+#include "mSLOGGER.H" // for LOGTEXT untilities
+#include "ATIO.H" // For CATIO class
+#include "PHONE.H"
+#include <et_clsvr.h>
+#include "ATBASE.H"
+#include "Matstd.h" // For AT command string constants
+#include "set_cbst.h" // for CATSetCBST class
+#include "et_struct.h"
+
+
+//
+// CAcquireEntry class
+//
+CAcquireEntry* CAcquireEntry::NewL(const TTsyReqHandle aTsyReqHandle)
+//
+// Create new request entry
+//
+ {
+ return new(ELeave) CAcquireEntry(aTsyReqHandle);
+ }
+
+CAcquireEntry::CAcquireEntry(const TTsyReqHandle aTsyReqHandle)
+//
+// Constructor
+//
+ {
+ iTsyReqHandle=aTsyReqHandle;
+ }
+
+CAcquireEntry::~CAcquireEntry()
+//
+// Destructor
+//
+ {}
+
+void CAcquireEntry::Deque()
+//
+// Deque List
+//
+ {
+ iLink.Deque();
+ iLink.iPrev=iLink.iNext=NULL;
+ }
+
+CAcquireOwnerList::CAcquireOwnerList()
+ {}
+
+CAcquireOwnerList::~CAcquireOwnerList()
+ {}
+
+CAcquireOwnerList* CAcquireOwnerList::NewL()
+//
+// Static function to create new acquire owner list
+//
+ {
+ CAcquireOwnerList* self=new(ELeave) CAcquireOwnerList();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+void CAcquireOwnerList::ConstructL()
+ {
+ iAcquireList.SetOffset(_FOFF(CAcquireEntry,iLink));
+ }
+
+CAcquireEntry* CAcquireOwnerList::FindByTsyReqHandle(const TTsyReqHandle aTsyReqHandle)
+//
+// Searches for client interested in taking ownership of call, by its TsyReqHandle
+//
+ {
+ CAcquireEntry* entry;
+ TDblQueIter<CAcquireEntry> iter(iAcquireList);
+ while(entry = iter++, entry!=NULL)
+ {
+ if(entry->iTsyReqHandle==aTsyReqHandle)
+ return entry;
+ }
+ return NULL;
+ }
+
+void CAcquireOwnerList::Remove(CAcquireEntry* aEntry)
+ {
+ aEntry->Deque();
+ delete aEntry;
+ }
+
+//
+// CHeartbeatRunner - periodic class to count seconds from beginning of call
+//
+CHeartbeatRunner* CHeartbeatRunner::NewL(CCallHayes* aCallHayes,CNotifications* aNotificationStore)
+ {
+ CHeartbeatRunner* self=new (ELeave) CHeartbeatRunner(aCallHayes,aNotificationStore);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CHeartbeatRunner::CHeartbeatRunner(CCallHayes* aCallHayes,CNotifications* aNotificationStore)
+ :iCallHayes(aCallHayes), iNotificationStore(aNotificationStore)
+ {}
+
+void CHeartbeatRunner::ConstructL()
+ {
+ iHeartbeat=CHeartbeat::NewL(0); // neutral priority
+ }
+
+CHeartbeatRunner::~CHeartbeatRunner()
+ {
+ if (iHeartbeat != NULL)
+ iHeartbeat->Cancel();
+ delete iHeartbeat;
+ }
+
+void CHeartbeatRunner::Start()
+ {
+ iStartTime.UniversalTime();
+ iHeartbeat->Start(ETwelveOClock,this);
+ }
+
+void CHeartbeatRunner::Stop()
+ {
+ iHeartbeat->Cancel();
+ iTicks=0;
+ }
+
+TTimeIntervalSeconds CHeartbeatRunner::CallDuration() const
+ {
+ TTimeIntervalSeconds duration(iTicks);
+ return duration;
+ }
+
+// private functions
+
+void CHeartbeatRunner::Beat()
+ {
+ iTicks++;
+ iNotificationStore->CheckNotification(iCallHayes,ETimePeriodElapsed);
+ }
+
+void CHeartbeatRunner::Synchronize()
+ {
+ TInt ticksMissed = 0;
+ TTime desiredTime = iStartTime + TTimeIntervalMicroSeconds(iTicks * KCallTimerInterval);
+ TTime currentTime; // set current time to now
+ currentTime.UniversalTime();
+ TTimeIntervalMicroSeconds missedTime = currentTime.MicroSecondsFrom(desiredTime);
+ // Calculate the ticks missed (quickly!)
+ TInt64 missedTimeInt = missedTime.Int64(); // convert the missed time interval to an Int64
+ ticksMissed = I64INT(missedTimeInt / KCallTimerInterval);
+ // The following loop increments the ticks missed by the same amount, but takes much longer
+ // while (desiredTime < currentTime)
+ // {
+ // desiredTime = desiredTime - TTimeIntervalMicroSeconds(iTickInterval);
+ // ticksMissed++;
+ // }
+ iTicks = iTicks + ticksMissed;
+ LOGTEXT3(_L8("Heartbeat function synchronising - from %d to %d"),iTicks-ticksMissed,iTicks);
+ if (ticksMissed!=0)
+ iNotificationStore->CheckNotification(iCallHayes,ETimePeriodElapsed);
+ }
+
+//
+// CCallHayes - General Call Functionality
+//
+void CCallHayes::CloseCall(TAny* aObj)
+//
+// Utility func for cleanup stack
+//
+ {
+ ((CObject*)aObj)->Close();
+ }
+
+CCallHayes::CCallHayes(CATIO* aIo,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+ : iPhoneGlobals(aPhoneGlobals),iIo(aIo),iInit(aInit)
+ {}
+
+void CCallHayes::ConstructL(const TName& aName)
+//
+// Initialise Call Information
+//
+ {
+ LOGTEXT(_L8("Entered CCallHayes::ConstructL()"));
+ iCallInfo.iCallName = aName;
+ iCallInfo.iBearerService.iBearerCaps = RCall::KBearerCapsCompressionUnknown | RCall::KBearerCapsProtocolUnknown;
+ iCallInfo.iBearerService.iBearerSpeed = RCall::EBearerDataUnknown;
+ iCallInfo.iHookStatus = RCall::EHookStatusOn;
+ iCallInfo.iClientPanicOccurred = ENoPanicOccurred;
+ // Read default call preferences from database
+ GetDefaultCallParams();
+ iCallInfo.iLoanedToClient = EFalse;
+ if (iPhoneGlobals->iPhoneStatus.iLineStatus == RCall::EStatusRinging)
+ {
+ iCallInfo.iMobileStatus = RMobileCall::EStatusRinging;
+ }
+ else
+ {
+ iCallInfo.iMobileStatus = RMobileCall::EStatusIdle;
+ }
+
+ iQuickInit=CATQuickInit::NewL(iIo,this,iPhoneGlobals);
+ iWaitForNoCarrier=CATWaitForNoCarrier::NewL(iIo,this,iPhoneGlobals);
+ iList=CAcquireOwnerList::NewL();
+ iCallTimer = CHeartbeatRunner::NewL(this,iPhoneGlobals->iNotificationStore);
+ LOGTEXT2(_L8("iCallTimer = %x"),iCallTimer);
+ }
+
+CCallHayes::~CCallHayes()
+ {
+ LOGTEXT(_L8("Entered CCallHayes destructor"));
+ if (Owner())
+ REINTERPRET_CAST(CLineHayes*,Owner())->RemoveCall(this);
+ iPhoneGlobals->iNotificationStore->RemoveClientFromLastEvents(this);
+ delete iWaitForNoCarrier;
+ delete iList;
+ delete iQuickInit;
+ delete iCallTimer;
+ }
+
+CTelObject::TReqMode CCallHayes::ReqModeL(const TInt aIpc)
+ {
+ TReqMode reqMode = CCallBase::ReqModeL(aIpc);
+ if ((reqMode & KReqModeFlowControlObeyed || aIpc==EEtelCallAnswer) && iPhoneGlobals->iPhoneStatus.iDataPortLoaned)
+ {
+ LOGTEXT2(_L8("ReqModeL Leaving with KErrInUse as data port is loaned (aIpc=%d)"),aIpc);
+ User::Leave(KErrInUse);
+ }
+ return reqMode;
+ }
+
+TInt CCallHayes::RegisterNotification(const TInt /*aIpc*/)
+ {
+ return KErrNone;
+ }
+TInt CCallHayes::DeregisterNotification(const TInt /*aIpc*/)
+ {
+ return KErrNone;
+ }
+
+
+void CCallHayes::Init()
+//
+// Only CPhoneHayes::Init() is implemented as that is called first
+//
+ {}
+
+
+TInt CCallHayes::NotifyCapsChange(const TTsyReqHandle aTsyReqHandle, RCall::TCaps* aCaps)
+ {
+ LOGTEXT(_L8("Call:\tCaps Change Notification lodged"));
+ iPhoneGlobals->iNotificationStore->RegisterNotification(ECallCaps,aTsyReqHandle,this,aCaps);
+ return KErrNone;
+ }
+
+TInt CCallHayes::NotifyCapsChangeCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGTEXT(_L8("Call:\tCaps Change Notification cancelled"));
+ iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
+ return KErrNone;
+ }
+
+TInt CCallHayes::NotifyHookChange(const TTsyReqHandle aTsyReqHandle, RCall::THookStatus* aHookStatus)
+ {
+ LOGTEXT(_L8("Call:\tHook Change Notification lodged"));
+ iPhoneGlobals->iNotificationStore->RegisterNotification(ECallHookChange,aTsyReqHandle,this,aHookStatus);
+ return KErrNone;
+ }
+
+TInt CCallHayes::NotifyHookChangeCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGTEXT(_L8("Call:\tHook Change Notification cancelled"));
+ iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
+ return KErrNone;
+ }
+
+TInt CCallHayes::NotifyStatusChange(const TTsyReqHandle aTsyReqHandle,RCall::TStatus* aStatus)
+ {
+ LOGTEXT(_L8("Call:\tStatus Change Notification lodged"));
+ iPhoneGlobals->iNotificationStore->RegisterNotification(ECallStatusChange,aTsyReqHandle,this,aStatus);
+ return KErrNone;
+ }
+
+TInt CCallHayes::NotifyStatusChangeCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGTEXT(_L8("Call:\tStatus Change Notification cancelled"));
+ iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
+ return KErrNone;
+ }
+
+TInt CCallHayes::NotifyDurationChange(const TTsyReqHandle aTsyReqHandle,TTimeIntervalSeconds* aTime)
+ {
+ LOGTEXT(_L8("Call:\tDuration Change Notification lodged"));
+ iPhoneGlobals->iNotificationStore->RegisterNotification(ECallDurationChange,aTsyReqHandle,this,aTime);
+ return KErrNone;
+ }
+
+TInt CCallHayes::NotifyDurationChangeCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGTEXT(_L8("Call:\tDuration Change Notification cancelled"));
+ iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
+ return KErrNone;
+ }
+
+TInt CCallHayes::GetInfo(const TTsyReqHandle aTsyReqHandle, RCall::TCallInfo* aCallInfo)
+ {
+ aCallInfo->iCallName = iCallInfo.iCallName;
+ aCallInfo->iStatus = GetCoreCallStatus();
+ aCallInfo->iHookStatus = iCallInfo.iHookStatus;
+ aCallInfo->iLineName = Owner()->Name();
+ GetCallDuration(aCallInfo->iDuration);
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CCallHayes::GetStatus(const TTsyReqHandle aTsyReqHandle, RCall::TStatus* aCallStatus)
+ {
+ LOGTEXT(_L8("Call:\tGetStatus() called"));
+ *aCallStatus = GetCoreCallStatus();
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CCallHayes::TransferOwnership(const TTsyReqHandle aTsyReqHandle)
+//
+// Transfer call ownership
+//
+ {
+ LOGTEXT(_L8("Call:\tTransferOwnership called"));
+ if (CheckOwnership(aTsyReqHandle)!=CCallBase::EOwnedTrue)
+ {
+ ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner);
+ return KErrNone;
+ }
+
+ if(iList->iAcquireList.IsEmpty()) // no one interested in this call !
+ {
+ ReqCompleted(aTsyReqHandle,KErrEtelNoClientInterestedInThisCall);
+ return KErrNone;
+ }
+
+ CAcquireEntry* entry=iList->iAcquireList.First();
+ if (entry) // someone interested in this call
+ {
+ LOGTEXT(_L8("Call:\tTransferOwnership successful"));
+ (void)SetOwnership(entry->iTsyReqHandle);
+ ReqCompleted(entry->iTsyReqHandle,KErrNone);
+ iList->Remove(entry);
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ }
+ return KErrNone;
+ }
+
+TInt CCallHayes::AcquireOwnership(const TTsyReqHandle aTsyReqHandle)
+//
+// Acquire call Ownership (server has already checked client does not own it)
+// If call is unowned and idle, this request is completed with CallNotActive.
+// A call must never be owned and idle concurrently.
+//
+ {
+ LOGTEXT(_L8("Call:\tAcquireOwnership called"));
+ if (CheckOwnership(aTsyReqHandle)==CCallBase::EOwnedUnowned)
+ {
+ LOGTEXT(_L8("Call:\tAcquireOwnership unsuccessful as call is not owned already"));
+ ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive);
+ }
+ else
+ {
+ if(iList->iAcquireList.IsEmpty())
+ // List is empty. Client is the first one to request ownership of the call.
+ {
+ CAcquireEntry* entry=NULL;
+ TRAPD(err,entry=CAcquireEntry::NewL(aTsyReqHandle));
+ if(err==KErrNone)
+ iList->iAcquireList.AddLast(*entry);
+ else
+ return err;
+ }
+ else
+ // List is not empty. Another client has already requested to acquire ownership of the call.
+ // Only one client can be waiting to acquire ownership at any one time.
+ return KErrInUse;
+ }
+ return KErrNone;
+ }
+
+TInt CCallHayes::AcquireOwnershipCancel(const TTsyReqHandle aTsyReqHandle)
+//
+// Cancel Acquire call Ownership
+//
+ {
+ CAcquireEntry* entry=iList->FindByTsyReqHandle(aTsyReqHandle);
+ __ASSERT_ALWAYS(entry!=NULL,Panic(EAcquirerNotFound));
+ if (entry != NULL)
+ {
+ iList->Remove(entry);
+ ReqCompleted(aTsyReqHandle, KErrCancel);
+ }
+ else
+ {
+ ReqCompleted(aTsyReqHandle, KErrNotFound);
+ }
+ return KErrNone;
+ }
+
+TInt CCallHayes::GetBearerServiceInfo(const TTsyReqHandle aTsyReqHandle,RCall::TBearerService* aBearerService)
+ {
+ *aBearerService = iCallInfo.iBearerService;
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CCallHayes::GetCallParams(const TTsyReqHandle aTsyReqHandle, TDes8* aParams)
+//
+// Call parameters are only set when connecting a call, so there have no meaning when a
+// call is not in progress.
+//
+ {
+ if (RMobileCall::EStatusIdle != iCallInfo.iMobileStatus &&
+ RMobileCall::EStatusUnknown != iCallInfo.iMobileStatus )
+ {
+ TPckg<RCall::TCallParams>* paramsPckg = (TPckg<RCall::TCallParams>*)aParams;
+ RCall::TCallParams& callparams = (*paramsPckg)();
+
+ //
+ // Configure basic TCallParams parameters
+ callparams.iSpeakerControl = iCallInfo.iSpeakerControl;
+ callparams.iSpeakerVolume = iCallInfo.iSpeakerVolume;
+ callparams.iInterval = iCallInfo.iInterval;
+ callparams.iWaitForDialTone = iCallInfo.iWaitForDialTone;
+
+ //
+ // Configure additional params as required
+ if(callparams.ExtensionId()==RMobileCall::KETelMobileCallParamsV1)
+ {
+ //
+ // Configure RMobileCall::TMobileCallParamsV1 parameters
+ RMobileCall::TMobileCallParamsV1Pckg* pckg = (RMobileCall::TMobileCallParamsV1Pckg*)aParams;
+ RMobileCall::TMobileCallParamsV1& params = (*pckg)();
+ params.iIdRestrict=iCallInfo.iCallParams.iIdRestrict;
+ params.iCug=iCallInfo.iCallParams.iCug;
+ params.iAutoRedial=iCallInfo.iCallParams.iAutoRedial;
+ }
+ else if(callparams.ExtensionId()==RMobileCall::KETelMobileDataCallParamsV1)
+ {
+ //
+ // Configure RMobileCall::TMobileDataCallParamsV1 parameters
+ RMobileCall::TMobileDataCallParamsV1Pckg* pckg = (RMobileCall::TMobileDataCallParamsV1Pckg*)aParams;
+ RMobileCall::TMobileDataCallParamsV1& params = (*pckg)();
+ params.iService=iCallInfo.iCallParams.iService;
+ params.iSpeed=iCallInfo.iCallParams.iSpeed;
+ params.iProtocol=iCallInfo.iCallParams.iProtocol;
+ params.iQoS=iCallInfo.iCallParams.iQoS;
+ params.iRLPVersion=iCallInfo.iCallParams.iRLPVersion;
+ params.iModemToMSWindowSize=iCallInfo.iCallParams.iModemToMSWindowSize;
+ params.iMSToModemWindowSize=iCallInfo.iCallParams.iMSToModemWindowSize;
+ params.iAckTimer=iCallInfo.iCallParams.iAckTimer;
+ params.iRetransmissionAttempts=iCallInfo.iCallParams.iRetransmissionAttempts;
+ params.iResequencingPeriod=iCallInfo.iCallParams.iResequencingPeriod;
+ params.iV42bisReq=iCallInfo.iCallParams.iV42bisReq;
+ params.iV42bisCodewordsNum=iCallInfo.iCallParams.iV42bisCodewordsNum;
+ params.iV42bisMaxStringLength=iCallInfo.iCallParams.iV42bisMaxStringLength;
+ }
+ else if(callparams.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1)
+ {
+ //
+ // Configure RMobileCall::TMobileHscsdCallParamsV1 parameters
+ RMobileCall::TMobileHscsdCallParamsV1Pckg* pckg = (RMobileCall::TMobileHscsdCallParamsV1Pckg*)aParams;
+ RMobileCall::TMobileHscsdCallParamsV1& params = (*pckg)();
+ params.iWantedAiur=iCallInfo.iCallParams.iWantedAiur;
+ params.iWantedRxTimeSlots=iCallInfo.iCallParams.iWantedRxTimeSlots;
+ params.iMaxTimeSlots=iCallInfo.iCallParams.iMaxTimeSlots;
+ params.iCodings=iCallInfo.iCallParams.iCodings;
+ params.iAsymmetry=iCallInfo.iCallParams.iAsymmetry;
+ params.iUserInitUpgrade=iCallInfo.iCallParams.iUserInitUpgrade;
+ }
+
+ //
+ // Complete the clients request
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ }
+ else
+ {
+ ReqCompleted(aTsyReqHandle,KErrUnknown);
+ }
+ return KErrNone;
+ }
+
+TInt CCallHayes::GetCallDuration(const TTsyReqHandle aTsyReqHandle, TTimeIntervalSeconds* aTime)
+ {
+ if ( RMobileCall::EStatusConnected != iCallInfo.iMobileStatus &&
+ RMobileCall::EStatusDisconnecting != iCallInfo.iMobileStatus)
+ {
+ ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive);
+ return KErrNone;
+ }
+ *aTime = iCallTimer->CallDuration();
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+void CCallHayes::GetCallDuration(TTimeIntervalSeconds& aTime) const
+ {
+ aTime = iCallTimer->CallDuration();
+ }
+
+void CCallHayes::GetDefaultCallParams()
+ {
+ iPhoneGlobals->iConfiguration->GetIntervalPref(iCallInfo.iInterval);
+ iPhoneGlobals->iConfiguration->GetSpeakerSettingPref(iCallInfo.iSpeakerControl);
+ iPhoneGlobals->iConfiguration->GetSpeakerVolumePref(iCallInfo.iSpeakerVolume);
+ iPhoneGlobals->iConfiguration->GetWaitForDialTonePref(iCallInfo.iWaitForDialTone);
+ }
+
+void CCallHayes::SetCallParams(const TDesC8* aParams)
+ {
+ if ((*aParams).Length()==0)
+ // Always returns KErrNone
+ GetDefaultCallParams();
+ else
+ {
+ TPckg<RCall::TCallParams>* paramsPckg = (TPckg<RCall::TCallParams>*)aParams;
+ RCall::TCallParams& callparams = (*paramsPckg)();
+ iCallInfo.iSpeakerControl = callparams.iSpeakerControl;
+ iCallInfo.iSpeakerVolume = callparams.iSpeakerVolume;
+ iCallInfo.iInterval = callparams.iInterval;
+ iCallInfo.iWaitForDialTone = callparams.iWaitForDialTone;
+ }
+ }
+
+TInt CCallHayes::ValidateRequest(const TTsyReqHandle aTsyReqHandle, RCall::TStatus aLineStatus)
+//
+// Validating a request
+//
+ {
+ CCallBase::TCallOwnership owned = CheckOwnership(aTsyReqHandle);
+ if (owned==CCallBase::EOwnedFalse) // call owned by another client
+ {
+ return KErrEtelNotCallOwner;
+ }
+ if (iPhoneGlobals->iPhoneStatus.iLineStatus != aLineStatus)
+ {
+ if (aLineStatus==RCall::EStatusIdle)
+ // implies that this call is already active (assuming an owned call is
+ // an active call) or ringing or unknown
+ {
+ return KErrInUse;
+ }
+ else if (aLineStatus==RCall::EStatusRinging)
+ {
+ return KErrNotReady;
+ }
+ }
+ return KErrNone;
+ }
+
+
+RCall::TStatus CCallHayes::GetCoreCallStatus()
+ {
+ RCall::TStatus coreStatus;
+ if (iCallInfo.iMobileStatus <= RMobileCall::EStatusDisconnecting)
+ //coreStatus = static_cast<RCall::TStatus>(iCallInfo.iMobileStatus);
+ coreStatus = (RCall::TStatus)iCallInfo.iMobileStatus;
+ else
+ switch (iCallInfo.iMobileStatus)
+ {
+ case RMobileCall::EStatusReconnectPending:
+ case RMobileCall::EStatusHold:
+ coreStatus = RCall::EStatusConnected;
+ break;
+ case RMobileCall::EStatusWaitingAlternatingCallSwitch:
+ coreStatus = RCall::EStatusIdle;
+ break;
+ default:
+ coreStatus = RCall::EStatusUnknown;
+ break;
+ }
+ return coreStatus;
+ }
+
+TInt CCallHayes::ChangeCallStatus(RMobileCall::TMobileCallStatus aCallStatus)
+ {
+ if (iCallInfo.iMobileStatus != aCallStatus)
+ {
+ iCallInfo.iMobileStatus = aCallStatus;
+
+ if (aCallStatus == RMobileCall::EStatusIdle)
+ {
+ iCallInfo.iHookStatus = RCall::EHookStatusOn;
+ iPhoneGlobals->iNotificationStore->CheckNotification(this,EBecomeIdle);
+ }
+ else if (aCallStatus != RMobileCall::EStatusUnknown && aCallStatus != RMobileCall::EStatusRinging)
+ {
+ iCallInfo.iHookStatus = RCall::EHookStatusOff;
+ }
+ if (aCallStatus == RMobileCall::EStatusConnected)
+ {
+ iPhoneGlobals->iNotificationStore->CheckNotification(this,EConnected);
+ iIo->Cancel();
+ TCommConfig aConfigPckg;
+ TInt ret = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeConnect);
+ if (ret==KErrNone)
+ ret = iIo->ConfigurePort(aConfigPckg);
+// if (!(iIo->ReadPending()))
+// iIo->Read();
+ iCallInfo.iTimeCallBegan.UniversalTime();
+ return ret;
+ }
+ }
+ return KErrNone;
+ }
+
+void CCallHayes::ChangeLineStatus(RCall::TStatus aLineStatus)
+ {
+ iPhoneGlobals->iPhoneStatus.iLineStatus = aLineStatus;
+ }
+
+void CCallHayes::SetToIdle()
+ {
+ iWaitForNoCarrier->StopWait();
+ // Always returns KErrNone
+ (void)SetUnowned();
+ iPhoneGlobals->iPhoneStatus.iMode = RPhone::EModeIdle;
+ ChangeLineStatus(RCall::EStatusIdle); // line status should be changed first because
+ // ChangeCallStatus is the function which sends
+ // the new event to the Notification Handler,
+ // and this will complete both line and call status
+ // notifications, taking the new statuses from the
+ // CLineHayes and CCallHayes objects.
+ // EStatusIdle always results in KErrNone return value
+ (void)ChangeCallStatus(RMobileCall::EStatusIdle);
+ StopCallTicker();
+ }
+
+void CCallHayes::SetToIdleAndCompleteReq(TTsyReqHandle aTsyReqHandle,TInt aStatus)
+ {
+ SetToIdle();
+ ReqCompleted(aTsyReqHandle, aStatus);
+ }
+
+void CCallHayes::GetCallInfo(TCallInfoIndex* aCallInfoIndex)
+//
+// Copied field by field since TCallInfoTSY is different to TCallInfoIndex
+//
+ {
+ aCallInfoIndex->iInfo.iCallName = iCallInfo.iCallName;
+ aCallInfoIndex->iInfo.iStatus = GetCoreCallStatus();
+ aCallInfoIndex->iInfo.iCallCapsFlags = 0;
+ }
+
+TBool CCallHayes::CheckName(const TDesC& aName) const
+//
+// Return TRUE if name is the same as the name of this call
+ {
+ if (iCallInfo.iCallName.CompareF(aName))
+ return EFalse;
+ else
+ return ETrue;
+ }
+
+TCallInfoTSY* CCallHayes::CallInfo()
+ {
+ return &iCallInfo;
+ }
+
+void CCallHayes::StartCallTicker() const
+ {
+ iCallTimer->Start();
+ }
+
+void CCallHayes::StopCallTicker() const
+ {
+ iCallTimer->Stop();
+ }
+
+void CCallHayes::ResetIsForIncomingCall()
+ {
+ iIsForIncomingCall=EFalse;
+ }
+
+TBool CCallHayes::IsForIncomingCall() const
+ {
+ return iIsForIncomingCall;
+ }
+
+void CCallHayes::SetOwnedByTSY()
+ {
+ iIsOwnedByTSY=ETrue;
+ }
+
+void CCallHayes::SetUnownedByTSY()
+ {
+ iIsOwnedByTSY=EFalse;
+ }
+
+TBool CCallHayes::IsOwnedByTSY() const
+ {
+ return iIsOwnedByTSY;
+ }
+
+
+//
+// Functions which are supported in one line but not the other
+//
+TInt CCallHayes::LoanDataPort(const TTsyReqHandle,RCall::TCommPort*)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CCallHayes::LoanDataPortCancel(const TTsyReqHandle)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CCallHayes::RecoverDataPort(const TTsyReqHandle)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CCallHayes::RecoverDataPortAndRelinquishOwnership()
+ {
+ return KErrNotSupported;
+ }
+
+TInt CCallHayes::GetFaxSettings(const TTsyReqHandle,RCall::TFaxSessionSettings*)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CCallHayes::SetFaxSettings(const TTsyReqHandle,const RCall::TFaxSessionSettings*)
+ {
+ return KErrNotSupported;
+ }
+
+CTelObject* CCallHayes::OpenNewObjectByNameL(const TDesC& /*aName*/)
+ {
+ User::Leave(KErrNotSupported);
+ return NULL;
+ }
+
+CTelObject* CCallHayes::OpenNewObjectL(TDes& /*aNewName*/)
+ {
+ User::Leave(KErrNotSupported);
+ return NULL;
+ }
+
+TInt CCallHayes::CheckAndSetRegistrationParams(const TInt /*aIpc*/,const TDes8* /*aDes1*/,const TDes8* /*aDes2*/)
+ {
+ return KErrNone;
+ }
+
+TInt CCallHayes::ExtFunc(const TTsyReqHandle,const TInt, const TDataPackage&)
+//
+// Unsupported in this TSY
+//
+ {
+ return KErrNotSupported;
+ }
+
+/*
+ * CCallMobile class that implements Multimode ETel Mobile Call requests
+ */
+
+CCallMobile::CCallMobile(CATIO* aIo,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+ : CCallHayes(aIo, aInit, aPhoneGlobals)
+ {
+ }
+
+CCallMobile::~CCallMobile()
+ {
+ }
+
+CTelObject::TReqMode CCallMobile::ReqModeL(const TInt aIpc)
+ {
+ // ReqModeL is called from the server's CTelObject::ReqAnalyserL
+ // in order to check the type of request it has
+
+ CTelObject::TReqMode ret=0;
+ switch (aIpc)
+ {
+//
+// No Flow Control NOR Multiple Completion
+//
+ case EMobileCallGetMobileCallCaps:
+ case EMobileCallGetMobileCallStatus:
+ break;
+
+ case EMobileCallGetMobileDataCallCaps:
+ break;
+//
+// Multiple Completion Services with Immediate Server Repost
+// (Usually Notifications)
+//
+ case EMobileCallNotifyMobileCallStatusChange:
+ case EMobileCallNotifyMobileCallCapsChange:
+
+ ret=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
+ break;
+//
+//
+//
+ default:
+ ret=CCallHayes::ReqModeL(aIpc);
+ break;
+ }
+
+ return ret;
+ }
+
+
+TInt CCallMobile::NumberOfSlotsL(const TInt aIpc)
+ {
+ // NumberOfSlotsL is called by the server when it is registering a new notification
+ // It enables the TSY to tell the server how many buffer slots to allocate for
+ // "repost immediately" notifications that may trigger before clients collect them
+
+ TInt numberOfSlots=1;
+ switch (aIpc)
+ {
+ case EMobileCallNotifyMobileCallStatusChange:
+ case EMobileCallNotifyMobileCallCapsChange:
+ LOGTEXT(_L8("CCallMobile: Registered with 5 slots"));
+ numberOfSlots=5;
+ break;
+ default:
+ numberOfSlots = CCallBase::NumberOfSlotsL(aIpc);
+ break;
+ }
+ return numberOfSlots;
+ }
+
+
+TInt CCallMobile::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc,
+ const TDataPackage& aPackage)
+ {
+ // ExtFunc is called by the server when it has a "extended", i.e. non-core ETel request
+ // for the TSY to process
+ // A request handle, request type and request data are passed to the TSY
+
+ TAny* dataPtr=aPackage.Ptr1();
+
+ // The request data has to extracted from TDataPackage and the TAny* pointers have to
+ // be "cast" to the expected request data type
+
+ switch (aIpc)
+ {
+//
+// No Flow Control NOR Multiple Completion
+//
+ case EMobileCallGetMobileCallCaps:
+ return GetMobileCallCaps(aTsyReqHandle, aPackage.Des1n());
+
+ case EMobileCallGetMobileCallStatus:
+ return GetMobileCallStatus(aTsyReqHandle,
+ REINTERPRET_CAST(RMobileCall::TMobileCallStatus*,dataPtr));
+//
+// Multiple Completion Services with Immediate Server Repost
+// (Usually Notifications)
+//
+ case EMobileCallNotifyMobileCallStatusChange:
+ return NotifyMobileCallStatusChange(aTsyReqHandle,
+ REINTERPRET_CAST(RMobileCall::TMobileCallStatus*, dataPtr));
+
+ case EMobileCallNotifyMobileCallCapsChange:
+ return NotifyMobileCallCapsChange(aTsyReqHandle, aPackage.Des1n());
+
+//
+// Cancels
+//
+ case EMobileCallNotifyMobileCallStatusChangeCancel:
+ return NotifyMobileCallStatusChangeCancel(aTsyReqHandle);
+
+ case EMobileCallNotifyMobileCallCapsChangeCancel:
+ return NotifyMobileCallCapsChangeCancel(aTsyReqHandle);
+
+ default:
+ return KErrNotSupported;
+ }
+ }
+
+TInt CCallMobile::CancelService(const TInt aIpc, const TTsyReqHandle aTsyReqHandle)
+ {
+ // CancelService is called by the server when it is "cleaning-up" any still outstanding
+ // asynchronous requests before closing a client's sub-session.
+ // This will happen if a client closes its R-class handle without cancelling outstanding
+ // asynchronous requests.
+
+ switch (aIpc)
+ {
+ case EMobileCallNotifyMobileCallStatusChange:
+ return NotifyMobileCallStatusChangeCancel(aTsyReqHandle);
+ case EMobileCallNotifyMobileCallCapsChange:
+ return NotifyMobileCallCapsChangeCancel(aTsyReqHandle);
+ default:
+ return CCallBase::CancelService(aIpc,aTsyReqHandle);
+ }
+ }
+
+TInt CCallMobile::GetMobileCallCaps(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
+ {
+ LOGTEXT(_L8("CCallMobile: :GetMobileCallCaps called"));
+
+ RMobileCall::TMobileCallCapsV1Pckg *capsPckg = REINTERPRET_CAST(RMobileCall::TMobileCallCapsV1Pckg *,aCaps);
+ RMobileCall::TMobileCallCapsV1& caps = (*capsPckg)();
+ // Always returns KErrNone
+ (void)CollateCurrentMobileCaps(aTsyReqHandle, &caps.iCallControlCaps);
+ caps.iCallEventCaps=0; // no call events are supported
+
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CCallMobile::GetCaps(const TTsyReqHandle aTsyReqHandle,RCall::TCaps* aCallCaps)
+ {
+ (void)CollateCurrentCoreCaps(aTsyReqHandle, reinterpret_cast<TUint32*>(&aCallCaps->iFlags));
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TBool CCallMobile::CollateCurrentMobileCaps(const TTsyReqHandle aTsyReqHandle, TUint32* aCallCaps)
+ {
+ CollateCoreCaps(aTsyReqHandle, aCallCaps);
+ if (iMobileCaps.iCallControlCaps != *aCallCaps)
+ {
+ iMobileCaps.iCallControlCaps = *aCallCaps;
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+TBool CCallMobile::CollateCurrentCoreCaps(const TTsyReqHandle aTsyReqHandle, TUint32* aCallCaps)
+ {
+ CollateCoreCaps(aTsyReqHandle, aCallCaps);
+ if (iCaps.iFlags != *aCallCaps)
+ {
+ iCaps.iFlags = *aCallCaps;
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+TInt CCallMobile::NotifyMobileCallCapsChange(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
+ {
+ LOGTEXT(_L8("CCallMobile::NotifyMobileCallCapsChange lodged"));
+ iPhoneGlobals->iNotificationStore->RegisterNotification(ECallMobileCaps,aTsyReqHandle,this,aCaps);
+ return KErrNone;
+ }
+
+TInt CCallMobile::NotifyMobileCallCapsChangeCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGTEXT(_L8("CCallMobile::NotifyMobileCallCapsChangeCancel called"));
+ iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
+ return KErrNone;
+ }
+
+TInt CCallMobile::GetMobileCallStatus(const TTsyReqHandle aTsyReqHandle,RMobileCall::TMobileCallStatus* aStatus)
+ {
+ LOGTEXT(_L8("CCallMobile::GetMobileCallStatus called"));
+ *aStatus=iCallInfo.iMobileStatus;
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+TInt CCallMobile::NotifyMobileCallStatusChange(const TTsyReqHandle aTsyReqHandle,RMobileCall::TMobileCallStatus* aStatus)
+ {
+ LOGTEXT(_L8("CCallMobile::NotifyMobileCallStatusChange lodged"));
+ iPhoneGlobals->iNotificationStore->RegisterNotification(EMobileCallStatusChange,aTsyReqHandle,this,aStatus);
+ return KErrNone;
+ }
+
+TInt CCallMobile::NotifyMobileCallStatusChangeCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGTEXT(_L8("CCallMobile::NotifyMobileCallStatusChangeCancel called"));
+ iPhoneGlobals->iNotificationStore->RemoveNotification(aTsyReqHandle);
+ return KErrNone;
+ }
+
+//
+// CCallMobileVoice - Voice Specific Call Functionality
+//
+
+CCallMobileVoice* CCallMobileVoice::NewL(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals,const TName& aName)
+ {
+ CCallMobileVoice* voiceCall=new(ELeave) CCallMobileVoice(aATIO,aInit,aPhoneGlobals);
+ TCleanupItem newCallVoiceHayesClose(CloseCall,voiceCall);
+ CleanupStack::PushL(newCallVoiceHayesClose);
+ voiceCall->ConstructL(aName);
+ CleanupStack::Pop();
+ return voiceCall;
+ }
+
+CCallMobileVoice::CCallMobileVoice(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+ : CCallMobile(aATIO,aInit,aPhoneGlobals)
+ {}
+
+void CCallMobileVoice::ConstructL(const TName& aName)
+ {
+ CCallHayes::ConstructL(aName);
+ iCallInfo.iLineOwnerName = KVoiceLineName;
+ iDialVoice=CATDialVoice::NewL(iIo,this,iInit,iPhoneGlobals);
+ iAnswerVoice=CATAnswerVoice::NewL(iIo,this,iInit,iPhoneGlobals);
+ iHangUpVoice=CATHangUpVoice::NewL(iIo,this,iInit,iPhoneGlobals);
+ }
+
+CCallMobileVoice::~CCallMobileVoice()
+//
+// Removes itself from array of calls in CLineMobileVoice
+//
+ {
+ delete iDialVoice;
+ delete iAnswerVoice;
+ delete iHangUpVoice;
+ }
+
+void CCallMobileVoice::CollateCoreCaps(const TTsyReqHandle /*aTsyReqHandle*/, TUint32* aCallCaps)
+ {
+ *aCallCaps = RCall::KCapsVoice;
+
+ // Voice calls can be manipulated by any client, not just owner so set as many caps as possible
+ if (iPhoneGlobals->iPhoneStatus.iModemDetected==RPhone::EDetectedPresent)
+ {
+ *aCallCaps |= (RCall::KCapsDial | RCall::KCapsConnect);
+
+ TInt ret=KErrNone;
+ if (!iIsForIncomingCall)
+ {
+ if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer())
+ ret=KErrEtelAnswerAlreadyOutstanding;
+ }
+ else
+ ret=KErrEtelAnswerAlreadyOutstanding;
+
+ if (ret==KErrNone && (iCallInfo.iMobileStatus==RMobileCall::EStatusIdle || iCallInfo.iMobileStatus==RMobileCall::EStatusRinging))
+ *aCallCaps |= RCall::KCapsAnswer;
+
+ if (iCallInfo.iMobileStatus==RMobileCall::EStatusConnected)
+ *aCallCaps |= RCall::KCapsHangUp;
+ }
+ }
+
+TInt CCallMobileVoice::Dial(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams,TDesC* aTelNumber)
+//
+// Dial a voice call
+//
+ {
+ SetCallParams(aCallParams);
+ LOGTEXT(_L8("VoiceCall:\tSubmitting Dial command for Voice call"));
+ if (iPhoneGlobals->iPhoneStatus.iLineStatus == RCall::EStatusIdle)
+ {
+ (void)SetOwnership(aTsyReqHandle);
+ iDialVoice->ExecuteCommand(aTsyReqHandle,aTelNumber,&iCallInfo);
+ return KErrNone;
+ }
+ else
+ {
+ return KErrInUse;
+ }
+ }
+
+TInt CCallMobileVoice::DialCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+ * Cancel the dial request if possible
+ */
+ {
+ LOGTEXT(_L8("VoiceCall:\tSubmitting Cancel Dial command for Voice call"));
+ iDialVoice->CancelCommand(aTsyReqHandle);
+ return KErrNone;
+ }
+
+TInt CCallMobileVoice::AnswerIncomingCall(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams)
+/**
+ * If there is no waiting call, will wait for one and then answer it. If there is, it will
+ * answer immediately.
+ */
+ {
+ CCallBase::TCallOwnership owned = CheckOwnership(aTsyReqHandle);
+ TInt ret=KErrNone;
+ if (owned==CCallBase::EOwnedFalse) // call owned by another client
+ {
+ ret=KErrEtelNotCallOwner;
+ }
+ else
+ {
+ if (!iIsForIncomingCall)
+ {
+ if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer())
+ ret=KErrEtelAnswerAlreadyOutstanding;
+ }
+ else
+ ret=KErrEtelAnswerAlreadyOutstanding;
+ }
+ if (ret==KErrNone)
+ {
+ CLineHayes* line = STATIC_CAST(CLineHayes*,Owner());
+ STATIC_CAST(CPhoneHayes*,line->Owner())->CancelOtherRingingCall(line);
+ line->FreePreAllocCallIfNecessary();
+ SetCallParams(aCallParams);
+ if (iCallInfo.iMobileStatus==RMobileCall::EStatusRinging)
+ {
+ (void)SetOwnership(aTsyReqHandle);
+ LOGTEXT(_L8("VoiceCall:\tSubmitting Answer command"));
+ iAnswerVoice->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
+ }
+ else // This call is now a client-designated Incoming Call object.
+ {
+ iIsForIncomingCall=ETrue;
+ iAnswerTsyReqHandle = aTsyReqHandle;
+ }
+ return KErrNone;
+ }
+ ReqCompleted(aTsyReqHandle,ret);
+ return KErrNone;
+ }
+
+
+TInt CCallMobileVoice::AnswerIncomingCallCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGTEXT(_L8("VoiceCall:\tSubmitting Cancel Answer command"));
+ if (iIsForIncomingCall)
+ {
+ iIsForIncomingCall=EFalse;
+ ReqCompleted(aTsyReqHandle,KErrCancel);
+ }
+ else
+ iAnswerVoice->CancelCommand(aTsyReqHandle);
+ return KErrNone;
+ }
+
+void CCallMobileVoice::AnswerImmediately()
+ {
+ (void)SetOwnership(iAnswerTsyReqHandle);
+ // EStatusRinging always results in KErrNone return value
+ (void) ChangeCallStatus(RMobileCall::EStatusRinging);
+ iPhoneGlobals->iNotificationStore->CheckNotification(this,ERingOccurred);
+ iIsForIncomingCall=EFalse;
+ // this must be after the check notification as CNotifications
+ // asks line for info about the call which Is For Incoming Call
+ LOGTEXT(_L8("VoiceCall:\tSubmitting Answer command"));
+ iAnswerVoice->ExecuteCommand(iAnswerTsyReqHandle,NULL,&iCallInfo);
+ }
+
+TInt CCallMobileVoice::Connect(const TTsyReqHandle aTsyReqHandle,const TDesC8* /*aCallParams*/)
+ {
+ ReqCompleted(aTsyReqHandle,KErrNotSupported);
+ return KErrNone;
+ }
+
+TInt CCallMobileVoice::ConnectCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ ReqCompleted(aTsyReqHandle,KErrNotSupported);
+ return KErrNone;
+ }
+
+TInt CCallMobileVoice::HangUp(const TTsyReqHandle aTsyReqHandle)
+ {
+ if (CheckOwnership(aTsyReqHandle)==CCallBase::EOwnedFalse)
+ {
+ ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner);
+ return KErrNone;
+ }
+ if ((iCallInfo.iMobileStatus!=RMobileCall::EStatusIdle) &&
+ (iCallInfo.iMobileStatus!=RMobileCall::EStatusDisconnecting))
+ {
+ LOGTEXT(_L8("VoiceCall:\tSubmitting Hang Up command"));
+ iHangUpVoice->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
+ return KErrNone;
+ }
+ else
+ {
+ // Call not in a state to be terminated - but return KErrNone
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+ }
+
+TInt CCallMobileVoice::HangUpCancel(const TTsyReqHandle aTsyReqHandle)
+//
+// Cancel the hang up command.
+//
+ {
+ LOGTEXT(_L8("VoiceCall:\tSubmitting Cancel Hang Up command"));
+ iHangUpVoice->Stop(aTsyReqHandle);
+ return KErrNone;
+ }
+
+TInt CCallMobileVoice::RelinquishOwnership()
+ {
+//
+// Called by server to tell TSY to either pass ownership on to another interested client
+// or hang up immediately. If call is currently connecting, RelinquishOwnershipComplete
+// will be called once cancelling has finished.
+//
+ LOGTEXT(_L8("VoiceCall:\tRelinquish Ownership"));
+ if(iList->iAcquireList.IsEmpty())
+ {
+ if (iDialVoice->IsPreConnectInProgress())
+ {
+ iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
+ return KErrNone;
+ }
+ switch(iCallInfo.iMobileStatus)
+ {
+ case RMobileCall::EStatusConnected:
+ iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
+ iHangUpVoice->ExecuteCommand(0, NULL, &iCallInfo);
+ break;
+ case RMobileCall::EStatusDialling:
+ case RMobileCall::EStatusConnecting:
+ case RMobileCall::EStatusAnswering:
+ case RMobileCall::EStatusDisconnecting:
+ iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
+ break;
+ default:
+ if (iPhoneGlobals->iPhoneStatus.iInitStatus==EPhoneInitialising)
+ iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
+ else
+ RelinquishOwnershipCompleted(KErrNone);
+ break;
+ }
+ return KErrNone;
+ }
+ CAcquireEntry* entry=iList->iAcquireList.First();
+ if (entry)
+ {
+ (void)SetOwnership(entry->iTsyReqHandle);
+ ReqCompleted(entry->iTsyReqHandle,KErrNone);
+ iList->Remove(entry);
+ }
+ RelinquishOwnershipCompleted(KErrNone);
+ return KErrNone;
+ }
+
+TInt CCallMobileVoice::RecoverDataPortAndRelinquishOwnership()
+ {
+ RecoverDataPortAndRelinquishOwnershipCompleted(KErrNotSupported);
+ return KErrNone;
+ }
+
+TInt CCallMobileVoice::LoanDataPort(const TTsyReqHandle aTsyReqHandle, RCall::TCommPort* /* aCommPort*/)
+ {
+ ReqCompleted(aTsyReqHandle,KErrNotSupported);
+ return KErrNone;
+ }
+
+TInt CCallMobileVoice::LoanDataPortCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ ReqCompleted(aTsyReqHandle,KErrNotSupported);
+ return KErrNone;
+ }
+
+TInt CCallMobileVoice::RecoverDataPort(const TTsyReqHandle aTsyReqHandle)
+ {
+ ReqCompleted(aTsyReqHandle,KErrNotSupported);
+ return KErrNone;
+ }
+
+
+//
+//
+// CCallMobileData - Data Specific Call Functionality
+//
+//
+
+CCallMobileData* CCallMobileData::NewL(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals,const TName& aName)
+ {
+ CCallMobileData* dataCall=new(ELeave) CCallMobileData(aATIO,aInit,aPhoneGlobals);
+ TCleanupItem newCallDataHayesClose(CloseCall,dataCall);
+ CleanupStack::PushL(newCallDataHayesClose);
+ dataCall->ConstructL(aName);
+ CleanupStack::Pop();
+ return dataCall;
+ }
+
+CCallMobileData::CCallMobileData(CATIO* aATIO,CATInit* aInit,CPhoneGlobals* aPhoneGlobals)
+ : CCallMobile(aATIO,aInit,aPhoneGlobals)
+ {}
+
+void CCallMobileData::ConstructL(const TName& aName)
+ {
+ CCallHayes::ConstructL(aName);
+ iCallInfo.iLineOwnerName = KDataLineName;
+ iDialData=CATDialData::NewL(iIo,this,iInit,iPhoneGlobals);
+ iAnswerData=CATAnswerData::NewL(iIo,this,iInit,iPhoneGlobals);
+ iSetCBST=CATSetCBST::NewL(iIo,this,iInit,iPhoneGlobals);
+ iConnectData=CATConnectData::NewL(iIo,this,iInit,iPhoneGlobals);
+ iHangUpData=CATHangUpData::NewL(iIo,this,iInit,iPhoneGlobals);
+ iATSetToOnlineDataMode=CATSetToOnlineDataMode::NewL(iIo,this,iInit,iPhoneGlobals);
+ }
+
+CCallMobileData::~CCallMobileData()
+//
+// Removes itself from array of calls in CLineMobileData
+//
+ {
+ delete iDialData;
+ delete iSetCBST;
+ delete iAnswerData;
+ delete iConnectData;
+ delete iHangUpData;
+ delete iATSetToOnlineDataMode;
+ }
+
+TInt CCallMobileData::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc,
+ const TDataPackage& aPackage)
+/**
+ * Process the IPC locally, otherwise delegate to our base class.
+ */
+ {
+ switch (aIpc)
+ {
+ case EMobileCallGetMobileDataCallCaps:
+ return GetMobileDataCallCaps(aTsyReqHandle, aPackage.Des1n());
+ default:
+ // Delegate the processing of the IPC to our base class
+ return CCallMobile::ExtFunc(aTsyReqHandle,aIpc,aPackage);
+ }
+ }
+
+
+TInt CCallMobileData::GetMobileDataCallCaps(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
+ {
+ LOGTEXT(_L8("CCallMobileData::GetMobileDataCallCaps called"));
+
+ //
+ // This is a synchronous client request so this method must complete quickly.
+ // The call caps returned are those which were discovered during the
+ // intialisation of the TSY (see ATINIT.CPP).
+ TPckg<RMobileCall::TMobileCallDataCapsV1>* pckg = (TPckg<RMobileCall::TMobileCallDataCapsV1>*)aCaps;
+ RMobileCall::TMobileCallDataCapsV1& caps = (*pckg)();
+ caps=iPhoneGlobals->iCallDataCaps;
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+
+void CCallMobileData::CollateCoreCaps(const TTsyReqHandle aTsyReqHandle, TUint32* aCallCaps)
+ {
+ *aCallCaps = RCall::KCapsData;
+ if (iPhoneGlobals->iPhoneStatus.iModemDetected==RPhone::EDetectedPresent)
+ {
+ CCallBase::TCallOwnership owner = CheckOwnership(aTsyReqHandle);
+ if (ValidateRequest(aTsyReqHandle,RCall::EStatusIdle)==KErrNone)
+ *aCallCaps |= (RCall::KCapsDial | RCall::KCapsConnect);
+ TInt ret=KErrNone;
+ if (owner==CCallBase::EOwnedFalse) // call owned by another client
+ ret=KErrEtelNotCallOwner;
+ else
+ {
+ if (!iIsForIncomingCall)
+ {
+ if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer())
+ ret=KErrEtelAnswerAlreadyOutstanding;
+ }
+ else
+ ret=KErrEtelAnswerAlreadyOutstanding;
+ }
+ if (ret==KErrNone && (iCallInfo.iMobileStatus==RMobileCall::EStatusIdle || iCallInfo.iMobileStatus==RMobileCall::EStatusRinging))
+ *aCallCaps |= RCall::KCapsAnswer;
+ if ((owner==CCallBase::EOwnedTrue || owner==CCallBase::EOwnedPriorityClient)
+ && iCallInfo.iMobileStatus==RMobileCall::EStatusConnected)
+ {
+ *aCallCaps |= RCall::KCapsHangUp;
+ if (iCallInfo.iLoanedToClient==EFalse)
+ *aCallCaps |= RCall::KCapsLoanDataPort;
+ else
+ *aCallCaps |= RCall::KCapsRecoverDataPort;
+ }
+ }
+ }
+
+TInt CCallMobileData::AssembleCBSTSetString(TBuf8<KGenericBufferSize>& aTxBuffer)
+/**
+ * This funciton assembles a +CBST= string ready to be sent to the modem using
+ * the values from CCallHayes::iCallInfo.
+ * This utility funciton is used by objects created and owned by this class.
+ * This has been done to reduce code size.
+ * @return KErrNone if and only if CBST string assembled
+ */
+ {
+ TInt ret(KErrNone); // Return value of this function
+
+ TInt speed(0); // these are the names that etsi use
+ TInt name(0); // these are the names that etsi use
+ TInt ce(0); // these are the names that etsi use
+ TBool speedSet(ETrue);
+ TBool nameSet(ETrue);
+ TBool ceSet(ETrue);
+
+ switch (iCallInfo.iCallParams.iService)
+ {
+ case RMobileCall::EServiceDataCircuitAsync:
+ name = 0;
+ break;
+ case RMobileCall::EServiceDataCircuitAsyncRdi:
+ name = 4;
+ break;
+ case RMobileCall::EServiceDataCircuitSync:
+ name = 1;
+ break;
+ case RMobileCall::EServiceDataCircuitSyncRdi:
+ name = 5;
+ break;
+ case RMobileCall::EServicePADAsyncUDI:
+ name = 2;
+ break;
+ case RMobileCall::EServicePADAsyncRDI:
+ name = 6;
+ break;
+ case RMobileCall::EServicePacketAccessSyncUDI:
+ name = 3;
+ break;
+ case RMobileCall::EServicePacketAccessSyncRDI:
+ name = 7;
+ break;
+ case RMobileCall::EServiceUnspecified: // taking the default value of 0
+ default:
+ nameSet=EFalse;
+ break;
+ }
+
+ switch(iCallInfo.iCallParams.iQoS)
+ {
+ case RMobileCall::EQoSTransparent:
+ ce = 0;
+ break;
+ case RMobileCall::EQosTransparentPreferred:
+ ce = 2;
+ break;
+ case RMobileCall::EQoSNonTransparent:
+ ce = 1;
+ break;
+ case RMobileCall::EQosNonTransparentPreferred:
+ ce = 3;
+ break;
+ case RMobileCall::EQoSUnspecified:
+ default:
+ ceSet=EFalse;
+ break;
+ }
+
+ switch(iCallInfo.iCallParams.iSpeed)
+ {
+ case RMobileCall::ESpeedAutobauding:
+ speed = 0;
+ break;
+
+ case RMobileCall::ESpeed2400:
+ {
+ if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV22bis)
+ speed = 4;
+ else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
+ speed = 36;
+ else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
+ (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
+ speed = 68;
+ else
+ speedSet=EFalse;
+ break;
+ }
+ case RMobileCall::ESpeed4800:
+ {
+ if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV32)
+ speed = 6;
+ else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
+ speed = 38;
+ else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
+ (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
+ speed = 70;
+ else
+ speedSet=EFalse;
+ break;
+ }
+ case RMobileCall::ESpeed9600:
+ {
+ if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV32)
+ speed = 7;
+ else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34)
+ speed = 12;
+ else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
+ speed = 39;
+ else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
+ (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
+ speed = 71;
+ else
+ speedSet=EFalse;
+ break;
+ }
+ case RMobileCall::ESpeed14400:
+ {
+ if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34)
+ speed = 14;
+ else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
+ speed = 43;
+ else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
+ (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
+ speed = 75;
+ else
+ speedSet=EFalse;
+ break;
+ }
+ case RMobileCall::ESpeed19200:
+ {
+ if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34)
+ speed = 15;
+ else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
+ speed = 47;
+ else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
+ (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
+ speed = 79;
+ else
+ speedSet=EFalse;
+ break;
+ }
+ case RMobileCall::ESpeed28800:
+ {
+ if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV34)
+ speed = 16;
+ else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
+ speed = 48;
+ else if ((iCallInfo.iCallParams.iProtocol ==RMobileCall:: EProtocolV110) ||
+ (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
+ speed = 80;
+ else
+ speedSet=EFalse;
+ break;
+ }
+ case RMobileCall::ESpeed38400:
+ {
+ if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
+ (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
+ speed = 81;
+ else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
+ speed = 49;
+ else
+ speedSet=EFalse;
+ break;
+ }
+ case RMobileCall::ESpeed48000:
+ if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
+ speed = 50;
+ else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
+ (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
+ speed = 82;
+ else
+ speedSet=EFalse;
+ break;
+ case RMobileCall::ESpeed56000:
+ if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV120)
+ speed = 51;
+ else if ((iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolV110) ||
+ (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolX31FlagStuffing))
+ speed = 83;
+ else if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolBitTransparent)
+ speed = 115;
+ else
+ speedSet=EFalse;
+ break;
+ case RMobileCall::ESpeed64000:
+ if (iCallInfo.iCallParams.iProtocol == RMobileCall::EProtocolBitTransparent)
+ speed = 116;
+ else
+ speedSet=EFalse;
+ break;
+
+ case RMobileCall::ESpeed33600: // this baud rate is not currently used in the etsi table
+ case RMobileCall::ESpeedUnspecified:
+ default:
+ speedSet=EFalse;
+ break;
+ }
+
+ //
+ // Try to assemble as much of the +CBST= command as we can.
+ // If we do not have a <speed> value we can not send the command.
+ // If we do not have a <ce> value then we can send a command giving only <speed> and <name>.
+ // etc...
+ if(speedSet)
+ {
+ aTxBuffer.Zero(); // Clear tx buffer
+
+ // Append +CBST= and the <speed> parameter
+ aTxBuffer.Append(KDataCallBearerServiceType);
+ aTxBuffer.AppendNum(speed);
+
+ if(nameSet)
+ {
+ // Append the <name> parameter
+ aTxBuffer.Append(TChar(','));
+ aTxBuffer.AppendNum(name);
+
+ if(ceSet)
+ {
+ // Append the <ce> parameter
+ aTxBuffer.Append(TChar(','));
+ aTxBuffer.AppendNum(ce);
+ }
+ }
+
+ // Append final \r char to AT command
+ aTxBuffer.Append(TChar('\r'));
+ }
+ else
+ {
+ // We have not have enough info to create a +CBST= string
+ ret=KErrArgument;
+ }
+
+ return ret;
+ }
+
+
+
+TInt CCallMobileData::Dial(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams,TDesC* aTelNumber)
+//
+// Dial a data call
+//
+ {
+ TInt ret(KErrNone);
+
+ SetDataCallParams(aCallParams);
+
+ ret=ValidateRequest(aTsyReqHandle,RCall::EStatusIdle);
+ if (ret==KErrNone)
+ {
+ (void)SetOwnership(aTsyReqHandle);
+ LOGTEXT(_L8("DataCall:\tSubmitting Dial command for Data call"));
+ iDialData->ExecuteCommand(aTsyReqHandle,aTelNumber,&iCallInfo);
+ }
+ else
+ ReqCompleted(aTsyReqHandle,ret); // An error occurred
+
+ return KErrNone; // Real return code is returned to client thru request completion
+ }
+
+
+TInt CCallMobileData::DialCancel(const TTsyReqHandle aTsyReqHandle)
+//
+// Cancel the dial request if possible
+//
+ {
+ LOGTEXT(_L8("DataCall:\tSubmitting Cancel Dial command for Data call"));
+ iDialData->CancelCommand(aTsyReqHandle);
+ return KErrNone;
+ }
+
+
+void CCallMobileData::SetDataCallParams(const TDesC8* aCallParams)
+/**
+ * Utility function which unpacks the call parameters supplied by the client
+ * and saves their values in iPhoneGlobals.
+ * If the client did not supply parameters then default ones are used.
+ */
+ {
+ if(aCallParams->Length()==0)
+ {
+ //
+ // Client did not supply parameters, so we use default ones
+ LOGTEXT(_L8("CCallMobileData::SetDataCallParams Using default parameters"));
+ CCallHayes::SetCallParams(aCallParams);
+
+ //
+ // Ensure the speed parameter is undefined so that we prevent the
+ // +CBST=... command being sent to the phone when dialling a CSD data call.
+ iCallInfo.iCallParams.iService = RMobileCall::EServiceUnspecified;
+ }
+ else
+ {
+ //
+ // Use call parameters that client supplied us
+ LOGTEXT(_L8("CCallMobileData::SetDataCallParams Using clients parameters"));
+ RCall::TCallParamsPckg* paramsPckgV1 = (RCall::TCallParamsPckg*)aCallParams;
+ RCall::TCallParams& paramsV1 = (*paramsPckgV1)();
+
+ CCallHayes::SetCallParams(aCallParams);
+ if (paramsV1.ExtensionId()==RMobileCall::KETelMobileCallParamsV1)
+ {
+ RMobileCall::TMobileCallParamsV1Pckg* mmParamsPckgV1 = (RMobileCall::TMobileCallParamsV1Pckg*)aCallParams;
+ RMobileCall::TMobileCallParamsV1& mmParamsV1 = (*mmParamsPckgV1)();
+ iCallInfo.iCallParams.iIdRestrict = mmParamsV1.iIdRestrict;
+ iCallInfo.iCallParams.iCug = mmParamsV1.iCug;
+ iCallInfo.iCallParams.iAutoRedial = mmParamsV1.iAutoRedial;
+ }
+
+ if((paramsV1.ExtensionId()==RMobileCall::KETelMobileDataCallParamsV1) ||
+ (paramsV1.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1))
+ {
+ RMobileCall::TMobileDataCallParamsV1Pckg* dataParamsPckgV1 = (RMobileCall::TMobileDataCallParamsV1Pckg*)aCallParams;
+ RMobileCall::TMobileDataCallParamsV1& dataParamsV1 = (*dataParamsPckgV1)();
+ iCallInfo.iCallParams.iService=dataParamsV1.iService;
+ iCallInfo.iCallParams.iSpeed=dataParamsV1.iSpeed;
+ iCallInfo.iCallParams.iProtocol=dataParamsV1.iProtocol;
+ iCallInfo.iCallParams.iQoS=dataParamsV1.iQoS;
+ iCallInfo.iCallParams.iRLPVersion=dataParamsV1.iRLPVersion;
+ iCallInfo.iCallParams.iModemToMSWindowSize=dataParamsV1.iModemToMSWindowSize;
+ iCallInfo.iCallParams.iMSToModemWindowSize=dataParamsV1.iMSToModemWindowSize;
+ iCallInfo.iCallParams.iAckTimer=dataParamsV1.iAckTimer;
+ iCallInfo.iCallParams.iRetransmissionAttempts=dataParamsV1.iRetransmissionAttempts;
+ iCallInfo.iCallParams.iResequencingPeriod=dataParamsV1.iResequencingPeriod;
+ iCallInfo.iCallParams.iV42bisReq=dataParamsV1.iV42bisReq;
+ iCallInfo.iCallParams.iV42bisCodewordsNum=dataParamsV1.iV42bisCodewordsNum;
+ iCallInfo.iCallParams.iV42bisMaxStringLength=dataParamsV1.iV42bisMaxStringLength;
+ }
+
+ if (paramsV1.ExtensionId()==RMobileCall::KETelMobileHscsdCallParamsV1)
+ {
+ RMobileCall::TMobileHscsdCallParamsV1Pckg* hscsdParamsPckgV1 = (RMobileCall::TMobileHscsdCallParamsV1Pckg*)aCallParams;
+ RMobileCall::TMobileHscsdCallParamsV1& hscsdParamsV1 = (*hscsdParamsPckgV1)();
+ iCallInfo.iCallParams.iWantedAiur = hscsdParamsV1.iWantedAiur;
+ iCallInfo.iCallParams.iWantedRxTimeSlots = hscsdParamsV1.iWantedRxTimeSlots;
+ iCallInfo.iCallParams.iMaxTimeSlots = hscsdParamsV1.iMaxTimeSlots;
+ iCallInfo.iCallParams.iCodings = hscsdParamsV1.iCodings;
+ iCallInfo.iCallParams.iAsymmetry = hscsdParamsV1.iAsymmetry;
+ iCallInfo.iCallParams.iUserInitUpgrade = hscsdParamsV1.iUserInitUpgrade;
+ }
+ }
+ }
+
+TInt CCallMobileData::AnswerIncomingCall(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams)
+/**
+ * If there is no waiting call, will wait for one and then answer it.
+ * If there is a waiting call, will answer immediatly.
+ * Regardless of if there is a waiting call or not, the +CBST= command is sent immediatly.
+ */
+ {
+ const CCallBase::TCallOwnership owned = CheckOwnership(aTsyReqHandle);
+ TInt ret=KErrNone;
+ if (owned==CCallBase::EOwnedFalse) // call owned by another client
+ {
+ ret=KErrEtelNotCallOwner;
+ }
+ else
+ {
+ if (!iIsForIncomingCall)
+ {
+ if (REINTERPRET_CAST(CPhoneHayes*,Owner()->Owner())->CheckForOutstandingAnswer())
+ ret=KErrEtelAnswerAlreadyOutstanding;
+ }
+ else
+ ret=KErrEtelAnswerAlreadyOutstanding;
+ }
+
+ if (ret==KErrNone)
+ {
+ CLineHayes* line = STATIC_CAST(CLineHayes*,Owner());
+ STATIC_CAST(CPhoneHayes*,line->Owner())->CancelOtherRingingCall(line);
+ line->FreePreAllocCallIfNecessary();
+ SetDataCallParams(aCallParams);
+ if (iCallInfo.iMobileStatus==RMobileCall::EStatusRinging)
+ {
+ (void)SetOwnership(aTsyReqHandle);
+ LOGTEXT(_L8("DataCall:\tSubmitting Answer command"));
+
+ // Start the 'send CBST to phone' AT machine and pass the
+ // CATAnswerData object, so that the call is answered after
+ // the CBST is sent.
+ iSetCBST->ExecuteCommand(aTsyReqHandle,iAnswerData,&iCallInfo);
+ }
+ else // This call is now a client-designated Incoming Call object.
+ {
+ iIsForIncomingCall=ETrue;
+ iAnswerTsyReqHandle = aTsyReqHandle;
+
+ // Start the 'send CBST to phone' AT machine. This state machine
+ // will not complete any client request.
+ iSetCBST->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
+ }
+ return KErrNone;
+ }
+
+ ReqCompleted(aTsyReqHandle,ret);
+ return KErrNone;
+ }
+
+
+TInt CCallMobileData::AnswerIncomingCallCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ LOGTEXT(_L8("DataCall:\tSubmitting Cancel Answer command"));
+ if (iIsForIncomingCall)
+ {
+ iIsForIncomingCall=EFalse;
+ ReqCompleted(aTsyReqHandle,KErrCancel);
+ }
+ else
+ iAnswerData->CancelCommand(aTsyReqHandle);
+ return KErrNone;
+ }
+
+void CCallMobileData::AnswerImmediately()
+ {
+ (void)SetOwnership(iAnswerTsyReqHandle);
+ // EStatusRinging always results in KErrNone return
+ (void) ChangeCallStatus(RMobileCall::EStatusRinging); // new 14/1/99
+ iPhoneGlobals->iNotificationStore->CheckNotification(this,ERingOccurred);
+ iIsForIncomingCall=EFalse; // this must be after the check notification as CNotifications
+ // asks line for info about the call which Is For Incoming Call
+ LOGTEXT(_L8("DataCall:\tSubmitting Answer command"));
+ iAnswerData->ExecuteCommand(iAnswerTsyReqHandle,NULL,&iCallInfo);
+ }
+
+TInt CCallMobileData::Connect(const TTsyReqHandle aTsyReqHandle,const TDesC8* aCallParams)
+//
+// Connect to an already dialled call
+//
+ {
+ TInt ret = ValidateRequest(aTsyReqHandle,RCall::EStatusIdle);
+ if (ret==KErrNone)
+ {
+ (void)SetOwnership(aTsyReqHandle);
+ SetCallParams(aCallParams);
+ LOGTEXT(_L8("DataCall:\tSubmitting Immediate Connect command"));
+ iConnectData->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
+ }
+ else
+ ReqCompleted(aTsyReqHandle,ret);
+ return KErrNone;
+ }
+
+TInt CCallMobileData::ConnectCancel(const TTsyReqHandle aTsyReqHandle)
+//
+// Cancel immediate connect command
+//
+ {
+ LOGTEXT(_L8("DataCall:\tSubmitting Cancel Connect command"));
+ iConnectData->CancelCommand(aTsyReqHandle);
+ return KErrNone;
+ }
+
+TInt CCallMobileData::HangUp(const TTsyReqHandle aTsyReqHandle)
+//
+// Terminate a data call. If someone else owns call complete with error, but if no-one owns
+// it send an ATH anyway, as the connection may have failed and the user wants to ensure
+// call has hung up. Call Start() instead of ExecuteCommand() because there is no need to
+// initialise before doing this or to send the escape sequence - the hang up sequence drops
+// DTR anyway.
+//
+ {
+ if (CheckOwnership(aTsyReqHandle)==CCallBase::EOwnedFalse)
+ {
+ ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner);
+ return KErrNone;
+ }
+ if ((iCallInfo.iMobileStatus!=RMobileCall::EStatusIdle) &&
+ (iCallInfo.iMobileStatus!=RMobileCall::EStatusDisconnecting))
+ {
+ LOGTEXT(_L8("DataCall:\tSubmitting Hang Up command"));
+ iHangUpData->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
+ return KErrNone;
+ }
+ else
+ {
+ // Call not in a state to be terminated - but return KErrNone
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+ }
+
+TInt CCallMobileData::HangUpCancel(const TTsyReqHandle aTsyReqHandle)
+//
+// Cancel the hang up command.
+//
+ {
+ LOGTEXT(_L8("DataCall:\tSubmitting Cancel Hang Up command"));
+ iHangUpData->Stop(aTsyReqHandle);
+ return KErrNone;
+ }
+
+TInt CCallMobileData::RelinquishOwnership()
+//
+// Called by server to tell TSY to either pass ownership on to another interested client
+// or hang up immediately. If call is currently connecting, RelinquishOwnershipComplete
+// will be called once cancelling has finished.
+//
+ {
+ LOGTEXT(_L8("DataCall:\tRelinquish Ownership"));
+ if(iList->iAcquireList.IsEmpty())
+ {
+ if (iDialData->IsPreConnectInProgress() ||
+ iConnectData->IsPreConnectInProgress() ||
+ iAnswerData->IsPreConnectInProgress())
+ {
+ iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
+ return KErrNone;
+ }
+ switch(iCallInfo.iMobileStatus)
+ {
+ case RMobileCall::EStatusConnected:
+ iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
+ //iHangUpData->ExecuteCommand(0,NULL,&iCallInfo);
+ iQuickInit->CancelAndHangUp(&iCallInfo,iHangUpData);
+ break;
+ case RMobileCall::EStatusDialling:
+ case RMobileCall::EStatusConnecting:
+ case RMobileCall::EStatusAnswering:
+ case RMobileCall::EStatusDisconnecting:
+ iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
+ break;
+ default:
+ if (iPhoneGlobals->iPhoneStatus.iInitStatus==EPhoneInitialising)
+ iCallInfo.iClientPanicOccurred = EPanicOccurredWithoutDataPortLoan;
+ else
+ RelinquishOwnershipCompleted(KErrNone);
+ break;
+ }
+ return KErrNone;
+ }
+ CAcquireEntry* entry=iList->iAcquireList.First();
+ if (entry)
+ {
+ (void)SetOwnership(entry->iTsyReqHandle);
+ ReqCompleted(entry->iTsyReqHandle,KErrNone);
+ iList->Remove(entry);
+ }
+ RelinquishOwnershipCompleted(KErrNone);
+ return KErrNone;
+ }
+
+TInt CCallMobileData::RecoverDataPortAndRelinquishOwnership()
+//
+// Called by server to tell TSY to either pass ownership on to another interested client
+// after regaining control of the port and performing a swift initialisation,
+// or hang up immediately
+//
+ {
+ LOGTEXT(_L8("DataPort Recover and Relinquish Ownership"));
+ iCallInfo.iLoanedToClient=EFalse;
+ iPhoneGlobals->iPhoneStatus.iDataPortLoaned = EFalse;
+ if(iList->iAcquireList.IsEmpty())
+ {
+ (void)SetUnowned();
+ iCallInfo.iClientPanicOccurred = EPanicOccurredDuringDataPortLoan;
+ iIo->Read();
+ iHangUpData->ExecuteCommand(0,NULL,&iCallInfo);
+ return KErrNone;
+ }
+ CAcquireEntry* entry=iList->iAcquireList.First();
+ if (entry)
+ {
+ (void)SetOwnership(entry->iTsyReqHandle);
+ ReqCompleted(entry->iTsyReqHandle,KErrNone);
+ iList->Remove(entry);
+ iQuickInit->StartQuickInit();
+ }
+ RecoverDataPortAndRelinquishOwnershipCompleted(KErrNone);
+ return KErrNone;
+ }
+
+TInt CCallMobileData::LoanDataPort(const TTsyReqHandle aTsyReqHandle, RCall::TCommPort* aCommPort)
+//
+// Get the port info
+//
+ {
+ LOGTEXT(_L8(" DataPort Loan"));
+ if (CheckOwnership(aTsyReqHandle)!=CCallBase::EOwnedTrue)
+ {
+ ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner);
+ return KErrNone;
+ }
+ if (iCallInfo.iMobileStatus != RMobileCall::EStatusConnected)
+ {
+ ReqCompleted(aTsyReqHandle,KErrEtelCallNotActive);
+ return KErrNone;
+ }
+ TInt ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameCsyName),aCommPort->iCsy);
+ if (!ret)
+ {
+ ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNamePortName),aCommPort->iPort);
+ }
+ if (ret)
+ {
+ ReqCompleted(aTsyReqHandle,ret);
+ return KErrNone;
+ }
+ iCallInfo.iLoanedToClient = ETrue;
+ iPhoneGlobals->iPhoneStatus.iDataPortLoaned = ETrue;
+ iPhoneGlobals->iNotificationStore->CheckNotification(this,EDataPortLoaned);
+ iWaitForNoCarrier->StopWait();
+ if (iPhoneGlobals->iPhoneStatus.iMode==RPhone::EModeOnlineCommand)
+ iATSetToOnlineDataMode->ExecuteCommand(aTsyReqHandle,NULL,&iCallInfo);
+ else
+ {
+ iIo->Cancel();
+ TCommConfig aConfigPckg;
+ TInt ret = iPhoneGlobals->iConfiguration->PortConfig(aConfigPckg,EConfigTypeFull);
+ if (ret==KErrNone)
+ ret = iIo->ConfigurePort(aConfigPckg);
+ ReqCompleted(aTsyReqHandle,ret);
+ }
+ return KErrNone;
+ }
+
+TInt CCallMobileData::LoanDataPortCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ iATSetToOnlineDataMode->CancelCommand(aTsyReqHandle);
+ return KErrNone;
+ }
+
+TInt CCallMobileData::RecoverDataPort(const TTsyReqHandle aTsyReqHandle)
+//
+// Take back control of data port
+// Check that call had been loaned to client
+//
+ {
+ if (iCallInfo.iLoanedToClient==EFalse)
+ {
+ ReqCompleted(aTsyReqHandle,KErrEtelPortNotLoanedToClient);
+ return KErrNone;
+ }
+ TCallOwnership owner = CheckOwnership(aTsyReqHandle);
+ if (owner!=CCallBase::EOwnedTrue && owner!=CCallBase::EOwnedPriorityClient)
+ {
+ ReqCompleted(aTsyReqHandle,KErrEtelNotCallOwner);
+ return KErrNone;
+ }
+ LOGTEXT(_L8("DataPort Recover"));
+ iCallInfo.iLoanedToClient=EFalse;
+ iPhoneGlobals->iPhoneStatus.iDataPortLoaned = EFalse;
+ LOGTEXT2(_L8("Comm signals : %x"),iIo->Signals());
+ iIo->ResetReadAndWriteBuffers(); // in case client has left RxBuffer non-empty
+ LOGTEXT2(_L8("Comm signals after ResetBuffers : %x"),iIo->Signals());
+ FlowControlSuspend(); // Defect fix for MPO-4ZECUN
+ iQuickInit->StartQuickInit();
+ ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }