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

📄 btserviceseng.cpp

📁 蓝牙通迅服务,挺有用的东东,希望对大家有所帮助
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// BtServicesEng.cpp
//
// Copyright (c) 2003 Symbian Ltd.	All rights reserved.
//

#include <qbtselectdlg.h>
#include <bt_sock.h>
#include <barsread.h>
#include <utf.h>
#include <btservices.rsg>
#include "btserviceseng.h"

const TInt KArrayIncrement = 5;
const TInt KMaxServiceNameLength = 256;
const TInt KDefaultLanguage = 0x0100;
const TInt KIndentationFactor = 3;

_LIT(KTextHexPrefix,"0x");

CBtServicesEng::CBtServicesEng()
: iUUIDFilter(KL2CAP)
	{
	}

CBtServicesEng::~CBtServicesEng()
	{
	delete iSdpAgent; // no need to Cancel separately
	delete iSearchPattern;
	if (iTextArray)
		{
		iTextArray->Reset();
		delete iTextArray;
		}
	if (iAttributeArray)
		{
		iAttributeArray->Reset();
		delete iAttributeArray;
		}
	iHandleArray.Close();
	delete iAttributeMatchList;
	delete iAttributeBuilder;

	iSocketServ.Close();
	iUUIDs.Close();
	iUUIDsAsText.ResetAndDestroy();
	iUUIDsAsText.Close();

	iErrorCodes.Close();
	iErrorMessages.ResetAndDestroy();
	iErrorMessages.Close();
	}

CBtServicesEng* CBtServicesEng::NewL()
	{
	CBtServicesEng* self = new(ELeave) CBtServicesEng();
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
	}

void CBtServicesEng::ConstructL()
	{
	iEikon = CEikonEnv::Static();

	iSearchPattern = CSdpSearchPattern::NewL();
	iTextArray = new(ELeave) CDesCArrayFlat(KArrayIncrement);
	iAttributeArray = new(ELeave) CDesCArrayFlat(KArrayIncrement);
	iAttributeBuilder = CBtAttributeBuilder::NewL(*this);

	HBufC8* buf = iEikon->AllocReadResourceAsDes8LC(R_UUID_AS_TEXT);
	TResourceReader res;
	res.SetBuffer(buf);

	TInt arrayCount = res.ReadInt16();
	TInt i;
	for (i = 0; i < arrayCount; i++)
		{
		TUint32 uuid = res.ReadUint32();
		iUUIDs.Append(TUUID(uuid));
		HBufC* textForm = res.ReadHBufCL();
		iUUIDsAsText.Append(textForm);
		}
	CleanupStack::PopAndDestroy(); // buf

	buf = iEikon->AllocReadResourceAsDes8LC(R_BLUETOOTH_ERROR_MESSAGES);
	res.SetBuffer(buf);
	arrayCount = res.ReadInt16();
	for (i = 0; i < arrayCount; i++)
		{
		TInt errorCode = res.ReadInt32();
		iErrorCodes.Append(errorCode);
		HBufC* message = res.ReadHBufCL();
		iErrorMessages.Append(message);
		}
	CleanupStack::PopAndDestroy(); // buf

	User::LeaveIfError(iSocketServ.Connect());
	}

void CBtServicesEng::NewDeviceSelectedL(const TBTDevAddr& aAddress,const TBTDeviceName& aDeviceName,const TBTDeviceClass& aClass)
	{
	iDeviceName = aDeviceName;
	iDeviceAddress = aAddress;
	iDeviceClass = aClass;

	GetDeviceServicesL();
	}

/**
This starts the SDP agent searching for services.
Firstly, the previous (if any) SDP agent is deleted and a
new one constructed with the address of the new device. The
record filter is set based on the UUID filter settings.
The NextRecordRequestL() function begins the search, with the
results being received via the MSdpAgentNotifier functions.
*/
void CBtServicesEng::GetDeviceServicesL()
	{
	if (iSdpAgent)
		{
		DeleteSdpAgent();
		}
	iSdpAgent = CSdpAgent::NewL(*this, iDeviceAddress); // create new SDP Agent for given device address

	iSearchPattern->Reset();
	iSearchPattern->AddL(iUUIDFilter);
	iSdpAgent->SetRecordFilterL(*iSearchPattern);

	iHandleArray.Reset();
	iTextArray->Reset();
	iView->ListBox().HandleItemRemovalL();
	iView->ListBox().DrawNow();

	TGulAlignment position(EHRightVCenter);
	_LIT(KMsgFindingServices, "Finding services");
	iView->GetEikonEnv()->BusyMsgL(KMsgFindingServices, position);
	iView->DimCancelButton(EFalse);
	iView->DimRefreshButton(ETrue);

	iSdpAgent->NextRecordRequestL();
	}

/**
The Sdp agent initially returns only record handles for each
service - this function then gets the name attribute for
each one.
*/
void CBtServicesEng::GetServiceNamesL()
	{
	if (iHandleCounter < iHandleArray.Count())
		{
		TSdpAttributeID attributeID = KSdpAttrIdOffsetServiceName + KDefaultLanguage; // only support default language for SDP
		iSdpAgent->AttributeRequestL(iHandleArray[iHandleCounter], attributeID);
		}
	else
		{
		iCurrentAttributeRequest = ENoOutstandingRequests;
		iView->GetEikonEnv()->BusyMsgCancel();
		iView->DimCancelButton(ETrue);
		iView->DimRefreshButton(EFalse);
		}
	}

/**
Begins getting the full attribute list
for a given service. Because an MSdpElementBuilder
pointer is passed in AttributeRequestL(), the SDP agent
calls the builder functions with each result, rather than
AttributeRequestResult(). 
*/
void CBtServicesEng::GetAttributesL(TInt aIndex)
	{
	iCurrentAttributeRequest = EGettingAllAttributes;
	iServiceName.Set((*iTextArray)[aIndex]);
	iAttributeArray->Reset();
	iAttributeBuilder->Reset();
	if (iAttributeMatchList)
		{
		delete iAttributeMatchList;
		iAttributeMatchList = NULL;
		}
	iAttributeMatchList = CSdpAttrIdMatchList::NewL();
	iAttributeMatchList->AddL(TAttrRange(0, KMaxTUint16)); // getting all attributes
	iAttributeBuilder->SetHandle(iHandleArray[aIndex]);
	iSdpAgent->AttributeRequestL(iAttributeBuilder, iHandleArray[aIndex], *iAttributeMatchList);
	}

void CBtServicesEng::CancelSdpAgent()
	{
	if (iSdpAgent)
		{
		iSdpAgent->Cancel();
		}
	}

void CBtServicesEng::DeleteSdpAgent()
	{
	delete iSdpAgent;
	iSdpAgent = NULL;
	}

void CBtServicesEng::SetUUIDsL()
	{
	TUint32 tempUUIDFilter = iUUIDFilter;
	if (iView->DisplayUUIDSettingsDialogL(tempUUIDFilter))
		{
		iUUIDFilter = tempUUIDFilter;
		HBufC* buf = HBufC::NewLC(KMaxDescriptorLength);
		TPtr uuidBuffer = buf->Des();
		_LIT(KStringUUIDFilter, "UUID Filter: ");
		uuidBuffer.Append(KStringUUIDFilter);
		AppendUUIDText(uuidBuffer, TUUID(iUUIDFilter));
		iView->SetUUIDTextL(uuidBuffer);
		CleanupStack::PopAndDestroy();
		if (!iView->RefreshButtonDimmed()) // an indicator that no device has been selected
			{
			GetDeviceServicesL();
			}
		}
	}

void CBtServicesEng::AppendUUIDText(TDes& aBuf, TUUID aUUID) const
	{
	if (aUUID == TUUID(0))
		{
		aUUID = TUUID(iUUIDFilter);
		}
	TInt i = 0;
	for (i = 0; i < iUUIDs.Count(); i++)
		{
		if (iUUIDs[i] == aUUID)
			{
			aBuf.Append(*(iUUIDsAsText[i]));
			return;
			}
		}
	_LIT(KTextUUIDHex,"UUID: 0x");
	aBuf.Append(KTextUUIDHex);
	TPtrC8 ptr(aUUID.ShortestForm());
	for (i = 0; i < (2 * ptr.Length()); i++) // get shortest form
		{
		aBuf.AppendNumFixedWidth(aUUID[i],EHex,2);
		}
	}

void CBtServicesEng::DisplayDeviceInfoL()
	{
	iView->DisplayDeviceInfoDialogL(iDeviceName,iDeviceAddress,iDeviceClass);
	}

void CBtServicesEng::DisplayLocalInfoL()
	{
	RSocket l2CapSock;
	TInt err = l2CapSock.Open(iSocketServ, KBTAddrFamily, KSockSeqPacket, KL2CAP);
	if (err != KErrNone)
		{
		_LIT(KErrorText,"Not supported");
		TGulAlignment position(EHRightVTop);
		iView->GetEikonEnv()->InfoMsgWithAlignmentAndDuration(position,KErrorText,KErrorMsgDuration);
		return;
		}
	CleanupClosePushL(l2CapSock);
	TRequestStatus stat;
	TBTDevAddrPckg addrbuf;
	l2CapSock.Ioctl(KHCILocalAddressIoctl, stat, &addrbuf, KSolBtHCI); // takes a TBTDevAddrPckg (TPckgBuf<TBTDevAddr>) as documented in 7.0 SDK
	User::WaitForRequest(stat);
	User::LeaveIfError(stat.Int());

	THCIDeviceClassBuf classbuf;
	l2CapSock.Ioctl(KHCIReadDeviceClassIoctl, stat, &classbuf, KSolBtHCI); // takes a THCIDeviceClassBuf (TPckgBuf<THCIDeviceClassIoctl>) as documented in 7.0 SDK
	User::WaitForRequest(stat);
	User::LeaveIfError(stat.Int());
	CleanupStack::PopAndDestroy(); // l2CapSock

	RHostResolver hr;
	User::LeaveIfError(hr.Open(iSocketServ, KBTAddrFamily, KBTLinkManager));
	CleanupClosePushL(hr);
	TBTDeviceName deviceName;
	User::LeaveIfError(hr.GetHostName(deviceName));
	CleanupStack::PopAndDestroy();

	TBTDevAddr& deviceAddress = addrbuf();
	TBTDeviceClass deviceClass(classbuf().iMajorServiceClass, classbuf().iMajorDeviceClass,classbuf().iMinorDeviceClass);

	iView->DisplayDeviceInfoDialogL(deviceName,deviceAddress,deviceClass);
	}

void CBtServicesEng::SetView(CBtServicesListView& aView)
	{
	iView = &aView;
	}

CDesCArrayFlat* CBtServicesEng::GetTextArray() const
	{
	return iTextArray;
	}

/**
Checks whether bluetooth is enabled by opening a host
resolver and immediately closing it again.
*/
TInt CBtServicesEng::BluetoothReady()
	{
	RHostResolver hr;
	TInt err = hr.Open(iSocketServ, KBTAddrFamily, KBTLinkManager); // just to check if bluetooth is enabled
	hr.Close();
	return err;
	}

TBool CBtServicesEng::GettingAllAttributes() const
	{
	return (iCurrentAttributeRequest == EGettingAllAttributes);
	}

void CBtServicesEng::AddAttributeLineL(const TDesC& aDes)
	{
	iAttributeArray->AppendL(aDes);
	}

void CBtServicesEng::AttributeRequestComplete(TSdpServRecordHandle /* aHandle */, TInt aError)
	{
	if(aError == KErrNone)
		{
		TRAP(aError, DoAttributeRequestCompleteL());
		}
	if(aError != KErrNone)
		{
		SdpCompletedWithError(aError);
		}
	}

void CBtServicesEng::DoAttributeRequestCompleteL()
	{
	if (iCurrentAttributeRequest == EGettingNamesOnly)
		{
		iHandleCounter++;
		GetServiceNamesL();
		}
	else if (iCurrentAttributeRequest == EGettingAllAttributes)
		{ // all attributes have been got
		iView->DisplayAttributeDialogL(iAttributeArray, iDeviceName, iServiceName);
		iCurrentAttributeRequest = ENoOutstandingRequests;
		}
	}

void CBtServicesEng::AttributeRequestResult(TSdpServRecordHandle /* aHandle */, TSdpAttributeID /* aAttrID */, CSdpAttrValue* aAttrValue)
	{
	TRAPD(err,DoAttributeRequestResultL(aAttrValue)); // passing ownership
	if (err != KErrNone)
		{
		iSdpAgent->Cancel();
		}
	}
	
void CBtServicesEng::DoAttributeRequestResultL(CSdpAttrValue* aAttrValue)
	{
	CleanupStack::PushL(aAttrValue); // taken ownership
	if (iCurrentAttributeRequest == EGettingNamesOnly) 
		{		 
		TBuf16<KMaxServiceNameLength> unicode;
		CnvUtfConverter::ConvertToUnicodeFromUtf8(unicode,aAttrValue->Des());
		if (unicode[unicode.Length() - 1] == L'\0')

⌨️ 快捷键说明

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