diff -r 000000000000 -r 7f656887cf89 libraries/btserial/src/connection/btincoming.cpp --- /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 +#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(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); + } + } +