diff -r e8e63152f320 -r 2a9601315dfc javacommons/comms/ipclib/clientserver/src.s60/commssession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javacommons/comms/ipclib/clientserver/src.s60/commssession.cpp Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,205 @@ +/* +* 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: CCommsSession handles communication with client side +* +*/ + +#include + +#include "logger.h" + +#include "common.h" +#include "commssession.h" +#include "ipcserver.h" + +namespace java +{ +namespace comms +{ +using java::util::ScopedLock; + +CCommsSession::CCommsSession(IpcListener& aListener, int aPermissions) + : mListener(aListener), mClientPermissions(aPermissions) +{ +} + +CCommsSession::~CCommsSession() +{ + while (!mMessageQueue.empty()) + { + std::auto_ptr tmp(mMessageQueue.front()); + mMessageQueue.pop(); + } +} + +void CCommsSession::ServiceL(const RMessage2& aMessage) +{ + TInt function = aMessage.Function(); + switch (function) + { + case ESend: + handleSendL(aMessage); + break; + + case EReceive: + handleReceiveL(aMessage); + break; + + case ECancelReceive: + handleCancelReceive(aMessage); + break; + + default: + aMessage.Complete(KErrNotSupported); + break; + } +} + +int CCommsSession::send(ipcMessage_t* aMsg) +{ + ScopedLock lock(mMutex); + + // messages from server are considered to be always trusted + aMsg->ipcHeader.permissions = -1; + HBufC8* msg = messageToDes(*aMsg); + mMessageQueue.push(msg); + + if (isReceivePending()) + { + HBufC8* msg = mMessageQueue.front(); + + TInt rc = doSend(mReceiveMessage, *msg); + if (rc == KErrNone) + { + mMessageQueue.pop(); + delete msg; + } + else + { + WLOG2(EJavaComms, "%s failed, err = %d", __PRETTY_FUNCTION__, rc); + } + } + return 0; +} + +void CCommsSession::handleSendL(const RMessage2& aMessage) +{ + TInt len = aMessage.GetDesLengthL(0); + int rc = KErrNone; + if (len < sizeof(ipcHeader_t)) + { + WLOG2(EJavaComms, "%s invalid message size, len = %d", __PRETTY_FUNCTION__, len); + rc = KErrArgument; + } + else + { + RBuf8 buffer; + + buffer.CleanupClosePushL(); + buffer.CreateL(len); + + aMessage.ReadL(0,buffer); + + char* buf = desToMessage(buffer); + ipcMessage_t* msg = reinterpret_cast(buf); + if (msg->ipcHeader.length == len) + { + msg->ipcHeader.sender = getId(); + msg->ipcHeader.permissions = mClientPermissions; + mListener.processMessage(msg); + } + else + { + WLOG3(EJavaComms, "%s message size does not match to header, len = %d header = %d", + __PRETTY_FUNCTION__, len, msg->ipcHeader.length); + rc = KErrArgument; + } + + delete[] buf; + CleanupStack::PopAndDestroy(); + } + aMessage.Complete(rc); +} + +void CCommsSession::handleReceiveL(const RMessage2& aMessage) +{ + ScopedLock lock(mMutex); + + if (mMessageQueue.empty()) + { + mReceiveMessage = aMessage; + } + else + { + HBufC8* msg = mMessageQueue.front(); + TInt rc = doSend(aMessage, *msg); + if (rc == KErrNone) + { + mMessageQueue.pop(); + delete msg; + } + else + { + WLOG2(EJavaComms, "%s failed, err = %d", __PRETTY_FUNCTION__, rc); + } + } +} + +void CCommsSession::handleCancelReceive(const RMessage2& aMessage) +{ + ScopedLock lock(mMutex); + + if (isReceivePending()) + { + mReceiveMessage.Complete(KErrCancel); + } + aMessage.Complete(KErrNone); +} + +bool CCommsSession::isReceivePending() const +{ + return !mReceiveMessage.IsNull(); +} + +int CCommsSession::getId() const +{ + // to be used as unique id to identify session - not as pointer + return (int)this; +} + +TInt CCommsSession::doSend(const RMessagePtr2& aMessage, HBufC8& aData) +{ + TInt allocatedLength = aMessage.GetDesMaxLength(0); + TInt neededLength = aData.Length(); + + TPckgBuf lengthPckg(neededLength); + TInt rc = aMessage.Write(1, lengthPckg); + + if (rc == KErrNone && allocatedLength >= neededLength) + { + rc = aMessage.Write(0, aData.Des()); + } + else + { + rc = KErrOverflow; + WLOG3(EJavaComms, "%s: allocated length for message is too small (required size=%d, allocated size=%d)", + __PRETTY_FUNCTION__, neededLength, allocatedLength); + } + + aMessage.Complete(rc); + return rc; +} + +} // namespace comms +} // namespace java