systemswstubs/examplecommonisc/IscDriver/src/IscChannel.cpp
branchRCL_3
changeset 44 b5894bb67e73
parent 35 37b610eb7fe3
equal deleted inserted replaced
35:37b610eb7fe3 44:b5894bb67e73
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  An example implementation for ISC Driver Reference
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <kern_priv.h>
       
    22 #include <IscDataTransmissionBase.h>
       
    23 #include "IscChannel.h"
       
    24 #include "IscDevice.h"
       
    25 #include "IscChannelContainer.h"
       
    26 #include "IscQueue.h"
       
    27 #include "IscTrace.h"
       
    28 
       
    29 // EXTERNAL DATA STRUCTURES
       
    30 
       
    31 // EXTERNAL FUNCTION PROTOTYPES  
       
    32 
       
    33 // CONSTANTS
       
    34 _LIT( KIscDriver, "IscDriver" );
       
    35 
       
    36 // MACROS
       
    37 
       
    38 // LOCAL CONSTANTS AND MACROS
       
    39 const TInt KIscInitializeDfcPriority( 1 );
       
    40 const TInt KOneParam( 1 );
       
    41 const TInt KTwoParams( 2 );
       
    42 const TInt KThreeParams( 3 );
       
    43 const TInt KFirstParam( 0 );
       
    44 const TInt KSecondParam( 1 );
       
    45 const TInt KThirdParam( 2 );
       
    46 const TInt KMultiplyByOne( KSecondParam );
       
    47 const TInt KMultiplyByThree( KThreeParams );
       
    48 const TInt KDivideByFour( 4 );
       
    49 
       
    50 // MODULE DATA STRUCTURES
       
    51 
       
    52 // LOCAL FUNCTION PROTOTYPES
       
    53 
       
    54 // FORWARD DECLARATIONS
       
    55 
       
    56 
       
    57 // ============================ MEMBER FUNCTIONS ===============================
       
    58 
       
    59 
       
    60 // -----------------------------------------------------------------------------
       
    61 // DIscChannel::DIscChannel
       
    62 // C++ default constructor.
       
    63 // ( other items were commented in a header ).
       
    64 // -----------------------------------------------------------------------------
       
    65 //
       
    66 EXPORT_C DIscChannel::DIscChannel( DLogicalDevice* aDevice ) 
       
    67     : iInitializeDfc( NULL ),
       
    68     iDataTransmissionIniData( NULL ),
       
    69     iMultiplexerIniData( NULL ),
       
    70     iMultiplexerBuffer( NULL ),
       
    71     iDataTransmissionBuffer( NULL ),
       
    72     iIscDevice( NULL ),
       
    73     iIscConnectionStatusPtr( NULL ),
       
    74     iIscFlowControlStatusPtr( NULL ),
       
    75     iReceiveBufPtr( NULL ),
       
    76     iDataReceiveBufPtr( NULL ),
       
    77     iNeededBufLen( NULL ),
       
    78     iNeededDataBufLen( NULL ),
       
    79     iChannelNumber( 0 ),
       
    80     iChannelOpen( EFalse ),
       
    81     iFrameRx( NULL ),
       
    82     iFrameRxQueue( NULL ),    
       
    83     iDataFrameRx( NULL ),
       
    84     iDataFrameRxQueue( NULL ),
       
    85     iULFlowControlStatus( EIscFlowControlOff ),
       
    86     iDLFlowControlStatus( EIscFlowControlOff ),
       
    87     iLastNotifiedULFlowstatus( EIscFlowControlOff ),
       
    88     iIscChannelHighWaterMark( 0 ),
       
    89     iIscChannelLowWaterMark( 0 ),
       
    90     iOverFlow( EFalse ),
       
    91     iClientPanic( EFalse ),
       
    92     iDataTransmissionErrorCode( KErrNone )
       
    93     {
       
    94     
       
    95     iIscDevice = ( DIscDevice * )aDevice;
       
    96     for ( TInt i( KErrNone ); i < EIscAsyncLast; i++ )
       
    97         {
       
    98         iIscRequests[i] = NULL;
       
    99         }
       
   100     iThread = &Kern::CurrentThread();   
       
   101     TInt r = iThread->Open();
       
   102     TRACE_ASSERT( r == KErrNone );
       
   103 
       
   104     }
       
   105 
       
   106 
       
   107 // -----------------------------------------------------------------------------
       
   108 // DIscChannel::~DIscChannel
       
   109 // Destructor
       
   110 // ( other items were commented in a header ).
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 DIscChannel::~DIscChannel()
       
   114     {
       
   115     C_TRACE( ( _T( "DIscChannel::~DIscChannel()" ) ) );
       
   116     
       
   117     if ( iChannelNumber < KIscNumberOfUnits )
       
   118         {
       
   119         IscChannelContainer::RemoveChannel( this );
       
   120         }
       
   121     else 
       
   122         {
       
   123         C_TRACE( ( _T( "DIscChannel::~DIscChannel() re-open" ) ) );
       
   124         }
       
   125 
       
   126     ChannelDestruction();    
       
   127     Kern::SafeClose( ( DObject*& )iThread, NULL );
       
   128     C_TRACE( ( _T( "DIscChannel::~DIscChannel() SafeClose called" ) ) );
       
   129 
       
   130     }
       
   131 
       
   132 // -----------------------------------------------------------------------------
       
   133 // DIscChannel::ChannelDestruction
       
   134 // Destructor
       
   135 // ( other items were commented in a header ).
       
   136 // -----------------------------------------------------------------------------
       
   137 //
       
   138 void DIscChannel::ChannelDestruction()
       
   139     {
       
   140     C_TRACE( ( _T( "DIscChannel::ChannelDestruction() iChannelNumber (0x%x)" ),iChannelNumber ) );
       
   141 
       
   142     // call DIscMultiplexerBase::CloseDLC and DLFlowControlNotify in case the channel has not been
       
   143     // properly closed ( e.g. client thread panic etc. )
       
   144     if ( iChannelOpen )
       
   145         {
       
   146         iIscDevice->CancelSending( iChannelNumber, this );// Delete pending send frames
       
   147         iIscDevice->iIscMultiplexerInterface->CloseDLC( iChannelNumber, this );
       
   148         iIscDevice->DLFlowControlNotify( EIscFlowControlOff, iChannelNumber, this );
       
   149         }
       
   150 
       
   151     if ( iFrameRxQueue )
       
   152         {
       
   153         while ( !iFrameRxQueue->Empty() )
       
   154             {
       
   155             TDes8* tempPtr = ( TDes8* ) iFrameRxQueue->GetFirst();
       
   156             iFrameRxQueue->DeleteFirst();
       
   157             iIscDevice->ReleaseMemoryBlock( tempPtr );
       
   158             }
       
   159         delete iFrameRxQueue;
       
   160         iFrameRxQueue = NULL;
       
   161         }
       
   162 
       
   163     if ( iFrameRx )
       
   164             {
       
   165             delete [] iFrameRx;
       
   166             iFrameRx = NULL;
       
   167             }
       
   168 
       
   169     if ( iDataFrameRxQueue )
       
   170         {
       
   171         while ( !iDataFrameRxQueue->Empty() )
       
   172             {
       
   173             TDes8* tempPtr = ( TDes8* ) iDataFrameRxQueue->GetFirst();
       
   174             iDataFrameRxQueue->DeleteFirst();
       
   175             iIscDevice->ReleaseMemoryBlock( tempPtr );        
       
   176             }
       
   177         delete iDataFrameRxQueue;
       
   178         iDataFrameRxQueue = NULL;        
       
   179         }
       
   180 
       
   181     if ( iDataFrameRx )
       
   182             {
       
   183             delete [] iDataFrameRx;
       
   184             iDataFrameRx = NULL;
       
   185             }
       
   186     
       
   187     if ( iInitializeDfc )
       
   188         {        
       
   189         delete iInitializeDfc;
       
   190         iInitializeDfc = NULL;
       
   191         }    
       
   192 
       
   193     if ( iDataTransmissionIniData )
       
   194         {
       
   195         Kern::Free( iDataTransmissionBuffer );
       
   196         delete iDataTransmissionIniData;
       
   197         iDataTransmissionIniData = NULL;
       
   198         }
       
   199 
       
   200     if ( iMultiplexerIniData )
       
   201         {
       
   202         Kern::Free( iMultiplexerBuffer );
       
   203         delete iMultiplexerIniData;
       
   204         iMultiplexerIniData = NULL;
       
   205         }
       
   206 
       
   207     C_TRACE( ( _T( "DIscChannel::ChannelDestruction - return void" ) ) );
       
   208     }
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // DIscChannel::HandleMsg
       
   212 // Message handling ( kernel server context ).
       
   213 // ( other items were commented in a header ).
       
   214 // -----------------------------------------------------------------------------
       
   215 //
       
   216 void DIscChannel::HandleMsg( 
       
   217     TMessageBase* aMsg )
       
   218     {
       
   219     C_TRACE( ( _T( "DIscChannel::HandleMsg(0x%x)" ), aMsg ) );
       
   220     TThreadMessage& m=*( TThreadMessage* )aMsg;
       
   221     TInt id( m.iValue );
       
   222 
       
   223     if ( id==( TInt )ECloseMsg )
       
   224         {
       
   225         C_TRACE( ( _T( "DIscChannel::HandleMsg ECloseMsg" ) ) );
       
   226         m.Complete( KErrNone,EFalse );
       
   227         return;
       
   228         }
       
   229 
       
   230     else if ( id==KMaxTInt )
       
   231         {
       
   232         // DoCancel
       
   233         // Should not come here ever
       
   234         ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscNotAllowedCallToDoCancel );
       
   235         }
       
   236 
       
   237     else if ( id<0 )
       
   238         {
       
   239         // DoRequest
       
   240         // should not come here ever
       
   241         ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscNotAllowedCallToDoRequest );
       
   242         }
       
   243     
       
   244     else
       
   245         {
       
   246         // DoControl
       
   247         TUint32 a1[ KThreeParams ];
       
   248         TInt r( KErrNone );
       
   249         if ( id != EIscSyncClose )
       
   250             {
       
   251             TInt amountOfParams( KErrNone );
       
   252             switch( id )
       
   253                 {
       
   254                 case EIscAsyncInitializeModemInterface:
       
   255                 case EIscAsyncOpen:
       
   256                     amountOfParams = KThreeParams;
       
   257                     break;
       
   258                 default:
       
   259                     ASSERT_RESET_ALWAYS( 0, "NokiaISCDriver", EIscUnknownCommand );
       
   260                 break;
       
   261                 }
       
   262             r = Kern::ThreadRawRead( iThread, ( TAny* )m.Ptr0(), a1,
       
   263                                      amountOfParams * sizeof( TAny* ) );
       
   264             TRACE_ASSERT( r == KErrNone );
       
   265             }
       
   266         if( r == KErrNone )
       
   267             {
       
   268             r=HandleRequest( id,a1,m.Ptr1() );
       
   269             }
       
   270 
       
   271         m.Complete( r,ETrue );
       
   272         }
       
   273     }
       
   274 
       
   275 // -----------------------------------------------------------------------------
       
   276 // DIscChannel::Request
       
   277 // Message handling ( user thread context ).
       
   278 // ( other items were commented in a header ).
       
   279 // -----------------------------------------------------------------------------
       
   280 //
       
   281 #ifndef COMPONENT_TRACE_FLAG
       
   282 TInt DIscChannel::Request( TInt aReqNo, TAny* a1, TAny* )
       
   283 #else 
       
   284 TInt DIscChannel::Request( TInt aReqNo, TAny* a1, TAny* a2)
       
   285 #endif
       
   286     {
       
   287     C_TRACE( ( _T( "DIscChannel::Request(0x%x, 0x%x, 0x%x)" ), aReqNo, a1, a2 ) );
       
   288 
       
   289     TInt r( KErrNotFound );
       
   290 
       
   291     if ( aReqNo<( TInt )EMinRequestId )
       
   292         C_TRACE( ( _T( "DIscChannel::Request ERROR: False aReqNo %d" ), aReqNo ) );
       
   293     
       
   294     if ( aReqNo >= 0 && aReqNo < EIscAsyncLastKernelServerContext ||
       
   295          aReqNo >= EIscAsyncLast && aReqNo < EIscSyncLastKernelServerContext )
       
   296         {
       
   297         TThreadMessage& m=Kern::Message();
       
   298         m.iValue=aReqNo;
       
   299         m.iArg[ KFirstParam ]=a1;
       
   300         m.iArg[ KSecondParam ]=NULL;
       
   301         r = m.SendReceive( &iMsgQ );
       
   302         }
       
   303     else
       
   304         {
       
   305         TInt ulen( KErrNotFound );
       
   306         switch ( aReqNo )
       
   307             {
       
   308             case EIscCancelAsyncInitialize:
       
   309             case EIscCancelAsyncReceive:
       
   310             case EIscCancelAsyncDataReceive:
       
   311             case EIscSyncGetConnectionStatus:
       
   312             case EIscCancelAsyncNotifyConnection:
       
   313             case EIscSyncGetFlowControlStatus:
       
   314             case EIscCancelAsyncNotifyFlowControl:
       
   315             case EIscSyncGetMaximunDataSize:
       
   316             case EIscCancelAsyncCustomOperation1:
       
   317             case EIscCancelAsyncCustomOperation2:
       
   318             case EIscCancelAsyncCustomOperation3:
       
   319             case EIscCancelAsyncCustomOperation4:
       
   320             case EIscCancelAsyncCustomOperation5:
       
   321             case EIscCancelAsyncOpen:
       
   322             case EIscSyncResetBuffers:
       
   323             case EIscCancelAsyncSend:
       
   324             case EIscCancelAsyncDataSend:
       
   325                 {
       
   326                 ulen = KErrNone;
       
   327                 break;
       
   328                 }
       
   329             case EIscSyncSend:
       
   330             case EIscSyncDataSend:
       
   331             case EIscSyncCustomOperation1:
       
   332             case EIscSyncCustomOperation2:
       
   333             case EIscSyncCustomOperation3:
       
   334             case EIscSyncCustomOperation4:
       
   335             case EIscSyncCustomOperation5:
       
   336             case EIscAsyncClose:
       
   337                 {
       
   338                 ulen = KOneParam;
       
   339                 break;
       
   340                 }
       
   341             case EIscAsyncSend:
       
   342             case EIscAsyncDataSend:
       
   343             case EIscSyncGetChannelInfo:
       
   344             case EIscAsyncNotifyConnectionStatus:
       
   345             case EIscAsyncNotifyFlowControlStatus:
       
   346             case EIscAsyncCustomOperation1:
       
   347             case EIscAsyncCustomOperation2:
       
   348             case EIscAsyncCustomOperation3:
       
   349             case EIscAsyncCustomOperation4:
       
   350             case EIscAsyncCustomOperation5:
       
   351                 {
       
   352                 ulen = KTwoParams;
       
   353                 break;
       
   354                 }
       
   355             case EIscAsyncReceive:
       
   356             case EIscAsyncDataReceive:
       
   357                 {
       
   358                 ulen = KThreeParams;
       
   359                 break;
       
   360                 }
       
   361             default:
       
   362                 {
       
   363                 TRACE_ASSERT_ALWAYS;
       
   364                 }
       
   365             }
       
   366         ASSERT_RESET_ALWAYS( KErrNotFound != ulen, "ISCDriver", EIscUnknownCommand );
       
   367         // Maximum number of elements is three!!!
       
   368         TAny* kptr[ KThreeParams ] = { KErrNone }; 
       
   369         if( ulen > KErrNone )
       
   370             {
       
   371             C_TRACE( ( _T( "DIscChannel::Request ISC kumemget32" ) ) );
       
   372             kumemget32( kptr , a1, ( sizeof( TAny* ) ) * ulen ); 
       
   373             }
       
   374         r = HandleRequest( aReqNo, kptr, NULL );
       
   375         }
       
   376     C_TRACE( ( _T( "DIscChannel::Request ISC return %d CH 0x%x" ), r, iChannelNumber ) );
       
   377     return r;        
       
   378 
       
   379     }
       
   380 
       
   381 // -----------------------------------------------------------------------------
       
   382 // DIscChannel::DoControl
       
   383 // Handles requests.
       
   384 // ( other items were commented in a header ).
       
   385 // -----------------------------------------------------------------------------
       
   386 //
       
   387 TInt DIscChannel::HandleRequest( 
       
   388     TInt aFunction, 
       
   389     TAny* a1, 
       
   390     TAny* /*a2*/ )
       
   391     {
       
   392     C_TRACE( ( _T( "DIscChannel::DoControl(0x%x, 0x%x) iChannelNumber 0x%x channelPtr 0x%x" ), aFunction, a1, iChannelNumber, this ) );
       
   393 
       
   394     TInt error( KErrNone );
       
   395     
       
   396 #ifdef _DEBUG
       
   397     // Check if control frame buffer overflow -> panic
       
   398     if ( iClientPanic )
       
   399         {
       
   400         C_TRACE( ( _T( "DIscChannel::DoControl() BUFFER OVERFLOW: PANIC CLIENT 0x%x" ), iChannelNumber ) );
       
   401         TRACE_ASSERT_ALWAYS;
       
   402         // This panic the user thread only.
       
   403 		Kern::ThreadKill( iThread, EExitPanic, EIscControlBufferOverflow, KIscDriver );
       
   404         }
       
   405 #endif // _DEBUG
       
   406 
       
   407     // Handle asynchronous requests
       
   408     if ( aFunction >= EIscAsyncInitializeModemInterface &&
       
   409          aFunction < EIscAsyncLast )
       
   410         {
       
   411         // if request is already active
       
   412         if ( iIscRequests[aFunction] )
       
   413             {
       
   414             TUint32* tablePtr = ( TUint32* )a1;
       
   415             TRequestStatus* requestStatus = ( TRequestStatus* )( tablePtr[ KFirstParam ] );
       
   416             Kern::RequestComplete( iThread, requestStatus, KErrAlreadyExists );
       
   417             }
       
   418         else
       
   419             {
       
   420             HandleAsyncRequest( aFunction, a1 );
       
   421             }
       
   422         }
       
   423     // Handle synchronous requests.
       
   424     else if ( aFunction >= EIscAsyncLast &&
       
   425               aFunction < EIscSyncLast )
       
   426         {
       
   427         error = HandleSyncRequest( aFunction, a1 );
       
   428         }
       
   429     // Handle cancellation requests.
       
   430     else if ( aFunction >= EIscSyncLast &&
       
   431               aFunction < EIscCancelLast )
       
   432         {
       
   433         error = HandleCancelRequest( aFunction, a1 );
       
   434         }
       
   435     // Undefined request, panic current thread. 
       
   436     else
       
   437         {
       
   438         // This panic the user thread only.
       
   439 		Kern::ThreadKill( iThread, EExitPanic, EIscControlBufferOverflow, KIscDriver );
       
   440         }
       
   441         
       
   442     C_TRACE( ( _T( "DIscChannel::DoControl - return %d" ), error ) );
       
   443 
       
   444     return error;
       
   445     }
       
   446 
       
   447    
       
   448 // -----------------------------------------------------------------------------
       
   449 // DIscChannel::HandleAsyncRequests
       
   450 // Handles asynchronous client requests
       
   451 // ( other items were commented in a header ).
       
   452 // -----------------------------------------------------------------------------
       
   453 //
       
   454 void DIscChannel::HandleAsyncRequest( 
       
   455     TInt aFunction, 
       
   456     TAny* a1 )
       
   457     {
       
   458     C_TRACE( ( _T( "DIscChannel::HandleAsyncRequest(0x%x, 0x%x) channelPtr 0x%x" ), aFunction, a1, this ) );
       
   459 
       
   460     TUint32* tablePtr = ( TUint32* )a1;
       
   461 
       
   462     switch ( aFunction )
       
   463         {
       
   464         case EIscAsyncInitializeModemInterface:
       
   465             {    
       
   466             TInt r = KErrNotFound;
       
   467             iIscRequests[EIscAsyncInitializeModemInterface] = ( TRequestStatus* )( tablePtr[ KFirstParam ] );
       
   468            
       
   469             iInitializeDfc = new TDfc( InitializeComplete, this, Kern::DfcQue0(), KIscInitializeDfcPriority );            
       
   470             ASSERT_RESET_ALWAYS( iInitializeDfc, "IscDriver",EIscMemoryAllocationFailure );
       
   471 
       
   472             // Get Data Transmission Driver initialization string
       
   473             TDesC8* tempPtr = ( TDesC8* )tablePtr[ KThirdParam ];
       
   474             iDataTransmissionBuffer = ( TUint8* )Kern::Alloc( KIscIniLineLength );
       
   475             ASSERT_RESET_ALWAYS( iDataTransmissionBuffer, "IscDriver",EIscMemoryAllocationFailure );
       
   476 
       
   477             iDataTransmissionIniData = new ( TPtr8 )( iDataTransmissionBuffer, KIscIniLineLength );
       
   478             ASSERT_RESET_ALWAYS( iDataTransmissionIniData, "IscDriver",EIscMemoryAllocationFailure );
       
   479 
       
   480             r = Kern::ThreadDesRead( iThread, tempPtr, *iDataTransmissionIniData, 0, KChunkShiftBy0 );
       
   481             ASSERT_RESET_ALWAYS( r == KErrNone, "IscDriver",EIscMemoryAllocationFailure );
       
   482 
       
   483             // Get Multiplexer initialization string
       
   484             tempPtr = ( TDesC8* )tablePtr[1];
       
   485             iMultiplexerBuffer = ( TUint8* )Kern::Alloc( KIscIniLineLength );
       
   486             ASSERT_RESET_ALWAYS( iMultiplexerBuffer, "IscDriver",EIscMemoryAllocationFailure );
       
   487 
       
   488             iMultiplexerIniData = new ( TPtr8 )( iMultiplexerBuffer, KIscIniLineLength );
       
   489             ASSERT_RESET_ALWAYS( iDataTransmissionIniData, "IscDriver",EIscMemoryAllocationFailure );
       
   490 
       
   491             r = Kern::ThreadDesRead( iThread, tempPtr, *iMultiplexerIniData, 0, KChunkShiftBy0 );
       
   492             ASSERT_RESET_ALWAYS( r == KErrNone, "IscDriver",EIscMemoryAllocationFailure );
       
   493 
       
   494             // If buffer configuration is given from isc_config.ini as multiplexer configuration string, multiplexer 
       
   495             // needs configuration before datatransmissin driver is initialized
       
   496             iIscDevice->iIscMultiplexerInterface->SetInitializationParameters( *iMultiplexerIniData );
       
   497 
       
   498             // Allocate buffers and receive queues
       
   499             iIscDevice->Initialize();
       
   500 
       
   501             iIscDevice->iIscDataTransmissionInterface->InitializeDataTransmission( *iDataTransmissionIniData, 
       
   502                                                                                    iInitializeDfc,
       
   503                                                                                    iDataTransmissionErrorCode );            
       
   504             break;
       
   505             }
       
   506             
       
   507         case EIscAsyncOpen:
       
   508             {
       
   509             iIscRequests[EIscAsyncOpen] = ( TRequestStatus* )( tablePtr[ KFirstParam ] );
       
   510             if ( iIscDevice->ConnectionStatus() == EIscConnectionOk )
       
   511                 {
       
   512                 TDesC8* openInfo = ( TDesC8* )tablePtr[ KThirdParam ];
       
   513                 // Channel info parameter has to be copied from user side in Epoc Kernel Architecture 2
       
   514                 TInt length = Kern::ThreadGetDesLength( iThread, ( TDesC8* )tablePtr[ KThirdParam ] );
       
   515                 TUint8* buffer = NULL;
       
   516                 TPtr8* bufferPtr = NULL;
       
   517                 if ( length > KErrNone )
       
   518                     {
       
   519                     C_TRACE( ( _T( "DIscChannel::HandleAsyncRequest EIscAsyncOpen channel info got" ) ) );
       
   520                     buffer = ( TUint8* )Kern::Alloc( length );
       
   521                     bufferPtr = new ( TPtr8 )( buffer, length );
       
   522                     TInt r = Kern::ThreadDesRead( iThread, openInfo, *bufferPtr, 0, KChunkShiftBy0 );
       
   523                     ASSERT_RESET_ALWAYS( r == KErrNone, "IscDriver",EIscMemoryAllocationFailure );
       
   524                     openInfo = ( TDesC8* )bufferPtr;
       
   525                     }
       
   526                 iIscDevice->iIscMultiplexerInterface->OpenDLC( ( TUint16 )tablePtr[ KSecondParam ], 
       
   527                                                                openInfo,
       
   528                                                                this );
       
   529 
       
   530                 if ( buffer )
       
   531                     Kern::Free( buffer );
       
   532                 if ( bufferPtr )
       
   533                     {
       
   534                     delete bufferPtr;
       
   535                     bufferPtr = NULL;
       
   536                     }
       
   537                 }
       
   538             else
       
   539                 {
       
   540                 CompleteRequest( aFunction, KErrNotReady );
       
   541                 }
       
   542             break;
       
   543             }
       
   544         case EIscAsyncSend:
       
   545             {
       
   546             iIscRequests[EIscAsyncSend] = ( TRequestStatus* )( tablePtr[ KFirstParam ] );
       
   547             if ( iIscDevice->ConnectionStatus() == EIscConnectionOk
       
   548                 && iULFlowControlStatus == EIscFlowControlOff )
       
   549                 {
       
   550                 TDesC8* ptr = ( TDesC8* ) tablePtr[ KSecondParam ];
       
   551 
       
   552                 // No return values check needed. Request completed with error value by multiplexer
       
   553                 iIscDevice->iIscMultiplexerInterface->Send( ( TUint16 )aFunction,
       
   554                                                             iChannelNumber, 
       
   555                                                             *ptr,
       
   556                                                             this );
       
   557                 }
       
   558             else
       
   559                 {
       
   560                 if ( iULFlowControlStatus != EIscFlowControlOff )
       
   561                     {
       
   562                     CompleteRequest( aFunction, KErrOverflow );
       
   563                     }
       
   564                 else
       
   565                     {
       
   566                     CompleteRequest( aFunction, KErrNotReady );
       
   567                     }
       
   568                 }
       
   569             break;
       
   570             }
       
   571         case EIscAsyncReceive:
       
   572             {    
       
   573             TRACE_ASSERT( tablePtr[ KFirstParam ] );
       
   574             TRACE_ASSERT( tablePtr[ KSecondParam ] );
       
   575             TRACE_ASSERT( tablePtr[ KThirdParam ] );
       
   576             
       
   577             // check for descriptor validity
       
   578             TRACE_ASSERT( Kern::ThreadGetDesMaxLength( iThread, (TPtr8* )tablePtr[KSecondParam] ) > 0 ); 
       
   579             
       
   580             //Store needed length ptr
       
   581             iNeededBufLen = ( TPtr8* )tablePtr[ KThirdParam ];
       
   582             
       
   583             //Store msg data ptr
       
   584             iReceiveBufPtr = ( TPtr8* )tablePtr[ KSecondParam ];
       
   585             
       
   586             iIscRequests[EIscAsyncReceive] = ( TRequestStatus* )( tablePtr[ KFirstParam ] );
       
   587                 
       
   588             break;
       
   589             }
       
   590         case EIscAsyncDataSend:
       
   591             {
       
   592             iIscRequests[EIscAsyncDataSend] = ( TRequestStatus* )( tablePtr[ KFirstParam ] );
       
   593                 
       
   594             if ( iIscDevice->ConnectionStatus() == EIscConnectionOk
       
   595                 && iULFlowControlStatus == EIscFlowControlOff )
       
   596                 {
       
   597                 TDesC8* ptr = ( TDesC8* )tablePtr[ KSecondParam ];
       
   598                 iIscDevice->iIscMultiplexerInterface->DataSend( ( TUint16 )aFunction,
       
   599                                                                 iChannelNumber,
       
   600                                                                 *ptr,
       
   601                                                                 this );
       
   602                 }
       
   603             else
       
   604                 {
       
   605                 if ( iULFlowControlStatus != EIscFlowControlOff )
       
   606                     {
       
   607                     CompleteRequest( aFunction, KErrOverflow );
       
   608                     }
       
   609                 else
       
   610                     {
       
   611                     CompleteRequest( aFunction, KErrNotReady );
       
   612                     }
       
   613                 }
       
   614             break;
       
   615             }
       
   616         case EIscAsyncDataReceive:
       
   617             {
       
   618             TRACE_ASSERT( tablePtr[ KFirstParam ] );
       
   619             TRACE_ASSERT( tablePtr[ KSecondParam ] );
       
   620             TRACE_ASSERT( tablePtr[ KThirdParam ] );
       
   621 
       
   622             // check for descriptor validity
       
   623             TRACE_ASSERT( Kern::ThreadGetDesMaxLength( iThread, (TPtr8* )tablePtr[KSecondParam] ) > 0 ); 
       
   624             
       
   625             //Store needed length ptr
       
   626             iNeededDataBufLen = ( TPtr8* )tablePtr[ KThirdParam ];
       
   627             
       
   628             //Store msg data ptr
       
   629             iDataReceiveBufPtr = ( TPtr8* )tablePtr[ KSecondParam ];
       
   630             
       
   631             iIscRequests[EIscAsyncDataReceive] = ( TRequestStatus* )( tablePtr[ KFirstParam ] );
       
   632                 
       
   633             break;
       
   634             }
       
   635         case EIscAsyncNotifyConnectionStatus:
       
   636             {
       
   637             iIscConnectionStatusPtr = ( TPtr8* )tablePtr[ KSecondParam ];
       
   638             iIscRequests[EIscAsyncNotifyConnectionStatus] = ( TRequestStatus* )( tablePtr[ KFirstParam ] );
       
   639             break;
       
   640             }
       
   641         case EIscAsyncNotifyFlowControlStatus:
       
   642             {
       
   643             iIscFlowControlStatusPtr = reinterpret_cast<TPtr8*>( tablePtr[ KSecondParam ] );
       
   644             iIscRequests[ EIscAsyncNotifyFlowControlStatus ] = reinterpret_cast<TRequestStatus*>( tablePtr[ KFirstParam ] );
       
   645             C_TRACE( ( _T( "DIscChannel::NotifyFlowControl iLastNotifiedULFlowstatus = %d iULFlowControlStatus = %d" ), iLastNotifiedULFlowstatus, iULFlowControlStatus ) );
       
   646             
       
   647             if( iULFlowControlStatus != iLastNotifiedULFlowstatus )
       
   648                 {
       
   649                 // Complete immediately.
       
   650                 C_TRACE( ( _T( "DIscChannel::HandleAsyncRequest iULFlowControlStatus != iLastNotifiedULFlowstatus" ) ) );
       
   651                 NotifyFlowControl( iULFlowControlStatus );    
       
   652                 }
       
   653             else
       
   654                 {
       
   655                 // None
       
   656                 }
       
   657             break;
       
   658             }
       
   659         case EIscAsyncCustomOperation1:
       
   660         case EIscAsyncCustomOperation2:
       
   661         case EIscAsyncCustomOperation3:
       
   662         case EIscAsyncCustomOperation4:
       
   663         case EIscAsyncCustomOperation5:
       
   664             {
       
   665             iIscRequests[aFunction] = ( TRequestStatus* )( tablePtr[ KFirstParam ] );
       
   666             TAny* tempPtr = ( TAny* )tablePtr[ KSecondParam ];
       
   667             iIscDevice->iIscMultiplexerInterface->CustomFunction( iChannelNumber, 
       
   668                                                              ( TUint16 )aFunction, 
       
   669                                                              tempPtr,
       
   670                                                              this );
       
   671             break;
       
   672             }
       
   673         case EIscAsyncClose:
       
   674             {
       
   675             iIscRequests[aFunction] = ( TRequestStatus* )( tablePtr[ KFirstParam ] );
       
   676 
       
   677             ResetBuffers();
       
   678             
       
   679             // Cancel all active requests except asynchronous close
       
   680             for ( TInt i( KErrNone ); i < EIscAsyncLast; i++ )
       
   681                 {
       
   682                 // if request is active complete it with KErrCancel
       
   683                 if ( iIscRequests[i] && i != EIscAsyncClose )
       
   684                     {
       
   685                     iIscDevice->iIscMultiplexerInterface->CancelNotify( iChannelNumber, i, this );
       
   686                     CompleteRequest( i, KErrCancel );
       
   687                     }
       
   688                 }            
       
   689 
       
   690             iChannelOpen = EFalse;
       
   691 
       
   692             iIscDevice->iIscMultiplexerInterface->CloseDLC( iChannelNumber, this );
       
   693             
       
   694             break;
       
   695             }
       
   696         default:
       
   697             {
       
   698             ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscUnknownCommand );
       
   699             break;
       
   700             }
       
   701         }
       
   702 
       
   703     IscChannelContainer::AddDfc();
       
   704     
       
   705     }
       
   706 
       
   707 
       
   708 // -----------------------------------------------------------------------------
       
   709 // DIscChannel::HandleSyncRequest
       
   710 // Handles synchronous client requests
       
   711 // ( other items were commented in a header ).
       
   712 // -----------------------------------------------------------------------------
       
   713 //
       
   714 TInt DIscChannel::HandleSyncRequest( 
       
   715         TInt aFunction, 
       
   716         TAny* a1 )
       
   717     {
       
   718     C_TRACE( ( _T( "DIscChannel::HandleSyncRequest(0x%x, 0x%x) channelPtr 0x%x" ), aFunction, a1, this ) );
       
   719 
       
   720     TInt error( KErrNone );
       
   721     TUint32* tablePtr = ( TUint32* )a1;
       
   722 
       
   723     switch ( aFunction )
       
   724         {
       
   725         case EIscSyncClose:
       
   726             {
       
   727             ResetBuffers();
       
   728             
       
   729             iIscDevice->iIscMultiplexerInterface->CloseDLC( iChannelNumber, this );
       
   730             
       
   731             // Cancel all active requests 
       
   732             for ( TInt i( KErrNone ); i < EIscAsyncLast; i++ )
       
   733                 {
       
   734                 // if request is active complete it with KErrCancel
       
   735                 if ( iIscRequests[i] )
       
   736                     {
       
   737                     iIscDevice->iIscMultiplexerInterface->CancelNotify( iChannelNumber, i, this );
       
   738                     CompleteRequest( i, KErrCancel );
       
   739                     }
       
   740                 }
       
   741 
       
   742             error = KErrNone;
       
   743             iChannelOpen = EFalse;
       
   744             break;
       
   745             }
       
   746         case EIscSyncSend:
       
   747             {
       
   748             if ( iIscDevice->ConnectionStatus() == EIscConnectionOk 
       
   749                 && iULFlowControlStatus == EIscFlowControlOff ) 
       
   750                 {
       
   751                 
       
   752                 TDesC8* ptr = ( TDesC8* ) tablePtr[ KFirstParam ];
       
   753                 error = iIscDevice->iIscMultiplexerInterface->Send( ( TUint16 )aFunction,
       
   754                                                             iChannelNumber, 
       
   755                                                             *ptr,
       
   756                                                             this );
       
   757                 }
       
   758             else
       
   759                 {
       
   760                 if ( iULFlowControlStatus != EIscFlowControlOff )
       
   761                     {
       
   762                     error = KErrOverflow;
       
   763                     }
       
   764                 else
       
   765                     {
       
   766                     error = KErrNotReady;
       
   767                     }
       
   768                 }
       
   769             break;
       
   770             }
       
   771         case EIscSyncDataSend:
       
   772             {
       
   773             if ( iIscDevice->ConnectionStatus() == EIscConnectionOk 
       
   774                 && iULFlowControlStatus == EIscFlowControlOff ) 
       
   775                 {
       
   776                 TDesC8* ptr = ( TDesC8* ) tablePtr[ KFirstParam ];
       
   777                 error = iIscDevice->iIscMultiplexerInterface->DataSend( ( TUint16 )aFunction,
       
   778                                                                 iChannelNumber,
       
   779                                                                 *ptr,
       
   780                                                                 this );
       
   781                 }
       
   782             else
       
   783                 {
       
   784                 if ( iULFlowControlStatus != EIscFlowControlOff )
       
   785                     {
       
   786                     error = KErrOverflow;
       
   787                     }
       
   788                 else
       
   789                     {
       
   790                     error = KErrNotReady;
       
   791                     }
       
   792                 }
       
   793             break;
       
   794             }
       
   795         case EIscSyncGetConnectionStatus:
       
   796             {
       
   797             error = iIscDevice->ConnectionStatus();
       
   798             break;
       
   799             }
       
   800         case EIscSyncGetFlowControlStatus:
       
   801             {
       
   802             error = iULFlowControlStatus;
       
   803             break;
       
   804             }
       
   805         case EIscSyncGetChannelInfo:
       
   806             {
       
   807             TDes8* tempPtr = ( TDes8* ) tablePtr[1];
       
   808             error = iIscDevice->iIscMultiplexerInterface->GetChannelInfo( ( TUint16 )tablePtr[ KFirstParam ],
       
   809                                                                   *tempPtr );
       
   810             break;
       
   811             }
       
   812         case EIscSyncGetMaximunDataSize:
       
   813             {
       
   814             error = iIscDevice->iIscMultiplexerInterface->MaximumDataSize( iChannelNumber );
       
   815             break;
       
   816             }
       
   817         case EIscSyncCustomOperation1:
       
   818         case EIscSyncCustomOperation2:
       
   819         case EIscSyncCustomOperation3:
       
   820         case EIscSyncCustomOperation4:
       
   821         case EIscSyncCustomOperation5:
       
   822             {
       
   823             TAny* tempPtr = ( TAny* )tablePtr[ KFirstParam ];
       
   824             error = iIscDevice->iIscMultiplexerInterface->CustomFunction( iChannelNumber,
       
   825                                                                      ( TUint16 )aFunction, 
       
   826                                                                      tempPtr,
       
   827                                                                      this );
       
   828             break;
       
   829             }
       
   830         case EIscSyncResetBuffers:
       
   831             {
       
   832             ResetBuffers();
       
   833             error = KErrNone;
       
   834             break;
       
   835             }
       
   836         default:
       
   837             {
       
   838             ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscUnknownCommand );
       
   839             break;
       
   840             }
       
   841         }
       
   842     return error;
       
   843     }
       
   844 
       
   845 // -----------------------------------------------------------------------------
       
   846 // DIscChannel::HandleCancelRequest
       
   847 // Cancels active request
       
   848 // ( other items were commented in a header ).
       
   849 // -----------------------------------------------------------------------------
       
   850 //
       
   851 TInt DIscChannel::HandleCancelRequest( 
       
   852     TInt aFunction, 
       
   853     TAny* /*a1*/ )
       
   854     {
       
   855     C_TRACE( ( _T( "DIscChannel::HandleCancelRequest(0x%x)" ), aFunction ) );
       
   856 
       
   857     TUint16 operationToCancel( 0 );
       
   858     switch ( aFunction )
       
   859         {
       
   860         
       
   861         case EIscCancelAsyncInitialize:
       
   862             {
       
   863             if ( iDataTransmissionIniData )
       
   864                 {
       
   865                 Kern::Free( iDataTransmissionBuffer );
       
   866                 delete iDataTransmissionIniData;
       
   867                 iDataTransmissionIniData = NULL;
       
   868                 }
       
   869             if ( iMultiplexerIniData )
       
   870                 {
       
   871                 Kern::Free( iMultiplexerBuffer );
       
   872                 delete iMultiplexerIniData;
       
   873                 iMultiplexerIniData = NULL; 
       
   874                 }
       
   875 
       
   876             operationToCancel = EIscAsyncInitializeModemInterface;
       
   877             break;
       
   878             }
       
   879         case EIscCancelAsyncOpen:
       
   880             {
       
   881             if ( KRequestPending == IsPending( EIscAsyncOpen ) )
       
   882                 {
       
   883                 iChannelOpen = EFalse;
       
   884                 }            
       
   885             operationToCancel = EIscAsyncOpen;
       
   886             break;
       
   887             }
       
   888         case EIscCancelAsyncSend:
       
   889             {
       
   890             operationToCancel = EIscAsyncSend;
       
   891             // Cancel sending / empty send queues
       
   892             iIscDevice->CancelSending( iChannelNumber, this );
       
   893             break;
       
   894             }
       
   895         case EIscCancelAsyncDataSend:
       
   896             {
       
   897             operationToCancel = EIscAsyncDataSend;
       
   898             // Cancel sending / empty send queues
       
   899             iIscDevice->CancelSending( iChannelNumber, this );
       
   900             break;
       
   901             }
       
   902         
       
   903         case EIscCancelAsyncReceive:
       
   904             {
       
   905             iReceiveBufPtr = NULL;
       
   906             iNeededBufLen = NULL;
       
   907             operationToCancel = EIscAsyncReceive;
       
   908             break;
       
   909             }
       
   910         
       
   911         case EIscCancelAsyncDataReceive:
       
   912             {
       
   913             iDataReceiveBufPtr = NULL;
       
   914             iNeededDataBufLen = NULL;
       
   915             operationToCancel = EIscAsyncDataReceive;
       
   916             break;
       
   917             }
       
   918         
       
   919         case EIscCancelAsyncNotifyConnection:
       
   920             {
       
   921             iIscConnectionStatusPtr = NULL;
       
   922             operationToCancel = EIscAsyncNotifyConnectionStatus;
       
   923             break;
       
   924             }
       
   925         
       
   926         case EIscCancelAsyncNotifyFlowControl:
       
   927             {
       
   928             iIscFlowControlStatusPtr = NULL;
       
   929             operationToCancel = EIscAsyncNotifyFlowControlStatus;
       
   930             break;
       
   931             }
       
   932         case EIscCancelAsyncCustomOperation1:
       
   933             {
       
   934             operationToCancel = EIscAsyncCustomOperation1;
       
   935             break;
       
   936             }
       
   937         case EIscCancelAsyncCustomOperation2:
       
   938             {
       
   939             operationToCancel = EIscAsyncCustomOperation2;
       
   940             break;
       
   941             }
       
   942         case EIscCancelAsyncCustomOperation3:
       
   943             {
       
   944             operationToCancel = EIscAsyncCustomOperation3;
       
   945             break;
       
   946             }
       
   947         case EIscCancelAsyncCustomOperation4:
       
   948             {
       
   949             operationToCancel = EIscAsyncCustomOperation4;
       
   950             break;
       
   951             }
       
   952         case EIscCancelAsyncCustomOperation5:
       
   953             {
       
   954             operationToCancel = EIscAsyncCustomOperation5;
       
   955             break;
       
   956             }
       
   957         case EIscCancelAsyncClose:
       
   958             {
       
   959             TRACE_ASSERT_ALWAYS;
       
   960             operationToCancel = EIscAsyncClose;
       
   961             break;
       
   962             }
       
   963         default:
       
   964             {
       
   965             ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscUnknownCommand );
       
   966             break;
       
   967             }
       
   968         }
       
   969 
       
   970     iIscDevice->iIscMultiplexerInterface->CancelNotify( iChannelNumber, ( TUint16 )operationToCancel, this );
       
   971     CompleteRequest( operationToCancel, KErrCancel );
       
   972 
       
   973     return KErrNone;
       
   974     }
       
   975 
       
   976 // -----------------------------------------------------------------------------
       
   977 // DIscChannel::DoCreate
       
   978 // Secondary initialization of channel
       
   979 // ( other items were commented in a header ).
       
   980 // -----------------------------------------------------------------------------
       
   981 //
       
   982 TInt DIscChannel::DoCreate( 
       
   983     TInt aUnit, 
       
   984     const TDesC8* anInfo, 
       
   985     const TVersion& /*aVer*/ )
       
   986     {
       
   987     C_TRACE( ( _T( "DIscChannel::DoCreate(0x%x, 0x%x, 0x%x)" ), aUnit, anInfo, this ) );
       
   988     if ( !Kern::CurrentThreadHasCapability( ECapabilityCommDD,__PLATSEC_DIAGNOSTIC_STRING
       
   989         ( "Checked by ISCDRIVER.LDD ( Inter-System Communication Driver )" ) ) )
       
   990         {
       
   991         return KErrPermissionDenied;
       
   992         }    
       
   993     TUint16 channelNumber = ( TUint16 )aUnit;
       
   994     if ( anInfo )
       
   995         {
       
   996         // check for channel number inside anInfo
       
   997         TUint8 channel = ( TUint8 )( *anInfo )[0];
       
   998         if ( channel >= KIscMaxChannelsInLdd )
       
   999             {
       
  1000             channelNumber += KIscMaxChannelsInLdd;
       
  1001             }
       
  1002         C_TRACE( ( _T( "DIscChannel::DoCreate channel=0x%x" ), channelNumber ) );
       
  1003         }
       
  1004 
       
  1005     if ( channelNumber != KIscControlChannel )
       
  1006         {
       
  1007         TIscConfiguration config;
       
  1008         iIscDevice->iIscMultiplexerInterface->GetConfiguration( config );
       
  1009         TInt i( KErrNone );
       
  1010         iFrameRx = new TUint32*[config.channelRcvQueueSize];
       
  1011         ASSERT_RESET_ALWAYS( iFrameRx, "IscDriver",EIscMemoryAllocationFailure );
       
  1012         for ( i = KErrNone; i < config.channelRcvQueueSize; i++ )
       
  1013             {
       
  1014             iFrameRx[i] = 0;
       
  1015             }
       
  1016 
       
  1017         iDataFrameRx = new TUint32*[config.channelDataRcvQueueSize];
       
  1018         ASSERT_RESET_ALWAYS( iDataFrameRx, "IscDriver",EIscMemoryAllocationFailure );
       
  1019         for ( i = KErrNone; i < config.channelDataRcvQueueSize; i++ )
       
  1020             {
       
  1021             iDataFrameRx[i] = 0;
       
  1022             }
       
  1023 
       
  1024         // creating frame queue for incoming frames
       
  1025         iFrameRxQueue = new  DIscQueue( iFrameRx, config.channelRcvQueueSize );
       
  1026         ASSERT_RESET_ALWAYS( iFrameRxQueue, "IscDriver",EIscMemoryAllocationFailure );
       
  1027 
       
  1028         // creating frame queue for incoming data frames
       
  1029         iDataFrameRxQueue = new  DIscQueue( iDataFrameRx, config.channelDataRcvQueueSize );
       
  1030         ASSERT_RESET_ALWAYS( iDataFrameRxQueue, "IscDriver",EIscMemoryAllocationFailure );
       
  1031     
       
  1032         // Flowcontrol marks for data frames
       
  1033         iIscChannelHighWaterMark = ( TUint16 )( ( ( ( TUint16 )config.channelDataRcvQueueSize ) * KMultiplyByThree ) / KDivideByFour );// 75% = multiply with 3, divide by 4 
       
  1034         iIscChannelLowWaterMark =  ( TUint16 )( ( ( ( TUint16 )config.channelDataRcvQueueSize ) * KMultiplyByOne ) / KDivideByFour );// 25% = multiply with 1, divide by 4 
       
  1035     
       
  1036         TRACE_ASSERT( iIscChannelHighWaterMark != 0 );
       
  1037         }
       
  1038 
       
  1039 #ifndef ISC_CHANNEL_SHARING_IN_USE
       
  1040     // Remove checking if channel already set to enable channel sharing
       
  1041     //Check if channel already set
       
  1042     if ( IscChannelContainer::Channel( channelNumber, 0 ) )
       
  1043         {
       
  1044         C_TRACE( ( _T( "DIscChannel::DoCreate channel 0x%x already set!!!!" ), channelNumber ) );
       
  1045         return KErrAlreadyExists;
       
  1046         }
       
  1047 #endif //ISC_CHANNEL_SHARING_IN_USE
       
  1048 
       
  1049     //Add itself to channel table.
       
  1050     TInt error = IscChannelContainer::SetChannel( ( DIscChannel* )this, channelNumber );
       
  1051     if ( KErrNone != error )
       
  1052         {
       
  1053         return error;
       
  1054         }
       
  1055 
       
  1056     iChannelOpen = ETrue;
       
  1057     
       
  1058     // Store channel number.
       
  1059     iChannelNumber = channelNumber;    
       
  1060     SetDfcQ( Kern::DfcQue0() );
       
  1061     iMsgQ.Receive();
       
  1062     
       
  1063     return KErrNone;
       
  1064 
       
  1065     }
       
  1066 
       
  1067 
       
  1068 // -----------------------------------------------------------------------------
       
  1069 // DIscChannel::NotifyFlowControl
       
  1070 // Notify user side client that uplink flow control is on/off
       
  1071 // ( other items were commented in a header ).
       
  1072 // -----------------------------------------------------------------------------
       
  1073 //
       
  1074 void DIscChannel::NotifyFlowControl
       
  1075         ( 
       
  1076         const TInt aFlowControlStatus
       
  1077         )
       
  1078     {
       
  1079     C_TRACE( ( _T( "DIscChannel::NotifyFlowControl(0x%x) iChannelNumber 0x%x channelPtr 0x%x" ), aFlowControlStatus, iChannelNumber, this ) );
       
  1080 
       
  1081     iULFlowControlStatus = aFlowControlStatus;
       
  1082     if( iIscRequests[ EIscAsyncNotifyFlowControlStatus ]
       
  1083         && iIscFlowControlStatusPtr )
       
  1084         {
       
  1085         TPtr8 tempDes( reinterpret_cast<TUint8*>( &iULFlowControlStatus ), sizeof ( TInt ), sizeof ( TInt ) );
       
  1086         iLastNotifiedULFlowstatus = aFlowControlStatus;
       
  1087         TInt r = ThreadWrite( static_cast<TAny*>( iIscFlowControlStatusPtr ), &tempDes, 0 );
       
  1088         TRACE_ASSERT( r == KErrNone ); 
       
  1089         CompleteRequest( EIscAsyncNotifyFlowControlStatus, r );
       
  1090         }
       
  1091     else
       
  1092         {
       
  1093         C_TRACE( ( _T( "DIscChannel::NotifyFlowControl No request pending!" ) ) );        
       
  1094         }
       
  1095     }
       
  1096 
       
  1097 // -----------------------------------------------------------------------------
       
  1098 // DIscChannel::NotifyConnectionStatus
       
  1099 // Notify user side client that connection status has changed
       
  1100 // ( other items were commented in a header ).
       
  1101 // -----------------------------------------------------------------------------
       
  1102 //
       
  1103 void DIscChannel::NotifyConnectionStatus( 
       
  1104     const TInt aConnectionStatus ) 
       
  1105     {
       
  1106     C_TRACE( ( _T( "DIscChannel::NotifyConnectionStatus(0x%x) channelPtr 0x%x" ), aConnectionStatus, this ) );
       
  1107 
       
  1108     if ( iIscRequests[EIscAsyncNotifyConnectionStatus] 
       
  1109          && iIscConnectionStatusPtr )
       
  1110         {
       
  1111         TInt temp = aConnectionStatus;
       
  1112         TPtr8 tempDes( ( TUint8* )&temp,sizeof ( TInt ),sizeof ( TInt ) );
       
  1113         TInt r = ThreadWrite( ( TAny* )iIscConnectionStatusPtr, &tempDes, 0 );
       
  1114         TRACE_ASSERT( r == KErrNone );
       
  1115 
       
  1116         CompleteRequest( EIscAsyncNotifyConnectionStatus, r );
       
  1117         }
       
  1118     }
       
  1119 
       
  1120 // -----------------------------------------------------------------------------
       
  1121 // DIscChannel::IsPending
       
  1122 // Check if asynchronous request is active
       
  1123 // ( other items were commented in a header ).
       
  1124 // -----------------------------------------------------------------------------
       
  1125 //
       
  1126 TInt DIscChannel::IsPending( 
       
  1127     const TUint16 aReqNumber )
       
  1128     {
       
  1129     TInt error( KErrNone );
       
  1130     if ( iIscRequests[aReqNumber] )
       
  1131         {
       
  1132         error = KRequestPending;
       
  1133         }
       
  1134     else
       
  1135         {
       
  1136         // error is KErrNone
       
  1137         }
       
  1138     return error;
       
  1139     }
       
  1140 // -----------------------------------------------------------------------------
       
  1141 // DIscChannel::CompleteRequest
       
  1142 // Function to complete clients pending asynchronous request
       
  1143 // ( other items were commented in a header ).
       
  1144 // -----------------------------------------------------------------------------
       
  1145 //
       
  1146 void DIscChannel::CompleteRequest( 
       
  1147     TInt aOperation, 
       
  1148     TInt aCompleteStatus )
       
  1149     {
       
  1150     C_TRACE( ( _T( "DIscChannel::CompleteRequest(0x%x, 0x%x) iChannelNumber 0x%x channelPtr 0x%x" ), aOperation, aCompleteStatus, iChannelNumber, this ) );
       
  1151   
       
  1152     if ( aOperation < EIscAsyncLast )
       
  1153         {
       
  1154         
       
  1155         TRequestStatus* requestStatus = iIscRequests[aOperation];
       
  1156         if ( requestStatus )
       
  1157             {        
       
  1158             // In case of higher priority thread, set request to NULL from the request table before actual completing
       
  1159             iIscRequests[aOperation] = NULL;
       
  1160             Kern::RequestComplete( iThread, requestStatus, aCompleteStatus );
       
  1161             }
       
  1162         }
       
  1163     else
       
  1164         {
       
  1165         // Do nothing
       
  1166         }
       
  1167 
       
  1168     C_TRACE( ( _T( "DIscChannel::CompleteRequest - return void" ) ) );
       
  1169 
       
  1170     }
       
  1171 
       
  1172 // -----------------------------------------------------------------------------
       
  1173 // DIscChannel::InitializeComplete
       
  1174 // Initialization complete dfc
       
  1175 // ( other items were commented in a header ).
       
  1176 // -----------------------------------------------------------------------------
       
  1177 //
       
  1178 void DIscChannel::InitializeComplete( 
       
  1179     TAny* aPtr )
       
  1180     {
       
  1181     C_TRACE( ( _T( "DIscChannel::InitializeComplete(0x%x)" ), aPtr ) );
       
  1182 
       
  1183     DIscChannel* ThisPtr = ( DIscChannel* )aPtr;
       
  1184     if ( KErrNone == ThisPtr->iDataTransmissionErrorCode )
       
  1185         {        
       
  1186         ThisPtr->DoMultiplexerInitialize();
       
  1187         }
       
  1188     else
       
  1189         {
       
  1190         ThisPtr->CompleteRequest( EIscAsyncInitializeModemInterface, ThisPtr->iDataTransmissionErrorCode );
       
  1191         }
       
  1192     C_TRACE( ( _T( "DIscChannel::InitializeComplete - return 0x%x" ) ) );
       
  1193 
       
  1194     }
       
  1195 
       
  1196 // -----------------------------------------------------------------------------
       
  1197 // DIscChannel::DoMultiplexerInitialize
       
  1198 // Completes the multiplexer initialization
       
  1199 // ( other items were commented in a header ).
       
  1200 // -----------------------------------------------------------------------------
       
  1201 //
       
  1202 void DIscChannel::DoMultiplexerInitialize()
       
  1203     {
       
  1204     C_TRACE( ( _T( "DIscChannel::DoMultiplexerInitialize() channelPtr 0x%x" ), this ) );
       
  1205     
       
  1206     if ( iIscRequests[EIscAsyncInitializeModemInterface] )
       
  1207         {
       
  1208         
       
  1209         iIscDevice->iIscMultiplexerInterface->InitializeMultiplexer( 
       
  1210                 EIscAsyncInitializeModemInterface, 
       
  1211                 *iMultiplexerIniData,
       
  1212                 this );
       
  1213         }
       
  1214 
       
  1215     C_TRACE( ( _T( "DIscChannel::DoMultiplexerInitialize - return void" ) ) );
       
  1216     }
       
  1217 
       
  1218 // -----------------------------------------------------------------------------
       
  1219 // DIscChannel::StoreFrame
       
  1220 // Stores the incoming frame to channels receive queue
       
  1221 // ( other items were commented in a header ).
       
  1222 // -----------------------------------------------------------------------------
       
  1223 //
       
  1224 void DIscChannel::StoreFrame( TDesC8* aData )
       
  1225     {
       
  1226     C_TRACE( ( _T( "DIscChannel::StoreFrame(0x%x) channelId 0x%x channelPtr 0x%x" ), aData, iChannelNumber, this ) );
       
  1227     
       
  1228     TInt error( KErrNone );
       
  1229 
       
  1230     TIscFrameInfo frameInfo;
       
  1231     iIscDevice->iIscMultiplexerInterface->GetFrameInfo( *aData, frameInfo );
       
  1232 
       
  1233     if ( frameInfo.frameType == EIscDataFrame )
       
  1234         {
       
  1235         C_TRACE( ( _T( "DIscChannel::StoreFrame dataFrame" ) ) );
       
  1236         error = iDataFrameRxQueue->Add( ( TAny* )aData );
       
  1237         if ( error == KErrNone )
       
  1238             {
       
  1239             if ( iDataFrameRxQueue->Count() >= iIscChannelHighWaterMark 
       
  1240                 && iDLFlowControlStatus == EIscFlowControlOff )
       
  1241                 {
       
  1242                 iIscDevice->DLFlowControlNotify( EIscFlowControlOn, iChannelNumber, this );
       
  1243                 iDLFlowControlStatus = EIscFlowControlOn;
       
  1244                 }
       
  1245             else if ( iDataFrameRxQueue->Count() <= iIscChannelLowWaterMark 
       
  1246                      && iDLFlowControlStatus != EIscFlowControlOff )
       
  1247                 {
       
  1248                 iIscDevice->DLFlowControlNotify( EIscFlowControlOff, iChannelNumber, this );
       
  1249                 iDLFlowControlStatus = EIscFlowControlOff;
       
  1250                 }
       
  1251             else
       
  1252                 {
       
  1253                 // Do nothing
       
  1254                 }
       
  1255             }
       
  1256         else
       
  1257             {
       
  1258             // Set overflow flag on. Complete next DataReceive with KErrOverFlow
       
  1259             TRACE_ASSERT_ALWAYS;
       
  1260             iOverFlow = ETrue;
       
  1261             iIscDevice->ReleaseMemoryBlock( ( TDes8* )aData );
       
  1262             }
       
  1263         }
       
  1264 
       
  1265     else
       
  1266         {
       
  1267         C_TRACE( ( _T( "DIscChannel::StoreFrame controlFrame" ) ) );
       
  1268         error = iFrameRxQueue->Add( ( TAny* )aData );
       
  1269         if ( error != KErrNone )
       
  1270             {
       
  1271             C_TRACE( ( _T( "DIscChannel::StoreFrame() CONTROL FRAME OVERFLOW channel %d" ), iChannelNumber ) );
       
  1272             TRACE_ASSERT_ALWAYS;
       
  1273             iClientPanic = ETrue;
       
  1274             iIscDevice->ReleaseMemoryBlock( ( TDes8* )aData );
       
  1275             }
       
  1276         }
       
  1277 
       
  1278     C_TRACE( ( _T( "DIscChannel::StoreFrame - return void" ) ) );
       
  1279     }
       
  1280 
       
  1281 // -----------------------------------------------------------------------------
       
  1282 // DIscChannel::EmptyBuffers
       
  1283 // Goes through channel's queue and delivers possible frame( s ) to client
       
  1284 // ( other items were commented in a header ).
       
  1285 // -----------------------------------------------------------------------------
       
  1286 //
       
  1287 void DIscChannel::EmptyBuffers()
       
  1288     {    
       
  1289     C_TRACE( ( _T( "DIscChannel::EmptyBuffers() channelId 0x%x channelPtr 0x%x" ),iChannelNumber, this ) );
       
  1290 
       
  1291     if ( iDataFrameRxQueue->NextBufferLength() > KErrNone )
       
  1292         {
       
  1293         TDes8* tempPtr = ( TDes8* ) iDataFrameRxQueue->GetFirst();
       
  1294         TIscFrameInfo frameInfo;
       
  1295         TInt desMaxLen( KErrNone );
       
  1296  
       
  1297         iIscDevice->iIscMultiplexerInterface->GetFrameInfo( *tempPtr, frameInfo );
       
  1298         
       
  1299         // frame incoming, and datareceive request active
       
  1300         if ( iIscRequests[EIscAsyncDataReceive] && frameInfo.frameType == EIscDataFrame )             
       
  1301             {
       
  1302             if ( frameInfo.concatenation == EIscNoConcatenation )
       
  1303                 {
       
  1304                 desMaxLen = Kern::ThreadGetDesMaxLength( iThread, iDataReceiveBufPtr );                    
       
  1305 
       
  1306                 C_TRACE( ( _T( "DIscChannel::EmptyBuffers() data desMaxLen %d" ),desMaxLen ) );
       
  1307 
       
  1308                 TRACE_ASSERT( desMaxLen > KErrNone );
       
  1309                 
       
  1310                 // check that client's memory block is big enough
       
  1311                 if ( desMaxLen >= frameInfo.writeLength )
       
  1312                     {
       
  1313                     // create a temporary descriptor for writing since we're
       
  1314                     // necessary not writing the whole contents of the 
       
  1315                     // source descriptor, only the part that ISC Multiplexer
       
  1316                     // wants
       
  1317                     TPtr8 writePtr( ( TUint8* )( tempPtr->Ptr() + frameInfo.writeStartIndex ),
       
  1318                                     frameInfo.writeLength,
       
  1319                                     frameInfo.writeLength );
       
  1320 
       
  1321                     TInt r = ThreadWrite( iDataReceiveBufPtr, &writePtr, 0 );
       
  1322 
       
  1323                     TRACE_ASSERT( r == KErrNone );
       
  1324                     
       
  1325                     // remove the pointer from queue and release the memory block 
       
  1326                     // but only if the ThreadWrite was successfull
       
  1327                     if  ( r == KErrNone )
       
  1328                         {
       
  1329                         iDataFrameRxQueue->DeleteFirst();
       
  1330                         iIscDevice->ReleaseMemoryBlock( tempPtr );
       
  1331                         if ( iOverFlow )
       
  1332                             {
       
  1333                             iOverFlow = EFalse;
       
  1334                             CompleteRequest( EIscAsyncDataReceive, KErrOverflow );
       
  1335                             }
       
  1336                         else
       
  1337                             {
       
  1338                             CompleteRequest( EIscAsyncDataReceive, KErrNone );
       
  1339                             }
       
  1340                         }
       
  1341                     else
       
  1342                         {
       
  1343                         C_TRACE( ( _T( "DIscChannel::EmptyBuffers() data ThreadWrite %d" ), r ) );
       
  1344                         CompleteRequest( EIscAsyncDataReceive, r );
       
  1345                         }
       
  1346                     }
       
  1347                 // client buffer too small
       
  1348                 else
       
  1349                     {
       
  1350                     TUint16 tempLen( frameInfo.writeLength );
       
  1351                     TPtr8 tempLenDes( ( TUint8* )&tempLen, sizeof ( TUint16 ), sizeof ( TUint16 ) );
       
  1352                     
       
  1353                     TInt r = ThreadWrite( ( TAny* )iNeededDataBufLen, &tempLenDes, 0 );
       
  1354                     TRACE_ASSERT( r == KErrNone );
       
  1355                     if ( r != KErrNone ) 
       
  1356                         {
       
  1357                         C_TRACE( ( _T( "DIscChannel::EmptyBuffers() data ThreadWrite %d" ), r ) );
       
  1358                         }
       
  1359                     
       
  1360                     CompleteRequest( EIscAsyncDataReceive, KErrNoMemory );
       
  1361                     }
       
  1362                 }
       
  1363             else
       
  1364                 {
       
  1365                 HandleConcatenatedDataFrame( tempPtr, frameInfo );
       
  1366                 }
       
  1367             }
       
  1368         }
       
  1369         // no frames in data queue
       
  1370     else
       
  1371         {
       
  1372         C_TRACE( ( _T( "DIscChannel::EmptyBuffers() channelId 0x%x channelPtr No frames in data queue" ), iChannelNumber, this ) );
       
  1373         }
       
  1374 
       
  1375     // Check if there is frame in queue
       
  1376     if ( iFrameRxQueue->NextBufferLength() > KErrNone )
       
  1377         {
       
  1378         TDes8* tempPtr = ( TDes8* ) iFrameRxQueue->GetFirst();
       
  1379         TIscFrameInfo frameInfo;
       
  1380         TInt desMaxLen( KErrNone );
       
  1381  
       
  1382         iIscDevice->iIscMultiplexerInterface->GetFrameInfo( *tempPtr, frameInfo );
       
  1383     
       
  1384         // frame incoming and normal receive request active
       
  1385         if ( iIscRequests[EIscAsyncReceive] && frameInfo.frameType == EIscNonDataFrame )
       
  1386             {
       
  1387             if ( frameInfo.concatenation == EIscNoConcatenation )
       
  1388                 {
       
  1389                 desMaxLen = Kern::ThreadGetDesMaxLength( iThread, iReceiveBufPtr );
       
  1390                 
       
  1391                 C_TRACE( ( _T( "DIscChannel::EmptyBuffers() desMaxLen %d" ),desMaxLen ) );
       
  1392 
       
  1393                 TRACE_ASSERT( desMaxLen > KErrNone );
       
  1394 
       
  1395                 // check that client's memory block is big enough
       
  1396                 if ( desMaxLen >= frameInfo.writeLength )
       
  1397                     {
       
  1398                     // create a temporary descriptor for writing since we're
       
  1399                     // necessary not writing the whole contents of the 
       
  1400                     // source descriptor, only the part that ISC Multiplexer
       
  1401                     // wants
       
  1402                     TPtr8 writePtr( ( TUint8* )( tempPtr->Ptr() + frameInfo.writeStartIndex ),
       
  1403                                     frameInfo.writeLength,
       
  1404                                     frameInfo.writeLength );
       
  1405                     
       
  1406                     TInt r = ThreadWrite( iReceiveBufPtr, &writePtr, 0 );
       
  1407 
       
  1408                     TRACE_ASSERT( r == KErrNone );
       
  1409                     
       
  1410                     // remove the pointer from queue and release the memory block 
       
  1411                     // but only if the ThreadWrite was successfull
       
  1412                     if ( r == KErrNone )
       
  1413                         {
       
  1414                         iFrameRxQueue->DeleteFirst();
       
  1415                         iIscDevice->ReleaseMemoryBlock( tempPtr );
       
  1416                         if ( iClientPanic )
       
  1417                             {
       
  1418                             iClientPanic = EFalse;
       
  1419                             CompleteRequest( EIscAsyncReceive, KErrOverflow );                            
       
  1420                             }
       
  1421                         else
       
  1422                             {
       
  1423                             CompleteRequest( EIscAsyncReceive, KErrNone );
       
  1424                             }
       
  1425                         }
       
  1426                     else
       
  1427                         {
       
  1428                         C_TRACE( ( _T( "DIscChannel::EmptyBuffers() ThreadWrite %d" ), r ) );
       
  1429                         CompleteRequest( EIscAsyncReceive, r );
       
  1430                         }
       
  1431                     }
       
  1432                 // client buffer too small
       
  1433                 else
       
  1434                     {
       
  1435                     TUint16 tempLen = frameInfo.writeLength;
       
  1436                     TPtr8 tempLenDes( ( TUint8* )&tempLen, sizeof ( TUint16 ), sizeof ( TUint16 ) );
       
  1437                     
       
  1438                     TInt r = ThreadWrite ( ( TAny* )iNeededBufLen, &tempLenDes, 0 );
       
  1439                     TRACE_ASSERT( r == KErrNone );
       
  1440                     if ( r != KErrNone ) 
       
  1441                         {
       
  1442                         C_TRACE( ( _T( "DIscChannel::EmptyBuffers() ThreadWrite %d" ), r ) );
       
  1443                         }
       
  1444                     
       
  1445                     CompleteRequest( EIscAsyncReceive, KErrNoMemory );
       
  1446                     }
       
  1447                 }
       
  1448             else
       
  1449                 {
       
  1450                 HandleConcatenatedFrame( tempPtr, frameInfo );
       
  1451                 }
       
  1452             }
       
  1453         }
       
  1454     // no frames in queue
       
  1455     else
       
  1456         {
       
  1457         C_TRACE( ( _T( "DIscChannel::EmptyBuffers() channelId 0x%x channelPtr 0x%x No frames in queue" ), iChannelNumber, this ) );
       
  1458         }
       
  1459 
       
  1460     // If possible, set flow control off from data frame receiving
       
  1461     if ( iDataFrameRxQueue->Count() <= iIscChannelLowWaterMark 
       
  1462          && iDLFlowControlStatus != EIscFlowControlOff )
       
  1463         {
       
  1464         iIscDevice->DLFlowControlNotify( EIscFlowControlOff, iChannelNumber, this );
       
  1465         iDLFlowControlStatus = EIscFlowControlOff;
       
  1466         }
       
  1467         
       
  1468 
       
  1469     C_TRACE( ( _T( "DIscChannel::EmptyBuffers - return void" ) ) );
       
  1470 
       
  1471     }
       
  1472 
       
  1473 // -----------------------------------------------------------------------------
       
  1474 // DIscChannel::HandleConcatenatedDataFrame
       
  1475 // Copies several data frames to clients buffer if needed before compliting receive request
       
  1476 // ( other items were commented in a header ).
       
  1477 // -----------------------------------------------------------------------------
       
  1478 //
       
  1479 void DIscChannel::HandleConcatenatedDataFrame( TDes8* aPtr, TIscFrameInfo& aInfo )
       
  1480     {
       
  1481     C_TRACE( ( _T( "DIscChannel::HandleConcatenatedDataFrame(0x%x, 0x%x) channelPtr 0x%x" ), aPtr, &aInfo, this ) );
       
  1482     TInt desMaxLen( KErrNone );
       
  1483     TInt desLen( KErrNone );
       
  1484     TUint16 totalLength( 0 );
       
  1485 
       
  1486     desMaxLen = Kern::ThreadGetDesMaxLength( iThread, iDataReceiveBufPtr );
       
  1487     desLen = Kern::ThreadGetDesLength( iThread, iDataReceiveBufPtr );
       
  1488     
       
  1489     if ( aInfo.totalLength > KErrNone )
       
  1490         {
       
  1491         totalLength = aInfo.totalLength;
       
  1492         }
       
  1493     else
       
  1494         { 
       
  1495         totalLength = desMaxLen;
       
  1496         }
       
  1497     switch ( aInfo.concatenation )
       
  1498         {
       
  1499         // first frame of a larger data chunk
       
  1500         case EIscConcatenationDataStart:
       
  1501             {
       
  1502             // check whether the whole data amount will fit into the user buffer
       
  1503             if ( desMaxLen >= ( desLen + aInfo.writeLength ) && desMaxLen >= totalLength )
       
  1504                 {
       
  1505                 // create a temporary descriptor for writing since we're
       
  1506                 // necessary not writing the whole contents of the 
       
  1507                 // source descriptor, only the part that ISC Multiplexer
       
  1508                 // wants
       
  1509                 TPtr8 writePtr( ( TUint8* )( aPtr->Ptr() + aInfo.writeStartIndex ),
       
  1510                                 aInfo.writeLength,
       
  1511                                 aInfo.writeLength );
       
  1512                 
       
  1513                 // start writing the data at offset 0 since this is the first frame 
       
  1514                 TInt r = ThreadWrite( iDataReceiveBufPtr, &writePtr, 0 );
       
  1515                     
       
  1516                 // remove the pointer from queue and release the memory block 
       
  1517                 // but only if the ThreadWrite was successfull
       
  1518                 // we do not complete the user request until EIscConcatenationDataEnd
       
  1519                 if ( r == KErrNone )
       
  1520                     {
       
  1521                     iDataFrameRxQueue->DeleteFirst();
       
  1522                     iIscDevice->ReleaseMemoryBlock( aPtr );
       
  1523                     }
       
  1524                 else
       
  1525                     {
       
  1526                     C_TRACE( ( _T( "DIscChannel::HandleConcatenatedDataFrame() ThreadWrite %d" ), r ) );
       
  1527                     TRACE_ASSERT_ALWAYS;
       
  1528                     CompleteRequest( EIscAsyncDataReceive, KErrWrite );
       
  1529                     }
       
  1530                 }            
       
  1531             else // buffer too small
       
  1532                 {
       
  1533                 TRACE_ASSERT( totalLength >= ( desLen + aInfo.writeLength ) );
       
  1534                 TPtr8 tempLenDes( ( TUint8* )&totalLength, sizeof ( TUint16 ), sizeof ( TUint16 ) );
       
  1535                 TInt r = ThreadWrite ( ( TAny* )iNeededDataBufLen, &tempLenDes, 0 );
       
  1536                 TRACE_ASSERT( r == KErrNone );
       
  1537                 if ( r != KErrNone ) 
       
  1538                     {
       
  1539                     C_TRACE( ( _T( "DIscChannel::HandleConcatenatedDataFrame() data start KErrNoMemory ThreadWrite %d" ), r ) );
       
  1540                     }
       
  1541                 
       
  1542                 CompleteRequest( EIscAsyncDataReceive, KErrNoMemory );
       
  1543                 }
       
  1544             break;
       
  1545             }
       
  1546         case EIscConcatenationData:
       
  1547         case EIscConcatenationDataEnd:    
       
  1548             {
       
  1549             // check whether the next frame fits to the remaining buffer
       
  1550             if ( ( desMaxLen - desLen ) >= aInfo.writeLength ) 
       
  1551                 {
       
  1552                 // create a temporary descriptor for writing since we're
       
  1553                 // necessary not writing the whole contents of the 
       
  1554                 // source descriptor, only the part that ISC Multiplexer
       
  1555                 // wants
       
  1556                 TPtr8 writePtr( ( TUint8* )( aPtr->Ptr() + aInfo.writeStartIndex ),
       
  1557                                 aInfo.writeLength,
       
  1558                                 aInfo.writeLength );
       
  1559                 
       
  1560                 // start writing the data at offset desLen
       
  1561                 TInt r = ThreadWrite( iDataReceiveBufPtr, &writePtr, desLen );
       
  1562                 TRACE_ASSERT( r == KErrNone );
       
  1563                 // remove the pointer from queue and release the memory block 
       
  1564                 // but only if the ThreadWrite was successfull
       
  1565                 if ( r == KErrNone ) 
       
  1566                     {
       
  1567                     iDataFrameRxQueue->DeleteFirst();
       
  1568                     iIscDevice->ReleaseMemoryBlock( aPtr );
       
  1569                     }                
       
  1570                 else
       
  1571                     {                    
       
  1572                     C_TRACE( ( _T( "DIscChannel::HandleConcatenatedDataFrame() data ThreadWrite %d" ), r ) );
       
  1573                     }
       
  1574 
       
  1575                 // complete client request if the frame was the last one
       
  1576                 if ( aInfo.concatenation == EIscConcatenationDataEnd )
       
  1577                     {
       
  1578                     if ( r == KErrNone )
       
  1579                         {
       
  1580                         CompleteRequest( EIscAsyncDataReceive, KErrNone );
       
  1581                          }
       
  1582                     else
       
  1583                         {
       
  1584                         CompleteRequest( EIscAsyncDataReceive, KErrWrite );
       
  1585                         }
       
  1586                     }
       
  1587                 }
       
  1588             else
       
  1589                 {
       
  1590                 CompleteRequest( EIscAsyncDataReceive, KErrUnderflow );
       
  1591                 }
       
  1592             break;
       
  1593             }
       
  1594         default:
       
  1595             {
       
  1596             ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscNotAllowedCallToDoCancel );
       
  1597             break;
       
  1598             }
       
  1599         }
       
  1600     }
       
  1601 
       
  1602 // -----------------------------------------------------------------------------
       
  1603 // DIscChannel::HandleConcatenatedFrame
       
  1604 // Copies several frames to clients buffer if needed before compliting receive request
       
  1605 // ( other items were commented in a header ).
       
  1606 // -----------------------------------------------------------------------------
       
  1607 //
       
  1608 void DIscChannel::HandleConcatenatedFrame( TDes8* aPtr, TIscFrameInfo& aInfo )
       
  1609     {
       
  1610     C_TRACE( ( _T( "DIscChannel::HandleConcatenatedFrame(0x%x, 0x%x) channelPtr 0x%x" ), aPtr, &aInfo, this ) );
       
  1611     TInt desMaxLen( 0 );
       
  1612     TInt desLen( 0 );
       
  1613     TUint16 totalLength( 0 );
       
  1614 
       
  1615     desMaxLen = Kern::ThreadGetDesMaxLength( iThread, iReceiveBufPtr );
       
  1616     desLen = Kern::ThreadGetDesLength( iThread, iReceiveBufPtr );
       
  1617 
       
  1618     if ( aInfo.totalLength > 0 )
       
  1619         {
       
  1620         totalLength = aInfo.totalLength;
       
  1621         }
       
  1622     else
       
  1623         { 
       
  1624         totalLength = desMaxLen;
       
  1625         }
       
  1626     switch ( aInfo.concatenation )
       
  1627         {
       
  1628         // first frame of a larger data chunk
       
  1629         case EIscConcatenationDataStart:
       
  1630             {
       
  1631             // check whether the whole data amount will fit into the user buffer
       
  1632             if ( desMaxLen >= ( desLen + aInfo.writeLength ) && desMaxLen >= totalLength )
       
  1633                 {
       
  1634                 // create a temporary descriptor for writing since we're
       
  1635                 // necessary not writing the whole contents of the 
       
  1636                 // source descriptor, only the part that ISC Multiplexer
       
  1637                 // wants
       
  1638                 TPtr8 writePtr( ( TUint8* )( aPtr->Ptr() + aInfo.writeStartIndex ),
       
  1639                                 aInfo.writeLength,
       
  1640                                 aInfo.writeLength );
       
  1641                 
       
  1642                 // start writing the data at offset 0 since this is the first frame 
       
  1643                 TInt r = ThreadWrite( iReceiveBufPtr, &writePtr, 0 );
       
  1644                 TRACE_ASSERT( r == KErrNone );
       
  1645                     
       
  1646                 // remove the pointer from queue and release the memory block 
       
  1647                 // but only if the ThreadWrite was successfull
       
  1648                 // we do not complete the user request until EIscConcatenationDataEnd
       
  1649                 if ( r == KErrNone )
       
  1650                     {
       
  1651                     iFrameRxQueue->DeleteFirst();
       
  1652                     iIscDevice->ReleaseMemoryBlock( aPtr );
       
  1653                     }
       
  1654                 else 
       
  1655                     {
       
  1656                     C_TRACE( ( _T( "DIscChannel::HandleConcatenatedFrame() ThreadWrite %d" ), r ) );
       
  1657                     CompleteRequest( EIscAsyncReceive, KErrWrite );
       
  1658                     }
       
  1659                 }
       
  1660             else // buffer too small
       
  1661                 {
       
  1662                 TRACE_ASSERT( totalLength >= ( desLen + aInfo.writeLength ) );
       
  1663                 TPtr8 tempLenDes( ( TUint8* )&totalLength, sizeof ( TUint16 ), sizeof ( TUint16 ) );
       
  1664                 TInt r = ThreadWrite ( ( TAny* )iNeededBufLen, &tempLenDes, 0 );
       
  1665                 TRACE_ASSERT( r == KErrNone );
       
  1666                 if ( r != KErrNone ) 
       
  1667                     {
       
  1668                     C_TRACE( ( _T( "DIscChannel::HandleConcatenatedFrame() ThreadWrite %d" ), r ) );
       
  1669                     }
       
  1670                 
       
  1671                 CompleteRequest( EIscAsyncReceive, KErrNoMemory );
       
  1672                 }
       
  1673             break;
       
  1674             }
       
  1675         case EIscConcatenationData:
       
  1676         case EIscConcatenationDataEnd:    
       
  1677             {
       
  1678             // check whether the next frame fits to the remaining buffer
       
  1679             if ( ( desMaxLen - desLen ) >= aInfo.writeLength ) 
       
  1680                 {
       
  1681                 // create a temporary descriptor for writing since we're
       
  1682                 // necessary not writing the whole contents of the 
       
  1683                 // source descriptor, only the part that ISC Multiplexer
       
  1684                 // wants
       
  1685                 TPtr8 writePtr( ( TUint8* )( aPtr->Ptr() + aInfo.writeStartIndex ),
       
  1686                                 aInfo.writeLength,
       
  1687                                 aInfo.writeLength );
       
  1688                 
       
  1689                 // start writing the data at offset desLen
       
  1690                 TInt r = ThreadWrite( iReceiveBufPtr, &writePtr, desLen );
       
  1691                 
       
  1692                 if ( r != KErrNone ) 
       
  1693                     {
       
  1694                     C_TRACE( ( _T( "DIscChannel::HandleConcatenatedFrame() ThreadWrite %d" ), r ) );
       
  1695                     }
       
  1696                 // remove the pointer from queue and release the memory block 
       
  1697                 // but only if the ThreadWrite was successfull
       
  1698                 if ( r == KErrNone )
       
  1699                     {
       
  1700                     iFrameRxQueue->DeleteFirst();
       
  1701                     iIscDevice->ReleaseMemoryBlock( aPtr );
       
  1702                     }
       
  1703 
       
  1704                 // complete client request if the frame was the last one
       
  1705                 if ( aInfo.concatenation == EIscConcatenationDataEnd )
       
  1706                     {
       
  1707                     if ( r == KErrNone )
       
  1708                         {
       
  1709                         CompleteRequest( EIscAsyncReceive, KErrNone );
       
  1710                          }
       
  1711                     else
       
  1712                         {
       
  1713                         CompleteRequest( EIscAsyncReceive, KErrWrite );
       
  1714                         }
       
  1715                     }
       
  1716                 }
       
  1717             else
       
  1718                 {
       
  1719                 CompleteRequest( EIscAsyncDataReceive, KErrUnderflow );
       
  1720                 }
       
  1721             break;
       
  1722             }
       
  1723         default:
       
  1724             {
       
  1725             ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscUnknownCommand );
       
  1726             break;
       
  1727             }
       
  1728         }
       
  1729 
       
  1730     }
       
  1731 
       
  1732 // -----------------------------------------------------------------------------
       
  1733 // DIscChannel::CopyFromUserBuffer
       
  1734 // Copy data from user-thread memory space.
       
  1735 // ( other items were commented in a header ).
       
  1736 // -----------------------------------------------------------------------------
       
  1737 //
       
  1738 TInt DIscChannel::CopyFromUserBuffer( 
       
  1739     const TDesC8& aUserBuffer,
       
  1740     TDes8& aKernelBuffer,
       
  1741     const TInt aOffset )
       
  1742     {
       
  1743     C_TRACE( ( _T( "DIscChannel::CopyFromUserBuffer(0x%x, 0x%x, 0x%x) channelPtr 0x%x" ), &aUserBuffer, &aKernelBuffer, aOffset, this ) );
       
  1744     return Kern::ThreadDesRead( iThread, ( TAny* )&aUserBuffer, aKernelBuffer, aOffset, KChunkShiftBy0 );
       
  1745 
       
  1746     }
       
  1747 
       
  1748 // -----------------------------------------------------------------------------
       
  1749 // DIscChannel::ThreadWrite
       
  1750 // Writes data/frames to clients buffer
       
  1751 // ( other items were commented in a header ).
       
  1752 // -----------------------------------------------------------------------------
       
  1753 //
       
  1754 TInt DIscChannel::ThreadWrite( 
       
  1755     TAny* dest,
       
  1756     const TDesC8* src,
       
  1757     const TInt aOffset )
       
  1758     {
       
  1759     C_TRACE( ( _T( "DIscChannel::ThreadWrite(0x%x, 0x%x, 0x%x)" ), dest, src, aOffset ) );
       
  1760     C_TRACE( ( _T( "DIscChannel::ThreadWrite writeLen 0x%x" ), src->Length() ) );
       
  1761     
       
  1762     return Kern::ThreadDesWrite( iThread, dest, *src, aOffset, iThread ); 
       
  1763 
       
  1764     }
       
  1765 
       
  1766 // -----------------------------------------------------------------------------
       
  1767 // DIscChannel::ResetBuffers
       
  1768 // Resets buffers
       
  1769 // ( other items were commented in a header ).
       
  1770 // -----------------------------------------------------------------------------
       
  1771 //
       
  1772 void DIscChannel::ResetBuffers()
       
  1773     {
       
  1774     // Delete pending send frames
       
  1775     iIscDevice->CancelSending( iChannelNumber, this );
       
  1776 
       
  1777     // Empty receive queue
       
  1778     if ( iFrameRxQueue )
       
  1779         {
       
  1780         while ( !iFrameRxQueue->Empty() )
       
  1781             {
       
  1782             TDes8* tempPtr = ( TDes8* ) iFrameRxQueue->GetFirst();
       
  1783             iFrameRxQueue->DeleteFirst();
       
  1784             iIscDevice->ReleaseMemoryBlock( tempPtr );
       
  1785             }
       
  1786         }
       
  1787     
       
  1788     // Empty data receive queue
       
  1789     if ( iDataFrameRxQueue )
       
  1790         {
       
  1791         while ( !iDataFrameRxQueue->Empty() )
       
  1792             {
       
  1793             TDes8* tempPtr = ( TDes8* ) iDataFrameRxQueue->GetFirst();
       
  1794             iDataFrameRxQueue->DeleteFirst();
       
  1795             iIscDevice->ReleaseMemoryBlock( tempPtr );
       
  1796             }
       
  1797         }
       
  1798     }
       
  1799 
       
  1800 //  End of File