videoconnutility/connutility/src/vcxconnutilimpl.cpp
branchRCL_3
changeset 47 826cea16efd9
parent 45 798ee5f1972c
child 48 13a33d82ad98
equal deleted inserted replaced
45:798ee5f1972c 47:826cea16efd9
     1 /*
       
     2 * Copyright (c) 2006 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 the License "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:    Class to handle connection creation.*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <e32cmn.h>
       
    22 #include <bldvariant.hrh>
       
    23 #include <commdb.h>            // CMDBSession
       
    24 #include <commsdattypesv1_1.h> // CCDWAPIPBearerRecord
       
    25 #include <ConnectionUiUtilities.h> 
       
    26 #include <cmdestination.h>
       
    27 #include <cdbcols.h>
       
    28 #include <commdbconnpref.h>
       
    29 #include <eikbtgrp.h>
       
    30 #include <WlanCdbCols.h>
       
    31 #include <connpref.h>
       
    32 #include <extendedconnpref.h>
       
    33 #include <mpxlog.h>
       
    34 
       
    35 #include <ipvideo/vcxconnectionutility.h>
       
    36 #include <ipvideo/vcxconnutilengineobserver.h>
       
    37 #include "vcxconnectionutility.hrh"
       
    38 #include "vcxconnutilimpl.h"
       
    39 #include "vcxconnutilengine.h"
       
    40 #include "vcxconnutilpubsub.h"
       
    41 #include "vcxconnutilwaitsch.h"
       
    42 
       
    43 // CONSTANTS
       
    44 _LIT( KConnUtilRoleSema, "__ConnUtillMasterSlaveRoleSwitchSema__ ");
       
    45 _LIT( KConnUtilConnectionSema, "__ConnUtillConnectionCreateSema__ ");
       
    46 
       
    47 const TInt KIptvCenRepAPModeAlwaysAsk = 0;
       
    48 const TInt KConUtilSemaStartupValue = 1;
       
    49 const TInt KNbrOfNotFoundConnTries = 30;
       
    50 
       
    51 
       
    52 // ============================ MEMBER FUNCTIONS ===============================
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 // CVcxConnUtilImpl::NewL()
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 CVcxConnUtilImpl* CVcxConnUtilImpl::NewL( CVcxConnectionUtility* aUiInterface )
       
    59     {
       
    60     CVcxConnUtilImpl* self = CVcxConnUtilImpl::NewLC( aUiInterface );  
       
    61     CleanupStack::Pop( self ); // self;
       
    62     return self;
       
    63     }
       
    64 
       
    65 // -----------------------------------------------------------------------------
       
    66 // CVcxConnUtilImpl::NewLC()
       
    67 // -----------------------------------------------------------------------------
       
    68 //
       
    69 CVcxConnUtilImpl* CVcxConnUtilImpl::NewLC( CVcxConnectionUtility* aUiInterface )
       
    70     {
       
    71     CVcxConnUtilImpl* self = new (ELeave) CVcxConnUtilImpl( aUiInterface );
       
    72     CleanupStack::PushL( self );
       
    73     self->ConstructL( );
       
    74     return self;
       
    75     }
       
    76 
       
    77 // -----------------------------------------------------------------------------
       
    78 // CVcxConnUtilImpl::ConstructL()
       
    79 // -----------------------------------------------------------------------------
       
    80 //
       
    81 void CVcxConnUtilImpl::ConstructL( )
       
    82     {
       
    83     MPX_DEBUG1("vcxconnutil ## CVcxConnUtilImpl::ConstructL() in");
       
    84     
       
    85     iWaitHandler = CVcxConnUtilWaitSch::NewL();
       
    86     
       
    87     iObservers.Reset();
       
    88     
       
    89     TInt err( KErrNone );
       
    90     err = iSemaSwitchRole.CreateGlobal( KConnUtilRoleSema, KConUtilSemaStartupValue );
       
    91     if( err == KErrAlreadyExists )
       
    92         {
       
    93         // semafore exists already, open it
       
    94         err = iSemaSwitchRole.OpenGlobal( KConnUtilRoleSema );
       
    95         }
       
    96     User::LeaveIfError( err );
       
    97     
       
    98     err = iSemaCreateConn.CreateGlobal( KConnUtilConnectionSema, KConUtilSemaStartupValue );
       
    99     if( err == KErrAlreadyExists )
       
   100         {
       
   101         // semafore exists already, open it
       
   102         err = iSemaCreateConn.OpenGlobal( KConnUtilConnectionSema );
       
   103         }
       
   104     User::LeaveIfError( err );
       
   105     
       
   106     iEngine = CVcxConnUtilEngine::NewL( this );
       
   107         
       
   108     iPubsub = CVcxConnUtilPubSub::NewL( this );
       
   109             
       
   110     // check and set pubsub -values 
       
   111     TInt activeIap( 0 );
       
   112     User::LeaveIfError( iPubsub->GetValue( EVCxPSIapId, activeIap ) );
       
   113     if( activeIap != 0 )
       
   114         {
       
   115         // check if there really is connection, if not reinit values
       
   116         if( !iEngine->IsIapConnected( activeIap ) )
       
   117             {
       
   118             // no connection, data integrity has been corrupted at some point
       
   119             activeIap = 0;
       
   120             }
       
   121         }
       
   122     if( activeIap == 0 ) 
       
   123         {
       
   124         MPX_DEBUG1("CVcxConnUtilImpl::ConstructL() no connection yet, initing values");
       
   125         User::LeaveIfError( iPubsub->SetValue( EVCxPSMasterExists, 0 ) );
       
   126         
       
   127         User::LeaveIfError( iPubsub->SetValue( EVCxPSIapId, 0 ) );
       
   128         
       
   129         User::LeaveIfError( iPubsub->SetValue( EVCxPSSnapId, 0 ) );
       
   130         
       
   131         User::LeaveIfError( iPubsub->SetValue( 
       
   132                                  EVCxPSConnectionStatus, EVCxNotConnected ) );
       
   133         
       
   134         User::LeaveIfError( iPubsub->SetValue( EVCxPSNbrConnInstances, 0 ) );        
       
   135         }
       
   136     
       
   137     MPX_DEBUG1("vcxconnutil ## CVcxConnUtilImpl::ConstructL() out");
       
   138     }
       
   139 
       
   140 // -----------------------------------------------------------------------------
       
   141 // CVcxConnUtilImpl::CVcxNsConnectionUtility()
       
   142 // -----------------------------------------------------------------------------
       
   143 //
       
   144 CVcxConnUtilImpl::CVcxConnUtilImpl( CVcxConnectionUtility* aUiInterface ) :
       
   145 iUIInterface( aUiInterface )
       
   146     {
       
   147     }
       
   148     
       
   149 // -----------------------------------------------------------------------------
       
   150 // CVcxConnUtilImpl::~CVcxConnectionUtility()
       
   151 // -----------------------------------------------------------------------------
       
   152 //
       
   153 CVcxConnUtilImpl::~CVcxConnUtilImpl()
       
   154     {   
       
   155     MPX_DEBUG1("vcxconnutil ## CVcxConnUtilImpl::~CVcxConnUtilImpl in");
       
   156     
       
   157     iObservers.Close();
       
   158     
       
   159     if( iEngine && iPubsub )
       
   160         {
       
   161         TRAP_IGNORE( DisconnectL() );
       
   162         }
       
   163     
       
   164     delete iWaitHandler;
       
   165     
       
   166     iSemaSwitchRole.Close();
       
   167     iSemaCreateConn.Close();
       
   168      
       
   169     delete iPubsub;
       
   170     delete iEngine;
       
   171     
       
   172     MPX_DEBUG1("vcxconnutil ## CVcxConnUtilImpl::~CVcxConnUtilImpl out");
       
   173     }
       
   174 
       
   175 // -----------------------------------------------------------------------------
       
   176 // CVcxConnUtilImpl::RegisterObserverL
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 void CVcxConnUtilImpl::RegisterObserverL( MConnUtilEngineObserver* aObserver )
       
   180    {
       
   181    MPX_DEBUG1("vcxconnutil ## CVcxConnUtilImpl::RegisterObserverL in");
       
   182    iObservers.AppendL( aObserver );
       
   183    MPX_DEBUG1("vcxconnutil ## CVcxConnUtilImpl::RegisterObserverL out");
       
   184    }
       
   185 
       
   186 // -----------------------------------------------------------------------------
       
   187 // CVcxConnUtilImpl::RemoveObserver
       
   188 // -----------------------------------------------------------------------------
       
   189 //
       
   190 void CVcxConnUtilImpl::RemoveObserver( MConnUtilEngineObserver* aObserver )
       
   191    {
       
   192    MPX_DEBUG1("Cvcxconnutil ## VcxConnUtilImpl::RemoveObserver in");
       
   193    TInt i;
       
   194    for ( i = 0; i < iObservers.Count(); i++ )
       
   195        {
       
   196        if ( aObserver == iObservers[i] )
       
   197            {
       
   198            iObservers.Remove( i );
       
   199            iObservers.Compress();
       
   200            break;
       
   201            }
       
   202        } 
       
   203    MPX_DEBUG1("Cvcxconnutil ## VcxConnUtilImpl::RemoveObserver out");
       
   204    }
       
   205 
       
   206 // -----------------------------------------------------------------------------
       
   207 // CVcxConnUtilImpl::EngineConnectionStatus
       
   208 // -----------------------------------------------------------------------------
       
   209 //
       
   210 TVCxConnectionStatus CVcxConnUtilImpl::EngineConnectionStatus()
       
   211     {
       
   212     return iEngine->ConnectionStatus();
       
   213     }
       
   214 
       
   215 // -----------------------------------------------------------------------------
       
   216 // CVcxConnUtilImpl::GetIap
       
   217 // -----------------------------------------------------------------------------
       
   218 //
       
   219 TInt CVcxConnUtilImpl::GetIap( TUint32& aIapId, TBool aSilent )
       
   220     {
       
   221     MPX_DEBUG1("vcxconnutil ## CVcxConnUtilImpl::GetIap in ");
       
   222     aIapId = 0;
       
   223     TInt err( KErrNone );
       
   224     // assume always new connection
       
   225     iNewConnection = ETrue;
       
   226     
       
   227     switch ( iEngine->ConnectionStatus() )
       
   228         {
       
   229         case EVCxNotConnected:            
       
   230         case EVCxDisconnecting:                    
       
   231             iSemaCreateConn.Wait();
       
   232             err = KErrNotFound;
       
   233             // KErrNotFound from connection creation indicates that we have 
       
   234             // some destination with unusable iap(s) in it for we cannot connect to
       
   235             // in that case, destination id to db is setted as "always ask" and connection
       
   236             // creation will be tried again for 30 times
       
   237             for(TInt i = 0; i < KNbrOfNotFoundConnTries && err == KErrNotFound; ++i)
       
   238                 {
       
   239                 err = CreateConnection( aSilent );
       
   240                 MPX_DEBUG2("vcxconnutil ## CVcxConnUtilImpl::GetIap - CreateConnection returned %d ", err );
       
   241                 }
       
   242             iSemaCreateConn.Signal();    
       
   243             break;             
       
   244         case EVCxConnecting:
       
   245             {
       
   246             // this instance is connecting, meaning engine is waiting for
       
   247             // networking to create connection, we need to wait for the engine 
       
   248             // to finish it's waiting
       
   249             TRAP( err, WaitL( EVCxPSConnectionStatus ) );
       
   250             if( iEngine->ConnectionStatus() != EVCxConnected )
       
   251                 {
       
   252                 // if main active object didn't managed to create connection,
       
   253                 // return error. This active object does not know the actual
       
   254                 // error so return KErrGeneral
       
   255                 err = KErrGeneral;
       
   256                 }
       
   257             else
       
   258                 {
       
   259                 err = HandleFinalizeConnection();
       
   260                 }
       
   261             }
       
   262             break;
       
   263         case EVCxRoamingAccepted: // pass throught
       
   264         case EVCxRoamingRequest:  // pass throught
       
   265             TRAP( err, WaitL( EVCxPSConnectionStatus ) );
       
   266         default:
       
   267             iNewConnection = EFalse; 
       
   268             break;
       
   269         }          
       
   270         
       
   271     if( err == KErrNone )
       
   272         {   
       
   273         // get iap id if any. If this is the first connection for this 
       
   274         // instance, iap id will be fetched later on
       
   275         aIapId = iEngine->IapId();       
       
   276         }
       
   277 
       
   278     MPX_DEBUG2("vcxconnutil ## CVcxConnUtilImpl::GetIap out error: %d ", err );
       
   279     return err;
       
   280     }
       
   281 
       
   282 // -----------------------------------------------------------------------------
       
   283 // CVcxConnUtilImpl::WapIdFromIapIdL
       
   284 // -----------------------------------------------------------------------------
       
   285 //
       
   286 TUint32 CVcxConnUtilImpl::WapIdFromIapIdL( TUint32 aIapId )
       
   287     {
       
   288     MPX_DEBUG1("vcxconnutil ## CVcxConnUtilImpl::WapIdFromIapIdL() in ");
       
   289     MPX_DEBUG2("vcxconnutil ## CVcxConnUtilImpl::WapIdFromIapIdL() IAP id = %d", aIapId);
       
   290     CMDBSession* db = CMDBSession::NewL( CMDBSession::LatestVersion() );
       
   291     CleanupStack::PushL( db );
       
   292     
       
   293     // WapIpBearer table contains the mapping between wap and iap id's.
       
   294     CCDWAPIPBearerRecord* wapBearerRecord = 
       
   295         static_cast<CCDWAPIPBearerRecord*>( CCDRecordBase::RecordFactoryL( KCDTIdWAPIPBearerRecord ) );
       
   296         
       
   297     CleanupStack::PushL( wapBearerRecord );
       
   298     
       
   299     wapBearerRecord->iWAPIAP = aIapId;
       
   300     
       
   301     TBool found = wapBearerRecord->FindL( *db );
       
   302     
       
   303     if ( !found )
       
   304         {
       
   305         MPX_DEBUG1("vcxconnutil ## CVcxConnUtilImpl::WapIdFromIapIdL() Record was not found. Leaving with KErrNotFound.");
       
   306         User::Leave(KErrNotFound);
       
   307         }
       
   308 
       
   309     TUint32 wap = static_cast<TUint32>( wapBearerRecord->iWAPAccessPointId );
       
   310     
       
   311     CleanupStack::PopAndDestroy( wapBearerRecord );
       
   312     CleanupStack::PopAndDestroy( db );
       
   313     
       
   314     MPX_DEBUG2("vcxconnutil ## CVcxConnUtilImpl::WapIdFromIapIdL() Matching WAP id = %d", wap);
       
   315     MPX_DEBUG1("vcxconnutil ## CVcxConnUtilImpl::WapIdFromIapIdL() out ");
       
   316     return wap;
       
   317     }
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 // CVcxConnUtilImpl::PrepareConnSettings()
       
   321 // -----------------------------------------------------------------------------
       
   322 //
       
   323 TInt CVcxConnUtilImpl::PrepareConnSettings()
       
   324     {
       
   325     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::PrepareConnSettings in");  
       
   326     TInt err( KErrNone );
       
   327     TInt vcDestinationID( 0 );
       
   328     
       
   329     if ( !iEngine->QueryConn() )
       
   330         {
       
   331         TRAP( err, vcDestinationID = 
       
   332             iEngine->GetCmmDestinationIdL( CMManager::ESnapPurposeUnknown ) );
       
   333         MPX_DEBUG2( "vcxconnutil ## CVcxConnUtilImpl::PrepareConnSettings - destination id %d", vcDestinationID);  
       
   334         }
       
   335    
       
   336     TBool detailsGotten( EFalse );
       
   337     TRAP( err, detailsGotten = iEngine->PrepareConnectionDetailsL( vcDestinationID ) );
       
   338     if( err == KErrNone && !detailsGotten )
       
   339         {
       
   340         // not able to resolve connection details, proceed with always ask
       
   341         iEngine->ResetConnectionInfo();
       
   342         }
       
   343     
       
   344     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::PrepareConnSettings out");  
       
   345     return err;            
       
   346     }
       
   347 
       
   348 // -----------------------------------------------------------------------------
       
   349 // CVcxConnUtilImpl::CreateConnection()
       
   350 // -----------------------------------------------------------------------------
       
   351 //
       
   352 TInt CVcxConnUtilImpl::CreateConnection( TBool aSilent )
       
   353     {
       
   354     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::CreateConnectionL in");     
       
   355     
       
   356     TInt err( KErrNone );
       
   357 
       
   358     TInt connStatusPS( EVCxNotConnected );
       
   359     
       
   360     err = PrepareConnSettings();
       
   361     if( err != KErrNone )
       
   362         {
       
   363         MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::CreateConnectionL error getting connsettings out");
       
   364         return err;
       
   365         }
       
   366     
       
   367     err = iPubsub->GetValue( EVCxPSConnectionStatus, connStatusPS );
       
   368     if( err != KErrNone )
       
   369         {
       
   370         MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::CreateConnectionL error getting PS conn status out");
       
   371         return err;
       
   372         }
       
   373     
       
   374     // if there is already an active connection created by some other  
       
   375     // instance, use that one
       
   376     TInt snapId( 0 );
       
   377     TBool masterConnect( EFalse );
       
   378 
       
   379     if( connStatusPS == EVCxConnected || connStatusPS == EVCxRoamingRequest )
       
   380         {        
       
   381         err = iPubsub->GetValue( EVCxPSSnapId, snapId );
       
   382         if( err != KErrNone )
       
   383             {
       
   384             MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::CreateConnectionL error getting PS snap id, out");                   
       
   385             return err;
       
   386             }
       
   387         if( snapId == 0 )
       
   388             {
       
   389             MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::CreateConnectionL not usable snap is in PS");
       
   390             // current snap is undefined, set snap id KErrNotFound for 
       
   391             // DoCreateConnection to use active iap instead of snap id
       
   392             snapId = KErrNotFound;
       
   393             }
       
   394         }
       
   395     else
       
   396         {
       
   397         masterConnect = ETrue;
       
   398         snapId = iEngine->DestinationId();
       
   399         }
       
   400 
       
   401     err = DoCreateConnection( aSilent, snapId, masterConnect );
       
   402     if( err == KErrNotFound && masterConnect )
       
   403         {
       
   404         // KErrNotFound from connection creation indicates that we have 
       
   405         // some destination with unusable iap(s) in it. Enable connection query.
       
   406         MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::CreateConnectionL - set connection query");
       
   407         iEngine->SetQueryConn( ETrue );
       
   408         }
       
   409     if( err == KErrNone )
       
   410         {
       
   411         err = HandleFinalizeConnection();
       
   412         }
       
   413     
       
   414     MPX_DEBUG2( "vcxconnutil ## CVcxConnUtilImpl::CreateConnectionL out (%d)", err);
       
   415     return err;
       
   416     }
       
   417 
       
   418 // -----------------------------------------------------------------------------
       
   419 // CVcxConnUtilImpl::DoCreateConnection()
       
   420 // -----------------------------------------------------------------------------
       
   421 //
       
   422 TInt CVcxConnUtilImpl::DoCreateConnection(  TBool /*aSilent*/, TInt32 aSnapId, TBool aMasterConnect )
       
   423     {
       
   424     MPX_DEBUG2( "vcxconnutil ## CVcxConnUtilImpl::DoCreateConnectionL in (snapId=%d)", aSnapId);
       
   425     
       
   426     TInt err( KErrNone );
       
   427     
       
   428     if ( aSnapId == KIptvCenRepAPModeAlwaysAsk )
       
   429         {  
       
   430         //In always ask mode we show always ask dialog
       
   431         TCommDbConnPref connPref;
       
   432         connPref.SetDialogPreference(  ECommDbDialogPrefPrompt  );
       
   433         err = iEngine->StartToConnect( connPref );
       
   434         MPX_DEBUG2( "CVcxConnUtilImpl::DoCreateConnectionL connection start always ask err %d", err);
       
   435         }
       
   436     else if ( aSnapId > KIptvCenRepAPModeAlwaysAsk )
       
   437         {
       
   438         TConnSnapPref prefs;
       
   439         prefs.SetSnap( aSnapId );
       
   440         err = iEngine->StartToConnect( prefs, aMasterConnect );
       
   441         MPX_DEBUG2( "CVcxConnUtilImpl::DoCreateConnectionL connection start err %d", err);
       
   442         }
       
   443     else
       
   444         {
       
   445         TInt iapPS( 0 );
       
   446         err = iPubsub->GetValue( EVCxPSIapId, iapPS );
       
   447         if( err == KErrNone )
       
   448             {
       
   449             if( iapPS )
       
   450                 {
       
   451                 TCommDbConnPref connPref;
       
   452                 connPref.SetIapId( iapPS );
       
   453                 connPref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
       
   454                 err = iEngine->StartToConnect( connPref, EFalse );
       
   455                 MPX_DEBUG2( "CVcxConnUtilImpl::DoCreateConnectionL connection via iap start err %d", err);
       
   456                 }
       
   457             else
       
   458                 {
       
   459                 err = KErrNotFound;
       
   460                 }            
       
   461             }  
       
   462         }
       
   463     if( err == KErrNone && aMasterConnect )
       
   464         {
       
   465         err = iEngine->CreateMobility();
       
   466         }
       
   467     MPX_DEBUG2( "vcxconnutil ## CVcxConnUtilImpl::DoCreateConnectionL out (%d)", err);
       
   468     return err;
       
   469     }
       
   470 
       
   471 // -----------------------------------------------------------------------------
       
   472 // CVcxConnUtilImpl::HandleFinalizeConnection()
       
   473 // -----------------------------------------------------------------------------
       
   474 //
       
   475 TInt CVcxConnUtilImpl::HandleFinalizeConnection()
       
   476     {
       
   477     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleFinalizeConnection in");
       
   478     if( !iNewConnection )
       
   479         {
       
   480         // if connection is not new for this instance
       
   481         // no finalizing required
       
   482         MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleFinalizeConnection no new connection, out");
       
   483         return KErrNone;
       
   484         }
       
   485     if( iEngine->ConnectionStatus() != EVCxConnected  )
       
   486         {
       
   487         // connection not ok, no point to proceed, return error
       
   488         MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleFinalizeConnection not connected, out");
       
   489         return KErrGeneral;
       
   490         }
       
   491 
       
   492     iNewConnection = EFalse;
       
   493     TRAPD( err, iEngine->FillActiveConnectionDetailsL() );
       
   494                
       
   495     if( err == KErrNone )
       
   496         {                
       
   497         TRAP( err, iPubsub->IncCounterPubSubL( EVCxPSNbrConnInstances ) );              
       
   498         if( err == KErrNone )
       
   499             {                                    
       
   500             // master role check and switch if necessary
       
   501             if( !iMaster )
       
   502                 {
       
   503                 err = CheckAndChangeSlaveToMaster();                        
       
   504                 }
       
   505             }
       
   506             if( err == KErrNone && iMaster )
       
   507                 {
       
   508                 TRAP( err, SaveConnectionToPubSubL() );
       
   509                 }
       
   510             if( err == KErrNone )
       
   511                 {    
       
   512                 // start getting events from pubsub
       
   513                 iPubsub->StartSubscibers();
       
   514                 }
       
   515          }            
       
   516      if( err != KErrNone )
       
   517          {
       
   518          // some operation above failed, internal error
       
   519          // try to disconnect and return error       
       
   520          TRAPD( errDisc, DisconnectL() );
       
   521          // return latest error if disconnecting fails
       
   522          if( errDisc != KErrNone )
       
   523              {
       
   524              err = errDisc;
       
   525              }
       
   526          }
       
   527      MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleFinalizeConnection out");
       
   528      return err;
       
   529     }
       
   530 
       
   531 // -----------------------------------------------------------------------------
       
   532 // CVcxConnUtilImpl::DisconnectConnection()
       
   533 // -----------------------------------------------------------------------------
       
   534 //
       
   535 void CVcxConnUtilImpl::DisconnectL()
       
   536     {
       
   537     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::Disconnect in");
       
   538     TVCxConnectionStatus connStatus = iEngine->ConnectionStatus();
       
   539     
       
   540     // if this is a master, and it is roaming we need to wait 
       
   541     // for roaming to finish
       
   542     if( iMaster )
       
   543         {
       
   544         // because EVCxRoamingAccepted is never saved as
       
   545         // connection status to PS,
       
   546         // it is safe to wait PS value key change here
       
   547         if( connStatus == EVCxRoamingRequest   ||
       
   548             connStatus == EVCxRoamingAccepted   )
       
   549             {
       
   550             MPX_DEBUG1( "CVcxConnUtilImpl::Disconnect master waiting roaming to finish");                        
       
   551             WaitL( EVCxPSConnectionStatus );
       
   552             MPX_DEBUG1( "CVcxConnUtilImpl::Disconnect master waiting finished");
       
   553             connStatus = iEngine->ConnectionStatus();
       
   554             }
       
   555         }
       
   556     else
       
   557         {
       
   558         // if slave is about to disconnect
       
   559         // and it's internal state is roaming
       
   560         // we know that it has been responded to 
       
   561         // roaming request. Decrease value here
       
   562         if( connStatus == EVCxRoamingRequest   ||
       
   563             connStatus == EVCxRoamingAccepted  ||
       
   564             connStatus == EVCxPendingClientRequest )
       
   565             {
       
   566             if( connStatus == EVCxRoamingAccepted )
       
   567                 {
       
   568                 MPX_DEBUG1( "CVcxConnUtilImpl::Disconnect slave removes it's acceptance");
       
   569                 iPubsub->DecCounterPubSubL( EVCxPSNbRoamAccepted );
       
   570                 }
       
   571             MPX_DEBUG1( "CVcxConnUtilImpl::Disconnect slave removes it's response");
       
   572             iPubsub->DecCounterPubSubL( EVCxPSNbrRoamResp );     
       
   573             }
       
   574         }
       
   575     
       
   576     // disconnecting, no longer interested in pubsub events
       
   577     iPubsub->CancelValueSubscribers();
       
   578     
       
   579     if( connStatus == EVCxNotConnected )
       
   580         {
       
   581         return;
       
   582         }
       
   583     
       
   584     TInt nbrOfConnUsers( 0 );
       
   585     User::LeaveIfError( iPubsub->GetValue( EVCxPSNbrConnInstances, nbrOfConnUsers ) );
       
   586                     
       
   587     if(  nbrOfConnUsers > 0 )
       
   588         {
       
   589         iPubsub->DecCounterPubSubL( EVCxPSNbrConnInstances );
       
   590         }  
       
   591     iPubsub->GetValue( EVCxPSNbrConnInstances, nbrOfConnUsers );
       
   592     // we're leaving and there are no other instances using connection
       
   593     if( nbrOfConnUsers == 0 )
       
   594         {
       
   595         // no more connection users, reset PS -values   
       
   596         User::LeaveIfError( iPubsub->SetValue( EVCxPSIapId,  0 ) );
       
   597           
       
   598         User::LeaveIfError( iPubsub->SetValue( EVCxPSSnapId, 0 ) );
       
   599             
       
   600         User::LeaveIfError( iPubsub->SetValue( 
       
   601                             EVCxPSConnectionStatus, EVCxNotConnected ) );
       
   602             
       
   603         User::LeaveIfError( iPubsub->SetValue( 
       
   604                             EVCxPSRoamingRequestStatus, EVCxRoamingNotInit ) );
       
   605         }
       
   606     iEngine->Disconnect();
       
   607        
       
   608     // cannot be master anymore if not using connection
       
   609     if( iMaster )
       
   610         {
       
   611         iMaster = EFalse;
       
   612         User::LeaveIfError( iPubsub->SetValue( EVCxPSMasterExists,  0 ) );  
       
   613         }
       
   614         
       
   615     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::Disconnect out");
       
   616     }
       
   617 
       
   618 // -----------------------------------------------------------------------------
       
   619 // CVcxConnUtilImpl::SaveConnectionToPubSubL()
       
   620 // -----------------------------------------------------------------------------
       
   621 //
       
   622 void CVcxConnUtilImpl::SaveConnectionToPubSubL()
       
   623     {
       
   624     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::SaveConnectionToPubSubL in");
       
   625     // publish connection properties
       
   626     // IAP id:
       
   627     User::LeaveIfError( iPubsub->SetValue( EVCxPSIapId, iEngine->IapId() ) );
       
   628     
       
   629     // Snap ID:
       
   630     User::LeaveIfError( iPubsub->SetValue( EVCxPSSnapId, iEngine->DestinationId() ) );
       
   631     
       
   632     // connection State
       
   633     User::LeaveIfError( iPubsub->SetValue( 
       
   634                               EVCxPSConnectionStatus, iEngine->ConnectionStatus() ) );   
       
   635     
       
   636     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::SaveConnectionToPubSubL out");
       
   637     }
       
   638 
       
   639 // -----------------------------------------------------------------------------
       
   640 // CVcxConnUtilImpl::RequestIsRoamingAllowedL()
       
   641 // -----------------------------------------------------------------------------
       
   642 //
       
   643 TBool CVcxConnUtilImpl::RequestIsRoamingAllowedL()
       
   644     {
       
   645     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::RequestIsRoamingAllowedL in");
       
   646     TBool okToRoam( ETrue );
       
   647     
       
   648     // if this instance is master, need to wait for slaves to request their status before proceeding
       
   649     if( iMaster )
       
   650         {        
       
   651         // init pubsubs for roaming request status checking
       
   652         User::LeaveIfError( iPubsub->SetValue( EVCxPSNbrRoamResp,    0 ) );
       
   653         User::LeaveIfError( iPubsub->SetValue( EVCxPSNbRoamAccepted, 0 ) );
       
   654         
       
   655         // query own state
       
   656         okToRoam = DoRequestClientRoamingL();
       
   657         // client might have disconnected
       
   658         if( iEngine->ConnectionStatus() == EVCxNotConnected )
       
   659             {
       
   660             MPX_DEBUG1( "CVcxConnUtilImpl::RequestIsRoamingAllowedL master disconnected, out");
       
   661             return EFalse;            
       
   662             }
       
   663              
       
   664         User::LeaveIfError( iPubsub->SetValue( EVCxPSConnectionStatus, EVCxRoamingRequest ) );
       
   665         TInt nbrOfConnUsers(0);
       
   666         User::LeaveIfError( iPubsub->GetValue( EVCxPSNbrConnInstances, nbrOfConnUsers ) );
       
   667         if( okToRoam && nbrOfConnUsers > 1 )
       
   668             {
       
   669             
       
   670             // if we have slaves also using connection, 
       
   671             // we need to wait for them to request roaming statuses
       
   672             // from their clients also. In this case, the status is being 
       
   673             // checked via pubsub EVCxPSRoamingRequestStatus to which master
       
   674             // updates after enought resposes are received
       
   675             MPX_DEBUG1( "CVcxConnUtilImpl::RequestIsRoamingAllowedL master waiting");
       
   676             TRAPD( err, WaitL( EVCxPSRoamingRequestStatus ) );
       
   677             if( err != KErrNone )
       
   678                 {
       
   679                 MPX_DEBUG2( "CVcxConnUtilImpl::RequestIsRoamingAllowedL master wait leaved %d", err );
       
   680                 }
       
   681             MPX_DEBUG1( "CVcxConnUtilImpl::RequestIsRoamingAllowedL master released");
       
   682     
       
   683             TInt roamingStatus( EVCxRoamingNotInit );
       
   684             User::LeaveIfError( iPubsub->GetValue( EVCxPSRoamingRequestStatus, roamingStatus ) );
       
   685             if( EVCxRoamingAllowed != roamingStatus )
       
   686                 {
       
   687                 okToRoam = EFalse;            
       
   688                 }
       
   689             }
       
   690         }    
       
   691     // reset roaming PS value
       
   692     User::LeaveIfError( iPubsub->SetValue( EVCxPSRoamingRequestStatus, EVCxRoamingNotInit ) );
       
   693     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::RequestIsRoamingAllowedL out");
       
   694     return okToRoam;
       
   695     }
       
   696  
       
   697 // -----------------------------------------------------------------------------
       
   698 // CVcxConnUtilImpl::DoRequestClientRoamingL()
       
   699 // -----------------------------------------------------------------------------
       
   700 //
       
   701 TBool CVcxConnUtilImpl::DoRequestClientRoamingL()
       
   702     {   
       
   703     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::DoRequestClientRoamingL in" );
       
   704     
       
   705     TBool okToRoam( ETrue );
       
   706     TInt err( KErrNone );
       
   707 
       
   708     TVCxConnectionStatus oldState = iEngine->ConnectionStatus();
       
   709     iEngine->SetConnectionStatus( EVCxPendingClientRequest );
       
   710     for ( TInt i = 0; i < iObservers.Count() && okToRoam; i++ )
       
   711         {
       
   712         TRAP( err, okToRoam = iObservers[i]->RequestIsRoamingAllowedL() );
       
   713         if( err != KErrNone || !okToRoam )
       
   714             {
       
   715             okToRoam = EFalse;
       
   716             break;
       
   717             }
       
   718         }
       
   719     if( iEngine->ConnectionStatus() != EVCxNotConnected )
       
   720         {
       
   721         // operation path back to connection utility, reset state, in case 
       
   722         // client has not diconnected during callback        
       
   723         iEngine->SetConnectionStatus( oldState );
       
   724         
       
   725         if( okToRoam && err == KErrNone )
       
   726             {
       
   727             // roaming ok for this instance, increase nbr of accepted   
       
   728             iPubsub->IncCounterPubSubL( EVCxPSNbRoamAccepted );
       
   729             MPX_DEBUG1( "CVcxConnUtilImpl::DoRequestClientRoamingL accepted increased" );
       
   730             }
       
   731         }
       
   732     
       
   733     // increase nbr of responses
       
   734     iPubsub->IncCounterPubSubL( EVCxPSNbrRoamResp );
       
   735         
       
   736     MPX_DEBUG2( "CVcxConnUtilImpl::DoRequestClientRoamingL allowed %d out", okToRoam );
       
   737     
       
   738     return okToRoam;
       
   739     }
       
   740 
       
   741 // -----------------------------------------------------------------------------
       
   742 // CVcxConnUtilImpl::IapChanged()
       
   743 // -----------------------------------------------------------------------------
       
   744 //
       
   745 void CVcxConnUtilImpl::IapChangedL()
       
   746     {
       
   747     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::IapChanged in");
       
   748     if( !iMaster )
       
   749         {
       
   750         MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::IapChanged not master out");
       
   751         return;
       
   752         }
       
   753     TInt err( KErrNone );
       
   754     
       
   755     // current information
       
   756     TUint32 oldIap = iEngine->IapId();
       
   757     TVCxConnectionStatus engineStatus = iEngine->ConnectionStatus();
       
   758     
       
   759     // resolve connection information from the network middleware
       
   760     iEngine->ResetConnectionInfo();
       
   761     if( engineStatus != EVCxNotConnected && 
       
   762         engineStatus != EVCxError )
       
   763         {
       
   764         iEngine->FillActiveConnectionDetailsL();                 
       
   765         }        
       
   766     
       
   767     // if there is no active connection or gotten iap id is invalid
       
   768     TUint32 iapID = iEngine->IapId();
       
   769     if( iapID == 0 || !( iEngine->IsIapConnected( iapID ) ) ) 
       
   770         {        
       
   771         if( engineStatus != EVCxError )
       
   772             {            
       
   773             engineStatus = EVCxNotConnected;
       
   774             }
       
   775         // signal status before disconnect -call to make sure 
       
   776         // slaves react in case master's disconnecting fails
       
   777         MPX_DEBUG2( "IapChanged not connected notify %d ", engineStatus );
       
   778         iPubsub->SetValue( EVCxPSConnectionStatus, engineStatus );
       
   779            
       
   780         MPX_DEBUG1( "CVcxConnUtilImpl::IapChanged no active iap, diconnect");
       
   781         TRAP( err, DisconnectL() );
       
   782         if( err != KErrNone )
       
   783             {
       
   784             MPX_DEBUG2( "CVcxConnUtilImpl::IapChanged no active iap, diconnect leaves %d", err );
       
   785             }
       
   786         }
       
   787     else
       
   788         {
       
   789         MPX_DEBUG1( "CVcxConnUtilImpl::IapChanged iap connected");
       
   790         engineStatus = EVCxConnected;
       
   791         iEngine->SetConnectionStatus( EVCxConnected );
       
   792         // refresh PS connection state
       
   793         SaveConnectionToPubSubL();
       
   794         }
       
   795                     
       
   796     // notify clients about iap change
       
   797     if( engineStatus != EVCxError && ( oldIap != iapID || !iapID ) )
       
   798         {
       
   799         MPX_DEBUG1( "CVcxConnUtilImpl::IapChanged notify observers");  
       
   800         NotifyObserversIAPChanged();        
       
   801         }
       
   802     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::IapChanged out");               
       
   803     }
       
   804 
       
   805 // -----------------------------------------------------------------------------
       
   806 // CVcxConnUtilImpl::WaitL()
       
   807 // -----------------------------------------------------------------------------
       
   808 //
       
   809 void CVcxConnUtilImpl::WaitL( TUint32 aWaitId )
       
   810     {
       
   811     iWaitHandler->WaitL( aWaitId );
       
   812     }
       
   813 
       
   814 // -----------------------------------------------------------------------------
       
   815 // CVcxConnUtilImpl::EndWait()
       
   816 // -----------------------------------------------------------------------------
       
   817 //
       
   818 void CVcxConnUtilImpl::EndWait( TUint32 aWaitId )
       
   819     {
       
   820     iWaitHandler->EndWait( aWaitId );
       
   821     }
       
   822 
       
   823 // -----------------------------------------------------------------------------
       
   824 // CVcxConnUtilImpl::IsMaster()
       
   825 // -----------------------------------------------------------------------------
       
   826 //
       
   827 TBool CVcxConnUtilImpl::IsMaster()
       
   828     {
       
   829     return iMaster;
       
   830     }
       
   831 
       
   832 // -----------------------------------------------------------------------------
       
   833 // CVcxConnUtilImpl::ValueChangedL()
       
   834 // -----------------------------------------------------------------------------
       
   835 //
       
   836 void CVcxConnUtilImpl::ValueChangedL( const TUint32& aKey, const TInt&  aValue )
       
   837     {
       
   838     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::ValueChangedL (TInt) in");   
       
   839     EndWait( aKey );
       
   840     // pubsub key value changed, check and update 
       
   841     // functionality as required.
       
   842     switch( aKey )
       
   843         {
       
   844         case EVCxPSMasterExists:
       
   845             {
       
   846             HandleMasterChangeL();           
       
   847             break;
       
   848             }              
       
   849         case EVCxPSConnectionStatus: 
       
   850             {   
       
   851             HandleSlaveConnectionStatusL( aValue );
       
   852             break;
       
   853             }
       
   854         case EVCxPSNbrRoamResp:
       
   855             {
       
   856             HandleRoamingReponsesL( aValue );
       
   857             }
       
   858             break;
       
   859         case EVCxPSRoamingRequestStatus:
       
   860             // NOP
       
   861             break;
       
   862         default:
       
   863             User::Leave( KErrNotFound );
       
   864             break;      
       
   865         } 
       
   866     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::ValueChangedL (TInt) out");  
       
   867     }
       
   868 
       
   869 // -----------------------------------------------------------------------------
       
   870 // CVcxConnUtilImpl::HandleMasterChangeL()
       
   871 // -----------------------------------------------------------------------------
       
   872 //
       
   873 void CVcxConnUtilImpl::HandleMasterChangeL()
       
   874     {
       
   875     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleMasterChangeL in"); 
       
   876     // if this instance is not connected, don't bother
       
   877     // to change. Not connected instance cannot be master
       
   878     if( iMaster )
       
   879         {
       
   880         MPX_DEBUG1( "CVcxConnUtilImpl::HandleMasterChangeL master, out");
       
   881         return;
       
   882         }
       
   883     
       
   884     if( iEngine->ConnectionStatus() != EVCxConnected )
       
   885         {
       
   886         MPX_DEBUG1( "CVcxConnUtilImpl::HandleMasterChangeL not connected, out");
       
   887         return;
       
   888         }
       
   889     
       
   890     User::LeaveIfError( CheckAndChangeSlaveToMaster() );
       
   891 
       
   892     if( iMaster )
       
   893         {                    
       
   894         // at this point we need to reinit ex-slave's connection to use 
       
   895         // destination (snap) instead of IAP for the ex-slave to be able 
       
   896         // to get mobility events. 
       
   897         // if original connection was via IAP due "always ask", do nothing
       
   898         if( iEngine->DestinationId() )
       
   899             {
       
   900             // this instance has become master, so it needs to init the mobility object
       
   901             if( iEngine->CreateMobility() != KErrNone )
       
   902                 {
       
   903                 MPX_DEBUG1( "CVcxConnUtilImpl::HandleMasterChangeL master reinit connection not ok");
       
   904                 DisconnectL();  
       
   905                 }
       
   906             else
       
   907                 {
       
   908                 MPX_DEBUG1( "CVcxConnUtilImpl::HandleMasterChangeL master reinit connection ok");
       
   909                 iEngine->FillActiveConnectionDetailsL();
       
   910                 SaveConnectionToPubSubL();
       
   911                 }
       
   912             }  
       
   913         }
       
   914     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleMasterChangeL out"); 
       
   915     }
       
   916 
       
   917 // -----------------------------------------------------------------------------
       
   918 // CVcxConnUtilImpl::CheckAndChangeSlaveToMaster()
       
   919 // -----------------------------------------------------------------------------
       
   920 //
       
   921 TInt CVcxConnUtilImpl::CheckAndChangeSlaveToMaster()
       
   922     {
       
   923     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::CheckAndChangeSlaveToMaster in"); 
       
   924     TInt err( KErrNone );  
       
   925     TInt status( 0 );
       
   926     
       
   927     ///////
       
   928     // entering critical section
       
   929     iSemaSwitchRole.Wait();                
       
   930     err = iPubsub->GetValue( EVCxPSMasterExists, status );
       
   931     // if master already exists, do nothing
       
   932     if( !status && err == KErrNone)
       
   933         {
       
   934         MPX_DEBUG1( "CVcxConnUtilImpl::CheckAndChangeSlaveToMaster changing master");
       
   935         iMaster = ETrue;
       
   936         err = iPubsub->SetValue( EVCxPSMasterExists, iMaster );
       
   937         }
       
   938     iSemaSwitchRole.Signal();
       
   939     // Leaving critical section
       
   940     ///////
       
   941     
       
   942     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::CheckAndChangeSlaveToMaster out"); 
       
   943     return err;
       
   944     }
       
   945 
       
   946 // -----------------------------------------------------------------------------
       
   947 // CVcxConnUtilImpl::HandleSlaveConnectionStatusL()
       
   948 // -----------------------------------------------------------------------------
       
   949 //
       
   950 void CVcxConnUtilImpl::HandleSlaveConnectionStatusL( const TInt& aNewStatus )
       
   951     {
       
   952     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleSlaveConnectionStatus in"); 
       
   953     // if master, do nothing
       
   954     if( iMaster )
       
   955         {
       
   956         MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleSlaveConnectionStatus master out"); 
       
   957         return;
       
   958         }
       
   959     // resolve given connection, this structure is needed  
       
   960     // to prevent errors in type check
       
   961     TVCxConnectionStatus gottenStatus( EVCxNotConnected );
       
   962     switch( aNewStatus )
       
   963         {
       
   964         case EVCxNotConnected: 
       
   965             gottenStatus = EVCxNotConnected; 
       
   966             break;
       
   967         case EVCxConnecting:
       
   968             gottenStatus = EVCxConnecting;
       
   969             break;
       
   970         case EVCxConnected:
       
   971             gottenStatus = EVCxConnected;
       
   972             break;
       
   973         case EVCxDisconnecting:
       
   974             gottenStatus = EVCxDisconnecting;
       
   975             break;
       
   976         case EVCxRoamingRequest:
       
   977             gottenStatus = EVCxRoamingRequest;
       
   978             break;
       
   979         case EVCxRoamingAccepted:
       
   980             gottenStatus = EVCxRoamingAccepted;
       
   981             break;  
       
   982         case EVCxError:
       
   983             gottenStatus = EVCxError;
       
   984             break;        
       
   985         default:
       
   986             User::Leave( KErrGeneral );
       
   987             break;
       
   988         }
       
   989     TVCxConnectionStatus currentStatus = iEngine->ConnectionStatus();  
       
   990     
       
   991     MPX_DEBUG2( "HandleSlaveConnectionStatus gotten %d", gottenStatus );
       
   992     MPX_DEBUG2( "HandleSlaveConnectionStatus current %d", currentStatus );
       
   993     
       
   994     if( gottenStatus == EVCxRoamingRequest && currentStatus == EVCxConnected )
       
   995         {
       
   996         // if master is requesting roaming, query all external clients  
       
   997         // whether we can roam or not  
       
   998         MPX_DEBUG1( "CVcxConnUtilImpl::HandleSlaveConnectionStatus slave check Roaming");
       
   999         if ( DoRequestClientRoamingL() )
       
  1000             {
       
  1001             gottenStatus = EVCxRoamingAccepted;
       
  1002             }
       
  1003         // client might have disconnected during roaming. In that case do not change status
       
  1004         if( iEngine->ConnectionStatus() != EVCxNotConnected )
       
  1005             {
       
  1006             // set connection status explicitly to tell slave we're roaming
       
  1007             iEngine->SetConnectionStatus( gottenStatus );
       
  1008             }
       
  1009         }
       
  1010     
       
  1011     else if( ( currentStatus == EVCxRoamingRequest  ||
       
  1012                currentStatus == EVCxRoamingAccepted || 
       
  1013                currentStatus == EVCxConnected ) &&
       
  1014                gottenStatus == EVCxConnected )
       
  1015         {
       
  1016         // if current status was roaming or
       
  1017         // master has notified new connection and state
       
  1018         // has changed to connected, meaning
       
  1019         // master has succesfully reinitialized preferred connection
       
  1020         // slave needs to try to reinit connection via new iap if 
       
  1021         // new iap differs from current
       
  1022         
       
  1023         TInt valueFromPS( 0 );
       
  1024         User::LeaveIfError( iPubsub->GetValue( EVCxPSIapId, valueFromPS ) );
       
  1025         MPX_DEBUG2( "HandleSlaveConnectionStatus slave iap %d", iEngine->IapId() );
       
  1026         MPX_DEBUG2( "HandleSlaveConnectionStatus slave PS iap %d", valueFromPS );
       
  1027         if( valueFromPS != iEngine->IapId() )
       
  1028             {
       
  1029             User::LeaveIfError( iPubsub->GetValue( EVCxPSSnapId, valueFromPS ) );
       
  1030             iEngine->Disconnect();
       
  1031             if( DoCreateConnection( ETrue, valueFromPS, EFalse ) == KErrNone )
       
  1032                 { 
       
  1033                 // refresh connection details
       
  1034                 iEngine->FillActiveConnectionDetailsL();                  
       
  1035                 MPX_DEBUG1( "CVcxConnUtilImpl::HandleSlaveConnectionStatus slave restarted ok" );                
       
  1036                 }
       
  1037             else
       
  1038                 {
       
  1039                 MPX_DEBUG1( "CVcxConnUtilImpl::HandleSlaveConnectionStatus slave restarting not ok" );
       
  1040                 DisconnectL();
       
  1041                 gottenStatus = EVCxNotConnected;
       
  1042                 }            
       
  1043             NotifyObserversIAPChanged();
       
  1044             }
       
  1045         iEngine->SetConnectionStatus( gottenStatus );        
       
  1046         }
       
  1047     else 
       
  1048         {
       
  1049         if( gottenStatus == EVCxNotConnected || 
       
  1050             gottenStatus == EVCxError )
       
  1051             {
       
  1052             // master has notified disconnecting or error for some reason
       
  1053             DisconnectL();  
       
  1054             // notify normal disconnect to observers
       
  1055             if( gottenStatus == EVCxNotConnected )
       
  1056                 {
       
  1057                 NotifyObserversIAPChanged();
       
  1058                 }
       
  1059             }
       
  1060         }
       
  1061     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleSlaveConnectionStatus out");
       
  1062     }
       
  1063 
       
  1064 // -----------------------------------------------------------------------------
       
  1065 // CVcxConnUtilImpl::ValueChangedL()
       
  1066 // -----------------------------------------------------------------------------
       
  1067 //
       
  1068 void CVcxConnUtilImpl::HandleRoamingReponsesL( const TInt& aNbrOfResps )
       
  1069     {
       
  1070     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleRoamingReponsesL in"); 
       
  1071     if( !iMaster )
       
  1072         {
       
  1073         MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleRoamingReponsesL slave out");
       
  1074         return;
       
  1075         }
       
  1076     if( iEngine->ConnectionStatus() !=  EVCxRoamingRequest )
       
  1077         {
       
  1078         MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleRoamingReponsesL not roaming");
       
  1079         return;
       
  1080         }
       
  1081     // check if all have been responded and if all agreed on roaming
       
  1082     TInt nbrOfConUsers( 0 );
       
  1083     TInt nbrOfAgeed( 0 );
       
  1084     TInt nbrofResponses( aNbrOfResps );
       
  1085    
       
  1086     User::LeaveIfError( iPubsub->GetValue( EVCxPSNbrConnInstances, nbrOfConUsers )  );
       
  1087     User::LeaveIfError( iPubsub->GetValue( EVCxPSNbRoamAccepted, nbrOfAgeed )  );
       
  1088     
       
  1089     if( nbrOfConUsers == nbrofResponses )
       
  1090         {
       
  1091         if( nbrofResponses == nbrOfAgeed )
       
  1092             {
       
  1093             // every instance has responded and all agrees roaming, 
       
  1094             // change state for master's main thread to proceed
       
  1095             MPX_DEBUG1( "CVcxConnUtilImpl::HandleRoamingReponsesL EVCxRoamingAllowed");
       
  1096             
       
  1097             User::LeaveIfError( iPubsub->SetValue( 
       
  1098                               EVCxPSRoamingRequestStatus, EVCxRoamingAllowed ) );
       
  1099             }
       
  1100         else
       
  1101             {
       
  1102             MPX_DEBUG1( "CVcxConnUtilImpl::HandleRoamingReponsesL EVCxRoamingNotInit");
       
  1103             User::LeaveIfError( iPubsub->SetValue( 
       
  1104                                   EVCxPSRoamingRequestStatus, EVCxRoamingNotInit ) );
       
  1105             }
       
  1106         }  
       
  1107     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::HandleRoamingReponsesL out"); 
       
  1108     }
       
  1109 
       
  1110 // -----------------------------------------------------------------------------
       
  1111 // CVcxConnUtilImpl::NotifyObserversIAPChanged()
       
  1112 // -----------------------------------------------------------------------------
       
  1113 //
       
  1114 void CVcxConnUtilImpl::NotifyObserversIAPChanged()
       
  1115     {
       
  1116     for ( TInt i = 0; i < iObservers.Count(); i++ )
       
  1117         {
       
  1118         MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::NotifyObserversIAPChanged notifying observer"); 
       
  1119         TRAPD( err, iObservers[i]->IapChangedL() );
       
  1120         if( err != KErrNone )
       
  1121             {
       
  1122             MPX_DEBUG2( "vcxconnutil ## NotifyObserversIAPChanged::IapChanged observer leaved %d", err);               
       
  1123             }        
       
  1124         } 
       
  1125     }
       
  1126 
       
  1127 // -----------------------------------------------------------------------------
       
  1128 // CVcxConnUtilImpl::DisplayWaitNote()
       
  1129 // -----------------------------------------------------------------------------
       
  1130 //
       
  1131 void CVcxConnUtilImpl::DisplayWaitNote(const TDesC& aConnectionName)
       
  1132      {
       
  1133      MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::DisplayWaitNote in"); 
       
  1134      if( iUIInterface )
       
  1135          {
       
  1136          iUIInterface->DisplayWaitNote( aConnectionName );
       
  1137          }
       
  1138      MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::DisplayWaitNote out");
       
  1139      }
       
  1140 
       
  1141 // -----------------------------------------------------------------------------
       
  1142 // CVcxConnUtilImpl::CloseWaitNote()
       
  1143 // -----------------------------------------------------------------------------
       
  1144 //
       
  1145 void CVcxConnUtilImpl::CloseWaitNote()
       
  1146     {
       
  1147     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::CloseWaitNote in");
       
  1148     if( iUIInterface )
       
  1149          {
       
  1150          iUIInterface->CloseWaitNote();
       
  1151          }
       
  1152     MPX_DEBUG1( "vcxconnutil ## CVcxConnUtilImpl::CloseWaitNote out");
       
  1153     }
       
  1154 
       
  1155 //  End of File