搜索藍牙服務

轉自:http://wiki.forum.nokia.com/index.php/CS000937_-_Discovering_Bluetooth_services

 

MMP file

The following capabilities and libraries are required:

CAPABILITY    LocalServices
LIBRARY       sdpagent.lib
LIBRARY       sdpdatabase.lib

Header file

#include <btsdp.h>
 
// The service ID that identifies the service. This ID is 
// used when advertising the service and discovering the service.
#define KBT_serviceID 0x10ff
 
class CMyServiceDiscoverer : public CBase,
                             public MSdpAgentNotifier,
                             public MSdpAttributeValueVisitor
{
...
 
// Service discovery agent
CSdpAgent*          iAgent;
 
// Service discovery search pattern
CSdpSearchPattern*  iSpat;
 
// Index of device in device data list used for service discovery
TInt                iDeviceIdx;
 
// Last discovered uuid in the service attributes
TUUID iLastUUID;
 
// Port (comm channel) found in the service attributes
TUint iPort;

 

Source file

Discover services on a given device. The service discovery agent will be started to do the discovery of services on given remote device. Service discovery will be limited to search only for services with the service ID.

void CMyServiceDiscoverer::DiscoverServicesOnDeviceL(TBTDevAddr* aDevAddr)
    {
    // Init new service discovery agent
    iAgent = CSdpAgent::NewL( *this, aDevAddr);
 
    // Set search properties for agent
    iSpat = CSdpSearchPattern::NewL();
 
    // Use own service id to filter the services discovered
    // -> will return only the services with matching service id(s)
    TUUID serviceUUID(KBT_serviceID);
    iSpat->AddL(serviceUUID);
    iAgent->SetRecordFilterL(*iSpat);
 
    // Initiate search
    // this will result in call to NextRecordRequestComplete()
    iAgent->NextRecordRequestL();
    }

Called when the service discovery agent has completed discovering services on device.

// from MSdpAgentNotifier
void CMyServiceDiscoverer::NextRecordRequestComplete(
    TInt aError,
    TSdpServRecordHandle aHandle,
    TInt aTotalRecordsCount)
    {
    if ( aError==KErrNone && aTotalRecordsCount>0 )
        {
        // We got records, retrieve attributes for record
        // request protocol descriptor from remote device records,
        // we need this to retrieve remote port to connect to later on.
        // Calls AttributeRequestResult()
        TRAPD(err,iAgent->AttributeRequestL(aHandle, KSdpAttrIdProtocolDescriptorList));
        if( err )
            {
            // TODO: Handle error
            }
        }
    else
        {
        // Done with this device
 
        // Discover services on next device, if any left
        iDeviceIdx++;
        if ( iDeviceIdx<iDevDataList->Count() )
            {
            // More devices to probe, proceed
            // TODO: Call DiscoverServicesOnDeviceL() again with 
            // next TBTDevAddr
            }
        else
            {
            // All devices done
            FinishDiscovery();
            }
        }
    }

Called when the service attributes for the service record have been retrieved.

// from MSdpAgentNotifier
void CMyServiceDiscoverer::AttributeRequestResult(
    TSdpServRecordHandle aHandle,
    TSdpAttributeID aAttrID,
    CSdpAttrValue* aAttrValue)
    {
    // Parse attributes, will result in call to VisitAttributeValue()
    TRAPD(err,aAttrValue->AcceptVisitorL(*this) );
    if( err )
        {
        // TODO: Handle error
        }
    delete aAttrValue;
    }

Called for processing of each service attribute. Check for attributes of UUID type. If the UUID is RFCOMM UUID, resolve the value for this attribute, which will be the channel number to be used for connecting to the remote device.

// From MSdpAttributeValueVisitor
void CMyServiceDiscoverer::VisitAttributeValueL(
    CSdpAttrValue &aValue,
    TSdpElementType aType)
    {
    switch (aType)
        {
        case ETypeUUID:
            {
            TPtrC8 uuid(aValue.UUID().ShortestForm());
            iLastUUID.SetL(uuid);
            break;
            }
        case ETypeUint:
            {
            if ( iLastUUID==KRFCOMM )
                {
                // Previous call to this method with rfcomm UUID, therefore
                // this one will be the value, rfcomm service channel (port)
                iPort=aValue.Uint();
                }
            break;
            }
        default:
            // the rest don't really matter..
            break;
        }
    }

Called when the request to resolve the service attributes for the service record completes. If there are more service records, proceed by resolving the next service record.

// From MSdpAgentNotifier
void CServiceDiscoverer::AttributeRequestComplete(
    TSdpServRecordHandle aHandle,
    TInt aError)
    {
    if ( aError==KErrNone )
        {
        // Done with attributes for this record, request next
        // service record, this calls NextRecordRequestComplete()
        TRAPD(err,iAgent->NextRecordRequestL());
        if( err )
            {
            // TODO: Handle error
            }
        }
    else
        {
        // TODO: Handle error
        }
    }
void CMyServiceDiscoverer::FinishDiscovery()
    {
    if(iAgent)
        {
        iAgent->Cancel();
        }
    delete iAgent;
    if(iSpat)
        {
        iSpat->Reset();
        }
    delete iSpat;
    }

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章