adaptationlayer/dataport/dataport_csy/src/dptx2pn.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 "dpbreak.h"         // break
       
    24 #include "dptx2pn.h"         // moves data from tx buffer to isc api
       
    25 #include "dpstd.h"           // fault codes etc.
       
    26 #include "dppif.h"           // pipe interface (pif)
       
    27 #include "dpflowctrl.h"      // flow control handling
       
    28 #include "dpdataconfig.h"    // configuration store
       
    29 #include "dpparityhandler.h" // parity bit handling in 7-bit data mode
       
    30 #include "pep_comm_types.h"  // pep_comm_types
       
    31 #include "dplog.h"           // dataport logging
       
    32 #include "osttracedefinitions.h"
       
    33 #ifdef OST_TRACE_COMPILER_IN_USE
       
    34 #include "dptx2pntraces.h"
       
    35 #endif
       
    36 
       
    37 // EXTERNAL DATA STRUCTURES
       
    38 // none
       
    39 
       
    40 // EXTERNAL FUNCTION PROTOTYPES
       
    41 // none
       
    42 
       
    43 // CONSTANTS
       
    44 // none
       
    45 
       
    46 // MACROS
       
    47 // none
       
    48 
       
    49 // LOCAL CONSTANTS AND MACROS
       
    50 // none
       
    51 
       
    52 // MODULE DATA STRUCTURES
       
    53 // none
       
    54 
       
    55 // LOCAL FUNCTION PROTOTYPES
       
    56 // none
       
    57 
       
    58 // FORWARD DECLARATIONS
       
    59 // none
       
    60 
       
    61 // ============================= LOCAL FUNCTIONS ===============================
       
    62 // none
       
    63 
       
    64 // ============================ MEMBER FUNCTIONS ===============================
       
    65 
       
    66 // ---------------------------------------------------------
       
    67 // C++ default constructor.
       
    68 //
       
    69 // ---------------------------------------------------------
       
    70 CDpTx2Pn::CDpTx2Pn(
       
    71     CDpDataPort& aDataPort ) :
       
    72     CActive( KDpTx2PnPriority ),
       
    73     iDataPort( aDataPort ),
       
    74     iBreak( iDataPort.BreakHandler() ),
       
    75     iBufferTx( iDataPort.Tx() ),
       
    76     iPifDcs( iDataPort.Pif() ),
       
    77     iFlowCtrl( iDataPort.FlowCtrl() ),
       
    78     iDataConfig( iDataPort.DataConfig() ),
       
    79     iParityHandler( iDataPort.ParityHandler() ),
       
    80     iTx( 0, 0 ),
       
    81     iTxTail( 0, 0 ),
       
    82     iRole( MDpDataClient::EDbDataClientReader )
       
    83     {
       
    84     OstTrace0( TRACE_NORMAL, CDPTX2PN_CDPTX2PN, "CDpTx2Pn::CDpTx2Pn" );
       
    85     LOGM(" CDpTx2Pn::CDpTx2Pn");
       
    86     }
       
    87 
       
    88 // ---------------------------------------------------------
       
    89 // CDpTx2Pn::ConstructL
       
    90 // Symbian 2nd phase constructor.
       
    91 // ---------------------------------------------------------
       
    92 void CDpTx2Pn::ConstructL()
       
    93     {
       
    94     OstTrace0( TRACE_NORMAL, CDPTX2PN_CONSTRUCTL, "CDpTx2Pn::ConstructL" );
       
    95     LOGM(" CDpTx2Pn::ConstructL");
       
    96 
       
    97     // If registering fails => can't do nothing here => must leave
       
    98     User::LeaveIfError( iBufferTx.RegisterDataClient( *this ) );
       
    99 
       
   100      //  initialise inner observer object
       
   101     iDpTx2PnPifObserver.Init( this );
       
   102     // register to PIF as observer
       
   103     iPifDcs.Attach( iDpTx2PnPifObserver );
       
   104     //  initialise inner observer object
       
   105     iDpTx2PnFcObserver.Init( this );
       
   106     // register to FlowCtrl as observer
       
   107     iFlowCtrl.Attach( iDpTx2PnFcObserver );
       
   108 
       
   109     CActiveScheduler::Add( this );
       
   110 
       
   111     if ( !IsActive() )
       
   112         {
       
   113         iRequestActive = ETrue;
       
   114         iStatus = KRequestPending;
       
   115         SetActive();
       
   116         }
       
   117     //no else
       
   118     }
       
   119 
       
   120 // ---------------------------------------------------------
       
   121 // CDpTx2Pn::NewL
       
   122 // Static constructor.
       
   123 // ---------------------------------------------------------
       
   124 CDpTx2Pn* CDpTx2Pn::NewL(
       
   125     CDpDataPort& aDataPort )
       
   126     {
       
   127     OstTrace0( TRACE_NORMAL, CDPTX2PN_NEWL, "CDpTx2Pn::NewL" );
       
   128     LOGM(" CDpTx2Pn::NewL");
       
   129 
       
   130     CDpTx2Pn* self = new( ELeave ) CDpTx2Pn( aDataPort );
       
   131 
       
   132     CleanupStack::PushL( self );
       
   133     self->ConstructL();
       
   134     CleanupStack::Pop( self );
       
   135 
       
   136     return self;
       
   137     }
       
   138 
       
   139 // ---------------------------------------------------------
       
   140 // CDpTx2Pn::~CDpTx2Pn
       
   141 // Destructor
       
   142 // ---------------------------------------------------------
       
   143 CDpTx2Pn::~CDpTx2Pn()
       
   144     {
       
   145     OstTrace0( TRACE_NORMAL, DUP1_CDPTX2PN_CDPTX2PN, "CDpTx2Pn::~CDpTx2Pn" );
       
   146     LOGM(" CDpTx2Pn::~CDpTx2Pn");
       
   147     DEBUG( "CDpTx2Pn::~CDpTx2Pn" )
       
   148 
       
   149     // unregister from PIF as observer
       
   150     iPifDcs.Detach( iDpTx2PnPifObserver );
       
   151     // unregister from FlowCtrl as observer
       
   152     iFlowCtrl.Detach( iDpTx2PnFcObserver );
       
   153     }
       
   154 
       
   155 // ---------------------------------------------------------
       
   156 // CDpTx2Pn::RunL
       
   157 // This is called when Tx2Pn is signalled. Tx2Pn can be
       
   158 // signalled by using iDataPort.SignalTx2Pn() or inside
       
   159 // CDpTx2Pn class just calling ReleaseNotify().
       
   160 // ---------------------------------------------------------
       
   161 //
       
   162 void CDpTx2Pn::RunL()
       
   163     {
       
   164     OstTrace1( TRACE_NORMAL, CDPTX2PN_RUNL, "CDpTx2Pn::RunL - Port: %u", iDataPort.PortUnit() );
       
   165     LOGM1("CDpTx2Pn::RunL - Port %d", iDataPort.PortUnit() );
       
   166     DEBUG("CDpTx2Pn::RunL\r\n" )
       
   167 
       
   168     TInt ret( KErrNone );
       
   169     TBool isNotReady( EFalse );
       
   170 
       
   171     // Request is completed
       
   172     iRequestActive = EFalse;
       
   173 
       
   174     if ( iStatus != KErrCancel )
       
   175         {
       
   176         if ( !IsFlowCtrlOn() )
       
   177             {
       
   178             // Call WritePn
       
   179             ret = WritePn();
       
   180 
       
   181             switch ( ret )
       
   182                 {
       
   183                 case KErrNone:
       
   184                 case KErrLocked:
       
   185                     {
       
   186                     // Ok, do nothing
       
   187                     break;
       
   188                     }
       
   189                 case KErrNotReady:
       
   190                     {
       
   191                     LOG1("CDpTx2Pn::RunL - Error: %d", ret );
       
   192                     OstTrace1( TRACE_NORMAL, DUP1_CDPTX2PN_RUNL, "CDpTx2Pn:: - Error: %d", ret );
       
   193                     // Try to recover from KErrNotReady fail
       
   194                     if ( !IsActive() )
       
   195                         {
       
   196                         iRequestActive = ETrue;
       
   197                         iStatus = KRequestPending;
       
   198                         SetActive();
       
   199                         }
       
   200                     //no else
       
   201                     isNotReady = ETrue;
       
   202                     break;
       
   203                     }
       
   204                 case KErrOverflow:
       
   205                 case KErrNoMemory:
       
   206                     {
       
   207                     LOG1("CDpTx2Pn::RunL - Error: %d", ret );
       
   208                     OstTrace1( TRACE_NORMAL, DUP2_CDPTX2PN_RUNL, "CDpTx2Pn:: - Error: %d", ret );
       
   209 
       
   210                     // KErrOverFlow (== ISC flow control on),
       
   211                     // KErrNomemory (== other ISC problems, no memory)
       
   212                     // => send failed
       
   213                     // Keep data in buffer but release data element
       
   214                     // (will be reserved again)
       
   215                     if ( KErrNone == iBufferTx.ReadElement().Release( 0 ) )
       
   216                         {
       
   217                         // reset descriptors
       
   218                         iTx.SetLength( 0 );
       
   219                         iTxTail.SetLength( 0 );
       
   220                         }
       
   221                     break;
       
   222                     }
       
   223                 default:
       
   224                     {
       
   225                     LOG1("CDpTx2Pn::RunL - Error: %d", ret );
       
   226                     OstTrace1( TRACE_NORMAL, DUP3_CDPTX2PN_RUNL, "CDpTx2Pn:: - Error: %d", ret );
       
   227 
       
   228                     // Something went wrong in WritePn method
       
   229                     // e.g. element reservation, must leave.
       
   230                     User::Leave(ret);
       
   231                     break;
       
   232                     }
       
   233 
       
   234                 } // switch ( ret )
       
   235             }
       
   236         else
       
   237             {
       
   238             LOG(" CDpTx2Pn::RunL, Flow control blocking");
       
   239             OstTrace0( TRACE_NORMAL, DUP4_CDPTX2PN_RUNL, "CDpTx2Pn:: Flow control blocking" );
       
   240             }
       
   241 
       
   242         if ( !isNotReady )
       
   243             {
       
   244             // Transmit buffer empty, is client intrested about that
       
   245             if ( 0 == ( iBufferTx.UsedBytes() ) && ( iOutBufIsEmptyNotify ) )
       
   246                 {
       
   247                 // We should notify client now.
       
   248                 iOutBufIsEmptyNotify = EFalse;
       
   249                 iDataPort.NotifyOutputEmptyCompleted( KErrNone );
       
   250                 }
       
   251             //no else
       
   252 
       
   253             // Set active again
       
   254             if ( !IsActive() )
       
   255                 {
       
   256                 iRequestActive = ETrue;
       
   257                 iStatus = KRequestPending;
       
   258                 SetActive();
       
   259                 }
       
   260             //no else
       
   261 
       
   262             // Signal ourselves only if there is data in buffer and
       
   263             // DP->DCS flow control is off.
       
   264             if ( iBufferTx.UsedBytes() && !IsFlowCtrlOn() )
       
   265                 {
       
   266                 ReleaseNotify();
       
   267                 }
       
   268             //no else
       
   269             }
       
   270         //no else
       
   271         }
       
   272     //no else
       
   273 
       
   274     }
       
   275 
       
   276 // ---------------------------------------------------------
       
   277 // CDpTx2Pn::RunError
       
   278 // Leave in RunL() is handled here. Error code is returned,
       
   279 // when internal error has occured.
       
   280 // ---------------------------------------------------------
       
   281 //
       
   282 TInt CDpTx2Pn::RunError(
       
   283     TInt aError )
       
   284     {
       
   285     OstTrace0( TRACE_NORMAL, CDPTX2PN_RUNERROR, "CDpTx2Pn::RunError" );
       
   286     OstTraceExt2( TRACE_NORMAL, DUP1_CDPTX2PN_RUNERROR, "CDpTx2Pn:: Port: %u, error code: %d", iDataPort.PortUnit(), aError );
       
   287 
       
   288     LOGM2("CDpTx2Pn::RunError - Port %d, error code: %d",
       
   289         iDataPort.PortUnit(), aError );
       
   290 
       
   291     return aError;
       
   292     }
       
   293 
       
   294 // ---------------------------------------------------------
       
   295 // CDpTx2Pn::DoCancel
       
   296 // This method cancels this active object by
       
   297 // RequestComplete(). This method must be called directly
       
   298 // (not through Cancel()), when RunL() should be completed
       
   299 // with KErrCancel.
       
   300 // ---------------------------------------------------------
       
   301 //
       
   302 void CDpTx2Pn::DoCancel()
       
   303     {
       
   304     OstTrace0( TRACE_NORMAL, CDPTX2PN_DOCANCEL, "CDpTx2Pn::DoCancel" );
       
   305     LOGM(" CDpTx2Pn::DoCancel");
       
   306     DEBUG( "CDpTx2Pn::DoCancel\n" )
       
   307 
       
   308     if ( iRequestActive )
       
   309         {
       
   310         // do the required signaling
       
   311         iRequestActive = EFalse;
       
   312         TRequestStatus* s = &iStatus;
       
   313         User::RequestComplete( s, KErrCancel );
       
   314         }
       
   315     //no else
       
   316     }
       
   317 
       
   318 // ---------------------------------------------------------
       
   319 // CDpTx2Pn::WritePn
       
   320 // Writes data to Isc Api.
       
   321 // ---------------------------------------------------------
       
   322 //
       
   323 TInt CDpTx2Pn::WritePn()
       
   324     {
       
   325     OstTrace0( TRACE_NORMAL, CDPTX2PN_WRITEPN, "CDpTx2Pn::WritePn" );
       
   326     OstTrace1( TRACE_NORMAL, DUP1_CDPTX2PN_WRITEPN, "CDpTx2Pn:: Port: %u", iDataPort.PortUnit() );
       
   327 
       
   328     LOGM1("CDpTx2Pn::WritePn - Port %d", iDataPort.PortUnit() );
       
   329 
       
   330     TInt len( 0 );
       
   331     TInt ret( KErrNone );
       
   332 
       
   333     // check pipe is enabled
       
   334     if ( iPifDcs.PipeState() != CDpPif::EDpPipeEnabled )
       
   335         {
       
   336         ret = KErrNotReady;
       
   337         }
       
   338     else if ( iBreakPending )
       
   339         {
       
   340         // length is as much as there is data before break,
       
   341         // but maximum KDpMaximumTxReservationSize
       
   342         if ( iBreakBytes > iBufferTx.MaxReservationSize() )
       
   343             {
       
   344             len = iBufferTx.MaxReservationSize();
       
   345             }
       
   346         else
       
   347             {
       
   348             len = iBreakBytes;
       
   349             }
       
   350         }
       
   351     else
       
   352         {
       
   353         // length is as much as there is but maximum KDpMaximumTxReservationSize
       
   354         if ( iBufferTx.UsedBytes() > iBufferTx.MaxReservationSize() )
       
   355             {
       
   356             len = iBufferTx.MaxReservationSize();
       
   357             }
       
   358         else
       
   359             {
       
   360             len = iBufferTx.UsedBytes();
       
   361             }
       
   362         }
       
   363 
       
   364     // Length can be 0, if Tx buffer has been flushed.
       
   365     // Try to recover with KErrNotReady error.
       
   366     if ( ( 0 == len ) && ( KErrNone == ret ) )
       
   367         {
       
   368         ret = KErrNotReady;
       
   369         }
       
   370     else if ( KErrNone == ret )
       
   371         {
       
   372         LOG("  CDpTx2Pn::WritePn, Tx element reservation");
       
   373         OstTrace0( TRACE_NORMAL, DUP2_CDPTX2PN_WRITEPN, "CDpTx2Pn:: Tx element reservation" );
       
   374 
       
   375         // try reserve read element, descriptor set to iTx,
       
   376         // possible tail into iTxTail
       
   377         TInt result( iBufferTx.ReadElement().Reserve( len, iTx, iTxTail ) );
       
   378 
       
   379         ret = HandleReturnValue( result );
       
   380         }
       
   381     //no else
       
   382 
       
   383     return ret;
       
   384     }
       
   385 
       
   386 // ---------------------------------------------------------
       
   387 // CDpTx2Pn::IsFlowCtrlOn
       
   388 // Is flow control on between DP->DCS. Returns also ETrue,
       
   389 // when pipe is not enabled.
       
   390 // ---------------------------------------------------------
       
   391 //
       
   392 TBool CDpTx2Pn::IsFlowCtrlOn()
       
   393     {
       
   394     OstTrace0( TRACE_NORMAL, CDPTX2PN_ISFLOWCTRLON, "CDpTx2Pn::IsFlowCtrlOn" );
       
   395     LOGM(" CDpTx2Pn::IsFlowCtrlOn");
       
   396 
       
   397     TBool ret( EFalse );
       
   398 
       
   399     if ( EFlowControlOn == iFlowCtrl.FlowCtrlDp2Dcs() ||
       
   400         CDpPif::EDpPipeEnabled != iPifDcs.PipeState() )
       
   401         {
       
   402         ret = ETrue;
       
   403         }
       
   404     else
       
   405         {
       
   406         ret = EFalse;
       
   407         }
       
   408 
       
   409     return ret;
       
   410     }
       
   411 
       
   412 // ---------------------------------------------------------
       
   413 // CDpTx2Pn::ReleaseNotify
       
   414 // This method signals this active object.
       
   415 // ---------------------------------------------------------
       
   416 //
       
   417 void CDpTx2Pn::ReleaseNotify()
       
   418     {
       
   419     OstTrace0( TRACE_NORMAL, CDPTX2PN_RELEASENOTIFY, "CDpTx2Pn::ReleaseNotify" );
       
   420     LOG(" CDpTx2Pn::ReleaseNotify");
       
   421     DEBUG( "CDpTx2Pn::ReleaseNotify" )
       
   422 
       
   423     // signal ourselves
       
   424     if ( iRequestActive )
       
   425         {
       
   426         iRequestActive = EFalse;
       
   427         TRequestStatus* s = &iStatus;
       
   428         User::RequestComplete( s, KErrNone );
       
   429         }
       
   430     //no else
       
   431     }
       
   432 
       
   433 // ---------------------------------------------------------
       
   434 // This method notifies that buffer is flushed. Classes which have access
       
   435 // to buffers are derived from this class. Derived class could override
       
   436 // this method, otherwise this default method will be used.
       
   437 // release this cactive object
       
   438 // ---------------------------------------------------------
       
   439 //
       
   440 void CDpTx2Pn::FlushNotify()
       
   441     {
       
   442     OstTrace0( TRACE_NORMAL, CDPTX2PN_FLUSHNOTIFY, "CDpTx2Pn::FlushNotify" );
       
   443     LOGM(" CDpTx2Pn::FlushNotify()");
       
   444 
       
   445     ReleaseNotify();
       
   446     }
       
   447 
       
   448 // -----------------------------------------------------------------------------
       
   449 // CDpTx2Pn::Role
       
   450 // This method gets the role (reader/writer) of data client.
       
   451 // -----------------------------------------------------------------------------
       
   452 //
       
   453 TUint8 CDpTx2Pn::Role()
       
   454     {
       
   455     OstTrace0( TRACE_NORMAL, CDPTX2PN_ROLE, "CDpTx2Pn::Role" );
       
   456 
       
   457     return iRole;
       
   458     }
       
   459 
       
   460 // ---------------------------------------------------------
       
   461 // CDpTx2Pn::UpDate
       
   462 // Called after pipe state change and after flow control
       
   463 // state change.
       
   464 // ---------------------------------------------------------
       
   465 //
       
   466 void CDpTx2Pn::UpDate(
       
   467     CDpSubject* /*aChangedSubject*/ )
       
   468     {
       
   469     OstTrace0( TRACE_NORMAL, CDPTX2PN_UPDATE, "CDpTx2Pn::UpDate" );
       
   470     LOG(" CDpTx2Pn::UpDate");
       
   471     DEBUG( "CDpTx2Pn::UpDate" )
       
   472 
       
   473     // if there is data ready signal ourselves
       
   474     if ( ( 0 < iBufferTx.UsedBytes() ) && ( !IsFlowCtrlOn() ) )
       
   475         {
       
   476         ReleaseNotify();
       
   477         }
       
   478     //no else
       
   479     }
       
   480 
       
   481 // ---------------------------------------------------------
       
   482 // CDpTx2Pn::SetBreakBytes
       
   483 // Set up flag if there is some data to be send before break
       
   484 // (this is client->DCS break)
       
   485 // ---------------------------------------------------------
       
   486 //
       
   487 void CDpTx2Pn::SetBreakBytes(
       
   488     const TInt aBreakBytes)
       
   489     {
       
   490     OstTrace0( TRACE_NORMAL, CDPTX2PN_SETBREAKBYTES, "CDpTx2Pn::SetBreakBytes" );
       
   491     LOG(" CDpTx2Pn::SetBreakBytes");
       
   492     DEBUG( "CDpTx2Pn::SetBreakBytes()" )
       
   493 
       
   494     iBreakBytes = aBreakBytes;
       
   495     // put break pending
       
   496     iBreakPending = ETrue;
       
   497     }
       
   498 
       
   499 // ---------------------------------------------------------
       
   500 // CDpTx2Pn::CancelBreakBytes
       
   501 // Clears pending break bytes. Client may have cancelled
       
   502 // it's break request.
       
   503 // ---------------------------------------------------------
       
   504 //
       
   505 void CDpTx2Pn::CancelBreakBytes()
       
   506     {
       
   507     OstTrace0( TRACE_NORMAL, CDPTX2PN_CANCELBREAKBYTES, "CDpTx2Pn::CancelBreakBytes" );
       
   508     LOG(" CDpTx2Pn::CancelBreakBytes");
       
   509     DEBUG( "CDpTx2Pn::CancelBreakBytes()" )
       
   510 
       
   511     iBreakBytes = 0;
       
   512     iBreakPending = EFalse;
       
   513     }
       
   514 
       
   515 // ---------------------------------------------------------
       
   516 // CDpTx2Pn::SetOutputBufferEmptyNotification
       
   517 // Setup flag that we are requested to notify or not the
       
   518 // client, when output buffer (TX buffer) empties.
       
   519 // ---------------------------------------------------------
       
   520 //
       
   521 void CDpTx2Pn::SetOutputBufferEmptyNotification(
       
   522     const TBool aUsedOrNot )
       
   523     {
       
   524     OstTrace0( TRACE_NORMAL, CDPTX2PN_SETOUTPUTBUFFEREMPTYNOTIFICATION, "CDpTx2Pn::SetOutputBufferEmptyNotification" );
       
   525     LOG(" CDpTx2Pn::SetOutputBufferEmptyNotification");
       
   526     DEBUG( "CDpTx2Pn::SetOutputBufferEmptyNotification")
       
   527 
       
   528     iOutBufIsEmptyNotify = aUsedOrNot;
       
   529     }
       
   530 
       
   531 // ---------------------------------------------------------
       
   532 // CDpTx2Pn::PipeSendWithParityAdd
       
   533 // This method writes data to Isc Api. In 7-bit data case
       
   534 // parity bits are added here using parity handler class.
       
   535 // ---------------------------------------------------------
       
   536 //
       
   537 TInt CDpTx2Pn::PipeSendWithParityAdd(
       
   538     TPtr8& aTx )
       
   539     {
       
   540     OstTrace0( TRACE_NORMAL, CDPTX2PN_PIPESENDWITHPARITYADD, "CDpTx2Pn::PipeSendWithParityAdd" );
       
   541     OstTrace1( TRACE_NORMAL, DUP1_CDPTX2PN_PIPESENDWITHPARITYADD, "CDpTx2Pn:: Port: %u", iDataPort.PortUnit() );
       
   542 
       
   543     LOGM1("CDpTx2Pn::PipeSendWithParityAdd - Port %d", iDataPort.PortUnit() );
       
   544 
       
   545     TUint8 pipeHandle( 0 );
       
   546     TInt result( iDataPort.ActivePipeHandle( pipeHandle ) );
       
   547 
       
   548     if ( KErrNone == result )
       
   549         {
       
   550         if ( EData7 == iDataConfig.DataBits() )
       
   551             {
       
   552             // DteParityBitWhen7Mode parameter tells whether parity bit should
       
   553             // be carried or not in data mesages in a pipe when DTE interface
       
   554             // is in  7-bit mode.
       
   555             if ( iDataConfig.DteParityBitWhen7Mode() == PEP_COMM_DATA_WITH_PARITY )
       
   556                 {
       
   557                 // use parity bits
       
   558                 iParityHandler.AddParityBits( aTx, iDataConfig.Parity() );
       
   559                 }
       
   560             //no else
       
   561             }
       
   562         //no else
       
   563 
       
   564         result = iDataPort.ISAHandle().DataSend( aTx );
       
   565 
       
   566 #if defined(_DEBUG)
       
   567         if ( KErrNone != result )
       
   568             {
       
   569             LOG1("Error Pipe send %d", result );
       
   570             OstTrace1( TRACE_NORMAL, DUP2_CDPTX2PN_PIPESENDWITHPARITYADD, "CDpTx2Pn:: Error Pipe send %d", result );
       
   571             }
       
   572         //no else
       
   573 #endif
       
   574         }
       
   575     //no else
       
   576 
       
   577     return result;
       
   578     }
       
   579 
       
   580 // ---------------------------------------------------------
       
   581 // CDpTx2Pn::HandleReturnValue
       
   582 // Handles the reserve methods return value.
       
   583 // ---------------------------------------------------------
       
   584 //
       
   585 TInt CDpTx2Pn::HandleReturnValue(
       
   586     const TInt aReturnValue )
       
   587     {
       
   588     OstTrace0( TRACE_NORMAL, CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn::HandleReturnValue" );
       
   589     OstTrace1( TRACE_NORMAL, DUP1_CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn:: Port: %u", iDataPort.PortUnit() );
       
   590 
       
   591     LOGM1("CDpTx2Pn::HandleReturnValue - Port %d", iDataPort.PortUnit() );
       
   592 
       
   593     TInt result( KErrNone );
       
   594 
       
   595     switch ( aReturnValue )
       
   596         {
       
   597         case KErrNone:
       
   598             {
       
   599             // write iTx
       
   600             if ( 0 < iTx.Length() )
       
   601                 {
       
   602                 result = PipeSendWithParityAdd( iTx );
       
   603                 }
       
   604             //no else
       
   605 
       
   606 #ifdef _DEBUG
       
   607             LOG1("-- WRITE -- %x", &iDataPort);
       
   608             OstTrace1( TRACE_NORMAL, DUP2_CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn:: -- WRITE -- %x", &iDataPort );
       
   609 
       
   610             if ( 0 < iTx.Length() )
       
   611                 {
       
   612                 if ( KErrOverflow != result )
       
   613                     {
       
   614                     iTotalSent = iTotalSent + iTx.Length();
       
   615                     }
       
   616                 OstTraceExt2( TRACE_NORMAL, DUP3_CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn:: Tx len = %d, Total Bytes sent = %d", iTx.Length(), iTotalSent );
       
   617                 OstTraceExt1( TRACE_NORMAL, DUP12_CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn:: TX = %s", iTx );
       
   618 
       
   619                 LOG2("    Tx len = %d, Total Bytes sent = %d",
       
   620                     iTx.Length(), iTotalSent );
       
   621                 LOGHEX( iTx, ETrue );
       
   622                 }
       
   623             //no else
       
   624 #endif
       
   625 
       
   626             if ( KErrNone == result )
       
   627                 {
       
   628                 TInt len( 0 );
       
   629 
       
   630                 // Write iTx OK => Write iTxTail
       
   631                 if ( 0 < iTxTail.Length() )
       
   632                     {
       
   633                     result = PipeSendWithParityAdd( iTxTail );
       
   634                     }
       
   635                 //no else
       
   636 
       
   637 #ifdef _DEBUG
       
   638                 if ( 0 < iTxTail.Length() )
       
   639                     {
       
   640                     if ( KErrOverflow != result )
       
   641                         {
       
   642                         iTotalSent = iTotalSent + iTxTail.Length();
       
   643                         }
       
   644                     OstTraceExt2( TRACE_NORMAL, DUP5_CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn:: Tx Tail len = %d, Total Bytes sent = %d", iTxTail.Length(), iTotalSent );
       
   645                     OstTraceExt1( TRACE_NORMAL, DUP13_CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn:: TX = %s", iTxTail );
       
   646 
       
   647                     LOG2("    Tx Tail len = %d, Total Bytes sent = %d",
       
   648                         iTxTail.Length(), iTotalSent );
       
   649                     LOGHEX( iTxTail, ETrue );
       
   650                     }
       
   651                 //no else
       
   652 #endif
       
   653 
       
   654                 if ( KErrNone == result )
       
   655                     {
       
   656                     // Write iTx OK & Write iTxTail OK
       
   657                     // => release iTx and iTxTail
       
   658                     LOG(" CDpTx2Pn::HandleReturnValue, Tx element release (iTx + iTxTail)");
       
   659                     OstTrace0( TRACE_NORMAL, DUP7_CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn:: Tx element release (iTx + iTxTail)" );
       
   660                     len = iTx.Length() + iTxTail.Length();
       
   661                     }
       
   662                 else
       
   663                     {
       
   664                     // Write iTx OK & Write iTxTail FAIL
       
   665                     // => release only iTx
       
   666                     OstTrace0( TRACE_NORMAL, DUP8_CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn:: Tail sending failed" );
       
   667                     OstTrace0( TRACE_NORMAL, DUP9_CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn:: Tx element release (iTx)" );
       
   668 
       
   669                     LOG(" CDpTx2Pn::HandleReturnValue, Tail sending failed");
       
   670                     LOG(" CDpTx2Pn::HandleReturnValue, Tx element release (iTx)");
       
   671                     len = iTx.Length();
       
   672                     }
       
   673 
       
   674                 // release read element
       
   675                 result = iBufferTx.ReadElement().Release( len );
       
   676 
       
   677                 if ( KErrNone == result )
       
   678                     {
       
   679                     // reset descriptors
       
   680                     iTx.SetLength( 0 );
       
   681                     iTxTail.SetLength( 0 );
       
   682 
       
   683                     if ( iBreakPending )
       
   684                         {
       
   685                         iBreakBytes -= len;
       
   686 
       
   687                         if ( iBreakBytes == 0 )
       
   688                             {
       
   689                             iBreakPending = EFalse;
       
   690                             TInt ret = iBreak.SendBreak();
       
   691                             iDataPort.BreakCompleted( ret );
       
   692                             }
       
   693                         //no else
       
   694                         }
       
   695                     //no else
       
   696                     }
       
   697                 //no else
       
   698                 }
       
   699             //no else
       
   700 
       
   701             break;
       
   702             }
       
   703         case KErrNoMemory:
       
   704             {
       
   705             DEBUG( "CDpTx2Pn, waiting..." )
       
   706             OstTrace0( TRACE_NORMAL, DUP10_CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn:: waiting..." );
       
   707 
       
   708             // do nothing, in RunL we are set active again
       
   709             break;
       
   710             }
       
   711         default:
       
   712             {
       
   713             LOG(" CDpTx2Pn::HandleReturnValue, Element reservation failed");
       
   714             OstTrace0( TRACE_NORMAL, DUP11_CDPTX2PN_HANDLERETURNVALUE, "CDpTx2Pn:: Element reservation failed" );
       
   715 
       
   716             // Return the error code. Caller of the WritePn can handel this.
       
   717             result = aReturnValue;
       
   718             }
       
   719         }
       
   720 
       
   721     return result;
       
   722     }
       
   723 
       
   724 //===========================================================
       
   725 
       
   726 // ---------------------------------------------------------
       
   727 // CDpTx2Pn::CDpTx2PnObserver::Init
       
   728 // This method initializes Tx2Pn observer.
       
   729 // ---------------------------------------------------------
       
   730 //
       
   731 void CDpTx2Pn::CDpTx2PnObserver::Init(
       
   732     CDpTx2Pn* aDpTx2Pn )
       
   733     {
       
   734     iDpTx2Pn = aDpTx2Pn;
       
   735     }
       
   736 
       
   737 // ---------------------------------------------------------
       
   738 // CDpTx2Pn::CDpTx2PnObserver::UpDate
       
   739 // This method updates Tx2Pn.
       
   740 // ---------------------------------------------------------
       
   741 //
       
   742 void CDpTx2Pn::CDpTx2PnObserver::UpDate(
       
   743     CDpSubject* aChangedSubject )
       
   744     {
       
   745     LOG(" CDpTx2Pn::CDpTx2PnObserver::UpDate");
       
   746 
       
   747     if ( iDpTx2Pn )
       
   748         {
       
   749         iDpTx2Pn->UpDate( aChangedSubject );
       
   750         }
       
   751     }
       
   752 
       
   753 // ================= OTHER EXPORTED FUNCTIONS ==============
       
   754 // none
       
   755 
       
   756 //  End of File