codhandler/codeng/src/Connection.cpp
changeset 0 dd21522fd290
child 28 d39add9822e2
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2002 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: 
       
    15 *      Implementation of class CConnection.   
       
    16 *      
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 
       
    23 #include "Connection.h"
       
    24 #include "CodPanic.h"
       
    25 #include "CodUtil.h"
       
    26 #include "CodError.h"
       
    27 #include "CodLogger.h"
       
    28 #include <CommDbConnPref.h>
       
    29 #include <cdblen.h>
       
    30 #include <es_enum.h>
       
    31 
       
    32 // ================= MEMBER FUNCTIONS =======================
       
    33 
       
    34 // ---------------------------------------------------------
       
    35 // CConnection::NewL()
       
    36 // ---------------------------------------------------------
       
    37 //
       
    38 CConnection* CConnection::NewL()
       
    39     {
       
    40     CConnection* conn = new (ELeave) CConnection();
       
    41     CleanupStack::PushL( conn );
       
    42     conn->ConstructL();
       
    43     CleanupStack::Pop( conn );
       
    44     return conn;
       
    45     }
       
    46 
       
    47 // ---------------------------------------------------------
       
    48 // CConnection::~CConnection()
       
    49 // ---------------------------------------------------------
       
    50 //
       
    51 CConnection::~CConnection()
       
    52     {
       
    53     Cancel();
       
    54     DoClose();
       
    55     }
       
    56 
       
    57 // ---------------------------------------------------------
       
    58 // CConnection::ConnectL()
       
    59 // ---------------------------------------------------------
       
    60 //
       
    61 void CConnection::ConnectL( TUint32 aIap, TRequestStatus* aStatus )
       
    62     {
       
    63     CLOG(( EConn, 2, _L("-> CConnection::ConnectL iap(%d)"), aIap ));
       
    64     // Misuse asserts.
       
    65     __ASSERT_ALWAYS( aStatus, CodPanic( ECodInvalidArguments ) );
       
    66     // Internal asserts.
       
    67     __ASSERT_DEBUG( !iParentStatus, CodPanic( ECodInternal ) );
       
    68 
       
    69     iStatus = KErrCodCannotConnect;
       
    70     if ( iState == EConnected )
       
    71         {
       
    72         // Already connected; do nothing.
       
    73         CLOG(( EConn, 4, _L("  already connected") ));
       
    74         iStatus = KErrNone;
       
    75         }
       
    76     else if ( iState == EInit )
       
    77         {
       
    78         // Not connected. Create connection.
       
    79         CLOG(( EConn, 4, _L("  starting connection") ));
       
    80         // Make this part atomic by pushing closes on the stack.
       
    81         User::LeaveIfError( iSockServ.Connect() );
       
    82         CleanupClosePushL<RSocketServ>( iSockServ );
       
    83         User::LeaveIfError( iConn.Open( iSockServ ) );
       
    84         CleanupClosePushL<RConnection>( iConn );
       
    85         iConnPref.SetDirection( ECommDbConnectionDirectionOutgoing );
       
    86         if ( aIap )
       
    87             {
       
    88             // Use specified IAP.
       
    89             iConnPref.SetIapId( aIap );
       
    90             iConnPref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
       
    91             }
       
    92         else
       
    93             {
       
    94             // aIap == 0 -> user select.
       
    95             iConnPref.SetDialogPreference( ECommDbDialogPrefPrompt );
       
    96             }
       
    97         iConn.Start( iConnPref, iStatus );
       
    98         iState = EConnecting;
       
    99         SetActive();
       
   100         CleanupStack::Pop( 2 ); // closing iConn and iSockServ
       
   101         // End of atomic part.
       
   102         }
       
   103     else
       
   104         {
       
   105         // Not expecting this to be called in other states.
       
   106         CLOG(( EConn, 0, _L("CConnection::ConnectL: unexpected state (%d)"), \
       
   107                                                                     iState ));
       
   108         __ASSERT_ALWAYS( EFalse, CodPanic( ECodInternal ) );
       
   109         }
       
   110 
       
   111     iParentStatus = aStatus;
       
   112     *iParentStatus = KRequestPending;
       
   113 
       
   114     if ( !IsActive() )
       
   115         {
       
   116         // Unless we have an outstanding connect request (iConn.Start),
       
   117         // we are done.
       
   118         Done();
       
   119         }
       
   120 
       
   121     CLOG(( EConn, 2, _L("<- CConnection::ConnectL") ));
       
   122     }
       
   123 
       
   124 // ---------------------------------------------------------
       
   125 // CConnection::AttachL()
       
   126 // ---------------------------------------------------------
       
   127 //
       
   128 void CConnection::AttachL( TUint32 aIap )
       
   129     {
       
   130     CLOG(( EConn, 2, _L("-> CConnection::AttachL iap(%d)"), aIap ));
       
   131 
       
   132     iStatus = KErrCodCannotConnect;
       
   133     if ( iState == EConnected )
       
   134         {
       
   135         // Already connected; do nothing.
       
   136         CLOG(( EConn, 4, _L("  already connected") ));
       
   137         iStatus = KErrNone;
       
   138         }
       
   139     else if ( iState == EInit )
       
   140         {
       
   141         // Not connected. Create connection, or attach to existing.
       
   142         CLOG(( EConn, 4, _L("  not connected") ));
       
   143         if ( aIap )
       
   144             {
       
   145             // Make this part atomic by pushing closes on the stack.
       
   146             User::LeaveIfError( iSockServ.Connect() );
       
   147             CleanupClosePushL<RSocketServ>( iSockServ );
       
   148             User::LeaveIfError( iConn.Open( iSockServ ) );
       
   149             CleanupClosePushL<RConnection>( iConn );
       
   150             TConnectionInfoBuf connInfo;
       
   151             TUint count;
       
   152             User::LeaveIfError( iConn.EnumerateConnections( count ) );
       
   153             CLOG(( EConn, 4, _L("  %d existing connections"), count ));
       
   154             TUint i;
       
   155             for ( i = count; i; i-- )
       
   156                 {
       
   157                 // Note: GetConnectionInfo expects 1-based index.
       
   158                 User::LeaveIfError( iConn.GetConnectionInfo( i, connInfo ) );
       
   159                 CLOG(( EConn, 4, _L("  conn(%d) iap(%d)"), \
       
   160                                                 i, connInfo().iIapId ));
       
   161                 if ( connInfo().iIapId == aIap )
       
   162                     {
       
   163                     CLOG(( EConn, 4, _L("  attach"), i, count ));
       
   164                     User::LeaveIfError( iConn.Attach
       
   165                         ( connInfo, RConnection::EAttachTypeNormal ) );
       
   166                     iState = EConnected;
       
   167                     iStatus = KErrNone;
       
   168                     break;
       
   169                     }
       
   170                 }
       
   171             CleanupStack::Pop( 2 ); // closing iConn and iSockServ
       
   172             // End of atomic part.
       
   173             }
       
   174         if ( iState == EInit )
       
   175             {
       
   176             CLOG(( EConn, 4, _L("  ended unconnected") ));
       
   177             iConn.Close();
       
   178             iSockServ.Close();
       
   179             }
       
   180         }
       
   181     else
       
   182         {
       
   183         // Not expecting this to be called in other states.
       
   184         CLOG(( EConn, 0, _L("CConnection::AttachL: unexpected state (%d)"), \
       
   185                                                                     iState ));
       
   186         __ASSERT_ALWAYS( EFalse, CodPanic( ECodInternal ) );
       
   187         }
       
   188     User::LeaveIfError( iStatus.Int() );
       
   189 
       
   190     CLOG(( EConn, 2, _L("<- CConnection::AttachL") ));
       
   191     }
       
   192 
       
   193 // ---------------------------------------------------------
       
   194 // CConnection::Close()
       
   195 // ---------------------------------------------------------
       
   196 //
       
   197 void CConnection::Close()
       
   198     {
       
   199     CLOG(( EConn, 2, _L("-> CConnection::Close") ));
       
   200     Cancel();
       
   201     DoClose();
       
   202     CLOG(( EConn, 2, _L("<- CConnection::Close") ));
       
   203     }
       
   204 
       
   205 // ---------------------------------------------------------
       
   206 // CConnection::IsConnected()
       
   207 // ---------------------------------------------------------
       
   208 //
       
   209 TBool CConnection::IsConnected( TUint32& aIap )
       
   210     {
       
   211     TBool connected( EFalse );
       
   212     if( iState == EConnected )
       
   213         {
       
   214         TBuf<KCommsDbSvrMaxColumnNameLength * 2 + 1> iapId;
       
   215         _LIT( KFormatIapId, "%S\\%S" );
       
   216         TPtrC iap( IAP );
       
   217         TPtrC id( COMMDB_ID );
       
   218         iapId.Format( KFormatIapId, &iap, &id );
       
   219         TInt err = iConn.GetIntSetting( iapId, aIap );
       
   220         connected = err ? EFalse : ETrue;
       
   221         }
       
   222     return connected;
       
   223     }
       
   224 
       
   225 // ---------------------------------------------------------
       
   226 // CConnection::CConnection()
       
   227 // ---------------------------------------------------------
       
   228 //
       
   229 CConnection::CConnection()
       
   230 : CActive( CActive::EPriorityStandard ),
       
   231   iState( EInit )
       
   232     {
       
   233     CActiveScheduler::Add( this );
       
   234     }
       
   235 
       
   236 // ---------------------------------------------------------
       
   237 // CConnection::ConstructL()
       
   238 // ---------------------------------------------------------
       
   239 //
       
   240 void CConnection::ConstructL()
       
   241     {
       
   242     if ( !CodUtil::ApCountL() )
       
   243         {
       
   244         // It's futile to try making a connection without an AP, so leave if
       
   245         // we don't have any.
       
   246         User::Leave( KErrCodNoAccessPoint );
       
   247         }
       
   248     }
       
   249 
       
   250 // ---------------------------------------------------------
       
   251 // CConnection::DoCancel()
       
   252 // ---------------------------------------------------------
       
   253 //
       
   254 void CConnection::DoCancel()
       
   255     {
       
   256     CLOG(( EConn, 2, _L("-> CConnection::DoCancel") ));
       
   257     __ASSERT_DEBUG( iState == EConnecting, CodPanic( ECodInternal ) );
       
   258     // RConnection has no cancel method matching the async RConnection::Start.
       
   259     // The only way to cancel is to close the RConnection.
       
   260     // (Our request will complete with KErrCancel, as expected.)
       
   261     DoClose();
       
   262     Done();
       
   263     CLOG(( EConn, 2, _L("<- CConnection::DoCancel") ));
       
   264     }
       
   265 
       
   266 // ---------------------------------------------------------
       
   267 // CConnection::RunL()
       
   268 // ---------------------------------------------------------
       
   269 //
       
   270 void CConnection::RunL()
       
   271     {
       
   272     CLOG(( EConn, 2, _L("-> CConnection::RunL iStatus(%d)"), \
       
   273         iStatus.Int() ));
       
   274     __ASSERT_DEBUG( iState == EConnecting, CodPanic( ECodInternal ) );
       
   275     User::LeaveIfError( iStatus.Int() );    // Handle errors in RunError().
       
   276     iState = EConnected;
       
   277     Done();
       
   278     CLOG(( EConn, 2, _L("<- CConnection::RunL") ));
       
   279     }
       
   280 
       
   281 // ---------------------------------------------------------
       
   282 // CConnection::RunError()
       
   283 // ---------------------------------------------------------
       
   284 //
       
   285 TInt CConnection::RunError( TInt LOG_ONLY( aError ) )
       
   286     {
       
   287     CLOG(( EConn, 2, _L("-> CConnection::RunError aError(%d)"), aError ));
       
   288     __ASSERT_DEBUG( iState == EConnecting, CodPanic( ECodInternal ) );
       
   289     DoClose();
       
   290     Done();
       
   291     CLOG(( EConn, 2, _L("<- CConnection::RunError") ));
       
   292     return KErrNone;
       
   293     }
       
   294 
       
   295 // ---------------------------------------------------------
       
   296 // CConnection::DoClose()
       
   297 // ---------------------------------------------------------
       
   298 //
       
   299 void CConnection::DoClose()
       
   300     {
       
   301     CLOG(( EConn, 2, _L("CConnection::DoClose") ));
       
   302     iConn.Close();
       
   303     iSockServ.Close();
       
   304     iState = EInit;
       
   305     }
       
   306 
       
   307 // ---------------------------------------------------------
       
   308 // CConnection::Done()
       
   309 // ---------------------------------------------------------
       
   310 //
       
   311 void CConnection::Done()
       
   312     {
       
   313     CLOG(( EConn, 2, _L("CConnection::Done iStatus(%d)"), iStatus.Int() ));
       
   314     __ASSERT_DEBUG( iParentStatus, CodPanic( ECodInternal ) );
       
   315     User::RequestComplete( iParentStatus, iStatus.Int() );
       
   316     iParentStatus = NULL;
       
   317     }