systemswstubs/examplecommonisc/IscDriver/src/IscDevice.cpp
changeset 46 e1758cbb96ac
parent 0 0ce1b5ce9557
equal deleted inserted replaced
43:e71858845f73 46:e1758cbb96ac
       
     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 
       
    22 #include <kernel.h>
       
    23 #include <kern_priv.h>
       
    24 #include <IscDataTransmissionBase.h>
       
    25 #include <IscMultiplexerBase.h>
       
    26 
       
    27 #include "IscMainRcvBuffer.h"
       
    28 #include "IscQueue.h"
       
    29 #include "IscSendQueue.h"
       
    30 #include "IscDevice.h"
       
    31 #include "IscChannel.h"
       
    32 #include "IscChannelContainer.h"
       
    33 #include "IscTrace.h"
       
    34 
       
    35 #ifdef __WINS__
       
    36 #include <windows.h>
       
    37 #endif
       
    38 
       
    39 
       
    40 // EXTERNAL DATA STRUCTURES
       
    41 
       
    42 // EXTERNAL FUNCTION PROTOTYPES  
       
    43 
       
    44 // CONSTANTS
       
    45 _LIT( KIscDriverName, "IscDriver" );
       
    46 
       
    47 // MACROS
       
    48 
       
    49 // LOCAL CONSTANTS AND MACROS
       
    50 const TInt KSendDfcPriority( 4 );
       
    51 const TInt KNotifyDfcPriority( 5 );
       
    52 const TInt KIscInterruptLevelTwo( 2 );
       
    53 
       
    54 // MODULE DATA STRUCTURES
       
    55 
       
    56 // LOCAL FUNCTION PROTOTYPES
       
    57 
       
    58 // FORWARD DECLARATIONS
       
    59 
       
    60 
       
    61 DIscDataTransmissionBase* DIscDevice::iIscDataTransmissionInterface = NULL;
       
    62 DIscMultiplexerBase* DIscDevice::iIscMultiplexerInterface = NULL;
       
    63 DIscSendQueue* DIscDevice::iSendQueue=NULL;
       
    64 DIscSendQueue* DIscDevice::iTempQueue=NULL;
       
    65 DIscSendQueue* DIscDevice::iControlSendQueue=NULL;
       
    66 TDfc* DIscDevice::iSendDfc = NULL;
       
    67 TDfc* DIscDevice::iNotifyDfc = NULL;
       
    68 TInt DIscDevice::iConnectionStatus = EIscConnectionNotOk;
       
    69 
       
    70 #ifdef __WINS__
       
    71 CRITICAL_SECTION g_IscDTBCriticalSection;
       
    72 #endif
       
    73 
       
    74 // ============================ MEMBER FUNCTIONS ===============================
       
    75 
       
    76 
       
    77 // -----------------------------------------------------------------------------
       
    78 // DIscDevice::DIscDevice
       
    79 // C++ default constructor
       
    80 // ( other items were commented in a header ).
       
    81 // -----------------------------------------------------------------------------
       
    82 //
       
    83 EXPORT_C DIscDevice::DIscDevice()
       
    84     :DLogicalDevice(),
       
    85     iSend( NULL ),
       
    86     iTempSend( NULL ),
       
    87     iControlSend( NULL ),
       
    88     iSendFrameParameters( NULL ),
       
    89     iTempFrameParameters( NULL ),
       
    90     iControlFrameParameters( NULL ),
       
    91     iIscMainRcvBuffer( NULL )     
       
    92     {
       
    93     C_TRACE( ( _T( "DIscDevice::DIscDevice()" ) ) );
       
    94 
       
    95     iVersion = TVersion( KMajorVersionNumber, KMinorVersionNumber,
       
    96     KBuildVersionNumber );
       
    97     iParseMask |= KDeviceAllowUnit;
       
    98     iParseMask |= KDeviceAllowInfo;
       
    99 
       
   100 #ifdef __WINS__
       
   101      InitializeCriticalSection( &g_IscDTBCriticalSection );
       
   102 #endif 
       
   103     }
       
   104 
       
   105 // Destructor
       
   106 EXPORT_C DIscDevice::~DIscDevice()
       
   107     {
       
   108     C_TRACE( ( _T( "DIscDevice::~DIscDevice()" ) ) );
       
   109 
       
   110     IscChannelContainer::DeActivate();
       
   111     
       
   112     if ( iIscMainRcvBuffer )
       
   113         {
       
   114         delete iIscMainRcvBuffer;
       
   115         iIscMainRcvBuffer = NULL;
       
   116         }
       
   117 
       
   118 
       
   119     iIscDataTransmissionInterface = NULL;
       
   120     iIscMultiplexerInterface = NULL;
       
   121 
       
   122     delete iTempSend;
       
   123     delete iControlSend;
       
   124     delete iSendQueue;
       
   125     delete iTempQueue;
       
   126     delete iControlSendQueue;
       
   127     delete iSendDfc;
       
   128     delete iNotifyDfc;
       
   129 
       
   130 #ifdef __WINS__
       
   131      DeleteCriticalSection( &g_IscDTBCriticalSection );
       
   132 #endif
       
   133         
       
   134     }
       
   135 
       
   136 
       
   137 // -----------------------------------------------------------------------------
       
   138 // DIscDevice::Install
       
   139 // Complete the installation of driver
       
   140 // ( other items were commented in a header ).
       
   141 // -----------------------------------------------------------------------------
       
   142 //
       
   143 TInt DIscDevice::Install()
       
   144     {
       
   145     C_TRACE( ( _T( "DIscDevice::Install()" ) ) );
       
   146 
       
   147     // Dfc for sending frames
       
   148     iSendDfc = new TDfc( Flush, this, Kern::DfcQue0(), KSendDfcPriority );
       
   149     iNotifyDfc = new TDfc( NotifyConnection, this, Kern::DfcQue0(), KNotifyDfcPriority );        
       
   150     ASSERT_RESET_ALWAYS( iSendDfc, "IscDriver",EIscMemoryAllocationFailure );
       
   151 
       
   152     //Initialize IscChannelContainer
       
   153     IscChannelContainer::Initialize();
       
   154     
       
   155     // connect to multiplexer and data transmission driver
       
   156     TInt r = InitializeLdd2LddInterface();
       
   157     if ( r != KErrNone )
       
   158         {
       
   159         TRACE_ASSERT_ALWAYS;
       
   160         return r;
       
   161         }
       
   162 
       
   163     return ( SetName( &KIscDriverName ) );
       
   164     }
       
   165 
       
   166 // -----------------------------------------------------------------------------
       
   167 // DIscDevice::Initialize
       
   168 // Complete the initialization of driver
       
   169 // ( other items were commented in a header ).
       
   170 // -----------------------------------------------------------------------------
       
   171 //
       
   172 void DIscDevice::Initialize()
       
   173     {
       
   174     C_TRACE( ( _T( "DIscDevice::Initialize()" ) ) );
       
   175 
       
   176     TInt i( 0 );
       
   177 
       
   178     // Get buffer configuration data from multiplexer
       
   179     TIscConfiguration configData;
       
   180     iIscMultiplexerInterface->GetConfiguration( configData );
       
   181 
       
   182     // Create main buffer  
       
   183     iIscMainRcvBuffer = new DIscMainRcvBuffer( this, configData.mainRcvQueueSize );
       
   184     ASSERT_RESET_ALWAYS( iIscMainRcvBuffer, "IscDriver",EIscMemoryAllocationFailure );
       
   185     
       
   186     // Do second phase installation    
       
   187     iIscMainRcvBuffer->DoCreate();
       
   188     
       
   189     // Create queue for sending frames
       
   190     iSend = new TUint32*[configData.channelSendQueueSize];
       
   191     ASSERT_RESET_ALWAYS( iSend, "IscDriver",EIscMemoryAllocationFailure );
       
   192     
       
   193     iSendFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize];
       
   194     for ( i = 0; i < configData.channelSendQueueSize; i++ )
       
   195         {
       
   196         iSendFrameParameters[i] = new TIscSendFrameInfo;
       
   197         }
       
   198     ASSERT_RESET_ALWAYS( iSendFrameParameters, "IscDriver",EIscMemoryAllocationFailure );
       
   199 
       
   200     iSendQueue = new DIscSendQueue( iSend, iSendFrameParameters, configData.channelSendQueueSize );
       
   201     ASSERT_RESET_ALWAYS( iSendQueue, "IscDriver",EIscMemoryAllocationFailure );
       
   202 
       
   203 
       
   204     // create temporary queue
       
   205     iTempSend = new TUint32*[configData.channelSendQueueSize];
       
   206     ASSERT_RESET_ALWAYS( iTempSend, "IscDriver",EIscMemoryAllocationFailure );
       
   207 
       
   208     iTempFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize];
       
   209     for ( i =0; i < configData.channelSendQueueSize; i++ )
       
   210         {
       
   211         iTempFrameParameters[i] = new TIscSendFrameInfo;
       
   212         }
       
   213     ASSERT_RESET_ALWAYS( iTempFrameParameters, "IscDriver",EIscMemoryAllocationFailure );
       
   214 
       
   215     iTempQueue = new DIscSendQueue( iTempSend, iTempFrameParameters, configData.channelSendQueueSize );
       
   216     ASSERT_RESET_ALWAYS( iTempQueue, "IscDriver",EIscMemoryAllocationFailure );
       
   217 
       
   218 
       
   219     // Create send queue for control channel
       
   220     iControlSend = new TUint32*[configData.channelSendQueueSize];
       
   221     ASSERT_RESET_ALWAYS( iControlSend, "IscDriver",EIscMemoryAllocationFailure );
       
   222 
       
   223     iControlFrameParameters = new TIscSendFrameInfo*[configData.channelSendQueueSize];
       
   224     for ( i = 0; i < configData.channelSendQueueSize; i++ )
       
   225         {
       
   226         iControlFrameParameters[i] = new TIscSendFrameInfo;
       
   227         }
       
   228     ASSERT_RESET_ALWAYS( iControlFrameParameters, "IscDriver",EIscMemoryAllocationFailure );
       
   229 
       
   230     iControlSendQueue = new DIscSendQueue( iControlSend, iControlFrameParameters, configData.channelSendQueueSize );
       
   231     ASSERT_RESET_ALWAYS( iControlSendQueue, "IscDriver",EIscMemoryAllocationFailure );
       
   232     
       
   233     iIscDataTransmissionInterface->AllocBuffers( configData.bufferConfig );
       
   234     
       
   235     iConnectionStatus = iIscDataTransmissionInterface->ConnectionStatus();
       
   236 
       
   237     iIscMultiplexerInterface->NotifyConnectionStatus( iConnectionStatus );
       
   238     C_TRACE( ( _T( "DIscDevice::Initialize - return void" ) ) );
       
   239     }
       
   240 // -----------------------------------------------------------------------------
       
   241 // DIscDevice::GetCaps
       
   242 // 
       
   243 // ( other items were commented in a header ).
       
   244 // -----------------------------------------------------------------------------
       
   245 //
       
   246 EXPORT_C void DIscDevice::GetCaps( 
       
   247     TDes8& /*aDes*/ ) const
       
   248     {
       
   249     // GetCaps implemented to keep compiler happy
       
   250     }
       
   251 
       
   252 // -----------------------------------------------------------------------------
       
   253 // DEcsDevice::Create
       
   254 // From DLogicalDevice
       
   255 // ( other items were commented in a header ).
       
   256 // -----------------------------------------------------------------------------
       
   257 //
       
   258 TInt DIscDevice::Create( 
       
   259     DLogicalChannelBase*& aChannel )
       
   260     {
       
   261     aChannel=new DIscChannel( this );
       
   262     return aChannel?KErrNone:KErrNoMemory;
       
   263     }
       
   264 
       
   265 // -----------------------------------------------------------------------------
       
   266 // DIscDevice::Receive
       
   267 // Frames coming from Domestic OS
       
   268 // ( other items were commented in a header ).
       
   269 // -----------------------------------------------------------------------------
       
   270 //
       
   271 EXPORT_C void DIscDevice::Receive( 
       
   272     TDesC8* aData ) const
       
   273     {
       
   274     DIscMainRcvBuffer::MsgReceive( aData );
       
   275     }
       
   276 
       
   277 
       
   278 // -----------------------------------------------------------------------------
       
   279 // DIscDevice::ReserveMemoryBlock
       
   280 // Get message block from buffers allocated in IscDataTransmissionBase.dll
       
   281 // ( other items were commented in a header ).
       
   282 // -----------------------------------------------------------------------------
       
   283 //
       
   284 EXPORT_C void DIscDevice::ReserveMemoryBlock( TDes8*& aPtr, TUint16 aSize )
       
   285     {
       
   286     iIscDataTransmissionInterface->ReserveMemoryBlock( aPtr, aSize );
       
   287     }
       
   288 
       
   289 // -----------------------------------------------------------------------------
       
   290 // DIscDevice::ReleaseMemoryBlock
       
   291 // Release memory block allocated with ReserveMemoryBlock
       
   292 // ( other items were commented in a header ).
       
   293 // -----------------------------------------------------------------------------
       
   294 //
       
   295 EXPORT_C void DIscDevice::ReleaseMemoryBlock( 
       
   296     TDes8* aPtr )
       
   297     {
       
   298     C_TRACE( ( _T( "DIscDevice::ReleaseMemoryBlock(0x%x)" ), aPtr ) );
       
   299 
       
   300     if ( iIscDataTransmissionInterface )
       
   301         {
       
   302         iIscDataTransmissionInterface->ReleaseMemoryBlock( aPtr );
       
   303         }
       
   304     }
       
   305 
       
   306 // -----------------------------------------------------------------------------
       
   307 // DIscDevice::NotifyConnectionStatus
       
   308 // Connection status change function
       
   309 // ( other items were commented in a header ).
       
   310 // -----------------------------------------------------------------------------
       
   311 //
       
   312 EXPORT_C void DIscDevice::NotifyConnectionStatus( const TInt aStatus )
       
   313     {
       
   314     C_TRACE( ( _T( "DIscDevice::NotifyConnectionStatus(0x%x)" ), aStatus ) );
       
   315     if ( iConnectionStatus != aStatus )
       
   316         {
       
   317         iConnectionStatus = aStatus;
       
   318 		if ( NKern::CurrentContext() == NKern::EInterrupt )
       
   319 			{
       
   320 			iNotifyDfc->Add();
       
   321 			}
       
   322 		else
       
   323 			{
       
   324 		    iNotifyDfc->Enque();
       
   325 		    }
       
   326         }
       
   327         
       
   328     C_TRACE( ( _T( "DIscDevice::NotifyConnectionStatus() return" ) ) );    
       
   329     }
       
   330 
       
   331 // -----------------------------------------------------------------------------
       
   332 // DIscDevice::NotifyConnection
       
   333 // Connection status change DFC function.
       
   334 // ( other items were commented in a header ).
       
   335 // -----------------------------------------------------------------------------
       
   336 //
       
   337 void DIscDevice::NotifyConnection( TAny* )
       
   338     {
       
   339     C_TRACE( ( _T( "DIscDevice::NotifyConnection(0x%x)" ), iConnectionStatus ) );
       
   340     
       
   341     iIscMultiplexerInterface->NotifyConnectionStatus( iConnectionStatus );
       
   342     DIscChannel* tempPtr = NULL;
       
   343     for ( TUint16 i = KIscFirstChannel; i < KIscNumberOfUnits; i++ )
       
   344         {
       
   345         for ( TUint16 ii( 0 ); ii < KIscMaxNumberOfChannelSharers; ii++ )
       
   346             {
       
   347             tempPtr = IscChannelContainer::Channel( i, ii );
       
   348             if ( tempPtr )
       
   349                 { 
       
   350                 tempPtr->NotifyConnectionStatus( iConnectionStatus );
       
   351                 tempPtr = NULL;
       
   352                 }
       
   353             }
       
   354         }
       
   355     C_TRACE( ( _T( "DIscDevice::NotifyConnection() return" ) ) );
       
   356 
       
   357     }
       
   358 
       
   359 // -----------------------------------------------------------------------------
       
   360 // DIscDevice::ULFlowControl
       
   361 // Function to notify client about uplink flow control status
       
   362 // ( other items were commented in a header ).
       
   363 // -----------------------------------------------------------------------------
       
   364 //
       
   365 EXPORT_C void DIscDevice::ULFlowControl( 
       
   366     const TInt aULFlowStatus,
       
   367     const TUint16 aChannelId,
       
   368     const TAny* aChannelPtr )
       
   369     {
       
   370     C_TRACE( ( _T( "DIscDevice::ULFlowControl(0x%x, 0x%x, 0x%x)" ), aULFlowStatus, aChannelId, aChannelPtr ) );
       
   371 
       
   372     DIscChannel* tempPtr = NULL;
       
   373     TBool channelFound(EFalse);
       
   374 
       
   375     if ( !aChannelPtr )
       
   376         {
       
   377         // All channels.
       
   378         for ( TUint16 i(0); i < KIscMaxNumberOfChannelSharers; i++ )
       
   379             {
       
   380             tempPtr = IscChannelContainer::Channel( aChannelId, i );
       
   381             if ( tempPtr )
       
   382                 {
       
   383                 tempPtr->NotifyFlowControl( aULFlowStatus );
       
   384                 tempPtr = NULL;
       
   385                 channelFound = ETrue;
       
   386                 }
       
   387             else
       
   388             	{
       
   389             	//Do nothing	
       
   390             	}
       
   391             }
       
   392         }
       
   393     else
       
   394         {
       
   395         // Single channel.
       
   396         for ( TUint16 i(0); i < KIscMaxNumberOfChannelSharers; i++ )
       
   397             {
       
   398             tempPtr = IscChannelContainer::Channel( aChannelId, i );
       
   399             if ( tempPtr == ( DIscChannel* )aChannelPtr )
       
   400                 {
       
   401                 tempPtr->NotifyFlowControl( aULFlowStatus );
       
   402                 tempPtr = NULL;
       
   403                 channelFound = ETrue;
       
   404                 break;
       
   405                 }
       
   406             else
       
   407             	{
       
   408             	//Do nothing	
       
   409             	}                
       
   410             }            
       
   411         }
       
   412 
       
   413     if ( channelFound == EFalse )
       
   414         TRACE_ASSERT_ALWAYS;
       
   415     
       
   416     }
       
   417 
       
   418 // -----------------------------------------------------------------------------
       
   419 // DIscDevice::IsPending
       
   420 // Function to check if asycnhronous request is active
       
   421 // ( other items were commented in a header ).
       
   422 // -----------------------------------------------------------------------------
       
   423 //
       
   424 EXPORT_C TInt DIscDevice::IsPending( 
       
   425     const TUint16 aReqNumber, 
       
   426     const TAny* aChannelPtr )
       
   427     {
       
   428     C_TRACE( ( _T( "DIscDevice::IsPending(0x%x, 0x%x)" ), aReqNumber, aChannelPtr ) );
       
   429 
       
   430     DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr;
       
   431     TInt error = IscChannelContainer::ValidateChannel( tempPtr );
       
   432     if( error == KErrNone )
       
   433     	{
       
   434     	error = tempPtr->IsPending( aReqNumber );
       
   435     	}
       
   436     C_TRACE( ( _T( "DIscDevice::IsPending - return %d" ), error ) );	
       
   437    	return error;
       
   438 
       
   439     }
       
   440 
       
   441 // -----------------------------------------------------------------------------
       
   442 // DIscDevice::DLFlowControl
       
   443 // Notify multiplexer about down link flow control
       
   444 // ( other items were commented in a header ).
       
   445 // -----------------------------------------------------------------------------
       
   446 //
       
   447 void DIscDevice::DLFlowControlNotify( 
       
   448     const TInt aDLFlowStatus,
       
   449     const TUint16 aChannel,
       
   450     const TAny* aChannelPtr )
       
   451     {
       
   452     C_TRACE( ( _T( "DIscDevice::DLFlowControlNotify(0x%x, 0x%x)" ), aDLFlowStatus, aChannel ) );
       
   453     if ( aChannel >= KIscFirstChannel 
       
   454         && aChannel < KIscNumberOfUnits )
       
   455         {        
       
   456         if ( aDLFlowStatus == EIscFlowControlOn )
       
   457             {
       
   458             iIscMultiplexerInterface->DLFlowControl( EIscFlowControlOn, aChannel, aChannelPtr );
       
   459             }        
       
   460         else
       
   461             {
       
   462             iIscMultiplexerInterface->DLFlowControl( EIscFlowControlOff, aChannel, aChannelPtr );            
       
   463             }
       
   464         }
       
   465     else
       
   466         {
       
   467         
       
   468         if ( aChannel == 0x00 )
       
   469             {
       
   470             // control channel, no flow control used
       
   471             }
       
   472         else
       
   473             {
       
   474             // should never came here
       
   475             TRACE_ASSERT_ALWAYS;
       
   476             }
       
   477         }
       
   478     }
       
   479 
       
   480 // -----------------------------------------------------------------------------
       
   481 // DIscDevice::InitializeLdd2LddInterface
       
   482 // Function to connect to DataTransmission and Multiplexer ldds
       
   483 // ( other items were commented in a header ).
       
   484 // -----------------------------------------------------------------------------
       
   485 //
       
   486 TInt DIscDevice::InitializeLdd2LddInterface()
       
   487     {
       
   488     C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface()" ) ) );
       
   489     
       
   490     // Find pointer to second level LDD.
       
   491     DObjectCon* lDevices = Kern::Containers()[ ELogicalDevice ];
       
   492     TKName driverName;
       
   493     ASSERT_RESET_ALWAYS( lDevices, "IscDriver", EIscLogicalDevicesNotFound );
       
   494 
       
   495     TInt err( KErrNone );
       
   496     //TInt driverHandle( KErrNone ); // API change in SOS9.2 WK08
       
   497 	TFindHandle driverHandle;
       
   498     // Find pointer to ISC Multiplexer.
       
   499     err = lDevices->FindByName( driverHandle, KIscMultiplexerName, driverName );
       
   500     if( KErrNone != err )
       
   501         {
       
   502         C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface() ISC Multiplexer Not Found!" ) ) );
       
   503         ASSERT_RESET_ALWAYS( 0, "IscDriver" ,EIscMultiplexerNotFound );
       
   504         }
       
   505 	
       
   506     iIscMultiplexerInterface = static_cast<DIscMultiplexerBase*>( lDevices->At( driverHandle ) );
       
   507     ASSERT_RESET_ALWAYS( iIscMultiplexerInterface, "IscDriver", EIscMultiplexerNotFound );
       
   508 
       
   509     //TInt secondDriverHandle( KErrNone );  // API change in SOS9.2 WK08
       
   510 	TFindHandle secondDriverHandle;
       
   511     // Find pointer to Data Transmission Plugin.
       
   512     err = lDevices->FindByName( secondDriverHandle, KIscDataTransmissionDriverName, driverName );
       
   513     if( KErrNone != err )
       
   514         {
       
   515         C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface() Data Transmission Plug-In Not Found!" ) ) );
       
   516         ASSERT_RESET_ALWAYS( 0, "IscDriver", EIscDataTransmissionDriverNotFound );
       
   517         }
       
   518 
       
   519     iIscDataTransmissionInterface = static_cast<DIscDataTransmissionBase*>( lDevices->At( secondDriverHandle ) );
       
   520     ASSERT_RESET_ALWAYS( iIscDataTransmissionInterface, "IscDriver", EIscDataTransmissionDriverNotFound );
       
   521     
       
   522     iIscDataTransmissionInterface->Connect( this );
       
   523     iIscMultiplexerInterface->Connect( this );
       
   524 
       
   525     C_TRACE( ( _T( "DIscDevice::InitializeLdd2LddInterface - return 0x%x" ), err ) );
       
   526     return err;
       
   527     
       
   528     }
       
   529 
       
   530 // -----------------------------------------------------------------------------
       
   531 // DIscDevice::QueueFrame
       
   532 // Queue frames that will be sent to Domestic OS
       
   533 // ( other items were commented in a header ).
       
   534 // -----------------------------------------------------------------------------
       
   535 //
       
   536 EXPORT_C TInt DIscDevice::QueueFrame( 
       
   537     const TUint16 aChannelId,
       
   538     const TDesC8* aFrame,
       
   539     const TAny* aChannelPtr,
       
   540     TAny* aFrameInfo )
       
   541     {
       
   542     C_TRACE( ( _T( "DIscDevice::QueueFrame(0x%x, 0x%x, 0x%x, 0x%x)" ), aChannelId, aFrame, aChannelPtr, aFrameInfo ) );
       
   543     
       
   544     TInt error = KErrNone;
       
   545     
       
   546     // control channel frame ( highest priority )
       
   547     if ( aChannelId == KIscControlChannel )
       
   548         {
       
   549         C_TRACE( ( _T( "DIscDevice::QueueFrame control frame queue" ) ) );
       
   550         //add to control frame queue
       
   551         error = iControlSendQueue->Add( ( TDes8* )aFrame, aChannelId, ( DIscChannel* )aChannelPtr, aFrameInfo );
       
   552         }
       
   553     else
       
   554         {        
       
   555         C_TRACE( ( _T( "DIscDevice::QueueFrame send queue" ) ) );
       
   556         // add to send queue
       
   557         error = iSendQueue->Add( ( TDes8* )aFrame, aChannelId, ( DIscChannel* )aChannelPtr, aFrameInfo );
       
   558         }
       
   559     
       
   560     C_TRACE( ( _T( "DIscDevice::QueueFrame - return 0x%x" ), error ) );
       
   561     return error;
       
   562     }
       
   563 
       
   564 
       
   565 // -----------------------------------------------------------------------------
       
   566 // DIscDevice::CancelSending
       
   567 // Cancels sending of frames to Domestic OS
       
   568 // ( other items were commented in a header ).
       
   569 // -----------------------------------------------------------------------------
       
   570 //
       
   571 EXPORT_C TInt DIscDevice::CancelSending( const TUint16 aChannelId, const TAny* aChannelPtr )
       
   572     {
       
   573     C_TRACE( ( _T( "DIscDevice::CancelSending - Caller is channel: %d (0x%x)" ), aChannelId, aChannelPtr ) );
       
   574     
       
   575     TInt error( KErrNotFound );
       
   576     TInt irqLevel( 0 );
       
   577 
       
   578     TInt counterA( 0 );
       
   579     TInt counterB( 0 );
       
   580 
       
   581     TIscSendFrameInfo* temp = NULL;
       
   582     TDes8* frame = NULL;
       
   583 
       
   584     irqLevel = DisableIrqs();
       
   585 
       
   586     if ( KIscControlChannel == aChannelId )
       
   587         {
       
   588         // empty control send queue
       
   589         while ( !iControlSendQueue->Empty() )
       
   590             {
       
   591             temp = iControlSendQueue->GetFirstFrameInfo();
       
   592             frame = ( TDes8* )iControlSendQueue->RemoveFirst();
       
   593             if ( temp && frame )
       
   594                 {
       
   595                 if ( temp->iChannelId == aChannelId && 
       
   596                      temp->iChannelPtr == ( DIscChannel* )aChannelPtr )
       
   597                     {
       
   598                     // sender found, no need to store the frame
       
   599                     counterB++;
       
   600                     }
       
   601                 else
       
   602                     {
       
   603                     iTempQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo );
       
   604                     }
       
   605                 }
       
   606             else
       
   607                 {
       
   608                 // should never came here
       
   609                 TRACE_ASSERT_ALWAYS;
       
   610                 }
       
   611             counterA++;
       
   612             temp = NULL;
       
   613             frame = NULL;
       
   614             }  
       
   615         
       
   616         while ( !iTempQueue->Empty() )
       
   617             {
       
   618             temp = iTempQueue->GetFirstFrameInfo();
       
   619             frame = ( TDes8* )iTempQueue->RemoveFirst();
       
   620             if ( temp && frame )
       
   621                 {
       
   622                 iControlSendQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo );
       
   623                 }
       
   624             else
       
   625                 {
       
   626                 // should never came here
       
   627                 TRACE_ASSERT_ALWAYS;
       
   628                 }
       
   629             temp = NULL;
       
   630             frame = NULL;
       
   631             }
       
   632         }
       
   633     else
       
   634         {
       
   635         // empty normal send queue
       
   636         while ( !iSendQueue->Empty() )
       
   637             {
       
   638             temp = iSendQueue->GetFirstFrameInfo();
       
   639             frame = ( TDes8* )iSendQueue->RemoveFirst();
       
   640             if ( temp && frame )
       
   641                 {
       
   642                 if ( temp->iChannelId == aChannelId  && 
       
   643                      temp->iChannelPtr == ( DIscChannel* )aChannelPtr )            
       
   644                     {
       
   645                     // sender found, no need to store frame
       
   646                     counterB++;                
       
   647                     }
       
   648                 else
       
   649                     {
       
   650                     iTempQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo );
       
   651                     }
       
   652                 }
       
   653             else
       
   654                 {
       
   655                 // should never came here
       
   656                 TRACE_ASSERT_ALWAYS;
       
   657                 }
       
   658             counterA++;
       
   659             temp = NULL;
       
   660             frame = NULL;
       
   661             }  
       
   662 
       
   663         while ( !iTempQueue->Empty() )
       
   664             {
       
   665             temp = iTempQueue->GetFirstFrameInfo();
       
   666             frame = ( TDes8* )iTempQueue->RemoveFirst();
       
   667             if ( temp && frame )
       
   668                 {
       
   669                 iSendQueue->Add( frame, temp->iChannelId, temp->iChannelPtr, temp->iFrameInfo );
       
   670                 }
       
   671             else
       
   672                 {
       
   673                 // should never came here
       
   674                 TRACE_ASSERT_ALWAYS;
       
   675                 }
       
   676 
       
   677             temp = NULL;
       
   678             frame = NULL;
       
   679             }
       
   680         }
       
   681         
       
   682     RestoreIrqs( irqLevel );
       
   683 
       
   684     C_TRACE( ( _T( "DIscDevice::CancelSending() - Frames in queue: Before: %d, After: %d" ), counterA, ( counterA-counterB ) ) );
       
   685     C_TRACE( ( _T( "DIscDevice::CancelSending() - So channel 0x%x 0x%x had %d pending messages!" ), aChannelId, aChannelPtr, counterB ) );
       
   686 
       
   687     // if there weren't any frames that were cancelled return KErrNotFound, otherwise return KErrNone
       
   688     if ( counterB > 0 )
       
   689         {        
       
   690         error = KErrNone;
       
   691         }
       
   692     
       
   693     return error;
       
   694 
       
   695     }
       
   696  
       
   697 // -----------------------------------------------------------------------------
       
   698 // DIscDevice::FlushQueues
       
   699 // Adds Dfc to empty queues
       
   700 // ( other items were commented in a header ).
       
   701 // -----------------------------------------------------------------------------
       
   702 //
       
   703 EXPORT_C void DIscDevice::FlushQueues()
       
   704     {
       
   705     C_TRACE( ( _T( "DIscDevice::FlushQueues()" ) ) );
       
   706  
       
   707     if ( NKern::CurrentContext() == NKern::EInterrupt )
       
   708 		{
       
   709 		iSendDfc->Add();
       
   710 		}
       
   711 	else
       
   712 		{
       
   713 	    iSendDfc->Enque();
       
   714 	    }
       
   715 
       
   716     }
       
   717 
       
   718 // -----------------------------------------------------------------------------
       
   719 // DIscDevice::CompleteRequest
       
   720 // Function to complete user side asynchronous request
       
   721 // ( other items were commented in a header ).
       
   722 // -----------------------------------------------------------------------------
       
   723 //
       
   724 // This method has been modified to allow channel sharing between application.
       
   725 // The completion routine uses directly a pointer on a DLogicalChannel instead of a channel index
       
   726 //
       
   727 EXPORT_C void DIscDevice::CompleteRequest( 
       
   728     TUint16 aOperation, 
       
   729     TInt aCompleteStatus,
       
   730     const TAny* aChannelPtr )
       
   731     {
       
   732     C_TRACE( ( _T( "DIscDevice::CompleteRequest(0x%x, 0x%x, 0x%x)" ), aOperation, aCompleteStatus, aChannelPtr ) ); 
       
   733 
       
   734     DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr;
       
   735     TInt error = IscChannelContainer::ValidateChannel( tempPtr );
       
   736     if( error == KErrNone )
       
   737     	{
       
   738     	tempPtr->CompleteRequest( aOperation, aCompleteStatus );
       
   739     	}	
       
   740 
       
   741     C_TRACE( ( _T( "DIscDevice::CompleteRequest - return void" ) ) );
       
   742     }
       
   743 
       
   744 // -----------------------------------------------------------------------------
       
   745 // DIscDevice::CopyFromUserBuffer
       
   746 // 
       
   747 // ( other items were commented in a header ).
       
   748 // -----------------------------------------------------------------------------
       
   749 //
       
   750 EXPORT_C TInt DIscDevice::CopyFromUserBuffer( 
       
   751     const TDesC8& aUserBuffer, 
       
   752     TDes8& aKernelBuffer, 
       
   753     const TAny* aChannelPtr,
       
   754     const TInt aOffset )
       
   755     {
       
   756     C_TRACE( ( _T( "DIscDevice::CopyFromUserBuffer(0x%x, 0x%x, 0x%x, 0x%x)" ), &aUserBuffer, &aKernelBuffer, aChannelPtr, aOffset ) );
       
   757 
       
   758     // Check if channel pointer is valid.
       
   759     DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr;
       
   760     TInt error = IscChannelContainer::ValidateChannel( tempPtr );
       
   761     if( error == KErrNone )
       
   762     	{
       
   763     	error = tempPtr->CopyFromUserBuffer( aUserBuffer, aKernelBuffer, aOffset );	
       
   764     	}
       
   765     C_TRACE( ( _T( "DIscDevice::CopyFromUserBuffer - return %d" ), error ) );	
       
   766    	return error;
       
   767     
       
   768     }
       
   769 
       
   770 // -----------------------------------------------------------------------------
       
   771 // DIscDevice::CopyToUserBuffer
       
   772 // 
       
   773 // (other items were commented in a header).
       
   774 // -----------------------------------------------------------------------------
       
   775 //
       
   776 EXPORT_C TInt DIscDevice::CopyToUserBuffer( 
       
   777     TAny* aUserBuffer, 
       
   778     const TDesC8& aKernelBuffer, 
       
   779     const TAny* aChannelPtr,
       
   780     const TInt aOffset )
       
   781     {
       
   782     C_TRACE( ( _T( "DIscDevice::CopyToUserBuffer(0x%x, 0x%x, 0x%x)" ), aUserBuffer, &aKernelBuffer, aChannelPtr ) );
       
   783     
       
   784     DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr;
       
   785     TInt error = IscChannelContainer::ValidateChannel( tempPtr );
       
   786     if( KErrNone == error )
       
   787     	{
       
   788     	error = tempPtr->ThreadWrite( aUserBuffer, &aKernelBuffer, aOffset );
       
   789     	}
       
   790     C_TRACE( ( _T( "DIscDevice::CopyToUserBuffer - return %d" ), error ) );	
       
   791    	return error;
       
   792 
       
   793     }
       
   794 
       
   795 // -----------------------------------------------------------------------------
       
   796 // DIscMultiplexerBase::GetThreadPtr
       
   797 // Returns user side thread. Ownership is not given.
       
   798 // ( other items were commented in a header ).
       
   799 // -----------------------------------------------------------------------------
       
   800 //
       
   801 EXPORT_C DThread* DIscDevice::GetThreadPtr( const TAny* aChannelPtr )
       
   802 	{
       
   803 	C_TRACE( ( _T( "DIscMultiplexerBase::GetThreadPtr(0x%x)" ), aChannelPtr ) );
       
   804     DIscChannel* tempPtr = ( DIscChannel* )aChannelPtr;
       
   805     TInt error = IscChannelContainer::ValidateChannel( tempPtr );
       
   806 	DThread* tmp = NULL;
       
   807 	if( KErrNone == error )
       
   808 		{
       
   809 		tmp = tempPtr->GetDThread();	
       
   810 		}
       
   811 	else
       
   812 		{
       
   813 		C_TRACE( ( _T( "DIscMultiplexerBase::GetThreadPtr failed return NULL" ) ) );	    				
       
   814 		}
       
   815 	C_TRACE( ( _T( "DIscMultiplexerBase::GetThreadPtr return 0x%x" ), tmp ) );	    	
       
   816    	return tmp;
       
   817    		
       
   818 	}
       
   819     
       
   820 // -----------------------------------------------------------------------------
       
   821 // DIscDevice::Flush
       
   822 // Dfc to empty control channel and other send queues
       
   823 // ( other items were commented in a header ).
       
   824 // -----------------------------------------------------------------------------
       
   825 //
       
   826 void DIscDevice::Flush( TAny* aPtr )
       
   827     {
       
   828     C_TRACE( ( _T( "DIscDevice::Flush(0x%x)" ), aPtr ) );
       
   829     DIscDevice* device = ( DIscDevice* )aPtr;
       
   830 
       
   831     TDes8* frame = NULL;
       
   832     TIscSendFrameInfo* temp = NULL;
       
   833 
       
   834     TInt irqLevel(0);
       
   835 
       
   836     // If transmission is asynchronous and there can't be
       
   837     // several requests at the same time
       
   838     if ( !iIscDataTransmissionInterface->IsWritePending() )
       
   839         {
       
   840         irqLevel = DisableIrqs();
       
   841         if ( !iControlSendQueue->Empty() )
       
   842             {
       
   843             temp = iControlSendQueue->GetFirstFrameInfo();
       
   844             frame = ( TDes8* )iControlSendQueue->RemoveFirst();
       
   845             }
       
   846         else
       
   847             {
       
   848             temp = iSendQueue->GetFirstFrameInfo();
       
   849             frame = ( TDes8* )iSendQueue->RemoveFirst();
       
   850             }
       
   851         RestoreIrqs( irqLevel );
       
   852         C_TRACE( ( _T( "DIscDevice::Flush after RESTOREIRQS" ) ) );    
       
   853         if ( frame )    
       
   854             iIscDataTransmissionInterface->SendFrame( *frame, device->iSendDfc, temp->iFrameInfo );
       
   855         }
       
   856     C_TRACE( ( _T( "DIscDevice::Flush - return 0x0" ) ) );
       
   857 
       
   858     }
       
   859 
       
   860 
       
   861 // -----------------------------------------------------------------------------
       
   862 // DIscDevice::ConnectionStatus
       
   863 // Function to tell current status of connection to Domestic OS
       
   864 // ( other items were commented in a header ).
       
   865 // -----------------------------------------------------------------------------
       
   866 //
       
   867 TInt DIscDevice::ConnectionStatus()
       
   868     {
       
   869     return iConnectionStatus;
       
   870     }
       
   871 
       
   872 // -----------------------------------------------------------------------------
       
   873 // DIscDevice::DisableIrqs
       
   874 // Function to disable interrupts
       
   875 // ( other items were commented in a header ).
       
   876 // -----------------------------------------------------------------------------
       
   877 //
       
   878 TInt DIscDevice::DisableIrqs()
       
   879     {
       
   880 #ifndef __WINS__
       
   881     return NKern::DisableInterrupts( KIscInterruptLevelTwo );
       
   882 #else //__WINS__
       
   883     EnterCriticalSection( &g_IscDTBCriticalSection );
       
   884     return KErrNone;
       
   885 #endif//__WINS__
       
   886     }
       
   887 
       
   888 // -----------------------------------------------------------------------------
       
   889 // DIscDevice::RestoreIrqs
       
   890 // Function to restore interrupts
       
   891 // ( other items were commented in a header ).
       
   892 // -----------------------------------------------------------------------------
       
   893 //
       
   894 #ifndef __WINS__
       
   895 void DIscDevice::RestoreIrqs( 
       
   896     TInt aLevel )
       
   897     {
       
   898     NKern::RestoreInterrupts( aLevel );
       
   899     
       
   900 #else //__WINS__
       
   901 void DIscDevice::RestoreIrqs( 
       
   902     TInt )
       
   903 	{
       
   904     LeaveCriticalSection( &g_IscDTBCriticalSection );
       
   905 #endif//__WINS__
       
   906     }
       
   907 
       
   908 
       
   909 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   910 
       
   911 // -----------------------------------------------------------------------------
       
   912 // E32Dll
       
   913 // Epoc Kernel Architecture 2 style entry point
       
   914 // ( other items were commented in a header ).
       
   915 // -----------------------------------------------------------------------------
       
   916 //
       
   917 DECLARE_STANDARD_LDD()
       
   918     {
       
   919     DLogicalDevice* device = new DIscDevice;
       
   920     if ( !device )
       
   921         {
       
   922         ASSERT_RESET_ALWAYS( 0,"IscDriver",EIscPanicCreateLogicalDevice );
       
   923         }
       
   924     return device;
       
   925     }
       
   926 
       
   927 //  End of File