libraries/btserial/src/connection/btincoming.cpp
changeset 0 7f656887cf89
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libraries/btserial/src/connection/btincoming.cpp	Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,310 @@
+// btincoming.cpp
+// 
+// Copyright (c) 2008 - 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+// 
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+
+#include <e32base.h>
+#include "btincomingserial.h"
+#include "btservice.h"
+#include "btdebug.h"
+
+_LIT(KBtSerialPanic, "BTSerial");
+void Panic(TBtSerialPanic aReason)
+	{
+	TRACE2("BtIncoming panic %d", aReason);
+	User::Panic(KBtSerialPanic, aReason);
+	};
+	
+	
+NONSHARABLE_CLASS(CBtRegQuery) : public CActive
+	{
+public:
+	CBtRegQuery(CBluetoothIncomingSerialConnection& aOwner);
+	void Start(CBTRegistryResponse& aResponse);
+private:
+	virtual void RunL();
+	virtual void DoCancel();
+private:
+	CBluetoothIncomingSerialConnection& iOwner;
+	CBTRegistryResponse* iResponse;
+	};
+	
+
+EXPORT_C CBluetoothIncomingSerialConnection* CBluetoothIncomingSerialConnection::NewL(MBtIncomingConnectionObserver& aObserver)
+	{
+	TRACE1("CBluetoothIncomingSerialConnection::NewL");
+	CBluetoothIncomingSerialConnection* self = new(ELeave)CBluetoothIncomingSerialConnection(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+EXPORT_C CBluetoothIncomingSerialConnection::~CBluetoothIncomingSerialConnection()
+	{
+	TRACE1("CBluetoothIncomingSerialConnection::~CBluetoothIncomingSerialConnection");
+	delete iService;
+	delete iSocket;
+	iSockServ.Close();
+	iSdpSession.Close();
+	}
+	
+CBluetoothIncomingSerialConnection::CBluetoothIncomingSerialConnection(MBtIncomingConnectionObserver& aObserver)
+	: iObserver(aObserver)
+	{
+	}
+	
+void CBluetoothIncomingSerialConnection::ConstructL()
+	{
+	TRACE1("+CBluetoothIncomingSerialConnection::ConstructL");
+	User::LeaveIfError(iSdpSession.Connect());
+	User::LeaveIfError(iSockServ.Connect());
+	TUUID serialPortUUID = TUUID(0x1101);
+	iService = CBtService::NewL(serialPortUUID, iSdpSession, iSockServ, *this, KRFCOMM); 
+	
+	// create a blank socket for the incoming connection
+	iSocket = CBluetoothSocket::NewL(*this, iSockServ);
+	TRACE1("-CBluetoothIncomingSerialConnection::ConstructL");
+	}
+	
+	
+EXPORT_C void CBluetoothIncomingSerialConnection::WaitForConnection()
+	{
+	TRACE1("CBluetoothIncomingSerialConnection::WaitForConnection");
+	iService->AcceptConnection(*iSocket);
+	}
+	
+EXPORT_C TBool CBluetoothIncomingSerialConnection::Connected()
+	{
+	TRACE2("CBluetoothIncomingSerialConnection::Connected %d", iSocketReady);
+	return iSocketReady;
+	}
+	
+EXPORT_C TBTDevAddr CBluetoothIncomingSerialConnection::ConnectedDeviceAddrL()
+	{
+	if (!iSocketReady) User::Leave(KErrNotReady);
+	TBTSockAddr remote;
+	iSocket->RemoteName(remote);
+	return remote.BTAddr();
+	}
+	
+EXPORT_C void CBluetoothIncomingSerialConnection::GetConnectedDeviceNameL()
+	{
+	if (iConnectedDevice) return;
+	if (!iSocketReady) User::Leave(KErrNotReady);
+	// lazy construction....
+	if (!iRegQuery) iRegQuery = new(ELeave)CBtRegQuery(*this);
+	if (iRegQuery->IsActive())
+		{
+		return;
+		}
+	if (reinterpret_cast<RHandleBase&>(iBtRegServ).Handle() == KNullHandle)
+		{
+		User::LeaveIfError(iBtRegServ.Connect());
+		}
+	if (iBtReg.SubSessionHandle() == KNullHandle)
+		{
+		User::LeaveIfError(iBtReg.Open(iBtRegServ));
+		}
+	if (!iRegReponse) iRegReponse = CBTRegistryResponse::NewL(iBtReg);
+	
+	
+	TBTSockAddr remote;
+	iSocket->RemoteName(remote);
+
+	TBTRegistrySearch findConnected;
+	findConnected.FindAddress(remote.BTAddr());
+	TRequestStatus stat;
+	iBtReg.CreateView(findConnected, stat);
+	User::WaitForRequest(stat);
+	User::LeaveIfError(stat.Int());
+	
+	iRegQuery->Start(*iRegReponse);
+	}
+	
+void CBluetoothIncomingSerialConnection::QueryComplete(TInt aError)
+	{
+	iBtReg.CloseView();
+	if (aError == KErrNone)
+		{
+		RBTDeviceArray& results = iRegReponse->Results();
+		if (results.Count() != 1)
+			// we queried by BD address, so should get 1 (or 0) results
+			{
+			aError = KErrNotFound;
+			}
+		if (aError == KErrNone)
+			{
+			TRAP(aError, iConnectedDevice = results[0]->CopyL());
+			}
+		if (aError == KErrNone)
+			{
+			if (iConnectedDevice->IsValidFriendlyName())
+				{
+				aError = iDeviceName.Create(iConnectedDevice->FriendlyName());
+				}
+			else
+				{
+				aError = iDeviceName.Create(iConnectedDevice->DeviceName().Length());
+				if (aError == KErrNone)
+					{
+					iDeviceName.Copy(iConnectedDevice->DeviceName());
+					}
+				}
+			if (aError!=KErrNone)
+				{
+				delete iConnectedDevice;
+				iConnectedDevice = NULL;
+				}
+				
+			}
+		}
+	iObserver.BtNameReceived(aError, iDeviceName);
+	}
+
+EXPORT_C void CBluetoothIncomingSerialConnection::Write(const TDesC8& aData)
+	{
+	TRACE1("CBluetoothIncomingSerialConnection::Write");
+	__ASSERT_ALWAYS(iSocketReady, Panic(EBtSerialNotConnected));
+	__ASSERT_ALWAYS(!iSending, Panic(EBtSerialWritePending));
+	TInt err = iSocket->Send(aData, 0);
+	if (err==KErrNone)
+		{
+		iSending = ETrue;
+		}
+	else
+		{
+		iObserver.BtWriteComplete(err);
+		}
+	}
+	
+EXPORT_C void CBluetoothIncomingSerialConnection::CancelWrite()
+	{
+	TRACE1("CBluetoothIncomingSerialConnection::CancelWrite");
+	iSocket->CancelSend();
+	iSending = EFalse;
+	}
+	
+EXPORT_C void CBluetoothIncomingSerialConnection::Read(TDes8& aData)
+	{
+	TRACE1("CBluetoothIncomingSerialConnection::Read");
+	__ASSERT_ALWAYS(iSocketReady, Panic(EBtSerialNotConnected));
+	__ASSERT_ALWAYS(!iReceiving, Panic(EBtSerialReadPending));
+	aData.Zero();	
+	TInt err = iSocket->RecvOneOrMore(aData, 0, iXferLen);
+	if (err==KErrNone)
+		{
+		iReceiving = ETrue;
+		}
+	else
+		{
+		iObserver.BtReadComplete(err);
+		}
+	}
+	
+EXPORT_C void CBluetoothIncomingSerialConnection::CancelRead()
+	{
+	TRACE1("CBluetoothIncomingSerialConnection::CancelRead");
+	iSocket->CancelRead();
+	iReceiving = EFalse;
+	}
+	
+EXPORT_C void CBluetoothIncomingSerialConnection::ShutDown()
+	{
+	iSocket->Shutdown(RSocket::EImmediate);
+	}
+
+void CBluetoothIncomingSerialConnection::HandleConnectCompleteL(TInt _BTDEB(aErr))
+	{
+	TRACE2("CBluetoothIncomingSerialConnection::HandleConnectCompleteL(%d)", aErr);
+	}
+	
+void CBluetoothIncomingSerialConnection::HandleAcceptCompleteL(TInt _BTDEB(aErr))
+	{
+	TRACE2("CBluetoothIncomingSerialConnection::HandleAcceptCompleteL(%d)", aErr);
+	}
+	
+void CBluetoothIncomingSerialConnection::HandleShutdownCompleteL(TInt aErr)
+	{
+	TRACE2("CBluetoothIncomingSerialConnection::HandleShutdownCompleteL(%d)", aErr);
+	iObserver.BtShutdownComplete(aErr);
+	}
+	
+void CBluetoothIncomingSerialConnection::HandleSendCompleteL(TInt aErr)
+	{
+	TRACE1("CBluetoothIncomingSerialConnection::HandleSendCompleteL");
+	__ASSERT_ALWAYS(iSending, PANIC());
+	iSending = EFalse;
+	iObserver.BtWriteComplete(aErr);
+	}
+	
+void CBluetoothIncomingSerialConnection::HandleReceiveCompleteL(TInt aErr)
+	{
+	TRACE1("CBluetoothIncomingSerialConnection::HandleReceiveCompleteL");
+	__ASSERT_ALWAYS(iReceiving, PANIC());
+	iReceiving = EFalse;
+	iObserver.BtReadComplete(aErr);
+	}
+
+void CBluetoothIncomingSerialConnection::HandleIoctlCompleteL(TInt _BTDEB(aErr))
+	{
+	TRACE2("CBluetoothIncomingSerialConnection::HandleIoctlCompleteL(%d)", aErr);
+	}
+	
+void CBluetoothIncomingSerialConnection::HandleActivateBasebandEventNotifierCompleteL(TInt _BTDEB(aErr), TBTBasebandEventNotification& /*aEventNotification*/)
+	{
+	TRACE2("CBluetoothIncomingSerialConnection::HandleActivateBasebandEventNotifierCompleteL(%d)", aErr);
+	}
+	
+void CBluetoothIncomingSerialConnection::HandleNewConnection(CBluetoothSocket* aConnectedSocket)
+	{
+	TRACE1("CBluetoothIncomingSerialConnection::HandleNewConnection");
+	__ASSERT_ALWAYS(iSocket == aConnectedSocket, PANIC());
+	iSocketReady = ETrue;
+	iObserver.BtSerialConnected();
+	}
+	
+void CBluetoothIncomingSerialConnection::HandleConnectFailed(TInt aError)
+	{
+	TRACE2("CBluetoothIncomingSerialConnection::HandleConnectFailed", aError);
+	iSocketReady = EFalse;
+	iObserver.BtSerialError(aError);
+	}
+	
+CBtRegQuery::CBtRegQuery(CBluetoothIncomingSerialConnection& aOwner)
+	: CActive(CActive::EPriorityStandard), iOwner(aOwner)
+	{
+	CActiveScheduler::Add(this);
+	}
+	
+void CBtRegQuery::Start(CBTRegistryResponse& aBtResponse)
+	{
+	iResponse = &aBtResponse;
+	iResponse->Start(iStatus);
+	SetActive();
+	}
+		
+void CBtRegQuery::RunL()
+	{
+	iOwner.QueryComplete(iStatus.Int());
+	}
+	
+void CBtRegQuery::DoCancel()
+	{
+	iResponse->Cancel();
+	// nasty race condition inside CBTRegistryResponse which means the cancal call may not
+	// request out TRequestStatus (if DoCancel doesn't need to be called)
+	if (iStatus == KRequestPending)
+		{
+		TRequestStatus* stat = &iStatus;
+		User::RequestComplete(stat, KErrCancel);
+		}
+	}
+