bluetooth/btstack/common/RegistryHelpers.cpp
changeset 0 29b1cd4cb562
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/common/RegistryHelpers.cpp	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,449 @@
+// RegistryHelpers.CPP
+
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Small classes to assist stack in using Registry
+// 
+//
+
+#include "RegistryHelpers.h"
+#include "hostresolver.h"
+#include "linkmgr.h"
+#include "linkutil.h"
+#include "debug.h"
+#include <comms-infras/commsdebugutility.h>
+
+__FLOG_STMT(_LIT8(KSubsys, "btstack");)
+__FLOG_STMT(_LIT8(KComponent, "btregistryhelpers");)
+
+//
+// Classes apertaining to MBTRegistryTaskNotifier //
+//
+
+CBTRegistryHelperBase::CBTRegistryHelperBase(MBTRegistryTaskNotifier& aParent, CRegistrySession& aRegSess)
+	: CActive(EPriorityHigh)
+	, iRegSess(aRegSess)
+	, iParent(&aParent)
+	{
+	// high for servicing the protocol quickly
+	CActiveScheduler::Add(this);
+	}
+
+CBTRegistryHelperBase::~CBTRegistryHelperBase()
+	{
+	__FLOG_STATIC(KSubsys, KComponent, _L8("sec\tRegistryHelper destructing"));
+	Cancel();
+	iRegistry.Close();
+	iRegSess.Close();
+	}
+
+void CBTRegistryHelperBase::ConstructL()
+	{
+	iRegSess.Open(); // Open the resource (as we will close on delete).
+	User::LeaveIfError(iRegistry.Open(iRegSess.RegServ()));
+	}
+
+void CBTRegistryHelperBase::DoCancel()
+	{
+	iRegistry.CancelRequest(iStatus);
+	}
+
+void CBTRegistryHelperBase::RunL()
+	{
+	// Store the value from iStatus in case another active request is started. 
+	TInt rValue = iStatus.Int();
+	
+	// Check that the registry access is complete.
+	if(IsRegistryTaskCompleteL())
+		{
+		// Is the parent of this object still available to be notified
+		// of completion.
+		if(iParent)
+			{
+			Notify(rValue);
+			}
+		else
+			{
+			delete this;
+			}
+		}
+	}
+
+TInt CBTRegistryHelperBase::RunError(TInt aError)
+	{
+	if(iParent)
+		{
+		Notify(aError);
+		}
+	else
+		{
+		delete this;
+		}
+	return KErrNone;
+	}
+
+TBool CBTRegistryHelperBase::IsRegistryTaskCompleteL()
+	{
+	// Default implementation.
+	return ETrue;
+	}
+	
+void CBTRegistryHelperBase::Notify(TInt aError)
+	{
+	// Default implementation.
+	__FLOG_STATIC2(KSubsys, KComponent, _L8("CBTRegistryHelperBase::Notify(%d), this 0x%08x"), aError, this);
+	iParent->RegistryTaskComplete(this, aError);
+	}
+
+void CBTRegistryHelperBase::DetachParent()
+	{
+	__FLOG_STATIC3(KSubsys, KComponent, _L8("CBTRegistryHelperBase::DetachParent(), this 0x%08x, Current Parent 0x%08x, IsActive() %d")
+			       ,this, iParent, IsActive());
+	
+	// If the helper is not currently active then this object must be deleted.
+	if(!IsActive())
+		{
+		delete this;
+		}
+	else
+		{
+		iParent = NULL;
+		}
+	}
+	
+CBTDeviceGetter::CBTDeviceGetter(MBTRegistryTaskNotifier& aParent, CRegistrySession& aRegSess)
+: CBTRegistryHelperBase(aParent, aRegSess)
+	{
+	}
+
+CBTDeviceGetter* CBTDeviceGetter::NewL(CRegistrySession& aRegSess,
+									  MBTRegistryTaskNotifier& aParent)
+	{
+	CBTDeviceGetter* self = new(ELeave) CBTDeviceGetter(aParent, aRegSess);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CBTDeviceGetter::Start(const TBTDevAddr& aAddr)
+	{
+	__FLOG_STATIC1(KSubsys, KComponent, _L8("Registry helper (Getter 0x%08x) started..."), this);
+	iDevice.SetAddress(aAddr);
+	iRegistry.GetDevice(iDevice, iStatus);
+	SetActive();
+	}
+
+void CBTDeviceGetter::Notify(TInt aError)
+	{
+	iParent->RegistryTaskComplete(this, iDevice, aError);
+	}
+
+CBTDeviceModifier* CBTDeviceModifier::NewL(CRegistrySession& aRegSess, MBTRegistryTaskNotifier& aParent, CBTInquiryMgr& aInquiryMgr)
+	{
+	CBTDeviceModifier* self = new(ELeave) CBTDeviceModifier(aParent, aInquiryMgr, aRegSess);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CBTDeviceModifier::CBTDeviceModifier(MBTRegistryTaskNotifier& aParent, CBTInquiryMgr& aInquiryMgr, CRegistrySession& aRegSess)
+: CBTRegistryHelperBase(aParent, aRegSess), iInquiryMgr(aInquiryMgr), iRegistryUpdateStatus(ENoChange)
+	{
+	}
+
+void CBTDeviceModifier::Start(const TBTNamelessDevice& aDevice, TBool aCanAddDevice)
+	{
+	__FLOG_STATIC1(KSubsys, KComponent, _L8("Registry helper (Modifier 0x%08x) started..."), this);
+
+	// Store the arguments and check if the device specified by the
+	// aDevice argument is currently present in the registry.
+	iCanAddDevice = aCanAddDevice;
+	iDevice = aDevice;
+
+	iRegistrySearch.Reset();
+	iRegistrySearch.FindAddress(iDevice.Address());
+	
+	// Check the registry for this address.  If a record exists the iStatus
+	// in the RunL will be 1.
+	iRegistry.CreateView(iRegistrySearch, iStatus);
+	iState = EFindingDevice;
+	SetActive();
+	}
+
+CBTDeviceModifier::~CBTDeviceModifier()
+	{
+	Cancel();
+	delete iDeviceWithName;
+	}
+
+TBool CBTDeviceModifier::IsRegistryTaskCompleteL()
+	{
+	switch(iState)
+		{
+		case EFindingDevice:
+			{
+			// A view has been created based on the address of the new device.
+			// If the iStatus value is 1 then the device has been found.
+			// Note.  The value can never be greater than 1.  The server will
+			// PANIC if this condition were to occur therefore the code here does
+			// not need to check this condition.
+			if(iStatus.Int() > 0)
+				{
+				// The device is in the registry, so it can be modified
+				iRegistry.ModifyDevice(iDevice, iStatus);
+				iState = EModifyingDevice;
+				iCanAddDevice = EFalse;		// reinforce this, as its needed in the subsequent state
+				SetActive();
+				}
+			else if (iStatus.Int()==KErrNotFound)
+				{
+				// The device could not be found.  Check if its valid to
+				// add the device.
+				if(iCanAddDevice)
+					{
+					// The device should be added into the registry
+					delete iDeviceWithName;
+					iDeviceWithName = NULL;
+					iDeviceWithName = CBTDevice::NewL(iDevice); 
+					iRegistry.AddDeviceL(*iDeviceWithName, iStatus); 
+					iState = EAddingDevice;
+					SetActive();
+					}
+				// ELSE Nothing more to be done - the modification will be lost.
+				}
+			}
+			break;				
+
+		case EAddingDevice:
+		case EModifyingDevice:
+			{
+  			if (iStatus.Int() == KErrNone)
+	  			{
+				if (iCanAddDevice)
+					{
+					// This informs the Phy that an a reg action has occurred
+					iRegistryUpdateStatus = EAddition;
+					}
+				else
+					{
+					iRegistryUpdateStatus = EModification;
+					}
+	  			}
+  			else
+	  			{
+	  			__FLOG_STATIC1(KSubsys, KComponent, _L8("CBTDeviceModifier::IsRegistryTaskCompleteL() - registry update problem (TRequestStatus %d)"), iStatus.Int());
+	  			}
+	
+ 			// now try to put the device name in if we have one	
+ 			const TDesC8* name = iInquiryMgr.DeviceNameFromCache(iDevice.Address());
+ 			if(name && (name->Length()>0))
+				{
+ 				iRegistry.ModifyBluetoothDeviceNameL(iDevice.Address(), *name, iStatus); 
+ 				iState = EModifyingName;
+ 				SetActive();
+				}
+			}
+			break;
+
+		case EModifyingName:
+		default:
+			break;
+		};
+		
+	// If more modifications are required to the registry this AO
+	// will be active.  i.e., if this AO is active then the registry
+	// task is NOT complete.
+	return (!IsActive());
+	}
+
+void CBTDeviceModifier::Notify(TInt aError)
+	{
+	// Inform the Phy whether the registry has been modified
+	iParent->RegistryTaskComplete(this, iRegistryUpdateStatus, aError);
+	}
+
+CBTDeviceNameChanger::CBTDeviceNameChanger(MBTRegistryTaskNotifier& aParent,CRegistrySession& aRegSess)
+: CBTRegistryHelperBase(aParent, aRegSess)
+	{
+	}
+
+CBTDeviceNameChanger* CBTDeviceNameChanger::NewL(CRegistrySession& aRegSess,
+									  MBTRegistryTaskNotifier& aParent)
+	{
+	CBTDeviceNameChanger* self = new(ELeave) CBTDeviceNameChanger(aParent, aRegSess);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CBTDeviceNameChanger::Start(const TBTDevAddr& aAddr, const TBTDeviceName8& aName)
+	{
+	__FLOG_STATIC1(KSubsys, KComponent, _L8("Registry helper (NameChanger 0x%08x) started..."), this);
+	iAddr = aAddr;
+	iName = aName;
+	TRAPD(err, iRegistry.ModifyBluetoothDeviceNameL(iAddr, iName, iStatus));
+	SetActive();
+	if(err != KErrNone)
+		{
+		TRequestStatus* status = &iStatus;
+		User::RequestComplete(status, err);
+		}
+	}
+
+CBTLinkKeyDeleter::CBTLinkKeyDeleter(MBTRegistryTaskNotifier& aParent, CRegistrySession& aRegSess)
+: CBTRegistryHelperBase(aParent, aRegSess)
+	{
+	}
+
+void CBTLinkKeyDeleter::Start(const TBTDevAddr& aDeviceAddr)
+	{
+	__FLOG_STATIC1(KSubsys, KComponent, _L8("Registry helper (Linkkey deleter 0x%08x) started..."), this);
+	iRegistry.UnpairDevice(aDeviceAddr, iStatus);
+	SetActive();
+	}
+
+CBTLinkKeyDeleter* CBTLinkKeyDeleter::NewL(CRegistrySession& aRegSess,
+										  MBTRegistryTaskNotifier& aParent)
+	{
+	CBTLinkKeyDeleter* self = new(ELeave) CBTLinkKeyDeleter(aParent, aRegSess);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+
+
+//
+// Classes apertaining to MBtPairedDeviceNotifier //
+//
+
+
+// ----------------------------------------------------------
+//	Active Paired Device Getter (from Registry)
+// ----------------------------------------------------------
+
+CBTPairedBDAddrGetter::CBTPairedBDAddrGetter(MBTPairedDeviceNotifier& aNotifier, RBTRegServ& aRegServ)
+	: CActive(EPriorityStandard)
+	, iNotifier(aNotifier)
+	, iRegistryServer(aRegServ)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CBTPairedBDAddrGetter::~CBTPairedBDAddrGetter()
+	{
+	Cancel();
+	delete iResponseHandler;
+	iView.Close();
+	}
+	
+CBTPairedBDAddrGetter* CBTPairedBDAddrGetter::NewL(MBTPairedDeviceNotifier& aNotifier, RBTRegServ& aRegServ)
+	{
+	CBTPairedBDAddrGetter* self = new (ELeave) CBTPairedBDAddrGetter(aNotifier, aRegServ);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+	
+void CBTPairedBDAddrGetter::ConstructL()
+	{
+	User::LeaveIfError(iView.Open(iRegistryServer));
+	}
+	
+void CBTPairedBDAddrGetter::Retrieve()
+	{
+	if(!IsActive())
+		{
+		// keep copy as we go async
+		iRegistrySearch.Reset();
+		iRegistrySearch.FindBonded();
+		iView.CreateView(iRegistrySearch, iStatus);
+		iState = ECreatingView;
+		SetActive();
+		}
+	}
+
+void CBTPairedBDAddrGetter::RunL()
+	{
+	// check for error
+	TInt result = iStatus.Int();
+	if (result < 0)
+		{
+		User::Leave(result);
+		}
+		
+	switch (iState)
+		{
+		case ECreatingView:
+			{
+			if (result == 0)
+				{
+				User::Leave(KErrNotFound); // let RunError handle this
+				}
+			else
+				{
+				delete iResponseHandler; //just in case not freed
+				iResponseHandler = NULL;
+				iResponseHandler = CBTRegistryResponse::NewL(iView);
+				iResponseHandler->Start(iStatus);
+				SetActive();
+				iState = EUsingResponse;
+				}
+			break;
+			}
+			
+		case EUsingResponse:
+			{
+			RBTDeviceArray& array(iResponseHandler->Results());
+			iNotifier.MbpdnAddPairedDevices(array);
+			iState = EReady;
+			break;
+			}
+
+		case EReady:
+		default:
+			{
+			__ASSERT_DEBUG(EFalse, Panic(EPairedBDAddrGetterUnexpectedState));
+			break;
+			}
+		}
+	}
+	
+	
+TInt CBTPairedBDAddrGetter::RunError(TInt aError)
+	{
+	iNotifier.MbpdnErrorInGettingPairedDevices(aError);
+	iState = EReady;
+	return KErrNone;
+	}
+	
+
+void CBTPairedBDAddrGetter::DoCancel()
+	{
+	// Cancelling registry search.
+	iView.CancelRequest(iStatus);
+	// Cancelling response retrieval.
+	delete iResponseHandler;
+	iResponseHandler = NULL;
+	// Resetting state
+	iState = EReady;
+	}
+
+