diff -r 000000000000 -r dfb7c4ff071f commsfwsupport/commselements/serverden/src/sd_apiextensionclient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/commsfwsupport/commselements/serverden/src/sd_apiextensionclient.cpp Thu Dec 17 09:22:25 2009 +0200 @@ -0,0 +1,373 @@ +// Copyright (c) 2008-2009 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: +// sd_apiextension.cpp +// +// + +/** + @file + @internalTechnology +*/ + +#include "sd_apiextensionclient.h" +#include "sd_apiextensionipc.h" + + +#ifdef _DEBUG +// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module +// (if it could happen through user error then you should give it an explicit, documented, category + code) +_LIT(KSpecAssert_ElemSvrDenApiXCC, "ElemSvrDenApiXCC"); +#endif + +using namespace Den; +using namespace Elements; + + +_LIT(KDenApiExtPanic, "API Extension Interface"); +/** + API extension interface panic codes + + @internalTechnology +*/ + +enum TDenApiExtPanic + { + EDenApiExtBadSessionHandle = 0, //< The session handle of the extension interface is invalid + EDenApiExtBadSubSessionHandle, //< The subsession handle of the extension interface is invalid + EDenApiExtBadHandle, //< The session handle of the extension interface is invalid + EDenApiExtMetaOverflow, //< Storing a message into a descriptor has overflowed + }; + + +// Implementation interface id for messages +static const TInt KApiExtMsgImplementationUid = 0x10285c89; + +enum + { + EApiExtReqMsg = 1, + EApiExtSubSessionReqMsg, + EApiExtSessionReqMsg, + EApiExtRespMsg + }; + +// +//TApiExtRespMsg +//EXPORT_REGISTER_TYPEID(TApiExtReqMsg, KReqMsgImplementationUid, EApiExtReqMsg) + +// +//TApiExtSubSessionReqMsg + +EXPORT_REGISTER_TYPEID(TApiExtSubSessionReqMsg, KApiExtMsgImplementationUid, EApiExtSubSessionReqMsg) + +// +//TApiExtHostRoutingReqMsg + +EXPORT_REGISTER_TYPEID(TApiExtSessionReqMsg, KApiExtMsgImplementationUid, EApiExtSessionReqMsg) + + +// +//TApiExtRespMsg +EXPORT_C TApiExtRespMsg* TApiExtRespMsg::NewL(const Meta::STypeId& aTypeId) + { + return static_cast(Meta::SMetaDataECom::NewInstanceL(aTypeId)); + } + +EXPORT_C TApiExtRespMsg* TApiExtRespMsg::NewL(const TDesC8& aMsgBuffer) + { + TPtrC8 buf(aMsgBuffer.Ptr(), aMsgBuffer.Length()); + return static_cast(Meta::SMetaDataECom::LoadL(buf)); + } + +EXPORT_REGISTER_TYPEID(TApiExtRespMsg, KApiExtMsgImplementationUid, EApiExtRespMsg) + +// +//RApiExtBase +TInt RApiExtCommonBase::PrepareForSending(TApiExtReqMsg& aRequestMsg, TRBuf8*& aBuffer) const + { + //clean up all used up buffers + for (TInt index = iBuffers.Count() - 1; index >= 0; --index) + { + if (iBuffers[index]->Length()==0) + { + delete iBuffers[index]; + iBuffers.Remove(index); + } + } + TInt error = KErrNoMemory; + TRBuf8* buffer = TRBuf8::New(aRequestMsg.Length()); + if (buffer!=NULL) + { + error = iBuffers.Append(buffer); //stick new buffer into the array + if (error!=KErrNone) + { + delete buffer; + buffer = NULL; + } + else + { + error = aRequestMsg.Store(*buffer); + if (error!=KErrNone) + { + __ASSERT_DEBUG(iBuffers[iBuffers.Count()-1]==buffer, User::Panic(KSpecAssert_ElemSvrDenApiXCC, 1)); //make sure we are removing what we believe we are removing + iBuffers.Remove(iBuffers.Count()-1); //remove the buffer + delete buffer; + buffer = NULL; + } + else + { + aBuffer = buffer; + } + } + } + return error; + } + +void RApiExtCommonBase::Close() + { +#if defined( _DEBUG ) + for (TInt index = iBuffers.Count() - 1; index >= 0; --index) + { + if (iBuffers[index]->Length()!=0) + { + User::Invariant(); //The request has not been processed by the server yet + } + } +#endif + + iBuffers.ResetAndDestroy(); + iIdentification=TApiExtIdentification(0,0); + } + +// +//RApiExtSubSessionBase +EXPORT_C TInt RApiExtSubSessionBase::Open(RExtendableSubSessionBase& aExtendableInterface, TInt aInterfaceId) + { + __ASSERT_ALWAYS(aExtendableInterface.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSessionHandle)); + + TApiExtIdentification identification(aInterfaceId); + TInt error = aExtendableInterface.SendReceive(EIpcSubSessionApiExtIfaceOpen, TIpcArgs(&identification)); + if (error == KErrNone) + { + iSubSession = aExtendableInterface; + iIdentification = identification; + } + return error; + } + +EXPORT_C void RApiExtSubSessionBase::Close() + { + if (!iSubSession.SubSessionHandle()) + return; + + iSubSession.SendReceive(EIpcSubSessionApiExtIfaceClose, TIpcArgs(&iIdentification)); + RApiExtCommonBase::Close(); + } + +//Calling this function, the client is responsible for providing a buffer +//that is big enough to store first the request message and then the response message. +EXPORT_C void RApiExtSubSessionBase::SendReceive(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf, TRequestStatus& aStatus) const + { + __ASSERT_ALWAYS(iSubSession.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle)); + aReqAndRespBuf.Zero(); + TInt error = aMsg.Store(aReqAndRespBuf); + if (error==KErrNone) + { + iSubSession.SendReceive(EIpcSubSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, &aReqAndRespBuf), aStatus); + } + else + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,error); + } + } + +EXPORT_C void RApiExtSubSessionBase::SendReceive(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf, TDes8& aReqAndRespBuf2, TRequestStatus& aStatus) const + { + __ASSERT_ALWAYS(iSubSession.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle)); + aReqAndRespBuf.Zero(); + TInt error = aMsg.Store(aReqAndRespBuf); + if (error==KErrNone) + { + iSubSession.SendReceive(EIpcSubSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, &aReqAndRespBuf, &aReqAndRespBuf2), aStatus); + } + else + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,error); + } + } + +//Calling this function, the client does not have to be concerned about the +//buffer management that happens underneath +EXPORT_C void RApiExtSubSessionBase::Send(TApiExtReqMsg& aMsg, TRequestStatus& aStatus) const + { + __ASSERT_ALWAYS(iSubSession.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle)); + TRBuf8* buffer = NULL; + TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer); + if (error==KErrNone) + { + iSubSession.SendReceive(EIpcSubSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer), aStatus); + } + else + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,error); + } + } + +EXPORT_C void RApiExtSubSessionBase::Send(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf2, TRequestStatus& aStatus) const + { + __ASSERT_ALWAYS(iSubSession.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle)); + TRBuf8* buffer = NULL; + TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer); + if (error==KErrNone) + { + iSubSession.SendReceive(EIpcSubSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer, &aReqAndRespBuf2), aStatus); + } + else + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,error); + } + } + +EXPORT_C void RApiExtSubSessionBase::Send(TApiExtReqMsg& aMsg, const RHandleBase& aHandleBase, TRequestStatus& aStatus) const + { + __ASSERT_ALWAYS(iSubSession.SubSessionHandle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle)); + TRBuf8* buffer = NULL; + TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer); + if (error==KErrNone) + { + iSubSession.SendReceive(EIpcSubSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer, aHandleBase), aStatus); + } + else + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,error); + } + } + +// +//RApiExtSessionBase +EXPORT_C TInt RApiExtSessionBase::Open(RExtendableSessionBase& aExtendableInterface, TInt aInterfaceId) + { + __ASSERT_ALWAYS(aExtendableInterface.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle)); + + TApiExtIdentification identification(aInterfaceId); + TInt error = aExtendableInterface.SendReceive(EIpcSessionApiExtIfaceOpen, TIpcArgs(&identification)); + if (error == KErrNone) + { + iSession = aExtendableInterface; + iIdentification = identification; + } + return error; + } + +EXPORT_C void RApiExtSessionBase::Close() + { + if (!iSession.Handle()) + return; + + iSession.SendReceive(EIpcSessionApiExtIfaceClose, TIpcArgs(&iIdentification)); + RApiExtCommonBase::Close(); + } + +//Calling this function, the client is responsible for providing a buffer +//that is big enough to store first the request message and then the response message. +EXPORT_C void RApiExtSessionBase::SendReceive(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf, TRequestStatus& aStatus) const + { + __ASSERT_ALWAYS(iSession.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle)); + aReqAndRespBuf.Zero(); + TInt error = aMsg.Store(aReqAndRespBuf); + if (error==KErrNone) + { + iSession.SendReceive(EIpcSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, &aReqAndRespBuf), aStatus); + } + else + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,error); + } + } + +EXPORT_C void RApiExtSessionBase::SendReceive(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf, TDes8& aReqAndRespBuf2, TRequestStatus& aStatus) const + { + __ASSERT_ALWAYS(iSession.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle)); + aReqAndRespBuf.Zero(); + TInt error = aMsg.Store(aReqAndRespBuf); + if (error==KErrNone) + { + iSession.SendReceive(EIpcSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, &aReqAndRespBuf, &aReqAndRespBuf2), aStatus); + } + else + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,error); + } + } + +//Calling this function, the client does not have to be concerned about the +//buffer management that happens underneath +EXPORT_C void RApiExtSessionBase::Send(TApiExtReqMsg& aMsg, TRequestStatus& aStatus) const + { + __ASSERT_ALWAYS(iSession.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle)); + + TRBuf8* buffer = NULL; + TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer); + if (error==KErrNone) + { + iSession.SendReceive(EIpcSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer), aStatus); + } + else + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,error); + } + } + +EXPORT_C void RApiExtSessionBase::Send(TApiExtReqMsg& aMsg, TDes8& aReqAndRespBuf2, TRequestStatus& aStatus) const + { + __ASSERT_ALWAYS(iSession.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle)); + + TRBuf8* buffer = NULL; + TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer); + if (error==KErrNone) + { + iSession.SendReceive(EIpcSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer, &aReqAndRespBuf2), aStatus); + } + else + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,error); + } + } + +EXPORT_C void RApiExtSessionBase::Send(TApiExtReqMsg& aMsg, const RHandleBase& aHandleBase, TRequestStatus& aStatus) const + { + __ASSERT_ALWAYS(iSession.Handle(), User::Panic(KDenApiExtPanic, EDenApiExtBadSubSessionHandle)); + + TRBuf8* buffer = NULL; + TInt error = RApiExtCommonBase::PrepareForSending(aMsg, buffer); + if (error==KErrNone) + { + iSession.SendReceive(EIpcSessionApiExtIfaceSendReceive, TIpcArgs(&iIdentification, buffer, aHandleBase), aStatus); + } + else + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,error); + } + } + +