bluetoothcommsprofiles/btpan/bnep/CBTAddrSubscriber.cpp
changeset 0 29b1cd4cb562
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothcommsprofiles/btpan/bnep/CBTAddrSubscriber.cpp	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,138 @@
+// Copyright (c) 2004-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:
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <bluetooth/logger.h>
+#include <es_prot.h>
+#include <bt_subscribe.h>
+#include "CBTAddrSubscriber.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_PAN_BNEP);
+#endif
+
+CBTAddrSubscriber::CBTAddrSubscriber (TBTDevAddr& aAddr, CBnepLocalDevice& aLocal)
+        : CActive(EPriorityStandard), iAddr(aAddr), iOwner(aLocal)
+    {
+    LOG_FUNC
+    CActiveScheduler::Add(this);
+    }
+
+CBTAddrSubscriber::~CBTAddrSubscriber()
+    {
+    LOG_FUNC
+    Cancel();
+    }
+
+/**
+   Create an address subscriber and queue the first request.
+   @param aAddr The address to update with published data.
+   @param aLocal The local device node which will be informed when the device
+   address changes.
+*/
+CBTAddrSubscriber* CBTAddrSubscriber::NewL (TBTDevAddr& aAddr, CBnepLocalDevice& aLocal)
+    {
+    LOG_STATIC_FUNC
+    CBTAddrSubscriber* self = new(ELeave) CBTAddrSubscriber(aAddr, aLocal);
+    CleanupStack::PushL(self);
+    User::LeaveIfError(self->iDevAddrProperty.Attach(KPropertyUidBluetoothCategory, KPropertyKeyBluetoothGetLocalDeviceAddress));
+
+    // Attempt to fetch the device address property and activate the AO subscription on 
+    // the property so that the upper layers can be notified when it is initialised by 
+    // the BT stack. If the property hasn't been initialised yet, SyncFetch will 
+    // return KErrUnderflow. In this context it is alright to ignore that return value.
+    self->SyncFetch(ETrue);
+    LOG(_L8("CBTAddrSubscriber requesting notifications"));
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+/**
+   Having been notified of a BDADDR change, notify owner if we
+   have an address at the moment.
+*/
+void CBTAddrSubscriber::RunL ()
+    {
+    LOG_FUNC
+    // Don't plan to restart the active object since the device address
+    // is unlikely to change after this runs once. However, the AO
+    // will reactivate if the property could not be fetched
+    // properly (i.e. err != KErrNone)
+    TInt err = SyncFetch(); 
+    if(KErrNone == err)
+        {
+        // Notify the upper layers of the address update.
+        iOwner.BDADDRChanged();
+        }
+    else
+        {
+        iDevAddrProperty.Subscribe(iStatus);
+        SetActive();
+        }
+    }
+
+void CBTAddrSubscriber::DoCancel ()
+    {
+    LOG_FUNC
+    iDevAddrProperty.Cancel();
+    }
+
+/**
+   Fetches the device address property synchronously if it exists.
+   Conditionally queue a request to be notified of future BDADDR changes.
+   By default, a request is not queued automatically.
+   @param aRestart specify whether to queue request and schedule the active object. Default is EFalse.
+   @return KErrUnderflow The property has zero length (i.e. is uninitialised)
+   @internalComponent
+*/
+TInt CBTAddrSubscriber::SyncFetch (TBool aRestart)
+    {
+    LOG_FUNC
+    TInt retval = KErrNone;
+    TBuf8<KBTDevAddrSize> addr;
+    iDevAddrProperty.Get(addr);
+    if (addr.Length())
+        {
+        iAddr = TBTDevAddr(addr);
+        LOG_BT(_L8("Setting address to %S"), iAddr);
+        }
+    else
+        {
+        // The property hasn't been initialised yet.
+        retval = KErrUnderflow;
+        }
+
+    if(aRestart)
+        {
+		if(retval == KErrNone)
+			{
+			// The BT stack was already up when BNEP started.  Call the
+			// BDADDRChanged method to inform the NIF that the link layer 
+			// is up.
+			iOwner.BDADDRChanged();
+			}
+		else
+			{
+	        // Watch out for any future updates on the property.
+	        iDevAddrProperty.Subscribe(iStatus);
+	        SetActive();
+			}
+        }
+    return retval;
+    }