⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btservicesearcher.cpp

📁 S60培训教材代码(连载)
💻 CPP
字号:
/* Copyright (c) 2002, Nokia Mobile Phones. All rights reserved */

#include "BTServiceSearcher.h"
#include "S60btlabapp.h"
#include <bt_sock.h>
#include "MessageProtocolConstants.h"


CBTServiceSearcher::CBTServiceSearcher(TInt aServiceClassID, TUint32 aAppUID, MLog& aLog) :
    iServiceClassID(aServiceClassID),
    iAppUID(aAppUID),
    iHostAppUID(0),
    iVisitAppUID(EFalse),
    iLog(aLog)
    {
    }

CBTServiceSearcher::~CBTServiceSearcher()
    {
    delete iAgent;
    iAgent = NULL;
    }

void CBTServiceSearcher::SelectDeviceByDiscoveryL()
    {
    RNotifier deviceNotifier;
    User::LeaveIfError(deviceNotifier.Connect());

    // Selection parameters
    TBTDeviceSelectionParams parameters;
    parameters.SetUUID(iServiceClassID);

    // Make device selection parameter package.
    TBTDeviceSelectionParamsPckg pckg(parameters);

    // Response parameters
    TBTDeviceResponseParamsPckg resPckg; 

    // Then we issue request to notifier
    TRequestStatus status;
    deviceNotifier.StartNotifierAndGetResponse(status, KDeviceSelectionNotifierUid, pckg, resPckg);
    User::WaitForRequest(status);
    deviceNotifier.CancelNotifier(KDeviceSelectionNotifierUid);
    
    // Close notifier
    deviceNotifier.Close();

    if (KErrNone == status.Int())
        {
        if (resPckg().IsValidBDAddr())
            {
            // Copy information to returned device
            iDeviceInfo.SetDeviceAddress ( resPckg().BDAddr() );
            iDeviceInfo.SetDeviceName( resPckg().DeviceName() );
            iDeviceInfo.SetDeviceClass( resPckg().DeviceClass() );
            }
        else
            {
            // The value found was invalid for some reason
            User::Leave(KErrNotFound);
            }
        }
    else
        {
        // User probably pressed cancel
        User::Leave(KErrCancel);
        }
    }


void CBTServiceSearcher::FindServiceL(TRequestStatus& aObserverRequestStatus)
    {
    SelectDeviceByDiscoveryL();

    // delete any existing agent
    delete iAgent;
    iAgent = NULL;

    // the bluetooth address of the previously selected device
    // is used to construct the agent
    iAgent = CSdpAgent::NewL(*this, iDeviceInfo.BDAddr());

    CSdpSearchPattern* searchPattern = CSdpSearchPattern::NewL();
    CleanupStack::PushL(searchPattern);

    // add the Service Class ID to the search pattern
    searchPattern->AddL(iServiceClassID); 

    // setup the agent with the search pattern
    iAgent->SetRecordFilterL(*searchPattern);

    // keep track of the external request status so the caller  
    // can be notified when the the search is complete
    iStatusObserver = &aObserverRequestStatus;

    // Perform asynchronous search
    iAgent->NextRecordRequestL();

    CleanupStack::PopAndDestroy();
    }

void CBTServiceSearcher::NextRecordRequestComplete(TInt aError, 
                                                   TSdpServRecordHandle aHandle, 
                                                   TInt aTotalRecordsCount)
    {
    iLog.LogL(_L8("NextRecordRequestComplete, num records = "), aTotalRecordsCount);

    if (KErrNone == aError && aTotalRecordsCount)
        {
        TRAP(
            aError,
            CSdpAttrIdMatchList* matchList = CSdpAttrIdMatchList::NewL();
	        CleanupStack::PushL(matchList);
            // Get L2CAP & RFCOMM channel numbers
	        matchList->AddL(TAttrRange(KSdpAttrIdProtocolDescriptorList));
            // Get the ID of the hosted game 
            matchList->AddL(TAttrRange(KAppUIDAttr));
	        iAgent->AttributeRequestL(aHandle, *matchList);
	        CleanupStack::PopAndDestroy(); // matchList - AttributeRequestL makes a copy
            );
        }
    if (KErrNone != aError || !aTotalRecordsCount)
        {
        // inform the caller that the search has failed
        Finished(KErrNotFound);
        }
    }

void CBTServiceSearcher::AttributeRequestResult(TSdpServRecordHandle /*aHandle*/,
                                                TSdpAttributeID aAttrID, 
                                                CSdpAttrValue* aAttrValue)
    {
    TRAPD(
        error,
        if (KSdpAttrIdProtocolDescriptorList == aAttrID)
            {
            // this is the attribute associated with port no
            iLog.LogL(_L8("AttributeRequestResult - getting port no"));
            aAttrValue->AcceptVisitorL(*this);
            }
        else if (KAppUIDAttr == aAttrID)
            {
            // this is the attribute associated with the app uid
            iLog.LogL(_L8("AttributeRequestResult - getting host app uid"));
            iVisitAppUID = ETrue;
            aAttrValue->AcceptVisitorL(*this);
            }
        )
    if (error != KErrNone)
        {
        // an error occured - notify the calling code
        Finished(error);
        }
    }


void CBTServiceSearcher::AttributeRequestComplete(TSdpServRecordHandle /*aHandle*/, TInt aError)
    {
    iLog.LogL(_L8("AttributeRequestComplete aError = "), aError);
    if (KErrNone == aError)
        {
        if (iHostAppUID == iAppUID)
            {
		    // the remote hosts app Uid matches this applications Uid
            iLog.LogL(_L8("Found service"));
            Finished();
            }
        else
            {
            iLog.LogL(_L8("Requesting next record"));
            iAgent->NextRecordRequestL();
            }
        }
    else
        {
        Finished(aError);
        }
    }

void CBTServiceSearcher::StartListL(CSdpAttrValueList&)
    {
    // no need for implementation
    }

void CBTServiceSearcher::VisitAttributeValueL(CSdpAttrValue &aValue, TSdpElementType aType)
    {
    if (aType == ETypeUint)
        {
        if (iVisitAppUID)
            {
            iVisitAppUID = EFalse;
            iHostAppUID = aValue.Uint();
            iLog.LogL(_L8("Host App UID = "), iHostAppUID);
            }
        else
            {
            iPort = static_cast<TInt>(aValue.Uint());
            iLog.LogL(_L8("Port No = "), iPort);
            }
        }
    }

void CBTServiceSearcher::EndListL()
    {
    // no need for implementation
    }


void CBTServiceSearcher::Finished(TInt aError /* default = KErrNone */)
    {
    User::RequestComplete(iStatusObserver, aError);
    }


const TBTDevAddr& CBTServiceSearcher::BTDevAddr()
    {
    return iDeviceInfo.BDAddr();
    }

TInt CBTServiceSearcher::Port() const
    {
    return iPort;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -