Revision: 201011
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 16 Apr 2010 16:09:25 +0300
changeset 17 907b2fb7aa8e
parent 16 0089b2f7ebd8
child 19 4b81101308c6
Revision: 201011 Kit: 201015
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/btdocs/Designs/backuprestore.mdzip
bluetooth/btextnotifiers/bwins/BTEXTNOTIFIERSU.DEF
bluetooth/btextnotifiers/eabi/BTExtNotifiersU.DEF
bluetooth/btextnotifiers/inc/BTExtNotifiersPartner.h
bluetooth/btextnotifiers/src/BTExtNotifiers.cpp
bluetooth/btstack/avctp/avctp.cpp
bluetooth/btstack/avctp/avctpmuxerstates.cpp
bluetooth/btstack/common/bt_v2.mmp
bluetooth/btstack/linkmgr/Subscribers.cpp
bluetooth/btstack/linkmgr/Subscribers.h
bluetooth/btstack/linkmgr/bredrcontrollerconfiguration.cpp
bluetooth/btstack/linkmgr/bredrcontrollerconfiguration.h
bluetooth/btstack/linkmgr/hcifacade.cpp
bluetooth/btstack/linkmgr/linkmgr.cpp
bluetooth/btstack/linkmgr/linkmgr.h
bluetooth/btstack/linkmgr/physicallinks.cpp
bluetooth/btstack/linkmgr/physicallinks.h
bluetooth/btstack/secman/btaccessrequester.cpp
bluetooth/btstack/secman/secman.cpp
bluetooth/btstack/secman/secman.h
bluetoothapitest/bluetoothsvs/group/bluetoothsvs.mrp
bluetoothmgmt/bluetoothclientlib/btlib/btsocket.cpp
bluetoothmgmt/bluetoothclientlib/inc/bt_subscribe_partner.h
bluetoothmgmt/bluetoothclientlib/inc/bttypespartner.h
bluetoothmgmt/btmgr/BTDevice/BTDevice.cpp
bluetoothmgmt/btmgr/BTManServer/BTManServer.cpp
bluetoothmgmt/btmgr/BTManServer/BTManServer.mmp
bluetoothmgmt/btmgr/BTManServer/BTRegistryDB.cpp
bluetoothmgmt/btmgr/BTManServer/BTRegistryDB.h
bluetoothmgmt/btmgr/BTManServer/backup_registration.xml
bluetoothmgmt/btmgr/BTManServer/btmanserverburmgr.cpp
bluetoothmgmt/btmgr/BTManServer/btmanserverburmgr.h
bluetoothmgmt/btmgr/BTManServer/btmanserverburmgr.inl
bluetoothmgmt/btmgr/BTManServer/btmanserverburstatemachine.cpp
bluetoothmgmt/btmgr/BTManServer/btmanserverburstatemachine.h
bluetoothmgmt/btmgr/Inc/BTManServer.h
bluetoothmgmt/btmgr/bld.inf
bluetoothmgmt/btrom/bluetooth.iby
bt_info/bt_metadata/bt_metadata.mrp
irda/irdastack/irtranp/BFTP.CPP
irda/irdastack/irtranp/SCEP.CPP
irda/irdastack/irtranp/tranp.cpp
--- a/atext/group/bld.inf	Fri Mar 19 09:53:48 2010 +0200
+++ b/atext/group/bld.inf	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Apr 16 16:09:25 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	Fri Mar 19 09:53:48 2010 +0200
+++ b/atext/server/inc/atextmetadata.h	Fri Apr 16 16:09:25 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	Fri Mar 19 09:53:48 2010 +0200
+++ b/atext/server/src/atextmetadata.cpp	Fri Apr 16 16:09:25 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	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btcomm/src/states.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -693,6 +693,7 @@
 		RNetDatabase& netdb=aContext->iNetDatabase;
 
 		TSDPAttributeKey key;
+		Mem::FillZ(&key, sizeof(TSDPAttributeKey));
 		key.iQueryType = KSDPAttributeQuery;
 		// suck out the first service record handle.
 		iFactory->iExtractedHandleCount = 1;
@@ -798,6 +799,7 @@
 		CleanupStack::PopAndDestroy(2);
 
 		TSDPAttributeKey key;
+		Mem::FillZ(&key, sizeof(TSDPAttributeKey));
 		key.iMaxLength = 200;
 		key.iRange = EFalse;
 		key.iStateLength = 0;
Binary file bluetooth/btdocs/Designs/backuprestore.mdzip has changed
--- a/bluetooth/btextnotifiers/bwins/BTEXTNOTIFIERSU.DEF	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btextnotifiers/bwins/BTEXTNOTIFIERSU.DEF	Fri Apr 16 16:09:25 2010 +0300
@@ -76,3 +76,7 @@
 	?StrongPinCodeRequired@TBTPinCodeEntryNotifierParams@@QBEHXZ @ 75 NONAME ; int TBTPinCodeEntryNotifierParams::StrongPinCodeRequired(void) const
 	?Type@TBTNotifierUpdateParams2@@QBE?AW4TUpdateParamType@1@XZ @ 76 NONAME ; enum TBTNotifierUpdateParams2::TUpdateParamType TBTNotifierUpdateParams2::Type(void) const
 	?RecommendedPinCodeMinLength@TBTPinCodeEntryNotifierParams@@QBEIXZ @ 77 NONAME ; unsigned int TBTPinCodeEntryNotifierParams::RecommendedPinCodeMinLength(void) const
+	??0TBTUserConfirmationParams@@QAE@XZ @ 78 NONAME ; TBTUserConfirmationParams::TBTUserConfirmationParams(void)
+	?LocallyInitiated@TBTUserConfirmationParams@@QBEHXZ @ 79 NONAME ; int TBTUserConfirmationParams::LocallyInitiated(void) const
+	??0TBTUserConfirmationParams@@QAE@ABVTBTDevAddr@@ABVTDesC16@@H@Z @ 80 NONAME ; TBTUserConfirmationParams::TBTUserConfirmationParams(class TBTDevAddr const &, class TDesC16 const &, int)
+
--- a/bluetooth/btextnotifiers/eabi/BTExtNotifiersU.DEF	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btextnotifiers/eabi/BTExtNotifiersU.DEF	Fri Apr 16 16:09:25 2010 +0300
@@ -95,3 +95,9 @@
 	_ZNK29TBTPinCodeEntryNotifierParams16PinCodeMinLengthEv @ 94 NONAME
 	_ZNK29TBTPinCodeEntryNotifierParams21StrongPinCodeRequiredEv @ 95 NONAME
 	_ZNK29TBTPinCodeEntryNotifierParams27RecommendedPinCodeMinLengthEv @ 96 NONAME
+	_ZN25TBTUserConfirmationParamsC1ERK10TBTDevAddrRK7TDesC16i @ 97 NONAME
+	_ZN25TBTUserConfirmationParamsC1Ev @ 98 NONAME
+	_ZN25TBTUserConfirmationParamsC2ERK10TBTDevAddrRK7TDesC16i @ 99 NONAME
+	_ZN25TBTUserConfirmationParamsC2Ev @ 100 NONAME
+	_ZNK25TBTUserConfirmationParams16LocallyInitiatedEv @ 101 NONAME
+
--- a/bluetooth/btextnotifiers/inc/BTExtNotifiersPartner.h	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btextnotifiers/inc/BTExtNotifiersPartner.h	Fri Apr 16 16:09:25 2010 +0300
@@ -184,6 +184,20 @@
 */
 const TUid KBTPasskeyDisplayNotifierUid={0x10285AD4};
 
+/*
+UID of the "User Confirmation" confirmation request RNotifier plugin.
+
+The notifier will be started with a parameter of type TBTUserConfirmationParamsPckg.
+
+The notifier will receive updates of type TBTNotifierUpdateParamsPckg2.
+
+@see TBTNotifierUpdateParamsPckg2
+
+@publishedPartner
+@released
+*/
+const TUid KBTUserConfirmationNotifierUid={0x2002E224};
+
 /**
 UID of the "PIN Code Entry" RNotifier plugin.
 
@@ -330,6 +344,33 @@
 	TUint32	iPadding1; 
 	};
 
+/** 
+Secure simple pairing "User Confirmation" parameters.
+This class packages the parameters passed to a numeric comparison notifier.
+	
+@publishedPartner
+@released
+*/
+NONSHARABLE_CLASS(TBTUserConfirmationParams)
+	: public TBTNotifierParams2
+	{	
+public:
+	IMPORT_C TBTUserConfirmationParams(const TBTDevAddr& aDevAddr, const TDesC& aDeviceName, TBool aLocallyInitiated);
+	IMPORT_C TBTUserConfirmationParams();
+	
+public:
+	IMPORT_C TBool LocallyInitiated() const;
+	
+private:
+	TBool				iLocallyInitiated;
+	
+	// This data padding has been added to help prevent future binary compatibility breaks	
+	// Neither iPadding1 nor iPadding2 have been zero'd because they are currently not used
+	TUint32	iPadding1;
+	TUint32 iPadding2;
+	};
+
+
 /**
 The base update parameter for the Bluetooth pairing notifiers.
 This class is intended to allow multiple different updates parameters to be
@@ -431,6 +472,12 @@
 */
 typedef TPckgBuf<TBTPasskeyDisplayParams> TBTPasskeyDisplayParamsPckg;
 /**
+Typedef'ed pckgbuf to send passkey entry display parameters to the notifier framework.
+@publishedPartner
+@released
+*/
+typedef TPckgBuf<TBTUserConfirmationParams> TBTUserConfirmationParamsPckg;
+/**
 Typedef'ed pckgbuf to send PIN code entry parameters to the notifier framework.
 @publishedPartner
 @released
@@ -456,4 +503,4 @@
 */
 typedef TPckgBuf<TBTPasskeyDisplayUpdateParams> TBTPasskeyDisplayUpdateParamsPckg;
 
-#endif // BTEXTNOTIFIERSPARTNER_H
\ No newline at end of file
+#endif // BTEXTNOTIFIERSPARTNER_H
--- a/bluetooth/btextnotifiers/src/BTExtNotifiers.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btextnotifiers/src/BTExtNotifiers.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -664,6 +664,42 @@
 	return iLocallyInitiated;
 	}
 
+//
+// TBTUserConfirmationParams
+//
+
+/**
+@internalTechnology
+*/
+EXPORT_C TBTUserConfirmationParams::TBTUserConfirmationParams(const TBTDevAddr& aDevAddr, const TDesC& aDeviceName, TBool aLocallyInitiated)
+	: TBTNotifierParams2(aDevAddr, aDeviceName)
+	, iLocallyInitiated(aLocallyInitiated)
+	{
+	LOG_FUNC
+	}
+
+/**
+Default constructor.  Required to allow the class to be packaged with the TPckg family of classes.
+@internalTechnology
+*/
+EXPORT_C TBTUserConfirmationParams::TBTUserConfirmationParams()
+	: TBTNotifierParams2()
+	{
+	LOG_FUNC
+	}
+
+/**
+Accessor for indicating whether the user confirmation process was initiated by a local request,
+or whether it was trigger by the remote device.
+@return EFalse if remote side initiated, otherwise it is locally initiated.
+*/
+EXPORT_C TBool TBTUserConfirmationParams::LocallyInitiated() const
+	{
+	LOG_FUNC
+	return iLocallyInitiated;
+	}
+
+
 
 //
 // TBTPinCodeEntryNotifierParams
--- a/bluetooth/btstack/avctp/avctp.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/avctp/avctp.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -398,6 +398,8 @@
 	config().SetMinMTU(KDefaultMtu);
 	config().SetMaxReceiveUnitSize(KAvctpSecondaryChannelInboundMTU);
 	config().SetMinMRU(KDefaultMtu);
+	config().ConfigureReliableChannel(TL2CapConfig::EDefaultRetransmission);
+	config().SetLegacyModesDisallowed(ETrue);
 	
 	__DEBUG_ONLY(TInt err =) sap2->SetOption(KSolBtL2CAP, KL2CAPUpdateChannelConfig, config); 
 	__ASSERT_DEBUG(err == KErrNone, Panic(ESetOptionError));
--- a/bluetooth/btstack/avctp/avctpmuxerstates.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/avctp/avctpmuxerstates.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -822,6 +822,8 @@
 		config().SetMinMTU(KDefaultMtu);
 		config().SetMaxReceiveUnitSize(KAvctpSecondaryChannelInboundMTU);
 		config().SetMinMRU(KDefaultMtu);
+		config().ConfigureReliableChannel(TL2CapConfig::EDefaultRetransmission);
+		config().SetLegacyModesDisallowed(ETrue);
 
 		err = aTransport.iChannelSAPs[KAvctpSecondaryChannel]->SetOption(KSolBtL2CAP, KL2CAPUpdateChannelConfig, config); 
 		__ASSERT_DEBUG(err == KErrNone, Panic(ESetOptionError));
--- a/bluetooth/btstack/common/bt_v2.mmp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/common/bt_v2.mmp	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-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"
@@ -70,6 +70,7 @@
 SOURCE btcommands.cpp
 SOURCE AclDataQ.cpp
 SOURCE AclDataQController.cpp
+SOURCE bredrcontrollerconfiguration.cpp
 
 SOURCE hcifacade.cpp
 SOURCE hcifacade_commands.cpp
--- a/bluetooth/btstack/linkmgr/Subscribers.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/linkmgr/Subscribers.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-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"
@@ -328,4 +328,35 @@
 		}
 	}
 
+//-----------------
 
+CPageScanParametersSubscriber* CPageScanParametersSubscriber::NewL(CLinkMgrProtocol& aLinkMgrProtocol)
+	{
+	CPageScanParametersSubscriber* s = new(ELeave) CPageScanParametersSubscriber(aLinkMgrProtocol);
+	CleanupStack::PushL(s);
+	s->ConstructL(KPropertyKeyBluetoothSetPageScanParameters);
+	CleanupStack::Pop(s);
+	return s;
+	}
+
+CPageScanParametersSubscriber::CPageScanParametersSubscriber(CLinkMgrProtocol& aLinkMgrProtocol)
+: CSubscriber(aLinkMgrProtocol)
+	{
+	}
+
+void CPageScanParametersSubscriber::RunL()
+	{
+	//Get this value first before we subscribe again
+	TInt ret = iStatus.Int();
+	Subscribe();
+
+	if(ret==KErrNone)
+		{
+		TInt pageScanParameters;
+		ret = iProperty.Get(pageScanParameters);
+		if(ret == KErrNone)
+			{
+			iParent.SetPageScanParameters(static_cast<TPageScanParameterSettings>(pageScanParameters));
+			}
+		}
+	}
--- a/bluetooth/btstack/linkmgr/Subscribers.h	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/linkmgr/Subscribers.h	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-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"
@@ -119,4 +119,13 @@
 	void RunL();
 	};
 
+NONSHARABLE_CLASS(CPageScanParametersSubscriber) : public CSubscriber
+	{
+public:
+	static CPageScanParametersSubscriber* NewL(CLinkMgrProtocol& aLinkMgrProtocol);
+private:
+	CPageScanParametersSubscriber(CLinkMgrProtocol& aLinkMgrProtocol);
+	void RunL();
+	};
+
 #endif //#ifndef _SUBSCRIBERS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/linkmgr/bredrcontrollerconfiguration.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -0,0 +1,192 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <bluetooth/logger.h>
+#include "debug.h"
+#include "linkutil.h"
+#include "bredrcontrollerconfiguration.h"
+#include <bt_subscribe.h>
+#include <bt_subscribe_partner.h>
+#include <bluetooth/hcicommandqueue.h>
+#include <bluetooth/hci/readpagescanactivitycommand.h>
+#include <bluetooth/hci/readpagescanactivitycompleteevent.h>
+#include <bluetooth/hci/readpagescantypecommand.h>
+#include <bluetooth/hci/readpagescantypecompleteevent.h>
+#include <bluetooth/hci/writepagescanactivitycommand.h>
+#include <bluetooth/hci/writepagescantypecommand.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_LINKMGR);
+#endif
+
+const TInt KUnitializedParameters	= -1;
+
+const TUint16 KDefaultPageScanInterval	= 0x0800;
+const TUint16 KDefaultPageScanWindow	= 0x0012;
+const TUint8 KDefaultPageScanType		= 0x00;
+
+const TUint16 KFastConnectionPageScanInterval	= 0x0024;
+const TUint16 KFastConnectionPageScanWindow		= 0x0012;
+const TUint8 KFastConnectionPageScanType		= 0x01;
+
+
+CBrEdrControllerConfiguration::CBrEdrControllerConfiguration(MHCICommandQueue& aCommandQueue,
+															 CLinkMgrProtocol& aLinkMgrProtocol)
+	:	iOriginalPageScanInterval(KDefaultPageScanInterval),
+		iOriginalPageScanWindow(KDefaultPageScanWindow),
+		iOriginalPageScanType(KDefaultPageScanType),
+		iPageScanParameters(KUnitializedParameters),
+		iCommandQueue(aCommandQueue),
+		iLinkMgrProtocol(aLinkMgrProtocol)
+	{
+	LOG_FUNC
+	}
+
+CBrEdrControllerConfiguration::~CBrEdrControllerConfiguration()
+	{
+	LOG_FUNC
+	}
+
+CBrEdrControllerConfiguration* CBrEdrControllerConfiguration::NewL(MHCICommandQueue& aCommandQueue,
+																   CLinkMgrProtocol& aLinkMgrProtocol)
+	{
+	LOG_STATIC_FUNC
+	CBrEdrControllerConfiguration* self
+		= new (ELeave) CBrEdrControllerConfiguration(aCommandQueue, aLinkMgrProtocol);
+	return self;
+	}
+
+void CBrEdrControllerConfiguration::SetPageScanParametersL(TPageScanParameterSettings aPageScanParameters)
+	{
+	LOG_FUNC
+	if (iPageScanParameters == KUnitializedParameters)
+		{
+		// obtain the original Controller parameters
+		LOG(_L("obtaining the original Controller parameters"));
+		
+		CReadPageScanActivityCommand* readPageScanActCmd = CReadPageScanActivityCommand::NewL();
+		// ownership of cmd transfered even if MhcqAddCommandL leaves
+		iCommandQueue.MhcqAddCommandL(readPageScanActCmd, *this);
+
+		CReadPageScanTypeCommand* readPageScanTypeCmd = CReadPageScanTypeCommand::NewL();
+		// ownership of cmd transfered even if MhcqAddCommandL leaves
+		iCommandQueue.MhcqAddCommandL(readPageScanTypeCmd, *this);
+
+		iPageScanParameters = EStandardPageScanParameters;
+
+		// if the original parameters are requested we don't do anything
+		if (aPageScanParameters == EStandardPageScanParameters)
+			return;
+		}
+
+	// store the settings to publish them later
+	iPageScanParameters			= EStandardPageScanParameters;
+
+	TUint16 pageScanInterval	= iOriginalPageScanInterval;
+	TUint16 pageScanWindow		= iOriginalPageScanWindow;
+	TUint8 pageScanType			= iOriginalPageScanType;
+
+	if (aPageScanParameters == EFastConnectionPageScanParameters)
+		{
+		// store the settings to publish them later
+		iPageScanParameters	= EFastConnectionPageScanParameters;
+		pageScanInterval	= KFastConnectionPageScanInterval;
+		pageScanWindow		= KFastConnectionPageScanWindow;
+		pageScanType		= KFastConnectionPageScanType;
+		}
+
+	LOG1(_L("Applying page scan parameter settings %d"), iPageScanParameters);
+
+	// apply the requested page scan parameters
+	CWritePageScanActivityCommand* writePageScanActCmd
+		= CWritePageScanActivityCommand::NewL(pageScanInterval, pageScanWindow);
+	// ownership of cmd transfered even if MhcqAddCommandL leaves
+	iCommandQueue.MhcqAddCommandL(writePageScanActCmd, *this);
+
+	CWritePageScanTypeCommand* writePageScanTypeCmd = CWritePageScanTypeCommand::NewL(pageScanType);
+	// ownership of cmd transfered even if MhcqAddCommandL leaves
+	iCommandQueue.MhcqAddCommandL(writePageScanTypeCmd, *this);
+	}
+
+void CBrEdrControllerConfiguration::MhcqcCommandEventReceived(const THCIEventBase& aEvent,
+															  const CHCICommandBase* aRelatedCommand)
+	{
+	LOG_FUNC
+	LOG3(_L("Event 0x%02x (errorcode=%d) received for Command 0x%04x"), aEvent.EventCode(),
+			aEvent.ErrorCode(), aRelatedCommand->Opcode());
+	if (aEvent.EventCode() == ECommandCompleteEvent && aEvent.ErrorCode() == KErrNone)
+		{
+		switch (aRelatedCommand->Opcode())
+			{
+		case KReadPageScanActivityOpcode:
+			{
+			const TReadPageScanActivityCompleteEvent& readPageScanActivityCompleteEvent
+				= TReadPageScanActivityCompleteEvent::Cast(aEvent);
+			iOriginalPageScanInterval	= readPageScanActivityCompleteEvent.PageScanInterval();
+			iOriginalPageScanWindow		= readPageScanActivityCompleteEvent.PageScanwindow();
+			LOG2(_L("page scan activity parameters received (interval=0x%04x, window=0x%04x)"),
+					iOriginalPageScanInterval, iOriginalPageScanWindow);
+			break;
+			}
+		case KReadPageScanTypeOpcode:
+			{
+			const TReadPageScanTypeCompleteEvent& readPageScanTypeCompleteEvent
+				= TReadPageScanTypeCompleteEvent::Cast(aEvent);
+			iOriginalPageScanType = readPageScanTypeCompleteEvent.PageScanType();
+			LOG1(_L("page scan type received (=0x%02)"), iOriginalPageScanType);
+			break;
+			}
+		case KWritePageScanActivityOpcode:
+			// provide an indication that the requested parameters have been enabled
+			// as there is no way to indicate halfway success (one command sent succefully, another failed)
+			// page scan activity command status is the criteria for the whole operation
+			(void) RProperty::Set(KPropertyUidBluetoothCategory,
+								  KPropertyKeyBluetoothGetPageScanParameters, iPageScanParameters);
+			LOG1(_L("Write Page Scan Activity command confirmed, page scan parameter settings %d applied"),
+					iPageScanParameters);
+			break;
+		case KWritePageScanTypeOpcode:
+			LOG(_L("Write Page Scan Type command confirmed"));
+			break;
+		default:
+			LOG1(_L("Warning!! Upexpected Command Complete Event Received (command opcode:0x%04x)"),
+					aRelatedCommand->Opcode());
+			__ASSERT_DEBUG(EFalse, Panic(EHCIUnexpectedEvent));
+			break;
+			}
+		}
+	}
+
+void CBrEdrControllerConfiguration::SetPageScanParameters(TPageScanParameterSettings aPageScanParameters)
+	{
+	LOG_FUNC
+	// errors handled by upper level component
+	// not updated in time the KPropertyKeyBluetoothGetPageScanParameters P&K key indicates an error situation
+	TRAPD(err, SetPageScanParametersL(aPageScanParameters));
+	if (err)
+		{
+		LOG1(_L("Warning!! SetPageScanParameters left with error %d"), err);
+		}
+	}
+
+void CBrEdrControllerConfiguration::MhcqcCommandErrored(TInt IF_FLOGGING(aErrorCode),
+														const CHCICommandBase* IF_FLOGGING(aCommand))
+	{
+	LOG_FUNC
+	// errors handled by upper level component
+	// not updated in time the KPropertyKeyBluetoothGetPageScanParameters P&K key indicates an error situation
+	LOG2(_L("Warning!! Command 0x%04x failed with error %d"), aCommand->Opcode(), aErrorCode);
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/linkmgr/bredrcontrollerconfiguration.h	Fri Apr 16 16:09:25 2010 +0300
@@ -0,0 +1,63 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#ifndef BREDRCONTROLLERCONFIGURATION_H
+#define BREDRCONTROLLERCONFIGURATION_H
+
+#include <e32base.h>
+#include <bttypespartner.h>
+#include <bluetooth/hcicommandqueueclient.h>
+
+class MHCICommandQueue;
+class CLinkMgrProtocol;
+
+/**
+	Handles page scan parameters update requests. Maps KPageScanParametersInfo enums to actual page scan parameters
+	and sends appropriate HCI commands.
+	Before the first update the original settings are stored. If fetching of them fails the default values
+	from the Bluetooth specification are used instead of them.
+*/
+NONSHARABLE_CLASS(CBrEdrControllerConfiguration) : public CBase, public MHCICommandQueueClient
+	{
+public:
+	static CBrEdrControllerConfiguration* NewL(MHCICommandQueue& aCommandQueue, CLinkMgrProtocol& aLinkMgrProtocol);
+	~CBrEdrControllerConfiguration();
+
+	// from MHCICommandQueueClient
+	void MhcqcCommandEventReceived(const THCIEventBase& aEvent, const CHCICommandBase* aRelatedCommand);
+	void MhcqcCommandErrored(TInt aErrorCode, const CHCICommandBase* aCommand);
+
+	void SetPageScanParameters(TPageScanParameterSettings aPageScanSettings);
+
+private:
+	CBrEdrControllerConfiguration(MHCICommandQueue& aCommandQueue, CLinkMgrProtocol& aLinkMgrProtocol);
+
+private:
+	void SetPageScanParametersL(TPageScanParameterSettings aPageScanSettings);
+
+private:
+// owned
+	TUint16		iOriginalPageScanInterval;
+	TUint16		iOriginalPageScanWindow;
+	TUint8		iOriginalPageScanType;
+
+	TInt		iPageScanParameters;
+
+// non-owned resources
+	MHCICommandQueue&	iCommandQueue;
+	CLinkMgrProtocol&	iLinkMgrProtocol;
+	};
+
+#endif
--- a/bluetooth/btstack/linkmgr/hcifacade.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/linkmgr/hcifacade.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-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"
@@ -372,6 +372,7 @@
 	switch(aStatus)
 		{
 	case EBTOn:
+		{
 		// Start-up Bluetooth
 		// Avoid from ON to ON
 		__ASSERT_DEBUG (iLastPowerState == EBTOff, Panic(EHCIPowerStateError));
@@ -380,7 +381,10 @@
 		//recovery the channels
 		iLinkMgrProtocol.LinkMuxer().ChannelsFree(iHCTLState);
 		
-		TRAPD(err, InitL(iLinkMgrProtocol.LocalDevice()));
+		TBTLocalDevice settings(iLinkMgrProtocol.LocalDevice());
+		iLinkMgrProtocol.DesiredLocalDeviceSettings().Modify(settings);
+		
+		TRAPD(err, InitL(settings));
 		// Hopefully this should just work it won't rename the device though 
 		// since that is persisted
 		if (err)
@@ -390,14 +394,17 @@
 			}
 		else
 			{
+			iLinkMgrProtocol.DesiredLocalDeviceSettings().ResetChangesMask();
 			// Reset the inquiry manager
 			iLinkMgrProtocol.InquiryMgr().SetHWState(CBTInquiryMgr::EIdle);
 			// Clear debug mode
 			iLinkMgrProtocol.SecMan().ClearDebugMode();
 			}
+		}
 		break;
 		
 	case EBTOff:
+		{
 		// Reset the Command Queue
 		// Avoid from OFF to OFF
 		__ASSERT_DEBUG (iLastPowerState == EBTOn, Panic(EHCIPowerStateError));
@@ -433,10 +440,13 @@
 		// NB This ensures AFH host channel classification command blocking is 
 		// not in place if power comes back on.
 		iAFHTimer->Reset();
+		}
 		break;
 		
 	default:
+		{
 		Panic(EHCIUnknownPowerState);
+		}
 		break;
 		}
 	
--- a/bluetooth/btstack/linkmgr/linkmgr.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/linkmgr/linkmgr.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -37,6 +37,7 @@
 #include "eirmanager.h"
 #include "eirpublisherlocalname.h"
 #include "eirpublishertxpowerlevel.h"
+#include "bredrcontrollerconfiguration.h"
 
 
 #include "ProxySAP.h"
@@ -110,6 +111,7 @@
 	iProperty.Delete(KPropertyUidBluetoothCategory,	KPropertyKeyBluetoothSetAFHChannelAssessmentMode);
 	iProperty.Delete(KPropertyUidBluetoothCategory,	KPropertyKeyBluetoothSetDeviceName);
 	iProperty.Delete(KPropertyUidBluetoothCategory,	KPropertyKeyBluetoothSetAcceptPairedOnlyMode);
+	iProperty.Delete(KPropertyUidBluetoothCategory,	KPropertyKeyBluetoothSetPageScanParameters);
 
 	// Delete standard P&S values (possibly trying to delete already deleted shared set+get values)
 	iProperty.Delete(KPropertyUidBluetoothCategory, KPropertyKeyBluetoothGetLocalDeviceAddress);
@@ -122,6 +124,8 @@
 	iProperty.Delete(KPropertyUidBluetoothCategory,	KPropertyKeyBluetoothGetAcceptPairedOnlyMode);
 	iProperty.Delete(KPropertyUidBluetoothCategory,	KPropertyKeyBluetoothHostResolverActive);
 	iProperty.Delete(KPropertyUidBluetoothCategory,	KPropertyKeyBluetoothSetSimplePairingDebugMode);
+	iProperty.Delete(KPropertyUidBluetoothCategory,	KPropertyKeyBluetoothGetPageScanParameters);
+
 
 	delete iPhysicalLinksMgr;
 	delete iInquiryMgr;
@@ -190,7 +194,6 @@
 		//
 		iLocalDeviceSettings.SetDeviceClass(iLocalDeviceSettings.DeviceClass() & KDeviceClassBitMask);
 		
-		
 		//NB - no (ELeave) here - in OOM we'd rather continue and not update the registry
 		//than Leave.  All calls to methods are guarded by "if (iRegistryUpdater)"
 		iRegistryUpdater = new CRegistryUpdater(iLocalDevice, iLocalDeviceSettings);
@@ -283,6 +286,11 @@
 		CleanupStack::Pop(subscriber);
 		}
 
+	subscriber = CPageScanParametersSubscriber::NewL(*this);
+	CleanupStack::PushL(subscriber);
+	User::LeaveIfError(iSubscribers.Append(subscriber));
+	CleanupStack::Pop(subscriber);
+
 	// set CoD - leave if goes wrong, user's device will be "unknown" otherwise
 	// NB - In future we should tie this to the SDP Server...(or someother higher API...)
 	
@@ -306,6 +314,9 @@
 	//is, as a consequence, 'Set' appropriately (when the associated controller 
 	//event arrives).
 	DoSetLimitedDiscoverableL(iLocalDeviceSettings.LimitedDiscoverable());
+
+	LOG(_L("LinkMgr : Initialising BR/EDR Controller Configuration"));
+	iBrEdrControllerConfiguration = CBrEdrControllerConfiguration::NewL(iHCIFacade->CommandQController(), *this);
 	
 	LOG(_L("LinkMgr : Initialising complete"));
 	}
@@ -382,6 +393,17 @@
 							KCOMMDD
 							));
 
+	(void)(iProperty.Define(KPropertyUidBluetoothCategory,
+							KPropertyKeyBluetoothSetPageScanParameters,
+							RProperty::EInt,
+							KLOCAL_SERVICES_AND_NETWORK_CONTROL,
+							KLOCAL_SERVICES_AND_NETWORK_CONTROL
+							));
+
+	(void) RProperty::Set(KPropertyUidBluetoothCategory,
+						  KPropertyKeyBluetoothSetPageScanParameters,
+						  EStandardPageScanParameters);
+
 
 	// Original Get P&S value definitions.
 
@@ -454,6 +476,17 @@
 							KLOCAL_SERVICES,
 						   	KLOCAL_SERVICES_AND_NETWORK_CONTROL
 							));
+
+	(void)(iProperty.Define(KPropertyUidBluetoothCategory,
+							KPropertyKeyBluetoothGetPageScanParameters,
+							RProperty::EInt,
+							KLOCAL_SERVICES_AND_NETWORK_CONTROL,
+							KLOCAL_SERVICES_AND_NETWORK_CONTROL
+							));
+							
+	(void) RProperty::Set(KPropertyUidBluetoothCategory,
+						  KPropertyKeyBluetoothGetPageScanParameters,
+						  EStandardPageScanParameters);
 	}
 
 void CLinkMgrProtocol::DeletePublications()
@@ -948,8 +981,19 @@
 	// Only write the CoD bits if they have changed from the existing setting
 	if (iPendingLocalDeviceSettings.DeviceClass() != aCoD)
 		{
-		iPendingLocalDeviceSettings.SetDeviceClass(aCoD);
-		iHCIFacade->WriteDeviceClassL(aCoD);
+		TRAPD(err, iHCIFacade->WriteDeviceClassL(aCoD));
+		if (err == KErrNone)
+			{
+			iPendingLocalDeviceSettings.SetDeviceClass(aCoD);
+			}
+		else
+			{
+			/* If the function errors, it is probably becuase the power is off, so we'll save the setting for power on
+			   If the error is for a different reason, setting this doesn't do any harm anyway - it will get picked
+			   up the next time the power is turned on */
+			iDesiredLocalDeviceSettings.SetDeviceClass(aCoD);
+			User::Leave(err);
+			}
 		}
 	}
 
@@ -963,6 +1007,13 @@
 		{
 		iPendingLocalDeviceSettings.SetDeviceName(aName);
 		}
+	else
+		{
+		/* If the function leaves, it is probably becuase the power is off, so we'll save the setting for power on
+		   If the leave is for a different reason, setting this doesn't do any harm anyway - it will get picked
+		   up the next time the power is turned on */
+		iDesiredLocalDeviceSettings.SetDeviceName(aName);
+		}
 	return err;
 	}
 
@@ -975,8 +1026,19 @@
 void CLinkMgrProtocol::SetAFHChannelAssessmentModeL(TBool aMode)
 	{
 	LOG_FUNC
-	iPendingLocalDeviceSettings.SetAFHChannelAssessmentMode(aMode);
-	iHCIFacade->WriteAFHChannelAssessmentModeL(aMode);
+	TRAPD(err, iHCIFacade->WriteAFHChannelAssessmentModeL(aMode));
+	if (err == KErrNone)
+		{
+		iPendingLocalDeviceSettings.SetAFHChannelAssessmentMode(aMode);
+		}
+	else
+		{
+		/* If the function leaves, it is probably becuase the power is off, so we'll save the setting for power on
+		   If the leave is for a different reason, setting this doesn't do any harm anyway - it will get picked
+		   up the next time the power is turned on */
+		iDesiredLocalDeviceSettings.SetAFHChannelAssessmentMode(aMode);
+		User::Leave(err);
+		}
 	}
 
 void CLinkMgrProtocol::SetLimitedDiscoverableIfChangedL(TBool aOn)
@@ -1004,9 +1066,20 @@
 	if (aOn)
 		{
 		// turn on LIAC
-		iPendingLocalDeviceSettings.SetLimitedDiscoverable(ETrue);
-		WriteClassOfDeviceL(iPendingLocalDeviceSettings.DeviceClass() | (EMajorServiceLimitedDiscoverableMode << 
-				(KLengthOfDeviceClass+KStartingOffsetOfDeviceClass))); 
+		TRAPD(err, WriteClassOfDeviceL(iPendingLocalDeviceSettings.DeviceClass() | (EMajorServiceLimitedDiscoverableMode << 
+				(KLengthOfDeviceClass+KStartingOffsetOfDeviceClass))));
+		if (err == KErrNone)
+			{
+			iPendingLocalDeviceSettings.SetLimitedDiscoverable(ETrue);
+			}
+		else
+			{
+			/* If the function leaves, it is probably becuase the power is off, so we'll save the setting for power on
+			   If the leave is for a different reason, setting this doesn't do any harm anyway - it will get picked
+			   up the next time the power is turned on */
+			iDesiredLocalDeviceSettings.SetLimitedDiscoverable(ETrue);
+			User::Leave(err);
+			}
 		numIACs = 2;
 		iacs[0] = KLIAC;
 		iacs[1] = KGIAC;
@@ -1014,9 +1087,20 @@
 	else
 		{
 		// turn off LIAC - could do the 1 minute GAP timer?
-		iPendingLocalDeviceSettings.SetLimitedDiscoverable(EFalse);
-		WriteClassOfDeviceL(iPendingLocalDeviceSettings.DeviceClass() & ~(EMajorServiceLimitedDiscoverableMode << 
-				(KLengthOfDeviceClass+KStartingOffsetOfDeviceClass))); 
+		TRAPD(err, WriteClassOfDeviceL(iPendingLocalDeviceSettings.DeviceClass() & ~(EMajorServiceLimitedDiscoverableMode << 
+				(KLengthOfDeviceClass+KStartingOffsetOfDeviceClass))));
+		if (err == KErrNone)
+			{
+			iPendingLocalDeviceSettings.SetLimitedDiscoverable(EFalse);
+			}
+		else
+			{
+			/* If the function leaves, it is probably becuase the power is off, so we'll save the setting for power on
+			   If the leave is for a different reason, setting this doesn't do any harm anyway - it will get picked
+			   up the next time the power is turned on */
+			iDesiredLocalDeviceSettings.SetLimitedDiscoverable(EFalse);
+			User::Leave(err);
+			}
 		numIACs = 1;
 		iacs[0] = KGIAC;
 		}
@@ -1223,6 +1307,10 @@
 	LOG_FUNC
 	iLocalDeviceAddress = aAddr;
 
+	// Also update registry with local device address
+	iLocalDeviceSettings.SetAddress(iLocalDeviceAddress);
+	UpdateSettings();
+
 	// publish this number - might be useful
 	const TDesC8& des = aAddr.Des();
 	(void)iProperty.Set(KPropertyUidBluetoothCategory,
@@ -1320,6 +1408,11 @@
 	iPendingLocalDeviceSettings.SetDeviceClass(KDeviceClassReset);
 	}
 
+void CLinkMgrProtocol::SetPageScanParameters(TPageScanParameterSettings aPageScanParameters)
+	{
+	LOG_FUNC
+	iBrEdrControllerConfiguration->SetPageScanParameters(aPageScanParameters);
+	}
 
 
 //
@@ -1383,7 +1476,6 @@
 	}
 
 
-
 //class CRegistryUpdater
 CRegistryUpdater::~CRegistryUpdater()
 	{
@@ -1449,57 +1541,81 @@
 void TBTTrackedLocalDevice::SetAddress(const TBTDevAddr& aAddr)
 	{
 	LOG_FUNC
-	TBTLocalDevice::SetAddress(aAddr);
-	StoreChange(EAddress);
+	if (aAddr != Address())
+		{
+		TBTLocalDevice::SetAddress(aAddr);
+		StoreChange(EAddress);
+		}
 	}
 	
 void TBTTrackedLocalDevice::SetDeviceClass(TUint32 aCod)
 	{
 	LOG_FUNC
-	TBTLocalDevice::SetDeviceClass(aCod);
-	StoreChange(ECoD);
+	if (aCod != DeviceClass())
+		{
+		TBTLocalDevice::SetDeviceClass(aCod);
+		StoreChange(ECoD);
+		}
 	}
 
 void TBTTrackedLocalDevice::SetDeviceName(const TDesC8& aName)
 	{
 	LOG_FUNC
-	TBTLocalDevice::SetDeviceName(aName);
-	StoreChange(EDeviceName);
+	if (aName != DeviceName())
+		{
+		TBTLocalDevice::SetDeviceName(aName);
+		StoreChange(EDeviceName);
+		}
 	}
 
 void TBTTrackedLocalDevice::SetScanEnable(THCIScanEnable aEnable)
 	{
 	LOG_FUNC
-	TBTLocalDevice::SetScanEnable(aEnable);
-	StoreChange(EScanEnable);
+	if (aEnable != ScanEnable())
+		{
+		TBTLocalDevice::SetScanEnable(aEnable);
+		StoreChange(EScanEnable);
+		}
 	}
 
 void TBTTrackedLocalDevice::SetLimitedDiscoverable(TBool aOn)
 	{
 	LOG_FUNC
-	TBTLocalDevice::SetLimitedDiscoverable(aOn);
-	StoreChange(ELimitedDiscoverable);
+	if (aOn != LimitedDiscoverable())
+		{
+		TBTLocalDevice::SetLimitedDiscoverable(aOn);
+		StoreChange(ELimitedDiscoverable);
+		}
 	}
 
 void TBTTrackedLocalDevice::SetPowerSetting(TUint8 aPowerSetting)
 	{
 	LOG_FUNC
-	TBTLocalDevice::SetPowerSetting(aPowerSetting);
-	StoreChange(EPowerSetting);
+	if (aPowerSetting != PowerSetting())
+		{
+		TBTLocalDevice::SetPowerSetting(aPowerSetting);
+		StoreChange(EPowerSetting);
+		}
 	}
 
 void TBTTrackedLocalDevice::SetAFHChannelAssessmentMode(TBool aOn)
 	{
 	LOG_FUNC
-	TBTLocalDevice::SetAFHChannelAssessmentMode(aOn);
-	StoreChange(EAFHChannelAssessmentMode);
+	if (aOn != AFHChannelAssessmentMode())
+		{
+		TBTLocalDevice::SetAFHChannelAssessmentMode(aOn);
+		StoreChange(EAFHChannelAssessmentMode);
+		}
 	}
 
 void TBTTrackedLocalDevice::SetAcceptPairedOnlyMode(TBool aOn)
 	{
 	LOG_FUNC
-	TBTLocalDevice::SetAcceptPairedOnlyMode(aOn);
-	StoreChange(EAcceptPairedOnlyMode);
+	if (aOn != AcceptPairedOnlyMode())
+		{
+		TBTLocalDevice::SetAcceptPairedOnlyMode(aOn);
+		StoreChange(EAcceptPairedOnlyMode);
+		}
 	}
 
 void TBTTrackedLocalDevice::StoreChange(TUint8 aChange)
--- a/bluetooth/btstack/linkmgr/linkmgr.h	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/linkmgr/linkmgr.h	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -52,6 +52,7 @@
 class CEirManServer;
 class CEirPublisherTxPowerLevel;
 class CEirPublisherLocalName;
+class CBrEdrControllerConfiguration;
 
 NONSHARABLE_CLASS(CRegistrySession)
 	: public CBase
@@ -165,6 +166,7 @@
 
 	// later - change local device management/notification to be nicer...
 	inline const TBTLocalDevice& LocalDevice() const;
+	inline TBTTrackedLocalDevice& DesiredLocalDeviceSettings();
 	void UpdateLocalDeviceName(const TDesC8& aName);
 	void UpdateLocalDeviceName(TBool aSucceeded);
 	void UpdateLocalDevicePower(TBTPowerState aState);
@@ -187,6 +189,7 @@
 	void SetUIConnecting(TBool aConnecting);
 	void SetUINumPhysicalLinks(TUint aNum);
 	void SetUINumSynchronousLinks(TUint aNum);
+	void SetPageScanParameters(TPageScanParameterSettings aPageScanParameters);
 
 	inline CHCIFacade& HCIFacade() const;
 	inline CBTInquiryMgr& InquiryMgr() const;
@@ -245,6 +248,7 @@
 	RBTLocalDevice			iLocalDevice; //subsession
 	TBTTrackedLocalDevice	iLocalDeviceSettings;
 	TBTLocalDevice			iPendingLocalDeviceSettings;
+	TBTTrackedLocalDevice			iDesiredLocalDeviceSettings;	
 	
 	RProperty				iProperty;
 
@@ -252,6 +256,8 @@
 	CHCIFacade*				iHCIFacade;
 	CLinkMuxer*				iLinkMuxer;
 	CEirManServer*			iEirManServer;
+
+	CBrEdrControllerConfiguration*	iBrEdrControllerConfiguration;
 	
 	CACLLinkStateFactory*	iACLStateFactory;
 	CSyncLinkStateFactory*	iSCOStateFactory;
@@ -311,6 +317,12 @@
 	return iLocalDeviceSettings;
 	}
 
+inline TBTTrackedLocalDevice& CLinkMgrProtocol::DesiredLocalDeviceSettings()
+	{
+	return iDesiredLocalDeviceSettings;
+	}
+
+
 inline CBTInquiryMgr& CLinkMgrProtocol::InquiryMgr() const
 	{
 	return *iInquiryMgr;
--- a/bluetooth/btstack/linkmgr/physicallinks.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/linkmgr/physicallinks.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -384,49 +384,12 @@
 	// Store the result of the retrieval for usage later.
 	iDeviceResult = aResult;
 
-	// the HW asked earlier for a link key - we can respond now
-	__ASSERT_DEBUG(iDevice.IsValidAddress(), Panic(EBTPhysicalLinksInvalidAddress));
-	if(iWaitingForLinkKeyFromRegistry)
+	if (iLinkKeyRequestOutstanding)
 		{
-		if (aResult == KErrNone && iDevice.IsValidLinkKey())
-			{
-			if ( iDevice.LinkKeyType() != ELinkKeyCombination)
-				{
-				if (iLinksMan.SecMan().DebugMode() && iDevice.LinkKeyType() != ELinkKeyDebug)
-					{
-					LOG(_L("CPhysicalLink: Debug mode - Link to debug link key"))
-					iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address());
-					}
-				else
-				if (iRequireAuthenticatedLinkKey && iDevice.LinkKeyType() == ELinkKeyUnauthenticatedUpgradable && IsPairable())
-					{
-					LOG(_L("CPhysicalLink: Requiring Authenticated link key but currently only have unauthenticated"))
-					iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address());
-					}
-				else
-					{
-					LOG(_L("CPhysicalLink: Issuing link key to HC now"))
-					iAuthenticationCtrl.LinkKeyRequestReply(iDevice.Address(), iDevice.LinkKey());
-					}
-				}
-			else if(IsPasskeyMinLengthOK() && SimplePairingMode() != EPhySimplePairingEnabled)
-				{
-				LOG(_L("CPhysicalLink: Issuing link key to HC now"))
-				iAuthenticationCtrl.LinkKeyRequestReply(iDevice.Address(), iDevice.LinkKey());
-				}
-			else
-				{
-				LOG(_L("CPhysicalLink: Current PIN code too short!"))
-				iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address());
-				}
-			}
-		else
-			{
-			iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address());
-			}	
+		// the HW asked earlier for a link key - we can respond now
+		__ASSERT_DEBUG(iDevice.IsValidAddress(), Panic(EBTPhysicalLinksInvalidAddress));
+		LinkKeyRequestResponseAttempt(ETrue);
 		}
-	iRequireAuthenticatedLinkKey = EFalse;
-	iWaitingForLinkKeyFromRegistry = EFalse;
 
 	RegistryTaskComplete(aHelper, aResult);	 // cleans up our helper
 	}
@@ -546,6 +509,10 @@
 		iDevice.SetPassKey(iNewPinCode);
 		}
 
+	if (iLinksMan.SecMan().IsDedicatedBondingAttempted(iDevice.Address()))
+		{
+		iLinkKeyObtainedThroughDedicatedBonding = ETrue;
+		}
 
 	SetLinkKey(aLinkKey, linkKeyType);	// keeps a copy in our 'cache', updates paired list in PHYs mananger
 
@@ -609,7 +576,10 @@
 		}
 	if(iDevice.IsValidLinkKey() && !iPreventLinkKeyUpdateReg)
 		{
-		if(!(iIOCapsReceived && (iAuthenticationRequirement == EMitmNotReqNoBonding || iAuthenticationRequirement == EMitmReqNoBonding)))
+		// We store the link key if it was obtained through dedicated bonding, even if the remote device indicated "no bonding"
+		// This fixes issues with a lot of remote stacks, and we'll let the UI delete the link key if they want to.
+		if(iLinkKeyObtainedThroughDedicatedBonding ||
+			!(iIOCapsReceived && (iAuthenticationRequirement == EMitmNotReqNoBonding || iAuthenticationRequirement == EMitmReqNoBonding)))
 			{
 			LOG(_L("!!! Storing Link Key in Registry"));
 			device.SetLinkKey(iDevice.LinkKey(), iDevice.LinkKeyType());
@@ -708,15 +678,9 @@
 			}
 		else
 			{
-			// If the remote doesn't support extended features, then neither they support SSP
-			// (no way to indicate the host supported bit).  So set it as disabled.
-			TPhysicalLinkSimplePairingMode previousSetting = SimplePairingMode();
-			__ASSERT_DEBUG(((SimplePairingMode() == EPhySimplePairingDisabled) || (SimplePairingMode() == EPhySimplePairingUndefined)),Panic(EBTSSPModeChangedDuringConnection));
-			iSimplePairingMode = EPhySimplePairingDisabled;
-			if(SimplePairingMode() != previousSetting)
-				{
-				iLinksMan.SecMan().SimplePairingSupportDetermined(BDAddr());
-				}
+			// If the remote doesn't support extended features, then they cannot support SSP
+			// (no way to indicate the host supported bit).  So set feature as disabled.
+			RemoteSimplePairingModeDetermined(EPhySimplePairingDisabled);
 			}
 		}
 	else
@@ -740,18 +704,12 @@
 
 			if (aErr == EOK && aBitMask & (1 << ESecureSimplePairingHostSupportBit) && iLinksMan.SecMan().LocalSimplePairingMode())
 				{
-				__ASSERT_DEBUG(((SimplePairingMode() == EPhySimplePairingEnabled) || (SimplePairingMode() == EPhySimplePairingUndefined)),Panic(EBTSSPModeChangedDuringConnection));
-				iSimplePairingMode = EPhySimplePairingEnabled;
+				RemoteSimplePairingModeDetermined(EPhySimplePairingEnabled);
 				}
 			else
 				{
-				__ASSERT_DEBUG(((SimplePairingMode() == EPhySimplePairingDisabled) || (SimplePairingMode() == EPhySimplePairingUndefined)),Panic(EBTSSPModeChangedDuringConnection));
-				iSimplePairingMode = EPhySimplePairingDisabled;
+				RemoteSimplePairingModeDetermined(EPhySimplePairingDisabled);
 				}
-			if(SimplePairingMode()!=currentSetting)
-				{
-				iLinksMan.SecMan().SimplePairingSupportDetermined(BDAddr());
-				}			
 			break;
 			}
 		default:
@@ -908,6 +866,7 @@
 		TRAP(err, iLinksMan.HCIFacade().AuthenticateL(Handle()));
 		if(err == KErrNone)
 			{
+			iLinkKeyReturnedInThisAuthentication = EFalse;
 			SetAuthenticationPending(EAuthenticationRequestPending);
 			}
 		}
@@ -2835,18 +2794,19 @@
 
 	SetAuthenticationPending(EPinRequestPending); // if not already set (because the remote initiated authentication).
 
-	__ASSERT_DEBUG(iSimplePairingMode != EPhySimplePairingEnabled, Panic(EBTSSPModeChangedDuringConnection));
-	if (iSimplePairingMode == EPhySimplePairingUndefined)
-		{
-		iSimplePairingMode = EPhySimplePairingDisabled;
-		}
-	
 	if (!IsConnected())
 		{
-		iPeerInSecurityMode3 = ETrue;
+		// If the ACL to the peer device is not yet connected, and the peer has initiated
+		// authentication then it must be in security mode 3.  This information is stored and
+		// if the connection completes the link will be set as authenticated.
+		SetPeerInSecurityMode3();
 		}
 
-	
+	// We can receive "fast" PIN requests if the remote device initiates pairing and indicates
+	// it doesn't have a link key.  If we see this then we know that we are not engaging in 
+	// simple pairing on this particular link.
+	RemoteSimplePairingModeDetermined(EPhySimplePairingDisabled);
+
 	if (iPinRequester)
 		{
 		return;
@@ -2989,6 +2949,12 @@
 		|| iLinksMan.SecMan().IsDedicatedBondingAttempted(iDevice.Address());
 	}
 
+TBool CPhysicalLink::IsPairingExpected() const
+	{
+	LOG_FUNC
+	return !(IsAuthenticationPending() && iLinkKeyReturnedInThisAuthentication);
+	}
+
 void CPhysicalLink::DeleteLinkKeyL()
 /**
 ensure that the LinkKey is removed from the device in the registry
@@ -3056,9 +3022,14 @@
 	return isPasskeyMinLengthOK;
 	}
 
-void CPhysicalLink::LinkKeyRequest(const TBTDevAddr& aAddr, MLinkKeyResponseHandler& /*aRequester*/)
+void CPhysicalLink::LinkKeyRequest(const TBTDevAddr& __DEBUG_ONLY(aAddr), MLinkKeyResponseHandler& /*aRequester*/)
 	{
 	LOG_FUNC
+	__ASSERT_DEBUG(aAddr == BDAddr(), Panic(EBTConnectionBadDeviceAddress));
+	ASSERT_DEBUG(!iLinkKeyRequestOutstanding);
+
+	iLinkKeyRequestOutstanding = ETrue;
+
 	// we don't keep a copy of the device record - we just leave the one copy with
 	// the baseband - it can tell us if there's a link key
 	// we can tell if the baseband has the device record or not
@@ -3070,68 +3041,13 @@
 	// if the connection completes the link will be set as authenticated.
 	if (!IsConnected())
 		{
-		iPeerInSecurityMode3 = ETrue;
-		}
-
-	if(!iPeerInSecurityMode3 && iLinksMan.SecMan().IsDedicatedBondingAttempted(iDevice.Address()))
-		{
-		// If we are doing DedicatedBonding then we should ignore the existing linkkey
-		// in an attempt to generate a stronger one if possible.
-		// Security mode 3 is a odd case - because we get what looks like double pairing (the remote
-		// initiated pairing on connection, then the dedicated bonding pairing).  So we have removed
-		// this feature for security mode 3 devices...they will have to suffer for their transgressions
-		LOG(_L("CPhysicalLink: Dedicated bonding attempt - Sending link key request negative reply"));
-		iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr);
-		iRequireAuthenticatedLinkKey = EFalse;
+		SetPeerInSecurityMode3();
 		}
-	else if (iDeviceResult==KErrNone && iDevice.IsValidLinkKey())
-		{
-		if (iLinksMan.SecMan().DebugMode() && iDevice.LinkKeyType() != ELinkKeyDebug)
-			{
-			LOG(_L("CPhysicalLink: Debug mode - Link to debug link key"))
-			iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr);
-			}
-		else
-			{
-			if (iDevice.LinkKeyType() != ELinkKeyCombination)
-				{
-				if (iRequireAuthenticatedLinkKey && iDevice.LinkKeyType() == ELinkKeyUnauthenticatedUpgradable && IsPairable())
-					{
-					LOG(_L("CPhysicalLink: Requiring Authenticated link key but currently only have unauthenticated"))
-					iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr);
-					}
-				else
-					{
-					LOG(_L("CPhysicalLink: Issuing link key to HC now"))
-					iAuthenticationCtrl.LinkKeyRequestReply(aAddr, iDevice.LinkKey());
-					}
-				}
-			else if(IsPasskeyMinLengthOK() && SimplePairingMode() != EPhySimplePairingEnabled)
-				{
-				LOG(_L("CPhysicalLink: Issuing link key to HC now"))
-				iAuthenticationCtrl.LinkKeyRequestReply(aAddr, iDevice.LinkKey());
-				}
-			else
-				{
-				LOG(_L("CPhysicalLink: Current PIN code too short!"))
-				iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr);
-				}
-			}
-		iRequireAuthenticatedLinkKey = EFalse;
+
+	if (iLinkKeyRequestOutstanding)
+		{ // might have already been called via SetPeerInSecurityMode3()
+		LinkKeyRequestResponseAttempt();
 		}
-	else if (iDeviceResult==KErrNone && !iDevice.IsValidLinkKey() || iDeviceResult==KErrNotFound)
-		{
-		LOG(_L("CPhysicalLink: No Link key available for the device"));
-		iAuthenticationCtrl.LinkKeyRequestNegativeReply(aAddr);
-		iRequireAuthenticatedLinkKey = EFalse;
-		}
-	else
-		{
-		LOG(_L("CPhysicalLink: Waiting for link key from Registry!"))
-		// we're still waiting for the device....we'll respond when it turns up
-		iWaitingForLinkKeyFromRegistry = ETrue;
-		}
-
 	}
 
 TInt CPhysicalLink::PINCodeRequestReply(const TBTDevAddr& aDevAddr, const TDesC8& aPin) const
@@ -3613,16 +3529,11 @@
 	iOOBDataPresence = aOOBDataPresence;
 	iAuthenticationRequirement = aAuthenticationRequirement;
 	
-	//If we haven't determined the SSP pairing mode till now then enable it and notify the state m/c.
-	//This condition is to cater the fast remote device which responds very quickly,  
-	//even before we determine whether it supports simple pairing!*/ 
-	__ASSERT_DEBUG(((SimplePairingMode() == EPhySimplePairingEnabled) || (SimplePairingMode() == EPhySimplePairingUndefined)),Panic(EBTSSPModeChangedDuringConnection));
-	if(SimplePairingMode() == EPhySimplePairingUndefined)
-		{
-		//Since we have received a I/O cap response the simple pairing must be enabled
-		iSimplePairingMode = EPhySimplePairingEnabled;
-		iLinksMan.SecMan().SimplePairingSupportDetermined(BDAddr());
-		}
+	// If we haven't determined the SSP pairing mode the link is operating in yet then enable it,
+	// since we have received a I/O cap response the simple pairing must be enabled.
+	// This condition is to cater the fast remote device which responds very quickly,
+	// even before we determine whether it supports simple pairing!
+	RemoteSimplePairingModeDetermined(EPhySimplePairingEnabled);
 	}
 
 
@@ -3751,12 +3662,175 @@
 	iPasskeyEntry->KeyPressed(aKey);
 	}
 
+void CPhysicalLink::NewUserConfirmerL(const TBTDevAddr aAddr,
+ 										  CBTSecMan& aSecMan,
+ 										  TBool	aInternallyInitiated)
+   	{
+	LOG_FUNC
+ 	__ASSERT_DEBUG(aAddr == BDAddr(), Panic(EBTConnectionBadDeviceAddress));
+  	iUserConfirmer = CBTUserConfirmer::NewL(aAddr, aSecMan, aInternallyInitiated);
+   	}
+
+CBTUserConfirmer* CPhysicalLink::InstanceUserConfirmer() const
+	{
+	LOG_FUNC
+	return iUserConfirmer;
+	}
+
+TBool CPhysicalLink::IsUserConfirmerActive()const
+	{
+	LOG_FUNC
+	return iUserConfirmer->IsActive();
+	}
+
+void CPhysicalLink::DeleteUserConfirmer()
+	{
+	LOG_FUNC
+	delete iUserConfirmer;
+	iUserConfirmer = NULL;
+	}
+
+void CPhysicalLink::CancelUserConfirmer()
+	{
+	LOG_FUNC
+	iUserConfirmer->Cancel();
+	}
+
 
 TBasebandTime CPhysicalLink::GetSniffInterval() const
 	{
 	return iSniffInterval;
 	}
 
+void CPhysicalLink::LinkKeyRequestResponseAttempt(TBool aForceResponse)
+	{
+	ASSERT_DEBUG(iLinkKeyRequestOutstanding);
+
+	if(!iPeerInSecurityMode3 && iLinksMan.SecMan().IsDedicatedBondingAttempted(iDevice.Address()))
+		{
+		// If we are doing DedicatedBonding then we should ignore the existing linkkey
+		// in an attempt to generate a stronger one if possible.
+		// Security mode 3 is a odd case - because we get what looks like double pairing (the remote
+		// initiated pairing on connection, then the dedicated bonding pairing).  So we have removed
+		// this feature for security mode 3 devices...they will have to suffer for their transgressions
+		LOG(_L("CPhysicalLink: Dedicated bonding attempt - Sending link key request negative reply"));
+		DoLinkKeyResponse(EFalse);
+		iRequireAuthenticatedLinkKey = EFalse;
+		}
+	else if (iDeviceResult==KErrNone && iDevice.IsValidLinkKey())
+		{
+		if (iLinksMan.SecMan().DebugMode() && iDevice.LinkKeyType() != ELinkKeyDebug)
+			{
+			LOG(_L("CPhysicalLink: Debug mode - Link to debug link key"))
+			DoLinkKeyResponse(EFalse);
+			}
+		else if (iDevice.LinkKeyType() != ELinkKeyCombination)
+			{
+			if (iRequireAuthenticatedLinkKey && iDevice.LinkKeyType() == ELinkKeyUnauthenticatedUpgradable && IsPairable())
+				{
+				LOG(_L("CPhysicalLink: Requiring Authenticated link key but currently only have unauthenticated"))
+				DoLinkKeyResponse(EFalse);
+				}
+			else
+				{
+				LOG(_L("CPhysicalLink: non - combination key, auth OK"))
+				DoLinkKeyResponse(ETrue);
+				}
+			}
+		else // Standard (legacy) Combination Key
+			{
+			if (SimplePairingMode() == EPhySimplePairingUndefined)
+				{
+				LOG(_L("CPhysicalLink: Waiting for Secure Simple Pairing mode to be determined"));
+				// wait for ssp mode to be determined...then try again
+				}
+			else if (IsPasskeyMinLengthOK() && SimplePairingMode() == EPhySimplePairingDisabled)
+				{
+				LOG(_L("CPhysicalLink: Combination key, Passkey len OK, no SSP"));
+				DoLinkKeyResponse(ETrue);
+				}
+			else
+				{
+				LOG(_L("CPhysicalLink: Current link key is not sufficient!"))
+				DoLinkKeyResponse(EFalse);
+				}
+			}
+		iRequireAuthenticatedLinkKey = EFalse;
+		}
+	else if (iDeviceResult==KErrNone && !iDevice.IsValidLinkKey() || iDeviceResult==KErrNotFound)
+		{
+		LOG(_L("CPhysicalLink: No Link key available for the device"));
+		DoLinkKeyResponse(EFalse);
+		iRequireAuthenticatedLinkKey = EFalse;
+		}
+	else if (aForceResponse)
+		{
+		LOG(_L("CPhysicalLink: Forcing a link key response (-ve as we don't have a link key yet)"));
+		DoLinkKeyResponse(EFalse);
+		}
+	else
+		{
+		LOG(_L("CPhysicalLink: Waiting for link key from Registry!"))
+		// we're still waiting for the device....we'll respond when it turns up
+		}
+	}
+
+/**
+Send a link key response for an outstanding request, assumes that all details
+have be validated.
+*/
+void CPhysicalLink::DoLinkKeyResponse(TBool aPositive)
+	{
+	LOG_FUNC
+	ASSERT_DEBUG(iLinkKeyRequestOutstanding);
+
+	if(aPositive)
+		{
+		LOG(_L("CPhysicalLink: Providing link key to HC..."))
+		ASSERT_DEBUG(iDevice.IsValidLinkKey());
+		if (IsAuthenticationPending())
+			{
+			iLinkKeyReturnedInThisAuthentication = ETrue;
+			}
+		iAuthenticationCtrl.LinkKeyRequestReply(iDevice.Address(), iDevice.LinkKey());
+		}
+	else
+		{
+		LOG(_L("CPhysicalLink: Indicating no link key to HC..."));
+		iAuthenticationCtrl.LinkKeyRequestNegativeReply(iDevice.Address());
+		}
+	iLinkKeyRequestOutstanding = EFalse;
+	}
+
+void CPhysicalLink::RemoteSimplePairingModeDetermined(TPhysicalLinkSimplePairingMode aSimplePairingMode)
+	{
+	LOG2(_L8("Current SimplePairingMode = %d, aSimplePairingMode = %d"), SimplePairingMode(), aSimplePairingMode);
+	ASSERT_DEBUG(aSimplePairingMode != EPhySimplePairingUndefined); // must be a definite value
+	__ASSERT_DEBUG(SimplePairingMode() == aSimplePairingMode || SimplePairingMode() == EPhySimplePairingUndefined, Panic(EBTSSPModeChangedDuringConnection));
+
+	const TPhysicalLinkSimplePairingMode previousSetting = iSimplePairingMode;
+	iSimplePairingMode = aSimplePairingMode;
+	if (previousSetting != iSimplePairingMode)
+		{
+		iLinksMan.SecMan().SimplePairingSupportDetermined(BDAddr());
+
+		// Also we may be waiting to respond to a link key request.
+		if (iLinkKeyRequestOutstanding)
+			{
+			LinkKeyRequestResponseAttempt();
+			}
+		}
+	}
+
+void CPhysicalLink::SetPeerInSecurityMode3()
+	{
+	iPeerInSecurityMode3 = ETrue;
+
+	// We also now know that the remote cannot possibly do SSP, *and* the LMP will
+	// likely lock our finding if the remote does SSP anyway while we do SM3.
+	RemoteSimplePairingModeDetermined(EPhySimplePairingDisabled);
+	}
+
 //
 // TLowPowModeCmdController
 //
--- a/bluetooth/btstack/linkmgr/physicallinks.h	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/linkmgr/physicallinks.h	Fri Apr 16 16:09:25 2010 +0300
@@ -444,10 +444,21 @@
 	void DeletePasskeyEntry();
 	void CancelPasskeyEntry();
 	void PasskeyEntryKeyPressed(THCIPasskeyEntryNotificationType aKey);
+
+	void NewUserConfirmerL(const TBTDevAddr aAddr,CBTSecMan& aSecMan,TBool aInternallyInitiated);
+
+	CBTUserConfirmer* InstanceUserConfirmer() const;
+	TBool IsUserConfirmerActive()const;
+	void DeleteUserConfirmer();
+	void CancelUserConfirmer();
+
+	
 	TBasebandTime GetSniffInterval() const;
 	
 	TBool IsPairable() const;
 
+	TBool IsPairingExpected() const;
+	
 private:
 	CPhysicalLink(CPhysicalLinksManager& aParent, CRegistrySession& aRegSess, const TBTNamelessDevice& aDevice);
 	void ConstructL();
@@ -486,6 +497,12 @@
 	void PINCodeRequestNegativeReply(const TBTDevAddr& aDevAddr);
 	
 	inline TBool IsAuthenticationPending() const;
+	
+	void LinkKeyRequestResponseAttempt(TBool aForceResponse = EFalse);
+	void DoLinkKeyResponse(TBool aPositive);
+
+	void RemoteSimplePairingModeDetermined(TPhysicalLinkSimplePairingMode aSimplePairingMode);
+	void SetPeerInSecurityMode3();
 
 private: // from MPINCodeResponseHandler
 	TInt PINCodeRequestReply(const TBTDevAddr& aDevAddr,const TDesC8& aPin) const;
@@ -513,15 +530,18 @@
 	CBTPinRequester*						iPinRequester;	// looks after PIN entry UI/state
 	CBTNumericComparator*					iNumericComparator; // looks after the numeric comparison UI/state
 	CBTPasskeyEntry*						iPasskeyEntry; // looks after the passkey entry UI/state
+	CBTUserConfirmer*					iUserConfirmer; // looks after the user confirmation UI/state
 	
 	CEncryptionEnforcer*					iEncryptionEnforcer;
 	
 	// the PHY's supported logical links...
 	RPointerArray<CACLLink>					iACLLogicalLinks;
 	CBTSynchronousLink*						iSyncLogicalLink; // stack only supports a signal one per PHY
-	
+
+	TBool						iLinkKeyRequestOutstanding;	// for if we have to wait for Registry or SSP support status
 
-	MPINCodeResponseHandler*	iPinHandler;
+	MPINCodeResponseHandler*	iPinHandler;		// for forwarding responses to
+
 	TBTConnect 					iLastPendingConnection;		// for if we have to wait for Registry to decide whether to rject or accept a connection
 	TBool						iPendingConnection;  // is a connection request waiting for a reply
 	TSglQue<CBTProxySAP>		iProxySAPs;			// the proxies bound to us
@@ -571,8 +591,8 @@
 	TBool						iNewPinCodeValid;
 	TBTPinCode					iNewPinCode;
 
-	TBool						iWaitingForLinkKeyFromRegistry;
-
+	TBool						iLinkKeyReturnedInThisAuthentication;
+	TBool						iLinkKeyObtainedThroughDedicatedBonding;
 private:
 	/**
 	Enumeration to represent the current state of the physical links storage in the registry,
--- a/bluetooth/btstack/secman/btaccessrequester.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/secman/btaccessrequester.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -79,7 +79,7 @@
 	, iPrefetchQueueLink(this)
 	, iAuthenticationInProgress(EFalse)
 	, iAccessType(aAccessType)
-	, iDedicatedBondingNotAvailable(EFalse)
+	, iRemoteIndicatedNoBonding(EFalse)
 	, iCurrentState(EBTUninitialised)
 	{
 	LOG_FUNC
@@ -508,7 +508,7 @@
 	THCIAuthenticationRequirement authReq = event->AuthenticationRequirements();
 	if (iAccessType == EDedicatedBonding && (authReq == EMitmReqNoBonding || authReq == EMitmNotReqNoBonding))
 		{
-		iDedicatedBondingNotAvailable = ETrue;
+		iRemoteIndicatedNoBonding = ETrue;
 		}
 	}
 
@@ -592,15 +592,6 @@
 	TBTSecEventUserConfirmationRequest* event = TBTSecEventUserConfirmationRequest::Cast(&aEvent);
 	__ASSERT_ALWAYS(event, User::Panic(KBTSecPanic, EBTSecBadStateMachineEvent));
 		
-	// Ignore the user confirmation request, we're unable to bond
-	// (dedicated bonding not available at both ends of the link)
-	// A negative reply is also sent in secman.cpp
-	if (UnableToBond())
-		{
-		CompleteRequest(KErrRemoteDeviceIndicatedNoBonding);
-		return;
-		}
-
 	// start guard timer...
 	iTimer->Start();
 	}
@@ -711,6 +702,14 @@
 		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);
 	}
 
@@ -1004,10 +1003,10 @@
 	return encryptionRequired;
 	}
 
-TBool CBTAccessRequester::UnableToBond() const
+TBool CBTAccessRequester::RemoteIndicatedNoBondingToDedicatedBonding() const
 	{
 	LOG_FUNC
-	return (iAccessType == EDedicatedBonding && iDedicatedBondingNotAvailable);
+	return (iAccessType == EDedicatedBonding && iRemoteIndicatedNoBonding);
 	}
 
 TAccessType CBTAccessRequester::AccessType() const
--- a/bluetooth/btstack/secman/secman.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/secman/secman.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -555,7 +555,8 @@
 	CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr);
 	__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing));
 	__ASSERT_DEBUG(!link->InstanceNumericComparator(), PANIC(KBTSecPanic, EBTSecConnectionNumericComparisonTwice));
-	if(link->InstanceNumericComparator())
+	__ASSERT_DEBUG(!link->InstanceUserConfirmer(), PANIC(KBTSecPanic, EBTSecConnectionUserConfirmationTwice));
+	if(link->InstanceNumericComparator() || link->InstanceUserConfirmer())
 		{
 		return;
 		}
@@ -581,6 +582,25 @@
 				}
 			}
 		}
+	else if (!link->IsPairingExpected()
+			|| ((link->AuthenticationRequirement() == EMitmNotReqDedicatedBonding 
+					|| link->AuthenticationRequirement() == EMitmReqDedicatedBonding)
+				&& !IsDedicatedBondingAttempted(aAddr)))
+		{
+		TRAPD(err,link->NewUserConfirmerL(aAddr, *this, ETrue));
+		if(err)
+			{
+			if(requester)
+				{
+				requester->CompleteRequest(EBTSecManAccessDenied);
+				}
+			else
+				{
+				TRAP_IGNORE(iCommandController->UserConfirmationRequestNegativeReplyL(aAddr));
+				return;// No passkey or comparison dialogs; disconnect instead
+				}
+			}
+		}
 	else
 		{
 		// Just Work...
@@ -596,7 +616,7 @@
 		}
 	}
 
-void CBTSecMan::UserConfirmationComplete(const TBTDevAddr& aAddr, TBool aResult, TInt aError)
+void CBTSecMan::NumericComparisonComplete(const TBTDevAddr& aAddr, TBool aResult, TInt aError)
 	{
 	LOG_FUNC
 	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
@@ -642,6 +662,63 @@
 	link->DeleteNumericComparator();
 	}
 
+void CBTSecMan::UserConfirmationComplete(const TBTDevAddr& aAddr, TBool aResult, TInt aError)
+	{
+	LOG_FUNC
+	CBTAccessRequester* requester = FindActiveAccessRequester(aAddr);
+	if (requester)
+		{
+		LOG(_L8("\tCBTAccessRequester FOUND!\n"));
+		if (aError == KErrNone)
+			{
+			TBTSecEventUserConfirmationComplete event(aResult);
+			requester->SendEvent(event);
+			}
+		else if (aError == KErrNotFound) // KErrNotFound -> Notifier isn't present, so allow anyway
+			{
+			TBTSecEventUserConfirmationComplete event(ETrue);
+			requester->SendEvent(event);
+			}
+		else
+			{
+			TBTSecEventUserConfirmationComplete event(EFalse);  // Failed, so send EFalse
+			requester->SendEvent(event);
+			}
+		}
+
+	CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr);
+	__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing));
+
+	if (aError==KErrNotFound) // KErrNotFound -> Notifier isn't present, so allow anyway
+		{
+		link->PinRequestSent();
+		// note: -- check errors here
+		TRAP_IGNORE(iCommandController->UserConfirmationRequestReplyL(aAddr));
+		}
+	else if (aError!=KErrNone)
+		{
+		// there was an error somewhere a long the way so respond negatively
+		// note: -- check errors here
+		TRAP_IGNORE(iCommandController->UserConfirmationRequestNegativeReplyL(aAddr));
+		}
+	else
+		{
+		// got a result
+		if(aResult)
+			{
+			link->PinRequestSent();
+			// note: -- check errors here
+			TRAP_IGNORE(iCommandController->UserConfirmationRequestReplyL(aAddr));
+			}
+		else
+			{
+			// note: -- check errors here
+			TRAP_IGNORE(iCommandController->UserConfirmationRequestNegativeReplyL(aAddr));
+			}
+		}
+	link->DeleteUserConfirmer();
+	}
+
 void CBTSecMan::PasskeyNotification(const TBTDevAddr& aAddr, TUint32 aPasskey)
 	{
 	LOG_FUNC
@@ -806,9 +883,13 @@
 	if (link->InstanceNumericComparator() && link->IsNumericComparatorActive())
 		{
 		link->CancelNumericComparator();
+		NumericComparisonComplete(aAddr, EFalse, err);
+		}
+	if (link->InstanceUserConfirmer() && link->IsUserConfirmerActive())
+		{
+		link->CancelUserConfirmer();
 		UserConfirmationComplete(aAddr, EFalse, err);
 		}
-
 	iPhysicalLinksManager->SimplePairingComplete(aAddr, aError);
 
  	// Add result to list (always with HCI error code).
@@ -1753,7 +1834,7 @@
 
 	__ASSERT_DEBUG(iNumericComparisonParamsPckg().DeviceAddress() == iDevAddr, PANIC(KBTSecPanic, EBTSecBadDeviceAddress));
 
-	iSecMan.UserConfirmationComplete(iDevAddr, iResultPckg(), iStatus.Int());
+	iSecMan.NumericComparisonComplete(iDevAddr, iResultPckg(), iStatus.Int());
 	}
 
 TInt CBTNumericComparator::RunError(TInt aError)
@@ -1917,3 +1998,133 @@
 	return aError;
 	}
 
+//------------------------------------------------------------------------//
+//class CBTNumericComparator
+//------------------------------------------------------------------------//
+CBTUserConfirmer* CBTUserConfirmer::NewL(const TBTDevAddr aAddr,
+												 CBTSecMan& aSecMan,
+												 TBool aInternallyInitiated)
+	{
+	LOG_STATIC_FUNC
+	CBTUserConfirmer* s = CBTUserConfirmer::NewLC(aAddr, aSecMan, aInternallyInitiated);
+	CleanupStack::Pop(s);
+	return s;
+	}
+
+CBTUserConfirmer* CBTUserConfirmer::NewLC(const TBTDevAddr aAddr,
+												  CBTSecMan& aSecMan,
+												  TBool aInternallyInitiated)
+	{
+	LOG_STATIC_FUNC
+	CBTUserConfirmer* s = new(ELeave) CBTUserConfirmer(aSecMan, aInternallyInitiated);
+	CleanupStack::PushL(s);
+	s->ConstructL(aAddr);
+	return s;
+	}
+
+CBTUserConfirmer::CBTUserConfirmer(CBTSecMan& aSecMan, TBool aInternallyInitiated)
+	: CSecNotifierRequester(aSecMan)
+	, iSecMan(aSecMan)
+	, iInternallyInitiated(aInternallyInitiated)
+	{
+	LOG_FUNC
+	CActiveScheduler::Add(this);
+	}
+
+CBTUserConfirmer::~CBTUserConfirmer()
+	{
+	LOG_FUNC
+	Cancel();
+	delete iNameUpdater;
+	}
+
+
+void CBTUserConfirmer::DoUpdateNotifier()
+	{
+	LOG_FUNC
+	if(IsActive())
+		{
+		if(!iNameUpdater)
+			{
+			//Create a new CSecNotifierUpdateAO object
+			TRAP_IGNORE(iNameUpdater = CSecNotifierUpdateAO<TBTDeviceNameUpdateParamsPckg>::NewL(iNotifier, KBTUserConfirmationNotifierUid));
+			}
+		if(iNameUpdater)
+			{
+			TBTDeviceName deviceName(KNullDesC);
+			TInt err = KErrNotFound;
+			if(iDeviceName)
+				{
+				TRAP(err, deviceName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName)); // Best effort attempt.
+				}
+
+			TBTDeviceNameUpdateParamsPckg pckg = TBTDeviceNameUpdateParams(deviceName, err);
+			iNameUpdater->DoUpdate(pckg);
+			}
+		}
+	}
+
+void CBTUserConfirmer::DoRequest()
+/**
+Start the RNotifier plugin that deals with authorisation.
+**/
+	{
+	LOG_FUNC
+	TInt err(KErrNone);
+
+	TBTDeviceName deviceName;
+
+	if (iDeviceName)
+		{
+		TRAP(err, deviceName = BTDeviceNameConverter::ToUnicodeL(*iDeviceName));
+		if (err!=KErrNone)
+			{
+			deviceName = KNullDesC;
+			}
+		}
+	else
+		{
+		deviceName = KNullDesC;
+		}
+	iUserConfirmationParamsPckg = TBTUserConfirmationParams(iDevAddr, deviceName, iInternallyInitiated);
+
+	iNotifier.StartNotifierAndGetResponse(iStatus, KBTUserConfirmationNotifierUid, iUserConfirmationParamsPckg, iResultPckg);
+	SetActive();
+	}
+
+
+void CBTUserConfirmer::DoCancel()
+	{
+	LOG_FUNC
+	iNotifier.CancelNotifier(KBTUserConfirmationNotifierUid);
+	if(iNameUpdater)
+		{
+		iNameUpdater->Cancel();
+		}
+	}
+
+void CBTUserConfirmer::RunL()
+	{
+	LOG_FUNC
+	// got an answer so unload the notifier
+	iNotifier.CancelNotifier(KBTUserConfirmationNotifierUid);
+
+	//remove ourself from the notifier que, allowing the next notifier to be activated
+	RemoveMyselfFromQue();
+	iIsAddedToNotifierQue = EFalse;
+
+	__ASSERT_DEBUG(iUserConfirmationParamsPckg().DeviceAddress() == iDevAddr, PANIC(KBTSecPanic, EBTSecBadDeviceAddress));
+
+	iSecMan.UserConfirmationComplete(iDevAddr, iResultPckg(), iStatus.Int());
+	}
+
+TInt CBTUserConfirmer::RunError(TInt aError)
+	{
+	LOG_FUNC
+	//will never get called as our RunL doesn't leave.
+	LOG1(_L8("\tCBTUserConfirmation::RunError(%d)\n"), aError);
+	return aError;
+	}
+
+
+
--- a/bluetooth/btstack/secman/secman.h	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetooth/btstack/secman/secman.h	Fri Apr 16 16:09:25 2010 +0300
@@ -266,6 +266,7 @@
 	void RemoteOOBDataRequest(const TBTDevAddr& aAddr);
 	void RemoteOOBDataRequestComplete(const TBTDevAddr& aAddr);
 	void UserConfirmationRequest(const TBTDevAddr& aAddr, TUint32 aNumericValue);
+	void NumericComparisonComplete(const TBTDevAddr& aAddr, TBool aResult, TInt aError);
 	void UserConfirmationComplete(const TBTDevAddr& aAddr, TBool aResult, TInt aError);
 	void PasskeyNotification(const TBTDevAddr& aAddr, TUint32 aPasskey);
 	void PasskeyNotificationComplete(const TBTDevAddr& aAddr, TInt aError);
@@ -360,7 +361,7 @@
 	TBool AuthenticationRequired() const;
 	TBool EncryptionRequired() const;
 	TBool AuthenticationInProgress() const;
-	TBool UnableToBond() const;
+	TBool RemoteIndicatedNoBondingToDedicatedBonding() const;
 	TBool BasebandConnected() const;
 	
 	void CompleteRequest(TInt aReason);
@@ -445,7 +446,7 @@
 	
 	TAccessType						iAccessType;
 	
-	TBool							iDedicatedBondingNotAvailable;  //< Remote IOCapabilitiesResponse says no dedicated bonding
+	TBool							iRemoteIndicatedNoBonding;  //< Remote IOCapabilitiesResponse says no dedicated bonding
 	THCIIoCapability				iRemoteIOCapability;
 	THCIOobDataPresence				iRemoteOOBDataPresence;
 	
@@ -668,6 +669,44 @@
 	TBuf8<1>							iResultPckg;
 	};
 
+/**
+Prompts the user to confirm whether or not they want to pair
+Uses the RNotifier framework to produce a dialog containing information
+about the remote device
+**/
+NONSHARABLE_CLASS(CBTUserConfirmer) 
+	: public CSecNotifierRequester
+	{
+public:
+	static CBTUserConfirmer* NewL(const TBTDevAddr aAddr,
+									  CBTSecMan& aSecMan, 
+									  TBool aInternallyInitiated);
+	static CBTUserConfirmer* NewLC(const TBTDevAddr aAddr,
+									   CBTSecMan& aSecMan, 
+									   TBool aInternallyInitiated);
+	~CBTUserConfirmer();
+
+private: // from CActive
+	void DoCancel();
+	void RunL();
+	TInt RunError(TInt aError);
+	
+private: //from CSecNotifierRequester
+	virtual void DoRequest();
+	virtual void DoUpdateNotifier();
+
+private:
+	CBTUserConfirmer(CBTSecMan& aSecMan, 
+						 TBool aInternallyInitiated);
+	
+private:
+	CSecNotifierUpdateAO<TBTDeviceNameUpdateParamsPckg>*	iNameUpdater;
+	CBTSecMan&												iSecMan;
+	TBool 													iInternallyInitiated;
+	TBTUserConfirmationParamsPckg							iUserConfirmationParamsPckg;
+	TPckgBuf<TBool>											iResultPckg;
+	};
+
 
 _LIT(KBTSecPanic, "BT Security");
 enum TBTSecPanic
@@ -708,6 +747,7 @@
 	EBTSecAccessRequesterShouldHaveNotBeenFound,
 	EBTSecAccessRequesterShouldHaveBeenFound,
 	EBTSecNotifierRequesterUsingTimerWithoutHandling,
+	EBTSecConnectionUserConfirmationTwice,
 	};
 
 
--- a/bluetoothapitest/bluetoothsvs/group/bluetoothsvs.mrp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothapitest/bluetoothsvs/group/bluetoothsvs.mrp	Fri Apr 16 16:09:25 2010 +0300
@@ -1,3 +1,19 @@
+#
+# 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: 
+#
+
 component	bluetoothsvs
 source			\sf\os\bt\bluetoothapitest\bluetoothsvs
 notes_source	\sf\os\bt\bluetoothapitest\bluetoothsvs\group\release.txt
--- a/bluetoothmgmt/bluetoothclientlib/btlib/btsocket.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothmgmt/bluetoothclientlib/btlib/btsocket.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -2792,11 +2792,8 @@
 void CAutoSniffDelayTimer::StartActive()
 	{
 	Start();
-	if(iSniffModeRequested)
-		{
-		// When enabling auto sniffing, we make use of Explicit active mode.
-		(void)MbbhBTBaseband().RequestExplicitActiveMode(ETrue);
-		}
+	// When enabling auto sniffing, we make use of Explicit active mode.
+	(void)MbbhBTBaseband().RequestExplicitActiveMode(ETrue);
 	}
 
 RBTBaseband& CAutoSniffDelayTimer::MbbhBTBaseband() 
@@ -2814,7 +2811,7 @@
 		if(iSniffModeRequested)
 			{
 			MbbhBTBaseband().CancelLowPowerModeRequester();
-			StartActive();
+			iSniffModeRequested = EFalse;
 			}
 		}
 	__ASSERT_ALWAYS(iBTAutoSniffBasebandChangeEventNotifier != NULL, Panic(EBBInvalidAddress));
--- a/bluetoothmgmt/bluetoothclientlib/inc/bt_subscribe_partner.h	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothmgmt/bluetoothclientlib/inc/bt_subscribe_partner.h	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-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"
@@ -67,4 +67,32 @@
 */
 const TUint KPropertyKeyBluetoothSetSimplePairingDebugMode = (KUidBluetoothPubSubKeyBase + 21);
 
+/** +-   
+KPropertyKeyBluetoothSetPageScanParameters     
+The key to control the parameters of the page scan Bluetooth hardware is currently performing.     
+The P&S value will contain an integer from TPageScanParameterSettings enumeration.     
+The values are mapped to actual parameters in the Bluetooth stack.     
+@see TPageScanParameterSettings     
+@publishedPartner     
+@released     
+@capability LocalServices   Needed for both read and write access to this property     
+@capability NetworkControl  Needed for both read and write access to this property     
+*/     
+const TUint KPropertyKeyBluetoothSetPageScanParameters = (KUidBluetoothPubSubKeyBase + 23);     
+      
+/**     
+KPropertyKeyBluetoothGetPageScanParameters     
+The key is intended to be used by the Bluetooth stack to provide an indication to the client     
+which has requested a page scan parameters change that the parameters have been enabled.     
+The value returned is of the TPageScanParameterSettings type.     
+The enumeration may gain additional members in future.     
+@see TPageScanParameterSettings     
+@publishedPartner     
+@released     
+@capability LocalServices   Needed for both read and write access to this property     
+@capability NetworkControl  Needed for both read and write access to this property     
+*/     
+const TUint KPropertyKeyBluetoothGetPageScanParameters = (KUidBluetoothPubSubKeyBase + 24);     
+  
+
 #endif //BT_SUBSCRIBE_PARTNER_H
\ No newline at end of file
--- a/bluetoothmgmt/bluetoothclientlib/inc/bttypespartner.h	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothmgmt/bluetoothclientlib/inc/bttypespartner.h	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -47,4 +47,15 @@
 */
 typedef TBuf8<KBluetoothSimplePairingRandomizerSize> TBluetoothSimplePairingRandomizer;
 
+/** For page scan parameters setting. +-   
+The enumeration may gain additional members in future.     
+@publishedPartner     
+@released     
+*/     
+enum TPageScanParameterSettings     
+    {     
+    EStandardPageScanParameters,     
+    EFastConnectionPageScanParameters     
+    }; 
+
 #endif	//_BTTYPESPARTNER_H
--- a/bluetoothmgmt/btmgr/BTDevice/BTDevice.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothmgmt/btmgr/BTDevice/BTDevice.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -88,7 +88,7 @@
 Initialises the device class to 0.
 **/
 EXPORT_C TBTDeviceClass::TBTDeviceClass() :
-	iDeviceClass(0)
+	iDeviceClass(0), iPadding1(0), iPadding2(0)
 	{
 	}
 
@@ -97,7 +97,7 @@
 @param	aDeviceClass The initial device class
 **/
 EXPORT_C TBTDeviceClass::TBTDeviceClass(TUint32 aDeviceClass) :
-	iDeviceClass(aDeviceClass)
+	iDeviceClass(aDeviceClass), iPadding1(0), iPadding2(0)
 	{
 	}
 
@@ -115,7 +115,7 @@
 */
 EXPORT_C TBTDeviceClass::TBTDeviceClass(TUint16 aMajorServiceClass, TUint8 aMajorDeviceClass,
 										TUint8 aMinorDeviceClass) :
-	iDeviceClass(0)
+	iDeviceClass(0), iPadding1(0), iPadding2(0)
 	{
 	iDeviceClass = (aMajorServiceClass & EMajorServiceMask);	// [00000000]0000000000000xxxxxxxxxxx
 	iDeviceClass <<= EMajorDeviceLength;	// [00000000]00000000xxxxxxxxxxx00000
--- a/bluetoothmgmt/btmgr/BTManServer/BTManServer.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothmgmt/btmgr/BTManServer/BTManServer.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -109,6 +109,9 @@
 
 	iContainerIndex = CObjectConIx::NewL();
 	// don't stop the server if we can't provide this service...				   
+	
+	//Start Backup/Restore Manager and obtain notification of backup/restore operations.
+	iBURManager=CBTManServerBURMgr::NewL(*this, this);
 	}
 
 
@@ -140,6 +143,7 @@
 	// Close the RProperty handle in case it is ever attached.
 	iProperty.Close();
 
+	delete iBURManager;
 	delete iRegistry;
 	delete iContainerIndex;
 	}
@@ -156,6 +160,32 @@
 	return new(ELeave) CBTManSession(*iRegistry, aMessage);
 	}
 
+void CBTManServer::BUROperationStarted()
+/**
+A backup or restore operation has started.
+Cancel the shutdown timer if it was running
+**/
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(!iBUROperationStarted, PanicServer(EBTManBadState));
+
+	iBUROperationStarted = ETrue;
+	iShutdown.Cancel();
+	}
+
+void CBTManServer::BUROperationStopped()
+/**
+A backup or restore operation has finished.
+Start the shutdown timer if there are no sessions running.
+**/
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iBUROperationStarted, PanicServer(EBTManBadState));
+
+	iBUROperationStarted = EFalse;
+	TryToStartShutdownTimer();
+	}
+
 void CBTManServer::AddSession()
 /**
 A new session is being created
@@ -180,7 +210,18 @@
 	LOG_FUNC
 	__ASSERT_DEBUG(iSessionCount > 0, PanicServer(EBTManBadState));
 	
-	if (--iSessionCount==0)
+	--iSessionCount;
+	TryToStartShutdownTimer();
+	}
+
+void CBTManServer::TryToStartShutdownTimer()
+/**
+Starts the shutdown timer if the server is able to shutdown
+**/
+	{
+	LOG_FUNC
+	
+	if (iSessionCount == 0 && !iBUROperationStarted)
 		{
 		iShutdown.Start();
 		}
@@ -204,13 +245,28 @@
 	// Go through all sessions - they'll dispatch so all the subessions apart from the one calling here
 	iSessionIter.SetToFirst();
 
-	while (iSessionIter != NULL)
+	while (iSessionIter)
 		{
 		CBTManSession* s = static_cast<CBTManSession*>(iSessionIter++);
 		s->SubSessionHasOverlappingView(aSubSessionViewOwner, aViewDescriptor);
 		}
 	}
 
+void CBTManServer::NotifyViewChange(const TDesC& aViewDescriptor)
+	{
+	LOG_FUNC
+	// For views not owned by subsessions (e.g. views owned by Backup/Restore classes)
+
+	// Go through all sessions - they'll dispatch so all the subessions apart from the one calling here
+	iSessionIter.SetToFirst();
+
+	while (iSessionIter)
+		{
+		CBTManSession* s = static_cast<CBTManSession*>(iSessionIter++);
+		s->SubSessionHasOverlappingView(aViewDescriptor);
+		}
+	}
+	
 void PanicClient(const RMessage2& aMessage,TInt aPanic, CBTManSession* aSession)
 /**
 RMessage2::Panic() also completes the message. This is:
@@ -1097,6 +1153,25 @@
 	return overlapFound;
 	}
 
+TBool CBTManSession::SubSessionHasOverlappingView(const TDesC& aViewDescriptor)
+	{
+	LOG_FUNC
+	// Iterate over all subsessions (view owner is not a subsession)
+	TBool overlapFound = EFalse;
+	for (TInt i = 0; i < iContainer->Count(); i++)
+		{
+		CBTManSubSession* ss = static_cast<CBTManSubSession*>((*iContainer)[i]);
+		if (ss->IsOverlappingView(aViewDescriptor))
+			{
+			// Overlaps - subsession will have completed the Notify message
+			// With bool return, we can test if indeed it did.
+			overlapFound = ETrue;
+			}
+		}
+
+	return overlapFound;
+	}
+
 
 //=====================================================================
 //	CBTManSubSession
--- a/bluetoothmgmt/btmgr/BTManServer/BTManServer.mmp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothmgmt/btmgr/BTManServer/BTManServer.mmp	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-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"
@@ -34,6 +34,8 @@
 SOURCE  LocalDeviceSubSession.cpp
 SOURCE  CSYSubSession.cpp
 SOURCE	BTRegistrySQL.cpp
+SOURCE	btmanserverburmgr.cpp
+SOURCE  btmanserverburstatemachine.cpp
 
 USERINCLUDE . ../Inc ../../btcommon/inc
 USERINCLUDE ../../bluetoothclientlib/inc
@@ -44,6 +46,8 @@
 
 LIBRARY esock.lib
 
+LIBRARY abclient.lib
+
 #include <bluetooth/btlogger.mmh>
 
 //MACRO ALLOW_UNREGISTERED_SERVICES
--- a/bluetoothmgmt/btmgr/BTManServer/BTRegistryDB.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothmgmt/btmgr/BTManServer/BTRegistryDB.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -1173,6 +1173,16 @@
 	return device;
 	}
 
+TBTLocalDevice* CBTRegistry::GetLocalDeviceL()
+	{
+	LOG_FUNC
+	TBTLocalDevice* device = GetLocalDeviceLC();
+	CleanupStack::Pop(device);
+	return device;
+	}
+
+
+
 const TBTCommPortSettings* CBTRegistry::GetCommPortSettingsLC(const TBTCommPortSettings& aSettings)
 /**
 	Get the virtual serial port settings for the port referred to in aSettings
@@ -1354,7 +1364,12 @@
 	defaultDevice.SetDeviceName(KDefaultLocalName);
 	defaultDevice.SetScanEnable(EPageScanOnly);
 	defaultDevice.SetLimitedDiscoverable(EFalse);
-	defaultDevice.SetDeviceClass(0);
+	
+	// set the default device class to be phone|smartphone
+	// MajorServiceClass set to zero as there are no default service class bits
+	TBTDeviceClass defaultCod (0, EMajorDevicePhone, EMinorDevicePhoneSmartPhone);
+	defaultDevice.SetDeviceClass(defaultCod.DeviceClass());
+	
 	// The registry is being kicked off with a default channel assessment 
 	// mode setting of 'enabled'. This is the default if h/w supports 
 	// channel assessment. If h/w does not support channel assessment,
--- a/bluetoothmgmt/btmgr/BTManServer/BTRegistryDB.h	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothmgmt/btmgr/BTManServer/BTRegistryDB.h	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -106,6 +106,8 @@
 // 1.1 - Adjusted the Time/Date fields for 64 bit integers (remote device table).
 // 1.2 - Added additional fields Link-key type and UI cookie (remote device table).
 
+// Note: Any changes to the registry version will also require changes to the CBTRegistryBURData class.
+
 // Useful SQL literals
 _LIT(KSQLIsNotNull, " IS NOT NULL");
 _LIT(KSQLCommaSpace, ", ");
@@ -173,6 +175,7 @@
 	void UpdateNameL(const TBTDevAddr& aAddress, const TDesC8& aName, TBTManServerRequest aRequest);
 // for local device table
 	TBTLocalDevice* GetLocalDeviceLC();
+	TBTLocalDevice* GetLocalDeviceL();
 	void UpdateLocalDeviceL(const TBTLocalDevice& aDevice);
 // CSY table
 	const TBTCommPortSettings* GetCommPortSettingsLC(const TBTCommPortSettings& aPort);
@@ -184,6 +187,8 @@
 	RDbView* OpenCommPortLC(const TBTCommPortSettings& aSettings);
 	RDbView* OpenCommPortL(const TBTCommPortSettings& aSettings);
 
+	void GetDefaultDeviceFromIniL(TBTLocalDevice& aDevice);
+
 private:
 	RDbTable* OpenTableL(const TDesC& aTable);	// opens and transfers ownership
 	RDbTable* OpenPersistTableL();	// opens and transfers ownership
@@ -209,7 +214,6 @@
 	CBTRegistry();
 	void DeleteCorruptRegistryL();
 	void SetupDefaultRegistryL();
-	void GetDefaultDeviceFromIniL(TBTLocalDevice& aDevice);
 	TBool FindVar(const TDesC8& aPtr, const TDesC8& aVarName, TPtrC8& aResult) const;
 	TBool FindVar(const TDesC8& aPtr, const TDesC8& aVarName, TInt& aResult) const;
 	TInt SetDeviceName(const TDesC& aDeviceName, TBTLocalDevice& aDevice);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothmgmt/btmgr/BTManServer/backup_registration.xml	Fri Apr 16 16:09:25 2010 +0300
@@ -0,0 +1,28 @@
+<?xml version="1.0" standalone="yes" ?>
+<!--
+ Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+
+ Contributors:
+
+ Description:
+ Registers the Bluetooth Manager server for hybrid (active and passive) 
+ backup and restore.
+
+-->
+
+<backup_registration>
+	<active_backup process_name="btmanserver.exe" />
+	<passive_backup>
+		<include_file name = "btregistrydb.bak" />
+	</passive_backup>
+
+	<restore requires_reboot = "yes" />
+</backup_registration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothmgmt/btmgr/BTManServer/btmanserverburmgr.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -0,0 +1,2020 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Implements backup and restore support for the Bluetooth Manager server.
+//
+
+#include <e32std.h>
+#include <e32base.h>
+#include <e32property.h>
+#include <f32file.h>
+#include <s32file.h>
+#include "btmanserverutil.h"
+#include "btmanserverburmgr.h"
+#include "BTManServer.h"
+
+#include "btmanclient.h"
+#include "btdevice.h"
+#include <bluetooth/hci/hcitypes.h>
+#include <bluetooth/logger.h>
+#include "BTSec.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_BT_MANAGER_SERVER);
+#endif
+
+
+/**
+Raises an EBTBURMgrInvalidState panic with state information encoded within the panic code.
+The first digit denotes the panic code (EBTBURMgrInvalidState).
+The second digit is a delimiter and is always 1.
+The next two digits represent the expected state
+The next digit again is a delimiter and is always 1.
+The final two digits represent the actual state. 
+
+For example, the panic code 7101100 indicates an EBTBURMgrInvalidState panic raised because the state
+machine is in the EBTBURStateNormal state when it was expected to be in the EBTBURStateBackupRequest state.
+**/
+void InvalidStatePanic(TBTBURState aExpectedState, TBTBURState aActualState)
+	{
+	LOG_STATIC_FUNC
+	User::Panic(KBTBackupPanicCat, (EBTBURMgrInvalidState*KBTBackupStatePanicMultiplier) + KBTBackupStatePanicMajorDelimiter + (aExpectedState * KBTBackupStateMultiplier) + KBTBackupStatePanicMinorDelimiter + aActualState);
+	}
+
+/**
+Raises an EBTBURMgrInvalidStateTransition panic with state information encoded within the panic code.
+The first digit denotes the panic code (EBTBURMgrInvalidStateTransition).
+The second digit is a delimiter and is always 1.
+The next two digits represent the expected state
+The next digit again is a delimiter and is always 1.
+The final two digits represent the actual state. 
+
+For example, the panic code 6101100 indicates an EBTBURMgrInvalidStateTransition panic raised because the state
+machine is in the EBTBURStateNormal state when it was expected to be in the EBTBURStateBackupRequest state.
+**/
+void InvalidStateTransitionPanic(TBTBURState aCurrentState, TBTBUREvent aEvent)
+	{
+	LOG_STATIC_FUNC
+	User::Panic(KBTBackupPanicCat, (EBTBURMgrInvalidStateTransition*KBTBackupStatePanicMultiplier) + KBTBackupStatePanicMajorDelimiter + (aCurrentState * KBTBackupStateMultiplier) + KBTBackupStatePanicMinorDelimiter + aEvent);
+	}
+
+
+/**
+CBTManServerBURMgr - Manages backup and restore support for the Bluetooth Manager server.
+**/
+
+/**
+Constructs a new instance of a CBTManServerBURMgr.
+An MBTBURNotify instance may be registered here for notifications. Ownership of the MBTBURNotify instance is not transferred.
+@see CBTManServerBURMgr::RequestBURNotification()
+**/
+CBTManServerBURMgr* CBTManServerBURMgr::NewL(CBTManServer& aBTManServer, MBTBURNotify* aBURNotify, TInt aPriority)
+	{
+	LOG_STATIC_FUNC
+	CBTManServerBURMgr* self = new(ELeave) CBTManServerBURMgr(aBTManServer, aBURNotify, aPriority);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CBTManServerBURMgr::CBTManServerBURMgr(CBTManServer& aBTManServer, MBTBURNotify* aBURNotify, TInt aPriority) 
+	: CActive(aPriority), 
+	iBTManServer(aBTManServer),  
+	iBUROperationStartNotified(EFalse)
+	{
+	LOG_FUNC
+
+	RequestBURNotification(aBURNotify);
+	CActiveScheduler::Add(this);
+	}
+
+CBTManServerBURMgr::~CBTManServerBURMgr()
+	{
+	LOG_FUNC
+
+	Cancel();
+	iProperty.Close();
+
+	// Close any open session on BT Manager
+	NotifyAnyBUROperationStopped();
+		
+	// Members which either hold data or are NULL
+	delete iActiveBackupClient;
+	delete iActiveBackupDataClient;
+	delete iBackupHandler;
+	delete iRestoreHandler;
+	delete iLocalAddrFetcher;
+
+	// Member that is instantiated for entire lifetime of CBTManServerBURMgr
+	delete iStateMachine;
+	}
+
+void CBTManServerBURMgr::ConstructL()
+	{
+	LOG_FUNC
+
+	// Construct state machine
+	iStateMachine = CBTManServerBURMgrStateFactory::NewL(*this);
+	// Construction counts as a transition into the default state (EBTBURStateNormal) of the state machine.
+	// However, since this does nothing if no backup/restore cleanup is required, we do not need to execute the 
+	// state action.
+	
+	// Setup iProperty to catch BUR flag from Secure Backup Engine
+	LEAVEIFERRORL(iProperty.Attach(KUidSystemCategory, KUidBackupRestoreKey));
+
+	// Subscribe to BUR P&S key to catch transitions
+	SubscribeToBackupRestoreKey();
+
+	// Also check flag now (it may have already transitioned)
+	TInt backupKeyValue = 0;
+	LEAVEIFERRORL(iProperty.Get(backupKeyValue));
+	TBURPartType backupState = GetBURPartType(backupKeyValue);	
+
+	// If we're not about to perform a restore, check if a restore file exists. If so, try to process restore file.
+	// The restore operation may not affect us, or may be postponed. In either case, we try to process the restore file
+	// again next time we start.
+	if (backupState != EBURRestoreFull && backupState != EBURRestorePartial)
+		{
+		// Delete any stale backup files
+		DeleteBackupFile();
+		// See if a restore file needs processing
+		CheckForRestoreFileL();
+		}
+
+	// Process flag
+	ProcessBackupState(backupState);
+	}
+
+/**
+Translates a given integer obtained from the KUidBackupRestoreKey P&S key to a TBURPartType value.
+This will validate the masked value to ensure that it falls within the range of the TBURPartType enum.
+In debug builds, a panic will be raised if this value is out of range.
+In release builds, EBURUnset is returned if the value is out of range.
+**/
+TBURPartType CBTManServerBURMgr::GetBURPartType(TInt aValue)
+	{
+	LOG_FUNC
+
+	switch (aValue & KBURPartTypeMask)
+		{
+	case EBURUnset:
+		return EBURUnset;
+	case EBURNormal:
+		return EBURNormal;
+	case EBURBackupFull:
+		return EBURBackupFull;
+	case EBURBackupPartial:
+		return EBURBackupPartial;
+	case EBURRestoreFull:
+		return EBURRestoreFull;
+	case EBURRestorePartial:
+		return EBURRestorePartial;
+	default:
+		__ASSERT_DEBUG(EFalse, PANIC(KBTBackupPanicCat, EBTBURMgrInvalidBackupRestoreState));
+		return EBURUnset;
+		}
+	}
+
+/**
+Attempts to locate a restore file in the private directory of this server.
+@return ETrue if the file can be found, EFalse otherwise.
+**/
+TBool CBTManServerBURMgr::RestoreFilePresent()
+	{
+	LOG_FUNC
+
+	RFs fsSession;
+	TInt err = fsSession.Connect();
+	if (err == KErrNone)
+		{
+		err = fsSession.SetSessionToPrivate(fsSession.GetSystemDrive());
+		if (err ==KErrNone)
+			{
+			TEntry entry;
+			err = fsSession.Entry(KBTManServerRestoreFileName, entry);
+			}
+
+		fsSession.Close();
+		}
+
+	// If restore file was found, err will be KErrNone
+	return (err == KErrNone);
+	}
+
+/**
+Checks for the existence of a restore file. If a restore file is found, then the local device address
+is feteched and processing of that restore file is initiated.
+**/
+void CBTManServerBURMgr::CheckForRestoreFileL()
+	{
+	LOG_FUNC
+
+	if (RestoreFilePresent())
+		{
+		// Fetch local address. When this is received, restore file processing will begin.
+		iLocalAddrFetcher = CBTLocalAddressFetcher::NewL(*this, iBTManServer.Registry());
+		iLocalAddrFetcher->FetchLocalAddress();
+		}
+	}
+
+/**
+Subscribes to the P&S flag provided by the Secure Backup Engine (to receive notification of backup/restore state changes).
+**/
+void CBTManServerBURMgr::SubscribeToBackupRestoreKey()
+	{
+	LOG_FUNC
+
+	iProperty.Subscribe(iStatus);
+	SetActive();	
+	}
+
+/**
+Processes a change in the backup/restore state of the device. 
+@param aBackupStateValue A value expressing the backup/restore state of the device. 
+**/
+void CBTManServerBURMgr::ProcessBackupState(TBURPartType aBURStateValue)
+	{
+	LOG_FUNC
+
+	iBURState = aBURStateValue;
+
+	switch (aBURStateValue)
+		{
+	case EBURBackupFull:
+		// Fall-through
+	case EBURBackupPartial:
+		iStateMachine->TransitionState(EBTBUREventBackup);
+		break;
+	case EBURRestoreFull:
+		// Fall-through
+	case EBURRestorePartial:
+		iStateMachine->TransitionState(EBTBUREventRestore);
+		break;
+	case EBURNormal:
+		iStateMachine->TransitionState(EBTBUREventNormal);
+		break;
+	default:	// EBURUnset
+		__ASSERT_DEBUG(aBURStateValue == EBURUnset, PANIC(KBTBackupPanicCat, EBTBURMgrUnknownBUREvent));
+		iStateMachine->TransitionState(EBTBUREventUnset);
+		}
+	}
+
+/**
+Registers an MBTBURNotify instance to receive notification of backup/restore operations starting and stopping.
+Ownership of this MBTBURNotify instance is not transferred.
+Any previous MBTBURNotify instance is deregistered on this method call.
+Supplying a NULL pointer will deregister the previously registered instance (if present).
+**/
+void CBTManServerBURMgr::RequestBURNotification(MBTBURNotify* aBURNotify)
+	{
+	LOG_FUNC
+
+	iBURNotify = aBURNotify;
+	}
+
+
+/**
+Receives a local address from a CBTLocalAddressFetcher instance.
+This will trigger processing of a pending restore file.
+**/
+void CBTManServerBURMgr::SetLocalAddress(TBTDevAddr& aLocalAddr)
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(aLocalAddr != TBTDevAddr(), PANIC(KBTBackupPanicCat, EBTBURMgrMissingLocalAddress));
+
+	// Use address only if it is non-zero.
+	if (aLocalAddr != TBTDevAddr())
+		{
+		// Take a copy
+		iLocalAddr = aLocalAddr;
+		// Attempt to start restore file processing.
+		// Note that this will fail if we are not in the normal state.
+		iStateMachine->TransitionState(EBTBUREventProcessRestoreFile);
+		}
+	}
+
+/**
+Receives notification that a restore file has been provided by the Secure Backup Engine.
+Upon receiving this notification, the restore file is renamed to have the appropriate extension and 
+the local device name is updated in the registry. The restore of the remote devices table is postponed
+until the next time BTManServer starts, so any ongoing BT connections are not affected.
+**/
+void CBTManServerBURMgr::RestoreFileReady()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateRestoreOngoing, InvalidStatePanic(EBTBURStateRestoreOngoing, iStateMachine->GetCurrentState()));
+
+	// Rename restore file
+	RenameBackupFileForRestore();
+	// Attempt to update local device name in the registry (best efforts only)
+	TRAP_IGNORE(UpdateLocalDeviceNameL());
+	}
+
+void CBTManServerBURMgr::HandleStateNormal()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateNormal, InvalidStatePanic(EBTBURStateNormal, iStateMachine->GetCurrentState()));
+
+	if (iActiveBackupClient)
+		{
+		// Backup or restore finished
+		if (iBackupHandler)
+			{
+			// Backup operation finished
+			// Delete backup file and destroy backup handler
+			DeleteBackupFile();
+			delete iBackupHandler;
+			iBackupHandler = NULL;
+			}
+		else
+			{
+			// Restore operation finished
+			delete iActiveBackupDataClient;
+			iActiveBackupDataClient = NULL;
+			}
+
+		// Destroy active backup client
+		delete iActiveBackupClient;
+		iActiveBackupClient = NULL;
+
+		// Notify that backup/restore operation has finished
+		NotifyBUROperationStopped();
+		}
+	}
+
+/**
+Determines if a BUR operation affects the Bluetooth Manager server.
+@return ETrue if a full backup or restore is ongoing, otherwise the return value
+given by CActiveBackupClient::DoesPartialBURAffectMeL()
+**/
+TBool CBTManServerBURMgr::DoesBURAffectMeL(CActiveBackupClient& aClient)
+	{
+	LOG_FUNC
+
+	if (iBURState == EBURBackupFull || iBURState == EBURRestoreFull)
+		{
+		return ETrue;
+		}
+	else
+		{
+		return aClient.DoesPartialBURAffectMeL();
+		}
+	}
+
+void CBTManServerBURMgr::HandleStateBackupRequestL()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateBackupRequest, InvalidStatePanic(EBTBURStateBackupRequest, iStateMachine->GetCurrentState()));
+
+	// Determine if this backup operation affects us and transition to next state based on this outcome.
+	iActiveBackupClient = CActiveBackupClient::NewL();
+
+	if (DoesBURAffectMeL(*iActiveBackupClient))
+		{
+		// We're affected, proceed with backup
+		iStateMachine->TransitionState(EBTBUREventBackupProceed);
+		}
+	else
+		{
+		// We're not effected, don't do any backup handling
+		iStateMachine->TransitionState(EBTBUREventBackupReject);
+		}
+	}
+
+void CBTManServerBURMgr::HandleStateBackupRequestError()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateBackupRequest, InvalidStatePanic(EBTBURStateBackupRequest, iStateMachine->GetCurrentState()));
+
+	// Transition to normal state
+	iStateMachine->TransitionState(EBTBUREventAbortStateAction);
+	}
+
+void CBTManServerBURMgr::HandleStateBackupOngoingL()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateBackupOngoing, InvalidStatePanic(EBTBURStateBackupOngoing, iStateMachine->GetCurrentState()));
+	__ASSERT_DEBUG(iActiveBackupClient, PANIC(KBTBackupPanicCat, EBTBURMgrActiveBackupClientNull));
+
+	// Provide notification that a BUR operation has started.
+	NotifyBUROperationStarted();
+
+	// Construct backup handler and prepare for backup
+	iBackupHandler = CBTBackupHandler::NewL(*this, iBTManServer.Registry());
+	iBackupHandler->CreateBackupFileL();
+
+	// Signal that we're ready for (passive) backup of prepared file
+	iActiveBackupClient->ConfirmReadyForBURL(KErrNone);
+
+	// Next state transition will be invoked when BUR P&S key changes
+	}
+
+void CBTManServerBURMgr::HandleStateBackupOngoingError()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateBackupOngoing, InvalidStatePanic(EBTBURStateBackupOngoing, iStateMachine->GetCurrentState()));
+
+	// Transition to normal state
+	iStateMachine->TransitionState(EBTBUREventAbortStateAction);
+	}
+
+void CBTManServerBURMgr::HandleStateBackupIgnore()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateBackupIgnore, InvalidStatePanic(EBTBURStateBackupIgnore, iStateMachine->GetCurrentState()));
+
+	// Destroy active backup client
+	delete iActiveBackupClient;
+	iActiveBackupClient = NULL;
+
+	// Next state transition will be invoked when BUR P&S key changes
+	}
+
+void CBTManServerBURMgr::HandleStateRestoreRequestL()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateRestoreRequest, InvalidStatePanic(EBTBURStateRestoreRequest, iStateMachine->GetCurrentState()));
+
+	// We do want a callback here. Even though the actual restore operation has been handled passively, we
+	// still need notificaton that the passive restore has completed (so we can then deal with the file).
+	iActiveBackupDataClient = CBTActiveBackupDataClient::NewL(*this);
+	iActiveBackupClient = CActiveBackupClient::NewL(iActiveBackupDataClient);
+
+	// Determine if this restore operation affects us and transition to next state based on this outcome
+	if (DoesBURAffectMeL(*iActiveBackupClient))
+		{
+		// We're affected, proceed with restore
+		iStateMachine->TransitionState(EBTBUREventRestoreProceed);
+		}
+	else
+		{
+		// We're not effected, don't do any restore handling
+		iStateMachine->TransitionState(EBTBUREventRestoreReject);
+		}
+	}
+
+void CBTManServerBURMgr::HandleStateRestoreRequestError()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateRestoreRequest, InvalidStatePanic(EBTBURStateRestoreRequest, iStateMachine->GetCurrentState()));
+	
+	// Transition to normal state
+	iStateMachine->TransitionState(EBTBUREventAbortStateAction);
+	}
+
+void CBTManServerBURMgr::HandleStateRestoreOngoingL()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateRestoreOngoing, InvalidStatePanic(EBTBURStateRestoreOngoing, iStateMachine->GetCurrentState()));
+
+	// Cancel any local address requests
+	if (iLocalAddrFetcher)
+		{
+		iLocalAddrFetcher->Cancel();
+		}
+
+	// Provide notification that a BUR operation has started.
+	NotifyBUROperationStarted();
+
+	// Signal that we're ready for active restore of prepared file
+	// (note that no data is actively restored, but we still need to invoke this method)
+	iActiveBackupClient->ConfirmReadyForBURL(KErrNone);
+
+	// Next state transition will be invoked when BUR P&S key changes
+	}
+
+void CBTManServerBURMgr::HandleStateRestoreOngoingError()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateRestoreOngoing, InvalidStatePanic(EBTBURStateRestoreOngoing, iStateMachine->GetCurrentState()));
+
+	// Transition to normal state
+	iStateMachine->TransitionState(EBTBUREventAbortStateAction);
+	}
+
+void CBTManServerBURMgr::HandleStateRestoreIgnore()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateRestoreIgnore, InvalidStatePanic(EBTBURStateRestoreIgnore, iStateMachine->GetCurrentState()));
+
+	// Destroy active backup client
+	delete iActiveBackupClient;
+	delete iActiveBackupDataClient;
+	iActiveBackupClient = NULL;
+	iActiveBackupDataClient = NULL;
+
+	// Next state transition will be invoked when BUR P&S key changes
+	}
+
+void CBTManServerBURMgr::HandleStateProcessRestoreFileL()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateProcessRestoreFile, InvalidStatePanic(EBTBURStateProcessRestoreFile, iStateMachine->GetCurrentState()));
+
+	// Start restore file processing
+	iRestoreHandler = CBTRestoreHandler::NewL(*this, iBTManServer);
+	iRestoreHandler->RestoreRemoteDeviceTableL(iLocalAddr);
+
+	iStateMachine->TransitionState(EBTBUREventProcessRestoreFileComplete);
+	}
+
+void CBTManServerBURMgr::HandleStateProcessRestoreFileError(TInt aError)
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateProcessRestoreFile, InvalidStatePanic(EBTBURStateProcessRestoreFile, iStateMachine->GetCurrentState()));
+
+	// Delete restore handler
+	delete iRestoreHandler;
+	iRestoreHandler = NULL;
+	
+	// If aError is anything other than KErrNoMemory, then delete restore file.
+	// OOM errors may be temporary, and a subsequent restore attempt may succeed.
+	if (aError != KErrNoMemory)
+		{
+		DeleteRestoreFile();
+		}
+
+	// Transition to normal state
+	iStateMachine->TransitionState(EBTBUREventAbortStateAction);
+	}
+
+void CBTManServerBURMgr::HandleStateRestoreFileProcessingComplete()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iStateMachine->GetCurrentState() == EBTBURStateRestoreFileProcessingComplete, InvalidStatePanic(EBTBURStateRestoreFileProcessingComplete, iStateMachine->GetCurrentState()));
+	
+	// Delete restore file (we're now done with it)
+	DeleteRestoreFile();
+
+	// Delete restore handler
+	delete iRestoreHandler;
+	iRestoreHandler = NULL;
+
+	iStateMachine->TransitionState(EBTBUREventRestoreFileTransitionNormal);
+	}
+
+/**
+Sends notification to a registered MBTBURNotify instance that a backup or restore operation has started.
+@see CBTManServerBURMgr::RequestBURNotification()
+**/
+void CBTManServerBURMgr::NotifyBUROperationStarted()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(!iBUROperationStartNotified, PANIC(KBTBackupPanicCat, EBTBURMgrBUROperationStartAlreadyNotified));
+	
+	if (!iBUROperationStartNotified)
+		{
+		iBUROperationStartNotified = ETrue;
+
+		if (iBURNotify)
+			{
+			iBURNotify->BUROperationStarted();
+			}
+		}
+	}
+
+/**
+Sends notification to the MBTBURNotify instance that a backup or restore operation has started. 
+This should correspond to a call to NotifyBUROperationStarted().
+@see CBTManServerBURMgr::RequestBURNotification()
+**/
+void CBTManServerBURMgr::NotifyBUROperationStopped()
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iBUROperationStartNotified, PANIC(KBTBackupPanicCat, EBTBURMgrBUROperationStartNotNotified));
+	
+	if (iBUROperationStartNotified)
+		{
+		iBUROperationStartNotified = EFalse;
+
+		if (iBURNotify)
+			{
+			iBURNotify->BUROperationStopped();
+			}
+		}
+	}
+
+/**
+Sends notification to the MBTBURNotify instance that a backup or restore operation has started. 
+This will send notification only if NotifyBUROperationStarted() has been called without a corresponding 
+call to NotifyBUROperationStopped().
+This is intended for use in error situations only.
+**/
+void CBTManServerBURMgr::NotifyAnyBUROperationStopped()
+	{
+	LOG_FUNC
+
+	// We deliberately want to fail silently here if no stop notification is expected.
+	if (iBUROperationStartNotified)
+		{
+		iBUROperationStartNotified = EFalse;
+
+		if (iBURNotify)
+			{
+			iBURNotify->BUROperationStopped();
+			}
+		}
+	}
+
+/**
+Utility function to delete a named file from the private directory of this process on the system drive.
+This is a best-efforts attempt which fails silently on error.
+@param aFileName The name of the file to delete.
+**/
+void CBTManServerBURMgr::DeleteFile(const TDesC& aFileName)
+	{
+	LOG_FUNC
+
+	RFs fsSession;
+	// Attempt to delete file
+	// This is best-efforts, failing silently on any error (as there is no remedy action that we can take).
+	if (fsSession.Connect() == KErrNone)
+		{
+		if (fsSession.SetSessionToPrivate(fsSession.GetSystemDrive()) == KErrNone)
+			{
+			// Try to ensure read-only and system attributes are not set
+			TUint attrs;
+			TInt err = fsSession.Att(aFileName, attrs);
+			if (err == KErrNone)
+				{
+				// Unset the files read-only and system attributes if these are set.
+				TUint unsetAttrs = (attrs & KEntryAttReadOnly) | (attrs & KEntryAttSystem);
+				if (unsetAttrs != KEntryAttNormal)
+					{
+					err = fsSession.SetAtt(aFileName, KEntryAttNormal, unsetAttrs);
+					}
+
+				// Attempt to delete the file, if we've managed to successfully retrieve and reset the file attributes. 
+				// Note that this is best-efforts.
+				if (err == KErrNone)
+					{
+					static_cast<void>(fsSession.Delete(aFileName));
+					}
+				}
+			}
+
+		fsSession.Close();
+		}
+	}	
+
+/**
+Deletes the backup file (with name KBTManServerBackupFileName) from the private directory of this process on the system drive.
+This is a best-efforts attempt which fails silently on error.
+**/
+void CBTManServerBURMgr::DeleteBackupFile()
+	{
+	LOG_FUNC
+
+	DeleteFile(KBTManServerBackupFileName);
+	}
+
+/**
+Deletes the restore file (with name KBTManServerRestoreFileName) from the private directory of this process on the system drive.
+This is a best-efforts attempt which fails silently on error.
+**/
+void CBTManServerBURMgr::DeleteRestoreFile()
+	{
+	LOG_FUNC
+
+	DeleteFile(KBTManServerRestoreFileName);
+	}
+
+/**
+Renames a restored backup file from KBTManServerBackupFileName to KBTManServerRestoreFileName.
+This facilitates processing of the restore file when the Bluetooth Manager server next starts.
+This is a best-efforts attempt, as no remedial action can be taken if this operation fails.
+**/
+void CBTManServerBURMgr::RenameBackupFileForRestore()
+	{
+	LOG_FUNC
+
+	// Delete any previous restore file
+	DeleteRestoreFile();
+	
+	RFs fsSession;
+	if (fsSession.Connect() == KErrNone)
+		{
+		static_cast<void>(fsSession.Rename(KBTManServerBackupFileName, KBTManServerRestoreFileName));
+		fsSession.Close();
+		}
+	}
+
+/**
+Parses the restore file and updates the loal device name in the registry.
+This update takes place as soon as the restore file is available, regardless of whether or not the local device
+address matches that held in the registry. If the local device name has already been set to a non-default value,
+then it is not modified.
+**/
+void CBTManServerBURMgr::UpdateLocalDeviceNameL()
+	{
+	LOG_FUNC
+		
+	CBTRestoreHandler* restoreHandler = CBTRestoreHandler::NewL(*this, iBTManServer);
+	CleanupStack::PushL(restoreHandler);
+
+	restoreHandler->RestoreLocalDeviceNameL();
+
+	CleanupStack::PopAndDestroy(restoreHandler);
+	}
+
+void CBTManServerBURMgr::RunL()
+	{
+	LOG_FUNC
+	
+	if (iStatus == KErrNone)
+		{
+		// Subscribe to catch the next transition
+		SubscribeToBackupRestoreKey();
+
+		// Handle this event
+		TInt backupKeyValue = 0;
+		LEAVEIFERRORL(iProperty.Get(backupKeyValue));
+		TBURPartType backupState = GetBURPartType(backupKeyValue);
+
+		ProcessBackupState(backupState);
+		}
+	}
+
+TInt CBTManServerBURMgr::RunError(TInt /*aError*/)
+	{
+	LOG_FUNC
+
+	// Problem occured in obtaining backup key value.
+	// Ignore the error, as there is nothing we can do.
+	return KErrNone;
+	}
+
+void CBTManServerBURMgr::DoCancel()
+	{
+	LOG_FUNC
+	
+	// Cancel our subscription
+	iProperty.Cancel();
+	}
+
+/**
+ CBTBackupHandler - Handles the task of backing up the BT registry into a backup file ready for passive backup.
+ **/
+CBTBackupHandler* CBTBackupHandler::NewL(CBTManServerBURMgr& aBURMgr, CBTRegistry& aRegistry)
+	{
+	LOG_STATIC_FUNC
+
+	CBTBackupHandler* result = new(ELeave) CBTBackupHandler(aBURMgr, aRegistry);
+	CleanupStack::PushL(result);
+	result->ConstructL();
+	CleanupStack::Pop(result);
+	return result;
+	}
+
+CBTBackupHandler::CBTBackupHandler(CBTManServerBURMgr& aBURMgr, CBTRegistry& aRegistry) 
+	: iBURMgr(aBURMgr), 
+	iRegistry(aRegistry)
+	{
+	LOG_FUNC
+	}
+
+void CBTBackupHandler::ConstructL()
+	{
+	LOG_FUNC
+
+	iRegistryData=CBTRegistryBURData::NewL();
+	}
+
+CBTBackupHandler::~CBTBackupHandler()
+	{
+	LOG_FUNC
+
+	delete iRegistryData;
+	}
+
+void CBTBackupHandler::CreateBackupFileL()
+	{
+	LOG_FUNC
+
+	// Collect backup registry data
+	iRegistryData->ReadFromRegistryL(iRegistry);
+	
+	// Only continue if the registry is populated (i.e. it may be in its default state, which does not need to be backed up).
+	// Determine this by examining the local device address stored in the registry. The default registry has this set to 0x0.
+	if (iRegistryData->IsLocalAddressNonZeroL())
+		{
+		// Construct backup file in private directory.
+		RFs fsSession;
+		LEAVEIFERRORL(fsSession.Connect());
+		CleanupClosePushL(fsSession);
+		LEAVEIFERRORL(fsSession.SetSessionToPrivate(fsSession.GetSystemDrive()));
+		// Create private path if it does not already exist.
+		LEAVEIFERRORL(fsSession.CreatePrivatePath(fsSession.GetSystemDrive()));
+
+		RFileWriteStream fStream;
+		// Create backup file, overwriting if necessary (don't care about previous backup files).
+		LEAVEIFERRORL(fStream.Replace(fsSession, KBTManServerBackupFileName, EFileWrite));
+		fStream.PushL();
+			    
+		// Write out data
+		iRegistryData->WriteToStreamL(fStream);
+		fStream.CommitL();
+
+		CleanupStack::PopAndDestroy(2, &fsSession);
+		}
+	}
+
+/**
+ CBTRestoreHandler - Handles the task of restoring the BT registry from a restore file given by passive restore.
+ **/
+CBTRestoreHandler* CBTRestoreHandler::NewL(CBTManServerBURMgr& aBURMgr, CBTManServer& aManServer)
+	{
+	LOG_STATIC_FUNC
+
+	CBTRestoreHandler* result = new(ELeave) CBTRestoreHandler(aBURMgr, aManServer);
+	CleanupStack::PushL(result);
+	result->ConstructL();
+	CleanupStack::Pop(result);
+	return result;
+	}
+
+CBTRestoreHandler::CBTRestoreHandler(CBTManServerBURMgr& aBURMgr, CBTManServer& aManServer) 
+	: iBURMgr(aBURMgr), 
+	iManServer(aManServer)
+	{
+	LOG_FUNC
+	}
+	
+void CBTRestoreHandler::ConstructL()
+	{
+	LOG_FUNC
+
+	iRegistryData = CBTRegistryBURData::NewL();
+	}
+
+CBTRestoreHandler::~CBTRestoreHandler()
+	{
+	LOG_FUNC
+
+	delete iRegistryData;
+	}
+
+void CBTRestoreHandler::RestoreLocalDeviceNameL()
+	{
+	LOG_FUNC
+
+	LoadRestoreDataL();
+
+	// If the local device name is still default, restore without validating the local address
+	// (otherwise we will not be able to restore this field before the next stack start, which may cause problems with some UIs)
+	CBTRegistry& registry = iManServer.Registry();
+	if (iRegistryData->WriteLocalDeviceNameToRegistryL(registry))
+		{
+		NotifyLocalTableChange();
+		}
+	}
+
+void CBTRestoreHandler::RestoreRemoteDeviceTableL(TBTDevAddr& aLocalAddr)
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(aLocalAddr != TBTDevAddr(), PANIC(KBTBackupPanicCat, EBTBURMgrMissingLocalAddress));
+
+	LoadRestoreDataL();
+    
+	// Compare local address held in restore file with our local address
+	if (iRegistryData->IsLocalAddressEqualL(aLocalAddr))
+		{
+    		// Proceed with restore of remote devices table
+		CBTRegistry& registry = iManServer.Registry();
+
+		TInt noRemoteDevices = iRegistryData->CountRemoteDevicesL();
+		for (TInt i = 0; i < noRemoteDevices; i++)
+			{
+			if (iRegistryData->WriteRemoteDeviceToRegistryL(registry, i))
+				{
+				NotifyRemoteTableChangeL(iRegistryData->GetRemoteDeviceL(i).BDAddr());
+				}
+			}
+		}
+	}
+
+void CBTRestoreHandler::LoadRestoreDataL()
+	{
+	LOG_FUNC
+
+	// Read restore file
+	RFs fsSession;
+	LEAVEIFERRORL(fsSession.Connect());
+	CleanupClosePushL(fsSession);
+	LEAVEIFERRORL(fsSession.SetSessionToPrivate(fsSession.GetSystemDrive()));
+	// Assuming private directory exists at this point
+	
+	RFileReadStream fStream;
+	LEAVEIFERRORL(fStream.Open(fsSession, KBTManServerRestoreFileName, EFileRead));
+	fStream.PushL();
+
+	// Read in data
+	iRegistryData->ReadFromStreamL(fStream);
+
+	// Cleanup
+	CleanupStack::PopAndDestroy(2, &fsSession);	//fStream and fsSession
+	}
+
+/**
+Sends a notification that the persistence table has been changed.
+The notification is observable through the P&S key KPropertyKeyBluetoothGetRegistryTableChange. 
+**/
+void CBTRestoreHandler::NotifyLocalTableChange()
+	{
+	LOG_FUNC
+	
+	// Notify the P&S key that the remote devices table has changed
+	iManServer.Publish(KPropertyKeyBluetoothGetRegistryTableChange, KRegistryChangeLocalTable);
+	}
+
+/**
+Sends a notification that a device in the remote devices table has been changed.
+The notification is observable through the P&S key KPropertyKeyBluetoothGetRegistryTableChange. 
+Interested parties can also use RBTRegistry::NotifyViewChange() to detect if the change affects their view.
+**/
+void CBTRestoreHandler::NotifyRemoteTableChangeL(const TBTDevAddr& aAddress)
+	{
+	LOG_FUNC
+	
+	// Construct SQL constraint which selects the device
+	RBTDbQuery query;
+	CleanupClosePushL(query);
+	query.FindDeviceL(aAddress);
+
+	HBufC* conDes = query.ConstraintBuf().AllocLC();
+
+	// Notify the P&S key that the remote devices table has changed
+	iManServer.Publish(KPropertyKeyBluetoothGetRegistryTableChange, KRegistryChangeRemoteTable);
+
+	// Signal notifiers waiting on view change
+	iManServer.NotifyViewChange(*conDes);
+
+	// Cleanup constDes and query
+	CleanupStack::PopAndDestroy(2, &query);
+	}
+
+/**
+CBTRegistryBURData - manages data from the Bluetooth registry that is to be backed up or restored.
+**/
+CBTRegistryBURData* CBTRegistryBURData::NewL()
+	{
+	LOG_STATIC_FUNC
+
+	CBTRegistryBURData* self = new(ELeave) CBTRegistryBURData();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CBTRegistryBURData::CBTRegistryBURData() 
+	: iHasRegistryData(EFalse)
+	{
+	LOG_FUNC
+	}
+
+CBTRegistryBURData::~CBTRegistryBURData()
+	{
+	LOG_FUNC
+
+	if (iRemoteDevices)	// Dont use ClearRegistryData() here as leave may have occured in ReadFromRegistryL() or ReadFromStreamL()
+		{
+		// Destroy all CBTDevices in iRemoteDevices (necessary before array deletion for CArrayPtrFlat)
+		iRemoteDevices->ResetAndDestroy();
+		}
+
+	delete iLocalDevice;
+	delete iRemoteDevicesSid;
+	delete iRemoteDevices;
+	}
+
+void CBTRegistryBURData::ConstructL()
+	{
+	LOG_FUNC
+
+	iRemoteDevicesSid = new (ELeave) CArrayFixFlat<TSecureId>(1);
+	iRemoteDevices = new(ELeave) CBTDeviceArray(1);
+	}
+	
+/**
+Writes the registry data held in this instance to a given stream.
+This does not write those registry fields which contain unset values.
+@param aStream The stream to write the registry data to.
+**/
+void CBTRegistryBURData::WriteToStreamL(RWriteStream& aStream) const
+	{
+	LOG_FUNC
+
+	// Writes registry data out to a given stream, avoiding any use of class externalisation.
+	if (HasRegistryData())
+		{
+		// This follows a specific file-format (tied to the registry version information), which is documented seperately.
+
+		// We should already have the following information for the local device.
+		__ASSERT_DEBUG(iLocalDevice->IsValidAddress(), PANIC(KBTBackupPanicCat, EBTBURMgrExpectedDataMissing));
+
+		// Write out version information
+		aStream.WriteUint32L(iRegistryVersionMajor);
+		aStream.WriteUint32L(iRegistryVersionMinor);
+
+		// Persistence table:
+		// Local device address and name only (both are mandatory).
+		aStream.WriteL(iLocalDevice->Address().Des(), KBTDevAddrSize);
+
+		__ASSERT_DEBUG(iLocalDevice->DeviceName().Length() <= KMaxTUint8, PANIC(KBTBackupPanicCat, EBTBURMgrDescriptorLengthTooLong));
+		aStream.WriteUint8L(iLocalDevice->DeviceName().Length());
+		aStream.WriteL(iLocalDevice->DeviceName(), iLocalDevice->DeviceName().Length());
+
+		// Remote devices table
+		TInt rdCount=CountRemoteDevicesL();
+
+		aStream.WriteUint32L(rdCount);
+		for (TInt i = 0; i < rdCount; i++)
+			{
+			const CBTDevice& nextRemDev = GetRemoteDeviceL(i);
+			const TBTNamelessDevice& nextRemDevNameless = nextRemDev.AsNamelessDevice();
+
+			__ASSERT_DEBUG(nextRemDev.IsValidBDAddr(), PANIC(KBTBackupPanicCat, EBTBURMgrExpectedDataMissing));
+
+			// Work out what is set and derive bitmask (can use TBTDeviceSet here as is public)
+			TUint32 rdSetMask = TBTNamelessDevice::EAddress;
+			if (nextRemDev.IsValidDeviceClass())
+				{
+				rdSetMask |= TBTNamelessDevice::EDeviceClass;
+				}
+			if (nextRemDev.IsValidLinkKey())
+				{
+				rdSetMask |= TBTNamelessDevice::ELinkKey;
+				}
+			if (nextRemDev.IsValidGlobalSecurity())
+				{
+				rdSetMask |= TBTNamelessDevice::EGlobalSecurity;
+				}
+			if (nextRemDevNameless.IsValidPageScanRepMode())
+				{
+				rdSetMask |= TBTNamelessDevice::EPageScanRepMode;
+				}
+			if (nextRemDevNameless.IsValidPageScanMode())
+				{
+				rdSetMask |= TBTNamelessDevice::EPageScanMode;
+				}
+			if (nextRemDevNameless.IsValidPageScanPeriodMode())
+				{
+				rdSetMask |= TBTNamelessDevice::EPageScanPeriodMode;
+				}
+			if (nextRemDevNameless.IsValidClockOffset())
+				{
+				rdSetMask |= TBTNamelessDevice::EClockOffset;
+				}
+			if (nextRemDev.IsValidUsed())
+				{
+				rdSetMask |= TBTNamelessDevice::EUsed;
+				}
+			if (nextRemDev.IsValidSeen())
+				{
+				rdSetMask |= TBTNamelessDevice::ESeen;
+				}
+			if (nextRemDev.IsValidPassKey())
+				{
+				rdSetMask |= TBTNamelessDevice::EPassKey;
+				}
+			if (nextRemDev.IsValidUiCookie())
+				{
+				rdSetMask |= TBTNamelessDevice::EUiCookie;
+				}
+			if (nextRemDev.IsValidDeviceName())
+				{
+				rdSetMask |= CBTDevice::EDeviceName;
+				}
+			if (nextRemDev.IsValidFriendlyName())
+				{
+				rdSetMask |= CBTDevice::EFriendlyName;
+				}
+			// Now write out bitmask
+			aStream.WriteUint32L(rdSetMask);
+
+			// Write valid setting for next remote device
+			aStream.WriteUint32L(GetRemoteDeviceEntrySidL(i));
+			aStream.WriteL(nextRemDev.BDAddr().Des(), KBTDevAddrSize);
+			if (rdSetMask & TBTNamelessDevice::EDeviceClass)
+				{
+				aStream.WriteUint32L(nextRemDev.DeviceClass().DeviceClass());
+				}
+			if (rdSetMask & TBTNamelessDevice::ELinkKey)
+				{
+				const TBTLinkKey& nextRemDevLinkKey = nextRemDev.LinkKey();
+				aStream.WriteL(nextRemDevLinkKey, KHCILinkKeySize);
+				aStream.WriteUint8L(nextRemDev.LinkKeyType());
+				}
+			if (rdSetMask & TBTNamelessDevice::EGlobalSecurity)
+				{
+				TBTDeviceSecurity nextRemDevGlobSec = nextRemDev.GlobalSecurity();
+				aStream.WriteUint8L(nextRemDevGlobSec.SecurityValue());
+				aStream.WriteUint32L(nextRemDevGlobSec.PasskeyMinLength());
+				}
+			if (rdSetMask & TBTNamelessDevice::EPageScanRepMode)
+				{
+				aStream.WriteUint8L(nextRemDevNameless.PageScanRepMode());
+				}
+			if (rdSetMask & TBTNamelessDevice::EPageScanMode)
+				{
+				aStream.WriteUint8L(nextRemDevNameless.PageScanMode());
+				}
+			if (rdSetMask & TBTNamelessDevice::EPageScanPeriodMode)
+				{
+				aStream.WriteUint8L(nextRemDevNameless.PageScanPeriodMode());
+				}
+			if (rdSetMask & TBTNamelessDevice::EClockOffset)
+				{
+				aStream.WriteUint16L(nextRemDevNameless.ClockOffset());
+				}
+			if (rdSetMask & TBTNamelessDevice::EUsed)
+				{
+				const TInt64& used = nextRemDev.Used().Int64();
+				aStream.WriteInt32L(I64HIGH(used));
+				aStream.WriteInt32L(I64LOW(used));
+				}
+			if (rdSetMask & TBTNamelessDevice::ESeen)
+				{
+				const TInt64& seen = nextRemDev.Seen().Int64();
+				aStream.WriteInt32L(I64HIGH(seen));
+				aStream.WriteInt32L(I64LOW(seen));
+				}
+			if (rdSetMask & TBTNamelessDevice::EPassKey)
+				{
+				const TBTPinCode& nextRemDevPassKey = nextRemDev.PassKey();
+				__ASSERT_DEBUG(nextRemDevPassKey.Length() == KHCIPINCodeSize + 1, PANIC(KBTBackupPanicCat, EBTBURMgrDescriptorUnexpectedLength));
+				aStream.WriteL(nextRemDevPassKey, KHCIPINCodeSize + 1);
+				}
+			if (rdSetMask & TBTNamelessDevice::EUiCookie)
+				{
+				aStream.WriteUint32L(nextRemDev.UiCookie());
+				}
+			if (rdSetMask & CBTDevice::EDeviceName)
+				{
+				__ASSERT_DEBUG(nextRemDev.DeviceName().Length() <= KMaxTUint8, PANIC(KBTBackupPanicCat, EBTBURMgrDescriptorLengthTooLong));
+				aStream.WriteUint8L(nextRemDev.DeviceName().Length());
+				aStream.WriteL(nextRemDev.DeviceName(), nextRemDev.DeviceName().Length());
+				}
+			if (rdSetMask & CBTDevice::EFriendlyName)
+				{
+				__ASSERT_DEBUG(nextRemDev.FriendlyName().Length() <= KMaxTUint8, PANIC(KBTBackupPanicCat, EBTBURMgrDescriptorLengthTooLong));
+				aStream.WriteUint8L(nextRemDev.FriendlyName().Length());
+				aStream.WriteL(nextRemDev.FriendlyName(), nextRemDev.FriendlyName().Length());
+				}
+			}
+		}
+	else
+		{
+		User::Leave(KErrNotFound);
+		}
+	}
+
+/**
+Reads registry data from a given stream and stores within this instance.
+Any registry data currently held is cleared first.
+@param aStream The stream to ready the registry data from.
+**/
+void CBTRegistryBURData::ReadFromStreamL(RReadStream& aStream)
+	{
+	LOG_FUNC
+
+	// This follows a specific file-format (tied to the registry version information), which is documented seperately.
+	
+	// Note that we dont make *ANY* assumptions as to what data should always be available, since the restore file could be corrupt.
+	// We will fail the restore if it turns out we do not have enough information, or if we have invalid information.
+	
+	// WARNING: When a new registry version is produced, this implementaton of backup/restore support will need modification.
+	// This assert should be updated to include all supported registry versions.
+	__ASSERT_DEBUG(KRegistryDBVersionMajor == 1 && KRegistryDBVersionMinor == 2, PANIC(KBTBackupPanicCat, EBTBURMgrUnsupportedRegistryVersion));
+	
+	// Extract version information and continue if we can handle it.
+	TUint32 regVersionMajor = aStream.ReadUint32L();
+	TUint32 regVersionMinor = aStream.ReadUint32L();
+	if (regVersionMajor == KRegistryDBVersionMajor && regVersionMinor == KRegistryDBVersionMinor)
+		{
+		// We support this version and this version only - read in registry data
+		ClearRegistryData();
+
+		iLocalDevice = new(ELeave) TBTLocalDevice;
+		
+		// Note version information for this registry
+		iRegistryVersionMajor = regVersionMajor;
+		iRegistryVersionMinor = regVersionMinor;
+
+		// Persistence table:
+		// Local device address and name only (both fields are mandatory).
+		TBTDevAddr address;
+		TPtr8 addrPtr(address.Des());
+		aStream.ReadL(addrPtr, KBTDevAddrSize);
+		if (addrPtr.Length() == KBTDevAddrSize)
+			{
+			iLocalDevice->SetAddress(address);
+			}
+		else
+			{
+			User::Leave(KErrCorrupt);
+			}
+
+		TInt deviceNameLength = static_cast<TInt>(aStream.ReadUint8L());
+		if (deviceNameLength <= KMaxBluetoothNameLen)
+			{
+			RBuf8 deviceName;
+			deviceName.CreateL(KMaxBluetoothNameLen);
+			CleanupClosePushL(deviceName);
+
+			aStream.ReadL(deviceName,deviceNameLength);
+			if (deviceName.Length() == deviceNameLength)
+				{
+				iLocalDevice->SetDeviceName(deviceName);
+				}
+			else
+				{
+				User::Leave(KErrCorrupt);
+				}
+			CleanupStack::PopAndDestroy(&deviceName);
+			}
+		else
+			{
+			User::Leave(KErrCorrupt);
+			}
+		
+		// Remote devices table:
+		TInt rdCount = aStream.ReadUint32L();
+		for (TInt i = 0; i < rdCount; i++)
+			{
+			// First read bitmask of available data
+			TUint32 rdSetMask = aStream.ReadUint32L();
+
+			// Then read available data from file and store
+			CBTDevice *rdInstance = CBTDevice::NewLC();
+			TBTNamelessDevice& rdNamelessDevInstance = rdInstance->AsNamelessDevice();
+			TSecureId rdSid = aStream.ReadUint32L();
+
+			// Remote BT address is mandatory
+			if (rdSetMask & TBTNamelessDevice::EAddress)
+				{
+				TBTDevAddr rdAddr;
+				TPtr8 rdAddrPtr(rdAddr.Des());
+				aStream.ReadL(rdAddrPtr, KBTDevAddrSize);
+
+				// Ensure address is of required length and is non-zero
+				if (rdAddrPtr.Length() == KBTDevAddrSize && rdAddr != TBTDevAddr())
+					{
+					rdInstance->SetDeviceAddress(rdAddr);
+					}
+				else
+					{
+					User::Leave(KErrCorrupt);
+					}
+				}
+			else
+				{
+				User::Leave(KErrCorrupt);
+				}
+
+			if (rdSetMask & TBTNamelessDevice::EDeviceClass)
+				{
+				TBTDeviceClass rdClass = TBTDeviceClass(aStream.ReadUint32L());
+				rdInstance->SetDeviceClass(rdClass);
+				}
+
+			if (rdSetMask & TBTNamelessDevice::ELinkKey)
+				{
+				TBTLinkKey rdLinkKey;
+				aStream.ReadL(rdLinkKey, KHCILinkKeySize);
+				if (rdLinkKey.Length() == KHCILinkKeySize)
+					{
+					TUint8 rdLinkKeyType = static_cast<TBTLinkKeyType>(aStream.ReadUint8L());
+					// Ensure value is in the valid range (ELinkKeyCombination is zero so (pointless) comparison with this gives warnings).
+					if (rdLinkKeyType <= ELinkKeyDebug)
+						{
+						rdInstance->SetLinkKey(rdLinkKey, static_cast<TBTLinkKeyType>(rdLinkKeyType));
+						}
+					else
+						{
+						User::Leave(KErrCorrupt);
+						}
+
+					}
+				else
+					{
+					User::Leave(KErrCorrupt);
+					}
+				}
+
+			if (rdSetMask & TBTNamelessDevice::EGlobalSecurity)
+				{
+				TBTDeviceSecurity rdGlobSec;
+				TUint8 globSecValue = aStream.ReadUint8L();
+				// Ensure value is in the valid range (lower value is zero so (pointless) comparison with this gives warnings).
+				if (globSecValue <= KBTBURMgrMaxGlobalSecurityValue)
+					{
+					rdGlobSec.SetSecurityValue(globSecValue);
+
+					TUint32 passKeyMinLen = aStream.ReadUint32L();
+
+					if (passKeyMinLen <= KHCIPINCodeSize)
+						{
+						rdGlobSec.SetPasskeyMinLength(passKeyMinLen);
+						rdInstance->SetGlobalSecurity(rdGlobSec);
+						}
+					else
+						{
+						User::Leave(KErrCorrupt);
+						}
+					}
+				else
+					{
+					User::Leave(KErrCorrupt);
+					}
+				}
+
+			if (rdSetMask & TBTNamelessDevice::EPageScanRepMode)
+				{
+				TUint8 rdPageScanRepMode = aStream.ReadUint8L();
+				// Ensure value is in the valid range (lower value is zero so (pointless) comparison with this gives warnings).
+				if (rdPageScanRepMode <= EPageScanModeR2)
+					{
+					rdNamelessDevInstance.SetPageScanRepMode(rdPageScanRepMode);
+					}
+				else
+					{
+					User::Leave(KErrCorrupt);
+					}
+				}
+
+			if (rdSetMask & TBTNamelessDevice::EPageScanMode)
+				{
+				TUint8 rdPageScanMode = aStream.ReadUint8L();
+				// Ensure value is in the valid range (lower value is zero so (pointless) comparison with this gives warnings).
+				if (rdPageScanMode <= KBTBURMgrMaxPageScanMode)
+					{
+					rdNamelessDevInstance.SetPageScanMode(rdPageScanMode);
+					}
+				else
+					{
+					User::Leave(KErrCorrupt);
+					}
+				}
+
+			if (rdSetMask & TBTNamelessDevice::EPageScanPeriodMode)
+				{
+				TUint8 rdPageScanPeriodMode = aStream.ReadUint8L();
+				// Ensure value is in the valid range (lower value is zero so (pointless) comparison with this gives warnings).
+				if (rdPageScanPeriodMode <= KBTBURMgrMaxPageScanPeriodMode)
+					{
+					rdNamelessDevInstance.SetPageScanPeriodMode(rdPageScanPeriodMode);
+					}
+				else
+					{
+					User::Leave(KErrCorrupt);
+					}
+				}
+
+			if (rdSetMask & TBTNamelessDevice::EClockOffset)
+				{
+				TUint16 rdClockOffset = aStream.ReadUint16L();
+				rdNamelessDevInstance.SetClockOffset(rdClockOffset);
+				}
+
+			if (rdSetMask & TBTNamelessDevice::EUsed)
+				{
+				TInt32 usedU = aStream.ReadInt32L();
+				TInt32 usedL = aStream.ReadInt32L();
+				TInt64 rdUsed = MAKE_TINT64(usedU, usedL);
+				rdNamelessDevInstance.SetUsed(rdUsed);
+				}
+
+			if (rdSetMask & TBTNamelessDevice::ESeen)
+				{
+				TInt32 seenU = aStream.ReadInt32L();
+				TInt32 seenL = aStream.ReadInt32L();
+				TInt64 rdSeen = MAKE_TINT64(seenU, seenL);
+				rdNamelessDevInstance.SetSeen(rdSeen);	
+				}
+
+			if (rdSetMask & TBTNamelessDevice::EPassKey)
+				{
+				TBTPinCode rdPassKey;
+				aStream.ReadL(rdPassKey, KHCIPINCodeSize + 1);
+				if (rdPassKey.Length() == KHCIPINCodeSize + 1)
+					{
+					rdInstance->SetPassKey(rdPassKey);
+					}
+				else
+					{
+					User::Leave(KErrCorrupt);
+					}
+				}
+			
+			if (rdSetMask & TBTNamelessDevice::EUiCookie)
+				{
+				TUint32 rdUiCookie = aStream.ReadUint32L();
+				rdNamelessDevInstance.SetUiCookie(rdUiCookie);
+				}
+
+			if (rdSetMask & CBTDevice::EDeviceName)
+				{
+				TInt rdNameLen = static_cast<TInt>(aStream.ReadUint8L());
+				if (rdNameLen <= KMaxBluetoothNameLen)
+					{
+					RBuf8 rdName;
+					rdName.CreateL(KMaxBluetoothNameLen);
+					CleanupClosePushL(rdName);
+					
+					aStream.ReadL(rdName, rdNameLen);
+					if (rdName.Length() == rdNameLen)
+						{
+						rdInstance->SetDeviceNameL(rdName);
+						}
+					else
+						{
+						User::Leave(KErrCorrupt);
+						}
+					CleanupStack::PopAndDestroy(&rdName);
+					}
+				else
+					{
+					User::Leave(KErrCorrupt);
+					}
+				}
+
+			if (rdSetMask & CBTDevice::EFriendlyName)
+				{
+				TInt rdFriendlyNameLen = static_cast<TInt>(aStream.ReadUint8L());
+				if (rdFriendlyNameLen <= KMaxFriendlyNameLen)
+					{
+					RBuf rdFriendlyName;
+					rdFriendlyName.CreateL(KMaxFriendlyNameLen);
+					CleanupClosePushL(rdFriendlyName);
+
+					aStream.ReadL(rdFriendlyName, rdFriendlyNameLen);
+					if (rdFriendlyName.Length() == rdFriendlyNameLen)
+						{
+						rdInstance->SetFriendlyNameL(rdFriendlyName);
+						}
+					else
+						{
+						User::Leave(KErrCorrupt);
+						}
+					CleanupStack::PopAndDestroy(&rdFriendlyName);
+					}
+				else
+					{
+					User::Leave(KErrCorrupt);
+					}
+				}
+			
+			// Data now stored, add rdInstance to our remote devices list
+			iRemoteDevices->AppendL(rdInstance);
+			iRemoteDevicesSid->AppendL(rdSid);
+			CleanupStack::Pop(rdInstance);
+			}
+
+		// Mark that we now have registry data 
+		iHasRegistryData = ETrue;
+		}
+	}
+
+/**
+Reads registry data from the registry into this instance.
+Any existing registry data held in this instance is cleared first.
+@param aRegistry The CBTRegistry instance to use for registry access.
+**/
+void CBTRegistryBURData::ReadFromRegistryL(CBTRegistry& aRegistry)
+	{
+	LOG_FUNC
+
+	ClearRegistryData();
+
+	// The meta information from our registry is known.
+	iRegistryVersionMajor = KRegistryDBVersionMajor;
+	iRegistryVersionMinor = KRegistryDBVersionMinor;
+
+	// Persistence table
+	iLocalDevice = aRegistry.GetLocalDeviceL();
+
+	// Remote device table
+	// Create a view on the table.
+	RBTDbQuery query;
+	CleanupClosePushL(query);
+	TBTRegistrySearch searchCriteria;
+	searchCriteria.FindAll();
+	query.SearchL(searchCriteria);
+	TDbBookmark bookmark;
+	RDbView* view = aRegistry.OpenViewL(query, bookmark);
+	CleanupCloseDeletePushL(view);
+
+	// Populate iRemoteDevices from the view.
+	while (!view->AtEnd())
+		{
+		CBTDevice *next = aRegistry.GetNextDeviceL(*view, bookmark, ETrue);
+		CleanupStack::PushL(next);
+		
+		// CBTRegisty::CreatingProcessUidL() requires a rowset with exactly one row.
+		// So we have to requery for this device to get a singular row.
+		TDbBookmark singleBookmark;
+		RDbView* singleView = aRegistry.OpenDeviceL(next->BDAddr(), singleBookmark);
+		CleanupCloseDeletePushL(singleView);
+		TSecureId nextSid = aRegistry.CreatingProcessUidL(*singleView);
+		CleanupStack::PopAndDestroy(singleView);
+		
+		iRemoteDevices->AppendL(next);
+		iRemoteDevicesSid->AppendL(nextSid);
+		
+		CleanupStack::Pop(next);	// iRemoteDevices now takes ownership
+		}
+
+	CleanupStack::PopAndDestroy(2, &query);	// view and query
+
+	// Mark that we now have registry data 
+	iHasRegistryData = ETrue;
+	}
+
+/**
+Updates the persistence table of the registry with local device name held in this instance
+if the registry currently holds a default name.
+@param aRegistry The CBTRegistry instance to use for registry access.
+@return ETrue if an update was made to the registry.
+**/
+TBool CBTRegistryBURData::WriteLocalDeviceNameToRegistryL(CBTRegistry& aRegistry) const
+	{
+	LOG_FUNC
+
+	TBool updateDone = EFalse;
+
+	// Update device name only if the registry has a default name 
+	TBTLocalDevice defaultDevice;
+	TRAP_IGNORE(aRegistry.GetDefaultDeviceFromIniL(defaultDevice));
+
+	if (!defaultDevice.IsValidDeviceName())
+		{
+		// Could not obtain a default name - use KDefaultLocalName instead
+		defaultDevice.SetDeviceName(KDefaultLocalName);
+		}
+
+	TBTLocalDevice* localDevice = aRegistry.GetLocalDeviceL();
+	CleanupStack::PushL(localDevice);
+
+	if (localDevice->DeviceName() == defaultDevice.DeviceName())
+		{
+		// Local device name is default, update with restored value.
+		localDevice->SetDeviceName(GetLocalDeviceNameL());
+		aRegistry.UpdateLocalDeviceL(*localDevice);
+		updateDone = ETrue;
+		}
+
+	CleanupStack::PopAndDestroy(localDevice);
+
+	return updateDone;
+	}
+
+/**
+Updates an entry of the remote devices table of the registry with data held in this instance.
+If the remote device already exists in the registry, the registry version is updated only if it
+does not hold a link key.
+Otherwise, the remote device is added to the registry.
+@param aRegistry The CBTRegistry instance to use for registry access.
+@param aDeviceIndex The remote device held in this CBTRegistryBURData instance to be written to the registry.
+@return ETrue if an update was made to the registry.
+**/
+TBool CBTRegistryBURData::WriteRemoteDeviceToRegistryL(CBTRegistry& aRegistry, TInt aDeviceIndex) const
+	{
+	LOG_FUNC
+
+	TBool updateDone = EFalse;
+	
+	// Get device and SID
+	const CBTDevice& nextRemDevice = GetRemoteDeviceL(aDeviceIndex);
+	TSecureId nextRemDeviceSid = GetRemoteDeviceEntrySidL(aDeviceIndex);
+
+	// Try to add device to registry. If this fails with KErrAlreadExists, then update existing device.
+	TRAPD(err, aRegistry.CreateDeviceL(nextRemDevice, nextRemDevice.IsValidUiCookie(), nextRemDeviceSid));
+
+	if (err == KErrNone)
+		{
+		// New device added successfully
+		updateDone = ETrue;
+		}
+	else if (err == KErrAlreadyExists)
+		{
+		// Device already exists. Extract and examine
+		TDbBookmark bookmark;
+		RDbView* view = aRegistry.OpenDeviceL(nextRemDevice.BDAddr(), bookmark);
+		CleanupCloseDeletePushL(view);
+		CBTDevice *regDev = aRegistry.GetNextDeviceL(*view, bookmark, ETrue);
+		CleanupStack::PushL(regDev);
+
+		if (!regDev->IsValidLinkKey())
+			{
+			// No link key - safe to restore remote device from file.
+			view->FirstL();
+			aRegistry.UpdateDeviceL(*view, nextRemDevice);
+			updateDone = ETrue;
+			}
+
+		CleanupStack::PopAndDestroy(2, view);
+		}
+	else
+		{
+		// Unexpected error - pass upward for handling
+		User::Leave(err);
+		}
+
+	return updateDone;
+	}
+
+void CBTRegistryBURData::GetRegistryVersionL(TUint32& aRegistryVersionMajor, TUint32& aRegistryVersionMinor) const
+	{
+	LOG_FUNC
+
+	if (!HasRegistryData())
+		{
+		User::Leave(KErrNotFound);
+		}
+	
+	aRegistryVersionMajor = iRegistryVersionMajor;
+	aRegistryVersionMinor = iRegistryVersionMinor;
+	}
+
+const TDesC8& CBTRegistryBURData::GetLocalDeviceNameL() const
+	{
+	LOG_FUNC
+
+	if (!HasRegistryData())
+		{
+		User::Leave(KErrNotFound);
+		}
+
+	__ASSERT_DEBUG(iLocalDevice, PANIC(KBTBackupPanicCat, EBTBURMgrExpectedDataMissing));
+	return iLocalDevice->DeviceName();
+	}
+
+TBool CBTRegistryBURData::IsLocalAddressNonZeroL() const
+	{
+	LOG_FUNC
+
+	TBTDevAddr zeroAddr;
+	return !IsLocalAddressEqualL(zeroAddr);
+	}
+
+TBool CBTRegistryBURData::IsLocalAddressEqualL(TBTDevAddr& aAddr) const
+	{
+	LOG_FUNC
+
+	if (!HasRegistryData())
+		{
+		User::Leave(KErrNotFound);
+		}
+
+	__ASSERT_DEBUG(iLocalDevice, PANIC(KBTBackupPanicCat, EBTBURMgrExpectedDataMissing));
+	return (iLocalDevice->Address() == aAddr);
+	}
+
+TInt CBTRegistryBURData::CountRemoteDevicesL() const
+	{
+	LOG_FUNC
+
+	if (!HasRegistryData())
+		{
+		User::Leave(KErrNotFound);
+		}
+	
+	__ASSERT_DEBUG(iRemoteDevices->Count() == iRemoteDevicesSid->Count(), PANIC(KBTBackupPanicCat, EBTBURMgrArraySizeMisMatch));	
+	return iRemoteDevices->Count();
+	}
+
+const CBTDevice& CBTRegistryBURData::GetRemoteDeviceL(TInt aDeviceIndex) const
+	{
+	LOG_FUNC
+
+	if (!HasRegistryData() || !((aDeviceIndex >= 0) && (aDeviceIndex < iRemoteDevices->Count())))
+		{
+		User::Leave(KErrNotFound);
+		}
+
+	__ASSERT_DEBUG(iRemoteDevices->Count() == iRemoteDevicesSid->Count(), PANIC(KBTBackupPanicCat, EBTBURMgrArraySizeMisMatch));	
+	return *(iRemoteDevices->At(aDeviceIndex));
+	}
+
+TSecureId CBTRegistryBURData::GetRemoteDeviceEntrySidL(TInt aDeviceIndex) const
+	{
+	LOG_FUNC
+
+	if (!HasRegistryData() || !((aDeviceIndex >= 0) && (aDeviceIndex < iRemoteDevicesSid->Count())))
+		{
+		User::Leave(KErrNotFound);
+		}
+	
+	__ASSERT_DEBUG(iRemoteDevices->Count() == iRemoteDevicesSid->Count(), PANIC(KBTBackupPanicCat, EBTBURMgrArraySizeMisMatch));	
+	return iRemoteDevicesSid->At(aDeviceIndex);
+	}
+
+/**
+Clears any registry data stored internally within this instance.
+If no data is stored, this method does nothing.
+**/
+void CBTRegistryBURData::ClearRegistryData()
+	{
+	LOG_FUNC
+
+	// This is a no-op if we have no registry data to clear
+	if (HasRegistryData())
+		{
+		// Clear data held previously
+		iRemoteDevicesSid->Reset();
+		iRemoteDevices->ResetAndDestroy();
+		delete iLocalDevice;
+		iLocalDevice = NULL;
+
+		iHasRegistryData = EFalse;
+		}
+	}
+
+/**
+CBTLocalAddressFetcher - Fetches the local device address, or waits for the addresss to become available, and 
+passes to CBTManServerBURMgr.
+**/
+CBTLocalAddressFetcher* CBTLocalAddressFetcher::NewL(CBTManServerBURMgr& aBURMgr, CBTRegistry& aRegistry, TInt aPriority)
+	{
+	LOG_STATIC_FUNC
+
+	CBTLocalAddressFetcher* result = new(ELeave) CBTLocalAddressFetcher(aBURMgr, aRegistry, aPriority);
+	CleanupStack::PushL(result);
+	result->ConstructL();
+	CleanupStack::Pop(result);
+	return result;
+	}
+
+CBTLocalAddressFetcher::CBTLocalAddressFetcher(CBTManServerBURMgr& aBURMgr, CBTRegistry& aRegistry, TInt aPriority) 
+	: CActive(aPriority), 
+	iBURMgr(aBURMgr), 
+	iRegistry(aRegistry)
+	{
+	LOG_FUNC
+
+	CActiveScheduler::Add(this);
+	}
+
+CBTLocalAddressFetcher::~CBTLocalAddressFetcher()
+	{
+	LOG_FUNC
+
+	// Cancel any outstanding requests
+	Cancel();
+	iProperty.Close();
+	}
+
+void CBTLocalAddressFetcher::ConstructL()
+	{
+	LOG_FUNC
+
+	// Attach to KPropertyKeyBluetoothGetLocalDeviceAddress
+	LEAVEIFERRORL(iProperty.Attach(KPropertyUidBluetoothCategory, KPropertyKeyBluetoothGetLocalDeviceAddress));
+	}
+
+void CBTLocalAddressFetcher::FetchLocalAddress()
+	{
+	LOG_FUNC
+
+	// Subscribe for local address, in case we need to wait
+	SubscribeToGetLocalDeviceAddressKey();	
+
+	// Attempt to read the BT address from KPropertyKeyBluetoothGetLocalDeviceAddress key
+	// If key is not found or yields a zero address then try the registry.
+	// If the registry also holds a zero address then wait for notification from the P&S key.
+	TBuf8<KBTDevAddrSize> btAddrDes;
+	TBTDevAddr btAddr;
+	TInt err = iProperty.Get(btAddrDes);
+	
+	if (err != KErrNone)
+		{
+		// Key does not exist or could not be read.
+		// Stack may not be loaded, so now try registry.
+		// Ignore any errors; if we can't read this now then we will wait for the stack.
+		TRAP_IGNORE(btAddr = GetLocalAddressFromRegistryL());
+		}
+	else
+		{
+		// Convert btAddrDes to TBTDevAddr if it has the required size.
+		if (btAddrDes.Length() == KBTDevAddrSize)
+			{
+			btAddr = btAddrDes;	
+			}
+
+		if (btAddr == TBTDevAddr())
+			{
+			// Key exists, so stack is loaded, but address is zero, so now try registry
+			// Ignore any errors; if we can't read this now then we will wait for the stack.
+			TRAP_IGNORE(btAddr = GetLocalAddressFromRegistryL());
+			}
+		}
+	
+	// We have tried our best to get the local address.
+	// If this is non-zero, provide to CBTManServerBURMgr instance. 
+	// Otherwise, wait on P&S key
+	if (btAddr != TBTDevAddr())
+		{
+		// We have a non-zero address.
+		// Cancel subscription and inform CBTManServerBURMgr.
+		Cancel();
+		iBURMgr.SetLocalAddress(btAddr);
+		}	
+	}
+
+void CBTLocalAddressFetcher::SubscribeToGetLocalDeviceAddressKey()
+	{
+	LOG_FUNC
+
+	// Subscribe to KPropertyKeyBluetoothGetLocalDeviceAddress key
+	iProperty.Subscribe(iStatus);
+	SetActive();
+	}
+
+TBTDevAddr CBTLocalAddressFetcher::GetLocalAddressFromRegistryL()
+	{
+	LOG_FUNC
+	
+	TBTLocalDevice* regLocalDevice=iRegistry.GetLocalDeviceL();
+	TBTDevAddr result=regLocalDevice->Address();
+	delete regLocalDevice;
+	
+	return result;	
+	}
+
+void CBTLocalAddressFetcher::RunL()
+	{
+	LOG_FUNC
+
+	if (iStatus == KErrNone)
+		{
+		// Obtain address and send to CBTManServerBURMgr
+		TBuf8<KBTDevAddrSize> btAddrDes;
+		TBTDevAddr btAddr;
+		TInt err = iProperty.Get(btAddrDes);
+				
+		__ASSERT_DEBUG(err == KErrNone, PANIC(KBTBackupPanicCat, EBTBURMgrUnexpectedRPropertyError));
+		
+		if (err == KErrNone) 
+			{
+			btAddr = btAddrDes;
+			iBURMgr.SetLocalAddress(btAddr);
+			}
+		}
+	}
+
+void CBTLocalAddressFetcher::DoCancel()
+	{
+	LOG_FUNC
+
+	// Cancel our subscription
+	iProperty.Cancel();
+	}
+
+/**
+CBTActiveBackupDataClient - Active callback implementation (for restore notification)
+**/
+CBTActiveBackupDataClient* CBTActiveBackupDataClient::NewL(CBTManServerBURMgr& aBURMgr)
+	{
+	LOG_STATIC_FUNC
+
+	CBTActiveBackupDataClient* result = new (ELeave) CBTActiveBackupDataClient(aBURMgr);
+	return result;
+	}
+
+CBTActiveBackupDataClient::CBTActiveBackupDataClient(CBTManServerBURMgr& aBURMgr) 
+	: iBURMgr(aBURMgr)
+	{
+	LOG_FUNC
+	}
+
+CBTActiveBackupDataClient::~CBTActiveBackupDataClient()
+	{
+	LOG_FUNC
+	}
+
+// Backup methods (not used)
+void CBTActiveBackupDataClient::AllSnapshotsSuppliedL()
+	{
+	LOG_FUNC
+
+	//Not supported
+	User::Leave(KErrNotSupported);
+	}
+ 
+void CBTActiveBackupDataClient::ReceiveSnapshotDataL(TDriveNumber /*aDrive*/, TDesC8& /*aBuffer*/, TBool /*aLastSection*/)
+	{
+	LOG_FUNC
+
+ 	//Not supported
+	User::Leave(KErrNotSupported);	
+	}
+ 
+TUint CBTActiveBackupDataClient::GetExpectedDataSize(TDriveNumber /*aDrive*/)
+	{
+	LOG_FUNC
+
+	//Not supported - so expected size can be 0
+	return 0;
+	}
+ 
+void CBTActiveBackupDataClient::GetSnapshotDataL(TDriveNumber /*aDrive*/, TPtr8& /*aBuffer*/, TBool& /*aFinished*/)
+	{
+	LOG_FUNC
+
+	//Not supported
+	User::Leave(KErrNotSupported);
+	}
+ 
+void CBTActiveBackupDataClient::InitialiseGetBackupDataL(TDriveNumber /*aDrive*/)
+	{
+	LOG_FUNC
+
+	//Not supported
+	User::Leave(KErrNotSupported);
+	}
+ 
+void CBTActiveBackupDataClient::GetBackupDataSectionL(TPtr8& /*aBuffer*/, TBool& /*aFinished*/)
+	{
+	LOG_FUNC
+
+	//Not supported
+	User::Leave(KErrNotSupported);
+	}
+         
+//Restore methods (only the notification method RestoreComplete() is used)
+ 
+void CBTActiveBackupDataClient::InitialiseRestoreBaseDataL(TDriveNumber /*aDrive*/)
+	{
+	LOG_FUNC
+
+	//Note that we are doing a base restore.
+	User::Leave(KErrNotSupported);
+	}
+ 
+void CBTActiveBackupDataClient::RestoreBaseDataSectionL(TDesC8& /*aBuffer*/, TBool /*aFinished*/)
+	{
+	LOG_FUNC
+
+	//Not supported
+	User::Leave(KErrNotSupported);
+	}	
+ 
+void CBTActiveBackupDataClient::InitialiseRestoreIncrementDataL(TDriveNumber /*aDrive*/)
+	{
+	LOG_FUNC
+
+	//Not supported
+	User::Leave(KErrNotSupported);
+	}
+ 
+void CBTActiveBackupDataClient::RestoreIncrementDataSectionL(TDesC8& /*aBuffer*/, TBool /*aFinished*/)
+	{
+	LOG_FUNC
+
+	//Not supported
+	User::Leave(KErrNotSupported);
+	}
+ 
+void CBTActiveBackupDataClient::RestoreComplete(TDriveNumber aDrive)
+	{
+	LOG_FUNC
+
+	// Allow CBTManServerBURMgr instance to handle arrival of restore file.
+	if (aDrive == RFs::GetSystemDrive())
+		{
+		iBURMgr.RestoreFileReady();
+		}
+	}
+ 
+         
+//General methods
+ 
+void CBTActiveBackupDataClient::TerminateMultiStageOperation()
+	{
+	LOG_FUNC
+
+	//Dont care - we will see the operation is cancelled when normal or unset mode is invoked.
+	}
+ 
+//Test methods
+ 
+TUint CBTActiveBackupDataClient::GetDataChecksum(TDriveNumber /*aDrive*/)
+	{
+	LOG_FUNC
+
+	//Return an invariant checksum
+	return 0;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothmgmt/btmgr/BTManServer/btmanserverburmgr.h	Fri Apr 16 16:09:25 2010 +0300
@@ -0,0 +1,347 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Implements backup and restore support for the Bluetooth Manager server.
+//
+
+/**
+ @file
+ @internalAll
+*/
+
+#ifndef BTMANSERVERBURMGR_H
+#define BTMANSERVERBURMGR_H
+
+#include <connect/abclient.h>
+
+#include "BTRegistryDB.h"
+
+#include "btmanserverburstatemachine.h"
+
+using namespace conn;
+
+_LIT(KBTBackupPanicCat, "BTManServer BUR Panic");
+// Used to allow state information to be encoded into a panic code.
+const TInt KBTBackupStatePanicMultiplier = 1000000;
+const TInt KBTBackupStateMultiplier = 1000;
+// Used to seperate the panic and state / event values in a panic code.
+const TInt KBTBackupStatePanicMajorDelimiter = 100000;
+const TInt KBTBackupStatePanicMinorDelimiter = 100;
+
+/**
+TBTBackupPanic - Panics that may be raised by the BUR manager
+**/
+enum TBTBackupPanic
+	{
+	EBTBURMgrAlreadyInOperation			= 0,	// A backup/restore event has been received during an ongoing BUR operation
+	EBTBURMgrExpectedDataMissing			= 1,	// An operation has found that it is missing essential data
+	EBTBURMgrBUROperationStartAlreadyNotified	= 2,	// An MBTNotify instance has already been told that a BUR operation has started (and has not received a corresponding BUROperationStop notification)
+	EBTBURMgrBUROperationStartNotNotified		= 3,	// An MBTNotify instance has been notified that a BUR operation has stopped, without receiving notification that it had started.
+
+	EBTBURMgrNoSessionAdded				= 4,	// No session has been registered on BTManServer for the BUR manager
+	EBTBURMgrInvalidRemoteDeviceIndex		= 5,	// An index for a remote device is invalid.
+	EBTBURMgrInvalidStateTransition			= 6,	// An attempted state transition was invalid.
+	EBTBURMgrInvalidState				= 7,	// Either the requested state was invalid or the current state is not valid for some operation.
+	EBTBURMgrInvalidStateIndex			= 8,	// A given state index is invalid.
+	EBTBURMgrMissingLocalAddress			= 9,	// A nonzero local address was expected but not found
+	EBTBURMgrUnexpectedMethodCall			= 10,	// A method was unexpectedly called
+	EBTBURMgrArraySizeMisMatch			= 11,	// An array does not have the expected size
+	EBTBURMgrUnknownBUREvent			= 12,	// An unrecognised backup or restore event was received.
+	EBTBURMgrActiveBackupClientNull			= 13,	// A pointer to a CActiveBackupClient instance is unexpectedly NULL
+	EBTBURMgrUnsupportedRegistryVersion		= 14,	// A new version of the registry is being used locally, which is not yet supported by this implementation.
+	EBTBURMgrUnexpectedRPropertyError		= 15,	// An RProperty::Get() call returned an error that was not expected.
+	EBTBURMgrInvalidBackupRestoreState		= 16,	// The masked value from the KUidBackupRestoreKey P&S key was not in the range of the TBURPartType enum.
+	EBTBURMgrDescriptorLengthTooLong		= 17,	// A descriptor length is greater than expected.
+	EBTBURMgrDescriptorUnexpectedLength		= 18,	// A descriptor length is different to what was expected.
+	};
+
+// The name of the backup file to which the BT registry will be copied to.
+_LIT(KBTManServerBackupFileName, "btregistrydb.bak");
+// The name of the restore file from which the BT registry will be restored from.
+_LIT(KBTManServerRestoreFileName, "btregistrydb.rst");
+
+// Some data range maximum values (where predefined const values are not available elsewhere)
+const TUint8 KBTBURMgrMaxGlobalSecurityValue	= 0x1F;		// All security options on in TBTDeviceSecurity
+const TUint8 KBTBURMgrMaxPageScanMode		= 0x3;		// Optional page scan mode III
+const TUint8 KBTBURMgrMaxPageScanPeriodMode	= 0x2;		// P2
+
+void InvalidStateTransitionPanic(TBTBURState aCurrentState, TBTBUREvent aEvent);
+
+
+class MBTBURNotify
+	{
+public:
+	/**
+	Invoked by CBTManServerBURMgr to provide notification that a backup or restore
+	operation has started.
+	**/
+	virtual void BUROperationStarted()=0;
+
+	/**
+	Invoked by CBTManServerBURMgr to provide notification that a backup or restore
+	operation has stopped.
+	**/
+	virtual void BUROperationStopped()=0;
+
+	};
+
+class CBTManServer;
+class CBTLocalAddressFetcher;
+class CBTBackupHandler;
+class CBTRestoreHandler;
+class CBTActiveBackupDataClient;
+
+NONSHARABLE_CLASS(CBTManServerBURMgr) : public CActive
+	{
+public:
+	static CBTManServerBURMgr* NewL(CBTManServer& aBTManServer, MBTBURNotify* aBURNotify, TInt aPriority=EPriorityStandard);
+	~CBTManServerBURMgr();
+
+	void RequestBURNotification(MBTBURNotify* aBURNotify);
+	void SetLocalAddress(TBTDevAddr& aLocalAddr);
+	void RestoreFileReady();
+
+	// Implementation of normal state action
+	void HandleStateNormal();
+
+	// Implementation of backup state-specific actions.
+	void HandleStateBackupRequestL();
+	void HandleStateBackupRequestError();
+	void HandleStateBackupOngoingL();
+	void HandleStateBackupOngoingError();
+	void HandleStateBackupIgnore();
+	
+	// Implementation of restore state-specific actions.
+	void HandleStateRestoreRequestL();
+	void HandleStateRestoreRequestError();
+	void HandleStateRestoreOngoingL();
+	void HandleStateRestoreOngoingError();
+	void HandleStateRestoreIgnore();
+
+	// Implementation of restore file processing state-specific actions.
+	void HandleStateProcessRestoreFileL();
+	void HandleStateProcessRestoreFileError(TInt aError);
+	void HandleStateRestoreFileProcessingComplete();
+
+	inline TInt TransitionState(TBTBUREvent aBUREvent);
+
+private:
+	CBTManServerBURMgr(CBTManServer& aBTManServer, MBTBURNotify* aBURNotify, TInt aPriority);
+	void ConstructL();
+
+	TBURPartType GetBURPartType(TInt aValue);
+
+	TBool RestoreFilePresent();
+	void CheckForRestoreFileL();
+
+	void SubscribeToBackupRestoreKey();
+	void ProcessBackupState(TBURPartType aBURStateValue);	
+	TBool DoesBURAffectMeL(CActiveBackupClient& aClient);
+
+	void NotifyBUROperationStarted();
+	void NotifyBUROperationStopped();
+	void NotifyAnyBUROperationStopped();
+
+	void DeleteFile(const TDesC& fileName);
+	void DeleteBackupFile();
+	void DeleteRestoreFile();
+
+	void RenameBackupFileForRestore();
+	void UpdateLocalDeviceNameL();
+
+	// From CActive:
+	void RunL();
+	TInt RunError(TInt aError);
+	void DoCancel();
+
+private:
+	CBTManServer& iBTManServer;
+	MBTBURNotify* iBURNotify;	// Does not own this object.
+
+	TBURPartType iBURState;
+
+	CActiveBackupClient* iActiveBackupClient;
+	RProperty iProperty;
+	CBTLocalAddressFetcher* iLocalAddrFetcher;
+
+	CBTManServerBURMgrStateFactory* iStateMachine;
+
+	CBTActiveBackupDataClient* iActiveBackupDataClient;
+	
+	TBool iBUROperationStartNotified;
+
+	CBTBackupHandler* iBackupHandler;
+	CBTRestoreHandler* iRestoreHandler;
+
+	TBTDevAddr iLocalAddr;
+
+	};
+
+class CBTRegistryBURData;
+
+NONSHARABLE_CLASS(CBTBackupHandler) : public CBase
+	{
+public:
+	static CBTBackupHandler* NewL(CBTManServerBURMgr& aBURMgr, CBTRegistry& aRegistry);
+	~CBTBackupHandler();
+
+	void CreateBackupFileL();
+
+private:
+	CBTBackupHandler(CBTManServerBURMgr& aBURMgr, CBTRegistry& aRegistry);
+	void ConstructL();
+
+private:
+	CBTManServerBURMgr& iBURMgr;
+	CBTRegistry& iRegistry;
+	CBTRegistryBURData* iRegistryData;
+	};
+
+NONSHARABLE_CLASS(CBTRestoreHandler) : public CBase
+	{ 
+public:
+	static CBTRestoreHandler* NewL(CBTManServerBURMgr& aBURMgr, CBTManServer& aManServer);
+	~CBTRestoreHandler();
+
+	void RestoreLocalDeviceNameL();
+	void RestoreRemoteDeviceTableL(TBTDevAddr& aLocalAddr);
+
+private:
+	CBTRestoreHandler(CBTManServerBURMgr& aBURMgr, CBTManServer& aManServer);
+	void ConstructL();
+
+	void LoadRestoreDataL();
+
+	void NotifyLocalTableChange();
+	void NotifyRemoteTableChangeL(const TBTDevAddr& aAddress);
+
+private:
+	CBTManServerBURMgr& iBURMgr;
+	CBTManServer& iManServer;
+	CBTRegistryBURData* iRegistryData;
+
+	TBTDevAddr iBTLocalAddr;
+	};
+
+
+NONSHARABLE_CLASS(CBTRegistryBURData) : public CBase
+	{
+public:		
+	static CBTRegistryBURData* NewL();
+	~CBTRegistryBURData();
+
+	void WriteToStreamL(RWriteStream& aStream) const;
+	void ReadFromStreamL(RReadStream& aStream);
+
+	void ReadFromRegistryL(CBTRegistry& aRegistry);
+	TBool WriteLocalDeviceNameToRegistryL(CBTRegistry& aRegistry) const;
+	TBool WriteRemoteDeviceToRegistryL(CBTRegistry& aRegistry, TInt aDeviceIndex) const;
+
+	inline TBool HasRegistryData() const;
+
+	void GetRegistryVersionL(TUint32& aRegistryVersionMajor, TUint32& aRegistryVersionMinor) const;
+	TBool IsLocalAddressNonZeroL() const;
+	TBool IsLocalAddressEqualL(TBTDevAddr& aAddr) const;
+	TInt CountRemoteDevicesL() const;
+	const CBTDevice& GetRemoteDeviceL(TInt aDeviceIndex) const;
+	TSecureId GetRemoteDeviceEntrySidL(TInt aDeviceIndex) const;
+	
+	void ClearRegistryData();
+
+private:
+	CBTRegistryBURData();
+	void ConstructL();
+
+	const TDesC8& GetLocalDeviceNameL() const;
+
+private:
+	TBool iHasRegistryData;
+
+	// Meta table:
+	TUint32 iRegistryVersionMajor;
+	TUint32 iRegistryVersionMinor;
+
+	// Persistence table
+	TBTLocalDevice* iLocalDevice;
+
+	// Remote device table:
+	CArrayFixFlat<TSecureId>* iRemoteDevicesSid;
+	CBTDeviceArray* iRemoteDevices;
+
+	};
+
+NONSHARABLE_CLASS(CBTLocalAddressFetcher) : public CActive
+	{
+public:
+	// High priority to ensure this AO fires before a client request to BTManServer
+	static CBTLocalAddressFetcher* NewL(CBTManServerBURMgr& aBURMgr, CBTRegistry& aRegistry, TInt aPriority=EPriorityHigh);
+	~CBTLocalAddressFetcher();
+
+	void FetchLocalAddress();
+
+
+private:
+	CBTLocalAddressFetcher(CBTManServerBURMgr& aBURMgr, CBTRegistry& aRegistry, TInt aPriority);
+	void ConstructL();
+	
+	void SubscribeToGetLocalDeviceAddressKey();
+	TBTDevAddr GetLocalAddressFromRegistryL();
+
+	// From CActive
+	void RunL();
+	void DoCancel();
+private:
+	CBTManServerBURMgr& iBURMgr;
+	CBTRegistry& iRegistry;
+	RProperty iProperty;
+
+	};
+
+NONSHARABLE_CLASS(CBTActiveBackupDataClient) : public CBase, public MActiveBackupDataClient
+	{
+public:
+	static CBTActiveBackupDataClient* NewL(CBTManServerBURMgr& aBURMgr);
+	~CBTActiveBackupDataClient();
+
+	// Backup methods (not used)
+	virtual void AllSnapshotsSuppliedL();
+	virtual void ReceiveSnapshotDataL(TDriveNumber aDrive, TDesC8& aBuffer, TBool aLastSection);
+	virtual TUint GetExpectedDataSize(TDriveNumber aDrive);
+	virtual void GetSnapshotDataL(TDriveNumber aDrive, TPtr8& aBuffer, TBool& aFinished);
+	virtual void InitialiseGetBackupDataL(TDriveNumber aDrive);
+	virtual void GetBackupDataSectionL(TPtr8& aBuffer, TBool& aFinished);
+
+	// Restore methods (only the notification method RestoreComplete() is used)
+	virtual void InitialiseRestoreBaseDataL(TDriveNumber aDrive);
+	virtual void RestoreBaseDataSectionL(TDesC8& aBuffer, TBool aFinished);
+	virtual void InitialiseRestoreIncrementDataL(TDriveNumber aDrive);
+	virtual void RestoreIncrementDataSectionL(TDesC8& aBuffer, TBool aFinished);
+	virtual void RestoreComplete(TDriveNumber aDrive);
+
+	// General methods
+	virtual void TerminateMultiStageOperation();
+
+	// Test methods
+	virtual TUint GetDataChecksum(TDriveNumber aDrive);
+	
+private:
+	CBTActiveBackupDataClient(CBTManServerBURMgr& aBURMgr);
+
+private:
+	CBTManServerBURMgr& iBURMgr;
+
+	};
+
+#include "btmanserverburmgr.inl"
+
+#endif //BTMANSERVERBURMGR_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothmgmt/btmgr/BTManServer/btmanserverburmgr.inl	Fri Apr 16 16:09:25 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Implements backup and restore support for the Bluetooth Manager server.
+//
+
+
+inline TInt CBTManServerBURMgr::TransitionState(TBTBUREvent aBUREvent)
+	{
+	return iStateMachine->TransitionState(aBUREvent);
+	}
+
+inline TBool CBTRegistryBURData::HasRegistryData() const
+	{
+	return iHasRegistryData;
+	}
+
+inline TBTBURState CBTManServerBURMgrStateFactory::GetCurrentState()
+	{
+	return iState;
+	}
+
+inline TBTBURState CBTManServerBURMgrStateAction::GetThisState()
+	{
+	return iState;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothmgmt/btmgr/BTManServer/btmanserverburstatemachine.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -0,0 +1,682 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Implements the state machine which drives backup and restore support for the 
+// Bluetooth Manager server.
+//
+
+#include <e32std.h>
+#include <e32base.h>
+#include "btmanserverburmgr.h"
+
+#include <bluetooth/logger.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_BT_MANAGER_SERVER);
+#endif
+
+/**
+CBTManServerBURMgrStateFactory - Manages the state machine that drives CBTManServerBURMgr
+**/
+
+CBTManServerBURMgrStateFactory* CBTManServerBURMgrStateFactory::NewL(CBTManServerBURMgr& aBURMgr)
+	{
+	LOG_STATIC_FUNC
+
+	CBTManServerBURMgrStateFactory* result = new (ELeave) CBTManServerBURMgrStateFactory(aBURMgr);
+	CleanupStack::PushL(result);
+	result->ConstructL();
+	CleanupStack::Pop(result);
+	return result;
+	}
+
+CBTManServerBURMgrStateFactory::CBTManServerBURMgrStateFactory(CBTManServerBURMgr& aBURMgr) 
+	: iBURMgr(aBURMgr), 
+	iState(EBTBURStateNormal)
+	{
+	LOG_FUNC
+	}
+
+CBTManServerBURMgrStateFactory::~CBTManServerBURMgrStateFactory()
+	{
+	LOG_FUNC
+
+	// Destroy state machine
+	iStateActions.ResetAndDestroy();
+	}
+
+void CBTManServerBURMgrStateFactory::ConstructL()
+	{
+	LOG_FUNC
+
+	ConstructStateMachineL();
+	}
+
+void CBTManServerBURMgrStateFactory::ConstructStateMachineL()
+	{
+	LOG_FUNC
+
+	// Construct the state instances - each state knows how to carry out its action and its possible transitions
+	// Note that the ordering here is critical - it must reflect the ordering of the enums in TBTBURState
+	for (TInt i = EBTBURStateNormal; i < EBTBURStateUnknown; i++)
+		{
+		CBTManServerBURMgrStateAction* nextState = ConstructStateLC(static_cast<TBTBURState>(i));
+		iStateActions.AppendL(nextState);
+		CleanupStack::Pop(nextState);
+		}
+	}
+
+CBTManServerBURMgrStateAction* CBTManServerBURMgrStateFactory::ConstructStateLC(TBTBURState aState)
+	{
+	LOG_FUNC
+
+	CBTManServerBURMgrStateAction* result = NULL;
+
+	switch (aState)
+		{
+	case EBTBURStateNormal:
+		result = CBTManServerBURMgrStateNormal::NewLC();
+		break;
+	case EBTBURStateBackupRequest:
+		result = CBTManServerBURMgrStateBackupRequest::NewLC();
+		break;
+	case EBTBURStateBackupOngoing:
+		result = CBTManServerBURMgrStateBackupOngoing::NewLC();
+		break;
+	case EBTBURStateBackupIgnore:
+		result = CBTManServerBURMgrStateBackupIgnore::NewLC();
+		break;
+	case EBTBURStateRestoreRequest:
+		result = CBTManServerBURMgrStateRestoreRequest::NewLC();
+		break;
+	case EBTBURStateRestoreOngoing:
+		result = CBTManServerBURMgrStateRestoreOngoing::NewLC();
+		break;
+	case EBTBURStateRestoreIgnore:
+		result = CBTManServerBURMgrStateRestoreIgnore::NewLC();
+		break;
+	case EBTBURStateProcessRestoreFile:
+		result = CBTManServerBURMgrStateProcessRestoreFile::NewLC();
+		break;
+	case EBTBURStateRestoreFileProcessingComplete:
+		result = CBTManServerBURMgrStateRestoreFileProcessingComplete::NewLC();
+		break;
+	default:
+		// EBTBURStateUnknown
+		__ASSERT_DEBUG(EFalse, PANIC(KBTBackupPanicCat, EBTBURMgrInvalidStateIndex));
+		User::Leave(KErrNotFound);
+		}
+
+	return result;
+	}
+
+/**
+Attempts to transition to a new state in the state machine, in response to a given event.
+This only succeeds if the event yields a valid transition from the current state.
+The transition event EBTBUREventAbortStateAction yields a valid transition for any state, 
+and this is tested for here.
+Upon successful transition, the action associated with the new state is executed.
+An invalid state transition in debug mode will result in a panic. In release mode, the current
+state is maintained.
+@param aTransitionEvent The event driving the state transition.
+@return	KErrNone if state transition is successful.
+	KErrNotFound if aTransitionEvent does not yield a valid transition for the current state.
+**/
+TInt CBTManServerBURMgrStateFactory::TransitionState(TBTBUREvent aTransitionEvent)
+	{
+	LOG_FUNC
+
+	TBTBURState nextState;
+
+	// We allow EBTBUREventAbortStateAction to transition any state back to normal (used for error handling)
+	if (aTransitionEvent == EBTBUREventAbortStateAction)
+		{
+		nextState = EBTBURStateNormal;
+		}
+	else
+		{
+		nextState = iStateActions[iState]->GetNextState(aTransitionEvent);
+		}
+	
+	// A request to process a restore file may come in at any time, and we may not be in a correct state to deal with it.
+	// This scenario is not an error, instead the request is simply ignored (as state transition is disallowed) and will be picked up
+	// when BTManServer next starts.
+	__ASSERT_DEBUG(nextState != EBTBURStateUnknown || aTransitionEvent == EBTBUREventProcessRestoreFile, InvalidStateTransitionPanic(iState, aTransitionEvent));
+
+	if (nextState == EBTBURStateUnknown)
+		{
+		// Invalid transition
+		return KErrNotFound;
+		}
+	else
+		{
+		// Make the transition and execute new state action.
+		iState = nextState;
+		ExecuteAction();
+
+		return KErrNone;
+		}
+	}
+
+/**
+Executes the action associated with the current state.
+The implementation of the action is given by CBTManServerBURMgrStateAction::ExecuteActionL().
+Error handling is provided by CBTManServerBURMgrStateAction::HandleActionError().
+**/
+void CBTManServerBURMgrStateFactory::ExecuteAction()
+	{
+	LOG_FUNC
+
+	TRAPD(err, iStateActions[iState]->ExecuteActionL(iBURMgr));
+	if (err != KErrNone)
+		{
+		iStateActions[iState]->HandleActionError(iBURMgr, err);
+		}
+	}
+
+/**
+CBTManServerBURMgrStateAction - Base class for action/transition handling for states of CBTManServerBURMgr
+**/
+
+CBTManServerBURMgrStateAction::CBTManServerBURMgrStateAction(TBTBURState aState) 
+	: iState(aState)
+	{
+	LOG_FUNC
+	}
+
+CBTManServerBURMgrStateAction::~CBTManServerBURMgrStateAction()
+	{
+	LOG_FUNC
+	}
+
+/**
+Handles a leave generated by ExecuteActionL().
+The default implementation is to do nothing. This accomodates states whose implementation of ExecuteActionL()
+is guaranteed not to leave.
+If a leave does occur, the state must either recover from the error in some way (allowing the state machine to 
+remain in its current state) or initiate a transition back to the normal state using the EBTBUREventAbortStateAction
+transition event (after any necessary cleanup has been performed).
+@param aBURMgr The CBTManServerBURMgr instance
+@param aError The error which generated the leave in ExecuteActionL()
+**/
+void CBTManServerBURMgrStateAction::HandleActionError(CBTManServerBURMgr& /*aBURMgr*/, TInt /*aError*/)
+	{
+	LOG_FUNC
+
+	// Do nothing by default (state may not have a leavable action)
+	}
+
+/**
+CBTManServerBURMgrStateNormal - Action/transition handling for EBTBURStateNormal state of CBTManServerBURMgr
+**/
+
+CBTManServerBURMgrStateNormal* CBTManServerBURMgrStateNormal::NewLC()
+	{
+	LOG_STATIC_FUNC
+
+	CBTManServerBURMgrStateNormal* result = new(ELeave) CBTManServerBURMgrStateNormal();
+	CleanupStack::PushL(result);
+	return result;
+	}
+
+CBTManServerBURMgrStateNormal::CBTManServerBURMgrStateNormal() 
+	: CBTManServerBURMgrStateAction(EBTBURStateNormal)
+	{
+	LOG_FUNC
+	}		
+
+CBTManServerBURMgrStateNormal::~CBTManServerBURMgrStateNormal()
+	{
+	LOG_FUNC
+	}
+
+TBTBURState CBTManServerBURMgrStateNormal::GetNextState(TBTBUREvent aTransitionEvent)
+	{
+	LOG_FUNC
+
+	// Valid transition events: EBTBUREventBackup, EBTBUREventRestore, EBTBUREventProcessRestoreFile, EBTBUREventUnset, EBTBUREventNormal
+	switch (aTransitionEvent)
+		{
+	case EBTBUREventBackup:
+		return EBTBURStateBackupRequest;
+	case EBTBUREventRestore:
+		return EBTBURStateRestoreRequest;
+	case EBTBUREventProcessRestoreFile:
+		return EBTBURStateProcessRestoreFile;
+	case EBTBUREventUnset:
+		// Fall-through
+	case EBTBUREventNormal:
+		return EBTBURStateNormal;
+	default:
+		// Unknown state (no valid transition)
+		return EBTBURStateUnknown;
+		}
+	}
+
+void CBTManServerBURMgrStateNormal::ExecuteActionL(CBTManServerBURMgr& aBURMgr)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateNormal();
+	}
+
+/**
+CBTManServerBURMgrStateBackupRequest - Action/transition handling for EBTBURStateBackupRequest state of CBTManServerBURMgr
+**/
+
+CBTManServerBURMgrStateBackupRequest* CBTManServerBURMgrStateBackupRequest::NewLC()
+	{
+	LOG_STATIC_FUNC
+
+	CBTManServerBURMgrStateBackupRequest* result = new(ELeave) CBTManServerBURMgrStateBackupRequest();
+	CleanupStack::PushL(result);
+	return result;
+	}
+
+CBTManServerBURMgrStateBackupRequest::CBTManServerBURMgrStateBackupRequest() 
+	: CBTManServerBURMgrStateAction(EBTBURStateBackupRequest)
+	{
+	LOG_FUNC
+	}		
+
+CBTManServerBURMgrStateBackupRequest::~CBTManServerBURMgrStateBackupRequest()
+	{
+	LOG_FUNC
+	}
+
+TBTBURState CBTManServerBURMgrStateBackupRequest::GetNextState(TBTBUREvent aTransitionEvent)
+	{
+	LOG_FUNC
+	
+	// Valid transition events: EBTBUREventBackupProceed, EBTBUREventBackupReject
+	switch (aTransitionEvent)
+		{
+	case EBTBUREventBackupProceed:
+		return EBTBURStateBackupOngoing;
+	case EBTBUREventBackupReject:
+		return EBTBURStateBackupIgnore;
+	default:
+		// Unknown state (no valid transition)
+		return EBTBURStateUnknown;
+		}
+	}
+
+void CBTManServerBURMgrStateBackupRequest::ExecuteActionL(CBTManServerBURMgr& aBURMgr)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateBackupRequestL();
+	}
+
+void CBTManServerBURMgrStateBackupRequest::HandleActionError(CBTManServerBURMgr& aBURMgr, TInt /*aError*/)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateBackupRequestError();
+	}
+
+/**
+CBTManServerBURMgrStateBackupOngoing - Action/transition handling for EBTBURStateBackupOngoing state of CBTManServerBURMgr
+**/
+
+CBTManServerBURMgrStateBackupOngoing* CBTManServerBURMgrStateBackupOngoing::NewLC()
+	{
+	LOG_STATIC_FUNC
+
+	CBTManServerBURMgrStateBackupOngoing* result = new(ELeave) CBTManServerBURMgrStateBackupOngoing();
+	CleanupStack::PushL(result);
+	return result;
+	}
+
+CBTManServerBURMgrStateBackupOngoing::CBTManServerBURMgrStateBackupOngoing() 
+	: CBTManServerBURMgrStateAction(EBTBURStateBackupOngoing)
+	{
+	LOG_FUNC
+	}		
+
+CBTManServerBURMgrStateBackupOngoing::~CBTManServerBURMgrStateBackupOngoing()
+	{
+	LOG_FUNC
+	}
+
+TBTBURState CBTManServerBURMgrStateBackupOngoing::GetNextState(TBTBUREvent aTransitionEvent)
+	{
+	LOG_FUNC
+	
+	// Valid transition events: EBTBUREventNormal
+	if (aTransitionEvent == EBTBUREventNormal)
+		{
+		return EBTBURStateNormal;
+		}
+	else
+		{
+		// Unknown state (no valid transition)
+		return EBTBURStateUnknown;
+		}
+	}
+
+void CBTManServerBURMgrStateBackupOngoing::ExecuteActionL(CBTManServerBURMgr& aBURMgr)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateBackupOngoingL();
+	}
+
+void CBTManServerBURMgrStateBackupOngoing::HandleActionError(CBTManServerBURMgr& aBURMgr, TInt /*aError*/)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateBackupOngoingError();
+	}	
+
+/**
+CBTManServerBURMgrStateBackupIgnore - Action/transition handling for EBTBURStateBackupIgnore state of CBTManServerBURMgr
+**/
+
+CBTManServerBURMgrStateBackupIgnore* CBTManServerBURMgrStateBackupIgnore::NewLC()
+	{
+	LOG_STATIC_FUNC
+
+	CBTManServerBURMgrStateBackupIgnore* result = new(ELeave) CBTManServerBURMgrStateBackupIgnore();
+	CleanupStack::PushL(result);
+	return result;
+	}
+
+CBTManServerBURMgrStateBackupIgnore::CBTManServerBURMgrStateBackupIgnore() 
+	: CBTManServerBURMgrStateAction(EBTBURStateBackupIgnore)
+	{
+	LOG_FUNC
+	}		
+
+CBTManServerBURMgrStateBackupIgnore::~CBTManServerBURMgrStateBackupIgnore()
+	{
+	LOG_FUNC
+	}
+
+TBTBURState CBTManServerBURMgrStateBackupIgnore::GetNextState(TBTBUREvent aTransitionEvent)
+	{
+	LOG_FUNC
+	
+	// Valid transition events: EBTBUREventNormal
+	if (aTransitionEvent == EBTBUREventNormal)
+		{
+		return EBTBURStateNormal;
+		}
+	else
+		{
+		// Unknown state (no valid transition)
+		return EBTBURStateUnknown;
+		}
+	}
+
+void CBTManServerBURMgrStateBackupIgnore::ExecuteActionL(CBTManServerBURMgr& aBURMgr)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateBackupIgnore();
+	}
+
+/**
+CBTManServerBURMgrStateRestoreRequest - Action/transition handling for EBTBURStateRestoreRequest state of CBTManServerBURMgr
+**/
+
+CBTManServerBURMgrStateRestoreRequest* CBTManServerBURMgrStateRestoreRequest::NewLC()
+	{
+	LOG_STATIC_FUNC
+
+	CBTManServerBURMgrStateRestoreRequest* result = new(ELeave) CBTManServerBURMgrStateRestoreRequest();
+	CleanupStack::PushL(result);
+	return result;
+	}
+
+CBTManServerBURMgrStateRestoreRequest::CBTManServerBURMgrStateRestoreRequest() 
+	: CBTManServerBURMgrStateAction(EBTBURStateRestoreRequest)
+	{
+	LOG_FUNC
+	}		
+
+CBTManServerBURMgrStateRestoreRequest::~CBTManServerBURMgrStateRestoreRequest()
+	{
+	LOG_FUNC
+	}
+
+TBTBURState CBTManServerBURMgrStateRestoreRequest::GetNextState(TBTBUREvent aTransitionEvent)
+	{
+	LOG_FUNC
+	
+	// Valid transition events: EBTBUREventRestoreProceed, EBTBUREventRestoreReject
+	switch (aTransitionEvent)
+		{
+	case EBTBUREventRestoreProceed:
+		return EBTBURStateRestoreOngoing;
+	case EBTBUREventRestoreReject:
+		return EBTBURStateRestoreIgnore;
+	default:
+		// Unknown state (no valid transition)
+		return EBTBURStateUnknown;
+		}
+	}
+
+void CBTManServerBURMgrStateRestoreRequest::ExecuteActionL(CBTManServerBURMgr& aBURMgr)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateRestoreRequestL();
+	}
+
+void CBTManServerBURMgrStateRestoreRequest::HandleActionError(CBTManServerBURMgr& aBURMgr, TInt /*aError*/)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateRestoreRequestError();
+	}
+
+/**
+CBTManServerBURMgrStateRestoreOngoing - Action/transition handling for EBTBURStateRestoreOngoing state of CBTManServerBURMgr
+**/
+
+CBTManServerBURMgrStateRestoreOngoing* CBTManServerBURMgrStateRestoreOngoing::NewLC()
+	{
+	LOG_STATIC_FUNC
+
+	CBTManServerBURMgrStateRestoreOngoing* result = new(ELeave) CBTManServerBURMgrStateRestoreOngoing();
+	CleanupStack::PushL(result);
+	return result;
+	}
+
+CBTManServerBURMgrStateRestoreOngoing::CBTManServerBURMgrStateRestoreOngoing() 
+	: CBTManServerBURMgrStateAction(EBTBURStateRestoreOngoing)
+	{
+	LOG_FUNC
+	}		
+
+CBTManServerBURMgrStateRestoreOngoing::~CBTManServerBURMgrStateRestoreOngoing()
+	{
+	LOG_FUNC
+	}
+
+TBTBURState CBTManServerBURMgrStateRestoreOngoing::GetNextState(TBTBUREvent aTransitionEvent)
+	{
+	LOG_FUNC
+
+	// Valid transition events: EBTBUREventNormal
+	if (aTransitionEvent == EBTBUREventNormal)
+		{
+		return EBTBURStateNormal;
+		}
+	else
+		{
+		// Unknown state (no valid transition)
+		return EBTBURStateUnknown;
+		}
+	}
+
+void CBTManServerBURMgrStateRestoreOngoing::ExecuteActionL(CBTManServerBURMgr& aBURMgr)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateRestoreOngoingL();
+	}
+
+void CBTManServerBURMgrStateRestoreOngoing::HandleActionError(CBTManServerBURMgr& aBURMgr, TInt /*aError*/)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateRestoreOngoingError();
+	}
+
+/**
+CBTManServerBURMgrStateRestoreIgnore - Action/transition handling for EBTBURStateRestoreIgnore state of CBTManServerBURMgr
+**/
+
+CBTManServerBURMgrStateRestoreIgnore* CBTManServerBURMgrStateRestoreIgnore::NewLC()
+	{
+	LOG_STATIC_FUNC
+
+	CBTManServerBURMgrStateRestoreIgnore* result = new(ELeave) CBTManServerBURMgrStateRestoreIgnore();
+	CleanupStack::PushL(result);
+	return result;
+	}
+
+CBTManServerBURMgrStateRestoreIgnore::CBTManServerBURMgrStateRestoreIgnore() 
+	: CBTManServerBURMgrStateAction(EBTBURStateRestoreIgnore)
+	{
+	LOG_FUNC
+	}		
+
+CBTManServerBURMgrStateRestoreIgnore::~CBTManServerBURMgrStateRestoreIgnore()
+	{
+	LOG_FUNC
+	}
+
+TBTBURState CBTManServerBURMgrStateRestoreIgnore::GetNextState(TBTBUREvent aTransitionEvent)
+	{
+	LOG_FUNC
+	
+	// Valid transition events: EBTBUREventNormal
+	if (aTransitionEvent==EBTBUREventNormal)
+		{
+		return EBTBURStateNormal;
+		}
+	else
+		{
+		// Unknown state (no valid transition)
+		return EBTBURStateUnknown;
+		}
+	}
+
+void CBTManServerBURMgrStateRestoreIgnore::ExecuteActionL(CBTManServerBURMgr& aBURMgr)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateRestoreIgnore();
+	}
+
+/**
+CBTManServerBURMgrStateProcessRestoreFile - Action/transition handling for EBTBURStateProcessRestoreFile state of CBTManServerBURMgr
+**/
+
+CBTManServerBURMgrStateProcessRestoreFile* CBTManServerBURMgrStateProcessRestoreFile::NewLC()
+	{
+	LOG_STATIC_FUNC
+
+	CBTManServerBURMgrStateProcessRestoreFile* result = new(ELeave) CBTManServerBURMgrStateProcessRestoreFile();
+	CleanupStack::PushL(result);
+	return result;
+	}
+
+CBTManServerBURMgrStateProcessRestoreFile::CBTManServerBURMgrStateProcessRestoreFile() 
+	: CBTManServerBURMgrStateAction(EBTBURStateProcessRestoreFile)
+	{
+	LOG_FUNC
+	}		
+
+CBTManServerBURMgrStateProcessRestoreFile::~CBTManServerBURMgrStateProcessRestoreFile()
+	{
+	LOG_FUNC
+	}
+
+TBTBURState CBTManServerBURMgrStateProcessRestoreFile::GetNextState(TBTBUREvent aTransitionEvent)
+	{
+	LOG_FUNC
+	
+	// Valid transition event: EBTBUREventProcessRestoreFileComplete
+	switch (aTransitionEvent)
+		{
+	case EBTBUREventProcessRestoreFileComplete:
+		return EBTBURStateRestoreFileProcessingComplete;
+	default:
+		// Unknown state (no valid transition)
+		return EBTBURStateUnknown;
+		}
+	}
+
+void CBTManServerBURMgrStateProcessRestoreFile::ExecuteActionL(CBTManServerBURMgr& aBURMgr)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateProcessRestoreFileL();
+	}
+
+void CBTManServerBURMgrStateProcessRestoreFile::HandleActionError(CBTManServerBURMgr& aBURMgr, TInt aError)
+	{
+	LOG_FUNC
+
+	aBURMgr.HandleStateProcessRestoreFileError(aError);
+	}
+
+/**
+CBTManServerBURMgrStateRestoreFileProcessingComplete - Action/transition handling for EBTBURStateRestoreFileProcessingComplete state of CBTManServerBURMgr
+**/
+
+CBTManServerBURMgrStateRestoreFileProcessingComplete* CBTManServerBURMgrStateRestoreFileProcessingComplete::NewLC()
+	{
+	LOG_STATIC_FUNC
+
+	CBTManServerBURMgrStateRestoreFileProcessingComplete* result = new(ELeave) CBTManServerBURMgrStateRestoreFileProcessingComplete();
+	CleanupStack::PushL(result);
+	return result;
+	}
+
+CBTManServerBURMgrStateRestoreFileProcessingComplete::CBTManServerBURMgrStateRestoreFileProcessingComplete() 
+	: CBTManServerBURMgrStateAction(EBTBURStateRestoreFileProcessingComplete)
+	{
+	LOG_FUNC
+	}		
+
+CBTManServerBURMgrStateRestoreFileProcessingComplete::~CBTManServerBURMgrStateRestoreFileProcessingComplete()
+	{
+	LOG_FUNC
+	}
+
+TBTBURState CBTManServerBURMgrStateRestoreFileProcessingComplete::GetNextState(TBTBUREvent aTransitionEvent)
+	{
+	LOG_FUNC
+	
+	// Valid transition events: EBTBUREventRestoreFileTransitionNormal
+	if (aTransitionEvent == EBTBUREventRestoreFileTransitionNormal)
+		{
+		return EBTBURStateNormal;
+		}
+	else
+		{
+		// Unknown state (no valid transition)
+		return EBTBURStateUnknown;
+		}
+	}
+
+void CBTManServerBURMgrStateRestoreFileProcessingComplete::ExecuteActionL(CBTManServerBURMgr& aBURMgr)
+	{
+	LOG_FUNC
+	aBURMgr.HandleStateRestoreFileProcessingComplete();
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothmgmt/btmgr/BTManServer/btmanserverburstatemachine.h	Fri Apr 16 16:09:25 2010 +0300
@@ -0,0 +1,267 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Implements the state machine which drives backup and restore support for the 
+// Bluetooth Manager server.
+//
+
+/**
+ @file
+ @internalAll
+*/
+
+#ifndef BTMANSERVERBURSTATEMACHINE_H
+#define BTMANSERVERBURSTATEMACHINE_H
+
+/**
+TBTBURState - records the state of the BUR manager.
+**/
+enum TBTBURState
+	{
+	EBTBURStateNormal,			// Waiting for a BUR event
+
+	EBTBURStateBackupRequest,		// Processing a backup request
+	EBTBURStateBackupOngoing, 		// Taking part in a backup operation
+	EBTBURStateBackupIgnore,		// Not taking part in a backup operation (e.g. operation may not affect us)
+
+	EBTBURStateRestoreRequest,		// Processing a restore request
+	EBTBURStateRestoreOngoing, 		// Taking part in a restore operation
+	EBTBURStateRestoreIgnore,		// Not taking part in a restore operation (e.g. operation may not affect us)
+
+	EBTBURStateProcessRestoreFile,		// Processing an available restore file.
+	EBTBURStateRestoreFileProcessingComplete,	// Processing of restore file has completed and registry has been updated
+	
+	EBTBURStateUnknown,			// Used to indicate an invalid transition
+	};
+
+/**
+TBTBUREvent - Events which can cause transitions in the state of the BUR manager
+**/
+enum TBTBUREvent
+	{
+	// Events relating to P&S key changes from BUR engine
+	EBTBUREventUnset,			// Unset notification event received from the Secure Backup Engine
+	EBTBUREventNormal,			// Normal mode notification event received from the Secure Backup Engine
+	EBTBUREventBackup,			// Backup notification event received from the Secure Backup Engine
+	EBTBUREventRestore,			// Restore notification event received from the Secure Backup Engine
+
+	// Internally generated events
+	EBTBUREventBackupProceed,		// BUR manager should proceed with backup operation
+	EBTBUREventBackupReject,		// BUR manager should not proceed with backup operation
+	EBTBUREventRestoreProceed,		// BUR manager should proceed with restore operation
+	EBTBUREventRestoreReject,		// BUR manager should not proceed with restore operation
+	EBTBUREventProcessRestoreFile,		// Request to process an available restore file
+	EBTBUREventProcessRestoreFileComplete,	// Parsing of restore file has completed
+	EBTBUREventRestoreFileTransitionNormal,	// Parsing of restore file has been completed, transition should be made to normal state.
+
+	EBTBUREventAbortStateAction,		// A state action has encountered an error which requires an abort back to normal state.
+	};
+
+/**
+State handling mechanisms - these classes support the state machine used by the BUR manager.
+**/
+
+class CBTManServerBURMgr;
+class CBTManServerBURMgrStateAction;
+
+NONSHARABLE_CLASS(CBTManServerBURMgrStateFactory) : public CBase
+	{
+public:
+	static CBTManServerBURMgrStateFactory* NewL(CBTManServerBURMgr& aBURMgr);
+	~CBTManServerBURMgrStateFactory();
+
+	inline TBTBURState GetCurrentState();
+	TInt TransitionState(TBTBUREvent aTransitionEvent);
+	void ExecuteAction();
+
+private:
+	CBTManServerBURMgrStateFactory(CBTManServerBURMgr& aBURMgr);
+	void ConstructL();
+
+	void ConstructStateMachineL();
+	CBTManServerBURMgrStateAction* ConstructStateLC(TBTBURState aState);
+
+private:
+	RPointerArray<CBTManServerBURMgrStateAction> iStateActions;
+	CBTManServerBURMgr& iBURMgr;
+	TBTBURState iState;
+
+	};
+
+NONSHARABLE_CLASS(CBTManServerBURMgrStateAction) : public CBase
+	{
+public:
+	~CBTManServerBURMgrStateAction();
+
+	inline TBTBURState GetThisState();
+	virtual TBTBURState GetNextState(TBTBUREvent aTransitionEvent)=0;
+	virtual void ExecuteActionL(CBTManServerBURMgr& aBURMgr)=0;
+	virtual void HandleActionError(CBTManServerBURMgr& aBURMgr, TInt aError);
+
+protected:
+	CBTManServerBURMgrStateAction(TBTBURState aState);
+
+protected:
+	TBTBURState iState;
+
+	};
+
+/**
+Normal state
+**/
+
+NONSHARABLE_CLASS(CBTManServerBURMgrStateNormal) : public CBTManServerBURMgrStateAction
+	{
+public:
+	static CBTManServerBURMgrStateNormal* NewLC();
+	~CBTManServerBURMgrStateNormal();
+
+	virtual TBTBURState GetNextState(TBTBUREvent aTransitionEvent);
+	virtual void ExecuteActionL(CBTManServerBURMgr& aBURMgr);
+
+protected:
+	CBTManServerBURMgrStateNormal();
+
+	};
+
+/**
+Backup states
+**/
+
+NONSHARABLE_CLASS(CBTManServerBURMgrStateBackupRequest) : public CBTManServerBURMgrStateAction
+	{
+public:
+	static CBTManServerBURMgrStateBackupRequest* NewLC();
+	~CBTManServerBURMgrStateBackupRequest();
+
+	virtual TBTBURState GetNextState(TBTBUREvent aTransitionEvent);
+	virtual void ExecuteActionL(CBTManServerBURMgr& aBURMgr);
+	virtual void HandleActionError(CBTManServerBURMgr& aBURMgr, TInt aError);
+
+protected:
+	CBTManServerBURMgrStateBackupRequest();
+
+	};
+
+NONSHARABLE_CLASS(CBTManServerBURMgrStateBackupOngoing) : public CBTManServerBURMgrStateAction
+	{
+public:
+	static CBTManServerBURMgrStateBackupOngoing* NewLC();
+	~CBTManServerBURMgrStateBackupOngoing();
+
+	virtual TBTBURState GetNextState(TBTBUREvent aTransitionEvent);
+	virtual void ExecuteActionL(CBTManServerBURMgr& aBURMgr);
+	virtual void HandleActionError(CBTManServerBURMgr& aBURMgr, TInt aError);
+
+protected:
+	CBTManServerBURMgrStateBackupOngoing();
+
+	};
+
+
+NONSHARABLE_CLASS(CBTManServerBURMgrStateBackupIgnore) : public CBTManServerBURMgrStateAction
+	{
+public:
+	static CBTManServerBURMgrStateBackupIgnore* NewLC();
+	~CBTManServerBURMgrStateBackupIgnore();
+
+	virtual TBTBURState GetNextState(TBTBUREvent aTransitionEvent);
+	virtual void ExecuteActionL(CBTManServerBURMgr& aBURMgr);
+
+protected:
+	CBTManServerBURMgrStateBackupIgnore();
+
+	};
+
+/**
+Restore states
+**/
+
+NONSHARABLE_CLASS(CBTManServerBURMgrStateRestoreRequest) : public CBTManServerBURMgrStateAction
+	{
+public:
+	static CBTManServerBURMgrStateRestoreRequest* NewLC();
+	~CBTManServerBURMgrStateRestoreRequest();
+
+	virtual TBTBURState GetNextState(TBTBUREvent aTransitionEvent);
+	virtual void ExecuteActionL(CBTManServerBURMgr& aBURMgr);
+	virtual void HandleActionError(CBTManServerBURMgr& aBURMgr, TInt aError);
+
+protected:
+	CBTManServerBURMgrStateRestoreRequest();
+
+	};
+
+NONSHARABLE_CLASS(CBTManServerBURMgrStateRestoreOngoing) : public CBTManServerBURMgrStateAction
+	{
+public:
+	static CBTManServerBURMgrStateRestoreOngoing* NewLC();
+	~CBTManServerBURMgrStateRestoreOngoing();
+
+	virtual TBTBURState GetNextState(TBTBUREvent aTransitionEvent);
+	virtual void ExecuteActionL(CBTManServerBURMgr& aBURMgr);
+	virtual void HandleActionError(CBTManServerBURMgr& aBURMgr, TInt aError);
+
+protected:
+	CBTManServerBURMgrStateRestoreOngoing();
+
+	};
+
+NONSHARABLE_CLASS(CBTManServerBURMgrStateRestoreIgnore) : public CBTManServerBURMgrStateAction
+	{
+public:
+	static CBTManServerBURMgrStateRestoreIgnore* NewLC();
+	~CBTManServerBURMgrStateRestoreIgnore();
+
+	virtual TBTBURState GetNextState(TBTBUREvent aTransitionEvent);
+	virtual void ExecuteActionL(CBTManServerBURMgr& aBURMgr);
+
+protected:
+	CBTManServerBURMgrStateRestoreIgnore();
+
+	};
+
+/**
+Restore file processing states
+**/
+
+NONSHARABLE_CLASS(CBTManServerBURMgrStateProcessRestoreFile) : public CBTManServerBURMgrStateAction
+	{
+public:
+	static CBTManServerBURMgrStateProcessRestoreFile* NewLC();
+	~CBTManServerBURMgrStateProcessRestoreFile();
+
+	virtual TBTBURState GetNextState(TBTBUREvent aTransitionEvent);
+	virtual void ExecuteActionL(CBTManServerBURMgr& aBURMgr);
+	virtual void HandleActionError(CBTManServerBURMgr& aBURMgr, TInt aError);
+
+protected:
+	CBTManServerBURMgrStateProcessRestoreFile();
+
+	};
+
+NONSHARABLE_CLASS(CBTManServerBURMgrStateRestoreFileProcessingComplete) : public CBTManServerBURMgrStateAction
+	{
+public:
+	static CBTManServerBURMgrStateRestoreFileProcessingComplete* NewLC();
+	~CBTManServerBURMgrStateRestoreFileProcessingComplete();
+
+	virtual TBTBURState GetNextState(TBTBUREvent aTransitionEvent);
+	virtual void ExecuteActionL(CBTManServerBURMgr& aBURMgr);
+
+protected:
+	CBTManServerBURMgrStateRestoreFileProcessingComplete();
+
+	};
+
+#endif // BTMANSERVERBURSTATEMACHINE_H
--- a/bluetoothmgmt/btmgr/Inc/BTManServer.h	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothmgmt/btmgr/Inc/BTManServer.h	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -24,6 +24,7 @@
 #include <bt_subscribe.h>
 #include "BTRegistryDB.h"
 #include "btmanclientserver.h"
+#include "btmanserverburmgr.h"
 
 #if KMaxBluetoothNameLen > KMaxFriendlyNameLen
 #define KLongestName KMaxBluetoothNameLen
@@ -105,13 +106,17 @@
 /**
 The BTMan Server.
 **/
-NONSHARABLE_CLASS(CBTManServer) : public CPolicyServer
+NONSHARABLE_CLASS(CBTManServer) : public CPolicyServer, public MBTBURNotify
 	{
 public:
 	//construct / destruct
 	static CServer2* NewLC();
 	~CBTManServer();
 
+	// From MBTBURNotify
+	virtual void BUROperationStarted();
+	virtual void BUROperationStopped();
+
 	void AddSession();
 	void DropSession();
 
@@ -126,12 +131,14 @@
 
 	void Publish(TUint aKey, TInt aValue); // only publish ints for now, ignore error
 	void NotifyViewChange(CBTManSubSession& aSubSessionViewOwner, const TDesC& aViewDescriptor);
+	void NotifyViewChange(const TDesC& aViewDescriptor);
 
 private:
 	CBTManServer();
 	void ConstructL();
 	//open/close a session
 	CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
+	void TryToStartShutdownTimer();
 
 private:
 	TInt					iMaxSessionCount;
@@ -140,6 +147,9 @@
 	CObjectConIx*			iContainerIndex;//<The server has an onject container index which creates an object container for each session
 	CBTRegistry*			iRegistry;
 	RProperty				iProperty;	// so that subsessions can publish change info
+	CBTManServerBURMgr*		iBURManager;	// Manage backup and restore events generated by the Secure Backup Engine
+
+	TBool			iBUROperationStarted;	// Whether or not a backup or restore operation is in progress (meaning that this server should not shutdown)
 	};
 
 inline TInt CBTManServer::MaxSessionCount() const {return iMaxSessionCount;}
@@ -186,6 +196,7 @@
 	void CancelRequest(const RMessage2& aMessage);
 
 	TBool SubSessionHasOverlappingView(CBTManSubSession& aSubSessionViewOwner, const TDesC& aViewDescriptor);
+	TBool SubSessionHasOverlappingView(const TDesC& aViewDescriptor);
 
 private:
 	void DoCompleteMessage(CBTManMessage& aMessage, TInt aReason);
--- a/bluetoothmgmt/btmgr/bld.inf	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothmgmt/btmgr/bld.inf	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-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"
@@ -23,6 +23,8 @@
 //	Export the compiled DBMS policy file for the Bluetooth Manager DB...
 BTManServer/100069CC.SPD z:/private/100012a5/policy/100069cc.spd
 
+//	Export the backup registration file for Bluetooth Manager
+BTManServer/backup_registration.xml z:/private/100069cc/backup_registration.xml
 
 PRJ_MMPFILES
 BTDevice/BTDevice.mmp
--- a/bluetoothmgmt/btrom/bluetooth.iby	Fri Mar 19 09:53:48 2010 +0200
+++ b/bluetoothmgmt/btrom/bluetooth.iby	Fri Apr 16 16:09:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -84,6 +84,9 @@
 REM Feature BLUETOOTH is not in this ROM (bluetooth.iby)
 #else
 
+REM BT Manager Backup Registration
+data=ZPRIVATE\100069cc\backup_registration.xml	Private\100069cc\backup_registration.xml
+
 REM default is to run Esock_BT thread in DealerPlayer role
 data=ZPRIVATE\101F7988\esock_bt.cmi private\101F7988\esock_bt.cmi
 
--- a/bt_info/bt_metadata/bt_metadata.mrp	Fri Mar 19 09:53:48 2010 +0200
+++ b/bt_info/bt_metadata/bt_metadata.mrp	Fri Apr 16 16:09:25 2010 +0300
@@ -1,3 +1,19 @@
+#
+# 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: 
+#
+
 component           bt_metadata
 source   \sf\os\bt\bt_info\bt_metadata 
 source   \sf\os\bt\package_definition.xml
--- a/irda/irdastack/irtranp/BFTP.CPP	Fri Mar 19 09:53:48 2010 +0200
+++ b/irda/irdastack/irtranp/BFTP.CPP	Fri Apr 16 16:09:25 2010 +0300
@@ -58,313 +58,12 @@
 * Parameter:			a_offset - the offset into the buffer where we should start parsing
 */
 
-void BFTP::ReqPDU(const TDesC8& a_Header, TInt a_offset)
-	{
-	BFTPPRINT(_L("BFTP: ReqPDU\n"));
-	
-	TUint16 AttNum = IrTranpUtil::DExtract(a_Header, a_offset);
-	a_offset+=2;
-	
-	for(TInt i=0;i<AttNum;i++) // Loop all AttNames
-		{
-		TBuf8<4> attName; // BFTP Attribute name
-		for(TInt j=0;j<4;j++) // we don't like it .. hardcoded
-			{
-			attName.Append(a_Header[a_offset+j]);
-			}
-		
-		a_offset+=4;
-		
-		if(attName.Compare(KTranpFIL0) == 0)
-			{
-			TUint32 length = IrTranpUtil::LExtract(a_Header, a_offset);
-			BFTPPRINT(_L("BFTP: Attribute FIL0\n"));
-			
-			m_FileName.SetLength(0);
-			m_FileName.Append((unsigned char*)a_Header.Ptr() + a_offset + 6, length-2);
-			
-			a_offset+=(length+4);
-			}
-		else if(attName.Compare(KTranpLFL0) == 0)
-			{
-			TUint32 length = IrTranpUtil::LExtract(a_Header, a_offset);
-			BFTPPRINT(_L("BFTP: Attribute LFL0\n"));
-
-			iLongFilename.Append((unsigned char*)a_Header.Ptr() + a_offset + 6, length-2);
-
-			a_offset+=(length+4);
-			}
-		else if(attName.Compare(KTranpTIM0) == 0)
-			{
-			TUint32 length = IrTranpUtil::LExtract(a_Header, a_offset);
-			BFTPPRINT(_L("BFTP: Attribute TIM0\n"));
-			a_offset+=(length+4);
-			}
-		else if(attName.Compare(KTranpTYP0) == 0)
-			{
-			TUint32 length = IrTranpUtil::LExtract(a_Header, a_offset);
-			BFTPPRINT(_L("BFTP: Attribute TYP0\n"));
-			a_offset+=(length+4);
-			}
-		else if(attName.Compare(KTranpTMB0) == 0)
-			{
-			TUint32 length = IrTranpUtil::LExtract(a_Header, a_offset);
-			BFTPPRINT(_L("BFTP: Attribute TMB0\n"));
-			a_offset+=(length+4);
-			}
-		else if(attName.Compare(KTranpBDY0) == 0)
-			{
-			TUint32 length = IrTranpUtil::LExtract(a_Header, a_offset);
-			BFTPPRINT(_L("BFTP: Attribute BDY0\n"));
-			
-			//iPicture.Set((unsigned char*)a_Header.Ptr() + a_offset + 6 + KTranpUPFHeader, length-2, length-2);
-			iUPFPicture.Set((unsigned char*)a_Header.Ptr() + a_offset + 6, length-2, length-2);
-			
-			iTranpProtocol->SetPicture(iPicture, m_FileName, iUPFPicture, iLongFilename);
-
-			a_offset+=(length+4);
-			/**/
-			TBuf8<256> userData;
-		
-			// AttNum
-			userData.Append(0x00);
-			userData.Append(0x01);
-			// attName
-			userData.Append(KTranpRPL0);
-			// AttLength
-			userData.Append(0x00);
-			userData.Append(0x00);
-			userData.Append(0x00);
-			userData.Append(2 + m_FileName.Length());
-			// AttType
-			userData.Append(0x01);
-			// AFLG
-			userData.Append(0x00);
-			// AttValue
-			userData.Append(m_FileName);
-			
-			TUint8 pduType = KTranpPduTypeRplAck;
-			m_oSCEP->SCEPSendCommand(userData, pduType); // We want SCEP to send a packet with this command
-			}
-		else if(attName.Compare(KTranpCMD0) == 0)
-			{
-			TUint32 length = IrTranpUtil::LExtract(a_Header, a_offset);
-			BFTPPRINT(_L("BFTP: Attribute CMD0\n"));
-			a_offset+=(length+4);
-			}
-		else if(attName.Compare(KTranpWHT0) == 0)
-			{
-			TUint32 length = IrTranpUtil::LExtract(a_Header, a_offset);
-			BFTPPRINT(_L("BFTP: Attribute WHT0\n"));
-			
-			// how to avoid copying of the information we put in the command??? Don't avoid it for now.
-			TPtr8 queryType((unsigned char*)a_Header.Ptr() + a_offset+6, 4, 4);
-
-			TBuf8<256> userData;
-			//TPtr8 userDataPtr = userData.Des();
-			
-			if (queryType.Compare(KTranpRIMG) == 0)
-				{
-				//This reply is for an RIMG query
-				// Its instructs the peer to send the image in its orginal lattice size
-
-				// AttNum
-				userData.Append(0x00);
-				userData.Append(0x01);
-				// AttName
-				userData.Append(KTranpBDY0);
-				// AttLength
-				userData.Append(0x00);
-				userData.Append(0x00);
-				userData.Append(0x00);
-				userData.Append(0x0d);
-				// AttType
-				userData.Append(0x00);
-				// AFLG
-				userData.Append(0x00);
-				
-				/*userData.Append(0x00);// <tag-pix-aspect> 3 bytes
-				userData.Append(0x01);
-				userData.Append(0x01);	*/
+void BFTP::ReqPDU(const TDesC8& /*a_Header*/, TInt /*a_offset*/)
+/** No Longer used.
 
-				switch(iLatticeSize)
-					{
-				case EQVGA:
-					//QVGA:=320x240  (0x0140 x 0x00f0)
-//					userData.Append(0x01);// <tag-org-size>     5 bytes
-//					userData.Append(0x40); // width [2 bytes]
-//					userData.Append(0x01);
-//					userData.Append(0xf0);// height [2 bytes]
-//					userData.Append(0x00);
-				
-					userData.Append(0x02);// <tag-acc-size>     6 bytes
-					userData.Append(0x01);// <num-acc-size>
-					userData.Append(0x40);// width [2 bytes]
-					userData.Append(0x01);
-					userData.Append(0xf0);// height [2 bytes]
-					userData.Append(0x00);
-				break;
-				case EVGA :
-					// VGA:=640x480 ( 0x0280 x 0x01e0)
-//					userData.Append(0x01);// <tag-org-size>     5 bytes
-//					userData.Append(0x80); // width [2 bytes]
-//					userData.Append(0x02);
-//					userData.Append(0xe0);// height [2 bytes]
-//					userData.Append(0x01);
-				
-					userData.Append(0x02);// <tag-acc-size>     6 bytes
-					userData.Append(0x01);// <num-acc-size>
-					userData.Append(0x80); // width [2 bytes]
-					userData.Append(0x02);
-					userData.Append(0xe0);// height [2 bytes]
-					userData.Append(0x01);
-				break;
-				case ESVGA:
-					// SVGA:=800x600 (0x0320 x 0x0258)
-//					userData.Append(0x01);// <tag-org-size>     5 bytes
-//					userData.Append(0x20);// width [2 bytes]
-//					userData.Append(0x03);
-//					userData.Append(0x58);// height [2 bytes]
-//					userData.Append(0x02);
-				
-					userData.Append(0x02);// <tag-acc-size>     6 bytes
-					userData.Append(0x01);// <num-acc-size>
-					userData.Append(0x20);// width [2 bytes]
-					userData.Append(0x03);
-					userData.Append(0x58);// height [2 bytes]
-					userData.Append(0x02);
-					break;
-				case EXGA:
-					// XGA:=1024x768 ( 0x0400 x 0x0300)
-//					userData.Append(0x01);// <tag-org-size>     5 bytes
-//					userData.Append(0x00);// width [2 bytes]
-//					userData.Append(0x04);
-//					userData.Append(0x00);// height [2 bytes]
-//					userData.Append(0x30);
-				
-					userData.Append(0x02);// <tag-acc-size>     6 bytes
-					userData.Append(0x01);// <num-acc-size>
-					userData.Append(0x00);// width [2 bytes]
-					userData.Append(0x04);
-					userData.Append(0x00);// height [2 bytes]
-					userData.Append(0x03);	
-					break;
-				case ESXGA: 
-					// SXGA:=1280x960 (0x0500 x 0x03c0)
-//					userData.Append(0x01);// <tag-org-size>     5 bytes
-//					userData.Append(0x00);// width [2 bytes]
-//					userData.Append(0x05);
-//					userData.Append(0xc0);// height [2 bytes]
-//					userData.Append(0x03);
-				
-					userData.Append(0x02);// <tag-acc-size>     6 bytes
-					userData.Append(0x01);// <num-acc-size>
-					userData.Append(0x00);// width [2 bytes]
-					userData.Append(0x05);
-					userData.Append(0xc0);// height [2 bytes]
-					userData.Append(0x03);
-				break;
-				case EFREE:
-					// FREE:=m x n
-				default:
-					// Send in orginal size
-//					userData.Append(0x01);// <tag-org-size>     5 bytes
-//					userData.Append(0xFF);
-//					userData.Append(0xFF);
-//					userData.Append(0xFF);
-//					userData.Append(0xFF);
-				
-					userData.Append(0x02);// <tag-acc-size>     6 bytes
-					userData.Append(0x01);// <num-acc-size>
-					userData.Append(0xFF);// width [2 bytes]
-					userData.Append(0xFF);
-					userData.Append(0xFF);// height [2 bytes]
-					userData.Append(0xFF);	
-					};
-
-				/*userData.Append(0x03);// <tag-org-samp>   3 bytes
-				userData.Append(0xC4);
-				userData.Append(0x20);
-				
-				userData.Append(0x04);// <tag-acc-samp>   3 bytes
-				userData.Append(0xC4);
-				userData.Append(0x20);*/
-				
-				userData.Append(0x05);//<tag-acc-filesize> 5 bytes
-				userData.Append(0xFF);
-				userData.Append(0xFF);
-				userData.Append(0xFF);
-				userData.Append(0xFF);	
-				}
-			else if (queryType.Compare(KTranpRINF) == 0)
-				{
-				// This  reply is for an RINF query
-				userData.Append(0x00);
-				userData.Append(0x01);
-				// AttName
-				userData.Append(KTranpBDY0);
-				// AttLength
-				userData.Append(0x00);
-				userData.Append(0x00);
-				userData.Append(0x00);
-				userData.Append(0x08);
-				// AttType
-				userData.Append(0x00);
-				// AFLG
-				userData.Append(0x00);
-				// AttValue
-				userData.Append(0x10); // memory
-				userData.Append(0xff);
-				userData.Append(0xff);
-				userData.Append(0x11); // battery
-				userData.Append(0xff);
-				userData.Append(0xff);	
-				}
-			else if (queryType.Compare(KTranpRCMD) == 0)
-				{
-                // This  reply is for an RINF query
-				userData.Append(0x00);
-				userData.Append(0x01);
-				// AttName
-				userData.Append(KTranpBDY0);
-				// AttLength
-				userData.Append(0x00);
-				userData.Append(0x00);
-				userData.Append(0x00);
-				userData.Append(0x07);
-				// AttType
-				userData.Append(0x00);
-				// AFLG
-				userData.Append(0x00);
-				// AttValue
-				userData.Append(0x20); // tag-opt-func
-                userData.Append(0x00);
-				userData.Append(0x01);
-				userData.Append(0x00);
-				userData.Append(0x01); // func-multi-command
-				}
-
-			a_offset+=(length+4);
-
-			TUint8 pduType = KTranpPduTypeRplAck;
-			m_oSCEP->SCEPSendCommand(userData, pduType); // We want SCEP to send a packet with this command
-			}
-		else if(attName.Compare(KTranpERR0) == 0)
-			{
-			TUint32 length = IrTranpUtil::LExtract(a_Header, a_offset);
-			BFTPPRINT(_L("BFTP: Attribute ERR0\n"));
-			a_offset+=(length+4);
-			}
-		else if(attName.Compare(KTranpRPL0) == 0)
-			{
-			TUint32 length = IrTranpUtil::LExtract(a_Header, a_offset);
-			BFTPPRINT(_L("BFTP: Attribute RPL0\n"));
-			a_offset+=(length+4);
-			}
+irda client libraries left in to avoid breaks */
+	{
 	}
-	
-	BFTPPRINT(_L("BFTP: Exiting ReqPDU\n"));
-}
 
 /*
 * Method description:	Called from the application with a picture to send
--- a/irda/irdastack/irtranp/SCEP.CPP	Fri Mar 19 09:53:48 2010 +0200
+++ b/irda/irdastack/irtranp/SCEP.CPP	Fri Apr 16 16:09:25 2010 +0300
@@ -109,149 +109,11 @@
 	return 0;
 	}
 
-void SCEP::ReceiveComplete(TDesC8& aBuffer)
-	{
-	SCEPPRINT_2(_L("SCEP::ReceiveComplete(%d)\n"),aBuffer.Length());
-
-	iSCEPFrame.Append(aBuffer); // Add new data to cached packet
-
-	TBool loopagain;
-	do
-		{
-		loopagain = EFalse;
-		
-		if ((iSCEPFrame[0]==0x00)&&(iSCEPFrame.Length()>=3))
-			{
-			TInt tempLength = 0;
-			TInt additionalLength = 0;
-			TInt lengthPos = 3;
-
-			if ((iSCEPFrame[1]==KTranpMsgTypeCER) && (iSCEPFrame[2]==KTranpInfTypeVer))
-				{
-				lengthPos = 5;
-				additionalLength = 4; // ... and that same packet has 4 trailing bytes
-				}
-				
-			if (iSCEPFrame.Length()>lengthPos+2)// Otherwise we might miss out on the last packet
-				{
-				if(iSCEPFrame[0] == 0x00) // Let's guess it's an SCEP header - HARDCODED AND UGLY!!!
-					{
-					tempLength = iSCEPFrame[lengthPos];
-					if(tempLength == 0xff)
-						{
-						tempLength = IrTranpUtil::DExtract(iSCEPFrame, lengthPos+1);
-						lengthPos = 5;
-						}
-					SCEPPRINT_2(_L("tempLength = %d"), tempLength);
-					}
-
-				tempLength += ((lengthPos+1) + additionalLength);
-				
-				SCEPPRINT_3(_L("iSCEPFrame.length(%d) >= templength(%d)"),iSCEPFrame.Length(),tempLength);
-
-					switch (iSCEPFrame[1])
-					{
-				case KTranpMsgTypeCER: // MsgType = Connection establishment request
-				case KTranpMsgTypeCEC: // MsgType = Connection establishment confirmation
-				case KTranpMsgTypeData: // Data (Command)
-				case KTranpMsgTypeDisc: // Disconnection
-					{
-					switch (iSCEPFrame[2])
-						{
-					case KTranpInfTypeVer: // Version of MsgType
-					case KTranpInfTypeNeg: // Negotiation Information
-					case KTranpInfTypeUser: // UserData
-					case KTranpInfTypeExt: // Extend in the future
-					case KTranpInfTypeRsn: // Reason
-						break;
-					default:
-						// bogus frame
-						SCEPPRINT(_L("SCEP::Bogus Inf Type in frame\n"));
-						iSCEPFrame.SetLength(0);
-						}
-					}
-					break;
-				default:
-					// bogus frame
-					SCEPPRINT(_L("SCEP::Bogus Msg Type in frame\n"));
-					iSCEPFrame.SetLength(0);
-					}
+void SCEP::ReceiveComplete(TDesC8& /*aBuffer*/)
+/** No Longer used.
 
-				if(iSCEPFrame.Length() >= tempLength) // yes, complete packet
-					{
-					TInt oldLength = iSCEPFrame.Length();
-					iSCEPFrame.SetLength(tempLength); // We only want exactly one packet
-					ParseCommand(iSCEPFrame);
-					
-					iSCEPFrame.SetLength(oldLength);
-					iSCEPFrame.Delete(0, tempLength); // The surplus data belongs to the next packet
-					SCEPPRINT(_L("\r\n***\r\n"));
-					//IrTranpUtil::HexOut(iSCEPFrame);
-					SCEPPRINT(_L("***\r\n"));
-					loopagain = (oldLength > tempLength) ? ETrue : EFalse;
-					}		
-				}	
-			}
-		else
-			{
-			SCEPPRINT(_L("SCEP:: Bogus Frame header\n"));
-			iSCEPFrame.SetLength(0);
-			}
-		} while (loopagain);
-
-
-	// let the commandprocessor send whatever's in queue
-	
-	m_oCommandP->DoCommand();
-
-	if ( (!(iComReadWrite->IsActive())) && !(iState == EError) ) //Make sure that thre is always an outstanding request
-		iComReadWrite->Receive(); 
-
-	switch(iState)
-		{
-	case EConnected:
-		iNotifier->Connected();
-		iState = EProgress;
-		SCEPPRINT(_L("SCEP: EConnected -> EProgress\r\n"));
-		break;
-	case EDisconnected:
-		iNotifier->Disconnected();
-		iComReadWrite->Close();
-		iState = EWaiting;
-		SCEPPRINT(_L("SCEP: EDisconnected -> EWaiting\r\n"));
-		break;
-	case EProgress:
-		{
-		SCEPPRINT(_L("SCEP: EProgress\r\n"));
-
-		TInt32 progress = 0;
-		if(m_packet!=NULL)
-			{
-			if(m_packet->Length() != 0)
-				{
-				Math::Int(progress, m_packet->Length()*100 / m_iPicSize);
-				}
-			iNotifier->ProgressIndication(progress);
-			}
-		}
-		break;
-	case EWaiting:
-		SCEPPRINT(_L("SCEP: EWaiting\r\n"));
-		break;
-	case EError:
-		SCEPPRINT(_L("SCEP: EError\r\n"));
-		break;
-	case ECommunicationInt:
-		SCEPPRINT(_L("SCEP: ECommunicationInt\r\n"));
-		iNotifier->Disconnected();
-		iComReadWrite->Close();
-		iState = EWaiting;
-		break;
-	default:
-		SCEPPRINT(_L("SCEP: Unknown state\r\n"));
-		break;
-		}
-	SCEPPRINT(_L("SCEP: Exit ReceiveComplete\r\n"));
+irda client libraries left in to avoid breaks */
+	{
 	}
 
 void SCEP::SendComplete()
@@ -319,19 +181,11 @@
 *
 */
 
-void SCEP::SCEPSendCommand(TDes8& a_userData, TUint8 a_pduType)
+void SCEP::SCEPSendCommand(TDes8& /*a_userData*/, TUint8 /*a_pduType*/)
+/** No Longer used.
+
+irda client libraries left in to avoid breaks */
 	{
-	SRPSCommand* command = new (ELeave) SRPSCommand(iComReadWrite);
-	command->SetPMID(m_PMID.Des());
-	command->SetSMID(m_SMID.Des());
-	command->SetDPID(m_DPID);
-	command->SetSPID(m_SPID);
-	command->SetCmdId(m_CmdId);
-	command->SetPDUType(a_pduType);
-	command->SetUserData(a_userData);
-	command->Create();
-//	IrTranpUtil::HexOut(command->GetData());
-	m_oCommandP->Add(command);
 	}
 
 /*
@@ -394,156 +248,12 @@
 * Parameter:			offset - where in the packet to start parsing
 */
 
-void SCEP::SCEPDataCommand(TDes8& a_Header, TInt offset)
+void SCEP::SCEPDataCommand(TDes8& /*a_Header*/, TInt /*offset*/)
+/** No Longer used.
+
+irda client libraries left in to avoid breaks */
 	{
-	SCEPPRINT(_L("Inside SCEPDataCommand\n"));
-	
-	if(a_Header[offset] == KTranpInfTypeUser)
-		{
-		// Always InfTypeUser when in SCEPDataCommand
-		TInt packetLength = a_Header[offset+1];
-		if(packetLength == 0xff)
-			{
-			// since length1 was 0xff, look at length2
-			packetLength = ((a_Header[offset+2] << 8) + (a_Header[offset+3])); // 16bit
-			offset+=4; // include inftype and length2
-			}
-		else
-			{
-			offset+=2; // include inftype and length1
-			}
-		
-		// TUint8 InfVer = a_Header[offset];
-		TUint8 DFLG = a_Header[offset+1];
-		// TUint16 length3 = IrTranpUtil::DExtract(a_Header, offset+2);
-		
-		if(DFLG == KTranpDFLGrcon)
-			{
-			// Reject to request connection
-			SCEPPRINT(_L("Connection rejected\n"));
-			}
-		else if(DFLG == KTranpDFLGnseg)
-			{
-			// PDU not segmented (single PDU)
-			DoCommand(a_Header, offset+4);
-			//					break;
-			}
-		else if(DFLG == KTranpDFLGfPDU)
-			{
-			// First segmented PDU
-			// We do all reassembling in SCEP, and then send the complete (big) packet to bFTP
-			// restno * PDU must be able to hold the complete packet, right?
-			
-			// Ownership of this data [m_packet] belongs to the TTranpPicture object
-			// so must ask the correct object to delete its heap.
-			// If we were already building a packet, get rid of it
-			iTranpProtocol->DeleteHeapData();
-			
-			TUint32 seqno = IrTranpUtil::LExtract(a_Header, offset+4);
-			TUint32 restno = IrTranpUtil::LExtract(a_Header, offset+8);
-			
-			TUint32 PDUSize;
-			switch(m_uiMaxPDU)
-				{
-				case '1':
-					{
-					PDUSize = 512;
-					break;
-					}
-				case '2':
-					{
-					PDUSize = 1024;
-					break;
-					}
-				case '3':
-					{
-					PDUSize = 2048;
-					break;
-					}
-				case '4':
-					{
-					PDUSize = 4096;
-					break;
-					}
-				default:
-					{
-					PDUSize = 512;
-					break;
-					}
-				}
-			
-			// This should not leave and report an error back...
-			//__UHEAP_FAILNEXT(1);
-			TRAPD( err , m_packet = HBufC8::NewL(PDUSize*restno)); // should be enough
-			if (err != KErrNone)
-				{
-				iNotifier->Error(err);
-				iState = EError;
-				return;
-				}
-			else
-				iTranpProtocol->SetHeapData(m_packet);
-			
-			m_iPicSize = PDUSize*restno;
-			
-			SCEPPRINT(_L("ResizeL went well\n"));
-			
-			m_seq = seqno;
-			AddSegment(a_Header, offset+12);
-			}
-		else if(DFLG == KTranpDFLGiPDU)
-			{
-			// Intermediate segmented PDUs
-			
-			TUint32 seqno = IrTranpUtil::LExtract(a_Header, offset+4);
-			if(seqno == m_seq+1)
-				{
-				AddSegment(a_Header, offset+12);
-				m_seq++;
-				}
-			else
-				{
-				SCEPPRINT(_L("Error in intermediate PDU\n"));
-				}
-			}
-		else if(DFLG == KTranpDFLGlPDU)
-			{
-			// Last segmented PDU
-			
-			m_seq++;
-			TUint32 restno = IrTranpUtil::LExtract(a_Header, offset+8);
-			if(restno == 1)
-				{
-				AddSegment(a_Header, offset+12);
-				//TPtr8 packetPtr = m_packet->Des();
-				DoCommand(*m_packet, 0); // Now let's play
-                iNotifier->ProgressIndication(100); // Makes sure 100% is reached
-		        iNotifier->GetComplete();
-                TPtr8 temp2 = m_packet->Des();
-	            temp2.Zero();
-				}
-			else
-				{
-				SCEPPRINT(_L("Error in last PDU\n"));
-				}
-			}
-		else if(DFLG == KTranpDFLGcint)
-			{
-			SCEPPRINT(_L("Communication interrupted\n"));
-			iState = ECommunicationInt;
-			}
-		else
-			{
-			// Ooops.
-			}
-		}
-	else 
-		{
-		// oops
-		}
-			
-	SCEPPRINT(_L("Exiting SCEPDataCommand\n"));
-}
+	}
 
 /*
 * Method description:	Adds segmented packets into a complete packet
@@ -664,46 +374,11 @@
 * Parameter:			a_offset - where in the packet the command is
 */
 
-void SCEP::DoCommand(const TDesC8& a_Header, TInt a_offset)
-	{
-	SCEPPRINT(_L("SCEP: DoCommand\n"));
-	
-	if(a_Header[a_offset] != 0x58) // Always 0x58 at the start of a command
-		{
-		SCEPPRINT(_L("SCEP: Command did not start with 0x58\n"));
-		return;
-		}
-	
-	TUint8 switchVar = (TUint8)(a_Header[a_offset+1] & 0xc0); // we only want the two highest bits for PDU type
-	if(switchVar == KTranpPduTypeReq)
-		{
-		// Don't care about the MachineIDs for now
-		SCEPPRINT(_L("SCEP: PduTypeReq\n"));
+void SCEP::DoCommand(const TDesC8& /*a_Header*/, TInt /*a_offset*/)
+/** No Longer used.
 
-		m_SPID = IrTranpUtil::DExtract(a_Header, 22 + a_offset);
-		m_DPID = IrTranpUtil::DExtract(a_Header, 24 + a_offset);
-		m_CmdId = IrTranpUtil::DExtract(a_Header,26 + a_offset);
-		// Pass SCEP packet Payload to BFTP layer
-		m_oBFTP->ReqPDU(a_Header, a_offset + 28); // hardcoded, but always 28
-		}
-	else if(switchVar == KTranpPduTypeRplAck)
-		{
-		SCEPPRINT(_L("SCEP: PduTypeRplAck\n"));
-		}
-	else if(switchVar == KTranpPduTypeRplNack)
-		{
-		SCEPPRINT(_L("SCEP: PduTypeRplNack\n"));
-		}
-	else if(switchVar == KTranpPduTypeAbt)
-		{
-		SCEPPRINT(_L("SCEP: PduTypeAbt\n"));
-		}
-	else
-		{
-		SCEPPRINT(_L("SCEP: PduType Broken\n"));
-		}
-	
-	SCEPPRINT(_L("SCEP: Exiting DoCommand\n"));
+irda client libraries left in to avoid breaks */
+	{
 	}
 
 /*
@@ -839,53 +514,11 @@
 // Parameter:			a_TempBuffer - the packet itself
 //
 
-void SCEP::ParseCommand(TDes8& a_TempBuffer)
+void SCEP::ParseCommand(TDes8& /*a_TempBuffer*/)
+/** No Longer used.
+
+irda client libraries left in to avoid breaks */
 	{
-	SCEPPRINT(_L("SCEP: ParseCommand\n"));
-	// parse the incoming buffer and see what command we're talking about. Return an instance of such a command.
-	
-	// Look at the first bytes, see what command it might be, call the correct private method and let it take care of the rest?
-	
-	if(a_TempBuffer[1] == KTranpMsgTypeCER)
-		// MsgType = Connection establishment request
-		{
-		SCEPPRINT(_L("SCEP: Got a connection request"));
-		SCEPConRequest(a_TempBuffer, 2);
-		
-		// Create and add a SCEPConConfirm!
-		SCONconL();
-		}
-	else if(a_TempBuffer[1] == KTranpMsgTypeCEC)
-		// MsgType = Connection establishment confirmation
-		{
-		SCEPPRINT(_L("SCEP: Got a connect ack"));
-		SCEPConConfirm(a_TempBuffer, 2);
-		}
-	else if(a_TempBuffer[1] == KTranpMsgTypeData)
-		// Data (Command)
-		{
-		SCEPPRINT(_L("SCEP: Got a data packet\n"));
-		SCEPDataCommand(a_TempBuffer, 2);
-		}
-	else if(a_TempBuffer[1] == KTranpMsgTypeDisc)
-		// Disconnection
-		{
-		SCEPPRINT(_L("SCEP: Got a disconnect packet\n"));
-		SCEPDisconnect(a_TempBuffer, 2);
-		if (m_packet != NULL)
-			m_iPicSize = m_packet->Length(); // Otherwise we'll never get to 100%
-		iSCEPFrame.Zero();
-		}
-	else
-		{
-		SCEPPRINT(_L("SCEP: Wacko! Default!\n"));
-		// Reserved
-		}
-	
-	
-	SCEPPRINT(_L("SCEP: Exiting ParseCommand\n"));
-	
-	return;
 	}
 
 //
--- a/irda/irdastack/irtranp/tranp.cpp	Fri Mar 19 09:53:48 2010 +0200
+++ b/irda/irdastack/irtranp/tranp.cpp	Fri Apr 16 16:09:25 2010 +0300
@@ -312,38 +312,27 @@
 	}
     
 EXPORT_C void CTranpSession::Connect()
-/** Establishes a connection with a peer device. This function is called before 
-sending a picture.
+/** No Longer used.
 
-The callback function Connect() is called when the connection has been successfully 
-established.
+irda client libraries left in to avoid breaks */
 
-@see MTranpNotification::Connected() */
 	{
-	User::Leave(KErrNotSupported); //Qualified
 	}
 
 EXPORT_C  void CTranpSession::Disconnect()
-/** Breaks the connection with a peer device. This function is called after sending 
-a picture.
+/** No Longer used.
 
-The callback function Disconnected() is called when the connection has been 
-broken.
+irda client libraries left in to avoid breaks */
 
-@see MTranpNotification::Connected() */
 	{
-	User::Leave(KErrNotSupported); //Qualified
 	}
     
 EXPORT_C  void CTranpSession::Query(TTranP /*aWhat*/)
-/** Requests information on the processing ability of the peer device. Typically, 
-this is called before sending a picture to that peer device. The information 
-is returned through the callback function QueryComplete().
+/** No Longer used.
 
-@param aWhat The specific type of information required from the peer device. 
-@see MTranpNotification::QueryComplete() */
+irda client libraries left in to avoid breaks */
+
 	{
-	User::Leave(KErrNotSupported); //Qualified
 	}
 
 EXPORT_C  void CTranpSession::Abort()
@@ -383,43 +372,25 @@
 	}
     
 EXPORT_C  void CTranpSession::Put(const TTranpPicture& /*aPicture*/)
-/** Sends a picture to a peer device.
-
-The following sequence of events is expected:
-
-This device sends picture data to the peer device, resulting in successive 
-calls to the ProgressIndication() callback function indicating how much of 
-the picture data has been received.
+/** No Longer used.
 
-Transmission of picture data is complete, resulting in a call to the GetComplete() 
-callback function.
-
-If the connection with the peer device is dropped at any stage in the transmission, 
-then this results in a call to the Error() callback function.
-
-@param aPicture The picture object 
-@see MTranpNotification::ProgressIndication()
-@see MTranpNotification::GetComplete()
-@see MTranpNotification::Error() */
+irda client libraries left in to avoid breaks */
 	{
-	User::Leave(KErrNotSupported); //Qualified
 	}
 	
 EXPORT_C  void CTranpSession::Config(const TTranpConfig& /*aConfig*/)
-/** Sets the configuration parameters.
+/** No Longer used.
 
-@param aConfig The configuration parameters */
+irda client libraries left in to avoid breaks */
 	{
-	User::Leave(KErrNotSupported); //Qualified
 	}
 
 EXPORT_C  TTranpConfig CTranpSession::Config() const
 
-/** Returns the configuration parameters.
+/** No Longer used.
 
-@return The configuration parameters. */
+irda client libraries left in to avoid breaks */
 	{
-	User::Leave(KErrNotSupported); //Qualified
 	return iConfig;
 	}