convergedcallengine/cce/src/cccetransfercontroller.cpp
changeset 0 ff3b6d0fd310
equal deleted inserted replaced
-1:000000000000 0:ff3b6d0fd310
       
     1 /*
       
     2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Contains transfer handling logic
       
    15 *
       
    16 */
       
    17 
       
    18 #include "cccelogger.h"
       
    19 #include "cccetransfercontroller.h"
       
    20 #include "cccecallcontainer.h"
       
    21 #include "cccecall.h"
       
    22 #include "mccpcall.h"
       
    23 #include "mccpcscall.h"
       
    24 #include "mccecallobserver.h"
       
    25 
       
    26 // ======== MEMBER FUNCTIONS ========
       
    27 
       
    28 
       
    29 // ---------------------------------------------------------------------------
       
    30 // Constructor
       
    31 // ---------------------------------------------------------------------------
       
    32 //
       
    33 CCCETransferController::CCCETransferController( 
       
    34     CCCECallContainer& aCallContainer ) :
       
    35     iCallContainer( aCallContainer )
       
    36     {
       
    37     Reset();
       
    38     }
       
    39 
       
    40 // ---------------------------------------------------------------------------
       
    41 // CCCETransferController::NewL
       
    42 // ---------------------------------------------------------------------------
       
    43 //
       
    44 CCCETransferController* CCCETransferController::NewL( 
       
    45     CCCECallContainer& aCallContainer )
       
    46     {
       
    47     CCCETransferController* self = new( ELeave ) CCCETransferController(
       
    48         aCallContainer );
       
    49     return self;
       
    50     }
       
    51 
       
    52 // ---------------------------------------------------------------------------
       
    53 // Destructor
       
    54 // ---------------------------------------------------------------------------
       
    55 //
       
    56 CCCETransferController::~CCCETransferController()
       
    57     {
       
    58     Reset();
       
    59     }
       
    60 
       
    61 // ---------------------------------------------------------------------------
       
    62 // CCCETransferController::ErrorOccurred
       
    63 // ---------------------------------------------------------------------------
       
    64 //
       
    65 void CCCETransferController::ErrorOccurred( 
       
    66     const TCCPError aError, MCCPCall* /*aCall*/ ) 
       
    67     {
       
    68     CCELOGSTRING2("CCCETransferController::ErrorOccurred() aError=%d", aError);    
       
    69     (void) aError; // remove urel compile warning 
       
    70     }
       
    71         
       
    72 // ---------------------------------------------------------------------------
       
    73 // CCCETransferController::CallStateChanged
       
    74 // ---------------------------------------------------------------------------
       
    75 //   
       
    76 void CCCETransferController::CallStateChanged( 
       
    77     const MCCPCallObserver::TCCPCallState aState, MCCPCall* /*aCall*/ ) 
       
    78     {
       
    79     CCELOGSTRING2("CCCETransferController::CallStateChanged():IN \
       
    80             aState=%d", aState);
       
    81     
       
    82     switch ( aState )
       
    83         {
       
    84         case ECCPStateIdle:
       
    85             {
       
    86             CCELOGSTRING("CCCETransferController::CallStateChanged: ECCPStateIdle");
       
    87             if ( iOriginatorCall && iObservedCall == iOriginatorCall )
       
    88                 {
       
    89                 CCELOGSTRING("CCCETransferController::CallStateChanged: Idle -> release original call");
       
    90                 iCallContainer.ReleaseCall( *iOriginatorCall, iOriginatorCall->Uid() ); 
       
    91                 iOriginatorCall = NULL;
       
    92                 iObservedCall = NULL;
       
    93                 }
       
    94             else if ( iTransferCall && iObservedCall == iTransferCall )
       
    95                 {
       
    96                 CCELOGSTRING("CCCETransferController::CallStateChanged: Idle -> release transfer call");
       
    97                 iCallContainer.ReleaseCall( *iTransferCall, iTransferCall->Uid() ); 
       
    98                 iTransferCall = NULL;
       
    99                 iObservedCall = NULL;
       
   100                 }
       
   101             }
       
   102             break;  
       
   103         case ECCPStateConnected:
       
   104             {
       
   105             CCELOGSTRING("CCCETransferController::CallStateChanged: ECCPStateConnected ");
       
   106             CCCECall* originator = iCallContainer.GetCall( iOriginatorCall );
       
   107             
       
   108             if ( !originator ||
       
   109                  ( originator->State() != CCPCall::EStateHold &&
       
   110                  originator->State() != CCPCall::EStateConnected ) )
       
   111                 {
       
   112                 // Originator disconnected or released.
       
   113                 // Terminate transfer call.
       
   114                 TInt err = iTransferCall->HangUp();
       
   115                 if ( err )
       
   116                     {
       
   117                     ReleaseTransferCall();
       
   118                     }
       
   119                 
       
   120                 }
       
   121             else if (  ECCETypeAttendedMO == iOngoingTransferType )
       
   122                 {
       
   123                 // Transfer call was connected
       
   124                 // Swap transfer call with original call and hangup&release
       
   125                 // original call
       
   126                 
       
   127                 
       
   128                 TRAPD( err, 
       
   129                        originator->SetConvergedCallL( iTransferCall, 
       
   130                            iTransferCall->Uid(), ETrue );
       
   131                        iTransferCall->RemoveObserver( *this );
       
   132                        iTransferCall->AddObserverL( *originator ); 
       
   133                        iOriginatorCall->RemoveObserver( *originator );
       
   134                        iOriginatorCall->AddObserverL( *this ); );
       
   135 
       
   136                 
       
   137     
       
   138                 iObservedCall = iOriginatorCall;
       
   139                 
       
   140                 if ( KErrNone == err )
       
   141                     {
       
   142                     // If original call was on hold, new call must be on hold also
       
   143                     if ( ECCPStateHold == originator->State() )
       
   144                         {
       
   145                         iTransferCall->Hold();
       
   146                         }
       
   147                    
       
   148                     // New call is no more on hold by remote end
       
   149                     static_cast<MCCPCallObserver*>(originator)->CallEventOccurred( ECCPRemoteResume, 
       
   150                                                                 &originator->GetCCPCall() ); 
       
   151                     }
       
   152                 else
       
   153                     {
       
   154                     CCELOGSTRING2("CCCETransferController::CallStateChanged():transfer error=%d",
       
   155                         err);
       
   156                     }
       
   157                 }
       
   158             else if ( ECCETypeAttendedMT == iOngoingTransferType ) 
       
   159                 {
       
   160                 
       
   161                 // Set new transferred call to original CCECall object
       
   162                 TRAP_IGNORE( originator->SetConvergedCallL( iTransferCall, 
       
   163                     iTransferCall->Uid(), ETrue ) );
       
   164                 
       
   165                 
       
   166                 // Release original call 
       
   167                 iOriginatorCall->RemoveObserver( *originator );
       
   168                 TRAP_IGNORE( iOriginatorCall->AddObserverL( *this ) );
       
   169                 
       
   170                 iObservedCall = iOriginatorCall;
       
   171                 iOriginatorCall->HangUp();
       
   172                 }
       
   173             }
       
   174             break;     
       
   175         default:
       
   176             CCELOGSTRING2("CCCETransferController::CallStateChanged: \
       
   177                     Unhandled state = %d",aState );
       
   178             break;
       
   179         }
       
   180     CCELOGSTRING("CCCETransferController::CallStateChanged():OUT");
       
   181     }
       
   182 
       
   183 // ---------------------------------------------------------------------------
       
   184 // CallStateChangedWithInband( TCCPCallState aState )
       
   185 // ---------------------------------------------------------------------------
       
   186 //
       
   187 void CCCETransferController::CallStateChangedWithInband( TCCPCallState aState, 
       
   188                                                          MCCPCall* aCall ) 
       
   189     {
       
   190     CCELOGSTRING("CCCETransferController::CallStateChangedWithInband()");
       
   191     CallStateChanged( aState, aCall );    
       
   192     }
       
   193 
       
   194 // ---------------------------------------------------------------------------
       
   195 // CCCETransferController::CallEventOccurred
       
   196 // ---------------------------------------------------------------------------
       
   197 // 
       
   198 void CCCETransferController::CallEventOccurred( 
       
   199     const MCCPCallObserver::TCCPCallEvent /*aEvent*/, MCCPCall* /*aCall*/ )
       
   200     {
       
   201     CCELOGSTRING("CCCETransferController::CallEventOccurred()");
       
   202     }
       
   203 
       
   204 // ---------------------------------------------------------------------------
       
   205 // CCCETransferController::CallCapsChanged
       
   206 // ---------------------------------------------------------------------------
       
   207 // 
       
   208 void CCCETransferController::CallCapsChanged( const TUint32 /*aCapsFlags*/, 
       
   209                                               MCCPCall* /*aCall*/ ) 
       
   210     {
       
   211     CCELOGSTRING("CCCETransferController::CallCapsChanged():");
       
   212     }
       
   213     
       
   214 // ---------------------------------------------------------------------------
       
   215 // CCCETransferController::Reset
       
   216 // ---------------------------------------------------------------------------
       
   217 //
       
   218 void CCCETransferController::Reset()
       
   219     {
       
   220     CCELOGSTRING("CCCETransferController::Reset()");
       
   221     iOriginatorCall = NULL;
       
   222     iOriginatorCallId = KErrNotFound;
       
   223     iTransferDialPending = EFalse;
       
   224     iTransferAccepted = EFalse;
       
   225     iOngoingTransferType = ECCETypeNone;
       
   226     iObservedCall = NULL;    
       
   227     }
       
   228     
       
   229 // ---------------------------------------------------------------------------
       
   230 // CCCETransferController::HandleRemoteTransferRequest
       
   231 // ---------------------------------------------------------------------------
       
   232 //
       
   233 void CCCETransferController::HandleRemoteTransferRequest( 
       
   234     MCCPCall* aNewTransferCall,
       
   235     MCCPCall* aOriginator, 
       
   236     TBool aAttented )                            
       
   237     {
       
   238     CCELOGSTRING("CCCETransferController::HandleTransferRequest():IN");
       
   239     
       
   240     CCCECall* originator = iCallContainer.GetCall( aOriginator );
       
   241     if ( originator && 
       
   242         ( originator->State() == CCPCall::EStateHold ||
       
   243           originator->State() == CCPCall::EStateConnected ) )
       
   244         {
       
   245         iOriginatorCall = aOriginator;
       
   246         iTransferCall = aNewTransferCall;
       
   247         
       
   248         // Unattended case
       
   249         if ( !aAttented )
       
   250             {        
       
   251             CCELOGSTRING("CCCETransferController::HandleTransferRequest() unattended ");
       
   252             iOriginatorCallId = originator->CallId();       
       
   253             iOngoingTransferType = ECCETypeUnattended;     
       
   254             originator->HandleTransfer( aAttented, *this );
       
   255             }
       
   256         // Attended case
       
   257         else
       
   258             {
       
   259             CCELOGSTRING("CCCETransferController::HandleTransferRequest() attended ");
       
   260             originator->SetTransferController( this );
       
   261             iOngoingTransferType = ECCETypeAttendedMO; 
       
   262             TRAP_IGNORE( iTransferCall->AddObserverL( *this ) );
       
   263             
       
   264             iObservedCall = iTransferCall;
       
   265             TInt error = iTransferCall->Dial(); 
       
   266             
       
   267             if( error )
       
   268                 {
       
   269                 CCELOGSTRING2("CCCETransferController: \
       
   270                     dial error: %d", error);
       
   271                 ReleaseTransferCall();    
       
   272                 }
       
   273             }
       
   274         }
       
   275     else
       
   276         {
       
   277         CCELOGSTRING("CCCETransferController: Originator call not found!");
       
   278         iCallContainer.ReleaseCall( *aNewTransferCall );
       
   279         }
       
   280     
       
   281     CCELOGSTRING("CCCETransferController::HandleTransferRequest():OUT");
       
   282     }
       
   283 
       
   284 // ---------------------------------------------------------------------------
       
   285 // CCCETransferController::TransferCallIncoming
       
   286 // ---------------------------------------------------------------------------
       
   287 //
       
   288 void CCCETransferController::TransferCallIncoming( MCCPCall* aNewTransferCall,
       
   289     MCCPCall* aOriginator )
       
   290     {
       
   291     CCELOGSTRING("CCCETransferController::TransferCallIncoming():IN");
       
   292     iTransferCall = aNewTransferCall;
       
   293     iOriginatorCall = aOriginator;
       
   294     
       
   295     CCCECall* originator = iCallContainer.GetCall( aOriginator );
       
   296     if ( originator )
       
   297         {
       
   298         originator->SetTransferController( this );
       
   299         
       
   300         iOngoingTransferType = ECCETypeAttendedMT;
       
   301          
       
   302         TInt err = KErrNone;
       
   303         TRAP( err, iTransferCall->AddObserverL( *this ) );
       
   304         if ( KErrNone == err )
       
   305             {
       
   306             iObservedCall = iTransferCall;
       
   307             // Answer new call when this gets connected original call will be terminated
       
   308             TInt err = iTransferCall->Answer(); 
       
   309             
       
   310             if ( KErrNone != err )
       
   311                 {
       
   312                 CCELOGSTRING2("CCCETransferController::TransferCallIncoming() Answering failed err=%d", err);
       
   313                 ReleaseTransferCall();
       
   314                 }
       
   315             }
       
   316         }
       
   317     else
       
   318         {
       
   319         CCELOGSTRING("CCCETransferController::TransferCallIncoming() originator not \
       
   320                 found");
       
   321         ReleaseTransferCall();
       
   322         }
       
   323      
       
   324     CCELOGSTRING("CCCETransferController::TransferCallIncoming():OUT");
       
   325     }
       
   326     
       
   327 // ---------------------------------------------------------------------------
       
   328 // CCCETransferController::ReleaseTransferCall
       
   329 // ---------------------------------------------------------------------------
       
   330 //
       
   331  void CCCETransferController::ReleaseTransferCall()
       
   332     {
       
   333     CCELOGSTRING("CCCETransferController::ReleaseTransferCall()");
       
   334     if ( iTransferCall )
       
   335         {
       
   336         iCallContainer.ReleaseCall(*iTransferCall);
       
   337         iTransferCall = NULL;
       
   338         Reset();
       
   339         CCELOGSTRING("CCCETransferController: TransferCall queued \
       
   340          to be released");
       
   341         }
       
   342     }
       
   343     
       
   344 // ---------------------------------------------------------------------------
       
   345 // CCCETransferController::OngoingTransferType
       
   346 // ---------------------------------------------------------------------------
       
   347 // 
       
   348 CCCETransferController::TTransferType CCCETransferController::OngoingTransferType() const
       
   349     {
       
   350     return iOngoingTransferType;    
       
   351     }
       
   352     
       
   353 // ---------------------------------------------------------------------------
       
   354 // CCCETransferController::TransferCall
       
   355 // ---------------------------------------------------------------------------
       
   356 // 
       
   357 MCCPCall* CCCETransferController::TransferCall() const
       
   358     {
       
   359     return iTransferCall;
       
   360     }
       
   361 
       
   362 // ---------------------------------------------------------------------------
       
   363 // CCCETransferController::OriginatorCall
       
   364 // ---------------------------------------------------------------------------
       
   365 // 
       
   366 MCCPCall* CCCETransferController::OriginatorCall() const
       
   367     {
       
   368     return iOriginatorCall;
       
   369     }
       
   370     
       
   371 // ---------------------------------------------------------------------------
       
   372 // CCCETransferController::SetTransferAccepted
       
   373 // ---------------------------------------------------------------------------
       
   374 //    
       
   375 void CCCETransferController::SetTransferAccepted( TBool aAccepted )
       
   376     {
       
   377     iTransferAccepted = aAccepted;
       
   378     }
       
   379 
       
   380 // ---------------------------------------------------------------------------
       
   381 // CCCETransferController::TransferAccepted
       
   382 // ---------------------------------------------------------------------------
       
   383 //      
       
   384 TBool CCCETransferController::TransferAccepted() const
       
   385     {
       
   386     return iTransferAccepted;
       
   387     }
       
   388     
       
   389 // ---------------------------------------------------------------------------
       
   390 // CCCETransferController::SetTransferDialPending
       
   391 // ---------------------------------------------------------------------------
       
   392 // 
       
   393 void CCCETransferController::SetTransferDialPending( TBool aDialPending )
       
   394     {
       
   395     CCELOGSTRING3("CCCETransferController::SetTransferDialPending() \
       
   396     iDialPending=%d aDialPending=%d",iTransferDialPending, aDialPending);
       
   397     iTransferDialPending = aDialPending;
       
   398     }
       
   399     
       
   400 // ---------------------------------------------------------------------------
       
   401 // CCCETransferController::HandleCallStateChanged
       
   402 // ---------------------------------------------------------------------------
       
   403 // 
       
   404 void CCCETransferController::HandleCallStateChanged( CCCECall* aCall,
       
   405         CCPCall::TCallState aStatus )
       
   406     {
       
   407     CCELOGSTRING2("CCCETransferController::HandleCallStatusChange():IN aStatus=%d",
       
   408             aStatus);
       
   409     
       
   410     switch ( aStatus )
       
   411         {         
       
   412         case CCPCall::EStateIdle:
       
   413         // flow through
       
   414         case CCPCall::EStateConnected:  
       
   415             {
       
   416             // When original or new call goes to idle/connected transfercontroller
       
   417             // can be resetted
       
   418             if( &aCall->GetCCPCall() == iOriginatorCall || 
       
   419                 &aCall->GetCCPCall() == iTransferCall )
       
   420                 {
       
   421                 Reset();
       
   422                 }
       
   423             }
       
   424             break;        
       
   425         case CCPCall::EStateDisconnecting:
       
   426             {
       
   427             // When original call goes to disconnecting state and there
       
   428             // is unattended transfer dial pending. Start dialing.
       
   429             if ( &aCall->GetCCPCall() == iOriginatorCall &&
       
   430                 iTransferDialPending )
       
   431                 {
       
   432                 CCCECall* call =iCallContainer.GetCall( iTransferCall );
       
   433                 if ( call )
       
   434                     {
       
   435                     iTransferDialPending = EFalse;
       
   436                     call->DoPendingRequest();
       
   437                     }
       
   438                 }
       
   439             }
       
   440             break;  
       
   441         default:
       
   442             CCELOGSTRING2("CCCETransferController::HandleCallStatusChange: \
       
   443                     Unhandled state = %d", aStatus );
       
   444         }
       
   445     CCELOGSTRING("CCCETransferController::HandleCallStatusChange():OUT");
       
   446     }
       
   447 // End of file