adaptationlayer/dataport/dataport_csy/src/dpdte2tx.cpp
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
equal deleted inserted replaced
-1:000000000000 0:63b37f68c1ce
       
     1 /*
       
     2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of 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 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "dpdef.h"        // dataport definitions
       
    22 #include "dpdataport.h"   // dataport main and c32 interface
       
    23 #include "dpdte2tx.h"     // moves data from client to tx buffer
       
    24 #include "dpflowctrl.h"   // flow control handling
       
    25 #include "dpdataconfig.h" // configuration store
       
    26 #include "dpescdetect.h"  // escape sequence detection
       
    27 #include "dprx2dte.h"     // moves data from rx buffer to client
       
    28 #include "dplog.h"        // dataport logging
       
    29 #include "osttracedefinitions.h"
       
    30 #ifdef OST_TRACE_COMPILER_IN_USE
       
    31 #include "dpdte2txtraces.h"
       
    32 #endif
       
    33 
       
    34 // LOCAL FUNCTION PROTOTYPES
       
    35 // none
       
    36 
       
    37 // ==================== LOCAL FUNCTIONS ====================
       
    38 
       
    39 // ================= MEMBER FUNCTIONS =======================
       
    40 
       
    41 // ---------------------------------------------------------
       
    42 // CDpDte2Tx::CDpDte2Tx
       
    43 // C++ default constructor.
       
    44 // ---------------------------------------------------------
       
    45 CDpDte2Tx::CDpDte2Tx(
       
    46     CDpDataPort& aDataPort ) :
       
    47     CActive( KDpDte2TxPriority ),
       
    48     iDataPort( aDataPort ),
       
    49     iBufferTx( iDataPort.Tx() ),
       
    50     iFlowCtrl( iDataPort.FlowCtrl() ),
       
    51     iEscDetect( iDataPort.EscDetect() ),
       
    52     iDataConfig( iDataPort.DataConfig() ),
       
    53     iRx2Dte( iDataPort.Rx2Dte() ),
       
    54     iTx( 0, 0 ),
       
    55     iRequestActive( EFalse ),
       
    56     iRole( MDpDataClient::EDbDataClientWriter )
       
    57     {
       
    58     OstTrace0( TRACE_NORMAL, CDPDTE2TX_CDPDTE2TX, "CDpDte2Tx::CDpDte2Tx" );
       
    59     LOGM(" CDpDte2Tx::CDpDte2Tx");
       
    60     }
       
    61 
       
    62 // ---------------------------------------------------------
       
    63 // CDpDte2Tx::ConstructL
       
    64 // Symbian 2nd phase constructor.
       
    65 // ---------------------------------------------------------
       
    66 void CDpDte2Tx::ConstructL()
       
    67     {
       
    68     OstTrace0( TRACE_NORMAL, CDPDTE2TX_CONSTRUCTL, "CDpDte2Tx::ConstructL" );
       
    69     LOGM(" CDpDte2Tx::ConstructL");
       
    70 
       
    71     //  initialise inner observer object
       
    72     iDpDte2TxFcObserver.Init(this);
       
    73 
       
    74     // register to FlowCtrl as observer
       
    75     iFlowCtrl.Attach( iDpDte2TxFcObserver );
       
    76 
       
    77     // If registering fails => can't do nothing here => must leave
       
    78     User::LeaveIfError( iBufferTx.RegisterDataClient( *this ) );
       
    79 
       
    80     CActiveScheduler::Add( this );
       
    81     }
       
    82 
       
    83 // ---------------------------------------------------------
       
    84 // CDpDte2Tx::NewL
       
    85 // Static constructor.
       
    86 // ---------------------------------------------------------
       
    87 CDpDte2Tx* CDpDte2Tx::NewL(
       
    88     CDpDataPort& aDataPort )
       
    89     {
       
    90     OstTrace0( TRACE_NORMAL, CDPDTE2TX_NEWL, "CDpDte2Tx::NewL" );
       
    91     LOGM(" CDpDte2Tx::NewL");
       
    92 
       
    93     CDpDte2Tx* self = new ( ELeave ) CDpDte2Tx( aDataPort );
       
    94 
       
    95     CleanupStack::PushL( reinterpret_cast< CActive* > ( self ) );
       
    96     self->ConstructL();
       
    97     CleanupStack::Pop( self );
       
    98 
       
    99     return self;
       
   100     }
       
   101 
       
   102 // ---------------------------------------------------------
       
   103 // CDpDte2Tx::~CDpDte2Tx
       
   104 // Destructor
       
   105 // ---------------------------------------------------------
       
   106 CDpDte2Tx::~CDpDte2Tx()
       
   107     {
       
   108     OstTrace0( TRACE_NORMAL, DUP1_CDPDTE2TX_CDPDTE2TX, "CDpDte2Tx::~CDpDte2Tx" );
       
   109     LOGM(" CDpDte2Tx::~CDpDte2Tx");
       
   110 
       
   111     iPendingClientBuffer = 0;
       
   112 
       
   113     // unregister from FlowCtrl as observer
       
   114     iFlowCtrl.Detach( iDpDte2TxFcObserver );
       
   115     }
       
   116 
       
   117 // ---------------------------------------------------------
       
   118 // CDpDte2Tx::WriteTx
       
   119 // This method puts write pending and signals itself
       
   120 // (Dte2Tx).
       
   121 // ---------------------------------------------------------
       
   122 //
       
   123 TInt CDpDte2Tx::WriteTx(
       
   124     const TAny* aClientBuffer,
       
   125     const TInt aLength)
       
   126     {
       
   127     OstTrace0( TRACE_NORMAL, CDPDTE2TX_WRITETX, "CDpDte2Tx::WriteTx" );
       
   128     OstTrace1( TRACE_NORMAL, DUP1_CDPDTE2TX_WRITETX, "CDpDte2Tx:: Port: %u", iDataPort.PortUnit() );
       
   129 
       
   130     LOGM1("CDpDte2Tx::WriteTx - Port %d", iDataPort.PortUnit() );
       
   131 
       
   132     TInt ret( KErrNone );
       
   133 
       
   134     if ( iWritePending )
       
   135         {
       
   136         //double write
       
   137         ret = KErrWrite;
       
   138         }
       
   139     else if ( 0 > aLength  )
       
   140         {
       
   141         //underflow
       
   142         ret = KErrArgument;
       
   143         }
       
   144     else if ( 0 != aLength )
       
   145         {
       
   146         // store pointer of client buffer
       
   147         iPendingClientBuffer = ( TAny* ) aClientBuffer;
       
   148         iPendingLength = aLength;
       
   149 
       
   150         iWritePending = ETrue;
       
   151 
       
   152         if ( !IsActive() )
       
   153             {
       
   154             iRequestActive = ETrue;
       
   155             iStatus = KRequestPending;
       
   156             SetActive();
       
   157             }
       
   158         //no else
       
   159 
       
   160         iDataPort.SignalDte2Tx();
       
   161         ret = KErrNotReady;
       
   162         }
       
   163 
       
   164     return ret;
       
   165     }
       
   166 
       
   167 // ---------------------------------------------------------
       
   168 // CDpDte2Tx::RunL
       
   169 // This method handles write operation after signalling.
       
   170 // ---------------------------------------------------------
       
   171 //
       
   172 void CDpDte2Tx::RunL()
       
   173     {
       
   174     OstTrace0( TRACE_NORMAL, CDPDTE2TX_RUNL, "CDpDte2Tx::RunL" );
       
   175     OstTrace1( TRACE_NORMAL, DUP1_CDPDTE2TX_RUNL, "CDpDte2Tx::RunL %x", &iDataPort );
       
   176     OstTrace1( TRACE_NORMAL, DUP2_CDPDTE2TX_RUNL, "CDpDte2Tx:: Port: %u", iDataPort.PortUnit() );
       
   177 
       
   178     LOGM1("CDpDte2Tx::RunL %x", &iDataPort);
       
   179     LOGM1("CDpDte2Tx::RunL - Port %d", iDataPort.PortUnit() );
       
   180 
       
   181     if ( iWritePending && iStatus != KErrCancel )
       
   182         {
       
   183         // check linefail
       
   184         TCommRole role;
       
   185         iDataPort.GetRole( role );
       
   186         if ( iDataConfig.IsLineFail( role ) )
       
   187             {
       
   188             LOG(" ERROR, Dte2Tx::RunL, Dte write completed with LINE FAIL.");
       
   189             OstTrace0( TRACE_NORMAL, DUP3_CDPDTE2TX_RUNL, "ERROR, Dte2Tx::RunL, Dte write completed with LINE FAIL." );
       
   190 
       
   191             iDataPort.WriteCompleted( KErrCommsLineFail );
       
   192             iWritePending = EFalse;
       
   193             iPendingClientBuffer = 0;
       
   194             iPendingLength = 0;
       
   195             }
       
   196         else if ( iDataConfig.IsEchoDte() &&
       
   197             ( iPendingLength - iIPCReadOffset ) > iRx2Dte.EchoBytesFreeSpace() )
       
   198             {
       
   199             if ( !IsActive() )
       
   200                 {
       
   201                 iRequestActive = ETrue;
       
   202                 iStatus = KRequestPending;
       
   203                 SetActive();
       
   204                 }
       
   205             //no else
       
   206             }
       
   207         else
       
   208             {
       
   209             // first take minimum of three elements
       
   210             TInt clientLength( iPendingLength - iIPCReadOffset );
       
   211             TInt freeBytes( iBufferTx.FreeBytes() );
       
   212             TInt len( 0 );
       
   213 
       
   214             if ( clientLength >= iBufferTx.MaxReservationSize() )
       
   215                 {
       
   216                 len = iBufferTx.MaxReservationSize();
       
   217                 }
       
   218             else
       
   219                 {
       
   220                 len = clientLength;
       
   221                 }
       
   222 
       
   223             if ( freeBytes > 0 )
       
   224                 {
       
   225                 if (len >= freeBytes)
       
   226                     {
       
   227                     len = freeBytes;
       
   228                     }
       
   229                 //no else
       
   230                 }
       
   231             //no else
       
   232 
       
   233             TPtr8 nullPtr( 0, 0 );
       
   234             CDpDataElement& elem = iBufferTx.WriteElement();
       
   235 
       
   236             TInt ret( elem.Reserve( len, iTx, nullPtr ) );
       
   237 
       
   238             if ( ret != KErrNone)
       
   239                 {
       
   240                 if ( ret == KErrNotReady )
       
   241                     {
       
   242                     if ( !IsActive() )
       
   243                         {
       
   244                         iRequestActive = ETrue;
       
   245                         iStatus = KRequestPending;
       
   246                         SetActive();
       
   247                         }
       
   248                     //no else
       
   249                     }
       
   250                 else
       
   251                     {
       
   252                     LOG1(" ErrorDte2Tx Tx element reservation failure! Id: %d",
       
   253                         ret );
       
   254                     OstTrace1( TRACE_NORMAL, DUP4_CDPDTE2TX_RUNL, "CDpDte2Tx:: ErrorDte2Tx Tx element reservation failure! Id: %d", ret );
       
   255 
       
   256                     User::Leave( ret );
       
   257                     }
       
   258                 }
       
   259             else
       
   260                 {
       
   261                 // we suppose it's always either KErrNone or KErrNotReady ...
       
   262                 User::LeaveIfError( iDataPort.IPCRead(
       
   263                     iPendingClientBuffer, iTx, iIPCReadOffset ) );
       
   264 
       
   265                 if ( iDataConfig.IsEchoDte() && 0 < iTx.Length() )
       
   266                     {
       
   267                     // configured to echo tx bytes
       
   268                     iRx2Dte.EchoTx( iTx );
       
   269                     }
       
   270                 //no else
       
   271 
       
   272                 iEscDetect.Scan( iTx );
       
   273 
       
   274                 // WasReaderWaiting is used to check if the reader was waiting
       
   275                 // for more data until it is being able to read. Otherwise it
       
   276                 // should signal to reader (Tx2Pn) that it can then read
       
   277                 TBool WasReaderWaiting = iBufferTx.IsReaderWaiting();
       
   278 
       
   279                 User::LeaveIfError( elem.Release( iTx.Length() ) );
       
   280 
       
   281                 iIPCReadOffset += iTx.Length();
       
   282 
       
   283                 // If reader was waiting for more data and got the enough,
       
   284                 // DPElement from Release will notify Reader using ReleaseNotify().
       
   285                 // WasReaderWaiting checks if Reader was waiting, if it is not,
       
   286                 // it should signal the reader to read the buffer.
       
   287                 if ( !WasReaderWaiting )
       
   288                     {
       
   289                     iDataPort.SignalTx2Pn();
       
   290                     }
       
   291                 //no else
       
   292 
       
   293                 if ( iIPCReadOffset >= iPendingLength )
       
   294                     {
       
   295                     LOG(" Dte2Tx::RunL, Dte write completed.");
       
   296                     OstTrace0( TRACE_NORMAL, DUP5_CDPDTE2TX_RUNL, "CDpDte2Tx:: Dte write completed" );
       
   297 
       
   298                     iIPCReadOffset = 0;
       
   299                     iDataPort.WriteCompleted( KErrNone );
       
   300                     iWritePending = EFalse;
       
   301                     iPendingClientBuffer = 0;
       
   302                     iPendingLength = 0;
       
   303                     }
       
   304                 else
       
   305                     {
       
   306                     if ( !IsActive() )
       
   307                         {
       
   308                         iRequestActive = ETrue;
       
   309                         iStatus = KRequestPending;
       
   310                         SetActive();
       
   311                         }
       
   312                     //no else
       
   313                     iDataPort.SignalDte2Tx();
       
   314                     }
       
   315                 }
       
   316             }
       
   317         }
       
   318         //no else
       
   319     }
       
   320 
       
   321 // ---------------------------------------------------------
       
   322 // CDpDte2Tx::RunError
       
   323 // Leave in RunL() is handled here. Error code is returned,
       
   324 // when internal error has occured.
       
   325 // ---------------------------------------------------------
       
   326 //
       
   327 TInt CDpDte2Tx::RunError(
       
   328     TInt aError )
       
   329     {
       
   330     OstTrace0( TRACE_NORMAL, CDPDTE2TX_RUNERROR, "CDpDte2Tx::RunError" );
       
   331     OstTraceExt2( TRACE_NORMAL, DUP1_CDPDTE2TX_RUNERROR, "CDpDte2Tx:: Port: %u, error code: %d", iDataPort.PortUnit(), aError );
       
   332 
       
   333     LOGM2("CDpDte2Tx::RunError - Port %d, error code: %d",
       
   334         iDataPort.PortUnit(), aError );
       
   335 
       
   336     return aError;
       
   337     }
       
   338 
       
   339 // ---------------------------------------------------------
       
   340 // CDpDte2Tx::UpDate
       
   341 // We are observer of FlowCtrl. E.g. when flow control
       
   342 // status changes, we are called.
       
   343 // ---------------------------------------------------------
       
   344 //
       
   345 void CDpDte2Tx::UpDate(
       
   346     CDpSubject* /*aChangedSubject*/)
       
   347     {
       
   348     OstTrace0( TRACE_NORMAL, CDPDTE2TX_UPDATE, "CDpDte2Tx::UpDate" );
       
   349     LOGM(" CDpDte2Tx::UpDate");
       
   350 
       
   351     ReleaseNotify();
       
   352     }
       
   353 
       
   354 // ---------------------------------------------------------
       
   355 // CDpDte2Tx::DoCancel
       
   356 // This method cancels this active object by
       
   357 // RequestComplete(). This method must be called directly
       
   358 // (not through Cancel()), when RunL() should be completed
       
   359 // with KErrCancel.
       
   360 // ---------------------------------------------------------
       
   361 //
       
   362 void CDpDte2Tx::DoCancel()
       
   363     {
       
   364     OstTrace0( TRACE_NORMAL, CDPDTE2TX_DOCANCEL, "CDpDte2Tx::DoCancel" );
       
   365     LOGM(" CDpDte2Tx::DoCancel");
       
   366 
       
   367     if ( iRequestActive )
       
   368         {
       
   369         iRequestActive = EFalse;
       
   370         // do the required signaling
       
   371         TRequestStatus* s=&iStatus;
       
   372         User::RequestComplete( s, KErrCancel );
       
   373         }
       
   374     //no else
       
   375     }
       
   376 
       
   377 // ---------------------------------------------------------
       
   378 // CDpDte2Tx::ReleaseNotify
       
   379 // This method signals ourselves (Dte2Tx).
       
   380 // ---------------------------------------------------------
       
   381 //
       
   382 void CDpDte2Tx::ReleaseNotify()
       
   383     {
       
   384     OstTrace0( TRACE_NORMAL, CDPDTE2TX_RELEASENOTIFY, "CDpDte2Tx::ReleaseNotify" );
       
   385     LOGM(" CDpDte2Tx::ReleaseNotify");
       
   386 
       
   387     // signal ourselves
       
   388     if ( iRequestActive )
       
   389         {
       
   390         iRequestActive = EFalse;
       
   391         TRequestStatus* status = &iStatus;
       
   392 
       
   393         User::RequestComplete( status, KErrNone );
       
   394         }
       
   395     //no else
       
   396     }
       
   397 
       
   398 // ---------------------------------------------------------
       
   399 // This method notifies that buffer is flushed. Classes which have access
       
   400 // to buffers are derived from this class. Derived class could override
       
   401 // this method, otherwise this default method will be used.
       
   402 // release this cactive object
       
   403 // ---------------------------------------------------------
       
   404 //
       
   405 void CDpDte2Tx::FlushNotify()
       
   406     {
       
   407     OstTrace0( TRACE_NORMAL, CDPDTE2TX_FLUSHNOTIFY, "CDpDte2Tx::FlushNotify" );
       
   408     LOGM(" CDpDte2Tx::FlushNotify()");
       
   409 
       
   410     ReleaseNotify();
       
   411     }
       
   412 
       
   413 // ---------------------------------------------------------
       
   414 // CDpDte2Tx::Role
       
   415 // This method gets the role (reader/writer) of data client.
       
   416 // ---------------------------------------------------------
       
   417 //
       
   418 TUint8 CDpDte2Tx::Role()
       
   419     {
       
   420     OstTrace0( TRACE_NORMAL, CDPDTE2TX_ROLE, "CDpDte2Tx::Role" );
       
   421     return iRole;
       
   422     }
       
   423 
       
   424 // ---------------------------------------------------------
       
   425 // CDpDte2Tx::CancelWrite
       
   426 // This method is called by client via
       
   427 // CDpDataPort::WriteCancel(). Client want to cancel pending
       
   428 // write operation. C32 makes WriteCompleted to DTE -->
       
   429 // don't make it here at all.
       
   430 // Status : Proposal
       
   431 // ---------------------------------------------------------
       
   432 //
       
   433 void CDpDte2Tx::CancelWrite()
       
   434     {
       
   435     OstTrace0( TRACE_NORMAL, CDPDTE2TX_CANCELWRITE, "CDpDte2Tx::CancelWrite" );
       
   436     LOGM(" CDpDte2Tx::CancelWrite");
       
   437 
       
   438     if ( iWritePending )
       
   439         {
       
   440         iPendingClientBuffer = 0;
       
   441         iPendingLength = 0;
       
   442         iWritePending = EFalse;
       
   443         iIPCReadOffset = 0;
       
   444         iDataPort.SignalDte2Tx();
       
   445         }
       
   446     //no else
       
   447     }
       
   448 
       
   449 // ---------------------------------------------------------
       
   450 // CDpDte2Tx::CDpDte2TxObserver::Init
       
   451 // This method initializes Dte2Tx observer.
       
   452 // ---------------------------------------------------------
       
   453 //
       
   454 void CDpDte2Tx::CDpDte2TxObserver::Init(
       
   455     CDpDte2Tx* aDpDte2Tx )
       
   456     {
       
   457     iDpDte2Tx = aDpDte2Tx;
       
   458     }
       
   459 
       
   460 // ---------------------------------------------------------
       
   461 // CDpDte2Tx::CDpDte2TxObserver::UpDate
       
   462 // This method updates Dte2Tx.
       
   463 // ---------------------------------------------------------
       
   464 //
       
   465 void CDpDte2Tx::CDpDte2TxObserver::UpDate(
       
   466     CDpSubject* aChangedSubject )
       
   467     {
       
   468     LOG(" CDpDte2Tx::CDpDte2TxObserver::UpDate");
       
   469 
       
   470     if ( iDpDte2Tx )
       
   471         {
       
   472         iDpDte2Tx->UpDate( aChangedSubject );
       
   473         }
       
   474     //no else
       
   475     }
       
   476 
       
   477 // ================= OTHER EXPORTED FUNCTIONS ==============
       
   478 // none
       
   479 
       
   480 //  End of File