libraries/btserial/src/connection/btincoming.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // btincoming.cpp
       
     2 // 
       
     3 // Copyright (c) 2008 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include <e32base.h>
       
    14 #include "btincomingserial.h"
       
    15 #include "btservice.h"
       
    16 #include "btdebug.h"
       
    17 
       
    18 _LIT(KBtSerialPanic, "BTSerial");
       
    19 void Panic(TBtSerialPanic aReason)
       
    20 	{
       
    21 	TRACE2("BtIncoming panic %d", aReason);
       
    22 	User::Panic(KBtSerialPanic, aReason);
       
    23 	};
       
    24 	
       
    25 	
       
    26 NONSHARABLE_CLASS(CBtRegQuery) : public CActive
       
    27 	{
       
    28 public:
       
    29 	CBtRegQuery(CBluetoothIncomingSerialConnection& aOwner);
       
    30 	void Start(CBTRegistryResponse& aResponse);
       
    31 private:
       
    32 	virtual void RunL();
       
    33 	virtual void DoCancel();
       
    34 private:
       
    35 	CBluetoothIncomingSerialConnection& iOwner;
       
    36 	CBTRegistryResponse* iResponse;
       
    37 	};
       
    38 	
       
    39 
       
    40 EXPORT_C CBluetoothIncomingSerialConnection* CBluetoothIncomingSerialConnection::NewL(MBtIncomingConnectionObserver& aObserver)
       
    41 	{
       
    42 	TRACE1("CBluetoothIncomingSerialConnection::NewL");
       
    43 	CBluetoothIncomingSerialConnection* self = new(ELeave)CBluetoothIncomingSerialConnection(aObserver);
       
    44 	CleanupStack::PushL(self);
       
    45 	self->ConstructL();
       
    46 	CleanupStack::Pop(self);
       
    47 	return self;
       
    48 	}
       
    49 
       
    50 EXPORT_C CBluetoothIncomingSerialConnection::~CBluetoothIncomingSerialConnection()
       
    51 	{
       
    52 	TRACE1("CBluetoothIncomingSerialConnection::~CBluetoothIncomingSerialConnection");
       
    53 	delete iService;
       
    54 	delete iSocket;
       
    55 	iSockServ.Close();
       
    56 	iSdpSession.Close();
       
    57 	}
       
    58 	
       
    59 CBluetoothIncomingSerialConnection::CBluetoothIncomingSerialConnection(MBtIncomingConnectionObserver& aObserver)
       
    60 	: iObserver(aObserver)
       
    61 	{
       
    62 	}
       
    63 	
       
    64 void CBluetoothIncomingSerialConnection::ConstructL()
       
    65 	{
       
    66 	TRACE1("+CBluetoothIncomingSerialConnection::ConstructL");
       
    67 	User::LeaveIfError(iSdpSession.Connect());
       
    68 	User::LeaveIfError(iSockServ.Connect());
       
    69 	TUUID serialPortUUID = TUUID(0x1101);
       
    70 	iService = CBtService::NewL(serialPortUUID, iSdpSession, iSockServ, *this, KRFCOMM); 
       
    71 	
       
    72 	// create a blank socket for the incoming connection
       
    73 	iSocket = CBluetoothSocket::NewL(*this, iSockServ);
       
    74 	TRACE1("-CBluetoothIncomingSerialConnection::ConstructL");
       
    75 	}
       
    76 	
       
    77 	
       
    78 EXPORT_C void CBluetoothIncomingSerialConnection::WaitForConnection()
       
    79 	{
       
    80 	TRACE1("CBluetoothIncomingSerialConnection::WaitForConnection");
       
    81 	iService->AcceptConnection(*iSocket);
       
    82 	}
       
    83 	
       
    84 EXPORT_C TBool CBluetoothIncomingSerialConnection::Connected()
       
    85 	{
       
    86 	TRACE2("CBluetoothIncomingSerialConnection::Connected %d", iSocketReady);
       
    87 	return iSocketReady;
       
    88 	}
       
    89 	
       
    90 EXPORT_C TBTDevAddr CBluetoothIncomingSerialConnection::ConnectedDeviceAddrL()
       
    91 	{
       
    92 	if (!iSocketReady) User::Leave(KErrNotReady);
       
    93 	TBTSockAddr remote;
       
    94 	iSocket->RemoteName(remote);
       
    95 	return remote.BTAddr();
       
    96 	}
       
    97 	
       
    98 EXPORT_C void CBluetoothIncomingSerialConnection::GetConnectedDeviceNameL()
       
    99 	{
       
   100 	if (iConnectedDevice) return;
       
   101 	if (!iSocketReady) User::Leave(KErrNotReady);
       
   102 	// lazy construction....
       
   103 	if (!iRegQuery) iRegQuery = new(ELeave)CBtRegQuery(*this);
       
   104 	if (iRegQuery->IsActive())
       
   105 		{
       
   106 		return;
       
   107 		}
       
   108 	if (reinterpret_cast<RHandleBase&>(iBtRegServ).Handle() == KNullHandle)
       
   109 		{
       
   110 		User::LeaveIfError(iBtRegServ.Connect());
       
   111 		}
       
   112 	if (iBtReg.SubSessionHandle() == KNullHandle)
       
   113 		{
       
   114 		User::LeaveIfError(iBtReg.Open(iBtRegServ));
       
   115 		}
       
   116 	if (!iRegReponse) iRegReponse = CBTRegistryResponse::NewL(iBtReg);
       
   117 	
       
   118 	
       
   119 	TBTSockAddr remote;
       
   120 	iSocket->RemoteName(remote);
       
   121 
       
   122 	TBTRegistrySearch findConnected;
       
   123 	findConnected.FindAddress(remote.BTAddr());
       
   124 	TRequestStatus stat;
       
   125 	iBtReg.CreateView(findConnected, stat);
       
   126 	User::WaitForRequest(stat);
       
   127 	User::LeaveIfError(stat.Int());
       
   128 	
       
   129 	iRegQuery->Start(*iRegReponse);
       
   130 	}
       
   131 	
       
   132 void CBluetoothIncomingSerialConnection::QueryComplete(TInt aError)
       
   133 	{
       
   134 	iBtReg.CloseView();
       
   135 	if (aError == KErrNone)
       
   136 		{
       
   137 		RBTDeviceArray& results = iRegReponse->Results();
       
   138 		if (results.Count() != 1)
       
   139 			// we queried by BD address, so should get 1 (or 0) results
       
   140 			{
       
   141 			aError = KErrNotFound;
       
   142 			}
       
   143 		if (aError == KErrNone)
       
   144 			{
       
   145 			TRAP(aError, iConnectedDevice = results[0]->CopyL());
       
   146 			}
       
   147 		if (aError == KErrNone)
       
   148 			{
       
   149 			if (iConnectedDevice->IsValidFriendlyName())
       
   150 				{
       
   151 				aError = iDeviceName.Create(iConnectedDevice->FriendlyName());
       
   152 				}
       
   153 			else
       
   154 				{
       
   155 				aError = iDeviceName.Create(iConnectedDevice->DeviceName().Length());
       
   156 				if (aError == KErrNone)
       
   157 					{
       
   158 					iDeviceName.Copy(iConnectedDevice->DeviceName());
       
   159 					}
       
   160 				}
       
   161 			if (aError!=KErrNone)
       
   162 				{
       
   163 				delete iConnectedDevice;
       
   164 				iConnectedDevice = NULL;
       
   165 				}
       
   166 				
       
   167 			}
       
   168 		}
       
   169 	iObserver.BtNameReceived(aError, iDeviceName);
       
   170 	}
       
   171 
       
   172 EXPORT_C void CBluetoothIncomingSerialConnection::Write(const TDesC8& aData)
       
   173 	{
       
   174 	TRACE1("CBluetoothIncomingSerialConnection::Write");
       
   175 	__ASSERT_ALWAYS(iSocketReady, Panic(EBtSerialNotConnected));
       
   176 	__ASSERT_ALWAYS(!iSending, Panic(EBtSerialWritePending));
       
   177 	TInt err = iSocket->Send(aData, 0);
       
   178 	if (err==KErrNone)
       
   179 		{
       
   180 		iSending = ETrue;
       
   181 		}
       
   182 	else
       
   183 		{
       
   184 		iObserver.BtWriteComplete(err);
       
   185 		}
       
   186 	}
       
   187 	
       
   188 EXPORT_C void CBluetoothIncomingSerialConnection::CancelWrite()
       
   189 	{
       
   190 	TRACE1("CBluetoothIncomingSerialConnection::CancelWrite");
       
   191 	iSocket->CancelSend();
       
   192 	iSending = EFalse;
       
   193 	}
       
   194 	
       
   195 EXPORT_C void CBluetoothIncomingSerialConnection::Read(TDes8& aData)
       
   196 	{
       
   197 	TRACE1("CBluetoothIncomingSerialConnection::Read");
       
   198 	__ASSERT_ALWAYS(iSocketReady, Panic(EBtSerialNotConnected));
       
   199 	__ASSERT_ALWAYS(!iReceiving, Panic(EBtSerialReadPending));
       
   200 	aData.Zero();	
       
   201 	TInt err = iSocket->RecvOneOrMore(aData, 0, iXferLen);
       
   202 	if (err==KErrNone)
       
   203 		{
       
   204 		iReceiving = ETrue;
       
   205 		}
       
   206 	else
       
   207 		{
       
   208 		iObserver.BtReadComplete(err);
       
   209 		}
       
   210 	}
       
   211 	
       
   212 EXPORT_C void CBluetoothIncomingSerialConnection::CancelRead()
       
   213 	{
       
   214 	TRACE1("CBluetoothIncomingSerialConnection::CancelRead");
       
   215 	iSocket->CancelRead();
       
   216 	iReceiving = EFalse;
       
   217 	}
       
   218 	
       
   219 EXPORT_C void CBluetoothIncomingSerialConnection::ShutDown()
       
   220 	{
       
   221 	iSocket->Shutdown(RSocket::EImmediate);
       
   222 	}
       
   223 
       
   224 void CBluetoothIncomingSerialConnection::HandleConnectCompleteL(TInt _BTDEB(aErr))
       
   225 	{
       
   226 	TRACE2("CBluetoothIncomingSerialConnection::HandleConnectCompleteL(%d)", aErr);
       
   227 	}
       
   228 	
       
   229 void CBluetoothIncomingSerialConnection::HandleAcceptCompleteL(TInt _BTDEB(aErr))
       
   230 	{
       
   231 	TRACE2("CBluetoothIncomingSerialConnection::HandleAcceptCompleteL(%d)", aErr);
       
   232 	}
       
   233 	
       
   234 void CBluetoothIncomingSerialConnection::HandleShutdownCompleteL(TInt aErr)
       
   235 	{
       
   236 	TRACE2("CBluetoothIncomingSerialConnection::HandleShutdownCompleteL(%d)", aErr);
       
   237 	iObserver.BtShutdownComplete(aErr);
       
   238 	}
       
   239 	
       
   240 void CBluetoothIncomingSerialConnection::HandleSendCompleteL(TInt aErr)
       
   241 	{
       
   242 	TRACE1("CBluetoothIncomingSerialConnection::HandleSendCompleteL");
       
   243 	__ASSERT_ALWAYS(iSending, PANIC());
       
   244 	iSending = EFalse;
       
   245 	iObserver.BtWriteComplete(aErr);
       
   246 	}
       
   247 	
       
   248 void CBluetoothIncomingSerialConnection::HandleReceiveCompleteL(TInt aErr)
       
   249 	{
       
   250 	TRACE1("CBluetoothIncomingSerialConnection::HandleReceiveCompleteL");
       
   251 	__ASSERT_ALWAYS(iReceiving, PANIC());
       
   252 	iReceiving = EFalse;
       
   253 	iObserver.BtReadComplete(aErr);
       
   254 	}
       
   255 
       
   256 void CBluetoothIncomingSerialConnection::HandleIoctlCompleteL(TInt _BTDEB(aErr))
       
   257 	{
       
   258 	TRACE2("CBluetoothIncomingSerialConnection::HandleIoctlCompleteL(%d)", aErr);
       
   259 	}
       
   260 	
       
   261 void CBluetoothIncomingSerialConnection::HandleActivateBasebandEventNotifierCompleteL(TInt _BTDEB(aErr), TBTBasebandEventNotification& /*aEventNotification*/)
       
   262 	{
       
   263 	TRACE2("CBluetoothIncomingSerialConnection::HandleActivateBasebandEventNotifierCompleteL(%d)", aErr);
       
   264 	}
       
   265 	
       
   266 void CBluetoothIncomingSerialConnection::HandleNewConnection(CBluetoothSocket* aConnectedSocket)
       
   267 	{
       
   268 	TRACE1("CBluetoothIncomingSerialConnection::HandleNewConnection");
       
   269 	__ASSERT_ALWAYS(iSocket == aConnectedSocket, PANIC());
       
   270 	iSocketReady = ETrue;
       
   271 	iObserver.BtSerialConnected();
       
   272 	}
       
   273 	
       
   274 void CBluetoothIncomingSerialConnection::HandleConnectFailed(TInt aError)
       
   275 	{
       
   276 	TRACE2("CBluetoothIncomingSerialConnection::HandleConnectFailed", aError);
       
   277 	iSocketReady = EFalse;
       
   278 	iObserver.BtSerialError(aError);
       
   279 	}
       
   280 	
       
   281 CBtRegQuery::CBtRegQuery(CBluetoothIncomingSerialConnection& aOwner)
       
   282 	: CActive(CActive::EPriorityStandard), iOwner(aOwner)
       
   283 	{
       
   284 	CActiveScheduler::Add(this);
       
   285 	}
       
   286 	
       
   287 void CBtRegQuery::Start(CBTRegistryResponse& aBtResponse)
       
   288 	{
       
   289 	iResponse = &aBtResponse;
       
   290 	iResponse->Start(iStatus);
       
   291 	SetActive();
       
   292 	}
       
   293 		
       
   294 void CBtRegQuery::RunL()
       
   295 	{
       
   296 	iOwner.QueryComplete(iStatus.Int());
       
   297 	}
       
   298 	
       
   299 void CBtRegQuery::DoCancel()
       
   300 	{
       
   301 	iResponse->Cancel();
       
   302 	// nasty race condition inside CBTRegistryResponse which means the cancal call may not
       
   303 	// request out TRequestStatus (if DoCancel doesn't need to be called)
       
   304 	if (iStatus == KRequestPending)
       
   305 		{
       
   306 		TRequestStatus* stat = &iStatus;
       
   307 		User::RequestComplete(stat, KErrCancel);
       
   308 		}
       
   309 	}
       
   310