msgconnmanager/src/msgconnmanager.cpp
branchRCL_3
changeset 18 fbd2e7cec7ef
parent 0 c8caa15ef882
equal deleted inserted replaced
17:2669f8761a99 18:fbd2e7cec7ef
       
     1 /*
       
     2 * Copyright (c) 2005 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:   Connection manager
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <in_sock.h>
       
    23 #include <es_enum.h>
       
    24 #include <f32file.h>
       
    25 #include <flogger.h>
       
    26 #include "msgconntimer.h"
       
    27 #include "msgconnmanager.h"
       
    28 
       
    29 // ================= MEMBER FUNCTIONS =======================
       
    30 //
       
    31 
       
    32 
       
    33 // ----------------------------------------------------------
       
    34 // CMsgConnManager::CMsgConnManager
       
    35 // 
       
    36 // ----------------------------------------------------------
       
    37 //
       
    38 CMsgConnManager::CMsgConnManager() : CActive( EPriorityUserInput + 2 ),
       
    39                                      iProgressStarted( EFalse ),
       
    40                                      iConnectionClosed( ETrue )
       
    41                                                 
       
    42     {
       
    43     
       
    44     }
       
    45 
       
    46 // ----------------------------------------------------------
       
    47 // CMsgConnManager::NewL
       
    48 // 
       
    49 // ----------------------------------------------------------
       
    50 //
       
    51 CMsgConnManager* CMsgConnManager::NewL( const TInt aAccessPoint )
       
    52     {
       
    53     CMsgConnManager* self = new ( ELeave ) CMsgConnManager();
       
    54     CleanupStack::PushL( self );
       
    55     self->ConstructL( aAccessPoint );
       
    56     CleanupStack::Pop();
       
    57     return self;
       
    58     }
       
    59 
       
    60 // ----------------------------------------------------------
       
    61 // CMsgConnManager::ConstructL
       
    62 // 
       
    63 // ----------------------------------------------------------
       
    64 //
       
    65 void CMsgConnManager::ConstructL( const TInt aAccessPoint )
       
    66     {
       
    67     DeleteLogFileL();
       
    68     iAccessPointID = aAccessPoint;
       
    69     iConnectionTimer = CMsgConnTimer::NewL();
       
    70     iCommsDatabase = CCommsDatabase::NewL( EDatabaseTypeUnspecified );
       
    71     User::LeaveIfError( iSocketSession.Connect() );
       
    72     User::LeaveIfError( iConnection.Open( iSocketSession ) );
       
    73     iConnectionClosed = EFalse;
       
    74     iAccessPointSettings.SetIapId( aAccessPoint );
       
    75     iAccessPointSettings.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
       
    76     #ifdef _DEBUG
       
    77         WriteToLog( _L8( "CONNMAN: LOGGING ENABLED" ) );
       
    78     #endif
       
    79     CActiveScheduler::Add( this );
       
    80     }
       
    81 
       
    82 // ----------------------------------------------------
       
    83 // CMsgConnManager::~CMsgConnManager
       
    84 // 
       
    85 // ----------------------------------------------------
       
    86 //
       
    87 CMsgConnManager::~CMsgConnManager()
       
    88     {
       
    89     #ifdef _DEBUG
       
    90         WriteToLog( _L8( "CMsgConnManager::~CMsgConnManager(), Destructor." ) );
       
    91     #endif
       
    92     Cancel();
       
    93     delete iCommsDatabase;
       
    94     delete iConnectionTimer;
       
    95     iConnection.Close();
       
    96     iSocketSession.Close();
       
    97     iEventSubscribers.Close();
       
    98     }
       
    99 
       
   100 // ----------------------------------------------------------
       
   101 // CMsgConnManager::DeleteLogFileL
       
   102 // 
       
   103 // ----------------------------------------------------------
       
   104 //
       
   105 void CMsgConnManager::DeleteLogFileL()
       
   106     {
       
   107     RFs session;
       
   108     User::LeaveIfError( session.Connect() );
       
   109     CFileMan* manager = CFileMan::NewL( session );
       
   110     manager->Delete( _L("C:\\logs\\MsgConnMan\\*.*") );
       
   111     session.Close();
       
   112     delete manager;
       
   113     manager = NULL;
       
   114     }
       
   115 
       
   116 // ---------------------------------------------------------
       
   117 // CMsgConnManager::StartBearerObserver
       
   118 // 
       
   119 // ---------------------------------------------------------
       
   120 //
       
   121 void CMsgConnManager::StartNetworkObserver()
       
   122     {
       
   123     #ifdef _DEBUG
       
   124         WriteToLog( _L8( "CMsgConnManager::StartNetworkObserver()  Closed: %d" ), iConnectionClosed );
       
   125     #endif
       
   126     #ifdef __WINS__
       
   127         if( !iConnectionClosed )
       
   128             {
       
   129             iStatus = KRequestPending;
       
   130             SetActive();
       
   131             }
       
   132     #else
       
   133         if( !iConnectionClosed )
       
   134             {
       
   135             if( !IsActive() )
       
   136                 {
       
   137                 iStatus = KRequestPending;
       
   138                 iConnection.ProgressNotification( iProgressBuffer, iStatus );
       
   139                 SetActive();
       
   140                 }
       
   141             }
       
   142     #endif
       
   143     }
       
   144 
       
   145 // ---------------------------------------------------------
       
   146 // CMsgConnManager::RunL()
       
   147 // 
       
   148 // ---------------------------------------------------------
       
   149 //
       
   150 void CMsgConnManager::RunL()
       
   151     {
       
   152     #ifdef _DEBUG
       
   153         WriteToLog( _L8( "CMsgConnManager::RunL(), iConnManStatus: %d  iStatus: %d  iStage: %d  iError: %d" ),
       
   154                     iConnManStatus, iStatus.Int(), iProgressBuffer().iStage, iProgressBuffer().iError );
       
   155     #endif
       
   156     switch( iConnManStatus ) 
       
   157         {
       
   158         case EMsgConnManWaitingForStartComplete:
       
   159             #ifdef _DEBUG
       
   160                 WriteToLog( _L8( " Current status is EMsgConnManWaitingForStartComplete." ) );
       
   161             #endif
       
   162             WatchConnectionOpening();
       
   163             break;
       
   164         case EMsgConnManWaitingForNotifications:
       
   165             #ifdef _DEBUG
       
   166                 WriteToLog( _L8( " Current status is EMsgConnManWaitingForNotifications." ) );
       
   167             #endif
       
   168             WatchConnectionOpening();
       
   169             break;
       
   170         case EMsgConnManObservingAccessPoint:
       
   171             #ifdef _DEBUG
       
   172                 WriteToLog( _L8( " Current status is EMsgConnManObservingAccessPoint." ) );
       
   173             #endif
       
   174             DetermineConnectionStatusL();
       
   175             break;
       
   176         case EMsgConnManBearerSuspended:
       
   177             #ifdef _DEBUG
       
   178                 WriteToLog( _L8( " Current status is EMsgConnManBearerSuspended." ) );
       
   179             #endif
       
   180             DetermineConnectionStatusL();
       
   181             break;
       
   182         case EMsgConnManDisconnectingPrevious:
       
   183             #ifdef _DEBUG
       
   184                 WriteToLog( _L8( " Timer expired, complete client's request." ) );
       
   185             #endif
       
   186             User::RequestComplete( iTimedCompleteStatus, KErrNone );
       
   187             iConnManStatus = EMsgConnManIdle;
       
   188             break;
       
   189         case EMsgConnManIdle:
       
   190             #ifdef _DEBUG
       
   191                 WriteToLog( _L8( " Idle, iStatus is %d." ), iStatus.Int() );
       
   192             #endif
       
   193             break;
       
   194         default:
       
   195             #ifdef _DEBUG
       
   196                 WriteToLog( _L8( " Default case, should not be here." ) );
       
   197             #endif
       
   198             break;
       
   199         }
       
   200     #ifdef _DEBUG
       
   201         WriteToLog( _L8( " RunL() ends" ) );
       
   202     #endif
       
   203     }
       
   204 
       
   205 // ----------------------------------------------------
       
   206 // CMsgConnManager::WatchConnectionOpening()
       
   207 // 
       
   208 // ----------------------------------------------------
       
   209 //
       
   210 void CMsgConnManager::WatchConnectionOpening()
       
   211     {
       
   212     #ifdef _DEBUG
       
   213         WriteToLog( _L8( "  CMsgConnManager::WatchConnectionOpening() - iProgressStarted: %d" ), iProgressStarted );
       
   214     #endif
       
   215     //Lets quit right away if it is an error
       
   216     if( iStatus != KErrNone )
       
   217         {
       
   218         #ifdef _DEBUG
       
   219             WriteToLog( _L8( "   Something wrong, complete with error: %d." ), iStatus.Int() );
       
   220         #endif
       
   221         iConnectionTimer->Cancel();
       
   222         if( iConnManStatus == EMsgConnManWaitingForNotifications )
       
   223             iConnection.CancelProgressNotification();
       
   224         iConnection.Close();
       
   225         iConnectionClosed = ETrue;
       
   226         User::RequestComplete( iClientStatus, iStatus.Int() );
       
   227         iConnManStatus = EMsgConnManIdle;
       
   228         }
       
   229     else
       
   230         {
       
   231         if( iProgressStarted )
       
   232             {
       
   233             iLastConnectionStage = iProgressBuffer().iStage;
       
   234             if( iLastConnectionStage == KLinkLayerOpen )  //we are done
       
   235                 {
       
   236                 #ifdef _DEBUG
       
   237                     WriteToLog( _L8( "   Connected. Completing with KErrNone." ) );
       
   238                 #endif
       
   239                 iConnectionTimer->Cancel();
       
   240                 iConnManStatus = EMsgConnManObservingAccessPoint;
       
   241                 StartNetworkObserver();
       
   242                 User::RequestComplete( iClientStatus, KErrNone );
       
   243                 iProgressStarted = EFalse;
       
   244                 }
       
   245             else
       
   246                 {
       
   247                 #ifdef _DEBUG
       
   248                     WriteToLog( _L8( "   Keep on waiting for progress." ) );
       
   249                 #endif
       
   250                 IssueRequest();
       
   251                 }
       
   252             }
       
   253         else
       
   254             {
       
   255             #ifdef _DEBUG
       
   256                 WriteToLog( _L8( "   Start complete, watch progress." ) );
       
   257             #endif
       
   258             if( iConnManStatus == EMsgConnManWaitingForStartComplete )
       
   259                 {
       
   260                 iProgressStarted = ETrue;
       
   261                 iConnManStatus = EMsgConnManWaitingForNotifications;
       
   262                 }
       
   263             IssueRequest();
       
   264             }
       
   265         }
       
   266     }
       
   267 
       
   268 // ----------------------------------------------------
       
   269 // CMsgConnManager::DetermineConnectionStatus()
       
   270 // 
       
   271 // ----------------------------------------------------
       
   272 //
       
   273 void CMsgConnManager::DetermineConnectionStatusL()
       
   274     {
       
   275     #ifdef _DEBUG
       
   276         WriteToLog( _L8( "  CMsgConnManager::DetermineConnectionStatus()" ) );
       
   277     #endif
       
   278     #ifdef __WINS__
       
   279         Cancel();
       
   280         switch( iStatus.Int() )
       
   281     #else
       
   282         switch( iProgressBuffer().iStage )
       
   283     #endif
       
   284         {
       
   285         case KLinkLayerClosed:
       
   286         case KConnectionUninitialised:
       
   287             #ifdef _DEBUG
       
   288                 CMsgConnManager::WriteToLog( _L8( "   KLinkLayerClosed, notify clients of EMsgBearerLost" ) );
       
   289             #endif
       
   290             Cancel();
       
   291             iConnManStatus = EMsgConnManBearerLost;
       
   292             BroadcastBearerEventL( EMsgBearerLost );
       
   293             iConnection.Close();
       
   294             iConnectionClosed = ETrue;
       
   295             iEventSubscribers.Reset();
       
   296             iConnManStatus = EMsgConnManIdle;
       
   297             break;
       
   298         case KLinkLayerOpen:
       
   299             #ifdef _DEBUG
       
   300                 WriteToLog( _L8( "   KLinkLayerOpen -> GPRS Context Active." ) );
       
   301             #endif
       
   302             if( iConnManStatus == EMsgConnManBearerSuspended )
       
   303                 {
       
   304                 #ifdef _DEBUG
       
   305                     WriteToLog( _L8( "   Moving to active state." ) );
       
   306                 #endif
       
   307                 iConnManStatus = EMsgConnManObservingAccessPoint;
       
   308                 BroadcastBearerEventL( EMsgBearerActive );
       
   309                 StartNetworkObserver();
       
   310                 }
       
   311             break;
       
   312         case KDataTransferTemporarilyBlocked:
       
   313             #ifdef _DEBUG
       
   314                 WriteToLog( _L8( "   KDataTransferTemporarilyBlocked -> GPRS Context Suspended." ) );
       
   315             #endif
       
   316             if( iConnManStatus != EMsgConnManBearerSuspended )
       
   317                 {
       
   318                 #ifdef _DEBUG
       
   319                     WriteToLog( _L8( "   Moving to suspended state." ) );
       
   320                 #endif
       
   321                 iConnManStatus = EMsgConnManBearerSuspended;
       
   322                 BroadcastBearerEventL( EMsgBearerSuspended );
       
   323                 }
       
   324             StartNetworkObserver();
       
   325             break;
       
   326         default:
       
   327             #ifdef _DEBUG
       
   328                 #ifdef __WINS__
       
   329                     if( iStatus.Int() == KErrCancel )
       
   330                         WriteToLog( _L8( "   Bearer event generation cancelled" ) );
       
   331                     else
       
   332                         WriteToLog( _L8( "   Some weird status: %d" ), iStatus.Int() );
       
   333                 #else
       
   334                     WriteToLog( _L8( "   Default case! WTF?!?" ) );
       
   335                 #endif
       
   336             #endif
       
   337             StartNetworkObserver();
       
   338             break;
       
   339         }     
       
   340     }
       
   341 
       
   342 // ---------------------------------------------------------
       
   343 // CMsgConnManager::CancelStartL
       
   344 // 
       
   345 // ---------------------------------------------------------
       
   346 //
       
   347 void CMsgConnManager::CancelStartL()
       
   348     {
       
   349     #ifdef _DEBUG
       
   350         WriteToLog( _L8( "CMsgConnManager::CancelStartL()" ) );
       
   351     #endif
       
   352     if( iClientStatus != NULL && iClientStatus->Int() == KRequestPending )
       
   353         {
       
   354         if( iConnManStatus == EMsgConnManWaitingForStartComplete ||
       
   355             iConnManStatus == EMsgConnManWaitingForNotifications )
       
   356             {
       
   357             Cancel();
       
   358             iEventSubscribers.Reset();
       
   359             User::RequestComplete( iClientStatus, KErrCancel );
       
   360             iConnManStatus = EMsgConnManIdle;
       
   361             iConnectionClosed = ETrue;
       
   362             }
       
   363         else User::Leave( KErrAbort );
       
   364         }
       
   365     else User::Leave( KErrAbort );
       
   366     }
       
   367 
       
   368 // ---------------------------------------------------------
       
   369 // CMsgConnManager::StopConnection
       
   370 // 
       
   371 // ---------------------------------------------------------
       
   372 //
       
   373 void CMsgConnManager::StopConnection()
       
   374     {
       
   375     #ifdef _DEBUG
       
   376         WriteToLog( _L8( "CMsgConnManager::StopConnection()" ) );
       
   377     #endif
       
   378     if( iConnManStatus == EMsgConnManWaitingForStartComplete ||
       
   379         iConnManStatus == EMsgConnManWaitingForNotifications ||
       
   380         iConnManStatus == EMsgConnManIdle )
       
   381         {
       
   382         #ifdef _DEBUG
       
   383             WriteToLog( _L8( "  Status is %d, wrong state for this operation. Abort." ), iConnManStatus );
       
   384         #endif
       
   385         }
       
   386     else
       
   387         {
       
   388         //If bearer has been lost, we're already closed
       
   389         if( iConnManStatus != EMsgConnManBearerLost )
       
   390             {
       
   391             Cancel();
       
   392             iConnection.Close();
       
   393             iConnectionClosed = ETrue;
       
   394             iEventSubscribers.Reset();
       
   395             iConnManStatus = EMsgConnManIdle;
       
   396             }
       
   397         }
       
   398     #ifdef _DEBUG
       
   399         WriteToLog( _L8( "  StopConnection() ends." ) );
       
   400     #endif
       
   401     }
       
   402 
       
   403 // ---------------------------------------------------------
       
   404 // CMsgConnManager::StopConnection
       
   405 // 
       
   406 // ---------------------------------------------------------
       
   407 //
       
   408 void CMsgConnManager::StopConnection( TRequestStatus& aStatus )
       
   409     {
       
   410     #ifdef _DEBUG
       
   411         WriteToLog( _L8( "CImpsConnectionManager::StopConnectionL()" ) );
       
   412     #endif  
       
   413     aStatus = KRequestPending;
       
   414     iClientStatus = &aStatus;
       
   415     iTimedCompleteStatus = &aStatus;
       
   416     if( iConnManStatus == EMsgConnManWaitingForStartComplete ||
       
   417         iConnManStatus == EMsgConnManWaitingForNotifications ||
       
   418         iConnManStatus == EMsgConnManDisconnectingPrevious ||
       
   419         iConnManStatus == EMsgConnManIdle )
       
   420         {
       
   421         #ifdef _DEBUG
       
   422             WriteToLog( _L8( "  Status is %d, wrong state for this operation. Abort." ),
       
   423                                 iConnManStatus );
       
   424         #endif
       
   425         User::RequestComplete( iClientStatus, KErrAbort );
       
   426         }
       
   427     else
       
   428         {
       
   429         //If bearer has been lost, we're already closed
       
   430         if( iConnManStatus != EMsgConnManBearerLost )
       
   431             {
       
   432             Cancel();
       
   433             iConnection.Close();
       
   434             iConnectionClosed = ETrue;
       
   435             iEventSubscribers.Reset();
       
   436             iConnectionTimer->ActivateTimer( iStatus, 4000000 );
       
   437             iConnManStatus = EMsgConnManDisconnectingPrevious;
       
   438             SetActive();
       
   439             }
       
   440         else
       
   441             {
       
   442             #ifdef _DEBUG
       
   443                 WriteToLog( _L8( "  Bearer lost, nothing to do. Complete with KErrNone" ) );
       
   444             #endif
       
   445             User::RequestComplete( iClientStatus, KErrNone );
       
   446             }
       
   447         }
       
   448     #ifdef _DEBUG
       
   449         WriteToLog( _L8( " StopConnectionL() ends" ) );
       
   450     #endif
       
   451     }
       
   452     
       
   453 // ----------------------------------------------------
       
   454 // CMsgConnManager::BroadcastBearerEvent
       
   455 // 
       
   456 // ----------------------------------------------------
       
   457 //
       
   458 void CMsgConnManager::BroadcastBearerEventL( const TMsgBearerEvent aBearerEvent )
       
   459     {
       
   460     #ifdef _DEBUG
       
   461         WriteToLog( _L8( "CMsgConnManager::BroadcastBearerEvent" ) );
       
   462     #endif
       
   463     TInt subs = iEventSubscribers.Count();
       
   464     #ifdef _DEBUG
       
   465         WriteToLog( _L8( " %d clients subscribed." ), subs );
       
   466     #endif
       
   467     if( subs > 0 )
       
   468         {
       
   469         TBool empty = EFalse;
       
   470         MMsgBearerObsCallback* client = NULL;
       
   471         for( TInt i = 0;i < subs && !empty;i++ )
       
   472             {
       
   473             //Just in case:
       
   474             //If a client has managed to remove a listener from the queue
       
   475             //in the previous callback, "i" will index a bad handle.
       
   476             subs = iEventSubscribers.Count();
       
   477             if( subs > 0 && i < subs )
       
   478                 {
       
   479                 client = iEventSubscribers[i];
       
   480                 __ASSERT_ALWAYS( client != NULL, User::Panic( _L( "ObserverNULL!" ), 1 ) );
       
   481                 TInt error = iProgressBuffer().iError;
       
   482                 if( aBearerEvent == EMsgBearerLost )
       
   483                     {
       
   484                     #ifdef _DEBUG
       
   485                         TInt stage = iProgressBuffer().iStage;
       
   486                         WriteToLog( _L8( " Event is EMsgBearerLost" ) );
       
   487                         WriteToLog( _L8( "   Stage: %d" ), stage );
       
   488                         WriteToLog( _L8( "   Error: %d" ), error );
       
   489                     #endif
       
   490                     }
       
   491                 TBool authClose = error == KErrConnectionTerminated;
       
   492                 client->HandleBearerEventL( authClose, aBearerEvent );
       
   493                 #ifdef _DEBUG
       
   494                     WriteToLog( _L8("  Client no. %d serviced" ), i );
       
   495                 #endif
       
   496                 }
       
   497             else
       
   498                 {
       
   499                 #ifdef _DEBUG
       
   500                     WriteToLog( _L8(
       
   501                     "  An event listener was removed inside the callback!" ) );
       
   502                 #endif
       
   503                 //Leave the for loop
       
   504                 empty = ETrue;
       
   505                 }
       
   506             }
       
   507         }
       
   508     #ifdef _DEBUG
       
   509         WriteToLog( _L8( " BroadcastBearerEvent() ends" ) );
       
   510     #endif
       
   511     }
       
   512 
       
   513 // ----------------------------------------------------
       
   514 // CMsgConnManager::IssueRequest
       
   515 // 
       
   516 // ----------------------------------------------------
       
   517 //
       
   518 void CMsgConnManager::IssueRequest()
       
   519     {
       
   520     #ifdef _DEBUG
       
   521         WriteToLog( _L8( "CMsgConnManager::IssueRequest(), status: %d" ), IsActive() );
       
   522     #endif
       
   523     iStatus = KRequestPending;
       
   524     iConnection.ProgressNotification( iProgressBuffer, iStatus );
       
   525     SetActive();
       
   526     }
       
   527 
       
   528 // ---------------------------------------------------------
       
   529 // CMsgConnManager::StartConnection
       
   530 //
       
   531 // ---------------------------------------------------------
       
   532 //
       
   533 void CMsgConnManager::StartConnection( TRequestStatus& aStatus )
       
   534     {
       
   535     #ifdef _DEBUG
       
   536         WriteToLog( _L8( "CMsgConnManager::StartConnection()  iConnManStatus: %d" ), iConnManStatus );
       
   537     #endif
       
   538     TInt error = 0;
       
   539     aStatus = KRequestPending;
       
   540     iClientStatus = &aStatus;
       
   541     if( iConnectionClosed )
       
   542         {
       
   543         error = iConnection.Open( iSocketSession );
       
   544         iConnectionClosed = EFalse;
       
   545         }
       
   546     TBool exists = EFalse;
       
   547     TNifProgress progress;
       
   548     error = iConnection.Progress( progress );
       
   549     #ifdef _DEBUG
       
   550         WriteToLog( _L8( " Connection stage: %d  error: %d" ), progress.iStage, error );
       
   551     #endif
       
   552     TRAPD( err, exists = IsValidApL( iAccessPointID ) );
       
   553     if( ( error == KErrNone && err == KErrNone ) && exists )
       
   554         {
       
   555         if( progress.iStage == KConnectionUninitialised ) 
       
   556             HandleNewConnection();
       
   557         else
       
   558             HandleExistingConnection();
       
   559         }
       
   560     else
       
   561         {
       
   562         #ifdef _DEBUG
       
   563             WriteToLog( _L8( " Something's wrong, complete with KErrUnknown. IAP exists: %d  Error: %d Err: %d" ), exists, error, err );
       
   564         #endif
       
   565         User::RequestComplete( iClientStatus, KErrUnknown );
       
   566         iConnectionClosed = ETrue;
       
   567         }
       
   568     }
       
   569 
       
   570 // ---------------------------------------------------------
       
   571 // CMsgConnManager::HandleNewConnection
       
   572 // 
       
   573 // ---------------------------------------------------------
       
   574 //
       
   575 void CMsgConnManager::HandleNewConnection()
       
   576     {
       
   577     #ifdef _DEBUG
       
   578         WriteToLog( _L8( "  CMsgConnManager::HandleNewConnection()" ) );
       
   579     #endif
       
   580     switch( iConnManStatus )
       
   581         {
       
   582         case EMsgConnManIdle:
       
   583             #ifdef _DEBUG
       
   584                 WriteToLog( _L8( "   Current status is EMsgConnManIdle," ) );
       
   585                 WriteToLog( _L8( "   starting to connect  IAP: %d" ), iAccessPointSettings.IapId() );
       
   586             #endif
       
   587             iLastConnectionStage = KConnectionUninitialised;
       
   588             iConnection.Start( iAccessPointSettings, iStatus );
       
   589             iConnManStatus = EMsgConnManWaitingForStartComplete;
       
   590             iConnectionTimer->ActivateTimer( this, 20000000 );
       
   591             SetActive();
       
   592             break;
       
   593         case EMsgConnManDisconnectingPrevious:
       
   594             #ifdef _DEBUG
       
   595                 WriteToLog( _L8( "   Current status is EMsgConnManDisconnectingPrevious," ) );
       
   596                 WriteToLog( _L8( "   new connection cannot be started, ignore." ) );
       
   597             #endif
       
   598             User::RequestComplete( iClientStatus, KErrNotReady );
       
   599             break;
       
   600         default:
       
   601             #ifdef _DEBUG
       
   602                 WriteToLog( _L8( "   We're in some weird state, complete with KErrUnknown" ) );
       
   603             #endif
       
   604             User::RequestComplete( iClientStatus, KErrUnknown );
       
   605             iConnManStatus = EMsgConnManIdle;
       
   606             break;
       
   607         }   
       
   608     }
       
   609 
       
   610 // ---------------------------------------------------------
       
   611 // CMsgConnManager::HandleExistingConnection
       
   612 // 
       
   613 // ---------------------------------------------------------
       
   614 //
       
   615 void CMsgConnManager::HandleExistingConnection()
       
   616     {
       
   617     #ifdef _DEBUG
       
   618         WriteToLog( _L8( "  CMsgConnManager::HandleOldConnection()" ) );
       
   619     #endif
       
   620     switch( iConnManStatus )
       
   621         {
       
   622         case EMsgConnManDisconnectingPrevious:
       
   623             #ifdef _DEBUG
       
   624                 WriteToLog( _L8( "   Current status is EMsgConnManDisconnectingPrevious," ) );
       
   625                 WriteToLog( _L8( "   attempting to open a connection while previous one is still disconnecting. Complete with KErrNotReady." ) );
       
   626             #endif
       
   627             User::RequestComplete( iClientStatus, KErrNotReady );
       
   628             break;
       
   629         case EMsgConnManObservingAccessPoint:
       
   630             #ifdef _DEBUG
       
   631                 WriteToLog( _L8( "   Current status is EMsgConnManObservingAccessPoint," ) );
       
   632                 WriteToLog( _L8( "   already connected" ) );
       
   633             #endif
       
   634             User::RequestComplete( iClientStatus, KErrNone );
       
   635             break;
       
   636         case EMsgConnManWaitingForStartComplete:
       
   637         case EMsgConnManWaitingForNotifications:
       
   638             #ifdef _DEBUG
       
   639                 WriteToLog( _L8( "   Already connecting, ignore" ) );
       
   640             #endif
       
   641             User::RequestComplete( iClientStatus, KErrAlreadyExists );
       
   642             break;
       
   643         default:
       
   644             #ifdef _DEBUG
       
   645                 WriteToLog( _L8( "   Unknown state, complete with KErrUnknown." ) );
       
   646             #endif
       
   647             User::RequestComplete( iClientStatus, KErrUnknown );
       
   648         }
       
   649     }
       
   650 
       
   651 // ---------------------------------------------------------
       
   652 // CMsgConnManager::HandleTimerEventL
       
   653 // 
       
   654 // ---------------------------------------------------------
       
   655 //
       
   656 void CMsgConnManager::HandleTimerEvent( TInt /*aStatus*/ )
       
   657     {
       
   658     #ifdef _DEBUG
       
   659         WriteToLog( _L8( "CMsgConnManager::HandleTimerEventL()" ) );
       
   660     #endif
       
   661     switch( iConnManStatus )
       
   662         {
       
   663         case EMsgConnManWaitingForNotifications:
       
   664         case EMsgConnManWaitingForStartComplete:
       
   665             Cancel();
       
   666             #ifdef _DEBUG
       
   667                 WriteToLog( _L8( "  Connection initiation timed out, complete with error KErrTimedOut" ) );
       
   668             #endif
       
   669             User::RequestComplete( iClientStatus, KErrTimedOut );
       
   670             iConnection.Close();
       
   671             iConnectionClosed = ETrue;
       
   672             iConnManStatus = EMsgConnManIdle;
       
   673             break;
       
   674         default:
       
   675             #ifdef _DEBUG
       
   676                 WriteToLog( _L8( "  Default case, problems..." ) );
       
   677             #endif
       
   678             break;
       
   679         }
       
   680     }
       
   681 
       
   682 // ---------------------------------------------------------
       
   683 // CMsgConnManager::AddEventSubscriberL
       
   684 // 
       
   685 // ---------------------------------------------------------
       
   686 //
       
   687 void CMsgConnManager::AddEventSubscriberL( MMsgBearerObsCallback* aClient )
       
   688     {
       
   689     #ifdef _DEBUG
       
   690         WriteToLog( _L8( "CMsgConnManager::AddEventSubscriberL()" ) );
       
   691     #endif
       
   692     if( iEventSubscribers.Count() < KMaxNumberOfSubscribers )
       
   693         User::LeaveIfError( iEventSubscribers.Append( aClient ) );
       
   694     else
       
   695         {
       
   696         #ifdef _DEBUG
       
   697             WriteToLog( _L8( "  Not allowed to have more than %d clients" ), KMaxNumberOfSubscribers );
       
   698         #endif
       
   699         User::Leave( KErrAlreadyExists );
       
   700         }
       
   701     }
       
   702 
       
   703 // ---------------------------------------------------------
       
   704 // CMsgConnManager::RemoveEventSubscriber
       
   705 // 
       
   706 // ---------------------------------------------------------
       
   707 //
       
   708 void CMsgConnManager::RemoveEventSubscriber( MMsgBearerObsCallback* aClient )
       
   709     {
       
   710     #ifdef _DEBUG
       
   711         WriteToLog( _L8( "CMsgConnManager::RemoveEventSubscriber()" ) );
       
   712     #endif
       
   713     TInt index = iEventSubscribers.Find( aClient );
       
   714     if( index >= 0 )
       
   715         {      
       
   716         iEventSubscribers.Remove( index );
       
   717         }
       
   718     }
       
   719 
       
   720 #ifdef _DEBUG
       
   721 // ----------------------------------------------------
       
   722 // CMsgConnManager::WriteToLog
       
   723 // 
       
   724 // ----------------------------------------------------
       
   725 //
       
   726 void CMsgConnManager::WriteToLog( TRefByValue<const TDesC8> aFmt,... )                                 
       
   727     {
       
   728     VA_LIST list;
       
   729     VA_START( list, aFmt );
       
   730     TBuf8<KConnManLogBufferMaxSize> buf;
       
   731     buf.FormatList( aFmt, list );
       
   732     RDebug::RawPrint( buf );
       
   733     RFileLogger::Write( KConnManLogDir, KConnManLogFile, EFileLoggingModeAppend, buf );
       
   734     }
       
   735 #endif
       
   736 
       
   737 // ----------------------------------------------------
       
   738 // CMsgConnManager::SetAccessPointIDL
       
   739 // 
       
   740 // ----------------------------------------------------
       
   741 //
       
   742 void CMsgConnManager::SetAccessPointIDL( const TInt aAccessPointID )
       
   743     {
       
   744     #ifdef _DEBUG
       
   745         WriteToLog( _L8( "CMsgConnManager::SetAccessPointIDL: %d" ), aAccessPointID );
       
   746     #endif
       
   747     if( IsValidApL( aAccessPointID ) )
       
   748         {
       
   749         iAccessPointID = aAccessPointID;
       
   750         iAccessPointSettings.SetIapId( iAccessPointID );
       
   751         iAccessPointSettings.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
       
   752         }
       
   753     else
       
   754         {
       
   755         #ifdef _DEBUG
       
   756             WriteToLog( _L8( "  The specified AP does not exist, leaves with KErrNotFound" ) );
       
   757         #endif
       
   758         User::Leave( KErrNotFound );
       
   759         }
       
   760     }
       
   761 
       
   762 // ----------------------------------------------------
       
   763 // CMsgConnManager::NumberOfActiveConns
       
   764 // 
       
   765 // ----------------------------------------------------
       
   766 //
       
   767 TInt CMsgConnManager::NumberOfActiveConns()
       
   768     {
       
   769     TUint count = 0;
       
   770     TInt error = KErrNone;
       
   771     if( !iConnectionClosed )
       
   772     	{
       
   773     	error = iConnection.EnumerateConnections( count );
       
   774     	}
       
   775     #ifdef _DEBUG
       
   776         WriteToLog( _L8( "CMsgConnManager::NumberOfActiveConns()  Conns: %d  Error: %d" ), count, error );
       
   777     #endif
       
   778     return KErrNone == error ? count : error;
       
   779     }
       
   780 
       
   781 // ---------------------------------------------------------
       
   782 // CMsgConnManager::ReadFromCommsDbLC
       
   783 // 
       
   784 // ---------------------------------------------------------
       
   785 //
       
   786 HBufC* CMsgConnManager::ReadFromCommsDbLC( const TSupportedCommDbRecords aParameter )
       
   787     {
       
   788     #ifdef _DEBUG
       
   789         WriteToLog( _L8( "CMsgConnManager::ReadFromCommsDbLC()" ) );
       
   790     #endif
       
   791     TPtrC dbRecord;
       
   792     HBufC* value = NULL;
       
   793     CCommsDbTableView* view = NULL;
       
   794     TInt error = InitCommDbViewLC( dbRecord, view, aParameter );
       
   795     if( error == KErrNone )
       
   796         {
       
   797         TDbColType colType;
       
   798         TUint32 attribute = 0;
       
   799         view->ReadTypeAttribL( dbRecord, colType, attribute );
       
   800         switch( colType )
       
   801             {
       
   802             case EDbColBit:
       
   803                 break;
       
   804             case EDbColUint32:
       
   805                 {
       
   806                 TUint32 intValue = 0;
       
   807                 _LIT( KProxyPort,"%d" );
       
   808                 view->ReadUintL( dbRecord, intValue );
       
   809                 value = HBufC::NewLC( sizeof( KProxyPort ) );
       
   810                 TPtr portPtr( value->Des() );
       
   811                 portPtr.Format( KProxyPort, intValue ); 
       
   812                 value->Des().Copy( portPtr );    
       
   813                 }
       
   814                 break;
       
   815             case EDbColText8:
       
   816                 break;
       
   817             case EDbColText16:
       
   818                 break;
       
   819             case EDbColLongText16:
       
   820                 value = view->ReadLongTextLC( dbRecord );
       
   821                 break;
       
   822             default:
       
   823                 break;
       
   824             }
       
   825             if( value != NULL )
       
   826                 {
       
   827                 #ifdef _DEBUG
       
   828                     HBufC8* temp = HBufC8::NewL( value->Des().Length() );
       
   829                     TPtr8 ptr( temp->Des() );
       
   830                     ptr.Copy( *value );
       
   831                     WriteToLog( _L8( "  Value was found: %S" ), &ptr );
       
   832                     delete temp;
       
   833                     temp = NULL;
       
   834                 #endif
       
   835                 CleanupStack::Pop();                //value
       
   836                 CleanupStack::PopAndDestroy();      //view
       
   837                 CleanupStack::PushL( value );       //Put it back in
       
   838                 }
       
   839             else
       
   840                 {
       
   841                 #ifdef _DEBUG
       
   842                     WriteToLog( _L8( "  No proxy address defined in CommDb" ) );
       
   843                 #endif
       
   844                 CleanupStack::PopAndDestroy();      //view
       
   845                 }
       
   846         }
       
   847     else
       
   848         {
       
   849         #ifdef _DEBUG
       
   850             WriteToLog( _L8( "  Error: %d" ), error );
       
   851         #endif
       
   852         }
       
   853     return value;
       
   854     }
       
   855 
       
   856 // ---------------------------------------------------------
       
   857 // CMsgConnManager::InitCommDbViewLC
       
   858 // 
       
   859 // ---------------------------------------------------------
       
   860 //
       
   861 TInt CMsgConnManager::InitCommDbViewLC( TPtrC& aDbRecord,
       
   862                                         CCommsDbTableView*& aView,
       
   863                                         const TSupportedCommDbRecords aParameter )
       
   864     {
       
   865     #ifdef _DEBUG
       
   866         WriteToLog( _L8( "  CMsgConnManager::InitCommDbViewLC" ) );
       
   867     #endif
       
   868     aView = iCommsDatabase->OpenViewMatchingUintLC
       
   869                             ( TPtrC( IAP ), TPtrC( COMMDB_ID ), iAccessPointID );
       
   870     TInt error = aView->GotoFirstRecord();
       
   871     if( error == KErrNone )
       
   872         {
       
   873         error = DetermineRecordTypeLC( aDbRecord, aView, aParameter );
       
   874         #ifdef _DEBUG
       
   875             if( error != KErrNone )
       
   876                 WriteToLog( _L8( "    DetermineRecordType() failed - Error: %d" ), error );
       
   877         #endif
       
   878         }
       
   879     else
       
   880         {
       
   881         #ifdef _DEBUG
       
   882             WriteToLog( _L8( "    No matching view found - Error: %d" ), error );
       
   883         #endif
       
   884         CleanupStack::PopAndDestroy();  //aView
       
   885         aView = NULL;
       
   886         }
       
   887     return error;
       
   888     }
       
   889 
       
   890 // ---------------------------------------------------------
       
   891 // CMsgConnManager::DetermineRecordType
       
   892 // 
       
   893 // ---------------------------------------------------------
       
   894 //
       
   895 TInt CMsgConnManager::DetermineRecordTypeLC( TPtrC& aDbColumn,
       
   896                                              CCommsDbTableView*& aView,
       
   897                                              const TSupportedCommDbRecords aParameter )
       
   898     {
       
   899     #ifdef _DEBUG
       
   900         WriteToLog( _L8( "      CMsgConnManager::DetermineRecordType()" ) );
       
   901     #endif 
       
   902     TInt error = KErrNotFound;
       
   903     switch( aParameter )
       
   904         {
       
   905         case EMsgProxyAddress:
       
   906             #ifdef _DEBUG
       
   907                 WriteToLog( _L8( "      Type is EImpsProxyAddress" ) );
       
   908             #endif
       
   909             if( CheckProxyUsageLC( aView ) )
       
   910                 {
       
   911                 error = KErrNone;
       
   912                 aDbColumn.Set( TPtrC( PROXY_SERVER_NAME ) );
       
   913                 }
       
   914             break;
       
   915         case EMsgProxyPort:
       
   916             #ifdef _DEBUG
       
   917                 WriteToLog( _L8( "      Type is EImpsProxyPort" ) );
       
   918             #endif
       
   919             if( CheckProxyUsageLC( aView ) )
       
   920                 {
       
   921                 error = KErrNone;
       
   922                 aDbColumn.Set( TPtrC( PROXY_PORT_NUMBER ) );
       
   923                 }
       
   924             break;
       
   925         default:
       
   926             #ifdef _DEBUG
       
   927                 WriteToLog( _L8( "      Default case, problems..." ) );
       
   928             #endif
       
   929             error = KErrNotSupported;
       
   930             break;
       
   931         }
       
   932     return error;
       
   933     }
       
   934 
       
   935 // ---------------------------------------------------------
       
   936 // CMsgConnManager::CheckProxyUsageLC
       
   937 // 
       
   938 // ---------------------------------------------------------
       
   939 //
       
   940 TBool CMsgConnManager::CheckProxyUsageLC( CCommsDbTableView*& aView )
       
   941     {
       
   942     #ifdef _DEBUG
       
   943         WriteToLog( _L8( "CMsgConnManager::CheckProxyUsageL()" ) );
       
   944     #endif
       
   945     TBool useProxy = EFalse;
       
   946     TUint32 serviceIdNumber = 0;
       
   947     TBuf<KCommsDbSvrMaxFieldLength> serviceIdText;
       
   948     aView->ReadTextL( TPtrC( IAP_SERVICE_TYPE ), serviceIdText );
       
   949     aView->ReadUintL( TPtrC( IAP_SERVICE ), serviceIdNumber );
       
   950     CleanupStack::PopAndDestroy();  //aView
       
   951     aView = NULL;
       
   952     aView = iCommsDatabase->OpenViewOnProxyRecordLC( serviceIdNumber, serviceIdText );
       
   953     TInt error = aView->GotoFirstRecord();
       
   954     if( error == KErrNone )
       
   955         {
       
   956         aView->ReadBoolL( TPtrC( PROXY_USE_PROXY_SERVER ), useProxy );
       
   957         if( !useProxy )
       
   958             {
       
   959             CleanupStack::PopAndDestroy();  //aView
       
   960             aView = NULL;
       
   961             }
       
   962         }
       
   963     else
       
   964         {
       
   965         #ifdef _DEBUG
       
   966             WriteToLog( _L8( "  The AP does not use a proxy server." ) );
       
   967         #endif
       
   968         CleanupStack::PopAndDestroy();  //aView
       
   969         aView = NULL;
       
   970         }
       
   971     return useProxy;
       
   972     }
       
   973 
       
   974 // ---------------------------------------------------------
       
   975 // CMsgConnManager::IsValidApL
       
   976 // 
       
   977 // ---------------------------------------------------------
       
   978 //
       
   979 TBool CMsgConnManager::IsValidApL( TUint32 aUid )
       
   980     {
       
   981     #ifdef _DEBUG
       
   982         WriteToLog( _L8( "CMsgConnManager::IsValidApL()" ) );
       
   983     #endif
       
   984     CCommsDbTableView* table = iCommsDatabase->OpenViewMatchingUintLC( TPtrC( IAP ),
       
   985                                                                        TPtrC( COMMDB_ID ),
       
   986                                                                        aUid );
       
   987     TInt res = table->GotoFirstRecord();
       
   988     CleanupStack::PopAndDestroy(); // table
       
   989     return res == KErrNone;
       
   990     }
       
   991 
       
   992 // ---------------------------------------------------------
       
   993 // CMsgConnManager::DoCancel
       
   994 // 
       
   995 // ---------------------------------------------------------
       
   996 //
       
   997 void CMsgConnManager::DoCancel()
       
   998     {
       
   999     #ifdef _DEBUG
       
  1000         WriteToLog( _L8( "CMsgConnManager::DoCancel()" ) );
       
  1001     #endif
       
  1002     switch( iConnManStatus )
       
  1003         {
       
  1004         case EMsgConnManWaitingForStartComplete:
       
  1005             #ifdef _DEBUG
       
  1006                 WriteToLog( _L8( "  Status is EMsgConnManWaitingForStartComplete" ) );
       
  1007             #endif
       
  1008             iConnection.Close();
       
  1009             iConnectionTimer->Cancel();
       
  1010             break;
       
  1011         case EMsgConnManWaitingForNotifications:
       
  1012             #ifdef _DEBUG
       
  1013                 WriteToLog( _L8( "  Status is EMsgConnManWaitingForNotifications" ) );
       
  1014             #endif
       
  1015             iConnection.CancelProgressNotification();
       
  1016             iConnectionTimer->Cancel();
       
  1017             iConnection.Close();
       
  1018             break;
       
  1019         case EMsgConnManDisconnectingPrevious:
       
  1020             #ifdef _DEBUG
       
  1021                 WriteToLog( _L8( "  Status is EMsgConnManDisconnectingPrevious" ) );
       
  1022             #endif
       
  1023             iConnectionTimer->Cancel();
       
  1024             User::RequestComplete( iClientStatus, KErrCancel );
       
  1025              #ifdef _DEBUG
       
  1026                 WriteToLog( _L8( "    StopConnection() terminated, client's request completed." ) );
       
  1027             #endif
       
  1028             break;
       
  1029         case EMsgConnManObservingAccessPoint:
       
  1030         case EMsgConnManBearerSuspended:
       
  1031             {
       
  1032             #ifdef _DEBUG
       
  1033                 WriteToLog( _L8( "  Status is %d" ), iConnManStatus );
       
  1034             #endif
       
  1035             iConnection.CancelProgressNotification();
       
  1036             #ifdef __WINS__
       
  1037                 TRequestStatus* status = &iStatus;
       
  1038                 User::RequestComplete( status, KErrCancel );
       
  1039             #endif
       
  1040             }
       
  1041             break;
       
  1042         case EMsgConnManIdle:
       
  1043             #ifdef _DEBUG
       
  1044                 WriteToLog( _L8( "  Status is EMsgConnManIdle" ) );
       
  1045             #endif
       
  1046             break;
       
  1047         default:
       
  1048             #ifdef _DEBUG
       
  1049                 WriteToLog( _L8( "  Default case" ) );
       
  1050             #endif
       
  1051             break;
       
  1052         }
       
  1053     }
       
  1054 
       
  1055 // ----------------------------------------------------
       
  1056 // NewImpsConnManL
       
  1057 // Returns a ConnManager instance
       
  1058 // ----------------------------------------------------
       
  1059 //
       
  1060 EXPORT_C MMsgConnManager* NewMsgConnManagerL( const TInt aDefaultAccessPoint ) 
       
  1061     { 
       
  1062     return CMsgConnManager::NewL( aDefaultAccessPoint ); 
       
  1063     }
       
  1064 
       
  1065