diff -r 000000000000 -r f63038272f30 bluetoothengine/bthid/bthidserver/src/socketinitiator.cpp --- /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 +#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(); + }