1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/cryptomgmtlibs/securitycommonutils/inc/scsserver.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,400 @@
1.4 +/*
1.5 +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +* Server-side classes which are required to implement a session counting server.
1.19 +*
1.20 +*/
1.21 +
1.22 +
1.23 +/**
1.24 + @file
1.25 + @publishedPartner
1.26 + @released
1.27 +*/
1.28 +
1.29 +#ifndef SCSSERVER_H
1.30 +#define SCSSERVER_H
1.31 +
1.32 +#include <e32base.h>
1.33 +
1.34 +#include <scs/scsclient.h>
1.35 +#include <scs/scscommon.h>
1.36 +
1.37 +#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
1.38 +#include "scsserverconstants.h"
1.39 +#endif
1.40 +
1.41 +// -------- error handling --------
1.42 +
1.43 +
1.44 +const TInt KErrScsAsyncAlreadyQueued = -5702; ///< Tried to re-queue an outstanding request.
1.45 +
1.46 +
1.47 +
1.48 +// forward declarations
1.49 +class CScsServer;
1.50 +class CScsSession;
1.51 +class CScsSubsession;
1.52 +
1.53 +class CShutdownTimer : public CTimer
1.54 +/**
1.55 + When an instance of this class is constructed it is given a delay period.
1.56 + If the object runs to completion, i.e. if it is not cancelled, then it stops
1.57 + the active scheduler, which has the effect of terminating the server.
1.58 +*/
1.59 + {
1.60 +public:
1.61 + static CShutdownTimer* NewL(TInt aDelayUs);
1.62 +
1.63 + void Restart();
1.64 +
1.65 + void ImmediateTimeoutNextRestart();
1.66 +
1.67 +private:
1.68 + CShutdownTimer(TInt aDelayUs);
1.69 +
1.70 + // implement CTimer
1.71 + virtual void RunL();
1.72 +
1.73 +private:
1.74 + TInt iDelayUs; ///< Timer delay in microseconds.
1.75 + TBool iImmediateTimeoutNextRestart;
1.76 + };
1.77 +
1.78 +class CAsyncRequest : public CActive
1.79 +/**
1.80 + An outstanding request on the server side. A subclass should
1.81 + be created for each type of outstanding request.
1.82 +
1.83 + This class is implemented as an active object, because it is
1.84 + anticipated that some asynchronous requests can be implemented
1.85 + simply by completing the client request when a TRequestStatus
1.86 + completes. The implementor can override this behavior by
1.87 + re-implementing RunL, e.g. to free some resources before completing
1.88 + the request. If they do so, they must call CompleteAndMarkForDeletion to
1.89 + complete the client request and mark this object for deletion (alternatively
1.90 + they can simply call CAsyncRequest::RunL from their RunL).
1.91 +
1.92 + This class cannot, however, anticipate the cancellation
1.93 + mechanism. The implementor must implement DoCancel for that.
1.94 + DoCancel should not delete the client request or mark this object
1.95 + for deletion.
1.96 +
1.97 + When the implementor has allocated an instance of this
1.98 + class, they must add it to the session by calling CAsyncRequest::TransferToScsFrameworkL.
1.99 + The second-phase constructor must not leave between that and calling
1.100 + SetActive.
1.101 +
1.102 + These objects are cancelled and destroyed when the
1.103 + client-side session / subsession sends a cancel command.
1.104 +
1.105 + @see CScsSession::AddAsyncRequestL
1.106 +*/
1.107 + {
1.108 +public:
1.109 + IMPORT_C CAsyncRequest(CScsSession* aSession, CScsSubsession* aSubsession, const RMessage2& aMessage);
1.110 +
1.111 + void CancelCompleteAndMarkForDeletion(); // explicit cancel request
1.112 + void MarkForDeletion(); // session close
1.113 + IMPORT_C virtual void DoCleanup(); // Cancel this request
1.114 +
1.115 + IMPORT_C void TransferToScsFrameworkL();
1.116 +protected:
1.117 +
1.118 + IMPORT_C void CompleteAndMarkForDeletion(TInt aError);
1.119 +
1.120 + // implement CActive
1.121 + IMPORT_C virtual void RunL();
1.122 +
1.123 + // override CActive
1.124 + IMPORT_C virtual TInt RunError(TInt aError);
1.125 +
1.126 +public:
1.127 + /** Session on which this request is queued. NULL if completed. */
1.128 + CScsSession* iSession;
1.129 + /** Subsession on which this request is queued. NULL if session-relative. */
1.130 + CScsSubsession* iSubsession;
1.131 + /** Outstanding message to complete. */
1.132 + const RMessagePtr2 iMessagePtr2;
1.133 + /** Identifies outstanding request. */
1.134 + TInt iFunction;
1.135 + };
1.136 +
1.137 +class CScsSubsession : public CObject
1.138 +/**
1.139 + If the server implementation supports subsessions, they must
1.140 + derive from this class.
1.141 +
1.142 + WARNING: Because this class derives from CObject you must not simply delete
1.143 + an instance of a class derived from this class (ie. your subsession), instead you MUST
1.144 + Close() it.
1.145 +
1.146 + In practise this probably means you need a ConstructL like this:-
1.147 + CFred *self = new(ELeave) CFred(....);
1.148 + CleanupClosePushL(*self); // Note use of CleanupClosePushL and of *self
1.149 + self->ConstructL(...);
1.150 + CleanupStack::Pop(self); // Note use of *self instead of self
1.151 + */
1.152 + {
1.153 +public:
1.154 + /**
1.155 + SCS routes subsession messages to this function; the session
1.156 + object does not have to decode them itself.
1.157 +
1.158 + @param aFunction Implementation function, i.e. the function
1.159 + identifier with the SCS field removed.
1.160 + @param aMessage Standard server message object.
1.161 + @return ETrue means complete client request now.
1.162 + */
1.163 + virtual TBool DoServiceL(TInt aFunction, const RMessage2& aMessage) = 0;
1.164 +
1.165 +protected:
1.166 + IMPORT_C CScsSubsession(CScsSession &aSession);
1.167 +
1.168 +public:
1.169 + // Note this is setup by the constructor, before the derived class
1.170 + // ConstructL is called.
1.171 + CScsSession& iSession; ///< Owning session.
1.172 + };
1.173 +
1.174 +class CScsSession : public CSession2
1.175 +/**
1.176 + When this session object is destroyed (because the client-server session
1.177 + has closed,) this notifies the server object which decrements the session
1.178 + count. Therefore, the server can be shut down after an inactivity
1.179 + period during which there are no open sessions.
1.180 +
1.181 + This object also frees any remaining subsession objects when it is closed.
1.182 +*/
1.183 + {
1.184 +protected:
1.185 + IMPORT_C void ConstructL();
1.186 + IMPORT_C virtual ~CScsSession();
1.187 +
1.188 + // implement CSession2
1.189 + IMPORT_C virtual void ServiceL(const RMessage2& aMessage);
1.190 + // override CSession2
1.191 + IMPORT_C virtual void ServiceError(const RMessage2& aMessage, TInt aError);
1.192 + IMPORT_C void CloseAllSubsessionsL();
1.193 +
1.194 + // asynchronous requests
1.195 + //IMPORT_C void CompleteAsyncRequest(CAsyncRequest* aAsyncRequest, TInt aReason);
1.196 +
1.197 +private:
1.198 + /**
1.199 + This function is called from ServiceL after it has removed the
1.200 + SCS-specific field and handled any other messages. I.e., it is
1.201 + called for functions which really require the session as opposed
1.202 + to subsession commands or debugging commands such as heap failure.
1.203 +
1.204 + @param aFunction Implementation function, i.e. the function
1.205 + identifier with the SCS field removed.
1.206 + @param aMessage Standard server message object.
1.207 + @return ETrue if client message should be completed now.
1.208 + */
1.209 + virtual TBool DoServiceL(TInt aFunction, const RMessage2& aMessage) = 0;
1.210 +
1.211 + void PreCloseSession();
1.212 +
1.213 + IMPORT_C virtual CScsSubsession* DoCreateSubsessionL(TInt aFunction, const RMessage2& aMessage);
1.214 +
1.215 + // subessions
1.216 + CScsSubsession* GetSubsessionL(const RMessage2& aMessage);
1.217 + void DeleteSubsessionContainers();
1.218 +
1.219 + void CreateSubsessionL(TInt aFunction, const RMessage2& aMessage);
1.220 + void CloseSubsessionL(const RMessage2& aMessage);
1.221 + TBool CallSubsessionFunctionL(TInt aFunction, const RMessage2& aMessage);
1.222 + void CancelAsyncSubsessionRequestL(TInt aFunction, const RMessage2& aMessage);
1.223 +
1.224 + // asynchronous requests (support)
1.225 + CAsyncRequest* FindSessionAsyncRequest(TInt aFunction);
1.226 + void CancelAsyncSessionRequestL(TInt aFunction);
1.227 +
1.228 +private:
1.229 + /**
1.230 + Number of open subsessions before a new one is created. This is used
1.231 + to manage cleanup if the subsession cannot be created.
1.232 + */
1.233 + TInt iPreCreateSubsessionCount;
1.234 +
1.235 + CObjectCon* iSsObjects; ///< Currently open subsessions.
1.236 + CObjectIx* iSsHandles; ///< Maps handles to open subsessions.
1.237 +
1.238 +public:
1.239 + IMPORT_C CScsSession(CScsServer &aServer);
1.240 + // This duplicates the iServer/Server() code in the base class,
1.241 + // BUT this variable IS setup before derived class ConstructL is
1.242 + // called and is NOT const. This trades off 4 bytes of memory
1.243 + // against making the code cleaner and more consistent....
1.244 + CScsServer& iServer; ///< Owning server.
1.245 + };
1.246 +
1.247 +/**
1.248 + Pass to CScsServer::CancelOutstandingRequests to mean all requests
1.249 + associated with a session or its subsessions.
1.250 + */
1.251 +CScsSubsession*const KWildSubsession = reinterpret_cast<CScsSubsession*>(~0);
1.252 +
1.253 +class CScsServer : public CPolicyServer
1.254 +/**
1.255 + The main server object allocates sessions. It also uses
1.256 + a shutdown timer to stop the server when there have been no
1.257 + open sessions for a set period.
1.258 +
1.259 + The implementor must define a subclass which returns session
1.260 + objects of the appropriate type.
1.261 + */
1.262 + {
1.263 +public:
1.264 + IMPORT_C virtual ~CScsServer();
1.265 +
1.266 + void IncrementSessionCount();
1.267 + void DecrementSessionCount();
1.268 + inline TInt SessionCount() const;
1.269 +
1.270 + IMPORT_C void ShutdownWhenIdleL();
1.271 +
1.272 + // asynchronous requests
1.273 + void AddAsyncRequestL(CAsyncRequest* aAsyncRequest);
1.274 + void CancelAsyncRequest(
1.275 + CScsSession* aSession, CScsSubsession* aSubsession, TInt aFunction);
1.276 +
1.277 + void CancelOutstandingRequests(CScsSession* aSession, TBool aCompleteClientRequests);
1.278 + void CancelOutstandingRequests(CScsSession* aSession, CScsSubsession* aSubsession, TBool aCompleteClientRequests);
1.279 +
1.280 + /**
1.281 + This function is called just before the SCS framework marks the heap for OOM
1.282 + testing and just before checking the heap.
1.283 +
1.284 + Typically this function should compact any arrays and free objects which change size and can
1.285 + not be compacted back to the same level.
1.286 + */
1.287 + IMPORT_C virtual void DoPreHeapMarkOrCheckL();
1.288 +
1.289 + /**
1.290 + This function is called just after the heap has either been marked or checked (which is just
1.291 + after DoPreHeapMarkOrCheck).
1.292 +
1.293 + Typically this function should re-create any objects which had to be freed by DoPreHeapMarkOrCheck.
1.294 + */
1.295 + IMPORT_C virtual void DoPostHeapMarkOrCheckL();
1.296 +
1.297 + enum TFunctionRanges
1.298 + /**
1.299 + Function ranges to be used when configuring the server security via
1.300 + a CPolicyServer::TPolicy object.
1.301 +
1.302 + Session/sSubsession function codes will be ORed into the
1.303 + EBaseSession/EBaseSubSession ranges.
1.304 +
1.305 + Values from EBaseMustAllow, upwards, are used internally and must be allowed.
1.306 +
1.307 + If there are multiple subsession types (with different function
1.308 + code values), then codes must be be different for each subsession
1.309 + (this restriction only applies if using the CPolicyServer::TPolicy
1.310 + mechanism to configure server security).
1.311 +
1.312 + WARNNIG: These ranges MUST match the values in scscommon.h TScsFunction.
1.313 + */
1.314 + {
1.315 + EBaseSession = 0x01000000,
1.316 + EBaseSubSession = 0x02000000,
1.317 + EBaseMustAllow = 0x03000000 //< Must allow from EBaseMustAllow upwards
1.318 + };
1.319 +
1.320 + static TInt StripScsFunctionMask(TInt aFunctionId) { return aFunctionId & ~ScsImpl::KScsFunctionMask;}
1.321 +
1.322 +protected:
1.323 + IMPORT_C CScsServer(const TVersion& aVersion, CActive::TPriority aPriority = CActive::EPriorityStandard);
1.324 + IMPORT_C CScsServer(const TVersion& aVersion, const CPolicyServer::TPolicy& aPolicy, CActive::TPriority aPriority = CActive::EPriorityStandard);
1.325 + IMPORT_C void ConstructL(TInt aShutdownPeriodUs);
1.326 +
1.327 + IMPORT_C void DisableShutdownTimer();
1.328 + IMPORT_C void EnableShutdownTimerL(TInt aShutdownPeriodUs);
1.329 +
1.330 +
1.331 + // implement CServer2
1.332 + IMPORT_C virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
1.333 +
1.334 + /**
1.335 + NewSessionL checks that this server supports the version which is
1.336 + requested by the client. If that is so, then it calls this function
1.337 + to allocate a new session object.
1.338 +
1.339 + @param aMessage Connection message, as passed to NewSessionL.
1.340 + @return New session object. This is owned by the kernel,
1.341 + which will delete it when the session is closed.
1.342 + */
1.343 + virtual CScsSession* DoNewSessionL(const RMessage2& aMessage) = 0;
1.344 +
1.345 +private:
1.346 + // asynchronous requests
1.347 + CAsyncRequest* FindAsyncRequest(
1.348 + CScsSession* aSession, CScsSubsession* aSubsession, TInt aFunction);
1.349 +
1.350 + static TInt RemoveCompletedRequests(TAny* aPtr);
1.351 + void RemoveCompletedRequests();
1.352 +
1.353 +private:
1.354 + /**
1.355 + This server's version. It is compared against client's requested version
1.356 + when the client attempts to make a connection.
1.357 + */
1.358 + const TVersion iVersion;
1.359 +
1.360 + /** Number of open sessions. Used to start and cancel the shutdown timer. */
1.361 + TInt iSessionCount;
1.362 +
1.363 + /**
1.364 + Shutdown timer, started when there are no open sessions, cancelled when
1.365 + the first session is created.
1.366 + */
1.367 + CShutdownTimer* iShutdownTimer;
1.368 +
1.369 +
1.370 +public:
1.371 + /**
1.372 + Generates instances of CObjectCon, for each session to host its subsessions.
1.373 + Public because must be accessible to session objects.
1.374 + */
1.375 + CObjectConIx* iContainerIndex;
1.376 +
1.377 + /** Currently outstanding requests. */
1.378 + RPointerArray<CAsyncRequest> iAsyncRequests;
1.379 +
1.380 + /** Runs to remove completed requests from iAsyncRequests. */
1.381 + CAsyncCallBack* iAsyncCleanup;
1.382 + };
1.383 +
1.384 +inline TInt CScsServer::SessionCount() const
1.385 + {
1.386 + return iSessionCount;
1.387 + }
1.388 +
1.389 +
1.390 +
1.391 +// -------- startup --------
1.392 +
1.393 +/**
1.394 + The server executable must implement a factory function with this
1.395 + signature and pass it to StartScsServer to allocate and start the server.
1.396 + */
1.397 +typedef CScsServer* (*TScsServerFactory)();
1.398 +
1.399 +IMPORT_C TInt StartScsServer(TScsServerFactory aServerFactoryLC);
1.400 +
1.401 +
1.402 +#endif // #ifndef SCSSERVER_H
1.403 +