/**
 *  Copyright Notification
 *  No part of this document may be reproduced, in an electronic retrieval system or otherwise, except as authorized by written permission.
 *  The copyright and the foregoing restriction extend to reproduction in all media.
 *  © 2016, oneM2M Partners Type 1 (ARIB, ATIS, CCSA, ETSI, TIA, TSDSI, TTA, TTC).
 *  All rights reserved.
 *  
 *  @author     ETSI
 *  @version    $URL: https://forge.etsi.org/svn/oneM2M/trunk/ttcn/LibOneM2M/OneM2M_Functions.ttcn $
 *              $Id: OneM2M_Functions.ttcn 134 2016-10-11 09:33:13Z reinaortega $
 *  @desc       Module containing functions for oneM2M
 *
 */
module OneM2M_Functions {
	
	import from LibCommon_Time {modulepar all;}
	import from XSD all;
	import from OneM2M_Templates all;
	import from OneM2M_Types all;//{type XSD.ID};
	import from OneM2M_TypesAndValues all;
	import from OneM2M_TestSystem all;
	import from OneM2M_Pixits all;
//	import from OneM2M_AdditionalTypes all;
	
	
	group configFunctions {
    	/**
    		@desc Ports mapping and default behaviour activation for Config 1
    	*/
    	function f_cf01Up() runs on CseTester {
    			
			// Variables
    			
			// Map
			map(self:mcaPort, system:mcaPort);
			map(self:acPort, system:acPort);
			activate(a_default());
			activate(a_cse_cf01());
    			
			// Connect
    						
			//Initialze the IUT
    						
		} // end f_cf01Up
		
		function f_cf02Up() runs on CseTester {
    			
			// Variables
    			
			// Map
			map(self:mcaPort, system:mcaPort);
			map(self:mccPort, system:mccPort);
			map(self:acPort, system:acPort);
			activate(a_default());
			activate(a_cse_cf02());
    			
			// Connect
    						
			//Initialze the IUT
    						
		} // end f_cf02Up
		
		/**
		 * @desc Ports unmapping
		 * @verdict 
		 */
		function f_cf01Down() runs on CseTester {
    	
			unmap(self:mcaPort, system:mcaPort);
			unmap(self:acPort, system:acPort);
			//stop;
		}	
    		
		function f_cf02Down() runs on CseTester {
    	
			unmap(self:mcaPort, system:mcaPort);
			unmap(self:mccPort, system:mccPort);
			unmap(self:acPort, system:acPort);
			//stop;
		}		
    	
	}//end group configFunctions
	
	group cseFunctions {
	
    	group preambleFunctions {
    
    		/**
    		 * @desc Creation of auxiliar resources ACP and AE for correct execution of the test case
    		 * @param p_allowedOperations Allowed operations for the auxiliar AE resource
    		 * @return Internal AE resource index
    		 * @verdict 
    		 */
    		function f_cse_preamble_registerAe(in template (value) AccessControlOperations p_allowedOperations := int63, in template (omit) PoaList p_poaList := omit) runs on CseTester return integer {//c_CRUDNDi
    		
    			var RequestPrimitive v_request;
    			var MsgIn v_response;
    			var integer v_aeAuxIndex := -1;
    			var integer v_acpAuxIndex := -1;
    		
    			if(PX_ACP_SUPPORT){
    				v_acpAuxIndex := f_cse_createAccessControlPolicyAux(p_allowedOperations := p_allowedOperations);
    				vc_acpAuxIndex := v_acpAuxIndex;
    			}
    			
    			if(v_acpAuxIndex != -1) {
    				vc_resourcesIndexToBeDeleted := {v_acpAuxIndex};
    				v_request := valueof(m_createAeAux({f_getResourceId(vc_resourcesList[v_acpAuxIndex].resource)}, p_poaList));
    				//mcaPort.send(m_request(m_createAeAux(p_name, {PX_URI_CSE & PX_CSE_NAME & "/" & PX_ACPAUX_NAME})));
    			} else {
					v_request := valueof(m_createAeAux(-, p_poaList));
    			}
    			
				v_request.to_ := f_addPrefix(f_getResourceAddress());
				mcaPort.send(m_request(v_request));
    			
    			tc_ac.start;
    			alt {
    				[] mcaPort.receive(mw_response(mw_responsePrimitiveOK)) -> value v_response {
    					tc_ac.stop;
    					log("Preamble: Application registered successfuly");
    					if(ischosen(v_response.primitive.responsePrimitive.primitiveContent.any_1[0].AE_optional)) {
    						vc_aeAux := v_response.primitive.responsePrimitive.primitiveContent.any_1[0].AE_optional;
    						
    						v_aeAuxIndex := f_setResource(v_response.primitive.responsePrimitive.primitiveContent);
    						vc_resourcesIndexToBeDeleted := vc_resourcesIndexToBeDeleted & {v_aeAuxIndex};
    						
    						if(ispresent(vc_aeAux.aE_ID)){
    							f_sendAcPrimitive("AE-ID_changed", oct2char(unichar2oct(vc_aeAux.aE_ID)));
    						} else {
    							f_sendAcPrimitive("AE-ID_changed", "0");
    						}	
    					};
    				}
    				[] mcaPort.receive(mw_response(mw_responsePrimitiveKO)) {
    					tc_ac.stop;
    					setverdict(inconc, "Preamble: Error while registering application");
    					stop;
    				}
    				[] mcaPort.receive {
    					tc_ac.stop;
    					setverdict(inconc, "Preamble: Unexpected message received");
    					stop;
    				}
    				[] tc_ac.timeout {
    					setverdict(inconc, "Preamble: No answer while registering resource");
    					stop;
    				}
    			}	
    			
    			return v_aeAuxIndex;
    		
    		}
    		
    		/**
    		 * @desc Creation of auxiliar resources ACP and AE for correct execution of the test case
    		 * @param p_allowedOperations Allowed operations for the auxiliar AE resource
    		 * @return Internal AE resource index
    		 * @verdict 
    		 */
    		function f_cse_preamble_registerAeWithId(XSD.ID p_appId, in template (value) AccessControlOperations p_allowedOperations := int63) runs on CseTester return integer {//c_CRUDNDi
    		
    			var RequestPrimitive v_request;
    			var MsgIn v_response;
    			var integer v_aeAuxIndex := -1;
    			var integer v_acpAuxIndex := -1;
    		
    			if(PX_ACP_SUPPORT){
    				v_acpAuxIndex := f_cse_createAccessControlPolicyAux(p_allowedOperations := p_allowedOperations);
    				vc_acpAuxIndex := v_acpAuxIndex;
    			}
    			
    			if(v_acpAuxIndex != -1) {
    				vc_resourcesIndexToBeDeleted := {v_acpAuxIndex};
    				v_request := valueof(m_createAe(p_appId, p_accessControlPolicyIDs := {f_getResourceId(vc_resourcesList[v_acpAuxIndex].resource)}));
    				
    				//TODO Test, to be removed
    				v_request.to_ := f_addPrefix(f_getResourceAddress());
    				
    				mcaPort.send(m_request(v_request));
    				//mcaPort.send(m_request(m_createAeAux(p_name, {PX_URI_CSE & PX_CSE_NAME & "/" & PX_ACPAUX_NAME})));
    			} else {
    				mcaPort.send(m_request(m_createAe(p_appId)));
    			}
    			tc_ac.start;
    			alt {
    				[] mcaPort.receive(mw_response(mw_responsePrimitiveOK)) -> value v_response {
    					tc_ac.stop;
    					log("Preamble: Application registered successfuly");
    					if(ischosen(v_response.primitive.responsePrimitive.primitiveContent.any_1[0].AE_optional)) {
    						vc_aeAux := v_response.primitive.responsePrimitive.primitiveContent.any_1[0].AE_optional;
    						
    						v_aeAuxIndex := f_setResource(v_response.primitive.responsePrimitive.primitiveContent);
    						vc_resourcesIndexToBeDeleted := vc_resourcesIndexToBeDeleted & {v_aeAuxIndex};
    						
    						if(ispresent(vc_aeAux.aE_ID)){
    							f_sendAcPrimitive("AE-ID_changed", oct2char(unichar2oct(vc_aeAux.aE_ID)));
    						} else {
    							f_sendAcPrimitive("AE-ID_changed", "0");
    						}	
    					}
    				}
    				[] mcaPort.receive(mw_response(mw_responsePrimitiveKO)) {
    					tc_ac.stop;
    					setverdict(inconc, "Preamble: Error while registering application");
    					stop;
    				}
    				[] mcaPort.receive {
    					tc_ac.stop;
    					setverdict(inconc, "Preamble: Unexpected message received");
    					stop;
    				}
    				[] tc_ac.timeout {
    					setverdict(inconc, "Preamble: No answer while registering resource");
    					stop;
    				}
    			}	
    			
    			return v_aeAuxIndex;
    		
    		}
    		
    		//Added by @Naum
    		function f_cse_preamble_createServiceSubscribedAppRule(in template ListOfM2MID p_allowedAEs, in template (value) AccessControlOperations p_allowedOperations := int63) runs on CseTester return integer {//c_CRUDNDi
    		
    			var MsgIn v_response;
    			var integer v_serviceSubscribedAppRuleIndex := -1;
    			var RequestPrimitive v_request;
    
    			v_serviceSubscribedAppRuleIndex := f_cse_createResource(int19, m_createServiceSubscribedAppRule({"None"}, {PX_APP_ID}, valueof(p_allowedAEs)));
    			
    			return v_serviceSubscribedAppRuleIndex;
    		
    		}
    	
    	}//end group preambleFunctions
    	
    	group postambleFunctions {
    
    		/**
    		 * @desc Deletion of all resources created during the test case execution. IUT gets clean and ready for next execution
    		 * @verdict 
    		 */
    		function f_cse_postamble_deleteResources() runs on CseTester {
    			var integer i;
    			var XSD.ID v_resourceAddress;
    			var MsgIn v_response;
    			var RequestPrimitive v_request;
    			
    			if (PX_RUN_POSTAMBLE) {
    				
    				for(i := 0; i < lengthof(vc_resourcesIndexToBeDeleted); i := i + 1) {
    					
    					v_resourceAddress := f_getResourceAddress(lengthof(vc_resourcesIndexToBeDeleted)-1 - i);
    					
    					v_request := valueof(m_deleteRequest(v_resourceAddress));
    					
    					if(PX_FROM_IS_AE_ID){
    						if(not(ischosen(vc_resourcesList[lengthof(vc_resourcesIndexToBeDeleted)-1 - i].resource.any_1[0].AccessControlPolicy_optional))) {
								v_request.from_ := vc_aeAux.aE_ID;
							}
    					}
    					mcaPort.send(m_request(v_request));
    					
    					tc_ac.start;
    					alt {
    						[] mcaPort.receive(mw_response(mw_responsePrimitiveOK)) {
    							tc_ac.stop;
    							log("Postamble: AE Resource deleted");
    						}
    						[] mcaPort.receive(mw_response(mw_responsePrimitiveKO)) {
    							tc_ac.stop;
    							log("Postamble: Error while deleting resource");
    						}
    						[] tc_ac.timeout {
    							log("Postamble: No answer while deleting resource");
    						}	
    					}	
    				}
    			}
    						
    			f_cse_postamble_default();
    		}
    		
			/**
			 * @desc Default postamble
			 * @verdict 
			 */
			function f_cse_postamble_default() runs on CseTester {
			}
    		
    		
    	}//end group postambleFunctions
    	
    	group helpingFunctions {
    
    		/**
    		 * @desc Creation of a resource
    		 * @param p_resourceType Resource type of the resource to be created
    		 * @param p_requestPrimitive Template request primitive
    		 * @param p_parentIndex Internal resource index which indicates the parent of the resource to be created
    		 * @return Internal resource index of the created resource
    		 * @verdict 
    		 */
    		function f_cse_createResource(in ResourceType p_resourceType, template RequestPrimitive p_requestPrimitive, integer p_parentIndex := -1) runs on CseTester return integer {
    		
    			var MsgIn v_response;
    			var RequestPrimitive v_request;
    			var XSD.ID v_resourceId;
    			var integer v_resourceIndex := -1;
    			
    			v_request := f_getCreateRequestPrimitive(p_resourceType, p_requestPrimitive, p_parentIndex);
    		
    			mcaPort.send(m_request(v_request));
    			tc_ac.start;
    			alt {
    				[] mcaPort.receive(mw_response(mw_responsePrimitiveOK)) -> value v_response {
    					tc_ac.stop;
    					setverdict(pass, "f_createResource: Resource type " & int2str(enum2int(p_resourceType)) & " created successfuly");
    					v_resourceIndex := f_setResource(v_response.primitive.responsePrimitive.primitiveContent, p_parentIndex);
    				}
    				[] mcaPort.receive(mw_response(mw_responsePrimitiveKO)) {
    					tc_ac.stop;
    					setverdict(inconc, "f_createResource: Error while creating resource type " & int2str(enum2int(p_resourceType)));
    				}
    				[] mcaPort.receive {
    					tc_ac.stop;
    					setverdict(inconc, "f_createResource: Unexpected message received");
    				}
    				[] tc_ac.timeout {
    					setverdict(inconc, "f_createResource: No answer while creating resource type " & int2str(enum2int(p_resourceType)));
    				}
    			}	
    			
    			return v_resourceIndex;
    	
    		}
    	
    		/**
    		 * @desc Creation of the auxiliar ACP resource
    		 * @param p_acpName ACP name
    		 * @param p_allowedOperations Allowed operations
    		 * @return Internal resource index of the created auxiliar ACP resource
    		 * @verdict 
    		 */
    		function f_cse_createAccessControlPolicyAux(in template (value) XSD.String p_acpName := c_acpAuxName, in template (value) AccessControlOperations p_allowedOperations := int63) runs on CseTester return integer{
    			var RequestPrimitive v_request;
    			var MsgIn v_response;
    			var integer v_acpAuxIndex := -1;
    			
    			v_request := valueof(m_createAcpAux(p_acpName := p_acpName, p_allowedOperations := p_allowedOperations));
    			
    			v_request.to_ := f_addPrefix(f_getResourceAddress());
    			
    			mcaPort.send(m_request(v_request));
    			tc_ac.start;
    			alt {
    				[] mcaPort.receive(mw_response(mw_responsePrimitiveOK)) -> value v_response {
    					tc_ac.stop;
    					setverdict(pass, "f_createAccessControlPolicy: Resource type " & int2str(1) & " created successfuly");
    					v_acpAuxIndex := f_setResource(v_response.primitive.responsePrimitive.primitiveContent);
    					vc_acpAux := v_response.primitive.responsePrimitive.primitiveContent.any_1[0].AccessControlPolicy_optional;//TODO To be removed
    				}
    				[] mcaPort.receive(mw_response(mw_responsePrimitiveKO)) {
    					tc_ac.stop;
    					setverdict(inconc, "f_createAccessControlPolicy: Error while creating resource type " & int2str(1));
    				}
    				[] mcaPort.receive {
    					tc_ac.stop;
    					setverdict(inconc, "f_createAccessControlPolicy: Unexpected message received");
    				}
    				[] tc_ac.timeout {
    					setverdict(inconc, "f_createAccessControlPolicy: No answer while creating resource type " & int2str(1));
    				}
    			}	
    		
    			return v_acpAuxIndex;
    
    		}
    			
    			
    		/**
    		 * @desc Creation of the auxiliar Container resource
    		 * @param p_parentIndex Internal resource index which indicates the parent of the Container resource to be created
    		 * @return Internal resource index of the created Container resource
    		 * @verdict 
    		 */
    		function f_cse_createContainerResourceAux (integer p_parentIndex := -1) runs on CseTester return integer {
    		
    			var MsgIn v_response;
    			var RequestPrimitive v_request;
    			var integer v_acpAuxIndex := -1;
    			var integer v_containerResourceIndex := -1;
    			
    			v_acpAuxIndex := f_cse_createAccessControlPolicyAux(p_acpName := c_acpAuxName);//"MyAcp_2"
    			
    			v_request := valueof(m_createContainerBase);
    			v_request.primitiveContent.any_1[0].Container_optional.accessControlPolicyIDs := {f_getResourceId(vc_resourcesList[v_acpAuxIndex].resource)};
    			v_request.primitiveContent.any_1[0].Container_optional.resourceName := "MyContainerAux";
    			
    			v_containerResourceIndex := f_cse_createResource(int3, v_request, p_parentIndex);
    			
    			return v_containerResourceIndex;		
    	
    		}
    		
    		/**
    		 * @desc Update of the auxiliar ACP resource
    		 * @param p_allowedOperations New allowed operations
    		 * @verdict 
    		 */
    		function f_cse_updateAcpAuxResource (in template (value) AccessControlOperations p_allowedOperations) runs on CseTester {
    			var RequestPrimitive v_request;
    			
    			v_request := valueof(m_updateAcpBase);
    			
    			v_request.to_ := f_addPrefix(f_getResourceAddress(vc_acpAuxIndex));
    			v_request.primitiveContent.any_1[0].AccessControlPolicy_optional.privileges.accessControlRule_list := {
    				{
    					accessControlOriginators := PX_ACOR, //{"admin:admin"}
    					accessControlOperations := valueof(p_allowedOperations),
    					accessControlContexts_list := omit,
						accessControlAuthenticationFlag := omit
    				}
    			};
    						
    			mcaPort.send(m_request(v_request));
    			tc_ac.start;
    			alt {
    				[] mcaPort.receive(mw_response(mw_responsePrimitiveOK))  {
    					tc_ac.stop;
    					setverdict(pass, "f_updateAcpAuxResource: " & v_request.to_ & " resource updated successfuly");
    				}
    				[] mcaPort.receive(mw_response(mw_responsePrimitiveKO)) {
    					tc_ac.stop;
    					setverdict(fail, "f_updateAcpAuxResource: Error while updating " & v_request.to_ & " resource");
    				}
    				[] tc_ac.timeout {
    					setverdict(inconc, "f_updateAcpAuxResource: No answer while updating " & v_request.to_ & " resource" );
    				}
    			}		
    		}   
    
    	}//end group helpingFunctions
    	
		group altstepFunctions {
    		 
			/**
			  * @desc	Cse altstep for config 01
			  */
			 altstep a_cse_cf01() runs on CseTester {
		
				[] mcaPort.receive {
					log("a_default: WARNING: Unexpected message received");
					repeat;
				}
			 }			
    		 
			/**
			  * @desc	Cse altstep for config 02
			  */
			 altstep a_cse_cf02() runs on CseTester {
    		
				[] mcaPort.receive {
					log("a_default: WARNING: Unexpected message received");
					repeat;
				}
				[] mccPort.receive {
					log("a_default: WARNING: Unexpected message received");
					repeat;
				}
			 }	

		}//end group altstepFunctions	
    	
	}//end cseFunctions
	
	group aeFunctions {
		
		group altstepFunctions {
    
			/**
			  * @desc	Ae altstep
			  */
			 altstep a_ae_default() runs on AeTester {
    		
				[] mcaPort.receive {
					log("a_default: WARNING: Unexpected message received");
					repeat;
				}
			 }		
    		 
		}//end group altstepFunctions
		
	}//end of aeFunctions


	group getSetFunctions {
    
		/**
		 * @desc Creation of a CREATE request primitive from a template request primitive
		 * @param p_resourceType Type of resource to be created
		 * @param p_request Template request primitive 
		 * @param p_parentIndex Internal resource index which indicates the parent of the resource to be created
		 * @return Created CREATE request primitive
		 * @verdict 
		 */
		function f_getCreateRequestPrimitive(in ResourceType p_resourceType, template RequestPrimitive p_request, integer p_parentIndex) runs on CseTester return RequestPrimitive {
    		var integer p_locresourceIndex := p_parentIndex;
    		
			p_request.from_ := f_getOriginator(p_parentIndex);
                
			p_request.to_ := f_addPrefix(f_getResourceAddress(p_parentIndex));
                
			if (p_resourceType == int1) {//AccessControlPolicy
    			
			} 
			if (p_resourceType == int9) {//group
				p_request.primitiveContent.any_1[0].Group_optional.memberIDs := {f_getResourceAddress(p_parentIndex)};
			}
			//@Martin
			if(p_resourceType == int3){//container
			  	//when a container is created by hosting cse for storing location information, the container is seen as a location container
				if(PX_IS_LOC_CONTAINER){
			    	p_request.primitiveContent.any_1[0].Container_optional.locationID := f_getResourceId(vc_resourcesList[p_locresourceIndex].resource);//resourceID of the locationPolicy
				}		  
			}
			
    		
			if (p_resourceType == int15) {//pollingChannel
				p_request.from_ := vc_aeAux.aE_ID;
			} 
    			
			if (p_resourceType == int23) {//subscription
				p_request.primitiveContent.any_1[0].Subscription_optional.notificationURI := {f_getResourceAddress(p_parentIndex)};
    					
				/*if(PX_FROM_IS_AE_ID) {
					if(PX_UNSTRUCTURED){
						p_request.primitiveContent.any_1[0].Subscription_optional.notificationURI := {vc_aeAux.aE_ID};
					} else {
						p_request.primitiveContent.any_1[0].Subscription_optional.notificationURI := {PX_CSE_ID & "/" & vc_aeAux.aE_ID};
					}
				} else {
					p_request.primitiveContent.any_1[0].Subscription_optional.notificationURI := {"/" & PX_CSE_NAME & "/" & PX_AEAUX_NAME};//c_aeAuxName
				}*/
			}
    		
			return valueof(p_request);
		}
    	
		/**
		 * @desc Creation of an UPDATE request primitive from a template request primitive
		 * @param p_resourceType Type of resource to be created
		 * @param p_resourceIndex Internal resource index which indicates the resource to be updated
		 * @param p_request Template request primitive
		 * @return Created UPDATE request primitive
		 * @verdict 
		 */
		function f_getUpdateRequestPrimitive(in ResourceType p_resourceType, integer p_resourceIndex, template RequestPrimitive p_request) runs on CseTester return RequestPrimitive {
    		
			p_request.from_ := f_getOriginator(p_resourceIndex);
                
			p_request.to_ := f_addPrefix(f_getResourceAddress(p_resourceIndex));
    			
			if (p_resourceType == int3) {//Container
    			
			//TODO
			} 
    		
			if (p_resourceType == int9) {//group
				//TODO	
    		
			}
    		
			if (p_resourceType == int18) {//schedule
				//TODO			
    	
			} 
    
			if (p_resourceType == int15) {//pollingChannel
				//TODO		
			}
    		
			if (p_resourceType == int23) {//subscription
				//TODO		
			} 
    		
			return 	valueof(p_request);
		}
    
		/**
		 * @desc Extraction from a primitiveContent field the resourceID attribute
		 * @param p_contentResource primitiveContent field
		 * @return resourceID attribute
		 * @verdict 
		 */
		function f_getResourceId(PrimitiveContent p_contentResource) return XSD.ID {
    				
			if(ischosen(p_contentResource.any_1[0].AccessControlPolicy_optional)) {
				return p_contentResource.any_1[0].AccessControlPolicy_optional.resourceID;
			}
			if(ischosen(p_contentResource.any_1[0].Container_optional)) {
				return p_contentResource.any_1[0].Container_optional.resourceID;
			}
			if(ischosen(p_contentResource.any_1[0].Schedule_optional)) {
				return p_contentResource.any_1[0].Schedule_optional.resourceID;
			}
			if(ischosen(p_contentResource.any_1[0].PollingChannel_optional)) {
				return p_contentResource.any_1[0].PollingChannel_optional.resourceID;
			}
			if(ischosen(p_contentResource.any_1[0].Subscription_optional)) {
				return p_contentResource.any_1[0].Subscription_optional.resourceID;
			}
			if(ischosen(p_contentResource.any_1[0].Group_optional)) {
				return p_contentResource.any_1[0].Group_optional.resourceID;
			}
			if(ischosen(p_contentResource.any_1[0].AE_optional)) {
				return p_contentResource.any_1[0].AE_optional.resourceID;
			}
			return "1";
      
		}
    		
		/**
		 * @desc Extraction from a primitiveContent field the resourceName attribute
		 * @param p_contentResource primitiveContent field
		 * @return resourceName attribute
		 * @verdict 
		 */
		function f_getResourceName(PrimitiveContent p_contentResource) return XSD.ID {
    				
			if(ischosen(p_contentResource.any_1[0].AccessControlPolicy_optional)) {
				return p_contentResource.any_1[0].AccessControlPolicy_optional.resourceName;
			}
			if(ischosen(p_contentResource.any_1[0].Container_optional)) {
				return p_contentResource.any_1[0].Container_optional.resourceName;
			}
			if(ischosen(p_contentResource.any_1[0].Schedule_optional)) {
				return p_contentResource.any_1[0].Schedule_optional.resourceName;
			}
			if(ischosen(p_contentResource.any_1[0].PollingChannel_optional)) {
				return p_contentResource.any_1[0].PollingChannel_optional.resourceName;
			}
			if(ischosen(p_contentResource.any_1[0].Subscription_optional)) {
				return p_contentResource.any_1[0].Subscription_optional.resourceName;
			}
			if(ischosen(p_contentResource.any_1[0].Group_optional)) {
				return p_contentResource.any_1[0].Group_optional.resourceName;
			}
			if(ischosen(p_contentResource.any_1[0].AE_optional)) {
				return p_contentResource.any_1[0].AE_optional.resourceName;
			}
    			
			return "1";
      
		}
    		
		/**
		 * @desc Resolution of the originator field (from) for a given resource
		 * @param p_targetResourceIndex Internal resource index of the given resource
		 * @return Originator for a given resource
		 * @verdict 
		 */
		function f_getOriginator(integer  p_targetResourceIndex := -1) runs on CseTester return XSD.AnyURI {
    			
			if(p_targetResourceIndex == -1) {
				return PX_SUPER_USER;
			}	
    			
			if(PX_FROM_IS_AE_ID) {
				if(ischosen(vc_resourcesList[p_targetResourceIndex].resource.any_1[0].AE_optional)) {
					return vc_resourcesList[p_targetResourceIndex].resource.any_1[0].AE_optional.aE_ID;
				} else {
					return f_getOriginator(vc_resourcesList[p_targetResourceIndex].parentIndex);
				}
			} else {
				return PX_SUPER_USER;
			}
		}
    		
		/**
		 * @desc Return of a index of a specific attribute from an attributeList by attributeName
		 * @param p_attributeList Target attributeList
		 * @param p_attributeName attributeName to be searched
		 * @return Index of the attribute in the attributeList
		 * @verdict 
		 */
		function f_getAttribute(in AttributeList p_attributeList, in XSD.NCName p_attributeName) return integer {
		var integer i;
		var Attribute v_attribute := {-, -};
    		
		for (i:=0; i < lengthof(p_attributeList); i := i + 1){
			if(p_attributeList[i] == p_attributeName){
				return i;
			}	
		}
    			
		return -1;
    		
		}
    		
		/**
		 * @desc Resolution of the resource address field (to) for a given resource depending on addressing and hierarchical format 
		 * @param p_targetResourceIndex Internal resource index of the given resource
		 * @return Resource address for the given resource
		 * @verdict 
		 */
		function f_getResourceAddress(integer  p_targetResourceIndex := -1) runs on CseTester return XSD.ID {
			var XSD.ID v_resourceAddress;
    		
			if(PX_ADDRESSING_FORMAT == e_cseRelative) {
    				
				if(PX_UNSTRUCTURED) {
					if(p_targetResourceIndex == -1) {
						return "";
					} else {
						return f_getResourceId(vc_resourcesList[p_targetResourceIndex].resource);
					}
				} else {
					if(p_targetResourceIndex == -1) {
						return PX_CSE_NAME;
					} else {
						v_resourceAddress := f_getResourceAddress(vc_resourcesList[p_targetResourceIndex].parentIndex) & "/" & f_getResourceName(vc_resourcesList[p_targetResourceIndex].resource);
						return v_resourceAddress;
					}	
				}
    				
			} else if (PX_ADDRESSING_FORMAT == e_spRelative) {
				if(PX_UNSTRUCTURED) {
					if(p_targetResourceIndex == -1) {
						return "/" & PX_CSE_ID;
					} else {
						v_resourceAddress := f_getResourceAddress() & "/" & f_getResourceId(vc_resourcesList[p_targetResourceIndex].resource);
						return v_resourceAddress;
					}
				} else {
					if(p_targetResourceIndex == -1) {
						return "/" & PX_CSE_ID & "/" & PX_CSE_NAME;
					} else {
						v_resourceAddress := f_getResourceAddress(vc_resourcesList[p_targetResourceIndex].parentIndex) & "/" & f_getResourceName(vc_resourcesList[p_targetResourceIndex].resource);
						return v_resourceAddress;
					}
				}
			} else if (PX_ADDRESSING_FORMAT ==  e_absolute) {
				if(PX_UNSTRUCTURED) {
					if(p_targetResourceIndex == -1) {
						return "";
					} else {
						return "";
					}
				} else {
					if(p_targetResourceIndex == -1) {
						return "";
					} else {
						return "";
					}	
				}				
			} else {
				return "";
			}
    			
		}
		/**
		 * @desc Saving of a resource and its parent index in the internal resource list
		 * @param p_resource Resource to be saved
		 * @param p_parentIndex Parent index of resource to be saved
		 * @return Internal resource index of the saved resource
		 * @verdict 
		 */
		function f_setResource(PrimitiveContent p_resource, integer  p_parentIndex := -1) runs on Tester return integer {
    			
			if(isbound(vc_resourcesList)) {
				vc_resourcesList[lengthof(vc_resourcesList)] := {p_parentIndex, p_resource};
			} else {
				vc_resourcesList[0] := {p_parentIndex, p_resource};
			}
			return lengthof(vc_resourcesList)-1;
    					
		}
    				
	}//end group getSetFunctions
	
	group commonFunctions {
		
		/**
		 * @desc Sending of an Adapter Control primitive
		 * @param event Action to be performed by TA
		 * @param data Corresponding information for the correct execution of the given action
		 * @verdict 
		 */
		function f_sendAcPrimitive(in charstring event, in charstring data) runs on Tester {

			var charstring v_data := "" & data; // clear encoding rules (ttwb issue ?)
			acPort.send(AcRequestPrimitive:{event, {charstring := v_data}});
			
		}
		
		group altstepFunctions {
    
			/**
			  * @desc	Default altstep
			  */
			 altstep a_default() runs on Tester {
    		
				[] tc_wait.timeout {
					 setverdict(inconc,"a_default: ERROR: Timeout while awaiting reaction of the IUT prior to Upper Tester action");
				}
				[] tc_ac.timeout {
					setverdict(inconc,"a_default: ERROR: Timeout while awaiting the reception of a message");
				}
			 }	    		 

		}//end group altstepFunctions
		
	}//end of commonFunctions

		

	

		

		

	

	
}  // end of module