diff -r 786b94c6f0a4 -r 5b153be919d4 atext/plugins/limitedpdpplugin/src/limitedpdpplugin.cpp --- a/atext/plugins/limitedpdpplugin/src/limitedpdpplugin.cpp Thu Aug 19 11:01:00 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,420 +0,0 @@ -/* - * Copyright (c) 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: Main handler for incoming requests - * - */ - -#include "limitedpdpplugin.h" -#include -#include "limitedpdpplugincopiedkeys.h" -#include "debug.h" - -// Internal constants -const TInt KDialupOverrideEnabled = 1; -const TInt KCloseTimeoutInterval = 15000000; // 15 secs -const TInt KCleanUpWaitTimeout = 300000; // 300 ms -#ifdef _DEBUG -const TInt KUsecToMSecDivider = 1000; -#endif - -// --------------------------------------------------------------------------- -// Two-phased constructor. -// --------------------------------------------------------------------------- -// -CLimitedPdpPlugin* CLimitedPdpPlugin::NewL() - { - CLimitedPdpPlugin* self = new ( ELeave ) CLimitedPdpPlugin(); - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - return self; - } - -// --------------------------------------------------------------------------- -// Destructor. -// --------------------------------------------------------------------------- -// -CLimitedPdpPlugin::~CLimitedPdpPlugin() - { - TRACE_FUNC_ENTRY - - // Check validity of handles so that Cancel functions can be called - if ( iProperty.Handle() != NULL ) - { - // Cancel just in case in spite of the fact that with current - // architecture cancelling of the operation is not possible - iProperty.Cancel(); - iProperty.Close(); - } - if ( iCancelTimer.Handle() != NULL ) - { - iCancelTimer.Cancel(); - iCancelTimer.Close(); - } - - TRACE_FUNC_EXIT - } - -// --------------------------------------------------------------------------- -// CLimitedPdpPlugin::CLimitedPdpPlugin -// --------------------------------------------------------------------------- -// -CLimitedPdpPlugin::CLimitedPdpPlugin() : - CATExtPluginBase() - { - // Nothing to do here, resources are initialized in ConstructL - } - -// --------------------------------------------------------------------------- -// CLimitedPdpPlugin::ConstructL -// --------------------------------------------------------------------------- -// -void CLimitedPdpPlugin::ConstructL() - { - TRACE_FUNC_ENTRY - - // No need to use cleanup stack here, since these will be closed in - // destructor anyway. - User::LeaveIfError( iCancelTimer.CreateLocal() ); - User::LeaveIfError( iProperty.Attach( KCopyOfConnectionMonitorPS, - KCopyOfDialUpConnection ) ); - iFeatureSupported = EFalse; - iFeatureSupported = CheckFeatureEnablement(); - - TRACE_FUNC_EXIT - } - -// --------------------------------------------------------------------------- -// Reports connection identifier name to the extension plugin. -// --------------------------------------------------------------------------- -// -void CLimitedPdpPlugin::ReportConnectionName( const TDesC8& /*aName*/) - { - } - -// --------------------------------------------------------------------------- -// Reports the support status of an AT command. This is a synchronous API. -// --------------------------------------------------------------------------- -// -TBool CLimitedPdpPlugin::IsCommandSupported( const TDesC8& /*aCmd*/) - { - TRACE_FUNC_ENTRY - // Set the return value according to feature support - TRACE_INFO(( _L("Returning feature support value %d"), - static_cast(iFeatureSupported))); - TRACE_FUNC_EXIT - return iFeatureSupported; - } - -// --------------------------------------------------------------------------- -// Handles an AT command. Cancelling of the pending request is done by -// HandleCommandCancel(). The implementation in the extension plugin should -// be asynchronous, but in this case we must use blocking behavior. This has -// a couple of drawbacks. First, the ATEXT thread is blocked and possible, -// which is against the requirements, and secondly and more importantly, the -// cancelling of this operation is not supported. -// --------------------------------------------------------------------------- -// -void CLimitedPdpPlugin::HandleCommand( const TDesC8& /*aCmd*/, - RBuf8& /*aReply*/, - TBool /*aReplyNeeded*/) - { - TRACE_FUNC_ENTRY - - // Double check that we are actually supporting the feature - if ( iFeatureSupported ) - { - // Request ConnMon to close existing packet data connections - TInt retTemp = CloseExistingConnections(); - if ( retTemp == KErrNone ) - { - retTemp = BlockThreadUntilConnectionsClosed(); - if ( retTemp == KErrNone ) - { - // Internal connections closed. We need to wait for a while - // to make sure that lower layer resources are properly - // cleaned in order to avoid conflicts in resource - // allocation. Again thread needs to be blocked, therefore - // User::After. - // NOTE: This is definitely a bad workaround and unreliable - // approach, but there aren't too many options... - TRACE_INFO(( _L("Block for %d ms for resource cleanup"), - ( KCleanUpWaitTimeout / KUsecToMSecDivider ))); - User::After( KCleanUpWaitTimeout ); - TRACE_INFO(( _L("Cleanup wait completed, exit"))); - } - } - } - - TRACE_FUNC_EXIT - } - -// --------------------------------------------------------------------------- -// Cancels a pending HandleCommand request. -// --------------------------------------------------------------------------- -// -void CLimitedPdpPlugin::HandleCommandCancel() - { - TRACE_FUNC_ENTRY - TRACE_FUNC_EXIT - } - -// --------------------------------------------------------------------------- -// Next reply part's length. -// The value must be equal or less than KDefaultCmdBufLength. -// When the reply from this method is zero, ATEXT stops calling -// GetNextPartOfReply(). -// --------------------------------------------------------------------------- -// -TInt CLimitedPdpPlugin::NextReplyPartLength() - { - TRACE_FUNC_ENTRY - TRACE_FUNC_EXIT - return KErrNotSupported; - } - -// --------------------------------------------------------------------------- -// Gets the next part of reply initially set by HandleCommandComplete(). -// Length of aNextReply must be equal or less than KDefaultCmdBufLength. -// --------------------------------------------------------------------------- -// -TInt CLimitedPdpPlugin::GetNextPartOfReply( RBuf8& /*aNextReply*/) - { - TRACE_FUNC_ENTRY - TRACE_FUNC_EXIT - return KErrNotSupported; - } - -// --------------------------------------------------------------------------- -// Receives unsolicited results. Cancelling of the pending request is done by -// by ReceiveUnsolicitedResultCancel(). The implementation in the extension -// plugin should be asynchronous. -// --------------------------------------------------------------------------- -// -void CLimitedPdpPlugin::ReceiveUnsolicitedResult() - { - TRACE_FUNC_ENTRY - TRACE_FUNC_EXIT - } - -// --------------------------------------------------------------------------- -// Cancels a pending ReceiveUnsolicitedResult request. -// --------------------------------------------------------------------------- -// -void CLimitedPdpPlugin::ReceiveUnsolicitedResultCancel() - { - TRACE_FUNC_ENTRY - TRACE_FUNC_EXIT - } - -// --------------------------------------------------------------------------- -// Reports NVRAM status change to the plugins. -// --------------------------------------------------------------------------- -// -void CLimitedPdpPlugin::ReportNvramStatusChange( const TDesC8& /*aNvram*/) - { - TRACE_FUNC_ENTRY - TRACE_FUNC_EXIT - } - -// --------------------------------------------------------------------------- -// Reports about external handle command error condition. -// This is for cases when for example DUN decided the reply contained an -// error condition but the plugin is still handling the command internally. -// Example: "AT+TEST;+TEST2" was given in command line; "AT+TEST" returns -// non-EReplyTypeError condition and "AT+TEST2" returns EReplyTypeError. -// As the plugin(s) returning the non-EReplyTypeError may still have some -// ongoing operation then these plugins are notified about the external -// EReplyTypeError in command line processing. It is to be noted that -// HandleCommandCancel() is not sufficient to stop the processing as the -// command handling has already finished. -// --------------------------------------------------------------------------- -// -void CLimitedPdpPlugin::ReportExternalHandleCommandError() - { - TRACE_FUNC_ENTRY - TRACE_FUNC_EXIT - } - -// --------------------------------------------------------------------------- -// Reads CenRep key to check whether requested functionality is active. -// --------------------------------------------------------------------------- -// -TBool CLimitedPdpPlugin::CheckFeatureEnablement() - { - TRACE_FUNC_ENTRY - TBool enabled( EFalse ); - CRepository* cmRepository = NULL; - TRAP_IGNORE( cmRepository = CRepository::NewL ( KCopyOfCRUidCmManager ) ); - if ( cmRepository ) - { - TInt overrideValue = KErrNotFound; - TInt retTemp = cmRepository->Get( KCopyOfDialUpOverride, - overrideValue ); - - if ( ( retTemp == KErrNone ) && ( overrideValue - == KDialupOverrideEnabled ) ) - { - enabled = ETrue; - TRACE_INFO(( _L("Dialup override feature enabled"))); - } - } - delete cmRepository; - TRACE_FUNC_EXIT - return enabled; - } - -// --------------------------------------------------------------------------- -// Ask ConnMon to close all existing packet data connections -// --------------------------------------------------------------------------- -// -TInt CLimitedPdpPlugin::CloseExistingConnections() - { - TRACE_FUNC_ENTRY - - TInt dialupState( EConnMonReady ); - TInt retVal( KErrNone ); - - retVal = iProperty.Get( dialupState ); - if ( retVal == KErrNone ) - { - TRACE_INFO(( _L("Current dialup connection PS key value %d"), - dialupState )); - if ( dialupState != EConnMonDialUpInit ) - { - TRACE_INFO(( _L("Setting dialup connection PS key to value %d"), - EConnMonDialUpInit )); - retVal = iProperty.Set( EConnMonDialUpInit ); - } - else - { - // Error situation, we should not end up to this function if - // the connection closing is already in init state. - retVal = KErrNotReady; - } - } - TRACE_INFO(( _L("Closing existing connections done with status %d"), - retVal )); - TRACE_FUNC_EXIT - return retVal; - } - -// --------------------------------------------------------------------------- -// Synchronously block thread until ConnMon indicates that connections are -// closed or operation timeouts. -// --------------------------------------------------------------------------- -// -TInt CLimitedPdpPlugin::BlockThreadUntilConnectionsClosed() - { - TRACE_FUNC_ENTRY - - TInt dialupState( EConnMonDialUpInit ); - TInt retVal( KErrNone ); - - // Read the dialup value just to check if ConnMon has been able to update - // it already to reflect correct state. - retVal = iProperty.Get( dialupState ); - - if ( retVal == KErrNone ) - { - TRACE_INFO(( _L("Dialup connection PS key value before wait: %d"), - dialupState )); - if ( dialupState == EConnMonDialUpInit ) - { - // Block thread until value changes - TRequestStatus propertyStatus; - TRequestStatus timeoutStatus; - // Set operation to timeout if closing internal contexts fails. - // If timeout expires before PS key is updated, this plugin - // will pass the ATD*99# command to modem. Most probably - // that will fail due to lack of resources. However, if - // internal connections are not closed within this timeframe - // there will be problems anyway. So this is only to hasten - // end user feedback on error situation. - iCancelTimer.After( timeoutStatus, KCloseTimeoutInterval ); - - // Loop for property subscription just in case the ConnMon does - // not set correct value in first attempt. The loop exiting is - // done separately below, but this condition is better than using - // while ( ETrue ) - while ( dialupState != EConnMonReady ) - { - iProperty.Subscribe( propertyStatus ); - - TRACE_INFO(( _L("Blocking thread to wait connection closing") )); - User::WaitForRequest( propertyStatus, timeoutStatus ); - - // Wait completed, check which condition was valid - if ( propertyStatus != KRequestPending ) - { - if ( propertyStatus == KErrNone ) - { - // ConnMon changed the value, check if it is valid - TInt retVal = iProperty.Get( dialupState ); - if ( retVal == KErrNone ) - { - if ( dialupState == EConnMonReady ) - { - TRACE_INFO(( _L("Existing connections closed successfully") )); - } - else - { - // Otherwise retry - TRACE_INFO(( _L("Wrong internal connection state (%d), retry"), - dialupState )); - continue; - } - } - } - else - { - retVal = propertyStatus.Int(); - } - // We should exit the loop, either due success of error - // Cancel and wait for timeout request to complete - TRACE_INFO((_L("Existing connections closed (status: %d), cancel timer"), - retVal )); - iCancelTimer.Cancel(); - // Wait... If the completion of Cancel() is not waited - // here, CActiveScheduler will panic due to stray signal - // (E32USER-CBase panic code 46) - User::WaitForRequest( timeoutStatus ); - TRACE_INFO(( _L("Timeout cancelled (timeoutStatus: %d), exit wait"), - timeoutStatus.Int() )); - break; - } - else if ( timeoutStatus != KRequestPending ) - { - // Timeout or error, exit - TRACE_INFO(( _L("Wait for existing connections timeouted (status: %d)"), - timeoutStatus.Int() )); - // Cancel PS subscription and wait for its completion - iProperty.Cancel(); - User::WaitForRequest( propertyStatus ); - retVal = iProperty.Set( EConnMonDialUpClosed ); - TRACE_INFO(( _L("Subscription cancelled (status: %d) and state reset, exit"), - propertyStatus.Int() )); - retVal = KErrTimedOut; - break; - } - } - } - } - // All done, exit - TRACE_INFO(( _L("Exiting from wait with status %d"), retVal )); - - TRACE_FUNC_EXIT - return retVal; - } -