--- a/atext/server/group/extsrv.mmp Fri Mar 12 15:49:00 2010 +0200
+++ b/atext/server/group/extsrv.mmp Mon Mar 15 12:44:59 2010 +0200
@@ -47,7 +47,7 @@
EPOCSTACKSIZE 0x5000 // Hack for plugins using RCmManager; remove this line when RCmManager becomes client-server
EPOCHEAPSIZE 0x1000 0x2000000 // Use same as MCE
-CAPABILITY CAP_SERVER NetworkControl CommDD
+CAPABILITY CAP_SERVER NetworkControl CommDD PowerMgmt
VENDORID VID_DEFAULT
SOURCEPATH ../src
--- a/bluetooth/btcomm/src/states.cpp Fri Mar 12 15:49:00 2010 +0200
+++ b/bluetooth/btcomm/src/states.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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;
Binary file bluetooth/btdocs/Designs/backuprestore.mdzip has changed
--- a/bluetooth/btextnotifiers/bwins/BTEXTNOTIFIERSU.DEF Fri Mar 12 15:49:00 2010 +0200
+++ b/bluetooth/btextnotifiers/bwins/BTEXTNOTIFIERSU.DEF Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btextnotifiers/eabi/BTExtNotifiersU.DEF Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btextnotifiers/inc/BTExtNotifiersPartner.h Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btextnotifiers/src/BTExtNotifiers.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/avctp/avctp.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/avctp/avctpmuxerstates.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/common/bt_v2.mmp Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/linkmgr/Subscribers.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/linkmgr/Subscribers.h Mon Mar 15 12:44:59 2010 +0200
@@ -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 Mon Mar 15 12:44:59 2010 +0200
@@ -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 Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/linkmgr/hcifacade.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/linkmgr/linkmgr.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/linkmgr/linkmgr.h Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/linkmgr/physicallinks.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -509,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
@@ -572,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());
@@ -859,6 +866,7 @@
TRAP(err, iLinksMan.HCIFacade().AuthenticateL(Handle()));
if(err == KErrNone)
{
+ iLinkKeyReturnedInThisAuthentication = EFalse;
SetAuthenticationPending(EAuthenticationRequestPending);
}
}
@@ -2941,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
@@ -3648,6 +3662,40 @@
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
{
@@ -3740,6 +3788,10 @@
{
LOG(_L("CPhysicalLink: Providing link key to HC..."))
ASSERT_DEBUG(iDevice.IsValidLinkKey());
+ if (IsAuthenticationPending())
+ {
+ iLinkKeyReturnedInThisAuthentication = ETrue;
+ }
iAuthenticationCtrl.LinkKeyRequestReply(iDevice.Address(), iDevice.LinkKey());
}
else
--- a/bluetooth/btstack/linkmgr/physicallinks.h Fri Mar 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/linkmgr/physicallinks.h Mon Mar 15 12:44:59 2010 +0200
@@ -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,7 +497,7 @@
void PINCodeRequestNegativeReply(const TBTDevAddr& aDevAddr);
inline TBool IsAuthenticationPending() const;
-
+
void LinkKeyRequestResponseAttempt(TBool aForceResponse = EFalse);
void DoLinkKeyResponse(TBool aPositive);
@@ -519,6 +530,7 @@
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;
@@ -579,6 +591,8 @@
TBool iNewPinCodeValid;
TBTPinCode iNewPinCode;
+ 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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/secman/btaccessrequester.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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();
}
@@ -705,6 +696,12 @@
else if(aResult == EBTSecManAccessGranted)
{
LOG(_L8("\tACCESS GRANTED"));
+ if (RemoteIndicatedNoBondingToDedicatedBonding())
+ {
+ // We allow the device to bond, but tell theUI layer so it can delete the link key if it wants to
+ aResult = KErrRemoteDeviceIndicatedNoBonding;
+ LOG(_L8("\t... but remote indicated no bonding"));
+ }
}
else
{
@@ -1004,10 +1001,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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/secman/secman.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -555,6 +555,7 @@
CPhysicalLink* link = iPhysicalLinksManager->FindPhysicalLink(aAddr);
__ASSERT_ALWAYS(link, PANIC(KBTSecPanic, EBTSecPhysicalLinkMissing));
__ASSERT_DEBUG(!link->InstanceNumericComparator(), PANIC(KBTSecPanic, EBTSecConnectionNumericComparisonTwice));
+ __ASSERT_DEBUG(!link->InstanceUserConfirmer(), PANIC(KBTSecPanic, EBTSecConnectionUserConfirmationTwice));
if(link->InstanceNumericComparator())
{
return;
@@ -581,6 +582,22 @@
}
}
}
+ else if (!link->IsPairingExpected())
+ {
+ 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 +613,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 +659,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 +880,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 +1831,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 +1995,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 12 15:49:00 2010 +0200
+++ b/bluetooth/btstack/secman/secman.h Mon Mar 15 12:44:59 2010 +0200
@@ -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/bluetoothmgmt/bluetoothclientlib/btlib/btsocket.cpp Fri Mar 12 15:49:00 2010 +0200
+++ b/bluetoothmgmt/bluetoothclientlib/btlib/btsocket.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetoothmgmt/bluetoothclientlib/inc/bt_subscribe_partner.h Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetoothmgmt/bluetoothclientlib/inc/bttypespartner.h Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetoothmgmt/btmgr/BTDevice/BTDevice.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetoothmgmt/btmgr/BTManServer/BTManServer.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetoothmgmt/btmgr/BTManServer/BTManServer.mmp Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetoothmgmt/btmgr/BTManServer/BTRegistryDB.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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
--- a/bluetoothmgmt/btmgr/BTManServer/BTRegistryDB.h Fri Mar 12 15:49:00 2010 +0200
+++ b/bluetoothmgmt/btmgr/BTManServer/BTRegistryDB.h Mon Mar 15 12:44:59 2010 +0200
@@ -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 Mon Mar 15 12:44:59 2010 +0200
@@ -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 Mon Mar 15 12:44:59 2010 +0200
@@ -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 Mon Mar 15 12:44:59 2010 +0200
@@ -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 Mon Mar 15 12:44:59 2010 +0200
@@ -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 Mon Mar 15 12:44:59 2010 +0200
@@ -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 Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetoothmgmt/btmgr/Inc/BTManServer.h Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetoothmgmt/btmgr/bld.inf Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/bluetoothmgmt/btrom/bluetooth.iby Mon Mar 15 12:44:59 2010 +0200
@@ -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/irda/irdastack/irtranp/BFTP.CPP Fri Mar 12 15:49:00 2010 +0200
+++ b/irda/irdastack/irtranp/BFTP.CPP Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/irda/irdastack/irtranp/SCEP.CPP Mon Mar 15 12:44:59 2010 +0200
@@ -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 12 15:49:00 2010 +0200
+++ b/irda/irdastack/irtranp/tranp.cpp Mon Mar 15 12:44:59 2010 +0200
@@ -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;
}