callcontinuity/vcchotrigger/src/vcchotrigger.cpp
branchRCL_3
changeset 28 d38647835c2e
child 29 755430a7d64b
equal deleted inserted replaced
27:f742655b05bf 28:d38647835c2e
       
     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:   Implementation of the handover trigger
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <e32base.h>
       
    21 
       
    22 #include <vccsubscribekeys.h>
       
    23 #include "vccuipsproperty.h"
       
    24 #include "vcchotrigger.h"
       
    25 #include "vccsignallevelhandler.h"
       
    26 #include "vccwlansignallevelhandler.h"
       
    27 #include "vccgsmsignallevelhandler.h"
       
    28 #include "rubydebug.h"
       
    29 #include "vcchopolicyreader.h"
       
    30 #include "vcccchmonitor.h"
       
    31 #include "vccengpsproperty.h"
       
    32 #include "cvccperformer.h"
       
    33 
       
    34 // Min. signal strength.
       
    35 static const TInt32 KStrengthMin = 110;
       
    36 
       
    37 // ======== MEMBER FUNCTIONS ========
       
    38 
       
    39 // ---------------------------------------------------------------------------
       
    40 // Symbian constructor
       
    41 // ---------------------------------------------------------------------------
       
    42 //
       
    43 EXPORT_C CVccHoTrigger* CVccHoTrigger::NewL()
       
    44     {
       
    45     RUBY_DEBUG_BLOCKL( "CVccHoTrigger::NewL" );
       
    46 
       
    47     CVccHoTrigger* self = new ( ELeave ) CVccHoTrigger();
       
    48 
       
    49     CleanupStack::PushL( self );
       
    50 
       
    51     self->ConstructL();
       
    52 
       
    53     CleanupStack::Pop( self );
       
    54 
       
    55     return self;
       
    56     }
       
    57 
       
    58 // ---------------------------------------------------------------------------
       
    59 // Destructor
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 CVccHoTrigger::~CVccHoTrigger()
       
    63     {
       
    64     RUBY_DEBUG0( "CVccHoTrigger::~CVccHoTrigger() - ENTER" );
       
    65 
       
    66     delete iProperty;
       
    67     delete iWlanSignalLevelHandler;
       
    68     delete iGsmSignalLevelHandler;
       
    69     delete iHoPolicyReader;
       
    70     delete iCchMonitor;
       
    71     delete iEngPsProperty;
       
    72     
       
    73     RUBY_DEBUG0( "CVccHoTrigger::~CVccHoTrigger() - EXIT" );
       
    74     }
       
    75 
       
    76 // -----------------------------------------------------------------------------
       
    77 // CVccHoTrigger::CVccHoTrigger()
       
    78 // C++ default constructor can NOT contain any code, that might leave.
       
    79 // -----------------------------------------------------------------------------
       
    80 //
       
    81 CVccHoTrigger::CVccHoTrigger() :         //: CActive( EPriorityStandard )
       
    82     iGsmClass( ESignalClassUndefined ),
       
    83     iWlanClass( ESignalClassUndefined ),
       
    84     iManualHoDone( EFalse ),
       
    85     iHoNotAllowed( EFalse ),
       
    86     iHoAllowedIfCsOriginated( ETrue )
       
    87     {
       
    88     RUBY_DEBUG_BLOCK( "CVccHoTrigger::CVccHoTrigger" );
       
    89     }
       
    90 // ---------------------------------------------------------------------------
       
    91 // 2nd phase constructor
       
    92 // ---------------------------------------------------------------------------
       
    93 //
       
    94 void CVccHoTrigger::ConstructL()
       
    95     {
       
    96     RUBY_DEBUG_BLOCKL( "CVccHoTrigger::ConstructL" );
       
    97 
       
    98     iProperty = CVccUiPsProperty::NewL();
       
    99     iHoPolicyReader = CVccHoPolicyReader::NewL();
       
   100     iHoPolicyReader->ReadSettingsL();
       
   101     
       
   102     iEngPsProperty = CVccEngPsProperty::NewL();
       
   103     iPolicy = iHoPolicyReader->HoPolicy();
       
   104     TSignalLevelParams gsm = iHoPolicyReader->CsSignalLevelParams();
       
   105     TSignalLevelParams wlan = iHoPolicyReader->PsSignalLevelParams();
       
   106     
       
   107 
       
   108     iWlanSignalLevelHandler =
       
   109         CVccWlanSignalLevelHandler::NewL( *this, wlan, *iEngPsProperty );
       
   110 
       
   111          
       
   112     iGsmSignalLevelHandler =
       
   113         CVccGsmSignalLevelHandler::NewL( *this, gsm );
       
   114   
       
   115     iHoAllowedIfCsOriginated = iPolicy.DtAllowedWhenCsOriginated();
       
   116     // Previous signal level class must be undefined
       
   117     iPreviousGsmClass = ESignalClassUndefined;
       
   118     iPreviousWlanClass = ESignalClassUndefined;
       
   119     // In the beginning the VoIP service is not available.
       
   120     // This will be changed when the cch monitor calls us
       
   121     // when the service is available.
       
   122     iCchServiceStatus = EServiceUnavailable;
       
   123     
       
   124     // CS network has signal level zero if the service is not
       
   125     // available.
       
   126     iCsSignalLevel = KStrengthMin;
       
   127 
       
   128     // We are not stared yet.
       
   129     iStarted = EFalse;
       
   130     
       
   131     // Update P&S keys to tell if we can do ho or not.    
       
   132     UpdatePsKeysL();
       
   133     // Create the CCH monitor. We are the observer to be
       
   134     // notified when the status changes.
       
   135     iCchMonitor = CVccCchMonitor::NewL( *this );
       
   136     }
       
   137 
       
   138 // -----------------------------------------------------------------------------
       
   139 // Stop monitoring
       
   140 // -----------------------------------------------------------------------------
       
   141 //
       
   142 EXPORT_C void CVccHoTrigger::Stop()
       
   143     {
       
   144     RUBY_DEBUG_BLOCK( "CVccHoTrigger::Stop" );
       
   145     Stop( *iWhoStartedMe );
       
   146     }
       
   147 
       
   148 // -----------------------------------------------------------------------------
       
   149 // Stop monitoring
       
   150 // -----------------------------------------------------------------------------
       
   151 //
       
   152 EXPORT_C void CVccHoTrigger::Stop( CVccPerformer& aStopper )
       
   153     {
       
   154     RUBY_DEBUG_BLOCK( "CVccHoTrigger::Stop" );
       
   155     // If someone else that the one who started us tries
       
   156     // to stop us, we do not allow it.
       
   157     // There may be several performers that are in differnet state
       
   158     // and in those state they do not need trigger and thus try
       
   159     // to stop us.
       
   160     if ( iWhoStartedMe == &aStopper )
       
   161         {
       
   162         iWhoStartedMe = NULL;
       
   163         iStarted = EFalse;
       
   164         TRAP_IGNORE( UpdatePsKeysL() );
       
   165         TRAP_IGNORE( iProperty->NotifySubscriberL( EVccNoRequestOngoing ) );
       
   166         iWlanSignalLevelHandler->Stop();
       
   167         iGsmSignalLevelHandler->Stop();
       
   168         
       
   169         iGsmClass = ESignalClassUndefined;
       
   170         iWlanClass = ESignalClassUndefined;        
       
   171         
       
   172         // Reset CS signal strength to min
       
   173         iCsSignalLevel = KStrengthMin;
       
   174         
       
   175         // Disable (do not send notifications).
       
   176         // The service is not actually disabled.
       
   177         // It will be disabled (if needed) when the monitor
       
   178         // is deleted.
       
   179         iCchMonitor->DisableService();
       
   180         RUBY_DEBUG0( " -Trigger stopped");
       
   181         }
       
   182     }
       
   183 
       
   184 // -----------------------------------------------------------------------------
       
   185 // Start monitoring
       
   186 // We must not leave.
       
   187 // -----------------------------------------------------------------------------
       
   188 //
       
   189 EXPORT_C void CVccHoTrigger::Start( CVccPerformer& aWhoStartedMe, 
       
   190                                     TBool aCsOriginated )
       
   191     {
       
   192     RUBY_DEBUG_BLOCK( "CVccHoTrigger::Start" );
       
   193     if( iHoAllowedIfCsOriginated == EFalse && aCsOriginated )
       
   194         {
       
   195         RUBY_DEBUG0( "HO not allowed for CS originated calls" );
       
   196                 
       
   197         Stop();
       
   198         return;
       
   199         }
       
   200     //anyone can start, but only the last one who started can stop the trigger
       
   201     iWhoStartedMe = &aWhoStartedMe;
       
   202     if( !iStarted )
       
   203         {
       
   204         
       
   205         // Previous signal level class must be undefined
       
   206         iPreviousGsmClass = ESignalClassUndefined;
       
   207         iPreviousWlanClass = ESignalClassUndefined;
       
   208     
       
   209         // read signal high/low levels, timers etc.
       
   210         TRAPD( err, iHoPolicyReader->ReadSettingsL() );
       
   211         RUBY_DEBUG1( "reading ho settings, err = %d", err );
       
   212         
       
   213         if ( !err )
       
   214         	{
       
   215 		    TSignalLevelParams gsm = iHoPolicyReader->CsSignalLevelParams();
       
   216 		    TSignalLevelParams wlan = iHoPolicyReader->PsSignalLevelParams();
       
   217 		    iPolicy = iHoPolicyReader->HoPolicy();
       
   218 		    
       
   219 		    iWlanSignalLevelHandler->SetParams( wlan );
       
   220 		    iGsmSignalLevelHandler->SetParams( gsm );
       
   221 		    
       
   222 		    TRAPD( err_wlan, iWlanSignalLevelHandler->StartL() );
       
   223 		    RUBY_DEBUG1( "starting wlan signal level handler, err = %d", err_wlan );
       
   224 		    TRAPD( err_gsm, iGsmSignalLevelHandler->StartL() );
       
   225 		    RUBY_DEBUG1( "starting gsm signal level handler, err = %d", err_gsm );
       
   226 		    
       
   227 		    if ( !err_wlan && !err_gsm )
       
   228 		    	{		    
       
   229 			    // Enable the VoIP service to be able to do VoIP calls.
       
   230 			    TRAPD( err_cch, iCchMonitor->EnableServiceL() );
       
   231 			    RUBY_DEBUG1( "enabling service, err = %d", err_cch );
       
   232 			    
       
   233 			    if ( !err_cch )
       
   234 			    	{
       
   235 			    	// Everything was started ok
       
   236 			    	iStarted = ETrue;
       
   237 			    	}
       
   238 		    	}
       
   239 		    else
       
   240 		    	{
       
   241 		    	// Stop the handlers just in case either one was started
       
   242 		    	iWlanSignalLevelHandler->Stop();
       
   243 		    	iGsmSignalLevelHandler->Stop();
       
   244 		    	}
       
   245         	}
       
   246         
       
   247         TRAP_IGNORE( UpdatePsKeysL() );
       
   248         }
       
   249     }
       
   250 
       
   251 // -----------------------------------------------------------------------------
       
   252 // Set the domain type of the current call
       
   253 // -----------------------------------------------------------------------------
       
   254 //
       
   255 EXPORT_C void CVccHoTrigger::SetCurrentDomainType( TCallDomainType aDomainType )
       
   256     {
       
   257     RUBY_DEBUG_BLOCK( "CVccHoTrigger::SetCurrentDomainType" );
       
   258     iDomainType = aDomainType;
       
   259     }
       
   260 
       
   261 // -----------------------------------------------------------------------------
       
   262 // Set the preferred domain type
       
   263 // -----------------------------------------------------------------------------
       
   264 //
       
   265 EXPORT_C void CVccHoTrigger::SetPreferredDomainType( 
       
   266                                         TVccHoPolicyPreferredDomain aDomainType )
       
   267     {
       
   268     RUBY_DEBUG1( "CVccHoTrigger::SetPreferredDomainType(%d)", aDomainType );
       
   269     iPolicy.SetPreferredDomain( aDomainType );
       
   270     }
       
   271 
       
   272 // -----------------------------------------------------------------------------
       
   273 // Set Immediate Domain Transfer on/off
       
   274 // -----------------------------------------------------------------------------
       
   275 //
       
   276 EXPORT_C void CVccHoTrigger::SetImmediateDomainTransfer( TBool aImmediateDT )
       
   277     {
       
   278     RUBY_DEBUG1( "CVccHoTrigger::SetImmediateDomainTransfer(%d)", aImmediateDT );
       
   279     iPolicy.SetDoImmediateHo(  aImmediateDT );
       
   280     }
       
   281 
       
   282 // -----------------------------------------------------------------------------
       
   283 // Handles wlan signal change notifications
       
   284 // -----------------------------------------------------------------------------
       
   285 //
       
   286 void CVccHoTrigger::WlanSignalChanged(
       
   287         TInt32 /*aSignalStrength*/,
       
   288         TSignalStrengthClass aClass )
       
   289     {
       
   290     RUBY_DEBUG_BLOCK( "CVccHoTrigger::WlanSignalChanged" );
       
   291 
       
   292     //Store signal strength class to that we know later what is the strength
       
   293     iWlanClass = aClass;
       
   294     
       
   295     RUBY_DEBUG1( " -iWlanClass=%x ", iWlanClass );
       
   296     RUBY_DEBUG1( " -iDomainType=%x ", iDomainType );
       
   297     RUBY_DEBUG1( " -iGsmClass=%x ", iGsmClass );
       
   298     RUBY_DEBUG1( " -DoImmediateHO=%x ", iPolicy.DoImmediateHo() );
       
   299     RUBY_DEBUG1( " -PreferredDomain=%x ", iPolicy.PreferredDomain() );
       
   300     RUBY_DEBUG1( " -iGsmClass=%x ", iGsmClass );
       
   301     RUBY_DEBUG1( " -DoHoInHeldWaitingCalls=%x ", iPolicy.DoHoInHeldWaitingCalls() );
       
   302     RUBY_DEBUG0( "0 = GOOD, 1 = WEAK, 2 = UNDEFINED" );
       
   303     
       
   304     // If the previous class is the same as the new one
       
   305     // - do nothing.
       
   306     
       
   307     if ( iPreviousWlanClass == iWlanClass )
       
   308         {
       
   309         if (iWlanClass == ESignalClassWeak)
       
   310             {
       
   311             RUBY_DEBUG0( "Signal is still weak try again to do HO" );
       
   312             }
       
   313         else
       
   314             {
       
   315             RUBY_DEBUG0( "No change in WLAN signal class -> return" );
       
   316             return;
       
   317             }
       
   318           }
       
   319     else
       
   320         {
       
   321         iPreviousWlanClass = iWlanClass;
       
   322         }
       
   323     
       
   324     TriggerHo();
       
   325      }
       
   326 
       
   327 // -----------------------------------------------------------------------------
       
   328 // Handles GSM singnal change notifications
       
   329 // -----------------------------------------------------------------------------
       
   330 //
       
   331 void CVccHoTrigger::GsmSignalChanged(
       
   332         TInt32 aSignalStrength,
       
   333         TSignalStrengthClass aClass )
       
   334     {
       
   335     RUBY_DEBUG_BLOCK( "VccHoTrigger::GsmSignalChanged" );
       
   336     RUBY_DEBUG1( " -iCsSignalLevel=%d ", aSignalStrength );
       
   337 
       
   338     //Store signal strength class to that we know later what is the strength
       
   339     iGsmClass = aClass;
       
   340     
       
   341     // Save the signal strength as "status".
       
   342     // Zero (0) means that the service is not available.
       
   343     iCsSignalLevel = aSignalStrength;
       
   344 
       
   345     // Update P&S keys to tell if we can do ho or not.
       
   346     // If the signal level has gone to zero, we are unable to
       
   347     // do hondover.
       
   348     
       
   349     TVccHoStatus hoStatus( EVccHoStateUnknown );
       
   350     iEngPsProperty->GetCurrentHoStatus( hoStatus );
       
   351     
       
   352     if( hoStatus != EVccCsToPsHoStarted || hoStatus != EVccCsToPsHoInprogress 
       
   353         || hoStatus != EVccPsToCsHoStarted || hoStatus != EVccPsToCsHoInprogress )
       
   354         {
       
   355         RUBY_DEBUG0( "HO not in progress,  updating keys" );
       
   356         TRAP_IGNORE( UpdatePsKeysL() );
       
   357         }
       
   358     
       
   359     RUBY_DEBUG1( " -iWlanClass=%x ", iWlanClass );
       
   360     RUBY_DEBUG1( " -iDomainType=%x ", iDomainType );
       
   361     RUBY_DEBUG1( " -iGsmClass=%x ", iGsmClass );
       
   362     RUBY_DEBUG1( " -DoImmediateHO=%x ", iPolicy.DoImmediateHo() );
       
   363     RUBY_DEBUG1( " -PreferredDomain=%x ", iPolicy.PreferredDomain() );
       
   364     RUBY_DEBUG1( " -DoHoInHeldWaitingCalls=%x ", iPolicy.DoHoInHeldWaitingCalls() );  
       
   365     RUBY_DEBUG0( "0 = GOOD, 1 = WEAK, 2 = UNDEFINED" );
       
   366     
       
   367     // If the previous class is the same as the new one
       
   368     // - do nothing.
       
   369     
       
   370     if ( iPreviousGsmClass == iGsmClass && iWlanClass != ESignalClassWeak  )
       
   371         {
       
   372         RUBY_DEBUG0( "No change in GSM signal class -> return" );
       
   373     
       
   374         return;
       
   375         }
       
   376     else
       
   377         {
       
   378         iPreviousGsmClass = iGsmClass;
       
   379         }
       
   380     
       
   381     TriggerHo();
       
   382     }
       
   383 
       
   384 // -----------------------------------------------------------------------------
       
   385 // Handles CCH monitor notifications
       
   386 // -----------------------------------------------------------------------------
       
   387 //
       
   388 void CVccHoTrigger::CchServiceStatusChanged( TServiceStatus aStatus )
       
   389     {
       
   390     RUBY_DEBUG_BLOCK( "VccHoTrigger::CchServiceStateChanged" );
       
   391     RUBY_DEBUG1( " -Service status = %d", aStatus );
       
   392     
       
   393     // Save the status
       
   394     iCchServiceStatus = aStatus;
       
   395     
       
   396     TRAP_IGNORE( UpdatePsKeysL() );
       
   397     TriggerHo();
       
   398     }
       
   399 
       
   400 // -----------------------------------------------------------------------------
       
   401 // Check if the CS or PS services are available or not
       
   402 // -----------------------------------------------------------------------------
       
   403 //
       
   404 TBool CVccHoTrigger::ServicesAvailable()
       
   405     {
       
   406     RUBY_DEBUG_BLOCK( "CVccHoTrigger::AreServicesAvailable" );
       
   407     
       
   408     TBool retVal( ETrue );
       
   409     
       
   410     // If PS service (VoIP service) is unavailable or
       
   411     // the CS service == 0 (i.e. signal level),
       
   412     // we cannot do handover.
       
   413     
       
   414     if ( iCchServiceStatus == EServiceUnavailable || 
       
   415                     iCsSignalLevel == KStrengthMin )
       
   416         {
       
   417         RUBY_DEBUG0( " -VoIP/CS service(s) not available" );
       
   418         retVal = EFalse;
       
   419         }
       
   420     
       
   421     return retVal;
       
   422     }
       
   423 
       
   424 // -----------------------------------------------------------------------------
       
   425 // Update (write) service status state to P&S.
       
   426 // -----------------------------------------------------------------------------
       
   427 //
       
   428 void CVccHoTrigger::UpdatePsKeysL()
       
   429     {
       
   430     RUBY_DEBUG_BLOCK( "CVccHoTrigger::UpdatePsKeysL" );
       
   431     
       
   432     // If we are started and both services are available,
       
   433     // handover can be done.
       
   434     // Services available in CS means that we have
       
   435     // signal strength != KStrengthMin (which is 110, returned
       
   436     // from the CS signal level monitor).
       
   437     
       
   438     RUBY_DEBUG1( " -iStarted = %d", iStarted );
       
   439     RUBY_DEBUG1( " -iHoNotAllowed = %d", iHoNotAllowed );
       
   440     RUBY_DEBUG1( " -Service status = %d (0=unavailable, 1=available)", iCchServiceStatus );
       
   441     RUBY_DEBUG1( " -CS signal min level = 110, current level = %d", iCsSignalLevel );
       
   442         
       
   443     if ( iStarted &&
       
   444             ( iCchServiceStatus == EServiceAvailable ) && 
       
   445             ( iCsSignalLevel != KStrengthMin ) &&
       
   446             ( !iHoNotAllowed ) )
       
   447         {
       
   448         RUBY_DEBUG0( " -We are started and both services are available" );
       
   449         // Check HO direction restrictions
       
   450         if ( ( iPolicy.AllowedDirection() & ECsToPsAllowed ) && 
       
   451                 ( iPolicy.AllowedDirection() & EPsToCsAllowed ) )
       
   452             {
       
   453             if( iPolicy.DoHoInHeldWaitingCalls() )
       
   454                 {
       
   455                 RUBY_DEBUG0( " -Services available and ho allowed to both \
       
   456                              directions, also in multicall" );
       
   457                 iEngPsProperty->NotifySubscriberL( EVccHoStateIdle, KErrNone );
       
   458                 }
       
   459             else
       
   460                 {
       
   461                 RUBY_DEBUG0( " -Services available and ho allowed to both \
       
   462                              directions but not in multicall" );
       
   463                 iEngPsProperty->NotifySubscriberL( EVccHoStateIdleIfSingleCall, KErrNone );
       
   464                 }
       
   465             }
       
   466         else if ( !( iPolicy.AllowedDirection() & ECsToPsAllowed  ) &&
       
   467                 ( iPolicy.AllowedDirection() & EPsToCsAllowed ) )
       
   468             {
       
   469             if( iPolicy.DoHoInHeldWaitingCalls() )
       
   470                 {
       
   471                 RUBY_DEBUG0( " -HO allowed only to CS" );
       
   472                 iEngPsProperty->NotifySubscriberL( EVccCsToPsNotAllowed, KErrNone );
       
   473                 }
       
   474             else
       
   475                 {
       
   476                 RUBY_DEBUG0( " -HO allowed only to CS, in single call situation" );
       
   477                 iEngPsProperty->NotifySubscriberL( EVccHoAllowedToCsIfSingleCall, KErrNone );
       
   478                 }
       
   479             }
       
   480         else if ( !( iPolicy.AllowedDirection() & EPsToCsAllowed ) &&  
       
   481                     ( iPolicy.AllowedDirection() & ECsToPsAllowed ) )
       
   482             {
       
   483             if( iPolicy.DoHoInHeldWaitingCalls() )
       
   484                 {
       
   485                 RUBY_DEBUG0( " -HO allowed only to PS" );
       
   486                 iEngPsProperty->NotifySubscriberL( EVccPsToCsNotAllowed, KErrNone );
       
   487                 }
       
   488             else
       
   489                 {
       
   490                 RUBY_DEBUG0( " -HO allowed only to PS, in single call situation" );
       
   491                 iEngPsProperty->NotifySubscriberL( EVccHoAllowedToPsIfSingleCall, KErrNone );
       
   492                 }
       
   493             }
       
   494         }
       
   495     else
       
   496         {
       
   497         RUBY_DEBUG0( " -We are stopped or services are unavailable:" );
       
   498         iEngPsProperty->NotifySubscriberL( EVccHoUnavailable, KErrNotReady );        
       
   499         }
       
   500     }
       
   501     
       
   502 // -----------------------------------------------------------------------------
       
   503 // If manual HO is done, no automatic should be made.
       
   504 // -----------------------------------------------------------------------------
       
   505 //
       
   506 EXPORT_C void CVccHoTrigger::ManualHoCallStarted()
       
   507     {
       
   508     RUBY_DEBUG_BLOCK( "CVccHoTrigger::ManualHoCallStarted" );
       
   509     iManualHoDone = ETrue;
       
   510     //notify Wlan Signal Level Handler so it can stop polling WLAN signal
       
   511     iWlanSignalLevelHandler->SetManualHoDone( ETrue );
       
   512     }
       
   513 
       
   514 // -----------------------------------------------------------------------------
       
   515 // After manual HO call has been released automatic HOs can be made again.
       
   516 // -----------------------------------------------------------------------------
       
   517 //
       
   518 EXPORT_C void CVccHoTrigger::ManualHoCallReleased()
       
   519     {
       
   520     RUBY_DEBUG_BLOCK( "CVccHoTrigger::ManualHoCallReleased" );
       
   521     iManualHoDone = EFalse;
       
   522 
       
   523     iWlanSignalLevelHandler->SetManualHoDone( EFalse );
       
   524     }
       
   525 
       
   526 // -----------------------------------------------------------------------------
       
   527 // During conference HO is not allowed
       
   528 // -----------------------------------------------------------------------------
       
   529 //
       
   530 EXPORT_C void CVccHoTrigger::HoNotAllowedL()
       
   531 	{
       
   532 	RUBY_DEBUG_BLOCK( "CVccHoTrigger::HoNotAllowedL" );
       
   533 	iHoNotAllowed = ETrue;
       
   534 	UpdatePsKeysL();
       
   535 	}
       
   536 
       
   537 // -----------------------------------------------------------------------------
       
   538 // After conference HO is allowed again
       
   539 // -----------------------------------------------------------------------------
       
   540 //
       
   541 EXPORT_C void CVccHoTrigger::HoAllowed()
       
   542 	{
       
   543 	RUBY_DEBUG_BLOCK( "CVccHoTrigger::HoAllowed" );
       
   544 	iHoNotAllowed = EFalse;
       
   545 	TRAP_IGNORE( UpdatePsKeysL() );
       
   546 	}
       
   547 
       
   548 // -----------------------------------------------------------------------------
       
   549 // Read settings
       
   550 // -----------------------------------------------------------------------------
       
   551 //
       
   552 EXPORT_C void CVccHoTrigger::ReadHoAllowedWhenCsOriginatedSettingL()
       
   553     {
       
   554     iHoPolicyReader->ReadSettingsL();
       
   555     iPolicy = iHoPolicyReader->HoPolicy();
       
   556     iHoAllowedIfCsOriginated = iPolicy.DtAllowedWhenCsOriginated();
       
   557     }
       
   558     
       
   559 // -----------------------------------------------------------------------------
       
   560 // Initiate the actual ho when its ok
       
   561 // -----------------------------------------------------------------------------
       
   562 //
       
   563 void CVccHoTrigger::TriggerHo()
       
   564 	{
       
   565 	RUBY_DEBUG_BLOCK( "CVccHoTrigger::TriggerHo" );
       
   566 	
       
   567 	RUBY_DEBUG1("Current domain is: %d", iDomainType);
       
   568 	//Check if manual ho is already made during this call and the 
       
   569 	//service availability.
       
   570 	if( iManualHoDone || !ServicesAvailable() || iHoNotAllowed )
       
   571 		{
       
   572 		return;
       
   573 		}
       
   574 	
       
   575 	//If immediate ho is "ON" do it first and then return.
       
   576 	if( iPolicy.DoImmediateHo() )
       
   577 		{
       
   578 		if ( DoImmediateHo() )
       
   579 		    {
       
   580 		    RUBY_DEBUG0( "VccHoTrigger::TriggerHo - immediate HO was initiated" );
       
   581 		    return;
       
   582 		    }
       
   583 		RUBY_DEBUG0( "VccHoTrigger::TriggerHo - no immediate HO" );
       
   584 		}
       
   585 	
       
   586 	if ( ( iWlanClass == ESignalClassWeak || iCchServiceStatus == EServiceUnavailable )&&
       
   587 	        iGsmClass == ESignalClassNormal && 
       
   588 	     ( iPolicy.AllowedDirection() & EPsToCsAllowed  ) && iDomainType == ECallDomainTypePS )
       
   589 	    {
       
   590 	    RUBY_DEBUG0( "VccHoTrigger::WlanSignalChanged - NotifySubscriberL" );
       
   591 	        
       
   592 	    // First empty the key, so that director 
       
   593 	    // gets notified about all changes
       
   594 	        
       
   595 	    TRAP_IGNORE( iProperty->NotifySubscriberL( EVccNoRequestOngoing ) );
       
   596 	    // Check whether HO is allowed in multicall situation
       
   597 	    if( iPolicy.DoHoInHeldWaitingCalls() )
       
   598 	        {
       
   599 	        TRAP_IGNORE( iProperty->NotifySubscriberL(
       
   600 	                    EVccAutomaticStartPsToCsHoRequest ) );
       
   601 	        }
       
   602 	    else
       
   603 	        {
       
   604 	        TRAP_IGNORE( iProperty->NotifySubscriberL(
       
   605 	                    EVccAutomaticStartPsToCsHoRequestIfSingleCall ) );
       
   606 	        }
       
   607 	        
       
   608 	    }        
       
   609 	
       
   610 	else if ( iGsmClass == ESignalClassWeak &&
       
   611             iWlanClass == ESignalClassNormal &&
       
   612             ( iPolicy.AllowedDirection() & ECsToPsAllowed ))
       
   613         {
       
   614         RUBY_DEBUG0( "VccHoTrigger::GsmSignalChanged - NotifySubscriberL" );
       
   615         
       
   616         // First empty the key, so that director 
       
   617         // gets notified about all changes
       
   618         
       
   619         TRAP_IGNORE( iProperty->NotifySubscriberL( EVccNoRequestOngoing ) );
       
   620         // Check whether HO is allowed in multicall situation
       
   621         if( iPolicy.DoHoInHeldWaitingCalls() )
       
   622             {
       
   623             TRAP_IGNORE( iProperty->NotifySubscriberL(
       
   624                         EVccAutomaticStartCsToPsHoRequest ) );
       
   625             }
       
   626         else
       
   627             {
       
   628             TRAP_IGNORE( iProperty->NotifySubscriberL(
       
   629                         EVccAutomaticStartCsToPsHoRequestIfSingleCall ) );
       
   630             }
       
   631         }
       
   632     }
       
   633 
       
   634 // -----------------------------------------------------------------------------
       
   635 // Initiate immediate ho
       
   636 // -----------------------------------------------------------------------------
       
   637 //
       
   638 TBool CVccHoTrigger::DoImmediateHo()
       
   639 	{
       
   640 	RUBY_DEBUG_BLOCK( "CVccHoTrigger::DoImmediateHo" );
       
   641 	TBool ret( EFalse );
       
   642 	if( ( iPolicy.PreferredDomain() == ECsPreferred ) &&
       
   643 	    iGsmClass ==  ESignalClassNormal &&
       
   644         ( iPolicy.AllowedDirection() & EPsToCsAllowed ) )  
       
   645 		{
       
   646 		// Current call is PS, CS signal is ok, preferred domain is CS
       
   647         // and immediate HO is requested -> HANDOVER to CS
       
   648         
       
   649         RUBY_DEBUG0( "VccHoTrigger::GsmSignalChanged - NotifySubscriberL ->\
       
   650                       IMMEDIATE HO to CS" );
       
   651         
       
   652         // First empty the key, so that director gets
       
   653         // notified about all changes
       
   654         
       
   655         TRAP_IGNORE( iProperty->NotifySubscriberL( EVccNoRequestOngoing ) );
       
   656         
       
   657         // Check whether HO is allowed in multicall situation
       
   658         if( iPolicy.DoHoInHeldWaitingCalls() )
       
   659             {
       
   660             TRAP_IGNORE( iProperty->NotifySubscriberL(
       
   661                         EVccAutomaticStartPsToCsHoRequest ) );
       
   662             ret = ETrue;
       
   663             }
       
   664         else
       
   665             {
       
   666             TRAP_IGNORE( iProperty->NotifySubscriberL(
       
   667                         EVccAutomaticStartPsToCsHoRequestIfSingleCall ) );
       
   668             ret = ETrue;
       
   669             }
       
   670 		}
       
   671 	
       
   672 	else if ( (iPolicy.PreferredDomain() == EPsPreferred)  &&
       
   673 	      iWlanClass == ESignalClassNormal && iCchServiceStatus != EServiceUnavailable &&
       
   674 	      ( iPolicy.AllowedDirection() & ECsToPsAllowed  ) && iDomainType != ECallDomainTypePS )
       
   675         {
       
   676         // Current call is CS, PS signal is ok, preferred domain is PS and 
       
   677 	    // immediate HO is requested -> HANDOVER to PS
       
   678 
       
   679         RUBY_DEBUG0( "VccHoTrigger::WlanSignalChanged - NotifySubscriberL ->\
       
   680                       IMMEDIATE HO to PS" );
       
   681 	       
       
   682 	    // First empty the key, so that director gets 
       
   683 	    // notified about all changes
       
   684 	        
       
   685 	    TRAP_IGNORE( iProperty->NotifySubscriberL( EVccNoRequestOngoing ) );
       
   686 	        
       
   687         // Check whether HO is allowed in multicall situation
       
   688 	    if( iPolicy.DoHoInHeldWaitingCalls() )
       
   689             {
       
   690 	        TRAP_IGNORE( iProperty->NotifySubscriberL(
       
   691 	                    EVccAutomaticStartCsToPsHoRequest ) );
       
   692 	        ret = ETrue;
       
   693 	        }
       
   694 	    else
       
   695 	        {
       
   696 	        TRAP_IGNORE( iProperty->NotifySubscriberL(
       
   697 	                       EVccAutomaticStartCsToPsHoRequestIfSingleCall ) );
       
   698 	        ret = ETrue;
       
   699 	        }
       
   700         }
       
   701 	return ret;
       
   702 	}