diff -r 000000000000 -r f63038272f30 bluetoothengine/bthid/bthidserver/src/bthidsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothengine/bthid/bthidserver/src/bthidsession.cpp Mon Jan 18 20:28:57 2010 +0200 @@ -0,0 +1,350 @@ +/* +* 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 +#include "bthidsession.h" +#include "bthidserver.h" +#include "bthidclientsrv.h" +#include "hidsdpclient.h" +#include "bthiddevice.h" +#include "bthidserver.pan" +#include "debug.h" + +CBTHidServerSession::CBTHidServerSession(CBTHidServer& aServer) : + iServer(aServer) + { + // Implementation not required + } + +CBTHidServerSession::~CBTHidServerSession() + { + iServer.DecrementSessions(); + delete iHidSdpClient; + } + +void CBTHidServerSession::ServiceL(const RMessage2& aMessage) + { + TRAPD( err, DispatchMessageL( aMessage ) ); + + if (aMessage.Function() == EBTHIDGetConnections && !aMessage.IsNull()) + { + // Handle the error code, what to to? + err = err; + } + } + +void CBTHidServerSession::DispatchMessageL(const RMessage2& aMessage) + { + switch (aMessage.Function()) + { + case EBTHIDServConnectDevice: + RequestConnectionL(aMessage); + break; + + case EBTHIDServCancelConnect: + if (iConnectionMessage.Handle()) + { + delete iHidSdpClient; + iHidSdpClient = 0; + + iServer.DeleteNewConnection(iConnectingID); + + iConnectionMessage.Complete(KErrCancel); + } + aMessage.Complete(KErrNone); + break; + + case EBTHIDServNotifyConnectionChange: + if (iUpdateMessage.Handle()) + { + // We're already busy + CBTHidServer::PanicClient(aMessage, EReqAlreadyPending); + } + else + { + iUpdateMessage = aMessage; + } + break; + + case EBTHIDServCancelNotify: + if (iUpdateMessage.Handle()) + { + iUpdateMessage.Complete(KErrCancel); + } + aMessage.Complete(KErrNone); + break; + + case EBTHIDServDisconnectDevice: + RequestDisconnectionL(aMessage); + break; + + case EBTHIDServIsConnected: + IsConnectedL(aMessage); + break; + + case EBTHidSrvDisconnectAllGracefully: + if (iDisconnectMsg.Handle()) + { + aMessage.Complete(KErrServerBusy); + } + else + { + iDisconnectMsg = aMessage; + iServer.DisconnectAllDeviceL(); + iDisconnectMsg.Complete(KErrNone); + } + break; + + case EBTHIDGetConnections: + GetConnections(aMessage); + break; + + default: + { + TRACE_INFO( ( _L( "[BTHID]\t DispatchMessageL: bad request (%d)" ), + aMessage.Function() ) ) + CBTHidServer::PanicClient(aMessage, EBadRequest); + } + break; + } + } + +void CBTHidServerSession::HidSdpSearchComplete(TInt aResult) + { + TRACE_FUNC + (_L("[BTHID]\tCBTHidServerSession::HidSdpSearchComplete")); + // This is a callback for the Hid SDP client so we can't delete it here + // Get it to destroy itself when its convenient. + iHidSdpClient->Kill(); + // Deleted outside destructor. + iHidSdpClient = 0; + + TInt err = aResult; + + // If the SDP search was a success + if (err == KErrNone) + { + // Try to connect to the device as a HID + TRAP( err, iServer.DoFirstConnectionL(iConnectingID); ) + + if (err == KErrAlreadyExists) + { + //there is already an active connection with the same CoD + TBuf8 buf; + TBTDevAddr dummyAddr = iServer.ConflictAddress(); + buf.Append(dummyAddr.Des()); + if (buf.Length()) + { + iConnectionMessage.Write(1, buf); + } + + //delete the connection object in the server + iServer.DeleteNewConnection(iConnectingID); + iConnectionMessage.Complete(err); + return; + } + } + + // Any error causes clean up, + if (err != KErrNone) + { + //delete the connection object in the server + iServer.DeleteNewConnection(iConnectingID); + + //Inform the client of the result + iConnectionMessage.Complete(aResult); + } + } + +void CBTHidServerSession::RequestConnectionL(const RMessage2& aMessage) + { + TRACE_FUNC + (_L("[BTHID]\tCBTHidServerSession::RequestConnectionL")); + + if (iConnectionMessage.Handle()) + { + // We're already busy + CBTHidServer::PanicClient(aMessage, EReqAlreadyPending); + } + else + { + TRACE_INFO(_L("[BTHID]\tCBTHidServerSession::RequestConnectionL continue to connect")); + // Keep a copy of message - for use later + iConnectionMessage = aMessage; + + // Read the connection parameters + TBTDevAddr addr; + TPckg addrPack(addr); + + iConnectionMessage.ReadL(0, addrPack); + // Ask the server to create a new connection object + + + iConnectingID = iServer.NewConnectionL(); + TRAPD( res, + // Retrieve the hid device object for this new connection + CBTHidDevice &devDetails = + iServer.ConnectionDetailsL(iConnectingID); + + // Fill in the information we got from the client + devDetails.iAddress = addr; + devDetails.iUseSecurity = ETrue; + + // Create a new HID Sdp Client + // Its only used here so it doesn't matter if we leave. + delete iHidSdpClient; + iHidSdpClient = 0; + //Create a new hid sdp client using the hid device object. + iHidSdpClient = CHidSdpClient::NewL(devDetails, *this); + + // Start the hid sdp client + iHidSdpClient->StartL(); + ) + + // If there was any error, inform the client and finish + if (res != KErrNone) + { + // Get the server to delete the new connection object + iServer.DeleteNewConnection(iConnectingID); + aMessage.Complete(res); + } + } + + } + +void CBTHidServerSession::RequestDisconnectionL(const RMessage2& aMessage) + { + TBTDevAddr addr; + TPckg addrPack(addr); + + // Read the address from the client thread. + aMessage.ReadL(0, addrPack); + + // Since the user can select this option using the BT Keyboard + // and the keydown event triggers it, depending on how long they + // hold down the key, the connection could be restored to send + // the key up event. + // Add a small delay, sensible enough for a press of the enter + // key before disconnection. + // Currently 3/4 of a second. + User::After(750000); + + //Keep the connection alive, initial reconnect from HID device available... + iServer.CloseBluetoothConnection(addr); + + aMessage.Complete(KErrNone); + } + +void CBTHidServerSession::InformStatusChange( + const THIDStateUpdateBuf& aUpdateParams) + { + TRACE_FUNC + (_L("[BTHID]\tCBTHidServerSession::InformStatusChange")); + + THIDStateUpdate update = aUpdateParams(); + TBTHidConnState state = update.iState; + + TBuf8 buf; + if (state == EBTDeviceAnotherExist) + { + TBTDevAddr iDumyAddr = iServer.ConflictAddress(); + buf.Append(iDumyAddr.Des()); + } + + TRACE_INFO( (_L("[BTHID]\tCBTHidServerSession::InformStatusChange, state=%d"), state) ); + + if (iUpdateMessage.Handle()) + { + TRACE_FUNC + (_L("[BTHID]\tCBTHidServerSession::InformStatusChange, OK - send message")); + // Trap any error + TRAPD( res, + iUpdateMessage.WriteL(0,aUpdateParams); + if (buf.Length()) + { + iUpdateMessage.WriteL(1,buf); + } + ) + + if (state == EBTDeviceAnotherExist) + { + iUpdateMessage.Complete(KErrAlreadyExists); + } + else + { + // Complete the message, with the error code from the trap. + iUpdateMessage.Complete(res); + } + } + } + +void CBTHidServerSession::InformConnectionResult(TInt aConnID, TInt aResult) + { + TRACE_INFO( (_L("[BTHID new]\tCBTHidServerSession::InformConnectionResult, Ids: %d==%d aResult = %d"), + iConnectingID, aConnID, aResult) ); + if ((iConnectionMessage.Handle()) && (iConnectingID == aConnID)) + { + iConnectionMessage.Complete(aResult); + } + } + +void CBTHidServerSession::IsConnectedL(const RMessage2& aMessage) + { + TBTDevAddr addr; + TPckg addrPck(addr); + aMessage.ReadL(0, addrPck); + TBTEngConnectionStatus ret = iServer.ConnectStatus(addr); + + aMessage.Complete(ret); + } + +void CBTHidServerSession::GetConnections(const RMessage2& aMessage) + { + TRACE_FUNC + TBuf8 buf; + buf.Zero(); + iServer.GetConnectionAddress(buf); + if (buf.Length()) + { + aMessage.Write(0, buf); + } + + aMessage.Complete(KErrNone); + } + +CBTHidServerSession* CBTHidServerSession::NewL(CBTHidServer& aServer) + { + CBTHidServerSession* self = CBTHidServerSession::NewLC(aServer); + CleanupStack::Pop(self); + return self; + } + +CBTHidServerSession* CBTHidServerSession::NewLC(CBTHidServer& aServer) + { + CBTHidServerSession* self = new (ELeave) CBTHidServerSession(aServer); + + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +void CBTHidServerSession::ConstructL() + { + iServer.IncrementSessions(); + }