Revision: 201011 RCL_3
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 31 Mar 2010 23:19:43 +0300
branchRCL_3
changeset 12 9b6d3ca0c601
parent 11 20fda83a6398
child 13 16aa830c86c8
Revision: 201011 Kit: 201013
atext/group/bld.inf
atext/plugins/group/bld.inf
atext/plugins/legacymodemplugin/group/bld.inf
atext/plugins/legacymodemplugin/group/legacymodemplugin.mmp
atext/plugins/legacymodemplugin/inc/debug.h
atext/plugins/legacymodemplugin/inc/debugconfig.h
atext/plugins/legacymodemplugin/inc/legacymodemplugin.h
atext/plugins/legacymodemplugin/inc/monitorspeakerparser.h
atext/plugins/legacymodemplugin/inc/prjconfig.h
atext/plugins/legacymodemplugin/rom/legacymodemplugin.iby
atext/plugins/legacymodemplugin/src/2002B340.rss
atext/plugins/legacymodemplugin/src/legacymodemplugin.cpp
atext/plugins/legacymodemplugin/src/monitorspeakerparser.cpp
atext/plugins/legacymodemplugin/src/proxy.cpp
atext/server/inc/atextmetadata.h
atext/server/src/atextmetadata.cpp
bluetooth/btcomm/src/states.cpp
bluetooth/btstack/linkmgr/physicallinks.cpp
bluetooth/btstack/linkmgr/physicallinks.h
bluetooth/btstack/secman/btaccessrequester.cpp
bluetooth/btstack/secman/secman.cpp
--- a/atext/group/bld.inf	Mon Mar 15 12:44:59 2010 +0200
+++ b/atext/group/bld.inf	Wed Mar 31 23:19:43 2010 +0300
@@ -26,5 +26,6 @@
 PRJ_MMPFILES
 #include "../client/group/bld.inf"
 #include "../server/group/bld.inf"
+#include "../plugins/group/bld.inf"
 
 PRJ_TESTMMPFILES
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/group/bld.inf	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,28 @@
+/*
+* Copyright (c) 2008 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:  build file
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+
+PRJ_EXPORTS
+
+PRJ_MMPFILES
+#include "../legacymodemplugin/group/bld.inf"
+
+PRJ_TESTMMPFILES
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/group/bld.inf	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,29 @@
+/*
+* 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:  This file provides the information required for building the
+*               whole of LegacyModemPlugin
+*
+*/
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+
+PRJ_EXPORTS
+../rom/legacymodemplugin.iby         CORE_OS_LAYER_IBY_EXPORT_PATH(legacymodemplugin.iby)
+
+PRJ_MMPFILES
+legacymodemplugin.mmp
+
+PRJ_TESTMMPFILES
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/group/legacymodemplugin.mmp	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,52 @@
+/*
+* 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:  Project definition file for project LegacyModemPlugin
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+TARGET                  legacymodemplugin.dll
+TARGETTYPE              PLUGIN
+UID                     0x10009D8D 0x2002B340
+
+CAPABILITY              CAP_ECOM_PLUGIN
+VENDORID                VID_DEFAULT
+
+SOURCEPATH              ../src
+SOURCE                  proxy.cpp
+SOURCE                  legacymodemplugin.cpp
+SOURCE                  monitorspeakerparser.cpp
+
+START RESOURCE          ../src/2002B340.rss
+TARGET                  legacymodemplugin.rsc
+END
+
+USERINCLUDE             ../inc
+
+OS_LAYER_SYSTEMINCLUDE
+
+// Note:
+// The only other SYSTEMINCLUDE should you shall add are Symbian specific ones.
+// If there is a S60 header in the subdirectory then that should be
+// added into the include statements (like #include <phonebook/header.h>)
+//SYSTEMINCLUDE           /epoc32/include/ecom
+SYSTEMINCLUDE           /epoc32/include/ecom
+
+LIBRARY ecom.lib
+LIBRARY euser.lib
+LIBRARY atextpluginbase.lib
+
+DEBUGLIBRARY flogger.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/inc/debug.h	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,171 @@
+/*
+* Copyright (c) 2008 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:  Logging definitions
+*
+*/
+
+
+#ifndef PRJ_LOGGING_H
+#define PRJ_LOGGING_H
+
+#include <e32base.h>
+#include "debugconfig.h"
+
+#ifdef PRJ_ENABLE_TRACE
+
+#ifdef PRJ_FILE_TRACE
+#include <flogger.h>
+#else
+#include <e32debug.h>
+#endif
+
+NONSHARABLE_CLASS(TOverflowTruncate16) : public TDes16Overflow
+    {
+public:
+    void Overflow(TDes16& /*aDes*/) {}
+    };
+
+NONSHARABLE_CLASS(TOverflowTruncate8) : public TDes8Overflow
+    {
+public:
+    void Overflow(TDes8& /*aDes*/) {}
+    };
+
+inline void Trace(TRefByValue<const TDesC16> aFmt, ...)
+    {
+    VA_LIST list;
+    VA_START(list,aFmt);
+#ifdef PRJ_FILE_TRACE
+    RFileLogger::WriteFormat(KLogDir, KLogFile, EFileLoggingModeAppend, aFmt, list);
+#else
+    TBuf16<KMaxLogLineLength> theFinalString;
+    theFinalString.Append(KTracePrefix16);
+    TOverflowTruncate16 overflow;
+    theFinalString.AppendFormatList(aFmt,list,&overflow);
+    RDebug::Print(theFinalString);
+#endif
+    }
+
+inline void Trace(TRefByValue<const TDesC8> aFmt, ...)
+    {
+    VA_LIST list;
+    VA_START(list, aFmt);
+#ifdef PRJ_FILE_TRACE
+    RFileLogger::WriteFormat(KLogDir, KLogFile, EFileLoggingModeAppend, aFmt, list);
+#else
+    TOverflowTruncate8 overflow;
+    TBuf8<KMaxLogLineLength> buf8;
+    buf8.Append(KTracePrefix8);
+    buf8.AppendFormatList(aFmt, list, &overflow);
+    TBuf16<KMaxLogLineLength> buf16(buf8.Length());
+    buf16.Copy(buf8);
+    TRefByValue<const TDesC> tmpFmt(_L("%S"));
+    RDebug::Print(tmpFmt, &buf16);
+#endif
+    }
+
+inline void TracePanic(
+    char* aFile,
+    TInt aLine,
+    TInt aPanicCode,
+    const TDesC& aPanicCategory)
+    {
+    TPtrC8 fullFileName((const TUint8*)aFile);
+    TPtrC8 fileName(fullFileName.Ptr()+fullFileName.LocateReverse('\\')+1);
+    TBuf8<KMaxLogLineLength> buf;
+    buf.Append(KPanicPrefix8);
+    buf.AppendFormat(_L8("%d at line %d in file %S"), aPanicCode, aLine, &fileName);
+    Trace(buf);
+    User::Panic(aPanicCategory, aPanicCode);
+    }
+
+inline void TraceLeave(char* aFile, TInt aLine, TInt aReason)
+    {
+    TPtrC8 fullFileName((const TUint8*)aFile);
+    TPtrC8 fileName(fullFileName.Ptr()+fullFileName.LocateReverse('\\')+1);
+    TBuf8<KMaxLogLineLength> buf;
+    buf.Append(KLeavePrefix8);
+    buf.AppendFormat(_L8("%d at line %d in file %S"), aReason, aLine, &fileName);
+    Trace(buf);
+    User::Leave(aReason);
+    }
+
+#define TRACE_INFO(p) {if(KTraceMask & KPRINTINFO) Trace p;}
+
+#define TRACE_ERROR(p) {if(KTraceMask & KPRINTERROR) Trace p;}
+
+#define TRACE_STATE(p) {if(KTraceMask & KPRINTSTATE) Trace p;}
+
+#define TRACE_WARNING(p) {if(KTraceMask & KPRINTWARNING) Trace p;}
+
+#define TRACE_INFO_SEG(p) {if(KTraceMask & KPRINTINFO) p;}
+
+#define TRACE_ASSERT(GUARD, CODE) {if (!(GUARD)) TracePanic(__FILE__, __LINE__, CODE, KPanicCategory);}
+
+#define PANIC(CODE) TracePanic(__FILE__, __LINE__, CODE, KPanicCategory)
+
+#define LEAVE_IF_ERROR(REASON) {if (REASON) TraceLeave(__FILE__, __LINE__, REASON);}
+
+#define LEAVE_IF_NULL(PTR) {if (!PTR) TraceLeave(__FILE__, __LINE__, PTR);}
+
+#define LEAVE(REASON) {TraceLeave(__FILE__, __LINE__, REASON);}
+
+#define TRACE_STATIC_FUNC_ENTRY {if(KTraceMask & KPRINTINFO) { TPtrC8 ptr8((TUint8*)__PRETTY_FUNCTION__); Trace(KFuncEntryFormat8, &ptr8);}}
+
+#define TRACE_FUNC_ENTRY {if(KTraceMask & KPRINTINFO) { TPtrC8 ptr8((TUint8*)__PRETTY_FUNCTION__); Trace(KFuncEntryThisFormat8, &ptr8, this);}}
+
+#define TRACE_FUNC_EXIT {if(KTraceMask & KPRINTINFO) { TPtrC8 ptr8((TUint8*)__PRETTY_FUNCTION__); Trace(KFuncExitFormat8, &ptr8);}}
+
+#define TRACE_STATIC_FUNC {if(KTraceMask & KPRINTINFO) { TPtrC8 ptr8((TUint8*)__PRETTY_FUNCTION__); Trace(KFuncFormat8, &ptr8);}}
+
+#define TRACE_FUNC {if(KTraceMask & KPRINTINFO) { TPtrC8 ptr8((TUint8*)__PRETTY_FUNCTION__); Trace(KFuncThisFormat8, &ptr8, this);}}
+
+#define RETURN_IF_ERR(ERR) {if(ERR) {TPtrC8 ptr8((TUint8*)__FILE__); Trace(_L8(" RETURN %d at file %S line %d"), ERR, &ptr8, __LINE__); return ERR;}}
+
+#else // PRJ_ENABLE_TRACE not defined
+
+#define TRACE_INFO(p)
+
+#define TRACE_ERROR(p)
+
+#define TRACE_STATE(p)
+
+#define TRACE_WARNING(p)
+
+#define TRACE_INFO_SEG(p)
+
+#define TRACE_ASSERT(GUARD, CODE)
+
+#define PANIC(CODE) {User::Panic(KPanicCategory, CODE);}
+
+#define LEAVE_IF_ERROR(REASON) {static_cast<void>(User::LeaveIfError(REASON));}
+
+#define LEAVE_IF_NULL(PTR) {static_cast<void>(User::LeaveIfNull(PTR));}
+
+#define LEAVE(REASON) {static_cast<void>(User::Leave(REASON));}
+
+#define TRACE_STATIC_FUNC_ENTRY
+
+#define TRACE_FUNC_ENTRY
+
+#define TRACE_FUNC_EXIT
+
+#define TRACE_STATIC_FUNC
+
+#define TRACE_FUNC
+
+#define RETURN_IF_ERR(ERR) {if(ERR) return ERR;}
+#endif // PRJ_ENABLE_TRACE
+
+#endif // PRJ_LOGGING_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/inc/debugconfig.h	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2008 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:  Logging configure file
+*
+*/
+
+
+#ifndef ATEXT_DEBUGCONFIG_H
+#define ATEXT_DEBUGCONFIG_H
+
+#include "prjconfig.h"
+
+/**
+ * Custom logging variations.
+ */
+#ifdef PRJ_FILE_TRACE
+_LIT(KLogFile,"lccustomplugin.txt");
+_LIT(KLogDir,"LCCUSTOMPLUGIN");
+#endif
+
+#ifdef PRJ_ENABLE_TRACE
+_LIT(KTracePrefix16, "[LCCUSTOMPLUGIN] ");
+_LIT8(KTracePrefix8, "[LCCUSTOMPLUGIN] ");
+_LIT8(KFuncFormat8, "><%S");
+_LIT8(KFuncThisFormat8, "><%S, [0x%08X]");
+_LIT8(KFuncEntryFormat8, ">%S");
+_LIT8(KFuncEntryThisFormat8, ">%S, [0x%08X]");
+_LIT8(KFuncExitFormat8, "<%S");
+
+_LIT(KPanicCategory, "lccustomplugin");
+_LIT8(KPanicPrefix8, "PANIC code ");
+_LIT8(KLeavePrefix8, "LEAVE code ");
+#endif
+
+const TInt KMaxLogLineLength = 512;
+
+#define KPRINTERROR        0x00000001 // Tracing level: error
+#define KPRINTINFO        0x00000002 // Tracing level: function trace
+#define KPRINTSTATE        0x00000004 // Tracing level: state machine info
+#define KPRINTWARNING   0x00000008 // Tracing level: warning
+
+const TInt KTraceMask = KPRINTERROR | KPRINTINFO | KPRINTSTATE | KPRINTWARNING;
+
+#endif // ATEXT_DEBUGCONFIG_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/inc/legacymodemplugin.h	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,421 @@
+/*
+* 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:  Main handler for incoming requests
+*
+*/
+
+#ifndef C_LEGACYMODEMPLUGIN_H
+#define C_LEGACYMODEMPLUGIN_H
+
+#include <atextpluginbase.h>
+
+class CLegacyModemPlugin;
+
+/** Character types: carriage return, line feed or backspace */
+enum TCharacterTypes
+    {
+    ECharTypeCR,  // Carriage return
+    ECharTypeLF,  // Line feed
+    ECharTypeBS   // Backspace
+    };
+
+/** Type of modes (quiet, verbose) */
+enum TModeTypes
+    {
+    EModeTypeQuiet,   // Quiet mode
+    EModeTypeVerbose  // Verbose mode
+    };
+
+/**  Handler types for the four types */
+enum TCmdHandlerType
+    {
+    ECmdHandlerTypeUndefined = KErrNotFound,
+    ECmdHandlerTypeBase      = 0x01,  // For command "AT+COMMAND"
+    ECmdHandlerTypeSet       = 0x02,  // For command "AT+COMMAND="
+    ECmdHandlerTypeRead      = 0x04,  // For command "AT+COMMAND?"
+    ECmdHandlerTypeTest      = 0x08,  // For command "AT+COMMAND=?"
+    };
+
+/**
+ *  Class for common AT command handler interface
+ *
+ *  @since S60 v5.0
+ */
+NONSHARABLE_CLASS( CLegacyModemPluginBase )
+    {
+
+public:
+
+    virtual ~CLegacyModemPluginBase() {};
+
+    /**
+     * Reports the support status of an AT command. This is a synchronous API.
+     *
+     * @param aCmd The AT command. Its format may vary depending on the
+     *             specification. E.g. in BT HFP case, the command may contain
+     *             a character carriage return (<cr>) in the end.
+     * @return ETrue if the command is supported; EFalse otherwise.
+     */
+    virtual TBool IsCommandSupported( const TDesC8& aCmd ) = 0;
+
+    /**
+     * Handles an AT command. Cancelling of the pending request is done by
+     * HandleCommandCancel(). The implementation in the extension plugin should
+     * be asynchronous.
+     *
+     * The extension plugin which accepts this command is responsible to supply
+     * the result codes and response and to format result codes properly, e.g.
+     * in BT HFP case, the format should be <cr><lf><result code><cr><lf>
+     *
+     * After an extension plugin has handled or decided to reject the given AT
+     * command, it must inform ATEXT by HandleCommandCompleted() with a proper
+     * error code.
+     *
+     * @since S60 5.0
+     * @param aCmd The AT command to be handled. Its format may vary depending
+     *             on the specification. E.g. in BT HFP case, the command may
+     *             contain a character carriage return (<cr>) in the end.
+     * @param aReply When passed in, contains the built in answer filled by
+     *               ATEXT if it is not empty; when command handling completes
+     *               successfully, contains the result codes and responses to
+     *               this command; Its ownership always belongs to ATEXT, plugin
+     *               may reallocate its space when needed.
+     * @param aReplyNeeded Reply needed if ETrue, no reply otherwise. If EFalse,
+     *                     the aReply must not contain the reply, otherwise it
+     *                     must contain verbose or numeric reply (ATV0/1) or an
+     *                     empty string reply (with ATQ).
+     * @return None
+     */
+    virtual void HandleCommand( const TDesC8& aCmd,
+                                RBuf8& aReply,
+                                TBool aReplyNeeded ) = 0;
+
+    /**
+     * Cancels a pending HandleCommand request.
+     *
+     * @since S60 5.0
+     * @return None
+     */
+    virtual void HandleCommandCancel() = 0;
+
+    };
+
+/**
+ *  Class for accessing plugin information and common functionality
+ *
+ *  @since S60 v5.0
+ */
+NONSHARABLE_CLASS( MLegacyModemPlugin )
+    {
+
+public:
+
+    /**
+     * Creates an AT command reply based on the reply type and completes the
+     * request to ATEXT. Uses iReplyBuffer for reply storage.
+     *
+     * @since S60 5.0
+     * @param aReplyType Type of reply
+     * @param aSrcBuffer Source buffer; used only if aReplyType is EReplyTypeOther
+     * @param aError Completion code. If not KErrNone then other arguments are
+     *               ignored and the request is completed to ATEXT with
+     *               EReplyTypeUndefined.
+     * @return None
+     */
+    virtual TInt CreateReplyAndComplete( TATExtensionReplyType aReplyType,
+                                         const TDesC8& aSrcBuffer=KNullDesC8,
+                                         TInt aError=KErrNone ) = 0;
+
+    /**
+     * Creates a buffer for "OK" or "ERROR" reply based on the line settings
+     *
+     * @since S60 5.0
+     * @param aReplyBuffer Destination buffer for the created reply
+     * @param aOkReply ETrue if "OK" reply needed,
+     *                 EFalse if "ERROR" reply needed
+     * @return Symbian error code on error, KErrNone otherwise
+     */
+    virtual TInt CreateOkOrErrorReply( RBuf8& aReplyBuffer,
+                                       TBool aOkReply ) = 0;
+
+    /**
+     * Checks if the command is a base, set, read or test type of command
+     *
+     * @since S60 5.0
+     * @param aCmdBase Base part of the command to check
+     * @param aCmdFull Full command to check
+     * @return Type of command
+     */
+    virtual TCmdHandlerType CheckCommandType( const TDesC8& aCmdBase,
+                                              const TDesC8& aCmdFull ) = 0;
+
+    };
+
+/**
+ *  Class for selecting handlers for different AT commands
+ *
+ *  @since S60 v5.0
+ */
+NONSHARABLE_CLASS( CLegacyModemPlugin ) : public CATExtPluginBase,
+                                          public MLegacyModemPlugin
+    {
+
+public:
+
+    /**
+     * Two-phased constructor.
+     * @return Instance of self
+     */
+    static CLegacyModemPlugin* NewL();
+
+    /**
+    * Destructor.
+    */
+    virtual ~CLegacyModemPlugin();
+
+private:
+
+    CLegacyModemPlugin();
+
+    void ConstructL();
+
+    /**
+     * Reports connection identifier name to the extension plugin.
+     *
+     * @since S60 5.0
+     * @param aName Connection identifier name
+     * @return None
+     */
+    void ReportConnectionName( const TDesC8& aName );
+
+    /**
+     * Reports the support status of an AT command. This is a synchronous API.
+     *
+     * @param aCmd The AT command. Its format may vary depending on the
+     *             specification. E.g. in BT HFP case, the command may contain
+     *             a character carriage return (<cr>) in the end.
+     * @return ETrue if the command is supported; EFalse otherwise.
+     */
+    TBool IsCommandSupported( const TDesC8& aCmd );
+
+    /**
+     * Handles an AT command. Cancelling of the pending request is done by
+     * HandleCommandCancel(). The implementation in the extension plugin should
+     * be asynchronous.
+     *
+     * The extension plugin which accepts this command is responsible to supply
+     * the result codes and response and to format result codes properly, e.g.
+     * in BT HFP case, the format should be <cr><lf><result code><cr><lf>
+     *
+     * After an extension plugin has handled or decided to reject the given AT
+     * command, it must inform ATEXT by HandleCommandCompleted() with a proper
+     * error code.
+     *
+     * @since S60 5.0
+     * @param aCmd The AT command to be handled. Its format may vary depending
+     *             on the specification. E.g. in BT HFP case, the command may
+     *             contain a character carriage return (<cr>) in the end.
+     * @param aReply When passed in, contains the built in answer filled by
+     *               ATEXT if it is not empty; when command handling completes
+     *               successfully, contains the result codes and responses to
+     *               this command; Its ownership always belongs to ATEXT, plugin
+     *               may reallocate its space when needed.
+     * @param aReplyNeeded Reply needed if ETrue, no reply otherwise. If EFalse,
+     *                     the aReply must not contain the reply, otherwise it
+     *                     must contain verbose or numeric reply (ATV0/1) or an
+     *                     empty string reply (with ATQ).
+     * @return None
+     */
+    void HandleCommand( const TDesC8& aCmd, RBuf8& aReply, TBool aReplyNeeded );
+
+    /**
+     * Cancels a pending HandleCommand request.
+     *
+     * @since S60 5.0
+     * @return None
+     */
+    void HandleCommandCancel();
+
+    /**
+     * 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().
+     *
+     * @since S60 5.0
+     * @return Next reply part's length if zero or positive
+     */
+    TInt NextReplyPartLength();
+
+    /**
+     * Gets the next part of reply initially set by HandleCommandComplete().
+     * Length of aNextReply must be equal or less than KDefaultCmdBufLength.
+     *
+     * @since S60 5.0
+     * @param aNextReply Next reply
+     * @return Symbian error code on error, KErrNone otherwise
+     */
+    TInt GetNextPartOfReply( RBuf8& aNextReply );
+
+    /**
+     * Receives unsolicited results. Cancelling of the pending request is done
+     * by ReceiveUnsolicitedResultCancel(). The implementation in the extension
+     * plugin should be asynchronous.
+     *
+     * @since S60 5.0
+     * @return None
+     */
+    void ReceiveUnsolicitedResult();
+
+    /**
+     * Cancels a pending ReceiveUnsolicitedResult request.
+     *
+     * @since S60 5.0
+     * @return None
+     */
+    void ReceiveUnsolicitedResultCancel();
+
+    /**
+     * Reports NVRAM status change to the plugins.
+     *
+     * @since S60 5.0
+     * @param aNvram New NVRAM status. Each call of this function is a result
+     *               of DUN extracting the form notified by
+     *               CATExtCommonBase::SendNvramStatusChange(). Each of the
+     *               settings from SendNvramStatusChange() is separated to
+     *               one call of ReportNvramStatusChange().
+     * @return None
+     */
+    void ReportNvramStatusChange( const TDesC8& aNvram );
+
+    /**
+     * 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: in command line "AT+TEST;ATDT1234" was given. "AT+TEST" returns
+     * "OK" and "ATDT" returns "CONNECT". Because "OK" and "CONNECT" are
+     * different reply types the condition is "ERROR" and DUN ends processing.
+     * This solution keeps the pointer to the last AT command handling plugin
+     * inside ATEXT and calls this function there to report the error.
+     * It is to be noted that HandleCommandCancel() is not sufficient to stop
+     * the processing as the command handling has already finished.
+     *
+     * @since S60 5.0
+     * @return None
+     */
+    void ReportExternalHandleCommandError();
+
+    /**
+     * Creates part of reply from the global reply buffer to the destination
+     * buffer. Used with APIs which need the next part of reply in multipart
+     * reply requests.
+     *
+     * @since S60 5.0
+     * @param aDstBuffer Destination buffer; the next part of reply is stored to
+     *                   this buffer.
+     * @return None
+     */
+    TInt CreatePartOfReply( RBuf8& aDstBuffer );
+
+    /**
+     * Appends one parameter to array for GetParameterArray()
+     *
+     * @since S60 5.0
+     * @param aParams Array of supported commands
+     * @param aStartIndex Start index for the parameter to be added
+     * @param aEndIndex End index for the parameter to be added
+     * @return None
+     */
+    void AppendOneParameterLC( RPointerArray<HBufC8>& aParams,
+                               TInt& aStartIndex,
+                               TInt aEndIndex );
+
+// from base class MLegacyModemPlugin
+
+    /**
+     * From MLegacyModemPlugin.
+     * Creates an AT command reply based on the reply type and completes the
+     * request to ATEXT. Uses iReplyBuffer for reply storage.
+     *
+     * @since S60 5.0
+     * @param aReplyType Type of reply
+     * @param aSrcBuffer Source buffer; used only if aReplyType is EReplyTypeOther
+     * @param aError Completion code. If not KErrNone then other arguments are
+     *               ignored and the request is completed to ATEXT with
+     *               EReplyTypeUndefined.
+     * @return None
+     */
+    TInt CreateReplyAndComplete( TATExtensionReplyType aReplyType,
+                                 const TDesC8& aSrcBuffer=KNullDesC8,
+                                 TInt aError=KErrNone );
+
+    /**
+     * From MLegacyModemPlugin.
+     * Creates a buffer for "OK" or "ERROR" reply based on the line settings
+     *
+     * @since S60 5.0
+     * @param aReplyBuffer Destination buffer for the created reply
+     * @param aOkReply ETrue if "OK" reply needed,
+     *                 EFalse if "ERROR" reply needed
+     * @return Symbian error code on error, KErrNone otherwise
+     */
+    TInt CreateOkOrErrorReply( RBuf8& aReplyBuffer,
+                               TBool aOkReply );
+
+    /**
+     * From MLegacyModemPlugin.
+     * Checks if the command is a base, set, read or test type of command
+     *
+     * @since S60 5.0
+     * @param aCmdBase Base part of the command to check
+     * @param aCmdFull Full command to check
+     * @return Type of command
+     */
+    TCmdHandlerType CheckCommandType( const TDesC8& aCmdBase,
+                                      const TDesC8& aCmdFull );
+
+private:  // data
+
+    /**
+     * AT commands handler array. Used for mapping HandleCommand() to
+     * IsCommandSupported() and to limit the number of string comparisons.
+     */
+    RPointerArray<CLegacyModemPluginBase> iHandlers;
+
+    /**
+     * Current AT command handler in iHandlers.
+     * Used when IsCommandSupported() detects a matching handler class.
+     */
+    CLegacyModemPluginBase* iHandler;
+
+    /**
+     * Buffer for handle command's command
+     * Not own.
+     */
+    const TDesC8* iHcCmd;
+
+    /**
+     * Buffer for handle command reply
+     * Not own.
+     */
+    RBuf8* iHcReply;
+
+    /**
+     * Global reply buffer for the AT command replies
+     */
+    RBuf8 iReplyBuffer;
+
+    };
+
+#endif  // C_LEGACYMODEMPLUGIN_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/inc/monitorspeakerparser.h	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,163 @@
+/*
+* 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: Handles commands "ATL", "ATL0", "ATL1", "ATL2", "ATL3", "ATM",
+*              "ATM0", "ATM1" and "ATM2"
+*
+*/
+
+#ifndef C_MONITORSPEAKERPARSER_H
+#define C_MONITORSPEAKERPARSER_H
+
+#include "legacymodemplugin.h"
+
+/**  Detected commands */
+enum TDetectedCmd
+    {
+    EDetectedCmdUndefined,
+    EDetectedCmdATL,   // For command "ATL"
+    EDetectedCmdATL0,  // For command "ATL0"
+    EDetectedCmdATL1,  // For command "ATL1"
+    EDetectedCmdATL2,  // For command "ATL2"
+    EDetectedCmdATL3,  // For command "ATL3"
+    EDetectedCmdATM,   // For command "ATM"
+    EDetectedCmdATM0,  // For command "ATM0"
+    EDetectedCmdATM1,  // For command "ATM1"
+    EDetectedCmdATM2   // For command "ATM2"
+    };
+
+/**
+ *  Main class for handling commands "ATL", "ATL0", "ATL1", "ATL2", "ATL3",
+ *  "ATM", "ATM0", "ATM1" and "ATM2"
+ *
+ *  @since S60 v5.0
+ */
+NONSHARABLE_CLASS( CMonitorSpeakerParser ) : public CLegacyModemPluginBase
+    {
+
+public:
+
+    /**
+     * Two-phased constructor.
+     * @param aCallback Callback
+     * @return Instance of self
+     */
+    static CMonitorSpeakerParser* NewL( MLegacyModemPlugin* aCallback );
+
+    /**
+    * Destructor.
+    */
+    virtual ~CMonitorSpeakerParser();
+
+private:
+
+    CMonitorSpeakerParser( MLegacyModemPlugin* aCallback );
+
+    void ConstructL();
+
+    /**
+     * Checks if the command is speaker loudness command
+     *
+     * @param aCmd Command to check
+     * @return ETrue if command understood, EFalse otherwise
+     */
+    TBool CheckSpeakerLoudnessCommand( const TDesC8& aCmd );
+
+    /**
+     * Checks if the command is speaker mode command
+     *
+     * @param aCmd Command to check
+     * @return ETrue if command understood, EFalse otherwise
+     */
+    TBool CheckSpeakerModeCommand( const TDesC8& aCmd );
+
+    /**
+     * Main command handler (leaving version)
+     *
+     * @return ETrue if command understood, EFalse otherwise
+     */
+    TBool HandleCommandL();
+
+// from base class CLcCustomPluginBase
+
+    /**
+     * From CLcCustomPluginBase.
+     * Reports the support status of an AT command. This is a synchronous API.
+     *
+     * @param aCmd The AT command. Its format may vary depending on the
+     *             specification. E.g. in BT HFP case, the command may contain
+     *             a character carriage return (<cr>) in the end.
+     * @return ETrue if the command is supported; EFalse otherwise.
+     */
+    TBool IsCommandSupported( const TDesC8& aCmd );
+
+    /**
+     * From CLcCustomPluginBase.
+     * Handles an AT command. Cancelling of the pending request is done by
+     * HandleCommandCancel(). The implementation in the extension plugin should
+     * be asynchronous.
+     *
+     * The extension plugin which accepts this command is responsible to supply
+     * the result codes and response and to format result codes properly, e.g.
+     * in BT HFP case, the format should be <cr><lf><result code><cr><lf>
+     *
+     * After an extension plugin has handled or decided to reject the given AT
+     * command, it must inform ATEXT by HandleCommandCompleted() with a proper
+     * error code.
+     *
+     * @since S60 5.0
+     * @param aCmd The AT command to be handled. Its format may vary depending
+     *             on the specification. E.g. in BT HFP case, the command may
+     *             contain a character carriage return (<cr>) in the end.
+     * @param aReply When passed in, contains the built in answer filled by
+     *               ATEXT if it is not empty; when command handling completes
+     *               successfully, contains the result codes and responses to
+     *               this command; Its ownership always belongs to ATEXT, plugin
+     *               may reallocate its space when needed.
+     * @param aReplyNeeded Reply needed if ETrue, no reply otherwise. If EFalse,
+     *                     the aReply must not contain the reply, otherwise it
+     *                     must contain verbose or numeric reply (ATV0/1) or an
+     *                     empty string reply (with ATQ).
+     * @return None
+     */
+    void HandleCommand( const TDesC8& aCmd, RBuf8& aReply, TBool aReplyNeeded );
+
+    /**
+     * From CLcCustomPluginBase.
+     * Cancels a pending HandleCommand request.
+     *
+     * @since S60 5.0
+     * @return None
+     */
+    void HandleCommandCancel();
+
+private:  // data
+
+    /**
+     * Callback to call when accessing plugin information
+     */
+    MLegacyModemPlugin* iCallback;
+
+    /**
+     * Handler type for the three types
+     */
+    TCmdHandlerType iCmdHandlerType;
+
+    /**
+     * Detected command
+     */
+    TDetectedCmd iDetectedCmd;
+
+    };
+
+#endif  // C_MONITORSPEAKERPARSER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/inc/prjconfig.h	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2008 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:  Project configure file
+*
+*/
+
+
+#ifndef ATEXT_PRJCONFIG_H
+#define ATEXT_PRJCONFIG_H
+
+/**
+ * Traces are enabled in _DEBUG build, by default.
+ */
+#ifdef _DEBUG
+#define PRJ_ENABLE_TRACE
+#endif
+
+/**
+ * traces to file if this is defined.
+ */
+//#define PRJ_FILE_TRACE
+
+
+/**
+ * build the project for module test purpose if this is defined
+ */
+//#define PRJ_MODULETEST_BUILD
+
+/**
+ * build the project using stubs to replace the dependencies if this is defined
+ */
+//#define PRJ_USE_STUB
+
+
+#endif // ATEXT_PRJCONFIG_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/rom/legacymodemplugin.iby	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,23 @@
+/*
+* 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:  Image description file for project LegacyModemPlugin
+*
+*/
+
+#ifndef __LEGACYMODEMPLUGIN_IBY__
+#define __LEGACYMODEMPLUGIN_IBY__
+
+ECOM_PLUGIN( legacymodemplugin.dll, legacymodemplugin.rsc )
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/src/2002B340.rss	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,45 @@
+/*
+* 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:  Resource definitions for project LegacyModemPlugin
+*
+*/
+
+#include <registryinfo.rh>
+
+// Declares info for two implementations
+RESOURCE REGISTRY_INFO theInfo
+	{
+	// UID for the DLL
+	dll_uid = 0x2002B340;
+	// Declare array of interface info
+	interfaces =
+		{
+		INTERFACE_INFO
+			{
+			// UID of interface that is implemented
+			interface_uid = 0x2001CBEE;  // ATEXT_INTERFACE_DUN_UID
+			implementations =
+				{
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x2002B341;
+					version_no = 1;
+					display_name = "LegacyModemPlugin";
+					default_data = "MATL|MATL0|MATL1|MATL2|MATL3|MATM|MATM0|MATM1|MATM2";
+					opaque_data = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/src/legacymodemplugin.cpp	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,408 @@
+/*
+* 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:  Main handler for incoming requests
+*
+*/
+
+#include "legacymodemplugin.h"
+#include "monitorspeakerparser.h"
+#include "debug.h"
+
+const TInt KErrorReplyLength = 9;  // CR+LF+"ERROR"+CR+LF
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CLegacyModemPlugin* CLegacyModemPlugin::NewL()
+    {
+    CLegacyModemPlugin* self = new (ELeave) CLegacyModemPlugin();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CLegacyModemPlugin::~CLegacyModemPlugin()
+	{
+	iHandlers.ResetAndDestroy();
+	iHandlers.Close();
+    iReplyBuffer.Close();
+	}
+
+// ---------------------------------------------------------------------------
+// CLegacyModemPlugin::CLegacyModemPlugin
+// ---------------------------------------------------------------------------
+//
+CLegacyModemPlugin::CLegacyModemPlugin() : CATExtPluginBase()
+    {
+    iHandler = NULL;
+    iHcCmd = NULL;
+    iHcReply = NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CLegacyModemPlugin::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CLegacyModemPlugin::ConstructL()
+    {
+    CLegacyModemPluginBase* handler = NULL;
+    handler = CMonitorSpeakerParser::NewL( this );
+    CleanupStack::PushL( handler );
+    iHandlers.AppendL( handler );
+    CleanupStack::Pop( handler );
+   	}
+
+// ---------------------------------------------------------------------------
+// Reports connection identifier name to the extension plugin.
+// ---------------------------------------------------------------------------
+//
+void CLegacyModemPlugin::ReportConnectionName( const TDesC8& /*aName*/ )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// Reports the support status of an AT command. This is a synchronous API.
+// ---------------------------------------------------------------------------
+//
+TBool CLegacyModemPlugin::IsCommandSupported( const TDesC8& aCmd )
+    {
+    TRACE_FUNC_ENTRY
+    iHcCmd = NULL;
+    iHcReply = NULL;
+    TInt i;
+    TInt count = iHandlers.Count();
+    for ( i=0; i<count; i++ )
+        {
+        CLegacyModemPluginBase* handler = iHandlers[i];
+        TBool supported = handler->IsCommandSupported( aCmd );
+        if ( supported )
+            {
+            iHandler = handler;
+            TRACE_FUNC_EXIT
+            return ETrue;
+            }
+        }
+    iHandler = NULL;
+    TRACE_FUNC_EXIT
+    return EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// Handles an AT command. Cancelling of the pending request is done by
+// HandleCommandCancel(). The implementation in the extension plugin should
+// be asynchronous.
+// ---------------------------------------------------------------------------
+//
+void CLegacyModemPlugin::HandleCommand( const TDesC8& aCmd,
+                                        RBuf8& aReply,
+                                        TBool aReplyNeeded )
+	{
+	TRACE_FUNC_ENTRY
+	if ( iHandler )
+	    {
+	    iHcCmd = &aCmd;
+	    iHcReply = &aReply;
+	    iHandler->HandleCommand( aCmd, aReply, aReplyNeeded );
+	    }
+	TRACE_FUNC_EXIT
+    }
+
+// ---------------------------------------------------------------------------
+// Cancels a pending HandleCommand request.
+// ---------------------------------------------------------------------------
+//
+void CLegacyModemPlugin::HandleCommandCancel()
+    {
+    TRACE_FUNC_ENTRY
+	if ( iHandler )
+	    {
+	    iHandler->HandleCommandCancel();
+	    }
+	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 CLegacyModemPlugin::NextReplyPartLength()
+    {
+    TRACE_FUNC_ENTRY
+    if ( iReplyBuffer.Length() < KDefaultCmdBufLength )
+        {
+        TRACE_FUNC_EXIT
+        return iReplyBuffer.Length();
+        }
+    TRACE_FUNC_EXIT
+    return KDefaultCmdBufLength;
+    }
+
+// ---------------------------------------------------------------------------
+// Gets the next part of reply initially set by HandleCommandComplete().
+// Length of aNextReply must be equal or less than KDefaultCmdBufLength.
+// ---------------------------------------------------------------------------
+//
+TInt CLegacyModemPlugin::GetNextPartOfReply( RBuf8& aNextReply )
+    {
+    TRACE_FUNC_ENTRY
+    TInt retVal = CreatePartOfReply( aNextReply );
+    TRACE_FUNC_EXIT
+    return retVal;
+    }
+
+// ---------------------------------------------------------------------------
+// Receives unsolicited results. Cancelling of the pending request is done by
+// by ReceiveUnsolicitedResultCancel(). The implementation in the extension
+// plugin should be asynchronous.
+// ---------------------------------------------------------------------------
+//
+void CLegacyModemPlugin::ReceiveUnsolicitedResult()
+    {
+    TRACE_FUNC_ENTRY
+    TRACE_FUNC_EXIT
+    }
+
+// ---------------------------------------------------------------------------
+// Cancels a pending ReceiveUnsolicitedResult request.
+// ---------------------------------------------------------------------------
+//
+void CLegacyModemPlugin::ReceiveUnsolicitedResultCancel()
+    {
+    TRACE_FUNC_ENTRY
+    TRACE_FUNC_EXIT
+    }
+
+// ---------------------------------------------------------------------------
+// Reports NVRAM status change to the plugins.
+// ---------------------------------------------------------------------------
+//
+void CLegacyModemPlugin::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 CLegacyModemPlugin::ReportExternalHandleCommandError()
+    {
+    TRACE_FUNC_ENTRY
+    TRACE_FUNC_EXIT
+    }
+
+// ---------------------------------------------------------------------------
+// Creates part of reply from the global reply buffer to the destination
+// buffer. Used with APIs which need the next part of reply in multipart reply
+// requests.
+// ---------------------------------------------------------------------------
+//
+TInt CLegacyModemPlugin::CreatePartOfReply( RBuf8& aDstBuffer )
+    {
+    TRACE_FUNC_ENTRY
+    if ( iReplyBuffer.Length() <= 0 )
+        {
+        TRACE_FUNC_EXIT
+        return KErrGeneral;
+        }
+    TInt partLength = NextReplyPartLength();
+    if ( iReplyBuffer.Length() < partLength )
+        {
+        TRACE_FUNC_EXIT
+        return KErrNotFound;
+        }
+    aDstBuffer.Create( iReplyBuffer, partLength );
+    iReplyBuffer.Delete( 0, partLength );
+    if ( iReplyBuffer.Length() == 0 )
+        {
+        iReplyBuffer.Close();
+        }
+    TRACE_FUNC_EXIT
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Creates an AT command reply based on the reply type and completes the
+// request to ATEXT. Uses iReplyBuffer for reply storage.
+// ---------------------------------------------------------------------------
+//
+TInt CLegacyModemPlugin::CreateReplyAndComplete(
+    TATExtensionReplyType aReplyType,
+    const TDesC8& aSrcBuffer,
+    TInt aError )
+    {
+    TRACE_FUNC_ENTRY
+    iReplyBuffer.Close();
+    if ( aError != KErrNone )
+        {
+        HandleCommandCompleted( aError, EReplyTypeUndefined );
+        iHcCmd = NULL;
+        iHcReply = NULL;
+        TRACE_FUNC_EXIT
+        return KErrNone;
+        }
+    if ( !iHcReply )
+        {
+        TRACE_FUNC_EXIT
+        return KErrGeneral;
+        }
+    switch ( aReplyType )
+        {
+        case EReplyTypeOther:
+            if ( iQuietMode || !iVerboseMode )
+                {
+                iReplyBuffer.Create( KNullDesC8 );
+                }
+            else
+                {
+                iReplyBuffer.Create( aSrcBuffer );
+                }
+            break;
+        case EReplyTypeOk:
+            CreateOkOrErrorReply( iReplyBuffer, ETrue );
+            break;
+        case EReplyTypeError:
+            CreateOkOrErrorReply( iReplyBuffer, EFalse );
+            break;
+        default:
+            TRACE_FUNC_EXIT
+            return KErrGeneral;
+        }
+    CreatePartOfReply( *iHcReply );
+    HandleCommandCompleted( KErrNone, aReplyType );
+    iHcCmd = NULL;
+    iHcReply = NULL;
+    TRACE_FUNC_EXIT
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// Creates a buffer for "OK" or "ERROR" reply based on the line settings
+// ---------------------------------------------------------------------------
+//
+TInt CLegacyModemPlugin::CreateOkOrErrorReply( RBuf8& aReplyBuffer,
+                                               TBool aOkReply )
+    {
+    TRACE_FUNC_ENTRY
+    if ( iQuietMode )
+        {
+        TRACE_FUNC_EXIT
+        return iReplyBuffer.Create( KNullDesC8 );
+        }
+    _LIT8( KErrorReplyVerbose, "ERROR" );
+    _LIT8( KOkReplyVerbose,    "OK" );
+    _LIT8( KErrorReplyNumeric, "4" );
+    _LIT8( KOkReplyNumeric,    "0" );
+    TBuf8<KErrorReplyLength> replyBuffer;
+    if ( iVerboseMode )
+        {
+        replyBuffer.Append( iCarriageReturn );
+        replyBuffer.Append( iLineFeed );
+        if ( aOkReply )
+            {
+            replyBuffer.Append( KOkReplyVerbose );
+            }
+        else
+            {
+            replyBuffer.Append( KErrorReplyVerbose );
+            }
+        replyBuffer.Append( iCarriageReturn );
+        replyBuffer.Append( iLineFeed );
+        }
+    else
+        {
+        if ( aOkReply )
+            {
+            replyBuffer.Append( KOkReplyNumeric );
+            }
+        else
+            {
+            replyBuffer.Append( KErrorReplyNumeric );
+            }
+        replyBuffer.Append( iCarriageReturn );
+        }
+    TInt retVal = aReplyBuffer.Create( replyBuffer );
+    TRACE_FUNC_EXIT
+    return retVal;
+    }
+
+// ---------------------------------------------------------------------------
+// From MHfpExtPlugin.
+// Checks if the command is a base, set, read or test type of command
+// ---------------------------------------------------------------------------
+//
+TCmdHandlerType CLegacyModemPlugin::CheckCommandType( const TDesC8& aCmdBase,
+                                                      const TDesC8& aCmdFull )
+    {
+    TRACE_FUNC_ENTRY
+    TInt retTemp = KErrNone;
+    TBuf8<KDefaultCmdBufLength> atCmdBuffer;
+    atCmdBuffer.Copy( aCmdBase );
+    // Check "base" command ("AT+COMMAND")
+    retTemp = aCmdFull.Compare( atCmdBuffer );
+    if ( retTemp == 0 )
+        {
+        TRACE_FUNC_EXIT
+        return ECmdHandlerTypeBase;
+        }
+    // Check "read" command ("AT+COMMAND?")
+    // Add last question mark
+    atCmdBuffer.Append( '?' );
+    retTemp = aCmdFull.Compare( atCmdBuffer );
+    if ( retTemp == 0 )
+        {
+        TRACE_FUNC_EXIT
+        return ECmdHandlerTypeRead;
+        }
+    // Check "test" command ("AT+COMMAND=?")
+    // Add "=" before the question mark
+    _LIT8( KAssignmentMark, "=" );
+    atCmdBuffer.Insert( atCmdBuffer.Length()-1, KAssignmentMark );
+    retTemp = aCmdFull.Compare( atCmdBuffer );
+    if ( retTemp == 0 )
+        {
+        TRACE_FUNC_EXIT
+        return ECmdHandlerTypeTest;
+        }
+    // Check "set" command ("AT+COMMAND=")
+    // Remove last question mark
+    atCmdBuffer.SetLength( atCmdBuffer.Length() - 1 );
+    retTemp = aCmdFull.Compare( atCmdBuffer );
+    if ( retTemp == 0 )
+        {
+        TRACE_FUNC_EXIT
+        return ECmdHandlerTypeSet;
+        }
+    TRACE_FUNC_EXIT
+    return ECmdHandlerTypeUndefined;
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/src/monitorspeakerparser.cpp	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,256 @@
+/*
+* 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: Handles commands "ATL", "ATL0", "ATL1", "ATL2", "ATL3", "ATM",
+*              "ATM0", "ATM1" and "ATM2"
+*
+*/
+
+#include "monitorspeakerparser.h"
+#include "debug.h"
+
+_LIT8( KAtlCmd,  "ATL"  );
+_LIT8( KAtl0Cmd, "ATL0" );
+_LIT8( KAtl1Cmd, "ATL1" );
+_LIT8( KAtl2Cmd, "ATL2" );
+_LIT8( KAtl3Cmd, "ATL3" );
+_LIT8( KAtmCmd,  "ATM"  );
+_LIT8( KAtm0Cmd, "ATM0" );
+_LIT8( KAtm1Cmd, "ATM1" );
+_LIT8( KAtm2Cmd, "ATM2" );
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CMonitorSpeakerParser* CMonitorSpeakerParser::NewL(
+    MLegacyModemPlugin* aCallback )
+    {
+    CMonitorSpeakerParser* self = new (ELeave) CMonitorSpeakerParser( aCallback );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CMonitorSpeakerParser::~CMonitorSpeakerParser()
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// CHfpExtParserMisc::CHfpExtParserMisc
+// ---------------------------------------------------------------------------
+//
+CMonitorSpeakerParser::CMonitorSpeakerParser( MLegacyModemPlugin* aCallback ) :
+    iCallback( aCallback )
+    {
+    iCmdHandlerType = ECmdHandlerTypeUndefined;
+    iDetectedCmd = EDetectedCmdUndefined;
+    }
+
+// ---------------------------------------------------------------------------
+// CHfpExtParserMisc::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CMonitorSpeakerParser::ConstructL()
+    {
+    if ( !iCallback )
+        {
+        User::Leave( KErrGeneral );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Checks if the command is speaker loudness command
+// ---------------------------------------------------------------------------
+//
+TBool CMonitorSpeakerParser::CheckSpeakerLoudnessCommand( const TDesC8& aCmd )
+    {
+    TRACE_FUNC_ENTRY
+    // The ATL command only supports one type: base
+    // The ATL0 command only supports one type: base
+    // The ATL1 command only supports one type: base
+    // The ATL2 command only supports one type: base
+    // The ATL3 command only supports one type: base
+    iCmdHandlerType = iCallback->CheckCommandType( KAtlCmd, aCmd );
+    if ( iCmdHandlerType == ECmdHandlerTypeBase )
+        {
+        iDetectedCmd = EDetectedCmdATL;
+        TRACE_FUNC_EXIT
+        return ETrue;
+        }
+    iCmdHandlerType = iCallback->CheckCommandType( KAtl0Cmd, aCmd );
+    if ( iCmdHandlerType == ECmdHandlerTypeBase )
+        {
+        iDetectedCmd = EDetectedCmdATL0;
+        TRACE_FUNC_EXIT
+        return ETrue;
+        }
+    iCmdHandlerType = iCallback->CheckCommandType( KAtl1Cmd, aCmd );
+    if ( iCmdHandlerType == ECmdHandlerTypeBase )
+        {
+        iDetectedCmd = EDetectedCmdATL1;
+        TRACE_FUNC_EXIT
+        return ETrue;
+        }
+    iCmdHandlerType = iCallback->CheckCommandType( KAtl2Cmd, aCmd );
+    if ( iCmdHandlerType == ECmdHandlerTypeBase )
+        {
+        iDetectedCmd = EDetectedCmdATL2;
+        TRACE_FUNC_EXIT
+        return ETrue;
+        }
+    iCmdHandlerType = iCallback->CheckCommandType( KAtl3Cmd, aCmd );
+    if ( iCmdHandlerType == ECmdHandlerTypeBase )
+        {
+        iDetectedCmd = EDetectedCmdATL3;
+        TRACE_FUNC_EXIT
+        return ETrue;
+        }
+    TRACE_FUNC_EXIT
+    return EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// Checks if the command is speaker mode command
+// ---------------------------------------------------------------------------
+//
+TBool CMonitorSpeakerParser::CheckSpeakerModeCommand( const TDesC8& aCmd )
+    {
+    TRACE_FUNC_ENTRY
+    // The ATM command only supports one type: base
+    // The ATM0 command only supports one type: base
+    // The ATM1 command only supports one type: base
+    // The ATM2 command only supports one type: base
+    iCmdHandlerType = iCallback->CheckCommandType( KAtmCmd, aCmd );
+    if ( iCmdHandlerType == ECmdHandlerTypeBase )
+        {
+        iDetectedCmd = EDetectedCmdATM;
+        TRACE_FUNC_EXIT
+        return ETrue;
+        }
+    iCmdHandlerType = iCallback->CheckCommandType( KAtm0Cmd, aCmd );
+    if ( iCmdHandlerType == ECmdHandlerTypeBase )
+        {
+        iDetectedCmd = EDetectedCmdATM0;
+        TRACE_FUNC_EXIT
+        return ETrue;
+        }
+    iCmdHandlerType = iCallback->CheckCommandType( KAtm1Cmd, aCmd );
+    if ( iCmdHandlerType == ECmdHandlerTypeBase )
+        {
+        iDetectedCmd = EDetectedCmdATM1;
+        TRACE_FUNC_EXIT
+        return ETrue;
+        }
+    iCmdHandlerType = iCallback->CheckCommandType( KAtm2Cmd, aCmd );
+    if ( iCmdHandlerType == ECmdHandlerTypeBase )
+        {
+        iDetectedCmd = EDetectedCmdATM2;
+        TRACE_FUNC_EXIT
+        return ETrue;
+        }
+    TRACE_FUNC_EXIT
+    return EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// Main command handler (leaving version)
+// ---------------------------------------------------------------------------
+//
+TBool CMonitorSpeakerParser::HandleCommandL()
+    {
+    TRACE_FUNC_ENTRY
+    TBool cmdUnderstood = EFalse;
+    // Just return "OK" for all detected commands
+    if ( iDetectedCmd != EDetectedCmdUndefined )
+        {
+        iCallback->CreateReplyAndComplete( EReplyTypeOk );
+        cmdUnderstood = ETrue;
+        }
+    TRACE_FUNC_EXIT
+    return cmdUnderstood;
+    }
+
+// ---------------------------------------------------------------------------
+// From CLegacyModemPluginBase.
+// Reports the support status of an AT command. This is a synchronous API.
+// ---------------------------------------------------------------------------
+//
+TBool CMonitorSpeakerParser::IsCommandSupported( const TDesC8& aCmd )
+    {
+    TRACE_FUNC_ENTRY
+    TBool cmdUnderstood = EFalse;
+    // Set all to undefined if either the command or its type is unknown
+    // HandleCommand() should be round only when both are set
+    cmdUnderstood = CheckSpeakerLoudnessCommand( aCmd );
+    if ( cmdUnderstood )
+        {
+        TRACE_FUNC_EXIT
+        return ETrue;
+        }
+    cmdUnderstood = CheckSpeakerModeCommand( aCmd );
+    if ( cmdUnderstood )
+        {
+        TRACE_FUNC_EXIT
+        return ETrue;
+        }
+    iCmdHandlerType = ECmdHandlerTypeUndefined;
+    iDetectedCmd = EDetectedCmdUndefined;
+    TRACE_FUNC_EXIT
+    return EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// From CLegacyModemPluginBase.
+// Handles an AT command. Cancelling of the pending request is done by
+// HandleCommandCancel(). The implementation in the extension plugin should
+// be asynchronous.
+// ---------------------------------------------------------------------------
+//
+void CMonitorSpeakerParser::HandleCommand( const TDesC8& /*aCmd*/,
+                                           RBuf8& /*aReply*/,
+                                           TBool aReplyNeeded )
+    {
+    TRACE_FUNC_ENTRY
+    if ( !aReplyNeeded )
+        {
+        TRACE_FUNC_EXIT
+        return;
+        }
+    // Checking the iDetectedCmd here means that the failure is the
+    // failing cmd type (set/read/test) for the command, not the command
+    // itself (when cmdUnderstood is EFalse)
+    TBool cmdUnderstood = EFalse;
+    TRAPD( retTrap, cmdUnderstood=HandleCommandL() )
+    if ( !cmdUnderstood || retTrap!=KErrNone )
+        {
+        iCallback->CreateReplyAndComplete( EReplyTypeError );
+        }
+    TRACE_FUNC_EXIT
+    }
+
+// ---------------------------------------------------------------------------
+// From CLegacyModemPluginBase.
+// Cancels a pending HandleCommand request.
+// ---------------------------------------------------------------------------
+//
+void CMonitorSpeakerParser::HandleCommandCancel()
+    {
+    TRACE_FUNC_ENTRY
+    TRACE_FUNC_EXIT
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atext/plugins/legacymodemplugin/src/proxy.cpp	Wed Mar 31 23:19:43 2010 +0300
@@ -0,0 +1,42 @@
+/*
+* 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:  Export ECom interface implementations
+*
+*/
+
+#include <e32base.h>
+#include <ecom/implementationproxy.h>
+#include "legacymodemplugin.h"
+
+// ---------------------------------------------------------------------------
+// An array of TImplementationProxy objects which onnect each
+// implemeation with its instantiation function
+// ---------------------------------------------------------------------------
+//
+const TImplementationProxy ImplementationTable[] =
+	{
+	IMPLEMENTATION_PROXY_ENTRY(0x2002B341, CLegacyModemPlugin::NewL),  // DUN
+	};
+
+// ---------------------------------------------------------------------------
+// Exported proxy function to resolve instantiation methods for an Ecom
+// plug-in DLL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+	{
+	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+
+	return ImplementationTable;
+	}
--- a/atext/server/inc/atextmetadata.h	Mon Mar 15 12:44:59 2010 +0200
+++ b/atext/server/inc/atextmetadata.h	Wed Mar 31 23:19:43 2010 +0300
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2008-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"
@@ -28,8 +28,10 @@
 /** Panic categories */
 enum TATExtPanicCategories
     {
-    EPanicCategoryFaultyMaster = 1,
-    EPanicCategoryPluginType   = 2
+    EPanicCategoryAddPIsM = 1,  // Master exists while adding Partial
+    EPanicCategoryAddMIsP = 2,  // Partial exists while adding Master
+    EPanicCategoryAddMIsM = 3,  // Master exists while adding Master
+    EPanicCategoryType    = 4   // Wrong plugin type (not M|P|O)
     };
 
 /**  Support types supported by RSS file (M|P|O) */
--- a/atext/server/src/atextmetadata.cpp	Mon Mar 15 12:44:59 2010 +0200
+++ b/atext/server/src/atextmetadata.cpp	Wed Mar 31 23:19:43 2010 +0300
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2008-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"
@@ -42,7 +42,7 @@
  */
 
 #include <ecom/ecom.h>
-#include <ecom/implementationInformation.h>
+#include <ecom/implementationinformation.h>
 #include <atextpluginbase.h>
 #include "atextclientsrv.h"
 #include "atextmetadata.h"
@@ -1369,7 +1369,7 @@
             break;
         default:
             _LIT( KPluginType, "PluginType" );
-            User::Panic( KPluginType, EPanicCategoryPluginType );
+            User::Panic( KPluginType, EPanicCategoryType );
         }
     i++;
     if ( i >= count )
@@ -1558,10 +1558,15 @@
     if ( aEntries->Count() > 0 )
         {
         TATExtOneCmdSupport& oneCmdSupport = (*aEntries)[0];
+        if ( oneCmdSupport.iSupportType == ESupportTypePartial )
+            {
+            _LIT( KAddMIsP, "AddMIsP" );
+            User::Panic( KAddMIsP, EPanicCategoryAddMIsP );
+            }
         if ( oneCmdSupport.iSupportType == ESupportTypeMaster )
             {
-            _LIT( KFaultyMaster, "FaultyMaster" );
-            User::Panic( KFaultyMaster, EPanicCategoryFaultyMaster );
+            _LIT( KAddMIsM, "AddMIsM" );
+            User::Panic( KAddMIsM, EPanicCategoryAddMIsM );
             }
         }
     aEntries->InsertL( 0, aOneCmdSupport );
@@ -1588,6 +1593,15 @@
     TATExtOneCmdSupport& aOneCmdSupport )
     {
     TRACE_FUNC_ENTRY
+    if ( aEntries->Count() > 0 )
+        {
+        TATExtOneCmdSupport& oneCmdSupport = (*aEntries)[0];
+        if ( oneCmdSupport.iSupportType == ESupportTypeMaster )
+            {
+            _LIT( KAddPIsM, "AddPIsM" );
+            User::Panic( KAddPIsM, EPanicCategoryAddPIsM );
+            }
+        }
     TInt i = aSearchHelper.iPartialIndex;
     if ( i < 0 )
         {
--- a/bluetooth/btcomm/src/states.cpp	Mon Mar 15 12:44:59 2010 +0200
+++ b/bluetooth/btcomm/src/states.cpp	Wed Mar 31 23:19:43 2010 +0300
@@ -799,6 +799,7 @@
 		CleanupStack::PopAndDestroy(2);
 
 		TSDPAttributeKey key;
+		Mem::FillZ(&key, sizeof(TSDPAttributeKey));
 		key.iMaxLength = 200;
 		key.iRange = EFalse;
 		key.iStateLength = 0;
--- a/bluetooth/btstack/linkmgr/physicallinks.cpp	Mon Mar 15 12:44:59 2010 +0200
+++ b/bluetooth/btstack/linkmgr/physicallinks.cpp	Wed Mar 31 23:19:43 2010 +0300
@@ -818,7 +818,7 @@
 		if (!aEncrypted)
 			{
 			iLinksMan.LinkManagerProtocol().ACLController().SetParked(iHandle, ETrue);
-			iEncryptionEnforcer->EncryptionDisabled(SimplePairingMode()== EPhySimplePairingEnabled);
+			iEncryptionEnforcer->EncryptionDisabled(IsEncryptionPauseResumeSupported());
 			}
 		else
 			{
@@ -4162,12 +4162,12 @@
 		}
 	}
 
-void CEncryptionEnforcer::EncryptionDisabled(TBool aSecurityModeFour)
+void CEncryptionEnforcer::EncryptionDisabled(TBool aEncryptionPauseResumeSupported)
 	{
 	LOG_FUNC
 	LOG1(_L("CEncryptionEnforcer::EncryptionDisabled() : current status = %d"), iState);
 
-	if(aSecurityModeFour)
+	if(aEncryptionPauseResumeSupported)
 		{
 		Stop();
 		ChangeState(EForcingInProgress);
--- a/bluetooth/btstack/linkmgr/physicallinks.h	Mon Mar 15 12:44:59 2010 +0200
+++ b/bluetooth/btstack/linkmgr/physicallinks.h	Wed Mar 31 23:19:43 2010 +0300
@@ -206,7 +206,7 @@
 	static CEncryptionEnforcer* NewLC(CPhysicalLink& aLink, THCIEncryptModeFlag aEncryptionMode);
 	
 	void EncryptionEnabled();
-	void EncryptionDisabled(TBool aSecurityModeFour);
+	void EncryptionDisabled(TBool aEncryptionPauseResumeSupported);
 	void RoleSwitchEvent();
 	
 private:
--- a/bluetooth/btstack/secman/btaccessrequester.cpp	Mon Mar 15 12:44:59 2010 +0200
+++ b/bluetooth/btstack/secman/btaccessrequester.cpp	Wed Mar 31 23:19:43 2010 +0300
@@ -696,18 +696,20 @@
 	else if(aResult == EBTSecManAccessGranted)
 		{
 		LOG(_L8("\tACCESS GRANTED"));
-		if (RemoteIndicatedNoBondingToDedicatedBonding())
-			{
-			// We allow the device to bond, but tell theUI layer so it can delete the link key if it wants to
-			aResult = KErrRemoteDeviceIndicatedNoBonding;
-			LOG(_L8("\t... but remote indicated no bonding"));
-			}
 		}
 	else
 		{
 		LOG1(_L8("\tERROR (%d)"), aResult);
 		}
 #endif // __FLOG_ACTIVE
+	
+	if (aResult == EBTSecManAccessGranted && RemoteIndicatedNoBondingToDedicatedBonding())
+		{
+		// We allow the device to bond, but tell theUI layer so it can delete the link key if it wants to
+		aResult = KErrRemoteDeviceIndicatedNoBonding;
+		LOG(_L8("\t... but remote indicated no bonding"));
+		}
+	
 	iSecMan.AccessRequestComplete(this, aResult);
 	}
 
--- a/bluetooth/btstack/secman/secman.cpp	Mon Mar 15 12:44:59 2010 +0200
+++ b/bluetooth/btstack/secman/secman.cpp	Wed Mar 31 23:19:43 2010 +0300
@@ -556,7 +556,7 @@
 	__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing));
 	__ASSERT_DEBUG(!link->InstanceNumericComparator(), PANIC(KBTSecPanic, EBTSecConnectionNumericComparisonTwice));
 	__ASSERT_DEBUG(!link->InstanceUserConfirmer(), PANIC(KBTSecPanic, EBTSecConnectionUserConfirmationTwice));
-	if(link->InstanceNumericComparator())
+	if(link->InstanceNumericComparator() || link->InstanceUserConfirmer())
 		{
 		return;
 		}
@@ -582,7 +582,10 @@
 				}
 			}
 		}
-	else if (!link->IsPairingExpected())
+	else if (!link->IsPairingExpected()
+			|| ((link->AuthenticationRequirement() == EMitmNotReqDedicatedBonding 
+					|| link->AuthenticationRequirement() == EMitmReqDedicatedBonding)
+				&& !IsDedicatedBondingAttempted(aAddr)))
 		{
 		TRAPD(err,link->NewUserConfirmerL(aAddr, *this, ETrue));
 		if(err)