--- a/telephonyserverplugins/common_tsy/commontsy/src/mmtsy/cmmlinetsy.cpp Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/common_tsy/commontsy/src/mmtsy/cmmlinetsy.cpp Thu May 06 15:10:38 2010 +0100
@@ -1,1262 +1,1262 @@
-// Copyright (c) 2006-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 FILES
-#include "cmmlinetsy.h"
-#include "cmmphonetsy.h"
-#include "cmmcalltsy.h"
-#include "cmmlinelist.h"
-#include "cmmcalllist.h"
-#include "cmmtsyreqhandlestore.h"
-#include "MmTsy_numberOfSlots.h"
-#include <ctsy/tflogger.h>
-#include <ctsy/pluginapi/cmmdatapackage.h>
-#include <et_struct.h>
-
-
-// ======== MEMBER FUNCTIONS ========
-
-CMmLineTsy::CMmLineTsy()
- {
- }
-
-void CMmLineTsy::ConstructL()
- {
- TFLOGSTRING("TSY: CMmLineTsy::ConstructL");
- //Initialise miscellaneous internal attributes
- InitInternalAttributesL();
-
- // Create and store a Call Object for incoming calls.
- TInt ret = CreateCallObjectForIncomingCall();
-
- if ( KErrNone != ret )
- {
- //if this fails, incoming calls cannot be called -> leave
- User::Leave( KErrNoMemory );
- }
-
- //create req handle store
- iTsyReqHandleStore = CMmTsyReqHandleStore::NewL(
- EMultimodeLineMaxNumOfRequests, iLineReqHandles );
- }
-
-CMmLineTsy::~CMmLineTsy()
- {
- TFLOGSTRING2("TSY: CMmLineTsy::~CMmLineTsy. Line name: %S", &iLineName);
-
- //delete req handle store
- delete iTsyReqHandleStore;
-
- //delete incoming call object
- if ( iCallForIncomingCall )
- {
- iCallForIncomingCall->Close();
- }
-
- // Remove all calls still open from this line
- iMmPhone->CallList()->RemoveCallsByLine( &iLineName );
-
- //Inform phone that this line has been removed.
- iMmPhone->RemoveLine( iLineName );
-
- iMmPhone = NULL;
- iCallForIncomingCall = NULL;
- iRetLineStatus = NULL;
- iRetCaps = NULL;
- iRetIncomingCallName = NULL;
- iRetCallAdded = NULL;
- iRetMobileLineStatus = NULL;
- iTsyReqHandleStore = NULL;
- iMessageManager = NULL;
- }
-
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::OpenNewObjectByNameL
-// Returns a pointer to an existing call. The TSY classes must not use this
-// method. This method is called when the client uses RCall::OpenExistingCall
-// method.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-CTelObject* CMmLineTsy::OpenNewObjectByNameL(
- const TDesC& aName )
- {
- TFLOGSTRING2("TSY: CMmLineTsy::OpenNewObjectByNameL %S", &aName);
-
- TName mmCallName( aName );
- CMmCallTsy* mmCall = iMmPhone->CallList()->GetMmCallByName( &mmCallName );
-
- //if not found, Leave...
- if ( NULL == mmCall )
- {
- User::Leave( KErrNotFound );
- }
- else
- {
- //Update iUnownedCallObject flag
- mmCall->SetUnownedCallObjectFlag( EFalse );
- }
-
- return mmCall;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::InitInternalAttributesL
-// Initialises miscellaneous internal attributes.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-void CMmLineTsy::InitInternalAttributesL()
- {
- // Set object attributes
- iLineStatus = RCall::EStatusIdle;
- iMobileLineStatus = RMobileCall::EStatusIdle;
-
- //reset the name for answering call
- iNameOfCallForAnswering.Zero();
-
- iNumCalls = 0; // Number of calls created from line;
- iCallSequenceNumber = 0; // The sequence number for the calls
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::CallObjectForIncomingCall
-// This method returns a Call object that is used for a new incoming call.
-// If there are no incoming calls this method creates a new call object.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-CMmCallTsy* CMmLineTsy::CallObjectForIncomingCall()
- {
- CMmCallTsy* callForIncomingCall = NULL;
-
- if ( iCallForIncomingCall == NULL )
- {
- CreateCallObjectForIncomingCall();
- }
-
- callForIncomingCall = iCallForIncomingCall;
-
- return callForIncomingCall;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::ReqModeL
-// ReqModeL is called from the server's CTelObject::ReqAnalyserL in order to
-// check the type of request it has
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-CTelObject::TReqMode CMmLineTsy::ReqModeL(
- const TInt aIpc )
- {
- TFLOGSTRING2("TSY: CMmLineTsy::ReqModeL IPC:%d",aIpc);
-
- CTelObject::TReqMode ret( 0 ); // default return value
-
- switch( aIpc )
- {
- // Non-flow control requests
- // All disabled
- // TSYs wishing to implement their own buffering algorithm will place
- // all requests in this category. This category will also be used by
- // the RecoverDataPort request that must be passed to the TSY to
- // indicate that it may use the communications port after a loan.
-
- //Get methods that do not use DOS and return immediately.
- //Flow control not required.
- case EEtelLineGetStatus:
- case EEtelLineGetCaps:
- case EEtelLineGetCallInfo:
- case EEtelLineGetInfo:
- case EEtelLineGetHookStatus:
- case EMobileLineGetMobileLineStatus:
-
- //Other methods that do not use DOS and return immediately.
- //Flow control not required.
- case EEtelLineEnumerateCall:
-
- //Methods that can propably take a long time and cannot therefore be
- //flow controlled. Solution: All these methods must check req handle
- //table before handling the request. In case that the request table
- //indicates that same method has been called and has not been
- //completed, the method should return KErrServerBusy.
- break;
- // Flow Controlled Services
- // KReqModeFlowControlObeyed
- // Commands that change the state of the phone, e.g. clearing the AoC
- // counter; are commands that the TSY should only deal with one at
- // a time.
-
- // ret = KReqModeFlowControlObeyed;
- // break;
-
- // ReqModePostImmediately
- // Requests that notify a client about a change of state, where the
- // TSY needs to distinguish between different clients.
- //ret=KReqModeRePostImmediately;
- //break;
-
- // KReqModeMultipleCompletionEnabled
- // (a) commands that may take some time, but which the TSY can handle
- // more than one of concurrently, or
- // (b) notifications that the TSY does not wish to be re-posted
- // immediately, so the server does no buffering.
- //ret=KReqModeMultipleCompletionEnabled;
- //break;
-
- // KReqModeMultipleCompletionEnabled | KReqModeFlowControlObeyed
- // A command that may take some time and which the TSY can only deal
- // with one at a time.
- //ret = KReqModeMultipleCompletionEnabled |
- // KReqModeFlowControlObeyed;
- //break;
-
- // Notification Requests
- // KReqModeMultipleCompletionEnabled | ReqModePostImmediately
- // Requests that notify a client about a change of state.
- // Since these requests do not require the issuing of any modem
- // commands, they do not have to obey flow control. The TSY never
- // gets more than one of these outstanding per CTelObject.
- case EEtelLineNotifyStatusChange:
- case EEtelLineNotifyCallAdded:
- case EETelLineCapsChangeNotification:
- case EEtelLineNotifyHookChange:
- case EEtelLineNotifyIncomingCall:
- case EMobileLineNotifyMobileLineStatusChange:
- ret = KReqModeMultipleCompletionEnabled |
- KReqModeRePostImmediately;
- break;
- // Cancel Requests
- //It is not necessary to include the Cancel methods in ReqModeL at all
- //The ETel server never calls ReqModeL with a Cancel IPC.
-
- //Other variations of return values are unusable
-
- // Default: Call CLineBase's ReqModeL.
- default:
- ret = CLineBase::ReqModeL( aIpc );
- break;
- }
-
- return ret;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::ExtFunc
-// TRAP's all CMmLineTsy related MM API requests in cases that they fail. This
-// method functions only as a centralized TRAP for the DoExtFuncL method that
-// does the actual mapping of IPC number to TSY method call.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::ExtFunc(
- const TTsyReqHandle aTsyReqHandle,
- const TInt aIpc,
- const TDataPackage& aPackage )
- {
- TInt ret( KErrNone );
- TInt trapError( KErrNone );
-
- //reset last tsy request type
- iReqHandleType = EMultimodeLineReqHandleUnknown;
-
- //Original code continues here.
- TRAP( trapError, ret = DoExtFuncL( aTsyReqHandle, aIpc, aPackage ); );
-
- if ( trapError != KErrNone )
- {
- // Object cannot be created.
- ReqCompleted( aTsyReqHandle, trapError );
- }
- else if ( ret != KErrNone )
- {
- ReqCompleted( aTsyReqHandle, ret );
- }
-
- //save request handle
- if ( EMultimodeLineReqHandleUnknown != iReqHandleType )
- {
- iTsyReqHandleStore->SetTsyReqHandle( iReqHandleType, aTsyReqHandle );
- }
-
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::DoExtFuncL
-// 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.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::DoExtFuncL(
- const TTsyReqHandle aTsyReqHandle,
- const TInt aIpc,
- const TDataPackage& aPackage )
- {
- TFLOGSTRING3("TSY: CMmLineTsy::DoExtFuncL IPC:%d Handle:%d", aIpc, \
- aTsyReqHandle);
-
- TInt ret ( KErrNone );
-
- 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 )
- {
- // Mobile Line Status
- // Get Mobile Line Status
- case EMobileLineGetMobileLineStatus:
- ret = GetMobileLineStatus( aTsyReqHandle,
- REINTERPRET_CAST( RMobileCall::TMobileCallStatus*, dataPtr ) );
- break;
- //Notify Change of Mobile Line Status
- case EMobileLineNotifyMobileLineStatusChange:
- ret = NotifyMobileLineStatusChange(
- REINTERPRET_CAST( RMobileCall::TMobileCallStatus*, dataPtr ) );
- break;
- default:
- ret = KErrNotSupported;
- break;
- }
-
- return ret;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::CreateNewCallName
-// Creates a new name for the call, which is the name of the line followed by
-// a call sequence number.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::CreateNewCallName(
- TDes& aNewName )
- {
- // buffer for the name
- TBuf<KMaxName> buf;
- // append line name first
- buf.Append( iLineName );
- // append call sequence number next
- buf.AppendNum( IncrementCallSequenceNumber() );
- // copy the created name
- aNewName.Copy( buf );
-
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::IncrementCallSequenceNumber
-// Returns the sequence number of the call created from this line. This
-// sequence number will be resetted when this line object is deleted. TInt
-// allows the value to increment to the value 2^32.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TUint CMmLineTsy::IncrementCallSequenceNumber()
- {
- // increment call sequence number
- iCallSequenceNumber++;
- return iCallSequenceNumber;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::EnumerateCall
-// This CORE API method returns the number of calls opened from a line. The
-// number of calls will be stored in the aCount pointer.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::EnumerateCall(
- const TTsyReqHandle aTsyReqHandle,
- TInt* aCount )
- {
- *aCount = iNumCalls;
- ReqCompleted( aTsyReqHandle, KErrNone );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::DecrementNumberOfCalls
-// Decrements number of calls opened from a line by one.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-void CMmLineTsy::DecrementNumberOfCalls()
- {
- if ( iNumCalls > 0 )
- {
- iNumCalls--;
- }
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyStatusChange
-// This CORE API method provides notification about a change in the line
-// status
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyStatusChange(
- const TTsyReqHandle aTsyReqHandle,
- RCall::TStatus* aLineStatus )
- {
- iRetLineStatus = aLineStatus;
- iTsyReqHandleStore->SetTsyReqHandle( EMultimodeLineNotifyStatusChange,
- aTsyReqHandle );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyStatusChangeCancel
-// This CORE API method cancels an outstanding line status change notification
-// request, placed using the NotifyStatusChange() method.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyStatusChangeCancel(
- const TTsyReqHandle aTsyReqHandle )
- {
- iRetLineStatus = NULL;
- iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeLineNotifyStatusChange );
- ReqCompleted( aTsyReqHandle, KErrCancel );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::CompleteNotifyStatusChange
-// This method is used to notify to the client about the line status change.
-// This method should only be called by the CMmCallTsy's
-// CompleteNotifyStatusChange method to guaratee that this is functioning
-// right.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-void CMmLineTsy::CompleteNotifyStatusChange()
- {
- TInt ret( KErrNone );
- TBool coreStatusChanged( EFalse );
- TBool mobileStatusChanged( EFalse );
- RCall::TStatus tempCoreStatus( RCall::EStatusIdle );
- RMobileCall::TMobileCallStatus tempMobileStatus(
- RMobileCall::EStatusIdle );
- TInt numberOfObjectsInCallList = iMmPhone->CallList()->
- GetNumberOfObjects();
-
- for ( TInt i = 0; i < numberOfObjectsInCallList; i++ )
- {
- CMmCallTsy* mmCall = iMmPhone->CallList()->GetMmCallByIndex(i);
-
- //check that the call object has been opened from this line
- if ( mmCall->Line() == this )
- {
- RMobileCall::TMobileCallStatus mobileStatus
- = mmCall->MobileCallStatus();
- switch( mobileStatus )
- {
- case RMobileCall::EStatusUnknown:
- tempCoreStatus = RCall::EStatusUnknown;
- tempMobileStatus = RMobileCall::EStatusUnknown;
- //get out of loop, resulting status is unknown...
- i = numberOfObjectsInCallList;
- break;
- case RMobileCall::EStatusConnected:
- tempCoreStatus = RCall::EStatusConnected;
- tempMobileStatus = RMobileCall::EStatusConnected;
- //get out of loop, resulting status is unknown...
- i = numberOfObjectsInCallList;
- break;
- case RMobileCall::EStatusRinging:
- //update core status
- if ( tempCoreStatus == RCall::EStatusIdle )
- {
- tempCoreStatus = RCall::EStatusRinging;
- }
- //update mobile status
- if ( tempMobileStatus == RMobileCall::EStatusIdle ||
- tempMobileStatus == RMobileCall::EStatusHold)
- {
- tempMobileStatus = mobileStatus;
- }
- break;
- case RMobileCall::EStatusDialling:
- if ( tempCoreStatus == RCall::EStatusIdle )
- {
- tempCoreStatus = RCall::EStatusDialling;
- }
- //update mobile status
- if ( tempMobileStatus == RMobileCall::EStatusIdle ||
- tempMobileStatus == RMobileCall::EStatusHold)
- {
- tempMobileStatus = mobileStatus;
- }
- break;
- case RMobileCall::EStatusAnswering:
- if ( tempCoreStatus == RCall::EStatusIdle ||
- tempCoreStatus == RCall::EStatusRinging )
- {
- tempCoreStatus = RCall::EStatusAnswering;
- }
- //update mobile status
- if ( tempMobileStatus == RMobileCall::EStatusIdle ||
- tempMobileStatus == RMobileCall::EStatusRinging ||
- tempMobileStatus == RMobileCall::EStatusHold )
- {
- tempMobileStatus = mobileStatus;
- }
- break;
- case RMobileCall::EStatusConnecting:
- if ( tempCoreStatus == RCall::EStatusIdle ||
- tempCoreStatus == RCall::EStatusDialling )
- {
- tempCoreStatus = RCall::EStatusConnecting;
- }
- //update mobile status
- if ( tempMobileStatus == RMobileCall::EStatusIdle ||
- tempMobileStatus == RMobileCall::EStatusDialling ||
- tempMobileStatus == RMobileCall::EStatusHold )
- {
- tempMobileStatus = mobileStatus;
- }
- break;
- case RMobileCall::EStatusDisconnecting:
- //update core status
- if ( tempCoreStatus == RCall::EStatusIdle )
- {
- tempCoreStatus = RCall::EStatusHangingUp;
- }
- if ( tempMobileStatus == RMobileCall::EStatusIdle )
- {
- tempMobileStatus = mobileStatus;
- }
- break;
- case RMobileCall::EStatusWaitingAlternatingCallSwitch:
- if ( tempMobileStatus == RMobileCall::EStatusIdle )
- {
- tempMobileStatus = mobileStatus;
- }
- break;
- case RMobileCall::EStatusHold:
- if ( tempMobileStatus == RMobileCall::EStatusIdle ||
- tempMobileStatus ==
- RMobileCall::EStatusDisconnecting )
- {
- tempCoreStatus = iLineStatus;
- tempMobileStatus = mobileStatus;
- }
- break;
- case RMobileCall::EStatusIdle:
- case RMobileCall::EStatusReconnectPending:
- case RMobileCall::EStatusDisconnectingWithInband:
- case RMobileCall::EStatusTransferring:
- case RMobileCall::EStatusTransferAlerting:
- default:
- break;
- }
- }
- }
-
- //check if core status has changed
- if ( tempCoreStatus != iLineStatus )
- {
- coreStatusChanged = ETrue;
- iLineStatus = tempCoreStatus;
- }
-
- //check if mobile status has changed
- if ( tempMobileStatus != iMobileLineStatus )
- {
- mobileStatusChanged = ETrue;
- iMobileLineStatus = tempMobileStatus;
- }
-
- //get core status change notification req handle
- TTsyReqHandle iNotifyStatusChangeHandle = iTsyReqHandleStore->
- GetTsyReqHandle( EMultimodeLineNotifyStatusChange );
-
- //if req handle available and status changed
- if ( ( iNotifyStatusChangeHandle > 0 ) && coreStatusChanged )
- {
- *iRetLineStatus = iLineStatus;
- iTsyReqHandleStore->ResetTsyReqHandle(
- EMultimodeLineNotifyStatusChange );
- ReqCompleted( iNotifyStatusChangeHandle, ret );
- }
-
- //get mobile status change notification req handle
- TTsyReqHandle iNotifyMobileLineStatusChangeHandle = iTsyReqHandleStore->
- GetTsyReqHandle( EMultimodeLineMobileLineStatusChange );
-
- //if req handle available and status changed
- if ( iNotifyMobileLineStatusChangeHandle > 0
- && ( coreStatusChanged || mobileStatusChanged ) )
- {
- *iRetMobileLineStatus = iMobileLineStatus;
- iTsyReqHandleStore->ResetTsyReqHandle(
- EMultimodeLineMobileLineStatusChange );
- ReqCompleted( iNotifyMobileLineStatusChangeHandle, ret );
- }
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::GetHookStatus
-// This CORE API method retrieves the current hook status. Method is not
-// currently supported,
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::GetHookStatus(
- const TTsyReqHandle aTsyReqHandle,
- RCall::THookStatus* )
- {
- ReqCompleted( aTsyReqHandle, KErrNotSupported );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::GetInfo
-// This CORE API method retrieves the current line information.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::GetInfo(
- const TTsyReqHandle aTsyReqHandle,
- RLine::TLineInfo* aLineInfo )
- {
- // The current hook status.
- aLineInfo->iHookStatus = RCall::EHookStatusUnknown;
- // The current line status.
- aLineInfo->iStatus = iLineStatus;
- // The name of the last call created on the line.
- aLineInfo->iNameOfLastCallAdded = iNameOfLastCallAdded;
- // The name of the call to which a new incoming call will be directed.
- aLineInfo->iNameOfCallForAnswering = iNameOfCallForAnswering;
-
- ReqCompleted( aTsyReqHandle, KErrNone );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::LineInfo
-// This method retrieves the current line information. The method is used by
-// MmPhone object.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-RPhone::TLineInfo CMmLineTsy::LineInfo() const
- {
- // Line info
- RPhone::TLineInfo lineInfo;
- // The current line status.
- lineInfo.iStatus = iLineStatus;
- // line capabilities
- lineInfo.iLineCapsFlags = iLineCaps.iFlags;
- // line name
- lineInfo.iName = iLineName;
-
- return lineInfo;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyCapsChange
-// This CORE API method provides notification of a change in the line
-// capabilities.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyCapsChange(
- const TTsyReqHandle aTsyReqHandle,
- RLine::TCaps* aCaps )
- {
- // On return, contains the new line capabilities
- iRetCaps = aCaps;
- iTsyReqHandleStore->SetTsyReqHandle( EMultimodeLineCapsChangeNotification,
- aTsyReqHandle );
-
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyCapsChangeCancel
-// This CORE API method cancels an "line capabilities change" notification
-// request, placed using the NotifyCapsChange() method.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyCapsChangeCancel(
- const TTsyReqHandle aTsyReqHandle )
- {
- iRetCaps = NULL;
- iTsyReqHandleStore->ResetTsyReqHandle(
- EMultimodeLineCapsChangeNotification );
- ReqCompleted( aTsyReqHandle, KErrCancel );
-
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::CompleteNotifyCapsChange
-// This method is used to notify to the client about the capabilities change.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-void CMmLineTsy::CompleteNotifyCapsChange()
- {
- //reset req handle. Returns the deleted req handle
- TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
- EMultimodeLineCapsChangeNotification );
-
- if ( EMultimodeLineReqHandleUnknown != reqHandle )
- {
- *iRetCaps = iLineCaps;
- ReqCompleted( reqHandle, KErrNone );
- }
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyIncomingCall
-// This CORE API method is used to notify a client when an incoming call is
-// detected.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyIncomingCall(
- const TTsyReqHandle aTsyReqHandle,
- TName* aName )
- {
- // On notification, contains the name of the incoming call.
- iRetIncomingCallName = aName;
- iTsyReqHandleStore->SetTsyReqHandle( EMultimodeLineNotifyIncomingCall,
- aTsyReqHandle );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyIncomingCallCancel
-// This CORE API method cancels an outstanding incoming call notification,
-// placed with the NotifyIncomingCall() method.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyIncomingCallCancel(
- const TTsyReqHandle aTsyReqHandle )
- {
- iRetIncomingCallName = NULL;
- iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeLineNotifyIncomingCall );
- ReqCompleted( aTsyReqHandle, KErrCancel );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyCallAdded
-// This CORE API method provides notification that a new call has been added
-// to the line.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyCallAdded(
- const TTsyReqHandle aTsyReqHandle,
- TName* aName )
- {
- TFLOGSTRING2("TSY: CMmLineTsy::NotifyCallAdded requested by client, \
- lineMode:%d", iLineMode);
- // On return, contains the name of the new call.
- iRetCallAdded = aName;
- iTsyReqHandleStore->SetTsyReqHandle( EMultimodeLineNotifyCallAdded,
- aTsyReqHandle );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyCallAddedCancel
-// This CORE API method cancels an outstanding "new call added" notification
-// request, placed using the NotifyCallAdded() method.(other items were
-// commented in a header).
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyCallAddedCancel(
- const TTsyReqHandle aTsyReqHandle )
- {
- TFLOGSTRING("TSY: CMmLineTsy::NotifyCallAddedCancel requested by client");
- iRetCallAdded = NULL;
- iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeLineNotifyCallAdded );
- ReqCompleted( aTsyReqHandle, KErrCancel );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::CompleteNotifyCallAdded
-// This CORE API method is used to notify to the client that a call has been
-// added to the line. NOTE: Type is not defined because this method may be
-// called when incoming call occurs or when a call object has been created.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-void CMmLineTsy::CompleteNotifyCallAdded(const TDesC& aName )
- {
- TFLOGSTRING3("TSY: CMmLineTsy::CompleteNotifyCallAdded entered, \
- CALL ADDED, Call name: %S, Call mode: %d", &aName, iLineMode );
-
- //reset req handle. Returns the deleted req handle
- TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
- EMultimodeLineNotifyCallAdded );
-
- iNumCalls++;
-
- if ( EMultimodeLineReqHandleUnknown != reqHandle )
- {
- TFLOGSTRING("TSY: CMmLineTsy::CompleteNotifyCallAdded, Completed!");
- *iRetCallAdded = aName;
- ReqCompleted( reqHandle, KErrNone );
- }
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::GetCaps
-// This CORE API method retrieves the line capabilities.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::GetCaps(
- const TTsyReqHandle aTsyReqHandle,
- RLine::TCaps* aCaps )
- {
- *aCaps = iLineCaps;
- ReqCompleted( aTsyReqHandle, KErrNone );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::GetStatus
-// This CORE API method returns core line status information.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::GetStatus(
- const TTsyReqHandle aTsyReqHandle,
- RCall::TStatus* aStatus )
- {
- *aStatus = iLineStatus;
- ReqCompleted( aTsyReqHandle, KErrNone );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyHookChange
-// This CORE API method provides notification when the hook status changes.
-// Feature is not supported.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyHookChange(
- const TTsyReqHandle aTsyReqHandle,
- RCall::THookStatus* )
- {
- ReqCompleted( aTsyReqHandle, KErrNotSupported );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyHookChangeCancel
-// This CORE API method cancels an outstanding hook change notification req
-// placed using the NotifyHookChange() method. Feature is not supported.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyHookChangeCancel(
- const TTsyReqHandle aTsyReqHandle )
- {
- ReqCompleted( aTsyReqHandle, KErrNotSupported );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::GetCallInfo
-// This CORE API method returns information about a call.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::GetCallInfo(
- const TTsyReqHandle aTsyReqHandle,
- TCallInfoIndex* aCallInfoIndex )
- {
- TFLOGSTRING3("TSY: CMmLineTsy::GetCallInfo - Line name: %S, Index: %d",
- &iLineName, aCallInfoIndex->iIndex );
-
- TInt ret( KErrNotFound );
-
- // Check if the call object can be found from call list by index
- CMmCallTsy* mmCall = REINTERPRET_CAST( CMmCallTsy*,
- iMmPhone->CallList()->GetMmCallByIndexAndLine(
- aCallInfoIndex->iIndex, &iLineName ) );
-
- // If call object was found, fill the client pointer with call information
- if ( mmCall )
- {
- aCallInfoIndex->iInfo.iCallName = mmCall->CallName();
- aCallInfoIndex->iInfo.iStatus = mmCall->Status();
- aCallInfoIndex->iInfo.iCallCapsFlags = mmCall->CallCaps();
-
- TFLOGSTRING3("TSY: CMmLineTsy::GetCallInfo - Call name: %S, Status: %d",
- &aCallInfoIndex->iInfo.iCallName, aCallInfoIndex->iInfo.iStatus );
-
- ret = KErrNone;
- }
-
- ReqCompleted( aTsyReqHandle, ret );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::CancelService
-// 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. Core API requests are directed to the
-// LineBase.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::CancelService(
- const TInt aIpc,
- const TTsyReqHandle aTsyReqHandle )
- {
- TInt ret( KErrNone );
-
- // When the clients close their sub-sessions (eg. by calling RLine::Close)
- // they may not have cancelled all their outstanding asynchronous requests
- // before closing. It is up to the ETel server to clean up in this
- // situation, so the server will find the list of outstanding requests
- // related to that sub-session object and pass these outstanding IPC
- // request numbers, one at a time, to the CancelService method in the TSY.
-
- switch ( aIpc )
- {
- //TSY has started a request and it is not possible to then cancel
- //this request. The best thing for the TSY to do in this case is to
- //proceed as though the Cancel never happened. The server's call to
- //the TSY cancel function will return synchronously. The TSY then
- //continues to wait for the original acknowledgement and when it
- //receives it, the TSY will complete the original request.
- //case XXX
- // break;
-
- //Cancel methods that are not supported
- //case XXX:
- // ret = KErrNotSupported;
- // break;
-
- //Notification Cancels, no special requirements.
- case EMobileLineNotifyMobileLineStatusChange:
- ret = NotifyMobileLineStatusChangeCancel( aTsyReqHandle );
- break;
- //Everything is taken care in the method implementation.
- //Just direct the request to the method.
- //case XXX:
- // ret = XXXCancel( aTsyReqHandle );
- // break;
-
- default:
- return CLineBase::CancelService( aIpc, aTsyReqHandle );
- }
-
- return ret;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::RegisterNotification
-// RegisterNotification is called when the server recognises that this
-// notification is being posted for the first time on this sub-session object.
-// It enables the TSY to "turn on" any regular notification messages that it
-// may receive from DOS. Currently does not really do anything but returns
-// KErrNone to ETel server in case of known notification request type.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::RegisterNotification(
- const TInt aIpc )
- {
- TInt ret( KErrNone );
-
- switch ( aIpc )
- {
- case EEtelLineNotifyStatusChange:
- case EEtelLineNotifyCallAdded:
- case EETelLineCapsChangeNotification:
- case EEtelLineNotifyHookChange:
- case EEtelLineNotifyIncomingCall:
- case EMobileLineNotifyMobileLineStatusChange:
- ret = KErrNone;
- break;
- default:
- // Unknown or invalid IPC
- ret = KErrNotSupported;
- }
- return ret;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::DeregisterNotification
-// DeregisterNotification is called when the server recognises that this
-// notification will not be posted again because the last client to have a
-// handle on this sub-session object has just closed the handle. It enables
-// TSY to "turn off" any regular notification messages that it may receive
-// from DOS. Currently does not really do anything but returns KErrNone to
-// ETel server in case of known notification request type.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::DeregisterNotification(
- const TInt aIpc )
- {
- TInt ret( KErrNone );
-
- switch ( aIpc )
- {
- case EEtelLineNotifyStatusChange:
- case EEtelLineNotifyCallAdded:
- case EETelLineCapsChangeNotification:
- case EEtelLineNotifyHookChange:
- case EEtelLineNotifyIncomingCall:
- case EMobileLineNotifyMobileLineStatusChange:
- ret = KErrNone;
- break;
- default:
- // Unknown or invalid IPC
- ret = KErrNotSupported;
- }
- return ret;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NumberOfSlotsL
-// 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.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NumberOfSlotsL(
- const TInt aIpc )
- {
- //There is a buffer in the ETel server for each type of NOTIFICATION and
- //the size of the buffer is determined by the TSY. When the ETel server
- //discovers that a request is "repost immediately" it will ask the TSY how
- //big a buffer it wants by calling CTelObject::NumberOfSlotsL( ).
- //
- //It is up to the TSY developer's judgement how many buffer slots this
- //method returns for each notification. If there is a danger that a
- //particular notification could trigger frequently and in rapid succession
- //(e.g. call group change notification) then at least 10 or 20 slots may
- //be required. For a notification that triggers rarely, perhaps 1 or 2
- //slots is enough.
- //
- //So if the ETel server has stored a few occurrences of a particular
- //notification, when a client subsequently calls that notification request
- //the ETel server will complete the client's request with the saved data.
-
- TInt numberOfSlots( 1 );
-
- switch ( aIpc )
- {
- case EEtelLineNotifyStatusChange:
- numberOfSlots = KMmLineStatusChangeSlots;
- break;
- case EEtelLineNotifyCallAdded:
- numberOfSlots = KMmLineCallAddedSlots;
- break;
- case EETelLineCapsChangeNotification:
- numberOfSlots = KMmLineCapsChangeSlots;
- break;
- case EEtelLineNotifyHookChange:
- numberOfSlots = KMmLineHookChangeSlots;
- break;
- case EEtelLineNotifyIncomingCall:
- numberOfSlots = KMmLineIncomingCallSlots;
- break;
- case EMobileLineNotifyMobileLineStatusChange:
- numberOfSlots = KMmLineMobileLineStatusChangeSlots;
- break;
- default:
- // Unknown or invalid Line IPC
- User::Leave( KErrNotSupported );
- break;
- }
- return numberOfSlots;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::LineMode
-// Returns line mode.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-RMobilePhone::TMobileService CMmLineTsy::LineMode() const
- {
- return iLineMode;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::LineName
-// Returns line name.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TName CMmLineTsy::LineName() const
- {
- return iLineName;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::GetMobileLineStatus
-// Returns the current status of the line through the aStatus argument. The
-// possible line states map to the call states (see MM API spec) so that a
-// line that has one or more calls opened from it will have a status defined
-// by this table.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::GetMobileLineStatus(
- const TTsyReqHandle aTsyReqHandle,
- RMobileCall::TMobileCallStatus* aStatus )
- {
- *aStatus = iMobileLineStatus;
- ReqCompleted( aTsyReqHandle, KErrNone );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyMobileLineStatusChange
-// Allows a client to be notified when the mobile line changes state. The
-// request completes when the line changes state, the new state being copied
-// to the aStatus parameter.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyMobileLineStatusChange(
- RMobileCall::TMobileCallStatus* aStatus )
- {
- iRetMobileLineStatus = aStatus;
- iReqHandleType = EMultimodeLineMobileLineStatusChange;
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::NotifyMobileLineStatusChangeCancel
-// Cancels an outstanding asynchronous NotifyMobileLineStatusChange request.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-TInt CMmLineTsy::NotifyMobileLineStatusChangeCancel(
- const TTsyReqHandle aTsyReqHandle )
- {
- iRetMobileLineStatus = NULL;
- iTsyReqHandleStore->ResetTsyReqHandle(
- EMultimodeLineMobileLineStatusChange );
- ReqCompleted( aTsyReqHandle, KErrCancel );
- return KErrNone;
- }
-
-// ---------------------------------------------------------------------------
-// CMmLineTsy::CompleteNotifyAddBypassingCall
-// Handles ghost call object creation and initialisation. Also notifies
-// clients about the ghost call (using NotifyCallAdded method)
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-void CMmLineTsy::CompleteNotifyAddBypassingCall(
- CMmDataPackage* aDataPackage )
- {
- TInt callId( -1 );
- RMobilePhone::TMobileService callMode( RMobilePhone::EVoiceService );
- RMobileCall::TMobileCallInfoV1* mobileCallInfo;
-
- const CCallDataPackage* callData =
- reinterpret_cast<const CCallDataPackage*>(aDataPackage);
-
- callData->GetCallIdAndMode( callId, callMode );
- callData->UnPackData ( &mobileCallInfo );
-
- if ( mobileCallInfo->iStatus == RMobileCall::EStatusDialling ||
- mobileCallInfo->iStatus == RMobileCall::EStatusConnecting ||
- mobileCallInfo->iStatus == RMobileCall::EStatusConnected )
- {
- TFLOGSTRING2("TSY: CMmLineTsy::CompleteNotifyAddBypassingCall, \
- CALL INITIATED - NOT REQUESTED BY ETEL's CLIENT, Call ID: %d",
- callId );
-
- //create new call object
- CMmCallTsy* mmGhostCall = CreateGhostCallObject(
- callId, callMode, mobileCallInfo->iStatus );
-
- if ( mmGhostCall )
- {
- // Add the new call to the list of calls
- TInt ret( iMmPhone->CallList()->AddObject( mmGhostCall ) );
-
- if ( KErrNone == ret )
- {
- mmGhostCall->CompleteNotifyMobileCallInfoChange(
- aDataPackage );
- CompleteNotifyStatusChange();
- //inform ETel client that someone is creating a MO call
- CompleteNotifyCallAdded( mmGhostCall->CallName() );
- mmGhostCall->SetGhostCall( ETrue );
- }
- else
- {
- delete mmGhostCall;
- }
- }
- }
- else
- {
- TFLOGSTRING3("TSY: CMmLineTsy::CompleteNotifyAddBypassingCall, \
- CALL NOT INITIATED - Call ID:%d, Call status:%d",
- callId, mobileCallInfo->iStatus);
- }
- }
-
-#ifdef TF_LOGGING_ENABLED
-// ---------------------------------------------------------------------------
-// CMmLineTsy::ReqCompleted
-// Overloads CTelObject::ReqCompleted for logging purposes. It prints the
-// aTsyReqHandle and aError variable in the log file and then calls
-// CTelObject::ReqCompleted.
-// (other items were commented in a header).
-// ---------------------------------------------------------------------------
-//
-void CMmLineTsy::ReqCompleted(
- const TTsyReqHandle aTsyReqHandle,
- const TInt aError )
- {
- TFLOGSTRING3("TSY: CMmLineTsy::ReqCompleted Handle:%d Error:%d",
- aTsyReqHandle, aError);
-
- CTelObject::ReqCompleted(aTsyReqHandle,aError);
- }
-
-#endif
-
-
-// End of File
+// Copyright (c) 2006-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 FILES
+#include "cmmlinetsy.h"
+#include "cmmphonetsy.h"
+#include "cmmcalltsy.h"
+#include "cmmlinelist.h"
+#include "cmmcalllist.h"
+#include "cmmtsyreqhandlestore.h"
+#include "MmTsy_numberOfSlots.h"
+#include <ctsy/tflogger.h>
+#include <ctsy/pluginapi/cmmdatapackage.h>
+#include <et_struct.h>
+
+
+// ======== MEMBER FUNCTIONS ========
+
+CMmLineTsy::CMmLineTsy()
+ {
+ }
+
+void CMmLineTsy::ConstructL()
+ {
+ TFLOGSTRING("TSY: CMmLineTsy::ConstructL");
+ //Initialise miscellaneous internal attributes
+ InitInternalAttributesL();
+
+ // Create and store a Call Object for incoming calls.
+ TInt ret = CreateCallObjectForIncomingCall();
+
+ if ( KErrNone != ret )
+ {
+ //if this fails, incoming calls cannot be called -> leave
+ User::Leave( KErrNoMemory );
+ }
+
+ //create req handle store
+ iTsyReqHandleStore = CMmTsyReqHandleStore::NewL(
+ EMultimodeLineMaxNumOfRequests, iLineReqHandles );
+ }
+
+CMmLineTsy::~CMmLineTsy()
+ {
+ TFLOGSTRING2("TSY: CMmLineTsy::~CMmLineTsy. Line name: %S", &iLineName);
+
+ //delete req handle store
+ delete iTsyReqHandleStore;
+
+ //delete incoming call object
+ if ( iCallForIncomingCall )
+ {
+ iCallForIncomingCall->Close();
+ }
+
+ // Remove all calls still open from this line
+ iMmPhone->CallList()->RemoveCallsByLine( &iLineName );
+
+ //Inform phone that this line has been removed.
+ iMmPhone->RemoveLine( iLineName );
+
+ iMmPhone = NULL;
+ iCallForIncomingCall = NULL;
+ iRetLineStatus = NULL;
+ iRetCaps = NULL;
+ iRetIncomingCallName = NULL;
+ iRetCallAdded = NULL;
+ iRetMobileLineStatus = NULL;
+ iTsyReqHandleStore = NULL;
+ iMessageManager = NULL;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::OpenNewObjectByNameL
+// Returns a pointer to an existing call. The TSY classes must not use this
+// method. This method is called when the client uses RCall::OpenExistingCall
+// method.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CTelObject* CMmLineTsy::OpenNewObjectByNameL(
+ const TDesC& aName )
+ {
+ TFLOGSTRING2("TSY: CMmLineTsy::OpenNewObjectByNameL %S", &aName);
+
+ TName mmCallName( aName );
+ CMmCallTsy* mmCall = iMmPhone->CallList()->GetMmCallByName( &mmCallName );
+
+ //if not found, Leave...
+ if ( NULL == mmCall )
+ {
+ User::Leave( KErrNotFound );
+ }
+ else
+ {
+ //Update iUnownedCallObject flag
+ mmCall->SetUnownedCallObjectFlag( EFalse );
+ }
+
+ return mmCall;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::InitInternalAttributesL
+// Initialises miscellaneous internal attributes.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmLineTsy::InitInternalAttributesL()
+ {
+ // Set object attributes
+ iLineStatus = RCall::EStatusIdle;
+ iMobileLineStatus = RMobileCall::EStatusIdle;
+
+ //reset the name for answering call
+ iNameOfCallForAnswering.Zero();
+
+ iNumCalls = 0; // Number of calls created from line;
+ iCallSequenceNumber = 0; // The sequence number for the calls
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::CallObjectForIncomingCall
+// This method returns a Call object that is used for a new incoming call.
+// If there are no incoming calls this method creates a new call object.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CMmCallTsy* CMmLineTsy::CallObjectForIncomingCall()
+ {
+ CMmCallTsy* callForIncomingCall = NULL;
+
+ if ( iCallForIncomingCall == NULL )
+ {
+ CreateCallObjectForIncomingCall();
+ }
+
+ callForIncomingCall = iCallForIncomingCall;
+
+ return callForIncomingCall;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::ReqModeL
+// ReqModeL is called from the server's CTelObject::ReqAnalyserL in order to
+// check the type of request it has
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CTelObject::TReqMode CMmLineTsy::ReqModeL(
+ const TInt aIpc )
+ {
+ TFLOGSTRING2("TSY: CMmLineTsy::ReqModeL IPC:%d",aIpc);
+
+ CTelObject::TReqMode ret( 0 ); // default return value
+
+ switch( aIpc )
+ {
+ // Non-flow control requests
+ // All disabled
+ // TSYs wishing to implement their own buffering algorithm will place
+ // all requests in this category. This category will also be used by
+ // the RecoverDataPort request that must be passed to the TSY to
+ // indicate that it may use the communications port after a loan.
+
+ //Get methods that do not use DOS and return immediately.
+ //Flow control not required.
+ case EEtelLineGetStatus:
+ case EEtelLineGetCaps:
+ case EEtelLineGetCallInfo:
+ case EEtelLineGetInfo:
+ case EEtelLineGetHookStatus:
+ case EMobileLineGetMobileLineStatus:
+
+ //Other methods that do not use DOS and return immediately.
+ //Flow control not required.
+ case EEtelLineEnumerateCall:
+
+ //Methods that can propably take a long time and cannot therefore be
+ //flow controlled. Solution: All these methods must check req handle
+ //table before handling the request. In case that the request table
+ //indicates that same method has been called and has not been
+ //completed, the method should return KErrServerBusy.
+ break;
+ // Flow Controlled Services
+ // KReqModeFlowControlObeyed
+ // Commands that change the state of the phone, e.g. clearing the AoC
+ // counter; are commands that the TSY should only deal with one at
+ // a time.
+
+ // ret = KReqModeFlowControlObeyed;
+ // break;
+
+ // ReqModePostImmediately
+ // Requests that notify a client about a change of state, where the
+ // TSY needs to distinguish between different clients.
+ //ret=KReqModeRePostImmediately;
+ //break;
+
+ // KReqModeMultipleCompletionEnabled
+ // (a) commands that may take some time, but which the TSY can handle
+ // more than one of concurrently, or
+ // (b) notifications that the TSY does not wish to be re-posted
+ // immediately, so the server does no buffering.
+ //ret=KReqModeMultipleCompletionEnabled;
+ //break;
+
+ // KReqModeMultipleCompletionEnabled | KReqModeFlowControlObeyed
+ // A command that may take some time and which the TSY can only deal
+ // with one at a time.
+ //ret = KReqModeMultipleCompletionEnabled |
+ // KReqModeFlowControlObeyed;
+ //break;
+
+ // Notification Requests
+ // KReqModeMultipleCompletionEnabled | ReqModePostImmediately
+ // Requests that notify a client about a change of state.
+ // Since these requests do not require the issuing of any modem
+ // commands, they do not have to obey flow control. The TSY never
+ // gets more than one of these outstanding per CTelObject.
+ case EEtelLineNotifyStatusChange:
+ case EEtelLineNotifyCallAdded:
+ case EETelLineCapsChangeNotification:
+ case EEtelLineNotifyHookChange:
+ case EEtelLineNotifyIncomingCall:
+ case EMobileLineNotifyMobileLineStatusChange:
+ ret = KReqModeMultipleCompletionEnabled |
+ KReqModeRePostImmediately;
+ break;
+ // Cancel Requests
+ //It is not necessary to include the Cancel methods in ReqModeL at all
+ //The ETel server never calls ReqModeL with a Cancel IPC.
+
+ //Other variations of return values are unusable
+
+ // Default: Call CLineBase's ReqModeL.
+ default:
+ ret = CLineBase::ReqModeL( aIpc );
+ break;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::ExtFunc
+// TRAP's all CMmLineTsy related MM API requests in cases that they fail. This
+// method functions only as a centralized TRAP for the DoExtFuncL method that
+// does the actual mapping of IPC number to TSY method call.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::ExtFunc(
+ const TTsyReqHandle aTsyReqHandle,
+ const TInt aIpc,
+ const TDataPackage& aPackage )
+ {
+ TInt ret( KErrNone );
+ TInt trapError( KErrNone );
+
+ //reset last tsy request type
+ iReqHandleType = EMultimodeLineReqHandleUnknown;
+
+ //Original code continues here.
+ TRAP( trapError, ret = DoExtFuncL( aTsyReqHandle, aIpc, aPackage ); );
+
+ if ( trapError != KErrNone )
+ {
+ // Object cannot be created.
+ ReqCompleted( aTsyReqHandle, trapError );
+ }
+ else if ( ret != KErrNone )
+ {
+ ReqCompleted( aTsyReqHandle, ret );
+ }
+
+ //save request handle
+ if ( EMultimodeLineReqHandleUnknown != iReqHandleType )
+ {
+ iTsyReqHandleStore->SetTsyReqHandle( iReqHandleType, aTsyReqHandle );
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::DoExtFuncL
+// 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.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::DoExtFuncL(
+ const TTsyReqHandle aTsyReqHandle,
+ const TInt aIpc,
+ const TDataPackage& aPackage )
+ {
+ TFLOGSTRING3("TSY: CMmLineTsy::DoExtFuncL IPC:%d Handle:%d", aIpc, \
+ aTsyReqHandle);
+
+ TInt ret ( KErrNone );
+
+ 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 )
+ {
+ // Mobile Line Status
+ // Get Mobile Line Status
+ case EMobileLineGetMobileLineStatus:
+ ret = GetMobileLineStatus( aTsyReqHandle,
+ REINTERPRET_CAST( RMobileCall::TMobileCallStatus*, dataPtr ) );
+ break;
+ //Notify Change of Mobile Line Status
+ case EMobileLineNotifyMobileLineStatusChange:
+ ret = NotifyMobileLineStatusChange(
+ REINTERPRET_CAST( RMobileCall::TMobileCallStatus*, dataPtr ) );
+ break;
+ default:
+ ret = KErrNotSupported;
+ break;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::CreateNewCallName
+// Creates a new name for the call, which is the name of the line followed by
+// a call sequence number.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::CreateNewCallName(
+ TDes& aNewName )
+ {
+ // buffer for the name
+ TBuf<KMaxName> buf;
+ // append line name first
+ buf.Append( iLineName );
+ // append call sequence number next
+ buf.AppendNum( IncrementCallSequenceNumber() );
+ // copy the created name
+ aNewName.Copy( buf );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::IncrementCallSequenceNumber
+// Returns the sequence number of the call created from this line. This
+// sequence number will be resetted when this line object is deleted. TInt
+// allows the value to increment to the value 2^32.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TUint CMmLineTsy::IncrementCallSequenceNumber()
+ {
+ // increment call sequence number
+ iCallSequenceNumber++;
+ return iCallSequenceNumber;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::EnumerateCall
+// This CORE API method returns the number of calls opened from a line. The
+// number of calls will be stored in the aCount pointer.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::EnumerateCall(
+ const TTsyReqHandle aTsyReqHandle,
+ TInt* aCount )
+ {
+ *aCount = iNumCalls;
+ ReqCompleted( aTsyReqHandle, KErrNone );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::DecrementNumberOfCalls
+// Decrements number of calls opened from a line by one.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmLineTsy::DecrementNumberOfCalls()
+ {
+ if ( iNumCalls > 0 )
+ {
+ iNumCalls--;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyStatusChange
+// This CORE API method provides notification about a change in the line
+// status
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyStatusChange(
+ const TTsyReqHandle aTsyReqHandle,
+ RCall::TStatus* aLineStatus )
+ {
+ iRetLineStatus = aLineStatus;
+ iTsyReqHandleStore->SetTsyReqHandle( EMultimodeLineNotifyStatusChange,
+ aTsyReqHandle );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyStatusChangeCancel
+// This CORE API method cancels an outstanding line status change notification
+// request, placed using the NotifyStatusChange() method.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyStatusChangeCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iRetLineStatus = NULL;
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeLineNotifyStatusChange );
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::CompleteNotifyStatusChange
+// This method is used to notify to the client about the line status change.
+// This method should only be called by the CMmCallTsy's
+// CompleteNotifyStatusChange method to guaratee that this is functioning
+// right.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmLineTsy::CompleteNotifyStatusChange()
+ {
+ TInt ret( KErrNone );
+ TBool coreStatusChanged( EFalse );
+ TBool mobileStatusChanged( EFalse );
+ RCall::TStatus tempCoreStatus( RCall::EStatusIdle );
+ RMobileCall::TMobileCallStatus tempMobileStatus(
+ RMobileCall::EStatusIdle );
+ TInt numberOfObjectsInCallList = iMmPhone->CallList()->
+ GetNumberOfObjects();
+
+ for ( TInt i = 0; i < numberOfObjectsInCallList; i++ )
+ {
+ CMmCallTsy* mmCall = iMmPhone->CallList()->GetMmCallByIndex(i);
+
+ //check that the call object has been opened from this line
+ if ( mmCall->Line() == this )
+ {
+ RMobileCall::TMobileCallStatus mobileStatus
+ = mmCall->MobileCallStatus();
+ switch( mobileStatus )
+ {
+ case RMobileCall::EStatusUnknown:
+ tempCoreStatus = RCall::EStatusUnknown;
+ tempMobileStatus = RMobileCall::EStatusUnknown;
+ //get out of loop, resulting status is unknown...
+ i = numberOfObjectsInCallList;
+ break;
+ case RMobileCall::EStatusConnected:
+ tempCoreStatus = RCall::EStatusConnected;
+ tempMobileStatus = RMobileCall::EStatusConnected;
+ //get out of loop, resulting status is unknown...
+ i = numberOfObjectsInCallList;
+ break;
+ case RMobileCall::EStatusRinging:
+ //update core status
+ if ( tempCoreStatus == RCall::EStatusIdle )
+ {
+ tempCoreStatus = RCall::EStatusRinging;
+ }
+ //update mobile status
+ if ( tempMobileStatus == RMobileCall::EStatusIdle ||
+ tempMobileStatus == RMobileCall::EStatusHold)
+ {
+ tempMobileStatus = mobileStatus;
+ }
+ break;
+ case RMobileCall::EStatusDialling:
+ if ( tempCoreStatus == RCall::EStatusIdle )
+ {
+ tempCoreStatus = RCall::EStatusDialling;
+ }
+ //update mobile status
+ if ( tempMobileStatus == RMobileCall::EStatusIdle ||
+ tempMobileStatus == RMobileCall::EStatusHold)
+ {
+ tempMobileStatus = mobileStatus;
+ }
+ break;
+ case RMobileCall::EStatusAnswering:
+ if ( tempCoreStatus == RCall::EStatusIdle ||
+ tempCoreStatus == RCall::EStatusRinging )
+ {
+ tempCoreStatus = RCall::EStatusAnswering;
+ }
+ //update mobile status
+ if ( tempMobileStatus == RMobileCall::EStatusIdle ||
+ tempMobileStatus == RMobileCall::EStatusRinging ||
+ tempMobileStatus == RMobileCall::EStatusHold )
+ {
+ tempMobileStatus = mobileStatus;
+ }
+ break;
+ case RMobileCall::EStatusConnecting:
+ if ( tempCoreStatus == RCall::EStatusIdle ||
+ tempCoreStatus == RCall::EStatusDialling )
+ {
+ tempCoreStatus = RCall::EStatusConnecting;
+ }
+ //update mobile status
+ if ( tempMobileStatus == RMobileCall::EStatusIdle ||
+ tempMobileStatus == RMobileCall::EStatusDialling ||
+ tempMobileStatus == RMobileCall::EStatusHold )
+ {
+ tempMobileStatus = mobileStatus;
+ }
+ break;
+ case RMobileCall::EStatusDisconnecting:
+ //update core status
+ if ( tempCoreStatus == RCall::EStatusIdle )
+ {
+ tempCoreStatus = RCall::EStatusHangingUp;
+ }
+ if ( tempMobileStatus == RMobileCall::EStatusIdle )
+ {
+ tempMobileStatus = mobileStatus;
+ }
+ break;
+ case RMobileCall::EStatusWaitingAlternatingCallSwitch:
+ if ( tempMobileStatus == RMobileCall::EStatusIdle )
+ {
+ tempMobileStatus = mobileStatus;
+ }
+ break;
+ case RMobileCall::EStatusHold:
+ if ( tempMobileStatus == RMobileCall::EStatusIdle ||
+ tempMobileStatus ==
+ RMobileCall::EStatusDisconnecting )
+ {
+ tempCoreStatus = iLineStatus;
+ tempMobileStatus = mobileStatus;
+ }
+ break;
+ case RMobileCall::EStatusIdle:
+ case RMobileCall::EStatusReconnectPending:
+ case RMobileCall::EStatusDisconnectingWithInband:
+ case RMobileCall::EStatusTransferring:
+ case RMobileCall::EStatusTransferAlerting:
+ default:
+ break;
+ }
+ }
+ }
+
+ //check if core status has changed
+ if ( tempCoreStatus != iLineStatus )
+ {
+ coreStatusChanged = ETrue;
+ iLineStatus = tempCoreStatus;
+ }
+
+ //check if mobile status has changed
+ if ( tempMobileStatus != iMobileLineStatus )
+ {
+ mobileStatusChanged = ETrue;
+ iMobileLineStatus = tempMobileStatus;
+ }
+
+ //get core status change notification req handle
+ TTsyReqHandle iNotifyStatusChangeHandle = iTsyReqHandleStore->
+ GetTsyReqHandle( EMultimodeLineNotifyStatusChange );
+
+ //if req handle available and status changed
+ if ( ( iNotifyStatusChangeHandle > 0 ) && coreStatusChanged )
+ {
+ *iRetLineStatus = iLineStatus;
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeLineNotifyStatusChange );
+ ReqCompleted( iNotifyStatusChangeHandle, ret );
+ }
+
+ //get mobile status change notification req handle
+ TTsyReqHandle iNotifyMobileLineStatusChangeHandle = iTsyReqHandleStore->
+ GetTsyReqHandle( EMultimodeLineMobileLineStatusChange );
+
+ //if req handle available and status changed
+ if ( iNotifyMobileLineStatusChangeHandle > 0
+ && ( coreStatusChanged || mobileStatusChanged ) )
+ {
+ *iRetMobileLineStatus = iMobileLineStatus;
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeLineMobileLineStatusChange );
+ ReqCompleted( iNotifyMobileLineStatusChangeHandle, ret );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::GetHookStatus
+// This CORE API method retrieves the current hook status. Method is not
+// currently supported,
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::GetHookStatus(
+ const TTsyReqHandle aTsyReqHandle,
+ RCall::THookStatus* )
+ {
+ ReqCompleted( aTsyReqHandle, KErrNotSupported );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::GetInfo
+// This CORE API method retrieves the current line information.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::GetInfo(
+ const TTsyReqHandle aTsyReqHandle,
+ RLine::TLineInfo* aLineInfo )
+ {
+ // The current hook status.
+ aLineInfo->iHookStatus = RCall::EHookStatusUnknown;
+ // The current line status.
+ aLineInfo->iStatus = iLineStatus;
+ // The name of the last call created on the line.
+ aLineInfo->iNameOfLastCallAdded = iNameOfLastCallAdded;
+ // The name of the call to which a new incoming call will be directed.
+ aLineInfo->iNameOfCallForAnswering = iNameOfCallForAnswering;
+
+ ReqCompleted( aTsyReqHandle, KErrNone );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::LineInfo
+// This method retrieves the current line information. The method is used by
+// MmPhone object.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+RPhone::TLineInfo CMmLineTsy::LineInfo() const
+ {
+ // Line info
+ RPhone::TLineInfo lineInfo;
+ // The current line status.
+ lineInfo.iStatus = iLineStatus;
+ // line capabilities
+ lineInfo.iLineCapsFlags = iLineCaps.iFlags;
+ // line name
+ lineInfo.iName = iLineName;
+
+ return lineInfo;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyCapsChange
+// This CORE API method provides notification of a change in the line
+// capabilities.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyCapsChange(
+ const TTsyReqHandle aTsyReqHandle,
+ RLine::TCaps* aCaps )
+ {
+ // On return, contains the new line capabilities
+ iRetCaps = aCaps;
+ iTsyReqHandleStore->SetTsyReqHandle( EMultimodeLineCapsChangeNotification,
+ aTsyReqHandle );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyCapsChangeCancel
+// This CORE API method cancels an "line capabilities change" notification
+// request, placed using the NotifyCapsChange() method.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyCapsChangeCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iRetCaps = NULL;
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeLineCapsChangeNotification );
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::CompleteNotifyCapsChange
+// This method is used to notify to the client about the capabilities change.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmLineTsy::CompleteNotifyCapsChange()
+ {
+ //reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeLineCapsChangeNotification );
+
+ if ( EMultimodeLineReqHandleUnknown != reqHandle )
+ {
+ *iRetCaps = iLineCaps;
+ ReqCompleted( reqHandle, KErrNone );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyIncomingCall
+// This CORE API method is used to notify a client when an incoming call is
+// detected.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyIncomingCall(
+ const TTsyReqHandle aTsyReqHandle,
+ TName* aName )
+ {
+ // On notification, contains the name of the incoming call.
+ iRetIncomingCallName = aName;
+ iTsyReqHandleStore->SetTsyReqHandle( EMultimodeLineNotifyIncomingCall,
+ aTsyReqHandle );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyIncomingCallCancel
+// This CORE API method cancels an outstanding incoming call notification,
+// placed with the NotifyIncomingCall() method.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyIncomingCallCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iRetIncomingCallName = NULL;
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeLineNotifyIncomingCall );
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyCallAdded
+// This CORE API method provides notification that a new call has been added
+// to the line.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyCallAdded(
+ const TTsyReqHandle aTsyReqHandle,
+ TName* aName )
+ {
+ TFLOGSTRING2("TSY: CMmLineTsy::NotifyCallAdded requested by client, \
+ lineMode:%d", iLineMode);
+ // On return, contains the name of the new call.
+ iRetCallAdded = aName;
+ iTsyReqHandleStore->SetTsyReqHandle( EMultimodeLineNotifyCallAdded,
+ aTsyReqHandle );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyCallAddedCancel
+// This CORE API method cancels an outstanding "new call added" notification
+// request, placed using the NotifyCallAdded() method.(other items were
+// commented in a header).
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyCallAddedCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ TFLOGSTRING("TSY: CMmLineTsy::NotifyCallAddedCancel requested by client");
+ iRetCallAdded = NULL;
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeLineNotifyCallAdded );
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::CompleteNotifyCallAdded
+// This CORE API method is used to notify to the client that a call has been
+// added to the line. NOTE: Type is not defined because this method may be
+// called when incoming call occurs or when a call object has been created.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmLineTsy::CompleteNotifyCallAdded(const TDesC& aName )
+ {
+ TFLOGSTRING3("TSY: CMmLineTsy::CompleteNotifyCallAdded entered, \
+ CALL ADDED, Call name: %S, Call mode: %d", &aName, iLineMode );
+
+ //reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeLineNotifyCallAdded );
+
+ iNumCalls++;
+
+ if ( EMultimodeLineReqHandleUnknown != reqHandle )
+ {
+ TFLOGSTRING("TSY: CMmLineTsy::CompleteNotifyCallAdded, Completed!");
+ *iRetCallAdded = aName;
+ ReqCompleted( reqHandle, KErrNone );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::GetCaps
+// This CORE API method retrieves the line capabilities.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::GetCaps(
+ const TTsyReqHandle aTsyReqHandle,
+ RLine::TCaps* aCaps )
+ {
+ *aCaps = iLineCaps;
+ ReqCompleted( aTsyReqHandle, KErrNone );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::GetStatus
+// This CORE API method returns core line status information.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::GetStatus(
+ const TTsyReqHandle aTsyReqHandle,
+ RCall::TStatus* aStatus )
+ {
+ *aStatus = iLineStatus;
+ ReqCompleted( aTsyReqHandle, KErrNone );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyHookChange
+// This CORE API method provides notification when the hook status changes.
+// Feature is not supported.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyHookChange(
+ const TTsyReqHandle aTsyReqHandle,
+ RCall::THookStatus* )
+ {
+ ReqCompleted( aTsyReqHandle, KErrNotSupported );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyHookChangeCancel
+// This CORE API method cancels an outstanding hook change notification req
+// placed using the NotifyHookChange() method. Feature is not supported.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyHookChangeCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ ReqCompleted( aTsyReqHandle, KErrNotSupported );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::GetCallInfo
+// This CORE API method returns information about a call.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::GetCallInfo(
+ const TTsyReqHandle aTsyReqHandle,
+ TCallInfoIndex* aCallInfoIndex )
+ {
+ TFLOGSTRING3("TSY: CMmLineTsy::GetCallInfo - Line name: %S, Index: %d",
+ &iLineName, aCallInfoIndex->iIndex );
+
+ TInt ret( KErrNotFound );
+
+ // Check if the call object can be found from call list by index
+ CMmCallTsy* mmCall = REINTERPRET_CAST( CMmCallTsy*,
+ iMmPhone->CallList()->GetMmCallByIndexAndLine(
+ aCallInfoIndex->iIndex, &iLineName ) );
+
+ // If call object was found, fill the client pointer with call information
+ if ( mmCall )
+ {
+ aCallInfoIndex->iInfo.iCallName = mmCall->CallName();
+ aCallInfoIndex->iInfo.iStatus = mmCall->Status();
+ aCallInfoIndex->iInfo.iCallCapsFlags = mmCall->CallCaps();
+
+ TFLOGSTRING3("TSY: CMmLineTsy::GetCallInfo - Call name: %S, Status: %d",
+ &aCallInfoIndex->iInfo.iCallName, aCallInfoIndex->iInfo.iStatus );
+
+ ret = KErrNone;
+ }
+
+ ReqCompleted( aTsyReqHandle, ret );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::CancelService
+// 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. Core API requests are directed to the
+// LineBase.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::CancelService(
+ const TInt aIpc,
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ TInt ret( KErrNone );
+
+ // When the clients close their sub-sessions (eg. by calling RLine::Close)
+ // they may not have cancelled all their outstanding asynchronous requests
+ // before closing. It is up to the ETel server to clean up in this
+ // situation, so the server will find the list of outstanding requests
+ // related to that sub-session object and pass these outstanding IPC
+ // request numbers, one at a time, to the CancelService method in the TSY.
+
+ switch ( aIpc )
+ {
+ //TSY has started a request and it is not possible to then cancel
+ //this request. The best thing for the TSY to do in this case is to
+ //proceed as though the Cancel never happened. The server's call to
+ //the TSY cancel function will return synchronously. The TSY then
+ //continues to wait for the original acknowledgement and when it
+ //receives it, the TSY will complete the original request.
+ //case XXX
+ // break;
+
+ //Cancel methods that are not supported
+ //case XXX:
+ // ret = KErrNotSupported;
+ // break;
+
+ //Notification Cancels, no special requirements.
+ case EMobileLineNotifyMobileLineStatusChange:
+ ret = NotifyMobileLineStatusChangeCancel( aTsyReqHandle );
+ break;
+ //Everything is taken care in the method implementation.
+ //Just direct the request to the method.
+ //case XXX:
+ // ret = XXXCancel( aTsyReqHandle );
+ // break;
+
+ default:
+ return CLineBase::CancelService( aIpc, aTsyReqHandle );
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::RegisterNotification
+// RegisterNotification is called when the server recognises that this
+// notification is being posted for the first time on this sub-session object.
+// It enables the TSY to "turn on" any regular notification messages that it
+// may receive from DOS. Currently does not really do anything but returns
+// KErrNone to ETel server in case of known notification request type.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::RegisterNotification(
+ const TInt aIpc )
+ {
+ TInt ret( KErrNone );
+
+ switch ( aIpc )
+ {
+ case EEtelLineNotifyStatusChange:
+ case EEtelLineNotifyCallAdded:
+ case EETelLineCapsChangeNotification:
+ case EEtelLineNotifyHookChange:
+ case EEtelLineNotifyIncomingCall:
+ case EMobileLineNotifyMobileLineStatusChange:
+ ret = KErrNone;
+ break;
+ default:
+ // Unknown or invalid IPC
+ ret = KErrNotSupported;
+ }
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::DeregisterNotification
+// DeregisterNotification is called when the server recognises that this
+// notification will not be posted again because the last client to have a
+// handle on this sub-session object has just closed the handle. It enables
+// TSY to "turn off" any regular notification messages that it may receive
+// from DOS. Currently does not really do anything but returns KErrNone to
+// ETel server in case of known notification request type.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::DeregisterNotification(
+ const TInt aIpc )
+ {
+ TInt ret( KErrNone );
+
+ switch ( aIpc )
+ {
+ case EEtelLineNotifyStatusChange:
+ case EEtelLineNotifyCallAdded:
+ case EETelLineCapsChangeNotification:
+ case EEtelLineNotifyHookChange:
+ case EEtelLineNotifyIncomingCall:
+ case EMobileLineNotifyMobileLineStatusChange:
+ ret = KErrNone;
+ break;
+ default:
+ // Unknown or invalid IPC
+ ret = KErrNotSupported;
+ }
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NumberOfSlotsL
+// 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.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NumberOfSlotsL(
+ const TInt aIpc )
+ {
+ //There is a buffer in the ETel server for each type of NOTIFICATION and
+ //the size of the buffer is determined by the TSY. When the ETel server
+ //discovers that a request is "repost immediately" it will ask the TSY how
+ //big a buffer it wants by calling CTelObject::NumberOfSlotsL( ).
+ //
+ //It is up to the TSY developer's judgement how many buffer slots this
+ //method returns for each notification. If there is a danger that a
+ //particular notification could trigger frequently and in rapid succession
+ //(e.g. call group change notification) then at least 10 or 20 slots may
+ //be required. For a notification that triggers rarely, perhaps 1 or 2
+ //slots is enough.
+ //
+ //So if the ETel server has stored a few occurrences of a particular
+ //notification, when a client subsequently calls that notification request
+ //the ETel server will complete the client's request with the saved data.
+
+ TInt numberOfSlots( 1 );
+
+ switch ( aIpc )
+ {
+ case EEtelLineNotifyStatusChange:
+ numberOfSlots = KMmLineStatusChangeSlots;
+ break;
+ case EEtelLineNotifyCallAdded:
+ numberOfSlots = KMmLineCallAddedSlots;
+ break;
+ case EETelLineCapsChangeNotification:
+ numberOfSlots = KMmLineCapsChangeSlots;
+ break;
+ case EEtelLineNotifyHookChange:
+ numberOfSlots = KMmLineHookChangeSlots;
+ break;
+ case EEtelLineNotifyIncomingCall:
+ numberOfSlots = KMmLineIncomingCallSlots;
+ break;
+ case EMobileLineNotifyMobileLineStatusChange:
+ numberOfSlots = KMmLineMobileLineStatusChangeSlots;
+ break;
+ default:
+ // Unknown or invalid Line IPC
+ User::Leave( KErrNotSupported );
+ break;
+ }
+ return numberOfSlots;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::LineMode
+// Returns line mode.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+RMobilePhone::TMobileService CMmLineTsy::LineMode() const
+ {
+ return iLineMode;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::LineName
+// Returns line name.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TName CMmLineTsy::LineName() const
+ {
+ return iLineName;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::GetMobileLineStatus
+// Returns the current status of the line through the aStatus argument. The
+// possible line states map to the call states (see MM API spec) so that a
+// line that has one or more calls opened from it will have a status defined
+// by this table.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::GetMobileLineStatus(
+ const TTsyReqHandle aTsyReqHandle,
+ RMobileCall::TMobileCallStatus* aStatus )
+ {
+ *aStatus = iMobileLineStatus;
+ ReqCompleted( aTsyReqHandle, KErrNone );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyMobileLineStatusChange
+// Allows a client to be notified when the mobile line changes state. The
+// request completes when the line changes state, the new state being copied
+// to the aStatus parameter.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyMobileLineStatusChange(
+ RMobileCall::TMobileCallStatus* aStatus )
+ {
+ iRetMobileLineStatus = aStatus;
+ iReqHandleType = EMultimodeLineMobileLineStatusChange;
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::NotifyMobileLineStatusChangeCancel
+// Cancels an outstanding asynchronous NotifyMobileLineStatusChange request.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmLineTsy::NotifyMobileLineStatusChangeCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iRetMobileLineStatus = NULL;
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeLineMobileLineStatusChange );
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmLineTsy::CompleteNotifyAddBypassingCall
+// Handles ghost call object creation and initialisation. Also notifies
+// clients about the ghost call (using NotifyCallAdded method)
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmLineTsy::CompleteNotifyAddBypassingCall(
+ CMmDataPackage* aDataPackage )
+ {
+ TInt callId( -1 );
+ RMobilePhone::TMobileService callMode( RMobilePhone::EVoiceService );
+ RMobileCall::TMobileCallInfoV1* mobileCallInfo;
+
+ const CCallDataPackage* callData =
+ reinterpret_cast<const CCallDataPackage*>(aDataPackage);
+
+ callData->GetCallIdAndMode( callId, callMode );
+ callData->UnPackData ( &mobileCallInfo );
+
+ if ( mobileCallInfo->iStatus == RMobileCall::EStatusDialling ||
+ mobileCallInfo->iStatus == RMobileCall::EStatusConnecting ||
+ mobileCallInfo->iStatus == RMobileCall::EStatusConnected )
+ {
+ TFLOGSTRING2("TSY: CMmLineTsy::CompleteNotifyAddBypassingCall, \
+ CALL INITIATED - NOT REQUESTED BY ETEL's CLIENT, Call ID: %d",
+ callId );
+
+ //create new call object
+ CMmCallTsy* mmGhostCall = CreateGhostCallObject(
+ callId, callMode, mobileCallInfo->iStatus );
+
+ if ( mmGhostCall )
+ {
+ // Add the new call to the list of calls
+ TInt ret( iMmPhone->CallList()->AddObject( mmGhostCall ) );
+
+ if ( KErrNone == ret )
+ {
+ mmGhostCall->CompleteNotifyMobileCallInfoChange(
+ aDataPackage );
+ CompleteNotifyStatusChange();
+ //inform ETel client that someone is creating a MO call
+ CompleteNotifyCallAdded( mmGhostCall->CallName() );
+ mmGhostCall->SetGhostCall( ETrue );
+ }
+ else
+ {
+ delete mmGhostCall;
+ }
+ }
+ }
+ else
+ {
+ TFLOGSTRING3("TSY: CMmLineTsy::CompleteNotifyAddBypassingCall, \
+ CALL NOT INITIATED - Call ID:%d, Call status:%d",
+ callId, mobileCallInfo->iStatus);
+ }
+ }
+
+#ifdef TF_LOGGING_ENABLED
+// ---------------------------------------------------------------------------
+// CMmLineTsy::ReqCompleted
+// Overloads CTelObject::ReqCompleted for logging purposes. It prints the
+// aTsyReqHandle and aError variable in the log file and then calls
+// CTelObject::ReqCompleted.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmLineTsy::ReqCompleted(
+ const TTsyReqHandle aTsyReqHandle,
+ const TInt aError )
+ {
+ TFLOGSTRING3("TSY: CMmLineTsy::ReqCompleted Handle:%d Error:%d",
+ aTsyReqHandle, aError);
+
+ CTelObject::ReqCompleted(aTsyReqHandle,aError);
+ }
+
+#endif
+
+
+// End of File