--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/bthid/bthidserver/src/socketinitiator.cpp Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,237 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: This is the implementation of application class
+ *
+*/
+
+#include <e32debug.h>
+#include "hiddebug.h"
+#include "socketinitiator.h"
+#include "sockinitnotifier.h"
+#include "timeouttimer.h"
+#include "bthidtypes.h"
+#include "sockets.pan"
+#include "debug.h"
+// The transport protocol of the sockets used by this object.
+_LIT(KTransportProtocol, "L2CAP");
+
+// 60*2 seconds socket connect time-out (initially this was 10 seconds, but was changed due to end-user feedback)
+const TInt CSocketInitiator::KTimeOut = 120000000;
+
+CSocketInitiator* CSocketInitiator::NewL(RSocketServ& aSocketServ,
+ MSockInitNotifier& aNotifier)
+ {
+ CSocketInitiator* self = NewLC(aSocketServ, aNotifier);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CSocketInitiator* CSocketInitiator::NewLC(RSocketServ& aSocketServ,
+ MSockInitNotifier& aNotifier)
+ {
+ CSocketInitiator* self = new (ELeave) CSocketInitiator(aSocketServ,
+ aNotifier);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+CSocketInitiator::CSocketInitiator(RSocketServ& aSocketServ,
+ MSockInitNotifier& aNotifier) :
+ CActive(CActive::EPriorityStandard), iSocketServ(aSocketServ), iNotifier(
+ aNotifier), iState(EIdle)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CSocketInitiator::~CSocketInitiator()
+ {
+ TRACE_INFO((_L("[BTHID]\tCSocketInitiator::~CSocketInitiator()")));
+ Cancel(); // Causes DoCancel
+
+ delete iTimer;
+ }
+
+void CSocketInitiator::ConnectSocketsL(const TBTDevAddr& aAddress,
+ TBool aUseSecurity, RSocket* aControlSocket,
+ RSocket* aInterruptSocket)
+ {
+ TRACE_INFO((_L("[BTHID]\tCSocketInitiator::ConnectSocketsL")));
+ // Store the params for later
+ iControlSocket = aControlSocket;
+ iInterruptSocket = aInterruptSocket;
+ iUseSecurity = aUseSecurity;
+
+ // First close the sockets
+ iControlSocket->Close();
+ iInterruptSocket->Close();
+
+ // Try to open the sockets as L2CAP
+ User::LeaveIfError(iControlSocket->Open(iSocketServ, KTransportProtocol));
+ User::LeaveIfError(
+ iInterruptSocket->Open(iSocketServ, KTransportProtocol));
+
+ iSockAddress.SetBTAddr(aAddress);
+ // First connect the control channel
+ iSockAddress.SetPort(KL2CAPHidControl);
+
+ // Set security requirements for the Control channel.
+ TBTServiceSecurity sec;
+ sec.SetAuthentication(aUseSecurity); //Require authentication
+ sec.SetEncryption(aUseSecurity); //and encryption.
+ sec.SetAuthorisation(EFalse); //and authorisation (This not needed for out-going connections)
+ iSockAddress.SetSecurity(sec);
+
+ // Start a timer to timeout the connect request
+ if (!iTimer->IsActive())
+ iTimer->After(KTimeOut);
+ // Issue the connect request
+ iControlSocket->Connect(iSockAddress, iStatus);
+ // Update the connect state
+ iState = EConnectingControl;
+
+#ifdef __WINS__
+
+ User::After(1); // Fix to allow emulator client to connect to server
+#endif
+
+ // Start this active object
+ SetActive();
+ }
+
+void CSocketInitiator::TimerExpired()
+ {
+ TRACE_INFO((_L("[BTHID]\tCSocketInitiator::TimerExpired()")));
+ // Cancel the operation in progress
+ Cancel();
+ // Inform the observer of this object that a failure occurred
+ // due to a timeout
+ iNotifier.SocketsConnFailed(KErrTimedOut);
+ }
+
+void CSocketInitiator::ConstructL()
+ {
+ // Create a timer
+ iTimer = CTimeOutTimer::NewL(EPriorityStandard, *this);
+ }
+
+void CSocketInitiator::DoCancel()
+ {
+ TRACE_INFO((_L("[BTHID]\tCSocketInitiator::DoCancel()")));
+
+ // Cancel appropriate request
+ switch (iState)
+ {
+ case EConnectingControl:
+ {
+ iControlSocket->CancelConnect();
+ break;
+ }
+ case EConnectingInterrupt:
+ {
+ iInterruptSocket->CancelConnect();
+ break;
+ }
+ default:
+ {
+ User::Panic(KPanicBTConnection, ESocketsBadStatus);
+ break;
+ }
+ }
+
+ //Close the sockets
+ iInterruptSocket->Close();
+ iControlSocket->Close();
+
+ // Set the connect state back to idle
+ iState = EIdle;
+ }
+
+void CSocketInitiator::RunL()
+ {
+ // Cancel any outstanding timer
+ iTimer->Cancel();
+
+ // Any error stops us dead.
+ if (iStatus != KErrNone)
+ {
+ //Close the sockets
+ iControlSocket->Close();
+ iInterruptSocket->Close();
+
+ // Set the connect state back to idle
+ iState = EIdle;
+ // Inform the observer that a failure occurred
+ iNotifier.SocketsConnFailed(iStatus.Int());
+ }
+ else
+ {
+ switch (iState)
+ {
+ case EConnectingControl:
+ {
+ TRACE_INFO((_L("[BTHID]\tCSocketInitiator::RunL(): Control channel connection request")));
+ ConnectInterruptSocket();
+ }
+ break;
+
+ case EConnectingInterrupt:
+ // L2CAP Interrupt channel connection request
+ // We are connected
+ // Set the connect state back to idle
+ {
+ TRACE_INFO((_L("[BTHID]\tCSocketInitiator::RunL(): Interrupt channel connection request")));
+ iState = EIdle;
+ // Inform the observer that connection is complete
+ iNotifier.SocketsConnected();
+ break;
+ }
+
+ default:
+ {
+ User::Panic(KPanicBTConnection, ESocketsBadState);
+ break;
+ }
+
+ };
+ }
+ }
+
+void CSocketInitiator::ConnectInterruptSocket()
+ {
+ // Connect the interrupt channel.
+ TRACE_INFO((_L("[BTHID]\tCSocketInitiator::ConnectInterruptSocket()")));
+ ///for BT Stack v2.0, use authentication and encryption
+ TBTServiceSecurity sec;
+ sec.SetAuthentication(iUseSecurity); // 2nd L2cap channel should need no authentication.
+ sec.SetEncryption(iUseSecurity); // but we need encryption.
+ iSockAddress.SetSecurity(sec);
+ ////
+ iSockAddress.SetPort(KL2CAPHidInterrupt);
+
+ // Start a timer to timeout the connect request
+ if (!iTimer->IsActive())
+ iTimer->After(KTimeOut);
+ // Issue the connect request
+ iInterruptSocket->Connect(iSockAddress, iStatus);
+ // Update the connect state
+ iState = EConnectingInterrupt;
+
+#ifdef __WINS__
+
+ User::After(1); // Fix to allow emulator client to connect to server
+#endif
+
+ SetActive();
+ }