--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/server/src/atextsession.cpp Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,1086 @@
+/*
+* Copyright (c) 2009 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:
+*
+*/
+
+
+#include <badesca.h>
+#include <atextpluginbase.h>
+#include <atext.h>
+#include "atextsrv.h"
+#include "atextclientsrv.h"
+#include "atextsession.h"
+#include "utils.h"
+#include "debug.h"
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CATExtSession* CATExtSession::NewL( CATExtSrv& aServer,
+ const TVersion& aVersion )
+ {
+ return new (ELeave) CATExtSession( aServer, aVersion );
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CATExtSession::~CATExtSession()
+ {
+ TRACE_FUNC_ENTRY
+ Destruct( EFalse );
+ TRACE_FUNC_EXIT
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of client requests passed to the server
+// ---------------------------------------------------------------------------
+//
+void CATExtSession::ServiceL( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( iVersion.iMajor==KServerMajorVersionNumber &&
+ iVersion.iMinor==KServerMinorVersionNumber &&
+ iVersion.iBuild==KServerBuildVersionNumber )
+ {
+ DoServiceL( aMessage );
+ }
+ else
+ {
+ aMessage.Complete( KErrNotSupported );
+ }
+ TRACE_FUNC_EXIT
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of client requests passed to the server
+// ---------------------------------------------------------------------------
+//
+void CATExtSession::DoServiceL( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ switch ( aMessage.Function() )
+ {
+ case EATExtSetExtensionInterface:
+ {
+ TRAPD( retTrap, IpcSetInterfaceL(aMessage) );
+ if ( retTrap != KErrNone )
+ {
+ aMessage.Complete( retTrap );
+ }
+ else if ( !iMetadata->SupportExists() )
+ {
+ aMessage.Complete( KErrNotFound );
+ }
+ else
+ {
+ aMessage.Complete( KErrNone );
+ }
+ break;
+ }
+ case EATExtSynchronousClose:
+ {
+ IpcSynchronousClose( aMessage );
+ }
+ break;
+ case EATExtHandleCommand:
+ {
+ IpcHandleCommand( aMessage );
+ break;
+ }
+ case EATExtCancelHandleCommand:
+ {
+ IpcCancelHandleCommand( aMessage );
+ break;
+ }
+ case EATExtGetNextPartOfReply:
+ {
+ IpcGetNextPartOfReply( aMessage );
+ break;
+ }
+ case EATExtNumberOfPlugins:
+ {
+ IpcNumberOfPlugins( aMessage );
+ }
+ break;
+ case EATExtReceiveUnsolicitedResult:
+ {
+ IpcReceiveUnsolicitedResult( aMessage );
+ break;
+ }
+ case EATExtCancelReceiveUnsolicitedResult:
+ {
+ IpcCancelReceiveUrc( aMessage );
+ break;
+ }
+ case EATExtMarkUrcHandlingOwnership:
+ {
+ IpcMarkUrcHandlingOwnership( aMessage );
+ break;
+ }
+ case EATExtReceiveEcomPluginChange:
+ {
+ IpcReceiveEcomPluginChange( aMessage );
+ }
+ break;
+ case EATExtCancelReceiveEcomPluginChange:
+ {
+ IpcCancelReceiveEcomPluginChange( aMessage );
+ }
+ break;
+ case EATExtReportQuietModeChange:
+ {
+ IpcReportQuietModeChange( aMessage );
+ }
+ break;
+ case EATExtReportVerboseModeChange:
+ {
+ IpcReportVerboseModeChange( aMessage );
+ }
+ break;
+ case EATExtReportCharacterChange:
+ {
+ IpcReportCharacterChange( aMessage );
+ }
+ break;
+ case EATExtReportListenerUpdateReady:
+ {
+ IpcReportListenerUpdateReady( aMessage );
+ }
+ break;
+ case EATExtBroadcastNvramStatusChange:
+ {
+ IpcBroadcastNvramStatusChange( aMessage );
+ }
+ break;
+ case EATExtReportExternalHandleCommandError:
+ {
+ IpcReportExternalHandleCommandError( aMessage );
+ }
+ break;
+ case EATExtReportHandleCommandAbort:
+ {
+ IpcReportHandleCommandAbort( aMessage );
+ }
+ break;
+ case EATExtGetNextSpecialCommand:
+ {
+ IpcGetNextSpecialCommand( aMessage );
+ }
+ break;
+ default:
+ {
+ aMessage.Complete( KErrNotSupported );
+ break;
+ }
+ }
+ TRACE_FUNC_EXIT
+ }
+
+// ---------------------------------------------------------------------------
+// CATExtSession::CATExtSession
+// ---------------------------------------------------------------------------
+//
+CATExtSession::CATExtSession( CATExtSrv& aServer, const TVersion& aVersion ) :
+ iServer( aServer ),
+ iListener( NULL ),
+ iMetadata( NULL ),
+ iVersion( aVersion )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of setting up interface
+// ---------------------------------------------------------------------------
+//
+void CATExtSession::IpcSetInterfaceL( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( iMetadata || iListener )
+ {
+ TRACE_FUNC_EXIT
+ User::Leave( KErrGeneral );
+ }
+ REComSession& ecomSession = REComSession::OpenL();
+ CleanupClosePushL( ecomSession );
+ TPckgBuf<TUid> ifUidPckgBuf;
+ TInt retTemp = ReadStructFromMessage( ifUidPckgBuf,
+ EATExtConnectParamUid,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ TRACE_FUNC_EXIT
+ User::Leave( retTemp );
+ }
+ RBuf8 connectionName;
+ CleanupClosePushL( connectionName );
+ retTemp = ReadStringFromMessage( connectionName,
+ EATExtConnectParamName,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ TRACE_FUNC_EXIT
+ User::Leave( retTemp );
+ }
+ // Create listener
+ CATExtListen* listener = CATExtListen::NewLC( ecomSession, this );
+ listener->AddInterfaceUid( ifUidPckgBuf() );
+ // Create metadata. Pass iListener to add the UIDs
+ CATExtMetadata* metadata = CATExtMetadata::NewLC( ecomSession,
+ listener,
+ *this );
+ metadata->CreateImplementationMetadataL( ifUidPckgBuf(), connectionName );
+ listener->IssueRequest();
+ CleanupStack::Pop( metadata );
+ CleanupStack::Pop( listener );
+ CleanupStack::PopAndDestroy( &connectionName );
+ CleanupStack::Pop( &ecomSession );
+ iEComSession = ecomSession;
+ iListener = listener;
+ iMetadata = metadata;
+ TRACE_FUNC_EXIT
+ }
+
+// ---------------------------------------------------------------------------
+// Synchronously closes the session
+// Optional: client can do either Close() or SynchronousClose()
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcSynchronousClose( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ Destruct( ETrue );
+ aMessage.Complete( KErrNone );
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of AT commands
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcHandleCommand( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ if ( aMessage.GetDesMaxLength(EATExtHandleCmdParamReply) !=
+ KDefaultCmdBufLength )
+ {
+ aMessage.Complete( KErrBadDescriptor );
+ TRACE_FUNC_EXIT
+ return KErrBadDescriptor;
+ }
+ TATExtCompletionInfo complInfo;
+ complInfo.iProcessed = EFalse;
+ complInfo.iReplyExpected = EFalse;
+ TInt retTemp = iMetadata->HandleCommand( aMessage, complInfo );
+ if ( retTemp != KErrNone )
+ {
+ TRACE_INFO(( _L8("Command handled with failure %d"), retTemp ));
+ iMetadata->CompleteCommandMessage( NULL,
+ retTemp,
+ EFalse, // no error reply
+ EReplyTypeUndefined, // general error condition
+ EFalse ); // no multipart
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ // Next check the case without support: in this case a reply
+ // can't be expected but return the "ERROR" anyway if needed.
+ if ( !complInfo.iProcessed )
+ {
+ // Return "ERROR".
+ TRACE_INFO(( _L8("Command handled without support: return \"ERROR\"") ));
+ iMetadata->CompleteCommandMessage( NULL,
+ KErrNone,
+ ETrue, // error reply
+ EReplyTypeError, // error type
+ EFalse ); // no multipart
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ // Third, check a case where there is support but reply is not
+ // expected. In this case "" must be returned to complete processing.
+ if ( !complInfo.iReplyExpected )
+ {
+ // Return ""
+ TRACE_INFO(( _L8("Command handled with support but no reply: return \"\"") ));
+ iMetadata->CompleteCommandMessage( NULL,
+ KErrNone,
+ EFalse, // no error reply
+ EReplyTypeOther, // reply type from plugin
+ EFalse ); // no multipart
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ // The rest are for known command with reply. This case is handled in
+ // HandleCommand().
+ TRACE_INFO(( _L8("Command handled: wait for asynchronous reply or do nothing") ));
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of pending AT command cancel
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcCancelHandleCommand( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TInt retVal = iMetadata->CancelHandleCommand();
+ aMessage.Complete( retVal );
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of getting the next part of a reply for
+// IpcHandleCommand().
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcGetNextPartOfReply( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TInt retTemp = iMetadata->GetNextPartOfReply( aMessage );
+ if ( retTemp != KErrNone )
+ {
+ aMessage.Complete( retTemp );
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ // Note: Completed in metadata if successfull
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of number of plugins. This information is needed to
+// instantiate one or more listeners by the user of the client.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcNumberOfPlugins( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TInt retVal = iMetadata->NumberOfPlugins();
+ aMessage.Complete( retVal );
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of receiving unsolicited result codes. Note that
+// IpcMarkUrcHandlingOwnership() must be called immediately after this in
+// order for the message to receive their destination.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcReceiveUnsolicitedResult( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ if ( aMessage.GetDesMaxLength(EATExtReceiveUrcCmdParamBuf) !=
+ KDefaultUrcBufLength )
+ {
+ aMessage.Complete( KErrBadDescriptor );
+ TRACE_FUNC_EXIT
+ return KErrBadDescriptor;
+ }
+ TPckgBuf<TUid> pluginUidPckgBuf;
+ TInt retTemp = ReadStructFromMessage( pluginUidPckgBuf,
+ EATExtReceiveUrcCmdParamUid,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ aMessage.Complete( retTemp );
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ TRAPD( retTrap, iMetadata->StartUrcReceivingL(aMessage,pluginUidPckgBuf()) );
+ if ( retTrap != KErrNone )
+ {
+ aMessage.Complete( retTrap );
+ TRACE_FUNC_EXIT
+ return retTrap;
+ }
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of pending receiving unsolicited result code cancel
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcCancelReceiveUrc( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TPckgBuf<TUid> pluginUidPckgBuf;
+ TInt retTemp = ReadStructFromMessage( pluginUidPckgBuf,
+ EATExtCancelReceiveUrcCmdParamUid,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ aMessage.Complete( retTemp );
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ TInt retVal = iMetadata->CancelUrcReceiving( pluginUidPckgBuf() );
+ aMessage.Complete( retVal );
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of marking URC handling ownership. Call to this
+// function must be done immediately after the call to
+// IpcReceiveUnsolicitedResult().
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcMarkUrcHandlingOwnership( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TInt retVal = iMetadata->MarkUrcHandlingOwnership( aMessage );
+ aMessage.Complete( retVal );
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of ECOM plugin change notifications
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcReceiveEcomPluginChange( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ if ( iEcomStatusMessage.Handle() )
+ {
+ aMessage.Complete( KErrBadHandle );
+ TRACE_FUNC_EXIT
+ return KErrBadHandle;
+ }
+ iEcomStatusMessage = aMessage;
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of pending ECOM plugin change notification cancel
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcCancelReceiveEcomPluginChange(
+ const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ if ( !iEcomStatusMessage.Handle() )
+ {
+ aMessage.Complete( KErrBadHandle );
+ TRACE_FUNC_EXIT
+ return KErrBadHandle;
+ }
+ iEcomStatusMessage.Complete( KErrCancel );
+ aMessage.Complete( KErrNone );
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of quiet mode change reporting. When quiet mode is on
+// the behavior is the same as with AT command "ATQ1: Result code
+// suppression". When quiet mode is on then verbose mode setting has no
+// effect.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcReportQuietModeChange( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TPckgBuf<TBool> quietModePckgBuf;
+ TInt retTemp = ReadStructFromMessage( quietModePckgBuf,
+ EATExtReportQuietModeChangeParamMode,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ aMessage.Complete( retTemp );
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ iMetadata->SetQuietMode( quietModePckgBuf() );
+ aMessage.Complete( KErrNone );
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of verbose mode change reporting. When verbose mode
+// is on the behavior is the same as with AT command "ATV1: DCE Response
+// format". If quiet mode is on then this setting has no effect.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcReportVerboseModeChange( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TPckgBuf<TBool> verboseModePckgBuf;
+ TInt retTemp = ReadStructFromMessage( verboseModePckgBuf,
+ EATExtReportVerboseModeChangeParamMode,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ aMessage.Complete( retTemp );
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ iMetadata->SetVerboseMode( verboseModePckgBuf() );
+ aMessage.Complete( KErrNone );
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of character change reporting. The change to carriage
+// return, line feed and backspace characters is reported to
+// CATExtPluginBase's protected data so that the it can easily be used by the
+// plugin implementation.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcReportCharacterChange( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TPckgBuf<TATExtensionCharType> charTypePckgBuf;
+ TInt retTemp = ReadStructFromMessage( charTypePckgBuf,
+ EATExtReportCharacterChangeParamType,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ aMessage.Complete( retTemp );
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ TPckgBuf<TInt8> charPckgBuf;
+ retTemp = ReadStructFromMessage( charPckgBuf,
+ EATExtReportCharacterChangeParamChar,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ aMessage.Complete( retTemp );
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ TInt retVal = iMetadata->SetCharacterValue( charTypePckgBuf(),
+ charPckgBuf() );
+ aMessage.Complete( retVal );
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of reporting listener update readiness. Client side
+// listener has to use this after it has updates its own internal states after
+// ECOM plugin change notification.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcReportListenerUpdateReady( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TPckgBuf<TUid> pluginUidPckgBuf;
+ TInt retTemp = ReadStructFromMessage( pluginUidPckgBuf,
+ EATExtReportListenerUpdateParamUid,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ aMessage.Complete( retTemp );
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ TPckgBuf<TATExtensionEcomType> updateTypePckgBuf;
+ retTemp = ReadStructFromMessage( updateTypePckgBuf,
+ EATExtReportListenerUpdateParamType,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ aMessage.Complete( retTemp );
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ TInt retVal = KErrNone;
+ switch ( updateTypePckgBuf() )
+ {
+ case EEcomTypeUninstall:
+ // 3. When client notifies of removal, remove the locked entry from metadata.
+ // See also NotifyPluginUninstallation()
+ retVal = iMetadata->RemoveImplementation( pluginUidPckgBuf() );
+ break;
+ case EEcomTypeInstall:
+ // 4. When client notifies installation, remove the lock from metadata.
+ // See also NotifyPluginInstallation()
+ retVal = iMetadata->UnlockPluginAccess( pluginUidPckgBuf() );
+ break;
+ default:
+ retVal = KErrNotSupported;
+ break;
+ }
+ aMessage.Complete( retVal );
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of NVRAM status change broadcasting. The NVRAM status
+// change is broadcasted to all of the plugins.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcBroadcastNvramStatusChange( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ RBuf8 nvramStatus;
+ TInt retTemp = ReadStringFromMessage( nvramStatus,
+ EATExtBroadcastNvramChangeParamNvram,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ aMessage.Complete( retTemp );
+ nvramStatus.Close();
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ TInt retVal = iMetadata->BroadcastNvramStatusChange( nvramStatus );
+ aMessage.Complete( retVal );
+ nvramStatus.Close();
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of reporting 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.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcReportExternalHandleCommandError(
+ const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TInt retVal = iMetadata->ReportExternalHandleCommandError();
+ aMessage.Complete( retVal );
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of reporting about abort condition in command
+// handling.
+// This is for cases when for example DUN decided an abort condition was
+// received from DTE (ITU-T V.250 5.6.1). This API is for notifying the
+// plugin that abort was requested. However the plugin currently handling
+// the command may ignore the request if it doesn't support abort for the
+// command or it may return the changed condition with
+// HandleCommandCompleted()
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcReportHandleCommandAbort( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TInt retVal = iMetadata->ReportHandleCommandAbort( aMessage );
+ aMessage.Complete( retVal );
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Handles the servicing of getting the next special command RSS file entry.
+// These commands are commands with a matching start but with any ending
+// sequence. Command "ATD*99***1#" is one of these and the number of these
+// commands should be kept minimal.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::IpcGetNextSpecialCommand( const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ aMessage.Complete( KErrGeneral );
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TPckgBuf<TBool> firstSearchPckgBuf;
+ TInt retTemp = ReadStructFromMessage( firstSearchPckgBuf,
+ EATExtGetNextSpecialCmdParamFirst,
+ aMessage );
+ if ( retTemp != KErrNone )
+ {
+ aMessage.Complete( retTemp );
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ TInt retVal = iMetadata->GetNextSpecialCommand( aMessage,
+ firstSearchPckgBuf() );
+ aMessage.Complete( retVal );
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// Reads a string from a message
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::ReadStringFromMessage( RBuf8& aBuffer,
+ TInt aDataSlot,
+ const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ TInt retVal = KErrNone;
+ TInt desLength = aMessage.GetDesLength( aDataSlot );
+ if ( desLength <= 0 )
+ {
+ TRACE_FUNC_EXIT
+ return KErrArgument;
+ }
+ retVal = aBuffer.Create( desLength );
+ if ( retVal == KErrNone )
+ {
+ retVal = aMessage.Read( aDataSlot, aBuffer );
+ TRACE_INFO(( _L("Read returned %d"), retVal ));
+ }
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// Reads a struct from a message
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::ReadStructFromMessage( TDes8& aBuffer,
+ TInt aDataSlot,
+ const RMessage2& aMessage )
+ {
+ TRACE_FUNC_ENTRY
+ TInt retVal = KErrNone;
+ TInt desLength = aMessage.GetDesLength( aDataSlot );
+ if ( desLength <= 0 )
+ {
+ TRACE_FUNC_EXIT
+ return KErrArgument;
+ }
+ retVal = aMessage.Read( aDataSlot, aBuffer );
+ TRACE_INFO(( _L("Read returned %d"), retVal ));
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// Destructs objects/associations for the current session
+// ---------------------------------------------------------------------------
+//
+void CATExtSession::Destruct( TBool aSyncClose )
+ {
+ TRACE_FUNC_ENTRY
+ if ( iEcomStatusMessage.Handle() )
+ {
+ iEcomStatusMessage.Complete( KErrServerTerminated );
+ }
+ delete iListener;
+ iListener = NULL;
+ delete iMetadata;
+ iMetadata = NULL;
+ iEComSession.Close();
+ if ( !aSyncClose )
+ {
+ REComSession::FinalClose();
+ iServer.ClientClosed( *this );
+ }
+ TRACE_FUNC_EXIT
+ }
+
+// ---------------------------------------------------------------------------
+// From MATExtPluginObserver.
+// Called by extension plugins when there is an unsolicited result code
+// should be sent to destination.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::SendUnsolicitedResult( CATExtPluginBase* aPlugin,
+ const TDesC8& aAT )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ iMetadata->CompleteUrcMessage( aAT, aPlugin );
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// From MATExtPluginObserver.
+// Called by Extension Plugins to inform ATEXT that a command handling has
+// been completed or rejected.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::HandleCommandCompleted( CATExtPluginBase* aPlugin,
+ TInt aError,
+ TATExtensionReplyType aReplyType )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TInt retVal = iMetadata->CompleteCommandMessage( aPlugin,
+ aError,
+ EFalse, // no error reply
+ aReplyType, // type of reply
+ ETrue ); // multipart
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// From MATExtPluginObserver.
+// Called by concrete extension plugin to inform the array of supported
+// commands should be returned
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::GetSupportedCommands( CATExtPluginBase* aPlugin,
+ RPointerArray<HBufC8>& aCmds )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TInt retVal = iMetadata->GetSupportedCommands( aPlugin, aCmds );
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// From MATExtPluginObserver.
+// Called by the destructor of CATExtPluginBase. A concrete service provider
+// implementation should not touch this.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::ATExtPluginClosed( CATExtPluginBase* aPlugin )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ TInt retVal = iMetadata->RemoveImplementationInstance( aPlugin );
+ // "delete this" used in plugin. Plugin must cancel asynchronous
+ // operations in its destructor to complete iCommandMessage and
+ // iUnsolicitedMessage
+ TRACE_FUNC_EXIT
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MATExtListen.
+// Notifies about an installed plugin.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::NotifyPluginInstallation(
+ TUid& /*aIfUid*/,
+ CImplementationInformation* aImplInfo )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata || !aImplInfo )
+ {
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ // 1. Add the new UID to metadata.
+ TRAPD( retTrap, iMetadata->AddImplementationL( aImplInfo ) );
+ if ( retTrap != KErrNone )
+ {
+ TRACE_FUNC_EXIT
+ return retTrap;
+ }
+ // 2. Lock the entry in metadata.
+ TUid pluginUid = aImplInfo->ImplementationUid();
+ TInt retTemp = iMetadata->LockPluginAccess( pluginUid );
+ if ( retTemp != KErrNone )
+ {
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ // 3. Notify client of installation.
+ if ( iEcomStatusMessage.Handle() )
+ {
+ TPckg<TUid> pluginUidPckg( pluginUid );
+ retTemp = iEcomStatusMessage.Write(
+ EATExtReceiveEcomPluginChangeParamUid,
+ pluginUidPckg );
+ TRACE_INFO(( _L("Write returned %d"), retTemp ));
+ TPckg<TATExtensionEcomType> ecomType( EEcomTypeInstall );
+ retTemp = iEcomStatusMessage.Write(
+ EATExtReceiveEcomPluginChangeParamType,
+ ecomType );
+ TRACE_INFO(( _L("Write returned %d"), retTemp ));
+ iEcomStatusMessage.Complete( KErrNone );
+ }
+ // 4. When client notifies installation, remove the lock from metadata.
+ // See IpcReportListenerUpdateReady() for this.
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// From MATExtListen.
+// Notifies about an uninstalled plugin.
+// ---------------------------------------------------------------------------
+//
+TInt CATExtSession::NotifyPluginUninstallation( TUid& /*aIfUid*/,
+ TUid& aPluginUid )
+ {
+ TRACE_FUNC_ENTRY
+ if ( !iMetadata )
+ {
+ TRACE_FUNC_EXIT
+ return KErrGeneral;
+ }
+ // 1. Lock the access to metadata from the responsible plugin UID.
+ TInt retTemp = iMetadata->LockPluginAccess( aPluginUid );
+ if ( retTemp != KErrNone )
+ {
+ TRACE_FUNC_EXIT
+ return retTemp;
+ }
+ // 2. Notify client of removal.
+ if ( iEcomStatusMessage.Handle() )
+ {
+ TPckg<TUid> pluginUid( aPluginUid );
+ retTemp = iEcomStatusMessage.Write(
+ EATExtReceiveEcomPluginChangeParamUid,
+ pluginUid );
+ TRACE_INFO(( _L("Write returned %d"), retTemp ));
+ TPckg<TATExtensionEcomType> ecomType( EEcomTypeUninstall );
+ retTemp = iEcomStatusMessage.Write(
+ EATExtReceiveEcomPluginChangeParamType,
+ ecomType );
+ TRACE_INFO(( _L("Write returned %d"), retTemp ));
+ iEcomStatusMessage.Complete( KErrNone );
+ }
+ // 3. When client notifies of removal, remove the locked entry from metadata.
+ // See IpcReportListenerUpdateReady() for this.
+ TRACE_FUNC_EXIT
+ return KErrNone;
+ }