diff -r 3dcb815346df -r 4096754ee773 localconnectivityservice/dun/utils/src/DunDownstream.cpp --- a/localconnectivityservice/dun/utils/src/DunDownstream.cpp Thu Aug 19 10:46:39 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,468 +0,0 @@ -/* -* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: Definitions needed for one "stream" of CDunTransporter -* -*/ - - -/* - * TODO: When local media is of type RComm, listening on it is started with - * RComm::NotifyDataAvailable() call. Check that USB ACM port and Irda RCOMM - * (and any other new media in the future) behaves correctly so that when - * RComm::ReadOneOrMore() is issued, the read is issued immediately without - * checking for new data. If waiting for new data happens in this - * NotifyDataAvailable/ReadOneOrMore combination, raise a defect to Symbian. - */ - -#include "DunTransporter.h" -#include "DunDownstream.h" -#include "DunUpstream.h" -#include "DunDebug.h" - -// --------------------------------------------------------------------------- -// Two-phased constructor. -// --------------------------------------------------------------------------- -// -CDunDownstream* CDunDownstream::NewL( MDunTransporterUtilityAux* aUtility ) - { - CDunDownstream* self = new (ELeave) CDunDownstream( aUtility ); - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - return self; - } - -// --------------------------------------------------------------------------- -// Destructor. -// --------------------------------------------------------------------------- -// -CDunDownstream::~CDunDownstream() - { - FTRACE(FPrint( _L("CDunDownstream::~CDunDownstream()" ))); - ResetData(); - FTRACE(FPrint( _L("CDunDownstream::~CDunDownstream() complete" ))); - } - -// --------------------------------------------------------------------------- -// Resets data to initial values -// --------------------------------------------------------------------------- -// -void CDunDownstream::ResetData() - { - // APIs affecting this: - // IssueRequest() - Stop(); - // InitializeForDataPushing() - delete iPushData.iDataPusher; - iPushData.iDataPusher = NULL; - // AddConnMonCallbackL() - iCallbacksR.Close(); - iCallbacksW.Close(); - // AddSkippedErrorL() - iOkErrorsR.Close(); - iOkErrorsW.Close(); - // Internal - Initialize(); - } - -// --------------------------------------------------------------------------- -// Initializes this stream for AT command notifications -// --------------------------------------------------------------------------- -// -TInt CDunDownstream::InitializeForDataPushing( - MDunAtCmdHandler* aAtCmdHandler ) - { - FTRACE(FPrint( _L("CDunDownstream::InitializeForDataPushing()" ) )); - if ( iPushData.iDataPusher || iPushData.iAtCmdHandler ) // optional - { - FTRACE(FPrint( _L("CDunDownstream::InitializeForDataPushing() (already exists) complete" ) )); - return KErrAlreadyExists; - } - if ( !aAtCmdHandler ) - { - FTRACE(FPrint( _L("CDunDownstream::InitializeForDataPushing() (aAtCmdHandler) not initialized!" ) )); - return KErrGeneral; - } - CDunDataPusher* dataPusher = NULL; - TRAPD( retTrap, dataPusher = CDunDataPusher::NewL(*this,this) ); - if ( retTrap != KErrNone ) - { - FTRACE(FPrint( _L("CDunDownstream::InitializeForDataPushing() (trapped!) complete" ) )); - return retTrap; - } - if ( iComm ) - { - dataPusher->SetMedia( iComm ); - } - else if ( iSocket ) - { - dataPusher->SetMedia( iSocket ); - } - iPushData.iDataPusher = dataPusher; - iPushData.iAtCmdHandler = aAtCmdHandler; - FTRACE(FPrint( _L("CDunDownstream::InitializeForDataPushing() complete" ) )); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// Checks if data is in queue -// --------------------------------------------------------------------------- -// -TBool CDunDownstream::IsDataInQueue( const TDesC8* aDataToPush ) - { - FTRACE(FPrint( _L("CDunDownstream::IsDataInQueue()" ) )); - if ( !iPushData.iDataPusher ) - { - FTRACE(FPrint( _L("CDunDownstream::IsDataInQueue() (iPushData.iDataPusher not initialized!) complete" ))); - return EFalse; - } - TInt foundIndex = iPushData.iDataPusher->FindEventFromQueue( aDataToPush ); - FTRACE(FPrint( _L("CDunDownstream::IsDataInQueue() complete" ) )); - return ( foundIndex >= 0 ) ? ETrue : EFalse; - } - -// --------------------------------------------------------------------------- -// Adds data to event queue and starts sending if needed -// --------------------------------------------------------------------------- -// -TInt CDunDownstream::AddToQueueAndSend( const TDesC8* aDataToPush, - MDunCompletionReporter* aCallback ) - { - FTRACE(FPrint( _L("CDunDownstream::AddToQueueAndSend()" ) )); - if ( !iPushData.iDataPusher ) - { - FTRACE(FPrint( _L("CDunDownstream::AddToQueueAndSend() (iPushData.iDataPusher not initialized!) complete" ))); - return KErrGeneral; - } - // Add to event queue. If something went wrong, just return - TInt retTemp = iPushData.iDataPusher->AddToEventQueue( aDataToPush, aCallback ); - if ( retTemp != KErrNone ) - { - FTRACE(FPrint( _L("CDunDownstream::AddToQueueAndSend() (ERROR) complete" ))); - return retTemp; - } - // Now push the data. If already active, push will start later, if not - // active it will start immediately. - iPushData.iDataPusher->SendQueuedData(); - FTRACE(FPrint( _L("CDunDownstream::AddToQueueAndSend() complete" ) )); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// Starts downstream by issuing read request -// --------------------------------------------------------------------------- -// -TInt CDunDownstream::StartStream() - { - FTRACE(FPrint( _L("CDunDownstream::StartStream()" ) )); - FTRACE(FPrint( _L("CDunDownstream::StartStream() (buffer=0x%08X)" ), iBufferPtr )); - // Note: only start URC here. - // The downstream read request is started when command mode ends. - // This is done to make the data arrive in the correct order (reply vs. - // data) with "ATD" command. - TInt retVal = KErrNone; - if ( iPushData.iAtCmdHandler ) - { - retVal = iPushData.iAtCmdHandler->StartUrc(); - } - FTRACE(FPrint( _L("CDunDownstream::StartStream() complete" ) )); - return retVal; - } - -// --------------------------------------------------------------------------- -// Stops transfer for read or write endpoints -// --------------------------------------------------------------------------- -// -TInt CDunDownstream::Stop( TBool aStopMplex ) - { - FTRACE(FPrint( _L("CDunDownstream::Stop() (Dir=%d)" ), iDirection)); - if ( !iPushData.iDataPusher ) - { - FTRACE(FPrint( _L("CDunDownstream::Stop() (iPushData.iDatapusher not initialized!) complete" ))); - return KErrGeneral; - } - // Stop the downstream related AT command handling functionality - if ( aStopMplex ) // optional - { - if ( iPushData.iAtCmdHandler ) - { - iPushData.iAtCmdHandler->StopAtCmdHandling(); - } - // Stop the multiplexer separately - iPushData.iDataPusher->Stop(); - } - if ( iTransferState != EDunStateTransferring ) - { - FTRACE(FPrint( _L("CDunDownstream::Stop() (not ready) complete" ))); - return KErrNotReady; - } - // Stop only current operation - if ( iOperationType == EDunOperationTypeRead ) - { - if ( iNetwork ) - { - iNetwork->ReadCancel(); - Cancel(); - FTRACE(FPrint( _L("CDunDownstream::Stop() (Network) cancelled" ))); - } - } - else if ( iOperationType == EDunOperationTypeWrite ) - { - iPushData.iDataPusher->StopOneEvent( iBufferPtr ); - } - iTransferState = EDunStateIdle; - FTRACE(FPrint( _L("CDunDownstream::Stop() complete" ))); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// CDunDownstream::CDunDownstream -// --------------------------------------------------------------------------- -// -CDunDownstream::CDunDownstream( MDunTransporterUtilityAux* aUtility ) : - iUtility( aUtility ) - { - Initialize(); - } - -// --------------------------------------------------------------------------- -// CDunDownstream::ConstructL -// --------------------------------------------------------------------------- -// -void CDunDownstream::ConstructL() - { - FTRACE(FPrint( _L("CDunDownstream::ConstructL()" ) )); - if ( !iUtility ) - { - User::Leave( KErrGeneral ); - } - FTRACE(FPrint( _L("CDunDownstream::ConstructL() complete" ) )); - } - -// --------------------------------------------------------------------------- -// Initializes this class -// --------------------------------------------------------------------------- -// -void CDunDownstream::Initialize() - { - // Don't initialize iUtility here (it is set through NewL) - iPushData.iDataMode = EFalse; - iPushData.iDataPusher = NULL; - iPushData.iAtCmdHandler = NULL; - } - -// --------------------------------------------------------------------------- -// Issues transfer request for this stream -// --------------------------------------------------------------------------- -// -TInt CDunDownstream::IssueRequest() - { - // Set direction - iDirection = static_cast( EDunStreamTypeDownstream | iOperationType ); - - FTRACE(FPrint( _L("CDunDownstream::IssueRequest() (Dir=%d)" ), iDirection)); - if ( !iPushData.iDataPusher ) - { - FTRACE(FPrint( _L("CDunDownstream::IssueRequest() (iPushData.iDataPusher not initialized!) complete" ) )); - return KErrGeneral; - } - - if ( iTransferState != EDunStateIdle ) - { - FTRACE(FPrint( _L("CDunDownstream::IssueRequest() (not ready) complete" ) )); - return KErrNotReady; - } - - if ( iOperationType == EDunOperationTypeRead ) - { - iBufferPtr->SetLength( iBufferPtr->MaxLength() ); - FTRACE(FPrint( _L("CDunDownstream::IssueRequest() trying to read %d bytes... (Dir=%d)" ), iBufferPtr->Length(), iDirection)); - } - else // iOperationType == EDunOperationTypeWrite - { - FTRACE(FPrint( _L("CDunDownstream::IssueRequest() writing %d bytes... (Dir=%d)" ), iBufferPtr->Length(), iDirection)); - } - - switch ( iDirection ) - { - case EDunReaderDownstream: - iStatus = KRequestPending; - iNetwork->ReadOneOrMore( iStatus, *iBufferPtr ); - SetActive(); - FTRACE(FPrint( _L("CDunDownstream::IssueRequest() RComm ReadOneOrMore() requested" ) )); - break; - case EDunWriterDownstream: - AddToQueueAndSend( iBufferPtr, this ); - break; - default: - FTRACE(FPrint( _L("CDunDownstream::IssueRequest() (ERROR) complete" ) )); - return KErrGeneral; - } - - iTransferState = EDunStateTransferring; - - FTRACE(FPrint( _L("CDunDownstream::IssueRequest() (Dir=%d) complete" ), iDirection)); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// From class CActive. -// Gets called when endpoint data read complete -// --------------------------------------------------------------------------- -// -void CDunDownstream::RunL() - { - FTRACE(FPrint( _L("CDunDownstream::RunL() (Dir=%d)" ), iDirection)); - iTransferState = EDunStateIdle; - if ( iOperationType != EDunOperationTypeRead ) - { - FTRACE(FPrint( _L("CDunDownstream::RunL() (wrong operation type!) complete" ))); - return; - } - - TBool isError; - TInt retTemp = iStatus.Int(); - TInt stop = ProcessErrorCondition( retTemp, isError ); - - if ( !stop ) // no real error detected -> continue - { - if ( !isError ) - { - // Operation type was read so now set to write - iOperationType = EDunOperationTypeWrite; - } // if ( !isError ) - - IssueRequest(); - - } // if ( !stop ) - else // stop -> tear down connection - { - // Now CDunDataPusher notifies to write case so here we just notify the - // read case. - TDunConnectionReason connReason; - connReason.iReasonType = EDunReasonTypeRW; - connReason.iContext = GetMediaContext( EDunStreamTypeDownstream ); - connReason.iSignalType = 0; - connReason.iSignalHigh = EFalse; - connReason.iDirection = iDirection; - connReason.iErrorCode = retTemp; - iUtility->DoNotifyConnectionNotOk( iComm, - iSocket, - connReason, - iCallbacksR ); - FTRACE(FPrint( _L("CDunDownstream::RunL() stop" ))); - } // else - - FTRACE(FPrint( _L("CDunDownstream::RunL() complete" ))); - } - -// --------------------------------------------------------------------------- -// From class CActive. -// Gets called on cancel -// --------------------------------------------------------------------------- -// -void CDunDownstream::DoCancel() - { - } - -// --------------------------------------------------------------------------- -// From class MDunStreamManipulator. -// Gets called when outside party wants to push data to the existing stream -// --------------------------------------------------------------------------- -// -TInt CDunDownstream::NotifyDataPushRequest( const TDesC8* aDataToPush, - MDunCompletionReporter* aCallback ) - { - FTRACE(FPrint( _L("CDunDownstream::NotifyDataPushRequest()" ))); - // If in data mode push the reply anyway as "CONNECT" or "NO CARRIER" - // reply could arrive before/after the command mode information itself. - TInt retVal = AddToQueueAndSend( aDataToPush, aCallback ); - FTRACE(FPrint( _L("CDunDownstream::NotifyDataPushRequest() complete" ))); - return retVal; - } - -// --------------------------------------------------------------------------- -// From class MDunCompletionReporter. -// Gets called when data push is complete -// --------------------------------------------------------------------------- -// -void CDunDownstream::NotifyDataPushComplete( TBool aAllPushed ) - { - FTRACE(FPrint( _L("CDunDownstream::NotifyDataPushComplete()" ))); - // Next just skip the notifications of atomic operations because also this - // class initiates the pushing of atomic data. - if ( !aAllPushed ) - { - FTRACE(FPrint( _L("CDunDownstream::NotifyDataPushComplete() (continue) complete" ))); - return; - } - iTransferState = EDunStateIdle; - iOperationType = EDunOperationTypeUndefined; - if ( !iPushData.iDataPusher ) - { - FTRACE(FPrint( _L("CDunDownstream::NotifyDataPushComplete() (iPushData.iDataPusher not initialized!) complete" ))); - return; - } - // Now the multiplexer might have pushed the contained data in this class - // or it might have pushed only the external data. If the pushed data - // contains this classes data then reissue request, otherwise just clear - // the queue. - TInt foundIndex = iPushData.iDataPusher->FindEventFromQueue( iBufferPtr ); - iPushData.iDataPusher->SignalCompletionAndClearQueue(); - FTRACE(FPrint( _L("CDunDownstream::NotifyDataPushComplete() (find event)" ))); - if ( foundIndex >= 0 ) - { - // Restart the reading from Dataport only if in data mode - FTRACE(FPrint( _L("CDunDownstream::NotifyDataPushComplete() (issue request)" ))); - if ( iPushData.iDataMode ) - { - iOperationType = EDunOperationTypeRead; - IssueRequest(); - } - } - FTRACE(FPrint( _L("CDunDownstream::NotifyDataPushComplete() complete" ))); - } - -// --------------------------------------------------------------------------- -// From class MDunCmdModeMonitor. -// Notifies about command mode start -// --------------------------------------------------------------------------- -// -void CDunDownstream::NotifyCommandModeStart() - { - FTRACE(FPrint( _L("CDunDownstream::NotifyCommandModeStart()" ))); - iPushData.iDataMode = EFalse; - // Now the data mode has ended. - // If read operation then cancel it. - if ( iOperationType == EDunOperationTypeRead ) - { - Stop( EFalse ); - } - FTRACE(FPrint( _L("CDunDownstream::NotifyCommandModeStart() complete" ))); - } - -// --------------------------------------------------------------------------- -// From class MDunCmdModeMonitor. -// Notifies about command mode end -// --------------------------------------------------------------------------- -// -void CDunDownstream::NotifyCommandModeEnd() - { - FTRACE(FPrint( _L("CDunDownstream::NotifyCommandModeEnd()" ))); - iPushData.iDataMode = ETrue; - // Command mode ends here so start reading from Dataport - iOperationType = EDunOperationTypeRead; - IssueRequest(); - FTRACE(FPrint( _L("CDunDownstream::NotifyCommandModeEnd() complete" ))); - }