adaptationlayer/dataport/dataport_csy/src/dprx2dte.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 "dprx2dte.h"     // moves data from rx buffer to client
       
    24 #include "dpbreak.h"      // break handling
       
    25 #include "dpflowctrl.h"   // flow control handling
       
    26 #include "dpdataconfig.h" // configuration store
       
    27 #include "dptermdetect.h" // terminator detection
       
    28 #include "dplog.h"        // dataport logging
       
    29 #include "osttracedefinitions.h"
       
    30 #ifdef OST_TRACE_COMPILER_IN_USE
       
    31 #include "dprx2dtetraces.h"
       
    32 #endif
       
    33 
       
    34 // EXTERNAL DATA STRUCTURES
       
    35 // none
       
    36 
       
    37 // EXTERNAL FUNCTION PROTOTYPES
       
    38 // none
       
    39 
       
    40 // CONSTANTS
       
    41 // none
       
    42 
       
    43 // MACROS
       
    44 // none
       
    45 
       
    46 // LOCAL CONSTANTS AND MACROS
       
    47 // none
       
    48 
       
    49 // MODULE DATA STRUCTURES
       
    50 // none
       
    51 
       
    52 // LOCAL FUNCTION PROTOTYPES
       
    53 // none
       
    54 
       
    55 // FORWARD DECLARATIONS
       
    56 // none
       
    57 
       
    58 // ============================= LOCAL FUNCTIONS ===============================
       
    59 // none
       
    60 
       
    61 // ============================ MEMBER FUNCTIONS ===============================
       
    62 
       
    63 // -----------------------------------------------------------------------------
       
    64 // CDpRx2Dte::CDpRx2Dte
       
    65 // C++ default constructor can NOT contain any code, that
       
    66 // might leave.
       
    67 // -----------------------------------------------------------------------------
       
    68 //
       
    69 CDpRx2Dte::CDpRx2Dte (
       
    70     CDpDataPort& aDataPort ) :
       
    71     CActive( KDpRx2DtePriority ),
       
    72     iDataPort( aDataPort ),
       
    73     iBufferRx( iDataPort.Rx() ),
       
    74     iFlowCtrl( iDataPort.FlowCtrl() ),
       
    75     iDataConfig( iDataPort.DataConfig() ),
       
    76     iBreak( iDataPort.BreakHandler() ),
       
    77     iTermDetect( iDataPort.TermDetect() ),
       
    78     iRx( 0, 0 ),
       
    79     iRxTail( 0, 0 ),
       
    80     iRole( MDpDataClient::EDbDataClientReader )
       
    81     {
       
    82     OstTrace0( TRACE_NORMAL, CDPRX2DTE_CDPRX2DTE, "CDpRx2Dte::CDpRx2Dte" );
       
    83     LOGM("CDpRx2Dte::CDpRx2Dte");
       
    84     }
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // CDpRx2Dte::ConstructL
       
    88 // Symbian 2nd phase constructor can leave.
       
    89 // -----------------------------------------------------------------------------
       
    90 //
       
    91 void CDpRx2Dte::ConstructL()
       
    92     {
       
    93     OstTrace0( TRACE_NORMAL, CDPRX2DTE_CONSTRUCTL, "CDpRx2Dte::ConstructL" );
       
    94     LOGM("CDpRx2Dte::ConstructL");
       
    95 
       
    96     // If registering fails => can't do nothing here => must leave
       
    97     User::LeaveIfError( iBufferRx.RegisterDataClient( *this ) );
       
    98 
       
    99     CActiveScheduler::Add( this );
       
   100 
       
   101     if ( !IsActive() )
       
   102         {
       
   103         iStatus = KRequestPending;
       
   104         iRequestActive = ETrue;
       
   105         SetActive();
       
   106         }
       
   107     //no else
       
   108     }
       
   109 
       
   110 // -----------------------------------------------------------------------------
       
   111 // CDpRx2Dte::NewL
       
   112 // Two-phased constructor.
       
   113 // -----------------------------------------------------------------------------
       
   114 //
       
   115 CDpRx2Dte* CDpRx2Dte::NewL(
       
   116     CDpDataPort& aDataPort )
       
   117     {
       
   118     OstTrace0( TRACE_NORMAL, CDPRX2DTE_NEWL, "CDpRx2Dte::NewL" );
       
   119     LOGM("CDpRx2Dte::NewL");
       
   120 
       
   121     CDpRx2Dte* self = new (ELeave) CDpRx2Dte( aDataPort );
       
   122 
       
   123     CleanupStack::PushL( self );
       
   124     self->ConstructL();
       
   125     CleanupStack::Pop( self );
       
   126 
       
   127     return self;
       
   128     }
       
   129 
       
   130 // -----------------------------------------------------------------------------
       
   131 // CDpRx2Dte::~CDpRx2Dte
       
   132 // Destructor
       
   133 // -----------------------------------------------------------------------------
       
   134 //
       
   135 CDpRx2Dte::~CDpRx2Dte()
       
   136     {
       
   137     OstTrace0( TRACE_NORMAL, DUP1_CDPRX2DTE_CDPRX2DTE, "CDpRx2Dte::~CDpRx2Dte" );
       
   138     LOGM("CDpRx2Dte::~CDpRx2Dte");
       
   139 
       
   140     iClientBuffer = 0;
       
   141     }
       
   142 
       
   143 // -----------------------------------------------------------------------------
       
   144 // CDpRx2Dte::RunL
       
   145 // We are signalled from Pn2Rx or from ourselves (Rx2Dte).
       
   146 // Always when we are signalled there is data available to be written
       
   147 // into client space. This method also checks if RX flow control
       
   148 // 'water mark low' is reached and informs flow control handler about that.
       
   149 // -----------------------------------------------------------------------------
       
   150 //
       
   151 void CDpRx2Dte::RunL()
       
   152     {
       
   153     OstTrace0( TRACE_NORMAL, CDPRX2DTE_RUNL, "CDpRx2Dte::RunL" );
       
   154     OstTrace1( TRACE_NORMAL, DUP1_CDPRX2DTE_RUNL, "CDpRx2Dte:: Port: %u", iDataPort.PortUnit() );
       
   155 
       
   156     LOGM1("CDpRx2Dte::RunL - Port %d", iDataPort.PortUnit() );
       
   157 
       
   158     if ( iStatus != KErrCancel )
       
   159         {
       
   160 #ifdef _DEBUG
       
   161         TInt ret( KErrNone );
       
   162 #endif
       
   163 
       
   164         if ( 0 < iEchoData.Length() && iReadPending )
       
   165             {
       
   166             // Writes echo bytes to the client
       
   167 #ifdef _DEBUG
       
   168             ret =
       
   169 #endif
       
   170             WriteEchoToClient();
       
   171             }
       
   172         else if ( iReadPending )
       
   173             {
       
   174 #ifdef _DEBUG
       
   175             ret =
       
   176 #endif
       
   177             WriteIntoClientSpace();
       
   178             }
       
   179         //no else
       
   180 
       
   181 #ifdef _DEBUG
       
   182         if ( ret != KErrNone )
       
   183             {
       
   184             LOG(" ERROR, CDpRx2Dte::RunL, Writing echo bytes to the client");
       
   185             OstTrace0( TRACE_NORMAL, DUP2_CDPRX2DTE_RUNL, "ERROR, CDpRx2Dte::RunL, Writing echo bytes to the client" );
       
   186             }
       
   187         //no else
       
   188 #endif
       
   189 
       
   190         if ( !IsActive() )
       
   191             {
       
   192             iStatus = KRequestPending;
       
   193             iRequestActive = ETrue;
       
   194             SetActive();
       
   195             }
       
   196         //no else
       
   197 
       
   198         if ( iReadPending &&
       
   199             ( 0 < iBufferRx.UsedBytes() || 0 < iEchoData.Length() ) )
       
   200             {
       
   201             iDataPort.SignalRx2Dte();
       
   202             }
       
   203         //no else
       
   204         }
       
   205     //no else
       
   206     }
       
   207 
       
   208 // -----------------------------------------------------------------------------
       
   209 // CDpRx2Dte::RunError
       
   210 // Leave in RunL() is handled here. RunL() should not leave.
       
   211 // -----------------------------------------------------------------------------
       
   212 //
       
   213 TInt CDpRx2Dte::RunError(
       
   214     TInt aError )
       
   215     {
       
   216     OstTrace0( TRACE_NORMAL, CDPRX2DTE_RUNERROR, "CDpRx2Dte::RunError" );
       
   217     OstTraceExt2( TRACE_NORMAL, DUP1_CDPRX2DTE_RUNERROR, "CDpRx2Dte:: Port: %u, error code: %d", iDataPort.PortUnit(), aError );
       
   218 
       
   219     LOGM2("CDpRx2Dte::RunError - Port %d, error code: %d",
       
   220         iDataPort.PortUnit(), aError );
       
   221 
       
   222     return aError;
       
   223     }
       
   224 
       
   225 // -----------------------------------------------------------------------------
       
   226 // CDpRx2Dte::DoCancel
       
   227 // This method cancels this active object
       
   228 // -----------------------------------------------------------------------------
       
   229 //
       
   230 void CDpRx2Dte::DoCancel()
       
   231     {
       
   232     OstTrace0( TRACE_NORMAL, CDPRX2DTE_DOCANCEL, "CDpRx2Dte::DoCancel" );
       
   233     LOGM("CDpRx2Dte::DoCancel");
       
   234 
       
   235     if ( iRequestActive )
       
   236         {
       
   237         // do the required signaling
       
   238         iRequestActive = EFalse;
       
   239         TRequestStatus* status = &iStatus;
       
   240         User::RequestComplete( status, KErrCancel );
       
   241         }
       
   242     //no else
       
   243     }
       
   244 
       
   245 // -----------------------------------------------------------------------------
       
   246 // CDpRx2Dte::SetDteRead
       
   247 // This is forwarded client StartRead().
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 TInt CDpRx2Dte::SetDteRead(
       
   251     const TAny* aDes,
       
   252     TInt aLength )
       
   253     {
       
   254     OstTrace0( TRACE_NORMAL, CDPRX2DTE_SETDTEREAD, "CDpRx2Dte::SetDteRead" );
       
   255     LOGM("CDpRx2Dte::SetDteRead");
       
   256 
       
   257     TInt ret( KErrNone );
       
   258 
       
   259     // no pending read
       
   260     if ( !iReadPending )
       
   261         {
       
   262         iReadPending = ETrue;
       
   263 
       
   264         // pointer into client buffer
       
   265         iClientBuffer = const_cast<TAny*>( aDes );
       
   266         iClientRequestedLength = aLength;
       
   267 
       
   268         if ( 0 > aLength )
       
   269             {
       
   270             // ReadOneOrMore
       
   271             // C32 gives client buffer size as negative value
       
   272             // see ECUART implementation
       
   273             iClientBufferLength = -aLength;
       
   274             }
       
   275         else
       
   276             {
       
   277             iClientBufferLength = aLength;
       
   278             }
       
   279 
       
   280         // if there is data ready signal ourselves
       
   281         if ( 0 < iBufferRx.UsedBytes() || 0 < iEchoData.Length() )
       
   282             {
       
   283             iDataPort.SignalRx2Dte();
       
   284             }
       
   285         //no else
       
   286         }
       
   287     else
       
   288         {
       
   289         // read twice attempted
       
   290         ret = KErrInUse;
       
   291         }
       
   292 
       
   293     return ret;
       
   294     }
       
   295 
       
   296 // -----------------------------------------------------------------------------
       
   297 // CDpRx2Dte::ResetDteRead
       
   298 // This is forwarded client made ReadCancel().
       
   299 // C32 makes ReadCompleted() to DTE --> don't make it here at all.
       
   300 // This is because DTE may have made timed read and when timer runs
       
   301 // out C32 wants to complete read by KErrTimedOut.
       
   302 // -----------------------------------------------------------------------------
       
   303 //
       
   304 TInt CDpRx2Dte::ResetDteRead()
       
   305     {
       
   306     OstTrace0( TRACE_NORMAL, CDPRX2DTE_RESETDTEREAD, "CDpRx2Dte::ResetDteRead" );
       
   307     OstTrace1( TRACE_NORMAL, DUP1_CDPRX2DTE_RESETDTEREAD, "CDpRx2Dte:: Port: %u", iDataPort.PortUnit() );
       
   308 
       
   309     LOGM1("CDpRx2Dte::ResetDteRead - Port %d", iDataPort.PortUnit() );
       
   310 
       
   311     // reset pointer pointing into client space & its length
       
   312     iReadPending = EFalse;
       
   313     iClientBuffer = 0;
       
   314     iClientBufferLength = 0;
       
   315     iClientRequestedLength = 0;
       
   316     iIPCWriteOffset = 0;
       
   317 
       
   318     return KErrNone;
       
   319     }
       
   320 
       
   321 // -----------------------------------------------------------------------------
       
   322 // CDpRx2Dte::Write
       
   323 // Reserve read element and IPCWrite data to client space.
       
   324 // -----------------------------------------------------------------------------
       
   325 //
       
   326 TInt CDpRx2Dte::Write()
       
   327     {
       
   328     OstTrace0( TRACE_NORMAL, CDPRX2DTE_WRITE, "CDpRx2Dte::Write" );
       
   329     OstTrace1( TRACE_NORMAL, DUP1_CDPRX2DTE_WRITE, "CDpRx2Dte:: Port: %u", iDataPort.PortUnit() );
       
   330 
       
   331     LOGM1("CDpRx2Dte::Write - Port %d", iDataPort.PortUnit() );
       
   332 
       
   333     TInt len( 0 );
       
   334     TInt maxLen( 0 );
       
   335     TInt ret( KErrNone );
       
   336 
       
   337     TCommRole role;
       
   338     iDataPort.GetRole( role );
       
   339 
       
   340     // verify read pending, else do nothing
       
   341     if ( !iReadPending )
       
   342         {
       
   343         ret = KErrNotReady;
       
   344         }
       
   345     // check line fail
       
   346     else if ( iDataConfig.IsLineFail( role ) )
       
   347         {
       
   348         iDataPort.ReadCompleted( KErrCommsLineFail );
       
   349         ResetDteRead();
       
   350         }
       
   351     else
       
   352         {
       
   353         // Find maximum length. i.e. which one is smaller our
       
   354         // maximum reservation size or client buffer to write
       
   355         // We can't write data over client buffer size -> smaller must be chocen
       
   356         maxLen = FindMaximumLength();
       
   357         // Lenght is count of bytes before break, but maximum maxLen or
       
   358         // lenght is as much as possible, but maximum maxLen
       
   359         len = FindLength( maxLen );
       
   360 
       
   361         LOG1("  CDpRx2Dte::Write, Rx element reservation - len: %d", len );
       
   362         OstTrace1( TRACE_NORMAL, DUP8_CDPRX2DTE_WRITE, "CDpRx2Dte:: Rx element reservation - len: %d", len );
       
   363 
       
   364         // try reserve read element, if return success descriptors are
       
   365         // set into buffer data
       
   366         ret = iBufferRx.ReadElement().Reserve( len, iRx, iRxTail, ETrue );
       
   367 
       
   368         switch ( ret )
       
   369             {
       
   370             case KErrNone:
       
   371                 {
       
   372 #ifdef _DEBUG
       
   373                 iTotalReceived = iTotalReceived + iRx.Length();
       
   374 
       
   375                 OstTrace1( TRACE_NORMAL, DUP2_CDPRX2DTE_WRITE, "CDpRx2Dte:: iBufferRx.UsedBytes = %d", iBufferRx.UsedBytes() );
       
   376                 OstTraceExt2( TRACE_NORMAL, DUP3_CDPRX2DTE_WRITE, "CDpRx2Dte:: len = %d, Total Received Bytes = %d", iRx.Length(), iTotalReceived );
       
   377                 OstTraceExt2( TRACE_NORMAL, DUP4_CDPRX2DTE_WRITE, "CDpRx2Dte:: Client buffer size = %d, DP Max. resv. size = %d", (iClientBufferLength - iIPCWriteOffset), iBufferRx.MaxReservationSize() );
       
   378                 OstTraceExt2( TRACE_NORMAL, DUP5_CDPRX2DTE_WRITE, "CDpRx2Dte:: Chosen maxLength = %d, Elem. reserved length = %d", maxLen, len );
       
   379                 OstTraceExt2( TRACE_NORMAL, DUP6_CDPRX2DTE_WRITE, "CDpRx2Dte:: iClientBufferLength = %d, iIPCWriteOffset = %d", iClientBufferLength, iIPCWriteOffset );
       
   380                 if( iRx.Length() > 0 )
       
   381                     {
       
   382                     OstTraceExt1( TRACE_NORMAL, DUP7_CDPRX2DTE_WRITE, "CDpRx2Dte:: RX = %s", iRx );
       
   383                     }
       
   384                 else
       
   385                     {
       
   386                     OstTrace0( TRACE_NORMAL, DUP12_CDPRX2DTE_WRITE, "CDpRx2Dte:: RX buffer empty" );
       
   387                     }
       
   388 
       
   389                 LOG1("  \tiBufferRx.UsedBytes() = %d", iBufferRx.UsedBytes() );
       
   390                 LOG2("  \tlen = %d, Total Received Bytes = %d",
       
   391                     iRx.Length(), iTotalReceived );
       
   392                 LOG2(" \tClient buffer size = %d, DP Max. resv. size = %d",
       
   393                     ( iClientBufferLength - iIPCWriteOffset ),
       
   394                     iBufferRx.MaxReservationSize() );
       
   395                 LOG2(" \tChocen maxLength = %d, Elem. reserved length = %d",
       
   396                     maxLen, len );
       
   397                 LOG2(" \tiClientBufferLength = %d, iIPCWriteOffset = %d",
       
   398                     iClientBufferLength, iIPCWriteOffset );
       
   399                 LOGHEX( iRx, EFalse );
       
   400 
       
   401 #endif
       
   402                 if ( iRxTail.Length() )
       
   403                     {
       
   404                     OstTrace1( TRACE_NORMAL, DUP9_CDPRX2DTE_WRITE, "CDpRx2Dte:: len tail = %d", iRxTail.Length() );
       
   405                     OstTraceExt1( TRACE_NORMAL, DUP10_CDPRX2DTE_WRITE, "CDpRx2Dte:: RXTail = %s", iRxTail );
       
   406 
       
   407                     LOG1("  \tlen tail = %d", iRxTail.Length() );
       
   408                     LOGHEX( iRxTail, EFalse );
       
   409                     }
       
   410                 //no else
       
   411 
       
   412                 // Write operation is handled here.
       
   413                 ret = MakeRx2DteWrite( len );
       
   414                 break;
       
   415                 }
       
   416             case KErrNotReady:
       
   417                 {
       
   418                 // we are set active in RunL
       
   419                 // OBS: returning KErrNone
       
   420                 ret = KErrNone;
       
   421                 break;
       
   422                 }
       
   423             default:
       
   424                 {
       
   425                 LOG1("  ERROR, CDpRx2Dte::Write Element reservation FAILED, error code: %d",
       
   426                     ret );
       
   427                 OstTrace1( TRACE_NORMAL, DUP11_CDPRX2DTE_WRITE, "ERROR, CDpRx2Dte::Write Element reservation FAILED, error code: %d", ret );
       
   428 
       
   429                 // returning error code. There's no need to leave because
       
   430                 // the error situation can be handeled.
       
   431                 }
       
   432             }
       
   433         }
       
   434 
       
   435     // if there is still data in buffer we are signalled from
       
   436     // 1. CDpRx2Dte::SetDteRead when client makes new read
       
   437     // 2. from end of RunL when buffer has data and read is pending
       
   438 
       
   439     return ret;
       
   440     }
       
   441 
       
   442 // -----------------------------------------------------------------------------
       
   443 // CDpRx2Dte::ReleaseNotify
       
   444 // This method signals ourselves (Rx2Dte).
       
   445 // -----------------------------------------------------------------------------
       
   446 //
       
   447 void CDpRx2Dte::ReleaseNotify()
       
   448     {
       
   449     OstTrace0( TRACE_NORMAL, CDPRX2DTE_RELEASENOTIFY, "CDpRx2Dte::ReleaseNotify" );
       
   450     LOG("CDpRx2Dte::ReleaseNotify");
       
   451 
       
   452     // signal ourselves
       
   453     if ( iRequestActive )
       
   454         {
       
   455         iRequestActive = EFalse;
       
   456         TRequestStatus* status = &iStatus;
       
   457         User::RequestComplete( status, KErrNone );
       
   458         }
       
   459     //no else
       
   460     }
       
   461 
       
   462 // -----------------------------------------------------------------------------
       
   463 // CDpRx2Dte::FlushNotify
       
   464 // This method notifies that buffer is flushed. Classes which have access
       
   465 // to buffers are derived from this class. Derived class could override
       
   466 // this method, otherwise this default method will be used.
       
   467 // -----------------------------------------------------------------------------
       
   468 //
       
   469 void CDpRx2Dte::FlushNotify()
       
   470     {
       
   471     OstTrace0( TRACE_NORMAL, CDPRX2DTE_FLUSHNOTIFY, "CDpRx2Dte::FlushNotify" );
       
   472     LOGM("CDpRx2Dte::FlushNotify()");
       
   473 
       
   474     ReleaseNotify();
       
   475     }
       
   476 
       
   477 // -----------------------------------------------------------------------------
       
   478 // CDpRx2Dte::Role
       
   479 // This method gets the role (reader/writer) of data client.
       
   480 // -----------------------------------------------------------------------------
       
   481 //
       
   482 TUint8 CDpRx2Dte::Role()
       
   483     {
       
   484     OstTrace0( TRACE_NORMAL, CDPRX2DTE_ROLE, "CDpRx2Dte::Role" );
       
   485     return iRole;
       
   486     }
       
   487 
       
   488 // -----------------------------------------------------------------------------
       
   489 // CDpRx2Dte::SetBreakBytes
       
   490 // Set break bytes to be send before break. If no breakbytes
       
   491 // we can complete break notify right here.
       
   492 // -----------------------------------------------------------------------------
       
   493 //
       
   494 void CDpRx2Dte::SetBreakBytes(
       
   495     const TInt aBreakBytes )
       
   496     {
       
   497     OstTrace0( TRACE_NORMAL, CDPRX2DTE_SETBREAKBYTES, "CDpRx2Dte::SetBreakBytes" );
       
   498     LOGM("CDpRx2Dte::SetBreakBytes");
       
   499 
       
   500     iBreakBytes = aBreakBytes;
       
   501 
       
   502     if ( iBreakBytes > 0 )
       
   503         {
       
   504         // there is some data before break
       
   505         iBreakPending = ETrue;
       
   506         }
       
   507     else
       
   508         {
       
   509         // data before break has sent
       
   510         iDataPort.BreakNotifyCompleted( KErrNone );
       
   511         iBreak.SetBreakNotify( EFalse );
       
   512         iBreakPending = EFalse;
       
   513         }
       
   514     }
       
   515 
       
   516 // -----------------------------------------------------------------------------
       
   517 // CDpRx2Dte::EchoTx
       
   518 // We are requested to write TX data back to client buffer.
       
   519 //  - Append echo data to small buffer.
       
   520 //  - Signal ourselves to data be written into client space
       
   521 // -----------------------------------------------------------------------------
       
   522 //
       
   523 void CDpRx2Dte::EchoTx(
       
   524     const TPtr8& aEchoData )
       
   525     {
       
   526     OstTrace0( TRACE_NORMAL, CDPRX2DTE_ECHOTX, "CDpRx2Dte::EchoTx" );
       
   527     LOGM("CDpRx2Dte::EchoTx");
       
   528 
       
   529     if ( EchoBytesFreeSpace() >= aEchoData.Length() )
       
   530         {
       
   531         iEchoData.Append( aEchoData );
       
   532         ReleaseNotify();
       
   533         }
       
   534     //no else
       
   535     }
       
   536 
       
   537 // -----------------------------------------------------------------------------
       
   538 // CDpRx2Dte::EchoBytes
       
   539 // This method gets count of echo bytes.
       
   540 // -----------------------------------------------------------------------------
       
   541 TInt CDpRx2Dte::EchoBytes()
       
   542     {
       
   543     OstTrace0( TRACE_NORMAL, CDPRX2DTE_ECHOBYTES, "CDpRx2Dte::EchoBytes" );
       
   544     LOGM("CDpRx2Dte::EchoBytes");
       
   545 
       
   546     return iEchoData.Length();
       
   547     }
       
   548 
       
   549 // -----------------------------------------------------------------------------
       
   550 // CDpRx2Dte::EchoBytesFreeSpace
       
   551 // This method gets echo buffer's free space.
       
   552 // -----------------------------------------------------------------------------
       
   553 //
       
   554 TInt CDpRx2Dte::EchoBytesFreeSpace()
       
   555     {
       
   556     OstTrace0( TRACE_NORMAL, CDPRX2DTE_ECHOBYTESFREESPACE, "CDpRx2Dte::EchoBytesFreeSpace" );
       
   557     LOGM("CDpRx2Dte::EchoBytesFreeSpace");
       
   558 
       
   559     TInt space( iEchoData.MaxLength() - iEchoData.Length() );
       
   560 
       
   561     if ( 0 > space )
       
   562         {
       
   563         space = 0;
       
   564         }
       
   565     //no else
       
   566 
       
   567     return space;
       
   568     }
       
   569 
       
   570 // -----------------------------------------------------------------------------
       
   571 // CDpRx2Dte::ResetEchoBytes
       
   572 // This method resets bytes from echo data.
       
   573 // -----------------------------------------------------------------------------
       
   574 //
       
   575 void CDpRx2Dte::ResetEchoBytes()
       
   576     {
       
   577     OstTrace0( TRACE_NORMAL, CDPRX2DTE_RESETECHOBYTES, "CDpRx2Dte::ResetEchoBytes" );
       
   578     LOGM("CDpRx2Dte::ResetEchoBytes");
       
   579 
       
   580     iEchoData.Zero();
       
   581     }
       
   582 
       
   583 // -----------------------------------------------------------------------------
       
   584 // CDpRx2Dte::WriteEchoToClient
       
   585 // Writes echo bytes back to client
       
   586 // -----------------------------------------------------------------------------
       
   587 //
       
   588 TInt CDpRx2Dte::WriteEchoToClient()
       
   589     {
       
   590     OstTrace0( TRACE_NORMAL, CDPRX2DTE_WRITEECHOTOCLIENT, "CDpRx2Dte::WriteEchoToClient" );
       
   591     OstTrace1( TRACE_NORMAL, DUP1_CDPRX2DTE_WRITEECHOTOCLIENT, "CDpRx2Dte:: Port: %u", iDataPort.PortUnit() );
       
   592 
       
   593     LOGM1("CDpRx2Dte::WriteEchoToClient - Port %d", iDataPort.PortUnit() );
       
   594 
       
   595     TInt ret( KErrNone );
       
   596     TInt spaceLeft( iClientBufferLength - iIPCWriteOffset );
       
   597 
       
   598     LOG1("  Rx2Dte::WriteEchoToClient, Client buffer length: %d",
       
   599         iClientBufferLength );
       
   600     OstTrace1( TRACE_NORMAL, DUP2_CDPRX2DTE_WRITEECHOTOCLIENT, "CDpRx2Dte:: Client buffer length: %d", iClientBufferLength );
       
   601 
       
   602     if ( iEchoData.Length() > spaceLeft )
       
   603         {
       
   604         // Avoid client buffer overflow when writing echo data
       
   605         // (e.g. at-commands)
       
   606         ret = iDataPort.IPCWrite(
       
   607             iClientBuffer, iEchoData.Left(spaceLeft), iIPCWriteOffset );
       
   608         // Move rest data to left
       
   609         iEchoData.Copy( iEchoData.Mid( spaceLeft ) );
       
   610         iIPCWriteOffset = iIPCWriteOffset + spaceLeft;
       
   611         }
       
   612     else
       
   613         {
       
   614         ret = iDataPort.IPCWrite( iClientBuffer, iEchoData, iIPCWriteOffset );
       
   615         iIPCWriteOffset = iIPCWriteOffset + iEchoData.Length();
       
   616         iEchoData.Zero();
       
   617         }
       
   618 
       
   619     if ( KErrNone != ret )
       
   620         {
       
   621         // Try to recover from write fail
       
   622         iEchoData.Zero();
       
   623 
       
   624         // Reset read
       
   625         iReadPending = EFalse;
       
   626         iStatus = KRequestPending;
       
   627 
       
   628         if ( !IsActive() )
       
   629             {
       
   630             iStatus = KRequestPending;
       
   631             iRequestActive = ETrue;
       
   632             SetActive();
       
   633             }
       
   634         //no else
       
   635 
       
   636         // Complete the read
       
   637         iDataPort.ReadCompleted( ret );
       
   638         ResetDteRead();
       
   639         }
       
   640     else
       
   641         {
       
   642         // We have space
       
   643         iDataPort.SignalDte2Tx();
       
   644 
       
   645         if ( ( 0 > iClientRequestedLength ) ||
       
   646             ( iIPCWriteOffset >= iClientRequestedLength ) ||
       
   647             ( iIPCWriteOffset >= iClientBufferLength ) )
       
   648             {
       
   649             // Complete the read in these situations:
       
   650             // 1. ReadOneOrMore (iClientRequestedLength is then negative)
       
   651             // 2. client requested length is full
       
   652             // 3. client buffer is full
       
   653             iDataPort.ReadCompleted( ret );
       
   654             ResetDteRead();
       
   655             }
       
   656         //no else
       
   657         }
       
   658 
       
   659     return ret;
       
   660     }
       
   661 
       
   662 // -----------------------------------------------------------------------------
       
   663 // CDpRx2Dte::WriteIntoClientSpace
       
   664 // Writes bytes into the client space
       
   665 // -----------------------------------------------------------------------------
       
   666 //
       
   667 TInt CDpRx2Dte::WriteIntoClientSpace()
       
   668     {
       
   669     OstTrace0( TRACE_NORMAL, CDPRX2DTE_WRITEINTOCLIENTSPACE, "CDpRx2Dte::WriteIntoClientSpace" );
       
   670     LOGM1("CDpRx2Dte::WriteIntoClientSpace - Port %d", iDataPort.PortUnit() );
       
   671 
       
   672     TInt ret( KErrNone );
       
   673 
       
   674     // Write into client space
       
   675     ret = Write();
       
   676     if ( ret != KErrNone )
       
   677         {
       
   678         // Try to recover from write fail
       
   679         iDataPort.ReadCompleted( ret );
       
   680         ResetDteRead();
       
   681 
       
   682         if ( !IsActive() )
       
   683             {
       
   684             iStatus = KRequestPending;
       
   685             iRequestActive = ETrue;
       
   686             SetActive();
       
   687             }
       
   688         //no else
       
   689         }
       
   690     else
       
   691         {
       
   692         // Is flowctrl on and rxBuffer "low watermark" reached
       
   693         if ( iFlowCtrl.FlowCtrlDcs2Dp() == EFlowControlOn )
       
   694             {
       
   695             if ( iBufferRx.UsedBytes() <= iDataConfig.WaterMarkLowSize( iBufferRx ) )
       
   696                 {
       
   697                 // OK, now we have again space in buffer
       
   698                 LOG("  CDpRx2Dte::WriteIntoClientSpace, Rx Low WaterMarkReached.");
       
   699                 OstTrace0( TRACE_NORMAL, DUP1_CDPRX2DTE_WRITEINTOCLIENTSPACE, "CDpRx2Dte:: Rx Low WaterMark reached" );
       
   700                 iFlowCtrl.WaterMarkLowReached();
       
   701                 }
       
   702             //no else
       
   703             }
       
   704         //no else
       
   705         }
       
   706 
       
   707     return ret;
       
   708     }
       
   709 
       
   710 // -----------------------------------------------------------------------------
       
   711 // CDpRx2Dte::FindMaximumLength
       
   712 // Find maximum length i.e. which one is smaller: our maximum
       
   713 // reservation size or client buffer where we write. We can't
       
   714 // write data over client buffer size -> smaller must be chocen.
       
   715 // -----------------------------------------------------------------------------
       
   716 //
       
   717 TInt CDpRx2Dte::FindMaximumLength()
       
   718     {
       
   719     OstTrace0( TRACE_NORMAL, CDPRX2DTE_FINDMAXIMUMLENGTH, "CDpRx2Dte::FindMaximumLength" );
       
   720     LOGM("CDpRx2Dte::FindMaximumLength");
       
   721 
       
   722     TInt len( 0 );
       
   723 
       
   724     if ( ( iClientBufferLength - iIPCWriteOffset ) >
       
   725             iBufferRx.UsedBytes() )
       
   726         {
       
   727         len = iBufferRx.UsedBytes();
       
   728         }
       
   729     else
       
   730         {
       
   731         len = iClientBufferLength - iIPCWriteOffset;
       
   732         }
       
   733 
       
   734     return len;
       
   735     }
       
   736 
       
   737 // -----------------------------------------------------------------------------
       
   738 // CDpRx2Dte::FindLength
       
   739 // This method returns amount of break bytes, if break is pending.
       
   740 // Amount of used bytes is returned, if break is not pending. If the
       
   741 // amount exceeds given length, the length is returned.
       
   742 // -----------------------------------------------------------------------------
       
   743 //
       
   744 TInt CDpRx2Dte::FindLength(
       
   745     const TInt aMaxLen )
       
   746     {
       
   747     OstTrace0( TRACE_NORMAL, CDPRX2DTE_FINDLENGTH, "CDpRx2Dte::FindLength" );
       
   748     LOGM("CDpRx2Dte::FindLength");
       
   749 
       
   750     TInt len( 0 );
       
   751 
       
   752     if ( iBreakPending )
       
   753         {
       
   754         // lenght is count of bytes before break, but maximum maxLen
       
   755         if ( iBreakBytes <= aMaxLen )
       
   756             {
       
   757             len = iBreakBytes;
       
   758             }
       
   759         else
       
   760             {
       
   761             len = aMaxLen;
       
   762             }
       
   763         }
       
   764     else
       
   765         {
       
   766         // lenght is as much as possible, but maximum maxLen
       
   767         if ( iBufferRx.UsedBytes() <= aMaxLen )
       
   768             {
       
   769             len = iBufferRx.UsedBytes();
       
   770             }
       
   771         else
       
   772             {
       
   773             len = aMaxLen;
       
   774             }
       
   775         }
       
   776 
       
   777     return len;
       
   778     }
       
   779 
       
   780 // -----------------------------------------------------------------------------
       
   781 // CDpRx2Dte::MakeRx2DteWrite
       
   782 // Makes the actual write operation.
       
   783 // -----------------------------------------------------------------------------
       
   784 //
       
   785 TInt CDpRx2Dte::MakeRx2DteWrite(
       
   786     const TInt aLen )
       
   787     {
       
   788     OstTrace0( TRACE_NORMAL, CDPRX2DTE_MAKERX2DTEWRITE, "CDpRx2Dte::MakeRx2DteWrite" );
       
   789     OstTraceExt2( TRACE_NORMAL, DUP1_CDPRX2DTE_MAKERX2DTEWRITE, "CDpRx2Dte::MakeRx2DteWrite %x, Port: %u", (TUint)&iDataPort, iDataPort.PortUnit() );
       
   790 
       
   791     LOGM2("CDpRx2Dte::MakeRx2DteWrite %x, Port %d",
       
   792         &iDataPort, iDataPort.PortUnit() );
       
   793 
       
   794     TInt ret( KErrNone );
       
   795     TInt ind( 0 );
       
   796     TInt termCount( iDataConfig.TerminatorCount() );
       
   797 
       
   798     // There is data in rx buffer
       
   799     if ( iRx.Length() )
       
   800         {
       
   801         // Scan terminator from iRx
       
   802         if ( 0 < termCount )
       
   803             {
       
   804             ind = iTermDetect.Scan( iRx );
       
   805             // terminator found
       
   806             if ( 0 <= ind )
       
   807                 {
       
   808                 iRx.SetLength( ind + 1 );
       
   809                 iRxTail.SetLength( 0 );
       
   810                 }
       
   811             //no else
       
   812             }
       
   813         //no else
       
   814 
       
   815         // IPC write into client space
       
   816         ret = iDataPort.IPCWrite( iClientBuffer, iRx, iIPCWriteOffset );
       
   817         iIPCWriteOffset = iIPCWriteOffset + iRx.Length();
       
   818 
       
   819         if ( KErrNone != ret )
       
   820             {
       
   821             LOG("  CDpRx2Dte::MakeRx2DteWrite, Rx element release (IPCWrite failed)");
       
   822             OstTrace0( TRACE_NORMAL, DUP2_CDPRX2DTE_MAKERX2DTEWRITE, "CDpRx2Dte:: Rx element release (IPCWrite failed)" );
       
   823 
       
   824             // Release element, because IPCWrite failed
       
   825             TInt err ( iBufferRx.ReadElement().Release( 0 ) );
       
   826 
       
   827             if ( KErrNone != err )
       
   828                 {
       
   829                 ret = err;
       
   830                 }
       
   831             //no else
       
   832 
       
   833             }
       
   834         //no else
       
   835         }
       
   836     //no else
       
   837 
       
   838     // Tail has a length, make the write in two pieces
       
   839     if ( KErrNone == ret && iRxTail.Length() )
       
   840         {
       
   841         ret = WriteTail( ind, termCount );
       
   842 
       
   843         iIPCWriteOffset = iIPCWriteOffset + iRxTail.Length();
       
   844 
       
   845         if ( KErrNone != ret )
       
   846             {
       
   847             LOG("  CDpRx2Dte::MakeRx2DteWrite, Rx element release (IPCWrite failed)");
       
   848             OstTrace0( TRACE_NORMAL, DUP3_CDPRX2DTE_MAKERX2DTEWRITE, "CDpRx2Dte:: Rx element release (IPCWrite failed)" );
       
   849 
       
   850             // Release element, because IPCWrite failed
       
   851             TInt err ( iBufferRx.ReadElement().Release( iRx.Length() ) );
       
   852 
       
   853             if ( KErrNone == err )
       
   854                 {
       
   855                 iReadPending = EFalse;
       
   856                 }
       
   857             else
       
   858                 {
       
   859                 ret = err;
       
   860                 }
       
   861             }
       
   862         //no else
       
   863         }
       
   864     //no else
       
   865 
       
   866     if ( KErrNone == ret )
       
   867         {
       
   868         if ( ( 0 > iClientRequestedLength ) ||
       
   869             ( 0 < termCount && 0 <= ind ) ||
       
   870             ( iIPCWriteOffset >= iClientRequestedLength ) ||
       
   871             ( iIPCWriteOffset >= iClientBufferLength ) )
       
   872             {
       
   873             // Complete the read in these situations:
       
   874             // 1. ReadOneOrMore (iClientRequestedLength is then negative)
       
   875             // 2. client uses terminated_read and terminator byte found
       
   876             // 3. client requested length is full
       
   877             // 4. client buffer is full
       
   878             //
       
   879             // (if terminator not found we don't complete read yet)
       
   880             iDataPort.ReadCompleted( ret );
       
   881             ResetDteRead();
       
   882             }
       
   883         //no else
       
   884 
       
   885         // Release read element
       
   886         OstTrace0( TRACE_NORMAL, DUP4_CDPRX2DTE_MAKERX2DTEWRITE, "CDpRx2Dte:: Rx element release" );
       
   887         OstTrace1( TRACE_NORMAL, DUP5_CDPRX2DTE_MAKERX2DTEWRITE, "CDpRx2Dte:: Rx element release - iRx: %d", iRx.Length() );
       
   888         OstTrace1( TRACE_NORMAL, DUP6_CDPRX2DTE_MAKERX2DTEWRITE, "CDpRx2Dte:: Rx element release - iRxTail: %d", iRxTail.Length() );
       
   889 
       
   890         LOG("  CDpRx2Dte::MakeRx2DteWrite, Rx element release");
       
   891         LOG1("  CDpRx2Dte::MakeRx2DteWrite, Rx element release - iRx: %d",
       
   892             iRx.Length() );
       
   893         LOG1("  CDpRx2Dte::MakeRx2DteWrite, Rx element release - iRxTail: %d",
       
   894             iRxTail.Length() );
       
   895 
       
   896         ret = iBufferRx.ReadElement().Release( iRx.Length() + iRxTail.Length() );
       
   897         if ( KErrNone == ret )
       
   898            {
       
   899             // Reset descriptors
       
   900             iRx.SetLength( 0 );
       
   901             iRxTail.SetLength( 0 );
       
   902 
       
   903             if ( iBreakPending )
       
   904                 {
       
   905                 iBreakBytes -= aLen;
       
   906                 if ( 0 == iBreakBytes )
       
   907                     {
       
   908                     iBreakPending = EFalse;
       
   909                     iDataPort.BreakNotifyCompleted( KErrNone );
       
   910                     iBreak.SetBreakNotify( EFalse );
       
   911                     }
       
   912                 //no else
       
   913                 }
       
   914             //no else
       
   915             }
       
   916         }
       
   917     //no else
       
   918 
       
   919     return ret;
       
   920     }
       
   921 
       
   922 // -----------------------------------------------------------------------------
       
   923 // CDpRx2Dte::WriteTail
       
   924 // Writes the tail.
       
   925 // -----------------------------------------------------------------------------
       
   926 //
       
   927 TInt CDpRx2Dte::WriteTail(
       
   928     TInt& aInd,
       
   929     const TInt aTermCount )
       
   930     {
       
   931     OstTrace0( TRACE_NORMAL, CDPRX2DTE_WRITETAIL, "CDpRx2Dte::WriteTail" );
       
   932     OstTrace1( TRACE_NORMAL, DUP1_CDPRX2DTE_WRITETAIL, "CDpRx2Dte:: Port: %u", iDataPort.PortUnit() );
       
   933     OstTrace0( TRACE_NORMAL, DUP2_CDPRX2DTE_WRITETAIL, "CDpRx2Dte:: -------------- Write Rx Tail --------------" );
       
   934 
       
   935     LOGM1("CDpRx2Dte::WriteTail - Port %d", iDataPort.PortUnit() );
       
   936     LOG("-------------- Write Rx Tail --------------");
       
   937 
       
   938     // scan terminator from iRxTail
       
   939     if ( 0 < aTermCount )
       
   940         {
       
   941         aInd = iTermDetect.Scan( iRxTail );
       
   942 
       
   943         // terminator found
       
   944         if ( 0 <= aInd )
       
   945             {
       
   946             iRxTail.SetLength( aInd + 1 );
       
   947             }
       
   948         //no else
       
   949         }
       
   950     //no else
       
   951 
       
   952     // we have to make two writes to client buffer. Second write starts
       
   953     // from where first one ends --> offset = iRx.Length().
       
   954     return ( iDataPort.IPCWrite( iClientBuffer, iRxTail, iIPCWriteOffset ) );
       
   955     }
       
   956 
       
   957 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   958 
       
   959 // none
       
   960 
       
   961 //  End of File