diff -r 000000000000 -r 7f656887cf89 libraries/btserial/src/server/btserialsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libraries/btserial/src/server/btserialsession.cpp Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,312 @@ +// btserialsession.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 "btserialsession.h" +#include "btserialserver.h" +#include "btserialclient.h" +#include +#include "..\connection\btdebug.h" + + +void PanicClient(const RMessagePtr2& aMessage,TBtSerialServerPanic aPanic) +// +// RMessage::Panic() also completes the message. This is: +// (a) important for efficient cleanup within the kernel +// (b) a problem if the message is completed a second time +// + { + _LIT(KPanic,"BtSerialSrv"); + aMessage.Panic(KPanic,aPanic); + } + +//______________________________________________________________________________ +// CBtSerialSession +void CBtSerialSession::CreateL() + { + TRACE1("CBtSerialSession::CreateL"); + iConnection = CBluetoothIncomingSerialConnection::NewL(*this); + } + +CBtSerialSession::CBtSerialSession() + { + } + +CBtSerialSession::~CBtSerialSession() + { + TRACE1("CBtSerialSession::~CBtSerialSession"); + delete iConnection; + iReadBuf.Close(); + iWriteBuf.Close(); + Server().DropSession(); + } + +void CBtSerialSession::ServiceL(const RMessage2& aMessage) + { + switch (aMessage.Function()) + { + case EBtSerialWaitForConnection: + WaitForConnectionL(aMessage); + break; + case EBtSerialCancelWaitForConnection: + CancelWaitForConnection(aMessage); + break; + case EBtSerialIsConnected: + IsConnectedL(aMessage); + break; + case EBtSerialWrite: + WriteL(aMessage); + break; + case EBtSerialCancelWrite: + CancelWrite(aMessage); + break; + case EBtSerialRead: + ReadL(aMessage); + break; + case EBtSerialCancelRead: + CancelRead(aMessage); + break; + case EBtSerialGetConnectedDeviceAddr: + GetConnectedDeviceAddrL(aMessage); + break; + case EBtSerialGetConnectedDeviceName: + GetConnectedDeviceNameL(aMessage); + break; + default: + PanicClient(aMessage,EPanicIllegalFunction); + break; + } + } + +void CBtSerialSession::Disconnect(const RMessage2& aMessage) + { + if (iConnection->Connected()) + { + TRACE1("CBtSerialSession::Disconnect shutting down connection & storing message"); + iDisconnectMessage = aMessage; + iConnection->ShutDown(); + } + else + { + CSession2::Disconnect(aMessage); + } + } + +void CBtSerialSession::ServiceError(const RMessage2& aMessage,TInt aError) + { + if (aError==KErrBadDescriptor) + PanicClient(aMessage,EPanicBadDescriptor); + CSession2::ServiceError(aMessage,aError); + } + +inline CBtSerialServer& CBtSerialSession::Server() + { + return *static_cast(const_cast(CSession2::Server())); + } + +void CBtSerialSession::WaitForConnectionL(const RMessage2& aMessage) + { + TRACE1("CBtSerialSession::WaitForConnectionL"); + if (iConnection->Connected()) + { + aMessage.Complete(KErrNone); + return; + } + if (!iConnectedMessage.IsNull()) + { + User::Leave(KErrAlreadyExists); + } + iConnectedMessage = aMessage; + if (!iWaitingForConnection) + { + iConnection->WaitForConnection(); + } + } + +void CBtSerialSession::CancelWaitForConnection(const RMessage2& aMessage) + { + TRACE1("CBtSerialSession::CancelWaitForConnection"); + if (!iConnectedMessage.IsNull()) + { + iConnectedMessage.Complete(KErrCancel); + } + aMessage.Complete(KErrNone); + } + +void CBtSerialSession::IsConnectedL(const RMessage2& aMessage) + { + TRACE1("CBtSerialSession::IsConnectedL"); + aMessage.Complete(iConnection->Connected()); + } + +void CBtSerialSession::WriteL(const RMessage2& aMessage) + { + TRACE1("CBtSerialSession::WriteL"); + if (!iWriteMessage.IsNull()) + { + User::Leave(KErrInUse); + } + TInt len = aMessage.GetDesLengthL(0); + if (iWriteBuf.MaxLength() < len) + { + RBuf8 buf; + buf.CreateL(len); + buf.Swap(iWriteBuf); + buf.Close(); + } + iWriteBuf.Zero(); + aMessage.ReadL(0, iWriteBuf); + iWriteMessage = aMessage; + if (iConnection->Connected()) + { + iConnection->Write(iWriteBuf); + } + // else the write will be performed when we are connected + } + +void CBtSerialSession::CancelWrite(const RMessage2& aMessage) + { + TRACE1("CBtSerialSession::CancelWrite"); + iConnection->CancelWrite(); + iWriteBuf.Zero(); + if (!iWriteMessage.IsNull()) + { + iWriteMessage.Complete(KErrCancel); + } + aMessage.Complete(KErrNone); + } + +void CBtSerialSession::ReadL(const RMessage2& aMessage) + { + TRACE1("CBtSerialSession::ReadL"); + if (!iReadMessage.IsNull()) + { + User::Leave(KErrInUse); + } + TInt len = aMessage.GetDesMaxLengthL(0); + if (iReadBuf.MaxLength() != len) // better to add length param to CBluetoothIncomingSerialConnection::Read + { + RBuf8 buf; + buf.CreateL(len); + buf.Swap(iReadBuf); + buf.Close(); + } + iReadBuf.Zero(); + iReadMessage = aMessage; + if (iConnection->Connected()) + { + iConnection->Read(iReadBuf); + } + } + +void CBtSerialSession::CancelRead(const RMessage2& aMessage) + { + TRACE1("CBtSerialSession::CancelRead"); + iConnection->CancelRead(); + if (!iReadMessage.IsNull()) + { + iReadMessage.Complete(KErrCancel); + } + aMessage.Complete(KErrNone); + } + +void CBtSerialSession::GetConnectedDeviceNameL(const RMessage2& aMessage) + { + if (!iGetNameMessage.IsNull()) + { + User::Leave(KErrAlreadyExists); + } + iGetNameMessage = aMessage; + iConnection->GetConnectedDeviceNameL(); + } + +void CBtSerialSession::GetConnectedDeviceAddrL(const RMessage2& aMessage) + { + TBTDevAddr addr = iConnection->ConnectedDeviceAddrL(); + TPckg pckg(addr); + aMessage.WriteL(0, pckg); + aMessage.Complete(KErrNone); + } + +void CBtSerialSession::BtSerialConnected() + { + TRACE1("CBtSerialSession::BtSerialConnected"); + if (!iConnectedMessage.IsNull()) + { + iConnectedMessage.Complete(KErrNone); + } + if (!iWriteMessage.IsNull()) + { + iConnection->Write(iWriteBuf); + } + if (!iReadMessage.IsNull()) + { + iConnection->Read(iReadBuf); + } + } + +void CBtSerialSession::BtWriteComplete(TInt aError) + { + TRACE1("CBtSerialSession::BtWriteComplete"); + iWriteMessage.Complete(aError); + } + +void CBtSerialSession::BtReadComplete(TInt aError) + { + TRACE1("CBtSerialSession::BtReadComplete"); + if (aError == KErrNone) + { + aError = iReadMessage.Write(0, iReadBuf); + } + iReadMessage.Complete(aError); + } + +void CBtSerialSession::BtSerialError(TInt aError) + { + TRACE1("CBtSerialSession::BtSerialError"); + if (!iConnectedMessage.IsNull()) + { + iConnectedMessage.Complete(aError); + } + } + +void CBtSerialSession::BtShutdownComplete(TInt /*aError*/) + { + TRACE1("CBtSerialSession::BtShutdownComplete"); + CSession2::Disconnect(iDisconnectMessage); + } + +void CBtSerialSession::BtNameReceived(TInt aError, const TDesC& aName) + { + TInt len = 0; + if (aError == KErrNone) + { + aError = iGetNameMessage.GetDesMaxLength(0); + if (aError >= 0) + { + len = aError; + aError = KErrNone; + } + } + if (aError == KErrNone) + { + aError = iGetNameMessage.Write(0, aName.Left(len)); + } + if (aError == KErrNone) + { + if (aName.Length() > len) + { + aError = KErrOverflow; + } + } + iGetNameMessage.Complete(aError); + } +