telephonyprotocols/gprsumtsqosprt/inc/async_request.h
changeset 0 3553901f7fa8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyprotocols/gprsumtsqosprt/inc/async_request.h	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,330 @@
+// Copyright (c) 2007-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:
+//
+
+#ifndef __ASYNC_REQUEST_H__
+#define __ASYNC_REQUEST_H__
+
+#include <networking/umtsnifcontrolif.h>
+#include "extension.h"
+#include "guqos_log.h"
+
+enum TRequest
+	{
+	EPendingAny = 0,
+	EPendingCreate,
+	EPendingDelete,
+	EPendingConfig,
+	EPendingSetQoS,
+	EPendingModifyActive,
+	EPendingActivate,
+	EPendingPacketFilterAdd,
+    EPendingPacketFilterRemove,
+    EPendingSblpParameterAdd,       // Request for adding sblp parameter
+    EPendingSblpParameterRemove,    // Request for removing sblp parameter
+	EPendingTFTRemove,
+	EPendingCancel,
+	EPendingNone
+	};
+
+class CFlowData;
+class CPdpContext;
+class CNif;
+
+template <class T>
+struct SActionStep 
+	{
+	/**
+	* An action of the state machine.
+	*
+	* Its it up to the action whether parameters are used or not. When the
+	* state machine is started, the parameters are both NULL, as there is
+	* no preceding event from NIF. Thus, the first action(s) usually ignore
+	* the parameters.
+	*
+	* The aContext parameter is initially NULL and upon each event reply
+	* from the NIF, it is filled with the related context. Action can
+	* change the current context for the subsequent actions using
+	* CRequestBase::SetContext . This change persists for the duration
+	* of the current CRequestBase::Run or CRequestBase::Start .
+	*
+	* @param aContext The context
+	* @param aParams  NULL or the parameters of the event from NIF
+	*
+	* @return
+	*	@li EFalse - No action activated, proceed to the next state
+	*	@li ETrue - Action activated. Action can be completion and
+	*		destruction of the request object. Thus, when action
+	*		returns ETrue, the member variables of the current
+	*		request MUST NOT BE REFERENCED.
+	*/
+	TBool (T::*iAction)(CPdpContext* aContext, const TContextParameters* aParams);
+	/**
+	* Expected result, if action activated.
+	* When action activates some NIF Control request, this code specifies the
+	* type of the expected result. When the event arrives, this code can be
+	* checked in the Run() function.
+	*/
+	//TRequest iRequest;
+	};
+
+// Base class for async requests: separate flow-specific and channel-specific requests?
+class CRequestBase : public CBase
+	{
+protected:
+	virtual ~CRequestBase();
+public:
+	CRequestBase(CNif& aNif);
+
+	virtual void Start();
+	void Run(const TRequest aRequest, CPdpContext* aPdpContext, const TContextParameters& aParams);
+	virtual TBool Action(CPdpContext* aPdpContext, const TContextParameters* aParams) = 0;
+
+	virtual void Cancel(CFlowData* aFlowData);
+	virtual void Cancel(CPdpContext* aContext) = 0;
+
+    TBool IsOk(TInt aResult, CPdpContext *aContext);
+
+    void CompleteAndDestruct(TInt aErrorCode, const TQoSParameters* aParams, const TExtensionData& aExtension=TExtensionData());
+
+
+	TSglQueLink iLink;
+protected:
+	virtual void Failure(CPdpContext* aPdpContext, TInt aErrorCode);
+
+	void SetContext(CPdpContext *aContext);
+	void SetExpected(const TRequest aRequest);
+
+	TBool ActionRemovePacketFilter(CPdpContext*, const TContextParameters*);
+
+	TBool ActionAddPacketFilter(CPdpContext*, const TContextParameters*);
+	TBool DoAddFlowToContext(CPdpContext*, const TContextParameters*);
+	TBool ActionCommit(CPdpContext*, const TContextParameters*);
+	TBool ActionRequestComplete(CPdpContext*, const TContextParameters*);
+
+	RExtensionData iExtension;		// Extension Data for the completion message
+	MQoSNegotiateEvent* iNotify;
+	CNif& iNif;
+
+	//
+	// The state machine information
+	//
+	TInt iState;		// Current State number [0...]
+	/**
+	* Associated flow, or NULL, if none.
+	*
+	* Some actions may use a flow as an additional input. The validity
+	* of this is at responsibility of the request implementation.
+	*/
+	CFlowData* iFlow;
+	/**
+	* The context has been modified.
+	*
+	* iContextModified is TRUE, when the iContext has queued modifications in NIF.
+	* This only controls whether ModifyActive can be skipped in ActionCommit.
+	*
+	* This is currently automaticly set whenever SetExpected is called,
+	* and cleared when iContext is changed.
+	*/
+	TBool iContextModified;
+private:
+	/**		
+	* The expected event completion.
+	*
+	* This value is defined only when some request has been passed to
+	* NIF Control() and then the value is the expected reply event
+	* from the NIF.
+	*/
+	TRequest iExpected;
+	/**
+	* The current context being acted on (or NULL).
+	*
+	* This value is defined only when executing the actions (e.g. while
+	* executing Run or Start. In other times, it is just left over
+	* value that might point to already destroyed context and must
+	* never be used.
+	*/
+	CPdpContext* iContext;
+	/**
+	* The current context parameters from NIF (or NULL)
+	*
+	* This value is defined only when executin Run().
+	*/
+	const TContextParameters* iParams;
+#ifdef _LOG
+	//
+	// For DEBUG / LOGGING purposes only
+public:
+	const TDesC* iName;	// Name must be set by the constructor of each derived class.
+#endif
+	};
+
+
+// Remove unneeded TFT's from the context
+class CClose : public CRequestBase
+	{
+	~CClose();
+public:
+	static CClose* New(CPdpContext& aContext);
+
+	virtual void Start();
+	virtual TBool Action(CPdpContext* aContext, const TContextParameters* aParams)
+		{return (this->*iActionList[iState].iAction)(aContext, aParams); }
+
+	virtual void Cancel(CPdpContext* aContext);
+
+protected:
+	CClose(CPdpContext& aContext);
+
+private:
+	static const SActionStep<CClose> iActionList[];
+	CPdpContext& iClosing;
+	};
+	
+// Context deletion requst
+class CDeleteRequest : public CRequestBase
+	{
+public:
+	static CDeleteRequest* NewL(CPdpContext* aContext);
+	
+	virtual void Start();
+	// This request has no "action list", it's all done in Start()
+	virtual TBool Action(CPdpContext*, const TContextParameters*) {return ETrue; }
+	virtual void Cancel(CPdpContext* aContext);
+protected:
+	CDeleteRequest(CPdpContext* aContext);
+private:
+	CPdpContext *iDelete;
+	};
+
+// Intermediate shared class for requests that negotiate QoS
+class CNegotiationBase : public CRequestBase
+	{
+protected:
+	~CNegotiationBase() {}
+public:
+	void SetParameters(const TQoSParameters& aParams, CExtensionPolicy& aPolicy);
+    void SetParametersFlowExtn(CExtensionPolicy &aPolicy);
+protected:
+ 	CNegotiationBase(CNif& aNif);
+	void Failure(CPdpContext* aPdpContext, TInt aErrorCode);
+
+
+	TBool ActionAddSblpParameter(CPdpContext*, const TContextParameters*);
+	TBool ActionSetQoS(CPdpContext*, const TContextParameters*);
+	TBool ActionNegotiationComplete(CPdpContext *, const TContextParameters*);
+
+    TBool iSblp;
+	RFlowExtensionParams  iFlowExtnParams;
+	TQoSParameters	iGeneric;
+	TQoSRequested	iUmts;
+	};
+
+
+class COpenChannel : public CNegotiationBase
+	{
+	~COpenChannel();
+public:
+	static COpenChannel* New(TUint aChannelId, CFlowData &aFlow, MQoSNegotiateEvent* aNotify);
+
+
+	virtual void Start();
+	virtual TBool Action(CPdpContext* aContext, const TContextParameters* aParams)
+		{return (this->*iActionList[iState].iAction)(aContext, aParams); }
+
+	virtual void Failure(CPdpContext* aPdpContext, TInt aErrorCode);
+	virtual void Cancel(CPdpContext* aContext);
+
+protected:
+	COpenChannel(TInt aChannelId, CFlowData& aFlow, MQoSNegotiateEvent* aNotify);
+
+	TBool ActionNewContext(CPdpContext*, const TContextParameters*);
+	TBool DoRememberCreatedContext(CPdpContext*, const TContextParameters*);
+
+private:
+
+	static const SActionStep<COpenChannel> iActionList[];
+
+	const TInt iChannelId;
+	CPdpContext* iNewContext;
+	};
+
+
+class CNegotiateChannel : public CNegotiationBase
+	{
+	~CNegotiateChannel();
+public:
+	static CNegotiateChannel* New(CPdpContext* aContext, MQoSNegotiateEvent* aNotify);
+
+	virtual void Start();
+	virtual TBool Action(CPdpContext* aContext, const TContextParameters* aParams)
+		{return (this->*iActionList[iState].iAction)(aContext, aParams); }
+	virtual void Cancel(CPdpContext* aContext);
+
+protected:
+	CNegotiateChannel(CPdpContext* aContext, MQoSNegotiateEvent* aNotify);
+	void ConstructL();
+
+private:
+	static const SActionStep<CNegotiateChannel> iActionList[];
+	CPdpContext* iChannel;
+	};
+
+class CJoinRequest : public CRequestBase
+	{
+	~CJoinRequest();
+public:
+	static CJoinRequest* New(CPdpContext* aContext, CFlowData* aFlowData, MQoSNegotiateEvent* aNotify);
+
+	virtual void Start();
+	virtual TBool Action(CPdpContext* aContext, const TContextParameters* aParams)
+		{return (this->*iActionList[iState].iAction)(aContext, aParams); }
+
+	virtual void Failure(CPdpContext* aPdpContext, TInt aErrorCode);
+	virtual void Cancel(CPdpContext* aContext);
+
+protected:
+	CJoinRequest(CPdpContext* aContext, CFlowData* aFlowData, MQoSNegotiateEvent* aNotify);
+
+	TBool DoStartWithTargetContext(CPdpContext *, const TContextParameters*);
+
+
+private:
+	static const SActionStep<CJoinRequest> iActionList[];
+	CPdpContext* iChannel;
+	};
+
+class CLeaveRequest : public CRequestBase
+	{
+	~CLeaveRequest();
+public:
+	static CLeaveRequest* New(CPdpContext* aContext, CFlowData* aFlowData, MQoSNegotiateEvent* aNotify);
+
+	virtual void Start();
+	virtual TBool Action(CPdpContext* aContext, const TContextParameters* aParams)
+		{return (this->*iActionList[iState].iAction)(aContext, aParams); }
+
+	virtual void Failure(CPdpContext* aPdpContext, TInt aErrorCode);
+	virtual void Cancel(CPdpContext* aContext);
+
+protected:
+	CLeaveRequest(CPdpContext* aContext, CFlowData* aFlowData, MQoSNegotiateEvent* aNotify);
+	void ConstructL();
+
+private:
+	static const SActionStep<CLeaveRequest> iActionList[];
+	CPdpContext* iChannel;
+	};
+
+#endif