commsfwsupport/commselements/nodemessages/inc/nm_interfaces.h
changeset 0 dfb7c4ff071f
child 29 9644881fedd0
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @publishedPartner
       
    19  @released
       
    20 */
       
    21 
       
    22 #ifndef SYMBIAN_NM_INTERFACES_H
       
    23 #define SYMBIAN_NM_INTERFACES_H
       
    24 
       
    25 //#include <elements/nm_signals.h>
       
    26 #include <elements/nm_address.h>
       
    27 #include <elements/nm_log.h>
       
    28 
       
    29 
       
    30 #ifdef _DEBUG
       
    31 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    32 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    33 _LIT(KSpecAssert_ElemNodeMessIntH, "ElemNodeMessIntH");
       
    34 #endif
       
    35 
       
    36 namespace Messages
       
    37 {
       
    38 
       
    39 class MTransportSender;
       
    40 class ANode;
       
    41 class TSignalBase;
       
    42 
       
    43 
       
    44 class TClientType
       
    45 /*
       
    46 TClientType defines a technology agnostic collection of enums for types and
       
    47 flags describing various traits of peers. It is also a placeholder for these
       
    48 values. When implementing a relation with a peer, TClientType (or its technology
       
    49 specific override) can be used to collect informations about the peers.
       
    50 @see RNodeInterface
       
    51 */
       
    52 	{
       
    53 public:
       
    54     enum TType
       
    55         {
       
    56         //-=============================================
       
    57         //
       
    58         // 1. Types 32bits (a client can only have one type)
       
    59         //
       
    60         //-=============================================
       
    61         EAll            = 0xFFFFFFFF,
       
    62         EUnknown        = 0x00000000,
       
    63         ERegistrar      = 0x00000001, //Useful general purpose role.
       
    64                                       //Used to represent simple non-standard or one-off or transient
       
    65                                       //roles which now do not need to be specially defined for these
       
    66                                       //simple and/or rare relationships.
       
    67         EWorker         = 0x00000002, //Useful general purpose role.
       
    68 
       
    69 		/**
       
    70 		@internalTechnology
       
    71 		Reserved types that can change at any time and must NOT be used under any circumstances.
       
    72 		Please take care when defining derived client types (do not reference ELastReservedType).
       
    73 		*/
       
    74         ELastReservedType_InternalTechnology_CanBeReusedAtAnyTime_DoNotUseInCode = 0x00000080,
       
    75 		};
       
    76 
       
    77 	enum TFlags
       
    78 		{
       
    79         //-=============================================
       
    80         //
       
    81         // 2. Flags 32bits (a client can have many flags)
       
    82         //
       
    83         //-=============================================
       
    84         ELeaving        = 0x00000001, //Client has been sent the final goodbye message (e.g TClientLeavingRequest)
       
    85                              //and we are awaiting the channel clear confirmation (e.g. TLeaveComplete).
       
    86                              //No further communication with this client is safe as it assumes we discard
       
    87                              //any references to it. For example it could destruct itself etc.
       
    88 		EAdministrative = 0x00000002, //These clients perform some administrative tasks on our node.
       
    89 
       
    90 		/**
       
    91 		@internalTechnology
       
    92 		Reserved flags that can change at any time and must NOT be used under any circumstances.
       
    93 		Please take care when defining derived client flags (do not reference ELastReservedFlag).
       
    94 		*/
       
    95         ELastReservedFlag_InternalTechnology_CanBeReusedAtAnyTime_DoNotUseInCode = 0x00000080
       
    96         };
       
    97 
       
    98 public:
       
    99 	IMPORT_C static const TClientType& NullType();
       
   100 
       
   101 	TClientType()
       
   102 	:	iClientType(EUnknown),
       
   103 	    iClientFlags(0)
       
   104 		{
       
   105 		}
       
   106 
       
   107 	TClientType(TUint aClientType, TUint aClientFlags = 0)
       
   108 	:	iClientType(aClientType),
       
   109 		iClientFlags(aClientFlags)
       
   110 		{
       
   111 		}
       
   112 
       
   113 	TClientType(const TClientType& aClientType)
       
   114 	:	iClientType(aClientType.iClientType),
       
   115 		iClientFlags(aClientType.iClientFlags)
       
   116 		{
       
   117 		}
       
   118 
       
   119 	TBool IsNull() const
       
   120 	    {
       
   121 	    return iClientType == 0 && iClientFlags == 0;
       
   122 	    }
       
   123 
       
   124 	TUint32 Type() const
       
   125 	    {
       
   126 	    return iClientType;
       
   127 	    }
       
   128 
       
   129 	TUint32 Flags() const
       
   130 	    {
       
   131 	    return iClientFlags;
       
   132 	    }
       
   133 
       
   134 	TUint32 SetFlags(TUint32 aFlags)
       
   135 	    {
       
   136 	    return iClientFlags |= aFlags;
       
   137 	    }
       
   138 
       
   139 	TUint32 ClearFlags(TUint32 aFlags)
       
   140 	    {
       
   141 	    return iClientFlags &= ~aFlags;
       
   142 	    }
       
   143 
       
   144 protected:
       
   145     TUint32 iClientType;
       
   146     TUint32 iClientFlags;
       
   147 	};
       
   148 
       
   149 //None of the specified
       
   150 struct TNoMatchPolicy
       
   151 	{
       
   152 	inline static TBool Match(TUint32 aVal, TUint32 aMatch)
       
   153 		{
       
   154         return (aVal & aMatch) == 0;
       
   155 		}
       
   156 	};
       
   157 
       
   158 //Any of the specified, can be more, can be less
       
   159 struct TAnyMatchPolicy
       
   160 	{
       
   161 	inline static TBool Match(TUint32 aVal, TUint32 aMatch)
       
   162 		{
       
   163         return (aVal & aMatch) != 0;
       
   164 		}
       
   165 	};
       
   166 
       
   167 //Any of the specified, both can be null, can be more, can be less
       
   168 struct TExactOrAnyMatchPolicy
       
   169 	{
       
   170 	inline static TBool Match(TUint32 aVal, TUint32 aMatch)
       
   171 		{
       
   172 		return (aVal == aMatch) || (aVal & aMatch) != 0;
       
   173 		}
       
   174 	};
       
   175 
       
   176 //All of the specified, can't be more, can be less
       
   177 struct TSubSetMatchPolicy
       
   178 	{
       
   179 	inline static TBool Match(TUint32 aVal, TUint32 aMatch)
       
   180 		{
       
   181         return (aVal & aMatch) == aVal;
       
   182 		}
       
   183 	};
       
   184 
       
   185 //Any of the specified, can be more, can't be less
       
   186 struct TSuperSetMatchPolicy
       
   187 	{
       
   188 	inline static TBool Match(TUint32 aVal, TUint32 aMatch)
       
   189 		{
       
   190         return (aVal & aMatch) == aMatch;
       
   191 		}
       
   192 	};
       
   193 
       
   194 //All of the specified, can't be less, can't be more
       
   195 struct TExactMatchPolicy
       
   196 	{
       
   197 	inline static TBool Match(TUint32 aVal, TUint32 aMatch)
       
   198 		{
       
   199 		return aVal == aMatch;
       
   200 		}
       
   201 	};
       
   202 
       
   203 template <typename TTYPEMATCHPOLICY = TSubSetMatchPolicy, typename TFLAGSMATCHPOLICY = TSuperSetMatchPolicy>
       
   204 struct TMatchPolicy
       
   205 	{
       
   206 	inline static TBool Match(const TClientType& aType, const TClientType& aMatch)
       
   207 		{
       
   208 		return TTYPEMATCHPOLICY::Match(aType.Type(),aMatch.Type())
       
   209 			&& TFLAGSMATCHPOLICY::Match(aType.Flags(),aMatch.Flags());
       
   210 		}
       
   211 	};
       
   212 
       
   213 template <typename TINCMATCHPOLICY = TMatchPolicy<TSubSetMatchPolicy,TSuperSetMatchPolicy>, typename TEXCMATCHPOLICY = TMatchPolicy<TExactMatchPolicy,TExactMatchPolicy> >
       
   214 struct TTypeMatchPolicy
       
   215 	{
       
   216 	inline static TBool Match(const TClientType& aType, const TClientType& aInclude, const TClientType& aExclude)
       
   217 		{
       
   218 		TBool inc = TINCMATCHPOLICY::Match(aType, aInclude);
       
   219 		TBool exc = aExclude.IsNull() || !TEXCMATCHPOLICY::Match(aType, aExclude);
       
   220 		return inc && exc;
       
   221 		}
       
   222 	};
       
   223 
       
   224 //We could be using partially specialised typedefs here,
       
   225 //if they only were supported by C++ at the time of writing this code...
       
   226 //                         INCType   |     Type                  Flag              EXCType    |      Type               Flag
       
   227 //                       ----------------------------------------------           -------------------------------------------------
       
   228 typedef TTypeMatchPolicy<TMatchPolicy<TSubSetMatchPolicy,  TSuperSetMatchPolicy>, TMatchPolicy<TSuperSetMatchPolicy,TAnyMatchPolicy> > TDefaultClientMatchPolicy;
       
   229 typedef TTypeMatchPolicy<TMatchPolicy<TSuperSetMatchPolicy,TSuperSetMatchPolicy>, TMatchPolicy<TSuperSetMatchPolicy,TAnyMatchPolicy> > TFlagsOnlyClientMatchPolicy;
       
   230 typedef TTypeMatchPolicy<TMatchPolicy<TSubSetMatchPolicy,  TNoMatchPolicy>,       TMatchPolicy<TSuperSetMatchPolicy,TAnyMatchPolicy> > TExcludeTypeAndFlagClientMatchPolicy;
       
   231 typedef TTypeMatchPolicy<TMatchPolicy<TSubSetMatchPolicy, TExactOrAnyMatchPolicy>, TMatchPolicy<TSuperSetMatchPolicy,TAnyMatchPolicy> > TExactOrAnyIncludeFlagsClientMatchPolicy;
       
   232 
       
   233 
       
   234 class RClientInterface
       
   235 /*
       
   236 Represents an opaque recipient of messages with no assumptions about its
       
   237 type (i.e.: it's not necesserilly a node and the only thing known about it, is its
       
   238 TRuntimeCtxId). Relations with such recipients should be implemented by declaring
       
   239 RClientInterface as members.
       
   240 @see RNodeInterface
       
   241 */
       
   242 	{
       
   243 public:
       
   244 	IMPORT_C RClientInterface();
       
   245 	IMPORT_C virtual ~RClientInterface(); //Derived types may be used via base ptrs
       
   246 	IMPORT_C void Open(const TRuntimeCtxId& aPostTo, MTransportSender* aSender = NULL);
       
   247 	IMPORT_C void Close(); // stomp members
       
   248 	IMPORT_C TBool operator==(const TRuntimeCtxId& aRHS) const;
       
   249 	IMPORT_C TBool operator==(const RClientInterface& aRHS) const;
       
   250 
       
   251 	IMPORT_C TBool IsOpen() const;
       
   252 
       
   253 	inline const TRuntimeCtxId& RecipientId() const
       
   254 		{
       
   255 		return *reinterpret_cast<const TRuntimeCtxId*>(iRecipientAddress);
       
   256 		}
       
   257 
       
   258 	IMPORT_C static void OpenPostMessageClose(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TSignalBase& aMessage);
       
   259 	IMPORT_C void PostMessage(const TRuntimeCtxId& aPostFrom, const TSignalBase& aMessage) const;
       
   260 
       
   261 protected:
       
   262 	void PostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TSignalBase& aMessage) const;
       
   263 	inline TRuntimeCtxId& RecipientRef()
       
   264 		{
       
   265 		return *reinterpret_cast<TRuntimeCtxId*>(iRecipientAddress);
       
   266 		}
       
   267 
       
   268 	inline const TRuntimeCtxId& RecipientRef() const
       
   269 		{
       
   270 		return *reinterpret_cast<const TRuntimeCtxId*>(iRecipientAddress);
       
   271 		}
       
   272 
       
   273 private:
       
   274 	MTransportSender* iTransportSender;
       
   275 	TUint8 iRecipientAddress[__Align8(TRuntimeCtxId::KMaxInlineAddressSize)];
       
   276 	};
       
   277 
       
   278 
       
   279 class RNodeInterface : public RClientInterface
       
   280 /*
       
   281 RNodeInterface represents a relation with a node (ANode). It does so by:
       
   282 - storing the node's address (TNodeId)
       
   283 - collecting informations about the node (::Type & ::Flags).
       
   284 Classes (typically nodes) should implement relations with another nodes
       
   285 by declaring RNodeInterface as members.
       
   286 @see TClientType
       
   287 */
       
   288 	{
       
   289 	friend class TClientIterBase;
       
   290 
       
   291 public:
       
   292 	IMPORT_C void Open(TNodeId aPostTo, const TClientType& aClientType = TClientType::NullType(), MTransportSender* aSender = NULL);
       
   293 	IMPORT_C void Close();
       
   294 	IMPORT_C TBool operator==(const RNodeInterface& aRHS) const;
       
   295 
       
   296 	inline TBool operator==(const TRuntimeCtxId& aRHS) const
       
   297 		{
       
   298 		return RClientInterface::operator==(aRHS);
       
   299 		}
       
   300 
       
   301 	IMPORT_C void PostMessage(const TRuntimeCtxId& aPostFrom, const TNodeId::TRemainder& aPostTo, const TSignalBase& aMessage) const;
       
   302 	inline void PostMessage(const TRuntimeCtxId& aPostFrom, const TSignalBase& aMessage) const
       
   303 		{
       
   304 		#ifdef SYMBIAN_TRACE_ENABLE
       
   305 			if(Flags() & TClientType::ELeaving)
       
   306 				{
       
   307 				NM_LOG_START_BLOCK(KNodeMessagesSubTag, _L8("ERROR: Post while node is leaving"));
       
   308 				NM_LOG_ADDRESS_EXT(KNodeMessagesSubTag, aPostFrom, _L8("From:"));
       
   309 				NM_LOG_ADDRESS_EXT(KNodeMessagesSubTag, RecipientId(), _L8("To:"));
       
   310 				NM_LOG_MESSAGE_EXT(KNodeMessagesSubTag, aMessage, _L8("Msg:"));
       
   311 				NM_LOG_END_BLOCK(KNodeMessagesSubTag, KNullDesC8);
       
   312 				}
       
   313 		#endif
       
   314 		__ASSERT_DEBUG(!(Flags() & TClientType::ELeaving), User::Panic(KSpecAssert_ElemNodeMessIntH, 1)); //OOOOOPS! What are you doing??
       
   315 		RClientInterface::PostMessage(aPostFrom, aMessage);
       
   316 		}
       
   317 
       
   318 	inline const TNodeId& RecipientId() const
       
   319 		{
       
   320 		return address_cast<TNodeId>(RClientInterface::RecipientId());
       
   321 		}
       
   322 
       
   323 	TClientType& ClientType()
       
   324 		{
       
   325 		return iClientType;
       
   326 		}
       
   327 
       
   328 	TUint32 Type() const
       
   329 	    {
       
   330 	    return iClientType.Type();
       
   331 	    }
       
   332 
       
   333 	TUint32 Flags() const
       
   334 	    {
       
   335 	    return iClientType.Flags();
       
   336 	    }
       
   337 
       
   338 	TUint32 SetFlags(TUint32 aFlags)
       
   339 	    {
       
   340 #if defined(_DEBUG) && defined(NM_LOG_FLAG_SETTINGS)
       
   341 	    // Note that this generates quite alot of logging, hence is not turned on by default.
       
   342 	    // Note also that (a minority of) flag setting may also take place in TNodePeerId.  
       
   343 	    const TUint32 oldFlags = Flags();
       
   344 	    const TUint32 newFlags = iClientType.SetFlags(aFlags);
       
   345 	    if (oldFlags != newFlags)
       
   346 	    	{
       
   347 	    	NM_LOG((KNodeMessagesSubTag, _L8("RNI::SetFlags(%x) ANode=%08x, %x->%x"), aFlags, &RecipientId().Node(), oldFlags, newFlags));
       
   348 	    	}
       
   349 	    return newFlags;
       
   350 #else
       
   351 	    return iClientType.SetFlags(aFlags);
       
   352 #endif
       
   353 	    }
       
   354 
       
   355 	TUint32 ClearFlags(TUint32 aFlags)
       
   356 	    {
       
   357 #if defined(_DEBUG) && defined(NM_LOG_FLAG_SETTINGS)
       
   358 	    const TUint32 oldFlags = Flags();
       
   359 	    const TUint32 newFlags = iClientType.ClearFlags(aFlags);
       
   360 	    if (oldFlags != newFlags)
       
   361 	    	{
       
   362 	    	NM_LOG((KNodeMessagesSubTag, _L8("RNI::ClearFlags(%x) ANode=%08x, %x->%x"), aFlags, &RecipientId().Node(), oldFlags, newFlags));
       
   363 	    	}
       
   364 	    return newFlags;
       
   365 #else
       
   366 	    return iClientType.ClearFlags(aFlags);
       
   367 #endif
       
   368 	    }
       
   369 
       
   370 protected:
       
   371 	TClientType iClientType;
       
   372 	};
       
   373 
       
   374 class RRequestOriginator
       
   375 /*
       
   376 RRequestOriginator is a helper class that ackowledges the very common scenario
       
   377 where an activity running at a remote node sends a request and that request
       
   378 needs to be replied to. RRequestOriginator is associated with a node (holds
       
   379 a reference to RNodeInterface) as well as stores the TNodeId::TReminder of
       
   380 the address in order to identify the activity running at that node.
       
   381 */
       
   382     {
       
   383 public:
       
   384 	IMPORT_C TInt Open(RNodeInterface& aNode, const TRuntimeCtxId& aRequestOriginator);
       
   385 	IMPORT_C void Open(RRequestOriginator& aOriginalRequest);
       
   386 	IMPORT_C void Close();
       
   387 
       
   388 	IMPORT_C TBool operator==(const RRequestOriginator& aRHS) const;
       
   389 	IMPORT_C TBool operator==(const TRuntimeCtxId& aRHS) const;
       
   390 
       
   391 	IMPORT_C TBool IsOpen() const;
       
   392 
       
   393 	Messages::RNodeInterface& Node()
       
   394 		{
       
   395 		__ASSERT_DEBUG(IsOpen(), User::Panic(Messages::KMessagesPanic,Messages::EClientNotValidPanic));
       
   396 		return *iNode;
       
   397 		}
       
   398 	const Messages::RNodeInterface& Node() const
       
   399 		{
       
   400 		__ASSERT_DEBUG(IsOpen(), User::Panic(Messages::KMessagesPanic,Messages::EClientNotValidPanic));
       
   401 		return *iNode;
       
   402 		}
       
   403 
       
   404 	Messages::TNodeId::TRemainder& Remainder()
       
   405 		{
       
   406 		Node(); //Make sure 'this' is openned
       
   407 		return iRemainder;
       
   408 		}
       
   409 	const Messages::TNodeId::TRemainder& Remainder() const
       
   410 		{
       
   411 		Node(); //Make sure 'this' is openned
       
   412 		return iRemainder;
       
   413 		}
       
   414 
       
   415 
       
   416 	IMPORT_C void PostMessage(const TRuntimeCtxId& aPostFrom, const TSignalBase& aMessage) const;
       
   417 	IMPORT_C void ReplyTo(const TRuntimeCtxId& aReplyFrom, const TSignalBase& aMessage);
       
   418 
       
   419 private:
       
   420 	Messages::TNodeId::TRemainder iRemainder;
       
   421 	Messages::RNodeInterface* 	  iNode;
       
   422     };
       
   423 
       
   424 //
       
   425 // TClientIterBase
       
   426 class TClientIterBase
       
   427 	{
       
   428 public:
       
   429 	typedef RPointerArray<RNodeInterface> TClientArray;
       
   430 
       
   431 public:
       
   432 	inline RNodeInterface* operator++(TInt /*aInd*/) //-postfix
       
   433 	    {
       
   434 	    RNodeInterface* cli = Find(iIndex, +1, 1);
       
   435 	    iIndex++;
       
   436 	    return cli;
       
   437 	    }
       
   438 
       
   439 	inline RNodeInterface* operator++()              //-prefix
       
   440 	    {
       
   441 	    ++iIndex;
       
   442 	    return Find(iIndex, +1, 1);
       
   443 	    }
       
   444 
       
   445 	inline RNodeInterface* operator--(TInt /*aInd*/) //-postfix
       
   446 	    {
       
   447 	    RNodeInterface* cli = Find(iIndex, -1, 1);
       
   448 	    iIndex--;
       
   449 	    return cli;
       
   450 	    }
       
   451 
       
   452 	IMPORT_C RNodeInterface* operator[](TInt aInd);
       
   453 
       
   454 	inline RNodeInterface* operator*()
       
   455 		{
       
   456 		return Find(iIndex, +1, 0);
       
   457 		}
       
   458 
       
   459     void SetToLast()
       
   460         {
       
   461         iIndex = iClients.Count() - 1;
       
   462         }
       
   463 
       
   464 	void Reset()
       
   465 		{
       
   466 		iIndex = 0;
       
   467 		}
       
   468 
       
   469 protected:
       
   470 	virtual TBool TypeMatch(RNodeInterface& aClient) const = 0;
       
   471 	explicit TClientIterBase(const RPointerArray<RNodeInterface>& aClients)
       
   472     :	iClients(aClients),
       
   473     	iIndex(0)
       
   474     	{
       
   475 		}
       
   476 
       
   477     IMPORT_C RNodeInterface* Find(TInt& aInd, TInt aDir, TInt aCount);
       
   478     const RPointerArray<RNodeInterface>& iClients;
       
   479     TInt iIndex;
       
   480 	};
       
   481 
       
   482 //
       
   483 // TClientIter
       
   484 template<class TTYPEMATCHPOLICY = TDefaultClientMatchPolicy>
       
   485 class TClientIter : public TClientIterBase
       
   486 	{
       
   487 public:
       
   488 	explicit TClientIter(const RPointerArray<RNodeInterface>& aClients, const TClientType& aInclude, const TClientType& aExclude = TClientType::NullType())
       
   489 	:	TClientIterBase(aClients), iInclude(aInclude), iExclude(aExclude) {};
       
   490 
       
   491 private:
       
   492 	virtual TBool TypeMatch(RNodeInterface& aClient) const
       
   493 		{
       
   494 		return TTYPEMATCHPOLICY::Match(aClient.ClientType(), iInclude, iExclude);
       
   495 		}
       
   496 
       
   497 	TClientType iInclude;
       
   498 	TClientType iExclude;
       
   499 	};
       
   500 
       
   501 
       
   502 } //namespace Messages
       
   503 
       
   504 #endif
       
   505 //SYMBIAN_NM_INTERFACES_H
       
   506 
       
   507