--- /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);
+ }
+ }
+