Polling bluetooth device
Article Metadata
Tested with
Devices(s): N79, 5800XM
Compatibility
Platform(s): S60 5th Edition
S60 3rd Edition, FP2
S60 3rd Edition, FP1
S60 3rd Edition, FP2
S60 3rd Edition, FP1
Article
Keywords: RSocketServ::FindProtocol()
Created: alexodus
(10 Mar 2011)
Last edited: hamishwillee
(24 Jun 2011)
Overview
CDevicePolling example illustrates how to do a polling for a (string) list of bluetooth Media Access Control address (MAC address)
MMP file
The following capabilities and libraries are required:
LIBRARY bluetooth.lib
CAPABILITY ReadDeviceData
Header file
DevicePollng.h
#ifndef DEVICEPOLLING_H
#define DEVICEPOLLING_H
#include <e32base.h> // For CActive, link against: euser.lib
#include <badesca.h>
#include <bt_sock.h>
/**
* @class MDevicePollingObserver
* @brief Mixin Observer for device(s) polling
* @ingroup mixins
*/
class MDevicePollingObserver {
public:
/*!
* HandleDevicePollingComplete()
*
* discussion Observer interface for handling device polling complete event.
*/
virtual void HandleDevicePollingComplete(TInt aError)=0;
/*!
* DeviceFound()
*
* device found
*/
virtual void DeviceFound(const TDesC& aMacAddress)=0;
/*!
* DeviceNotFound()
*
* device not found
*/
virtual void DeviceNotFound(const TDesC& aMacAddress)=0;
};
/**
* @class CDevicePolling
* @brief Active Object for polling a list of (string) macaddress(es)
*/
class CDevicePolling : public CActive {
public:
// Cancel and destroy
~CDevicePolling();
// Two-phased constructor.
static CDevicePolling* NewL(RSocketServ& aSocketServ, MDevicePollingObserver& aObserver);
// Two-phased constructor.
static CDevicePolling* NewLC(RSocketServ& aSocketServ, MDevicePollingObserver& aObserver);
public:
// New functions
// Function for making the initial request
void PollingDevicesL(CDesCArrayFlat* aRemainingDevicesArray);
/*!
* StopPolling()
*
* Stops ongoing device polling
*
*/
void StopPolling();
private:
// C++ constructor
CDevicePolling(RSocketServ& aSocketServ, MDevicePollingObserver& aObserver);
// Second-phase constructor
void ConstructL();
private:
// From CActive
// Handle completion
void RunL();
// How to cancel me
void DoCancel();
// Override to handle leaves from RunL(). Default implementation causes
// the active scheduler to panic.
TInt RunError(TInt aError);
private:
// socket server handle
RSocketServ& iSocketServ;
// observer reference
MDevicePollingObserver& iObserver;
// host resolver
RHostResolver iResolver;
TInquirySockAddr iAddr;
TNameEntry iEntry;
CDesCArrayFlat* iRemainingDevicesArray;
};
#endif // DEVICEPOLLING_H
Source file
DevicePollng.cpp
#include "DevicePolling.h"
_LIT(KBTLinkManagerTxt,"BTLinkManager");
CDevicePolling::CDevicePolling(RSocketServ& aSocketServ, MDevicePollingObserver& aObserver) :
CActive(CActive::EPriorityStandard), iSocketServ(aSocketServ), iObserver(aObserver) {
CActiveScheduler::Add(this);
}
CDevicePolling *CDevicePolling::NewL(RSocketServ & aSocketServ, MDevicePollingObserver & aObserver) {
CDevicePolling* self = CDevicePolling::NewLC(aSocketServ,aObserver);
CleanupStack::Pop(); // self;
return self;
}
CDevicePolling *CDevicePolling::NewLC(RSocketServ & aSocketServ, MDevicePollingObserver & aObserver) {
CDevicePolling* self = new (ELeave) CDevicePolling(aSocketServ,aObserver);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
TInt CDevicePolling::RunError(TInt aError) {
return aError;
}
void CDevicePolling::ConstructL() {
iRemainingDevicesArray = new (ELeave) CDesCArrayFlat(2);
}
CDevicePolling::~CDevicePolling() {
Cancel();
iResolver.Close();
delete iRemainingDevicesArray;
}
void CDevicePolling::DoCancel() {
iResolver.Cancel();
}
void CDevicePolling::PollingDevicesL(CDesCArrayFlat* aRemainingDevicesArray) {
iRemainingDevicesArray->Reset();
for (TInt i = 0; i< aRemainingDevicesArray->Count(); i++) {
iRemainingDevicesArray->AppendL((*aRemainingDevicesArray) [i] );
}
if (!IsActive()) {
// initialize host resolver
// load protocol for discovery
TProtocolDesc pdesc;
User::LeaveIfError(iSocketServ.FindProtocol(KBTLinkManagerTxt(), pdesc));
iResolver.Close();
User::LeaveIfError(iResolver.Open(iSocketServ, pdesc.iAddrFamily, pdesc.iProtocol));
// start device discovery by invoking remote address lookup
#ifdef ENABLE_LIAC
TUint myIAC( iLIAC?KLIAC:KGIAC );
iAddr.SetIAC( myIAC );
#else
iAddr.SetIAC(KGIAC);
#endif
iAddr.SetAction(KHostResInquiry | KHostResIgnoreCache);
iResolver.GetByAddress(iAddr, iEntry, iStatus);
SetActive();
}
else {
User::Leave(KErrNotReady);
}
}
void CDevicePolling::RunL() {
// RHostResolver.GetByAddress(..) has completed, process results
if (iStatus != KErrNone) {
// all devices (if any) done, notify
for (TInt i = 0; i<iRemainingDevicesArray->Count();i++) {
iObserver.DeviceNotFound((*iRemainingDevicesArray)[i]);
}
iObserver.HandleDevicePollingComplete(KErrNone);
}
else {
// new device data entry
TBTDevAddr m = static_cast<TBTSockAddr> (iEntry().iAddr).BTAddr();
TBuf<25> tBufAddr;
m.GetReadable(tBufAddr);
TInt pos;
TInt error = iRemainingDevicesArray->Find(tBufAddr,pos);
if (error == KErrNone) {
//device found in array
if (pos>=0) {
iRemainingDevicesArray->Delete(pos);
iObserver.DeviceFound(tBufAddr);
}
} else {
//device not found
}
if (iRemainingDevicesArray->Count()>0) {
// get next discovered device
iResolver.Next(iEntry, iStatus);
// wait for resolver to complete
SetActive();
} else {
//
iObserver.HandleDevicePollingComplete(KErrNone);
}
}
}
void CDevicePolling::StopPolling() {
Cancel();
iObserver.HandleDevicePollingComplete(KErrNone);
}
Example code:
Example.h
class CExample : public CBase,
public MDevicePollingObserver {
public:
[...]
~CExample();
public:
// New functions
//from MDevicePollingObserver
void HandleDevicePollingComplete(TInt aError);
void DeviceFound(const TDesC& aMacAddress);
void DeviceNotFound(const TDesC& aMacAddress);
private:
// Basic two-phase EPOC constructors
/*!
* ConstructL()
*
*/
void ConstructL();
private:
// data members
// device polling
CDevicePolling* iDevicePolling;
// socket server
RSocketServ iSocketServ;
};
#endif
Example.cpp
[...]
void CExample::::ConstructL() {
[...]
// get socket server session
User::LeaveIfError(iSocketServ.Connect());
// init device polling
iDevicePolling = CDevicePolling::NewL(iSocketServ, *this);
CDevicePollingCDesCArrayFlat* remainingDevicesArray = new (ELeave) CDesCArrayFlat(2);
//populating macaddress list
remainingDevicesArray->AppendL(_L("macaddress1"));
[...]
remainingDevicesArray->AppendL(_L("macaddress2"));
iDevicePolling->PollingDevicesL(remainingDevicesArray);
}
CExample::~CExample() {
[...]
iDevicePolling->Cancel();
delete iDevicePolling;
iSocketServ.Close();
}
void CExample::HandleDevicePollingComplete(TInt aError) {
// polling finished
}
void CExample::DeviceFound(const TDesC& aMacAddress) {
//device found
}
void CExample::DeviceNotFound(const TDesC& aMacAddress) {
//device not found
}


(no comments yet)