localconnectivityservice/dun/utils/src/DunSignalNotify.cpp
branchRCL_3
changeset 39 4096754ee773
parent 38 3dcb815346df
child 40 52a167391590
equal deleted inserted replaced
38:3dcb815346df 39:4096754ee773
     1 /*
       
     2 * Copyright (c) 2006-2010 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:  Monitors signal changes on network side and reports changes
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #ifdef PRJ_USE_NETWORK_STUBS
       
    20 #include <c32comm_stub.h>
       
    21 #else
       
    22 #include <d32comm.h>
       
    23 #endif
       
    24 #include "DunTransporter.h"
       
    25 #include "DunSignalNotify.h"
       
    26 #include "DunDebug.h"
       
    27 
       
    28 const TUint KDunSixLowestBitsMask = 0x3F;  // Symbian magic
       
    29 
       
    30 // ======== MEMBER FUNCTIONS ========
       
    31 
       
    32 // ---------------------------------------------------------------------------
       
    33 // Two-phased constructor.
       
    34 // ---------------------------------------------------------------------------
       
    35 //
       
    36 CDunSignalNotify* CDunSignalNotify::NewL( MDunTransporterUtilityAux* aUtility )
       
    37     {
       
    38     CDunSignalNotify* self = new (ELeave) CDunSignalNotify( aUtility );
       
    39     CleanupStack::PushL( self );
       
    40     self->ConstructL();
       
    41     CleanupStack::Pop( self );
       
    42     return self;
       
    43     }
       
    44 
       
    45 // ---------------------------------------------------------------------------
       
    46 // Destructor
       
    47 // ---------------------------------------------------------------------------
       
    48 //
       
    49 CDunSignalNotify::~CDunSignalNotify()
       
    50     {
       
    51     FTRACE(FPrint( _L("CDunSignalNotify::~CDunSignalNotify()") ));
       
    52     ResetData();
       
    53     FTRACE(FPrint( _L("CDunSignalNotify::~CDunSignalNotify() complete") ));
       
    54     }
       
    55 
       
    56 // ---------------------------------------------------------------------------
       
    57 // Resets data to initial values
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 void CDunSignalNotify::ResetData()
       
    61     {
       
    62     FTRACE(FPrint( _L("CDunSignalNotify::ResetData()") ));
       
    63     // APIs affecting this:
       
    64     // IssueRequest()
       
    65     Stop();
       
    66     // AddCallback()
       
    67     iCallbacks.Close();
       
    68     // Internal
       
    69     Initialize();
       
    70     FTRACE(FPrint( _L("CDunSignalNotify::ResetData() complete") ));
       
    71     }
       
    72 
       
    73 // ---------------------------------------------------------------------------
       
    74 // Adds callback for line status change controlling
       
    75 // The callback will be called when line status change is detected in
       
    76 // endpoint
       
    77 // ---------------------------------------------------------------------------
       
    78 //
       
    79 TInt CDunSignalNotify::AddCallback( MDunConnMon* aCallback )
       
    80     {
       
    81     FTRACE(FPrint( _L("CDunSignalNotify::AddCallback()" ) ));
       
    82     if ( !aCallback )
       
    83         {
       
    84         FTRACE(FPrint( _L("CDunSignalNotify::AddCallback() (ERROR) complete" ) ));
       
    85         return KErrGeneral;
       
    86         }
       
    87     TInt retTemp = iCallbacks.Find( aCallback );
       
    88     if ( retTemp != KErrNotFound )
       
    89         {
       
    90         FTRACE(FPrint( _L("CDunSignalNotify::AddCallback() (already exists) complete" ) ));
       
    91         return KErrAlreadyExists;
       
    92         }
       
    93     retTemp = iCallbacks.Append( aCallback );
       
    94     if ( retTemp != KErrNone )
       
    95         {
       
    96         FTRACE(FPrint( _L("CDunSignalNotify::AddCallback() (append failed!) complete" ) ));
       
    97         return retTemp;
       
    98         }
       
    99     FTRACE(FPrint( _L("CDunSignalNotify::AddCallback() complete" ) ));
       
   100     return KErrNone;
       
   101     }
       
   102 
       
   103 // ---------------------------------------------------------------------------
       
   104 // Sets media to use for this endpoint monitor
       
   105 // ---------------------------------------------------------------------------
       
   106 //
       
   107 TInt CDunSignalNotify::SetMedia( RComm* aComm )
       
   108     {
       
   109     FTRACE(FPrint( _L("CDunSignalNotify::SetMedia()" )));
       
   110     if ( !aComm )
       
   111         {
       
   112         FTRACE(FPrint( _L("CDunSignalNotify::SetMedia() (aComm) not initialized!" )));
       
   113         return KErrGeneral;
       
   114         }
       
   115     // As it's not possible to listen for RFCOMM signal changes the RTS and DTR
       
   116     // signals should be anyway set high to Dataport
       
   117     aComm->SetSignals( KSignalRTS|KSignalDTR, 0 );
       
   118     // Next check if signal change notification from Dataport supported
       
   119     TCommCaps2 caps;
       
   120     aComm->Caps( caps );
       
   121     if ( !(caps().iNotificationCaps & KNotifySignalsChangeSupported) )
       
   122         {
       
   123         FTRACE(FPrint( _L("CDunSignalNotify::SetMedia() (RComm) (not supported) complete" )));
       
   124         return KErrNotSupported;
       
   125         }
       
   126     iListenSignals = KSignalDTEInputs;
       
   127     iNetwork = aComm;
       
   128     FTRACE(FPrint( _L("CDunSignalNotify::SetMedia() (RComm) complete" )));
       
   129     return KErrNone;
       
   130     }
       
   131 
       
   132 // ---------------------------------------------------------------------------
       
   133 // Issues request to start monitoring the endpoint for line status change
       
   134 // ---------------------------------------------------------------------------
       
   135 //
       
   136 TInt CDunSignalNotify::IssueRequest()
       
   137     {
       
   138     FTRACE(FPrint( _L("CDunSignalNotify::IssueRequest()" )));
       
   139     if ( iSignalNotifyState != EDunStateIdle )
       
   140         {
       
   141         FTRACE(FPrint( _L("CDunSignalNotify::IssueRequest() (not ready) complete" )));
       
   142         return KErrNotReady;
       
   143         }
       
   144     if ( !iNetwork )
       
   145         {
       
   146         FTRACE(FPrint( _L("CDunSignalNotify::IssueRequest() (iNetwork) not initialized!" ) ));
       
   147         return KErrGeneral;
       
   148         }
       
   149     TUint currentSignals = iNetwork->Signals( iListenSignals );
       
   150     TUint oldSignalsLow = iSignals & KDunSixLowestBitsMask;
       
   151     TUint newSignalsLow = currentSignals & KDunSixLowestBitsMask;
       
   152     TUint oldSignalsHigh = oldSignalsLow * KSignalChanged;
       
   153     TUint newSignalsHigh = newSignalsLow * KSignalChanged;
       
   154     FTRACE(FPrint( _L("CDunSignalNotify::IssueRequest() oldSignalsLow=0x%08X" ), oldSignalsLow ));
       
   155     FTRACE(FPrint( _L("CDunSignalNotify::IssueRequest() newSignalsLow=0x%08X" ), newSignalsLow ));
       
   156     FTRACE(FPrint( _L("CDunSignalNotify::IssueRequest() oldSignalsHigh=0x%08X" ), oldSignalsHigh ));
       
   157     FTRACE(FPrint( _L("CDunSignalNotify::IssueRequest() newSignalsHigh=0x%08X" ), newSignalsHigh ));
       
   158     if ( newSignalsLow != oldSignalsLow )
       
   159         {
       
   160         FTRACE(FPrint( _L("CDunSignalNotify::IssueRequest() signals already set..." ) ));
       
   161         iSignals = newSignalsLow | (oldSignalsHigh ^ newSignalsHigh);
       
   162         ManageSignalChange();
       
   163         }
       
   164     else
       
   165         {
       
   166         FTRACE(FPrint( _L("CDunSignalNotify::IssueRequest() start waiting for change..." ) ));
       
   167         iStatus = KRequestPending;
       
   168         iNetwork->NotifySignalChange( iStatus, iSignals, iListenSignals );
       
   169         SetActive();
       
   170         iSignalNotifyState = EDunStateSignalNotify;
       
   171         }
       
   172     FTRACE(FPrint( _L("CDunSignalNotify::IssueRequest() complete" )));
       
   173     return KErrNone;
       
   174     }
       
   175 
       
   176 // ---------------------------------------------------------------------------
       
   177 // Stops monitoring the endpoint for line status change
       
   178 // ---------------------------------------------------------------------------
       
   179 //
       
   180 TInt CDunSignalNotify::Stop()
       
   181     {
       
   182     FTRACE(FPrint( _L("CDunSignalNotify::Stop()" )));
       
   183     if ( iSignalNotifyState != EDunStateSignalNotify )
       
   184         {
       
   185         FTRACE(FPrint( _L("CDunSignalNotify::Stop() (not ready) complete" )));
       
   186         return KErrNotReady;
       
   187         }
       
   188     if ( !iNetwork )
       
   189         {
       
   190         FTRACE(FPrint( _L("CDunSignalNotify::Stop() (iNetwork) not initialized!" )));
       
   191         return KErrGeneral;
       
   192         }
       
   193     iNetwork->NotifySignalChangeCancel();
       
   194     Cancel();
       
   195     iSignalNotifyState = EDunStateIdle;
       
   196     FTRACE(FPrint( _L("CDunSignalNotify::Stop() complete" )));
       
   197     return KErrNone;
       
   198     }
       
   199 
       
   200 // ---------------------------------------------------------------------------
       
   201 // CDunSignalNotify::CDunSignalNotify
       
   202 // ---------------------------------------------------------------------------
       
   203 //
       
   204 CDunSignalNotify::CDunSignalNotify( MDunTransporterUtilityAux* aUtility ) :
       
   205     CActive( EPriorityHigh ),
       
   206     iUtility( aUtility )
       
   207     {
       
   208     Initialize();
       
   209     }
       
   210 
       
   211 // ---------------------------------------------------------------------------
       
   212 // CDunSignalNotify::ConstructL
       
   213 // ---------------------------------------------------------------------------
       
   214 //
       
   215 void CDunSignalNotify::ConstructL()
       
   216     {
       
   217     FTRACE(FPrint( _L("CDunSignalNotify::ConstructL()" ) ));
       
   218     if ( !iUtility )
       
   219         {
       
   220         User::Leave( KErrGeneral );
       
   221         }
       
   222     CActiveScheduler::Add( this );
       
   223     FTRACE(FPrint( _L("CDunSignalNotify::ConstructL() complete" ) ));
       
   224     }
       
   225 
       
   226 // ---------------------------------------------------------------------------
       
   227 // Initializes this class
       
   228 // ---------------------------------------------------------------------------
       
   229 //
       
   230 void CDunSignalNotify::Initialize()
       
   231     {
       
   232     FTRACE(FPrint( _L("CDunSignalNotify::Initialize()" ) ));
       
   233     // Don't initialize iUtility here (it is set through NewL)
       
   234     iSignalNotifyState = EDunStateIdle;
       
   235     iListenSignals = 0;
       
   236     iSignals = 0;
       
   237     iNetwork = NULL;
       
   238     FTRACE(FPrint( _L("CDunSignalNotify::Initialize() complete" ) ));
       
   239     }
       
   240 
       
   241 // ---------------------------------------------------------------------------
       
   242 // Manages signal changes
       
   243 // ---------------------------------------------------------------------------
       
   244 //
       
   245 void CDunSignalNotify::ManageSignalChange()
       
   246     {
       
   247     FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange()" ) ));
       
   248     // The following signals are input signals from network side:
       
   249     // KSignalDTEInputs = KSignalCTS | KSignalDSR | KSignalDCD | KSignalRNG
       
   250     if ( iSignals & KCTSChanged )
       
   251         {
       
   252         FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() checking CTS..." ) ));
       
   253         if ( iSignals & KSignalCTS )  // CTS changed to high
       
   254             {
       
   255             ReportSignalChange( KSignalCTS, 0 );
       
   256             FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() CTS changed high" ) ));
       
   257             }
       
   258         else  // CTS changed to low
       
   259             {
       
   260             ReportSignalChange( 0, KSignalCTS );
       
   261             FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() CTS changed low" ) ));
       
   262             }
       
   263         }
       
   264     if ( iSignals & KDSRChanged )
       
   265         {
       
   266         FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() checking DSR..." ) ));
       
   267         if ( iSignals & KSignalDSR )  // DSR changed to high
       
   268             {
       
   269             ReportSignalChange( KSignalDSR, 0 );
       
   270             FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() DSR changed high" ) ));
       
   271             }
       
   272         else  // DSR changed to low
       
   273             {
       
   274             ReportSignalChange( 0, KSignalDSR );
       
   275             FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() DSR changed low" ) ));
       
   276             }
       
   277         }
       
   278     if ( iSignals & KDCDChanged )
       
   279         {
       
   280         FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() checking DCD..." ) ));
       
   281         if ( iSignals & KSignalDCD )  // DCD changed to high
       
   282             {
       
   283             ReportSignalChange( KSignalDCD, 0 );
       
   284             FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() DCD changed high" ) ));
       
   285             }
       
   286         else  // DCD changed to low
       
   287             {
       
   288             ReportSignalChange( 0, KSignalDCD );
       
   289             FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() DCD changed low" ) ));
       
   290             }
       
   291         }
       
   292     if ( iSignals & KRNGChanged )
       
   293         {
       
   294         FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() checking RNG..." ) ));
       
   295         if ( iSignals & KSignalRNG )  // RNG changed to high
       
   296             {
       
   297             ReportSignalChange( KSignalRNG, 0 );
       
   298             FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() RNG changed high" ) ));
       
   299             }
       
   300         else  // RNG changed to low
       
   301             {
       
   302             ReportSignalChange( 0, KSignalRNG );
       
   303             FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() RNG changed low" ) ));
       
   304             }
       
   305         }
       
   306     IssueRequest();
       
   307     FTRACE(FPrint( _L("CDunSignalNotify::ManageSignalChange() complete" ) ));
       
   308     }
       
   309 
       
   310 // ---------------------------------------------------------------------------
       
   311 // Reports signal change
       
   312 // ---------------------------------------------------------------------------
       
   313 //
       
   314 void CDunSignalNotify::ReportSignalChange( TUint aSetMask, TUint aClearMask )
       
   315     {
       
   316     FTRACE(FPrint( _L("CDunSignalNotify::ReportSignalChange()" ) ));
       
   317 
       
   318     TUint signalType = aClearMask;
       
   319     TUint signalHigh = EFalse;
       
   320     if ( aSetMask != 0 )
       
   321         {
       
   322         signalType = aSetMask;
       
   323         signalHigh = ETrue;
       
   324         }
       
   325     TInt i;
       
   326     TInt count = iCallbacks.Count();
       
   327     TDunConnectionReason connReason;
       
   328     TConnId localId = iUtility->GetLocalId( iNetwork );
       
   329     connReason.iReasonType = EDunReasonTypeSignal;
       
   330     connReason.iContext = EDunMediaContextNetwork;
       
   331     connReason.iSignalType = signalType;
       
   332     connReason.iSignalHigh = signalHigh;
       
   333     connReason.iDirection = EDunDirectionUndefined;
       
   334     connReason.iErrorCode = KErrNone;
       
   335     for ( i=0; i<count; i++ )
       
   336         {
       
   337         TRAP_IGNORE(
       
   338             iCallbacks[i]->NotifyProgressChangeL( localId, connReason ) );
       
   339         }
       
   340 
       
   341     FTRACE(FPrint( _L("CDunSignalNotify::ReportSignalChange() complete" ) ));
       
   342     }
       
   343 
       
   344 // ---------------------------------------------------------------------------
       
   345 // From class CActive.
       
   346 // Gets called when line status changes
       
   347 // ---------------------------------------------------------------------------
       
   348 //
       
   349 void CDunSignalNotify::RunL()
       
   350     {
       
   351     FTRACE(FPrint( _L("CDunSignalNotify::RunL()" ) ));
       
   352     iSignalNotifyState = EDunStateIdle;
       
   353     TInt retTemp = iStatus.Int();
       
   354     if ( retTemp != KErrNone )
       
   355         {
       
   356         TInt i;
       
   357         TInt count = iCallbacks.Count();
       
   358         TDunConnectionReason connReason;
       
   359         TConnId localId = iUtility->GetLocalId( iNetwork );
       
   360         connReason.iReasonType = EDunReasonTypeRunL;
       
   361         connReason.iContext = EDunMediaContextNetwork;
       
   362         connReason.iSignalType = 0;
       
   363         connReason.iSignalHigh = EFalse;
       
   364         connReason.iDirection = EDunDirectionUndefined;
       
   365         connReason.iErrorCode = retTemp;
       
   366         for ( i=0; i<count; i++ )
       
   367             {
       
   368             TRAP_IGNORE(
       
   369                 iCallbacks[i]->NotifyProgressChangeL( localId, connReason ) );
       
   370             }
       
   371         return;
       
   372         }
       
   373     FTRACE(FPrint( _L("CDunSignalNotify::RunL() managing signal 0x%08X" ), iSignals ));
       
   374     ManageSignalChange();
       
   375     FTRACE(FPrint( _L("CDunSignalNotify::RunL() complete" ) ));
       
   376     }
       
   377 
       
   378 // ---------------------------------------------------------------------------
       
   379 // From class CActive.
       
   380 // Gets called on cancel
       
   381 // ---------------------------------------------------------------------------
       
   382 //
       
   383 void CDunSignalNotify::DoCancel()
       
   384     {
       
   385     }