--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/ClientResolver/Server/src/CSIPCRServerSession.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,806 @@
+// Copyright (c) 2005-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:
+// Name : CSIPCRServerSession.cpp
+// Part of : SIP Client Resolver
+// Version : 1.0
+//
+
+
+
+// INCLUDES
+#include <e32math.h>
+#include "CSipCRServerSession.h"
+#include "CSIPCRRoutingTable.h"
+#include "CSIPClientResolver.h"
+#include "CSIPCRITCUtility.h"
+#include "CSIPCRSessionReceiver.h"
+#include "CSipCRServer.h"
+#include "sipCRclientserver.h"
+#include "CSIPCRRequestItem.h"
+#include "siprequest.h"
+#include "sipresponse.h"
+#include "TSipClient.h"
+#include "sipresolvedclient.h"
+#include "sipcontenttypeheader.h"
+#include "sipstrconsts.h"
+#include "sipstrings.h"
+#include "uricontainer.h"
+#include "SIPCRSerializer.h"
+#include "sipresolvedclient2.h"
+#include "sipcrworkerao.h"
+#include "sipcrrequestqueuecleanupdata.h"
+
+const TUint K480ResponseCode = 480;
+const TUint K503ResponseCode = 503;
+
+_LIT(KWorkerThreadName, "SIPClientResolverSessionWorker");
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::NewL
+// ----------------------------------------------------------------------------
+//
+CSIPCRServerSession* CSIPCRServerSession::NewL(CSIPCRServer& aCRServer)
+ {
+ CSIPCRServerSession* self = CSIPCRServerSession::NewLC(aCRServer);
+ CleanupStack::Pop (self);
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::NewLC
+// ----------------------------------------------------------------------------
+//
+CSIPCRServerSession* CSIPCRServerSession::NewLC(CSIPCRServer& aCRServer)
+ {
+ CSIPCRServerSession* self = new(ELeave)CSIPCRServerSession(aCRServer);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::CSIPCRServerSession
+// ----------------------------------------------------------------------------
+//
+CSIPCRServerSession::CSIPCRServerSession(CSIPCRServer& aCRServer)
+ : iClientUid(TUid::Null()),
+ iClientUidSet(EFalse),
+ iCRServer(aCRServer)
+ {
+ iCRServer.IncrementSessions();
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ConstructL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::ConstructL()
+ {
+ User::LeaveIfError(iRequestQueueMutex.CreateLocal());
+ iReceiver = CSIPCRSessionReceiver::NewL(iCRServer.ITCUtility());
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::~CSIPCRServerSession
+// ----------------------------------------------------------------------------
+//
+CSIPCRServerSession::~CSIPCRServerSession ()
+ {
+ iWorkerAos.ResetAndDestroy();
+ delete iReceiver;
+ iRequestQueue.ResetAndDestroy();
+ iCRServer.DecrementSessions();
+ if (iClientUidSet)
+ {
+ iCRServer.RoutingTable().Remove(iClientUid);
+ }
+ iRequestQueueMutex.Close();
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ServiceL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::ServiceL(const RMessage2& aMessage)
+ {
+ DoServiceL(aMessage.Function(),aMessage);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::WorkerAoRequestCompleted
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::WorkerAoRequestCompleted(CSipCrWorkerAo* aWorkerAo)
+ {
+ TInt err = aWorkerAo->CompletionCode();
+ TUint32 requestId = aWorkerAo->RequestId();
+ if (err != KErrNone && requestId > 0)
+ {
+ TRAP_IGNORE(iReceiver->ErrorReceivedL(requestId,err))
+ }
+ TInt index = iWorkerAos.Find(aWorkerAo);
+ if (index >= 0)
+ {
+ iWorkerAos.Remove(index);
+ }
+ delete aWorkerAo;
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::RoutingEntryAddedL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::RoutingEntryAddedL(const TUid& aUid)
+ {
+ CSIPCRITCUtility::WaitForMutexLC(iRequestQueueMutex);
+
+ // Complete pending requests for aUid
+ CSIPCRRequestItem* requestItem = NULL;
+ for (TInt i=iRequestQueue.Count()-1; i >= 0; i--)
+ {
+ requestItem = iRequestQueue[i];
+ if (requestItem->ChannelUid() == aUid)
+ {
+ TUint32 requestId = requestItem->RequestId();
+ TUid nextHopUid(TUid::Null());
+ if (iCRServer.RoutingTable().FindMatch(aUid,iClientUid,nextHopUid))
+ {
+ iReceiver->RequestCompletedL(requestId,nextHopUid);
+ }
+ else
+ {
+ iReceiver->ErrorReceivedL(requestId,KErrNotFound);
+ }
+ ProtectedRemoveFromRequestQueue( requestItem );
+ delete requestItem;
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // signals iRequestQueueMutex
+
+ CSipCrWorkerAo* workerAo = CSipCrWorkerAo::NewLC(*this);
+ CreateWorkerThreadL(workerAo,ConnectWorkerThreadFunction);
+ CleanupStack::Pop(workerAo);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::DoServiceL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::DoServiceL (TInt aFunction,
+ const RMessage2& aMessage)
+ {
+ switch (aFunction)
+ {
+#ifndef PLAT_SEC_TEST
+ case ESIPCRIpcSetClientUid:
+ SetUIDL(aMessage); break;
+
+ case ESIPCRIpcRegister:
+ RegisterL(iCRServer.ITCUtility().ReadUIDL(aMessage)); break;
+
+ case ESIPCRIpcDeregister:
+ DeregisterL(iCRServer.ITCUtility().ReadUIDL(aMessage)); break;
+
+ case ESIPCRIpcClientReadyToReceive: // Async. Don't complete yet.
+ ClientReadyToReceiveL(aMessage); return;
+
+ case ESIPCRIpcClientCancelReceive:
+ CancelClientReceiveL(); break;
+
+ case ESIPCRIpcCancelRequest:
+ CancelRequestL(aMessage); break;
+
+ case ESIPCRIpcCancelAllRequests:
+ CancelAllRequests(); break;
+
+ case ESIPCRIpcChannel:
+ ChannelL(aMessage); break;
+
+ case ESIPCRIpcChannelWithResolver:
+ ChannelWithResolverL(aMessage); break;
+
+ case ESIPCRIpcClientReceiveSipResponse:
+ ClientReceiveSipResponseL(aMessage); break;
+
+ default:
+ break;
+#endif
+ }
+ iCRServer.ITCUtility().Complete(aMessage,KErrNone);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ChannelWithResolverL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::ChannelWithResolverL(const RMessage2& aMessage)
+ {
+ CSIPRequest* request = CSIPRequest::NewLC();
+ iCRServer.ITCUtility().ReadSIPRequestL(aMessage, *request);
+ TUid resolverUid = iCRServer.ITCUtility().ReadResolverUidL(aMessage);
+ TUint32 requestId = CreateRequestId();
+ TSipClient clientUid(TUid::Null(),EFalse,EFalse);
+ ChannelL(requestId,*request,clientUid,resolverUid);
+ CleanupStack::PopAndDestroy(request);
+ iCRServer.ITCUtility().WriteRequestIdL(aMessage,requestId);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ChannelL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::ChannelL(const RMessage2& aMessage)
+ {
+ CSIPRequest* request = CSIPRequest::NewLC();
+ iCRServer.ITCUtility().ReadSIPRequestL(aMessage, *request);
+
+ TUint32 requestId = CreateRequestId();
+ iCRServer.ITCUtility().WriteRequestIdL(aMessage,requestId);
+
+ TSipClient clientUid(TUid::Null(),EFalse,EFalse);
+
+ CSIPResponse* response = ResolveClientL(*request,clientUid);
+ if (response)
+ {
+ CleanupStack::PushL(response);
+ iReceiver->AddErrorResponseL(requestId,response);
+ CleanupStack::PopAndDestroy(response);
+ }
+ else
+ {
+ ChannelL(requestId,*request,clientUid,TUid::Null());
+ }
+ CleanupStack::PopAndDestroy(request);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::RegisterL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::RegisterL(const TUid& aChannelUid)
+ {
+ iCRServer.RoutingTable().AssociateL(iClientUid, aChannelUid);
+ iCRServer.RoutingEntryAddedL(aChannelUid);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::DeregisterL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::DeregisterL(const TUid& aChannelUid)
+ {
+ iCRServer.RoutingTable().Remove(aChannelUid);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::SetUIDL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::SetUIDL(const RMessage2& aMessage)
+ {
+ iClientUid = iCRServer.ITCUtility().ReadUIDL (aMessage);
+ iCRServer.RoutingTable().AddL(iClientUid);
+ iClientUidSet = ETrue;
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ClientReadyToReceiveL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::ClientReadyToReceiveL(const RMessage2& aMessage)
+ {
+ iReceiver->ClientReadyToReceiveL(aMessage);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ClientReceiveSipResponseL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::ClientReceiveSipResponseL(const RMessage2& aMessage)
+ {
+ iReceiver->WriteSipResponseToClientL(aMessage);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::CancelRequestL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::CancelRequestL(const RMessage2& aMessage)
+ {
+ TUint32 requestId = iCRServer.ITCUtility().ReadRequestIdL(aMessage);
+ TBool found = EFalse;
+
+ CSIPCRITCUtility::WaitForMutexLC(iRequestQueueMutex);
+
+ for (TInt i=iRequestQueue.Count()-1; i >=0 && !found; i--)
+ {
+ CSIPCRRequestItem* requestItem = iRequestQueue[i];
+ if (requestItem->RequestId() == requestId)
+ {
+ CancelConnectL( requestItem );
+ ProtectedRemoveFromRequestQueue( requestItem );
+ delete requestItem;
+ found = ETrue;
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // signals iRequestQueueMutex
+
+ iReceiver->RemoveByRequestId(requestId);
+ CSipCrWorkerAo* workerAo = CSipCrWorkerAo::NewLC(*this);
+ CreateWorkerThreadL(workerAo,ConnectWorkerThreadFunction);
+ CleanupStack::Pop(workerAo);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::CancelConnectL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::CancelConnectL( CSIPCRRequestItem* aRequestItem )
+ {
+ if ( aRequestItem->Client().PluginType() == TSipClient::ESecondGeneration )
+ {
+ if ( aRequestItem->ConnectCalled() )
+ {
+ CSIPResolvedClient2* resolvedClient2 =
+ iCRServer.LoadPlugin2LC(
+ aRequestItem->Client().ImplementationUid() );
+ resolvedClient2->CancelConnect( aRequestItem->Client().Uid() );
+ CleanupStack::PopAndDestroy( resolvedClient2 );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CSIPCRServerSession::AddToRequestQueueL
+// ---------------------------------------------------------------------------
+//
+template<class T> void CSIPCRServerSession::AddToRequestQueueL(
+ CSIPCRRequestItem* aRequestItem,
+ T& aResolvedClient )
+ {
+ __ASSERT_ALWAYS ( aRequestItem, User::Leave( KErrArgument ) );
+
+ // The request item needs to be in request queue
+ // in case the client connects immediately after calling ConnectL
+ // and the main thread examines the request queue
+ ProtectedAddToRequestQueueL( aRequestItem );
+ TSipCrRequestQueueCleanupData cleanupData;
+ cleanupData.iSession = this;
+ cleanupData.iRequestItem = aRequestItem;
+ TCleanupItem cleanupItem( RemoveFromRequestQueue, &cleanupData );
+ CleanupStack::PushL(cleanupItem);
+ TBool connectSucceeded = ConnectL( *aRequestItem, aResolvedClient );
+ CleanupStack::Pop(); // cleanupItem, leave the item to queue
+ if ( !connectSucceeded )
+ {
+ ProtectedRemoveFromRequestQueue( aRequestItem );
+ delete aRequestItem;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CSIPCRServerSession::ConnectL
+// ---------------------------------------------------------------------------
+//
+template<class T> TBool CSIPCRServerSession::ConnectL(
+ CSIPCRRequestItem& aRequestItem,
+ T& aResolvedClient )
+ {
+ TBool success = ETrue;
+ TRAPD (err, aResolvedClient.ConnectL(aRequestItem.ChannelUid()));
+ if (err == KErrNoMemory)
+ {
+ User::Leave(err);
+ }
+ else if (err != KErrNone)
+ {
+ CSIPResponse* response = CSIPResponse::NewLC(K480ResponseCode,
+ SIPStrings::StringF(SipStrConsts::EPhraseTemporarilyNotAvailable));
+ iReceiver->AddErrorResponseL(aRequestItem.RequestId(),response);
+ CleanupStack::Pop(response);
+ success = EFalse;
+ }
+ else
+ {
+ aRequestItem.SetConnectCalled();
+ }
+ return success;
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::CancelAllRequests
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::CancelAllRequests()
+ {
+ iRequestQueueMutex.Wait(); // Protect iRequestQueue with a mutex
+ iRequestQueue.ResetAndDestroy();
+ iRequestQueueMutex.Signal();
+ iReceiver->RemoveAll();
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::CancelClientReceiveL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::CancelClientReceiveL ()
+ {
+ iReceiver->CancelClientReceiveL();
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ResolveClientL
+// ----------------------------------------------------------------------------
+//
+CSIPResponse* CSIPCRServerSession::ResolveClientL(
+ CSIPRequest& aRequest,
+ TSipClient& aUid)
+ {
+ RArray<TSipClient> uids;
+ CleanupClosePushL(uids);
+ // Always execute the client resolving code in the main thread
+ // Multithreading the resolving code would be error prone and
+ // there is no performance reason to create a new thread for resolving.
+ CSIPResponse* response =
+ iCRServer.ClientResolver().FindUidL(aRequest,uids);
+ if (!response)
+ {
+ __ASSERT_ALWAYS(uids.Count() > 0, User::Leave(KErrNotFound));
+ if (!FindUid(uids,aUid,ETrue,ETrue) &&
+ !FindUid(uids,aUid,ETrue,EFalse) &&
+ !FindUid(uids,aUid,EFalse,ETrue) &&
+ !FindUid(uids,aUid,EFalse,EFalse))
+ {
+ response = CSIPResponse::NewL(K503ResponseCode,
+ SIPStrings::StringF(SipStrConsts::EPhraseServiceUnavailable));
+ }
+ }
+ CleanupStack::PopAndDestroy(1); // uids
+ return response;
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ChannelL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::ChannelL(
+ TUint32 aRequestId,
+ CSIPRequest& aRequest,
+ const TSipClient& aClient,
+ const TUid& aResolverUid)
+ {
+ // SIP request cannot be passed as such to the worker thread because
+ // the main and worker threads are using a different string pool.
+ // Instead SIP request is externalized in the main thread and
+ // internalized in the worker thread.
+ CBufBase* serializedRequest = SIPCRSerializer::ExternalizeL(aRequest);
+ CleanupStack::PushL(serializedRequest);
+ HBufC8* requestBody = aRequest.TakeContentOwnershipL();
+ CleanupStack::PushL(requestBody);
+
+ CSipCrWorkerAo* workerAo =
+ CSipCrWorkerAo::NewL(
+ aRequestId,serializedRequest,requestBody,
+ aClient,aResolverUid,*this);
+
+ CleanupStack::Pop(requestBody);
+ CleanupStack::Pop(serializedRequest);
+
+ CleanupStack::PushL(workerAo);
+ CreateWorkerThreadL(workerAo,ChannelWorkerThreadFunction);
+ CleanupStack::Pop(workerAo);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ChannelImplementationL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::ChannelImplementationL( CSipCrWorkerAo& aWorkerAo )
+ {
+ CSIPRequest* request = CSIPRequest::NewLC();
+ SIPCRSerializer::InternalizeL(
+ aWorkerAo.SerializedSipRequest().Ptr( 0 ), *request );
+ request->SetContent( aWorkerAo.GetSipRequestBody() );
+
+ CSIPResolvedClient2* resolvedClient2 = NULL;
+ CSIPResolvedClient* resolvedClient = NULL;
+
+ if ( aWorkerAo.SipClient().PluginType() == TSipClient::EFirstGeneration )
+ {
+ resolvedClient =
+ iCRServer.LoadPlugin1LC( aWorkerAo.SipClient().Uid(),
+ aWorkerAo.ResolverUid() );
+ __ASSERT_ALWAYS ( resolvedClient , User::Leave( KErrNoMemory ) );
+ }
+ else
+ {
+ resolvedClient2 =
+ iCRServer.LoadPlugin2LC( aWorkerAo.SipClient().ImplementationUid() );
+ __ASSERT_ALWAYS ( resolvedClient2 , User::Leave( KErrNoMemory ) );
+ }
+
+ TUid channelUid;
+ ChannelUidL( aWorkerAo.SipClient(), channelUid, request, resolvedClient );
+
+ TUid nextHopUid( TUid::Null() );
+
+ if ( iCRServer.RoutingTable().FindMatch( channelUid,
+ iClientUid,
+ nextHopUid ) )
+ {
+ iReceiver->RequestCompletedL( aWorkerAo.RequestId(),nextHopUid );
+ }
+ else // Client not running
+ {
+ CSIPCRRequestItem* requestItem =
+ CSIPCRRequestItem::NewLC( aWorkerAo.RequestId(),
+ aWorkerAo.SipClient(),
+ channelUid,
+ aWorkerAo.ResolverUid() );
+ if ( resolvedClient )
+ {
+ AddToRequestQueueL( requestItem, *resolvedClient );
+ }
+ else
+ {
+ AddToRequestQueueL( requestItem, *resolvedClient2 );
+ }
+ CleanupStack::Pop( requestItem );
+ }
+ if ( resolvedClient )
+ {
+ CleanupStack::PopAndDestroy( resolvedClient );
+ }
+ if ( resolvedClient2 )
+ {
+ CleanupStack::PopAndDestroy( resolvedClient2 );
+ }
+
+ CleanupStack::PopAndDestroy( request );
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ChannelUidL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::ChannelUidL(
+ const TSipClient& aClient,
+ TUid& aChannelUid,
+ CSIPRequest* aRequest,
+ CSIPResolvedClient* aResolvedClient )
+ {
+ if ( aClient.PluginType() == TSipClient::EFirstGeneration )
+ {
+ HBufC8* uri = aRequest->RequestURI()->ToTextL();
+ CleanupStack::PushL(uri);
+
+ CSIPContentTypeHeader* contenTypeHeader =
+ static_cast<CSIPContentTypeHeader*>(
+ aRequest->Header(
+ SIPStrings::StringF(SipStrConsts::EContentTypeHeader),0));
+
+ if(aResolvedClient)
+ {
+ aChannelUid = aResolvedClient->ChannelL(aRequest->Method(),
+ *uri,
+ aRequest->AllHeadersL(),
+ aRequest->Content(),
+ contenTypeHeader);
+ }
+ CleanupStack::PopAndDestroy(uri);
+ }
+ else
+ {
+ aChannelUid = aClient.Uid();
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::HandleNextPendingRequestL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::HandleNextPendingRequestL(
+ CSipCrWorkerAo& /*aWorkerAo*/)
+ {
+ CSIPCRITCUtility::WaitForMutexLC(iRequestQueueMutex);
+
+ if ( iRequestQueue.Count() > 0 && !( iRequestQueue[0]->ConnectCalled() ) )
+ {
+ CSIPCRRequestItem* requestItem = iRequestQueue[ 0 ];
+ if ( requestItem->Client().PluginType() ==
+ TSipClient::EFirstGeneration )
+ {
+ CSIPResolvedClient* resolvedClient =
+ iCRServer.LoadPlugin1LC( requestItem->Client().Uid(),
+ requestItem->ResolverUid() );
+ ConnectL( *requestItem, *resolvedClient );
+ CleanupStack::PopAndDestroy( resolvedClient );
+ }
+ else
+ {
+ CSIPResolvedClient2* resolvedClient2 =
+ iCRServer.LoadPlugin2LC( requestItem->Client().ImplementationUid() );
+ ConnectL( *requestItem, *resolvedClient2 );
+ CleanupStack::PopAndDestroy( resolvedClient2 );
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // signals iRequestQueueMutex
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::CreateRequestId
+// ----------------------------------------------------------------------------
+//
+TUint32 CSIPCRServerSession::CreateRequestId()
+ {
+ if (iRequestIdCounter < KMaxTUint32)
+ {
+ iRequestIdCounter++;
+ }
+ else
+ {
+ iRequestIdCounter = 1;
+ }
+ return iRequestIdCounter;
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::FindUid
+// ----------------------------------------------------------------------------
+//
+TBool CSIPCRServerSession::FindUid(
+ const RArray<TSipClient>& aUids,
+ TSipClient& aUid,
+ TBool aRomBased,
+ TBool aConnected)
+ {
+ TInt found = EFalse;
+ for (TInt i=0; i < aUids.Count() && !found; i++)
+ {
+ const TSipClient& client = aUids[i];
+ TBool connected = iCRServer.RoutingTable().HasUid(client.Uid());
+ if ( client.RomBased() == aRomBased && connected == aConnected )
+ {
+ if ( aConnected || client.AllowStarting() )
+ {
+ aUid.SetUid( client.Uid() );
+ aUid.SetAllowStarting( client.AllowStarting() );
+ aUid.SetPluginType( client.PluginType() );
+ aUid.SetRomBased( client.RomBased() );
+ aUid.SetImplementationUid( client.ImplementationUid() );
+ found = ETrue;
+ }
+ }
+ }
+ return found;
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::CreateWorkerThreadL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::CreateWorkerThreadL(
+ CSipCrWorkerAo* aWorkerAo,
+ ThreadFunctionPtr aThreadFunctionPtr)
+ {
+ TName threadName(KWorkerThreadName);
+ threadName.AppendNum(static_cast<TUint64>(Math::Random()),EHex);
+ RThread thread;
+ TInt err = thread.Create(threadName,
+ aThreadFunctionPtr,
+ KDefaultStackSize,
+ NULL, // Use the same heap as the main thread
+ aWorkerAo);
+ User::LeaveIfError(err);
+ CleanupClosePushL(thread);
+ aWorkerAo->StartThreadL(thread);
+ err = iWorkerAos.Append(aWorkerAo);
+ if (err != KErrNone)
+ {
+ aWorkerAo->Cancel();
+ User::Leave(err);
+ }
+ CleanupStack::PopAndDestroy(&thread);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ChannelWorkerThreadFunction
+// ----------------------------------------------------------------------------
+//
+TInt CSIPCRServerSession::ChannelWorkerThreadFunction(TAny* aPtr)
+ {
+ return WorkerThreadFunctionImpl(aPtr,
+ &CSIPCRServerSession::ChannelImplementationL);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ConnectWorkerThreadFunction
+// ----------------------------------------------------------------------------
+//
+TInt CSIPCRServerSession::ConnectWorkerThreadFunction(TAny* aPtr)
+ {
+ return WorkerThreadFunctionImpl(aPtr,
+ &CSIPCRServerSession::HandleNextPendingRequestL);
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::WorkerThreadFunctionImpl
+// ----------------------------------------------------------------------------
+//
+TInt CSIPCRServerSession::WorkerThreadFunctionImpl(
+ TAny* aPtr,
+ WorkerFunctionPtr aWorkerFunctionPtr)
+ {
+ CSipCrWorkerAo* workerAo =
+ reinterpret_cast<CSipCrWorkerAo*>(aPtr);
+ TInt err = KErrNoMemory;
+ CTrapCleanup* cleanupStack = CTrapCleanup::New();
+ if (cleanupStack)
+ {
+ TRAP(err, SIPStrings::OpenL());
+ if (!err)
+ {
+ TRAP(err, (workerAo->Session().*aWorkerFunctionPtr)(*workerAo));
+ SIPStrings::Close();
+ REComSession::FinalClose(); // For each thread separately
+ }
+ }
+ delete cleanupStack;
+ return err;
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ProtectedAddToRequestQueueL
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::ProtectedAddToRequestQueueL(
+ CSIPCRRequestItem* aRequestItem)
+ {
+ CSIPCRITCUtility::WaitForMutexLC(iRequestQueueMutex);
+ iRequestQueue.AppendL(aRequestItem);
+ CleanupStack::PopAndDestroy(); // signals iRequestQueueMutex
+ }
+
+// ----------------------------------------------------------------------------
+// CSIPCRServerSession::ProtectedRemoveFromRequestQueue
+// ----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::ProtectedRemoveFromRequestQueue(
+ CSIPCRRequestItem* aRequestItem)
+ {
+ iRequestQueueMutex.Wait();
+ TInt index = iRequestQueue.Find(aRequestItem);
+ if (index >= 0)
+ {
+ iRequestQueue.Remove(index);
+ }
+ iRequestQueueMutex.Signal();
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPCRServerSession::RemoveFromRequestQueue
+// -----------------------------------------------------------------------------
+//
+void CSIPCRServerSession::RemoveFromRequestQueue(TAny* aCleanupData)
+ {
+ TSipCrRequestQueueCleanupData* cleanupData =
+ reinterpret_cast<TSipCrRequestQueueCleanupData*>(aCleanupData);
+ cleanupData->iSession->ProtectedRemoveFromRequestQueue(
+ cleanupData->iRequestItem);
+ }
+
+// End of File