telephonyserverplugins/common_tsy/commontsy/src/mmfax/CMmFaxExt.cpp
changeset 0 3553901f7fa8
child 19 630d2f34d719
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserverplugins/common_tsy/commontsy/src/mmfax/CMmFaxExt.cpp	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,612 @@
+// 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 <ctsy/tflogger.h>
+#include "cmmfaxext.h"
+#include "cmmphonetsy.h"
+#include "cmmlinelist.h"
+#include "cmmfaxcalltsy.h"
+#include "cmmfaxlinetsy.h"
+#include <ctsy/pluginapi/cmmdatapackage.h>
+#include "cmmcallgsmwcdmaext.h"
+
+
+// ======== MEMBER FUNCTIONS ========
+
+CMmFaxExt::CMmFaxExt(
+    CMmCallTsy* aMmCall )   // call that owns this object
+    : iMmCall( reinterpret_cast<CMmFaxCallTsy*>( aMmCall ) )
+    {
+TFLOGSTRING2("TSY: CMmFaxExt::CMmFaxExt: Call Id:%d", iMmCall->CallId() );
+    iFax           = NULL;
+    iFaxSession    = NULL;
+    iFaxCompletion = NULL;
+    }
+
+void CMmFaxExt::ConstructL()
+    {
+TFLOGSTRING("TSY: CMmFaxExt::ConstructL");
+
+    // Create CMmFaxCompletion class for Fax Server.
+    iFaxCompletion = new (ELeave) CMmFaxCompletion();
+    iDataPortLoaned = EFalse;
+    }
+
+CMmFaxExt* CMmFaxExt::NewL(
+        CMmCallTsy* aMmCall )  // The call object which owns CMmFaxExt  
+    {
+TFLOGSTRING("TSY: CMmFaxExt::NewL");
+
+    CMmFaxExt* self = new ( ELeave ) CMmFaxExt( aMmCall );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+
+    return self;
+    }
+
+CMmFaxExt::~CMmFaxExt()
+    {
+    //This must execute here, if status is Idle (Fax Client API) on HangUp,
+    //this will never be executed. so we do it here. It is ok to call
+    //cleanup multiple times.
+    CleanUpFaxServer();
+
+    if ( iFax )
+        {
+TFLOGSTRING("TSY: CMmFaxExt::~CMmFaxExt: deleting iFax");
+        delete iFax;
+        iFax = NULL;
+        }
+
+    if (iFaxCompletion)
+        {
+TFLOGSTRING("TSY: CMmFaxExt::~CMmFaxExt: deleting iFaxCompletion");
+        delete iFaxCompletion;
+        iFaxCompletion = NULL;
+        }
+
+    // mark fax as unopened, so that it can be opened again.
+	if( iMmCall )
+		{
+		(reinterpret_cast<CMmFaxLineTsy*>( iMmCall->Line() ))->
+			iFaxOpened = EFalse;
+		}
+
+    iMmCall = NULL;
+    iFaxSession = NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::CompleteOperation
+// Completes ongoing read/write operation on CMmFaxCompletion object.
+// Returns: None
+// ---------------------------------------------------------------------------
+//
+void CMmFaxExt::CompleteOperation(
+        TInt aError ) 
+    {
+TFLOGSTRING("TSY: CMmFaxExt::CompleteOperation");
+     
+    if ( iFaxCompletion )
+        {
+        iFaxCompletion->CompleteOperation( aError );
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+// CMmFaxExt::ConfigureCompletion
+// Set fax request handle to CMmFaxCompletion class object.
+// Returns: None
+// ---------------------------------------------------------------------------
+//
+void CMmFaxExt::ConfigureCompletion(
+        const TTsyReqHandle aTsyReqHandle,  
+        CTelObject* aTelObject )            
+    {
+TFLOGSTRING("TSY: CMmFaxExt::Configure");
+
+    iFaxCompletion->Configure( aTsyReqHandle, aTelObject );
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::CreateFaxObject
+// Creates CMmTsyFax object and returns it.
+// Returns: Pointer to created object
+// ---------------------------------------------------------------------------
+//
+CTelObject* CMmFaxExt::OpenNewObjectByNameL(
+        const TDesC& aName )  
+    {
+TFLOGSTRING("TSY: CMmFaxExt::OpenNewObjectByNameL");
+
+    // check the name of opened object..
+    _LIT(KFaxObjectName, "FAX");
+    if ( aName != KFaxObjectName )
+        {
+        User::Leave(KErrNotSupported);
+        }
+
+    //  We only want one fax object to be opened per phone.
+    //  Previously only the connected call could open a fax object, so it was
+    //  easy to check whether one had already been opened. Now a fax call can
+    //  open a fax object at any time making it less clear how to check that
+    //  no other call has opened one.
+    RPhone::TLineInfo lineInfo = iMmCall->Line()->LineInfo();
+    TBool& faxOpened = (reinterpret_cast<CMmFaxLineTsy*>(
+        iMmCall->Owner() ))->iFaxOpened;
+    if ( lineInfo.iStatus != GetCallStatus() )
+        { 
+		// another fax call is in progress so this call cannot open a fax object
+        User::Leave( KErrEtelNotCallOwner );
+        }
+
+    if ( faxOpened )
+        {
+        // Another call on this line has already opened fax.
+        User::Leave( KErrAlreadyExists );
+        }
+
+
+    // create new fax object..
+    iFax = CMmTsyFax::NewL( this );
+
+    // set faxopened flag of the line object
+    faxOpened = ETrue;
+
+    return iFax;
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::FaxConnectHandler
+// Checks if some another uses fax line.
+// Returns: Error value
+// ---------------------------------------------------------------------------
+//
+TInt CMmFaxExt::FaxConnectHandler()
+    {
+TFLOGSTRING("TSY: CMmFaxExt::FaxConnectHandler");
+
+    TInt errorCode( KErrNone );
+
+    if ( (reinterpret_cast<CMmFaxLineTsy*>( iMmCall->Line() ))->iFaxOpened 
+          && NULL == iFax )
+        {
+        iMmCall->SetUnowned();
+        errorCode = KErrEtelNotFaxOwner;
+        }
+    else
+        {
+        TRAP( errorCode, GetFaxBaseL() );
+        if ( KErrNone != errorCode )
+            {
+            iMmCall->SetUnowned();
+            }
+        }
+    return errorCode;
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::AnswerIncomingCall
+// Starts waiting for incoming fax call
+// Returns: Error value
+// ---------------------------------------------------------------------------
+//
+TInt CMmFaxExt::AnswerIncomingCall(
+        const TTsyReqHandle& aTsyReqHandle ) // function identification handle
+    {
+TFLOGSTRING("TSY: CMmFaxExt::AnswerIncomingCall");
+    
+    TInt ret( KErrGeneral );
+
+    // check and set call ownership..
+    MCallBaseTSY::TCallOwnership ownerShip = iMmCall->CheckOwnership( 
+      aTsyReqHandle );
+    if ( ownerShip == MCallBaseTSY::EOwnedUnowned 
+         || ownerShip == MCallBaseTSY::EOwnedPriorityClient ) 
+        {
+        iMmCall->SetOwnership( aTsyReqHandle );
+
+        // open faxserver library and faxserver session (iFaxSession)
+        ret = FaxConnectHandler(); 
+        if ( KErrNone == ret )
+            {
+            ret = OpenFaxServer(NULL, EWaitForRingAndReceive);
+            if ( KErrNone == ret )
+                {
+                ConfigureCompletion(aTsyReqHandle, iMmCall);
+                iFaxSession->RxConnect();
+                }
+            }
+
+        }
+    else // ownership test failed
+        {
+        ret = KErrEtelNotCallOwner;
+        }
+
+    // We don't complete erroneous request here since
+    // CTsyCall::AnswerIncomingCall (calling function) does it for us..
+    return ret;
+    }
+    
+// ---------------------------------------------------------------------------
+// CMmFaxExt::Dial
+// Start fax call connection.
+// Returns: Error value
+// ---------------------------------------------------------------------------
+//
+TInt CMmFaxExt::Dial(
+        const TTsyReqHandle& aTsyReqHandle, 
+        TDesC* aTelNumber )      
+    {
+TFLOGSTRING("TSY: CMmFaxExt::Dial");
+    
+    TInt ret( KErrGeneral );
+
+    // check and set call ownership..
+    MCallBaseTSY::TCallOwnership ownerShip = iMmCall->CheckOwnership( 
+      aTsyReqHandle );
+    if( ownerShip == MCallBaseTSY::EOwnedUnowned
+         || ownerShip == MCallBaseTSY::EOwnedPriorityClient ) 
+        {
+        iMmCall->SetOwnership( aTsyReqHandle );
+
+        ret = FaxConnectHandler();
+        if( KErrNone == ret )
+            {
+            TFaxMode faxMode;
+            if( RCall::ETransmit == iFaxSettings.iMode )
+                {
+                faxMode = EDialAndTransmit;
+                }
+            // we're receiving
+            else    
+                {
+                if( RCall::EFaxPoll  == iFaxSettings.iFaxRetrieveType )
+                    {
+                    faxMode = EDialAndReceivePoll;
+                    }
+                else 
+                    {
+                    faxMode = EDialAndReceiveFaxBack; 
+                    }
+                }
+
+            ret = OpenFaxServer( aTelNumber, faxMode );
+            if( KErrNone == ret )
+                {
+                ConfigureCompletion( aTsyReqHandle, iMmCall );
+                if( EDialAndTransmit == faxMode )
+                    {
+TFLOGSTRING("TSY: CMmFaxExt::FaxDial:TxConnect");
+                    iFaxSession->TxConnect();
+                    }
+                else
+                    {
+TFLOGSTRING("TSY: CMmFaxExt::FaxDial:RxConnect");
+                    iFaxSession->RxConnect();
+                    }
+                }
+            } // faxconnect
+        }
+    else 
+        {
+        // ownership test failed
+        ret = KErrEtelNotCallOwner;
+        }
+
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::HangUp
+// Hangup fax call.
+// Returns:None
+// ---------------------------------------------------------------------------
+//
+void CMmFaxExt::HangUp()
+    {
+TFLOGSTRING("TSY: CMmFaxExt::HangUp");
+    CleanUpFaxServer();
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::FaxSession
+// Returns Fax session pointer.
+// Returns:Pointer to Fax session 
+// ---------------------------------------------------------------------------
+//
+CFaxSession* CMmFaxExt::GetFaxSession()
+    {
+    return iFaxSession;
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::GetFaxBaseL
+// Loads fax server.
+// Returns:None 
+// ---------------------------------------------------------------------------
+//
+void CMmFaxExt::GetFaxBaseL()
+    {
+TFLOGSTRING("TSY: CMmFaxExt::GetFaxBaseL");
+
+    TInt errorCode = iFaxServerLib.Load( KFaxServerName );
+
+    if ( KErrNone == errorCode )
+        {
+#if defined (_UNICODE)
+            if( iFaxServerLib.Type()[1] != TUid::Uid( 
+                  KUidUnicodeDynamicFaxServer ) )
+                {
+                errorCode = KErrBadLibraryEntryPoint;
+                }
+#else
+            if( iFaxServerLib.Type()[1] != TUid::Uid( KUidDynamicFaxServer ) )
+                {
+                errorCode = KErrBadLibraryEntryPoint;
+                }
+#endif
+        
+        if ( KErrNone == errorCode )
+            {   
+            TFaxServerEntry libEntry = reinterpret_cast<TFaxServerEntry>(
+                iFaxServerLib.Lookup( 1 ) );
+            if ( libEntry != NULL )
+                {
+                // call CFaxSession::NewL(). LibEntry may leave.
+                TRAP( errorCode, iFaxSession = (*libEntry)(); );  
+                if ( KErrNone == errorCode )
+                    {
+                    // fax server session has been created,
+                    // Now set completion callback, it's methods called by
+                    // fax server when something significant happens
+                    iFaxSession->SetCallBack( iFaxCompletion );
+                    }
+                else
+                    {
+                    // failed to create fax server session
+                    iFaxServerLib.Close();
+                    }
+                }
+            else
+                {
+                // entry point was not found
+                errorCode = KErrBadLibraryEntryPoint;
+                iFaxServerLib.Close();
+                }
+            }
+        else
+          {
+            // Uid type test failed
+            iFaxServerLib.Close();
+          }
+        }
+    User::LeaveIfError( errorCode );
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::OpenFaxServer
+// Open CFaxSession object with desired settings.
+// Returns: Error Code 
+// ---------------------------------------------------------------------------
+//
+TInt CMmFaxExt::OpenFaxServer(
+        const TDesC* aTelNumber,  // phone number
+        const TFaxMode aFaxMode ) // fax mode
+    {
+TFLOGSTRING("TSY: CMmFaxExt::OpenFaxServer");
+
+    TInt errorCode ( KErrNone );
+    TFaxServerSessionSettings faxSettings;
+    if ( aTelNumber )
+        {
+        faxSettings.iPhoneNumber.Copy( *aTelNumber );
+        }
+    else
+        {
+        faxSettings.iPhoneNumber.Zero();
+        }
+
+    // Dataport names
+    _LIT( KDataPortPort, "DATAPORT::0" );
+    _LIT( KDataPortName, "DATAPORT");
+
+    faxSettings.iLogging          = ETrue;
+    faxSettings.iMode             = aFaxMode;
+    faxSettings.iFaxClass         = iFaxSettings.iFaxClass;
+    faxSettings.iPortDriverName   = KDataPortName;
+    faxSettings.iCommPortName     = KDataPortPort;
+    faxSettings.iFaxId            = iFaxSettings.iFaxId;
+    faxSettings.iMaxSpeed         = iFaxSettings.iMaxSpeed;
+    faxSettings.iMinSpeed         = iFaxSettings.iMinSpeed;
+    faxSettings.iPreferredECM     = iFaxSettings.iPreferredECM;
+    faxSettings.iFaxOnDemandDelay = iFaxSettings.iFaxOnDemandDelay;
+    faxSettings.iTxResolution     = iFaxSettings.iTxResolution;
+    faxSettings.iTxCompression    = iFaxSettings.iTxCompression;
+    faxSettings.iTxPages          = iFaxSettings.iTxPages;
+    faxSettings.iRxResolution     = iFaxSettings.iRxResolution;
+    faxSettings.iRxCompression    = iFaxSettings.iRxCompression;
+    RFax::TProgress* faxProgress  = iMmCall->CreateFaxProgressChunk();
+
+    if ( NULL == faxProgress )
+        {
+        errorCode = KErrEtelFaxChunkNotCreated;
+        }
+    else
+        {
+        // allocate dataport for fax...
+        RCall::TCommPort commPort;
+        commPort.iCsy.Copy( KDataPortName );
+        commPort.iPort.Copy( KDataPortPort );
+
+        //Create package
+        CCallDataPackage package;
+        //Set call id and call mode
+        package.SetCallIdAndMode(
+            iMmCall->CallId(), RMobilePhone::ECircuitDataService );
+        //Pack commport
+        package.PackData( &commPort );
+
+        //Send request to the Domestic OS layer.
+        TInt trapError( KErrNone );
+        TRAP( trapError,
+            errorCode = iMmCall->Phone()->MessageManager()->
+                HandleRequestL( EEtelCallLoanDataPort, &package );
+            );
+
+        if ( KErrNone != trapError )
+            {
+            //error handling, leaved.
+            errorCode = trapError;
+            }
+
+        // if dataport is allocated, open fax server
+        if (errorCode == KErrNone)
+            {
+            errorCode = iFaxSession->FxOpen( faxSettings, faxProgress );
+
+            if (errorCode != KErrNone)
+                {
+                // error, free dataport
+                //Send request to the Domestic OS layer.
+                trapError = KErrNone;
+                TRAP( trapError,
+                    errorCode = iMmCall->Phone()->MessageManager()->
+                        HandleRequestL( EEtelCallRecoverDataPort, &package );
+                    );
+
+                if ( KErrNone != trapError )
+                    {
+                    //error handling, leaved.
+                    errorCode = trapError;
+                    }
+                }
+            else
+                {
+                iDataPortLoaned = ETrue;
+                }
+            }
+        }
+    
+    return errorCode;
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::CleanUpFaxServer
+// Closes Fax Server, deletes fax progress chunk and closes Fax Server library
+// Returns: None 
+// ---------------------------------------------------------------------------
+//
+void CMmFaxExt::CleanUpFaxServer()
+    {
+TFLOGSTRING("TSY: CMmFaxExt::CleanUpFaxServer");
+
+    if ( iFaxSession )
+        {
+        iFaxSession->FxClose();
+        iMmCall->DeleteFaxProgressChunk();
+        iFaxServerLib.Close();
+
+        if ( iDataPortLoaned )
+            {
+            // free dataport
+            _LIT( KDataPortPort, "DATAPORT::0" );
+            _LIT( KDataPortName, "DATAPORT");
+
+            RCall::TCommPort commPort;
+            commPort.iCsy.Copy( KDataPortName );
+            commPort.iPort.Copy( KDataPortPort );
+
+            //Create package
+            CCallDataPackage package;
+            //Set call id and call mode
+            package.SetCallIdAndMode(
+                iMmCall->CallId(), RMobilePhone::ECircuitDataService );
+            //Pack commport
+            package.PackData( &commPort );
+
+            //Send request to the Domestic OS layer.
+            TRAPD( trapError,
+                iMmCall->Phone()->MessageManager()->
+                    HandleRequestL( EEtelCallRecoverDataPort, &package );
+                );
+            }
+
+        iFaxSession = NULL;
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+// CMmFaxExt::GetFaxSettings
+// Get fax settings from CMmFaxExt class object's member variable.
+// Returns: Error Value 
+// ---------------------------------------------------------------------------
+//
+ TInt CMmFaxExt::GetFaxSettings(
+        RCall::TFaxSessionSettings* aSettings ) 
+    {
+TFLOGSTRING("TSY: CMmFaxExt::GetFaxSettings");
+    *aSettings = iFaxSettings;
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::SetFaxSettings
+// Set fax settings to CMmFaxExt class object's member variable.
+// Returns: Error Value 
+// ---------------------------------------------------------------------------
+//
+ TInt CMmFaxExt::SetFaxSettings(
+        const RCall::TFaxSessionSettings* aSettings ) // in: fax settings.
+    {
+TFLOGSTRING("TSY: CMmFaxExt::SetFaxSettings");
+        iFaxSettings = *aSettings;
+        return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::GetCallStatus
+// Returns call status from CMmCallTsy object.
+// Returns: Call status 
+// ---------------------------------------------------------------------------
+//
+RCall::TStatus CMmFaxExt::GetCallStatus() const
+    {
+    return iMmCall->Status();
+    }
+
+// ---------------------------------------------------------------------------
+// CMmFaxExt::GetCallStatus
+// Sets terminate flag true on CMmTsyFax object.
+// Returns:  None 
+// ---------------------------------------------------------------------------
+//
+void CMmFaxExt::DialCancel()
+    {
+    TFLOGSTRING("TSY: CMmFaxExt::DialCancel");
+    if ( iFax ) 
+        {
+        iFax->Terminate();
+        }
+    }
+
+// ========================== OTHER EXPORTED FUNCTIONS =======================
+
+//  End of File