telephonyserverplugins/common_tsy/commontsy/src/mmtsy/cmmlinetsy.cpp
branchopencode
changeset 24 6638e7f4bd8f
parent 0 3553901f7fa8
--- 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