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

📄 bluetooth1.cpp

📁 《UIQ 3 The Complete Guide》书的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			iObserver->StatusInfo(EBtsDisconnected,error);
			iState=ECreatorStateIdle; // need to re-initiate the connection
			}
		else
			{ // process whole frame
			if (iStatus.Int()==KErrNone)
				{
				iData.SetLength(iDataPtr.Length());
				iObserver->DataReceived(iData); // observer must use all iData
				Read(); // get next frame header, BtDataReceived() sorts out errors b4 here
				}
			else
				{
				iObserver->StatusInfo(EBtsDisconnected,iStatus.Int());
				iState=ECreatorStateIdle; // need to re-initiate the connection
				}
			}
		break;

	default:
		Panic(10);
		break;
		}
	}

void CBtConnectionCreator::DoCancel()
// Cancel any outstanding activity, maybe called from destructor
	{
	switch (iState)
		{
	case ECreatorStateFindService:
		iSdpAgent->Cancel();
		delete(iSdpAgent);
		iSdpAgent=NULL;
		delete(iSdpSearchPattern);
		iSdpSearchPattern=NULL;
		break;

	case ECreatorStateConnecting:
		iSocket.CancelConnect();
		break;

	case ECreatorStateConnected:
		iSocket.CancelRead();
		break;

	default: // logically impossible state - so programming error if we get here
		Panic(10);
		break;
		}
	iState=ECreatorStateIdle;
	}

void CBtConnectionCreator::StartDiscoveryL()
//
// Start the discovery of remote devices. Once a remote device has been chosen by the user we
// start the request to obtain a remote service discovery database entry we can use
//
	{
	__ASSERT_DEBUG(iState==ECreatorStateIdle,Panic(11));

	iRemotePort=(-1);

	CBTDeviceArray* btDeviceArray=new(ELeave)CBTDeviceArray(2);
	CleanupStack::PushL(btDeviceArray);
	TRAPD(err,
		CQBTUISelectDialog* dlg=CQBTUISelectDialog::NewL(btDeviceArray);
		if (dlg->RunDlgLD(KQBTUISelectDlgFlagNone))
			{
			if (btDeviceArray->Count()>0)
				{
				CBTDevice* dev=btDeviceArray->At(0);
				iRemoteDevAddr=dev->BDAddr();
				iRemoteDevClass=dev->DeviceClass();

				TBTDeviceName8 name(dev->DeviceName());
				iRemoteDevName=BTDeviceNameConverter::ToUnicodeL(name);

			    iSdpAgent=CSdpAgent::NewL(*this,iRemoteDevAddr);
				iSdpSearchPattern=CSdpSearchPattern::NewL();
				iSdpSearchPattern->AddL(KSerialPortServiceClass); 
				iSdpAgent->SetRecordFilterL(*iSdpSearchPattern);
				iSdpAgent->NextRecordRequestL(); // calls back NextRecordRequestComplete()

				// setup AO to represent the async SDP agent search
	            iState=ECreatorStateFindService;
		        iStatus=KRequestPending;
	            SetActive();
				}
			}
		);

	if (err!=KErrNone)
		{
		delete(iSdpAgent);
		iSdpAgent=NULL;
		delete(iSdpSearchPattern);
		iSdpSearchPattern=NULL;
		iObserver->StatusInfo(EBtsConnectionEstablished,err);
		iState=ECreatorStateIdle;
		}
	CleanupStack::PopAndDestroy(btDeviceArray);
	User::LeaveIfError(err);
	}

TInt CBtConnectionCreator::IsConnected() const
// Report if the connection creator is connected
	{
	return(iState==ECreatorStateConnected);
	}

//////////////////////////////////////////////////////////////////////////////////
class CAppSpecificView : public CQikViewBase, public MBtEngineObserver
	{
protected: 
	// from CQikViewBase
	TVwsViewId ViewId() const;
	void HandleCommandL(CQikCommand& aCommand);
	void ViewConstructL();
	void ViewDeactivated();
	void ViewActivatedL(const TVwsViewId& aPrevViewId,const TUid aCustomMessageId,const TDesC8& aCustomMessage);

	// from MBtEngineObserver
	void LogInfo(const TDesC& aBuf);
	void StatusInfo(const TBluetoothStatus,const TInt aVal);
	void DataReceived(const TDesC8& aData);

	// new methods
	void RebuildListbox();

public:
	// new methods
	~CAppSpecificView();
	CAppSpecificView(CAppSpecificUi& aAppUi);
	
protected:
	RSocketServ iSocketServer;
	CBtConnectionListener* iListenEngine;
	CBtConnectionCreator* iConnectEngine;

	CLogText* iLogText;

	TInt iMessageIndex;
	};

CAppSpecificView::~CAppSpecificView()
	{
	delete(iConnectEngine);
	delete(iListenEngine);
	delete(iLogText);
	iSocketServer.Close();
	}

CAppSpecificView::CAppSpecificView(CAppSpecificUi& aAppUi) :
	CQikViewBase(aAppUi,KNullViewId)
	{}

TVwsViewId CAppSpecificView::ViewId() const
//
// All views are uniquely identified within the entire system. A TVwsViewId consists of 
// the application uid (uid3) and app specific view uid
//
	{
	return(KViewIdListView);
	}

const TInt KMaxPredefinedMessages=6;	// we have 6 predefined messages in this example app
void CAppSpecificView::HandleCommandL(CQikCommand& aCommand)
//
// Handle the commands coming in from the controls that can deliver cmds..
//
	{
	switch (aCommand.Id())
		{
	case EAppCmdXfer:
		{
		TBuf<64> bb;
		iEikonEnv->ReadResourceL(bb,R_STR_MESSAGE_1+iMessageIndex);

		// our app is defined to take 8 bit descriptors as its data to xfer
		// assuming only Ascii chars in the msg content, this is valid. In a commercial app this is
		// unlikely to be acceptable - since many characters no not belong to Ascii table. 
		TBuf8<64> bb8;
		bb8.Copy(bb);

		// this is simple application state checking to show the sort of thing you may have to implment 
		// in your commercial grade application. This example simply blocks sending text. If text is derived from
		// user input you might want to queue the text up until a connection established. 
		if (iConnectEngine->IsConnected())
			iConnectEngine->SendData(bb8);
		else if (iListenEngine->IsConnected())
			iListenEngine->SendData(bb8);
		else
			User::Leave(KErrDisconnected);

		iMessageIndex++;
		if (iMessageIndex==KMaxPredefinedMessages)	
			iMessageIndex=0;
		break;
		}

	case EAppCmdConnect:
		// a commercial grade application needs to check the application state to ensure that 
		// neither a previous StartDiscoveryL() or StartListening() is in progress or completed
		// otherwise simply calling StartDiscoveryL() again will have adverse affects, 
		// almost certainly resulting in a PANIC due to programmer error
		iConnectEngine->StartDiscoveryL();
		break;

	case EAppCmdListen:
		// a commercial grade application needs to check the application state to ensure that 
		// neither a previous StartDiscoveryL() or StartListening() is in progress or completed
		// otherwise simply calling StartListening() agin will have adverse affects, 
		// almost certainly resulting in a PANIC due to programmer error
		iListenEngine->StartListening();
		break;

	case EEikCmdExit:
		iQikAppUi.HandleCommandL(EEikCmdExit);
		break;

	default: // e.g. the back button...
		CQikViewBase::HandleCommandL(aCommand);
		break;
		}
	}

void CAppSpecificView::RebuildListbox()
//
// Rebuild the listbox from scratch
//
	{
	TRAPD(err,
		CQikListBox* listbox=LocateControlByUniqueHandle<CQikListBox>(EAppSpecificListViewListId);
		listbox->RemoveAllItemsL();

		MQikListBoxModel& model(listbox->Model());
		model.ModelBeginUpdateLC();
		TInt count=iLogText->Count();
		for (TInt i=0;i<count;i++)
			{
			MQikListBoxData* lbData=model.NewDataL(MQikListBoxModel::EDataNormal);
			CleanupClosePushL(*lbData);
			lbData->AddTextL(iLogText->At(i),EQikListBoxSlotText1);
			CleanupStack::PopAndDestroy(lbData);
			}
		model.ModelEndUpdateL();
		);
	}

void CAppSpecificView::LogInfo(const TDesC& aBuf)
// Called back by the engine to add some log text to output log so operations are visible
	{
	// This is an example app. Logging content to the list box in this fashion cannot be 
	// recommended for commerical quality applications
	iLogText->LogText(aBuf);
	RebuildListbox();
	}

void CAppSpecificView::StatusInfo(const TBluetoothStatus aStatus,const TInt aVal)
//
// The bluetooth engine is reporting a change in status. We simply log this.
//
	{
	TBuf<128> bb;
	switch (aStatus)
		{
	case EBtsConnectionEstablished:		// a connection has been established
		_LIT(KConnectedOK,"Connected OK");
		_LIT(KConErr,"ConErr %d");
		if (aVal==KErrNone)
			bb=KConnectedOK;
		else
			bb.Format(KConErr,aVal);
		iLogText->LogText(bb);
		RebuildListbox();
		break;
	case EBtsDisconnected:				// connection been disconnected
		_LIT(KDisc,"Disc %d");
		bb.Format(KDisc,aVal);
		iLogText->LogText(bb);
		RebuildListbox();
		break;
	case EBtsDataTransmitted:			// data has been transmitted
		_LIT(KMsgSent,"Msg Sent");
		iEikonEnv->InfoMsg(KMsgSent);
		break;
		}
	}

void CAppSpecificView::DataReceived(const TDesC8& aData)
	{
	// This is an example app. Logging content to the list box in this fashion cannot be 
	// recommended for commerical quality applications
	TBuf<KMaxBluetoothDataSize> bb;
	bb.Copy(aData);
	iLogText->LogText(bb);
	RebuildListbox();
	}

void CAppSpecificView::ViewConstructL()
	{
	// Loads information about the UI configurations this view supports
	// together with definition of each view.	
	ViewConstructFromResourceL(R_APP_VIEW_CONFIGURATIONS);

	// obtain IPC connected to the Symbian socket server process that does lots on our behalf
	User::LeaveIfError(iSocketServer.Connect());

	// we store logged text here
	iLogText=new(ELeave)CLogText;
	iLogText->ConstructL();

#ifdef __WINS__

	// so at least we dont exit immediately when run on emul...
	_LIT(KRealDevices,"real devices !");
	_LIT(KEmulatorOnly,"emulator, only");
	_LIT(KNotWorkOnThe,"not work on the");
	_LIT(KThisApplicationDoes,"This application does");
	_LIT(KAttention,"Attention");

	iLogText->LogText(KRealDevices);
	iLogText->LogText(KEmulatorOnly);
	iLogText->LogText(KNotWorkOnThe);
	iLogText->LogText(KThisApplicationDoes);
	iLogText->LogText(KAttention);

#else
	// We can listen for incoming BT connections
	iListenEngine=new(ELeave)CBtConnectionListener(iSocketServer,this);
	iListenEngine->ConstructL();

	// and establish connections
	iConnectEngine=new(ELeave)CBtConnectionCreator(iSocketServer,this);
	iConnectEngine->ConstructL();
#endif

	}

void CAppSpecificView::ViewDeactivated()
//
// Here we choose to remove all items from the list box. This saves memory.
//
	{
	}

void CAppSpecificView::ViewActivatedL(
//
// The view is being activated. Generate the listbox content. Move highlight to current entry.
//
	const TVwsViewId& aPrevViewId,
	const TUid aCustomMessageId,
	const TDesC8& aCustomMessage)
	{
	RebuildListbox(); // especially if __WINS__
	}
	
//////////////////////////////////////////////////////////////////////////////
CAppSpecificUi::~CAppSpecificUi()
	{
	}

void CAppSpecificUi::ConstructL()
//
// Normal primary entry point to a Symbian App
//
	{
	CQikAppUi::ConstructL();

	// We create and add a list view.
	CAppSpecificView* list=new(ELeave)CAppSpecificView(*this);
	CleanupStack::PushL(list);
	list->ConstructL();
	AddViewL(*list);	// takes ownership
	CleanupStack::Pop(list);

	SetDefaultViewL(*list);
	}

void CAppSpecificUi::HandleCommandL(TInt aCommand)
//
// If we have commands common across all Views we can implement them here
//
	{
	switch (aCommand)
		{
	case EEikCmdExit:
		Exit();
		break;

	default:
		break;
		}
	}
	
/////////////////////////////////////////////////////////////////////////////////////////////
// Standard Symbian application framework code when creating an application
class CAppSpecificDocument : public CQikDocument
	{
protected:
	CQikAppUi* CreateAppUiL();
public:
    CAppSpecificDocument(CQikApplication& aApp);
	static CAppSpecificDocument* NewL(CQikApplication& aApp);
protected:
	};

CAppSpecificDocument::CAppSpecificDocument(CQikApplication& aApp) :
	CQikDocument(aApp)
	{
	__DECLARE_NAME(_S("CAppSpecificDocument"));
	}

CAppSpecificDocument* CAppSpecificDocument::NewL(CQikApplication& aApp)
	{
	return(new(ELeave)CAppSpecificDocument(aApp));
	}

CQikAppUi* CAppSpecificDocument::CreateAppUiL()
	{
	return(new(ELeave)CAppSpecificUi);
	}

//////////////////////////////////////////////////////////////////////////////////
// Standard Symbian application framework code when creating an application
class CAppSpecificApplication : public CQikApplication
	{
protected:
	TUid AppDllUid() const;
	CApaDocument* CreateDocumentL();
	}; 

TUid CAppSpecificApplication::AppDllUid() const
    {
    return(KAppSpecificUid);
    }

CApaDocument* CAppSpecificApplication::CreateDocumentL()
    {
    return(CAppSpecificDocument::NewL(*this));
    }

//////////////////////////////////////////////////////////////////////////////////
// Standard Symbian application start up code
LOCAL_C CApaApplication* NewApplication()
    {
    return(new CAppSpecificApplication);
    }

GLDEF_C TInt E32Main()
	{
	return(EikStart::RunApplication(NewApplication));
	}

⌨️ 快捷键说明

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