///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2019 Ericsson Telecom AB
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v2.0
// which accompanies this distribution, and is available at
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
///////////////////////////////////////////////////////////////////////////////
//  File:               IFW_CoAP_Peer_TestSteps.ttcn
//  Description:
//  Rev:                <RnXnn>
//  Prodnr:             CNL 113 910
//  Updated:            2020-02-06
//  Contact:            http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
module IFW_CoAP_Peer_TestSteps 
{
    import from IoT_FT_Framework_Definitions all;
    import from IFW_Common all;
    import from IFW_CoAP_Peer_Definitions all;
    import from IFW_CoAP_Peer_Functions all;
    import from CoAP_Types all;


	function f_IFW_CoapPeer_init(in integer p_peerIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];	  
	  if (v_peer == null) { log("CFW: No coap peer found"); return false; }	  
	  f_isRunningGuard(v_peer);
	  
	  v_peer.start(f_CoAP_Peer_init());
      v_peer.done;
      
	  return true;	  
	}

    function f_IFW_CoapPeer_listen(in integer p_peerIdx) runs on IFW_MAIN_CT
    return boolean
    {
      var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];     
      if (v_peer == null) { log("CFW: No coap peer found"); return false; }   
      f_isRunningGuard(v_peer);
      
      v_peer.start(f_CoAP_Peer_listen());
      v_peer.done;
      
      return true;    
    }

    function f_IFW_CoapPeer_connect(in integer p_peerIdx) runs on IFW_MAIN_CT
    return boolean
    {
      var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];     
      if (v_peer == null) { log("CFW: No coap peer found"); return false; }   
      f_isRunningGuard(v_peer);
      
      v_peer.start(f_CoAP_Peer_connect());
      v_peer.done;
      
      return true;    
    }
	
	function f_IFW_CoapPeer_setRemote(in integer p_peerIdx, in charstring p_remoteAddrId) runs on IFW_MAIN_CT
	return boolean
	{
 		var NamedHostPort v_addr;
		if (f_lookupAddress(p_remoteAddrId, v_addr))
		{
			var CoapContext v_ctx;
			f_IFW_CoapPeer_getContext(p_peerIdx, v_ctx);
			v_ctx.remoteHost := v_addr.hostName;
			v_ctx.remotePort := v_addr.portNumber;
			
			f_IFW_CoapPeer_setContext(p_peerIdx, v_ctx);
		}
		return true;
	}	
	
	function f_IFW_CoapPeer_getContext(in integer p_peerIdx, out CoapContext p_coapContext) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];	  
	  if (v_peer == null) { log("CFW: No user found"); return false; }	  
	  f_isRunningGuard(v_peer);
	  
	  v_peer.start(f_CoAP_Peer_getContext());
      v_peer.done(CoapContext:?) -> value p_coapContext;
      
	  return true;
	}
	
	function f_IFW_CoapPeer_setContext(in integer p_peerIdx, in CoapContext p_coapContext) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];
	  if (v_peer == null) { log("CFW: No user found"); return false; }	  
	  f_isRunningGuard(v_peer);
	  
	  v_peer.start(f_CoAP_Peer_setContext(p_coapContext));
      v_peer.done;
      
	  return true;
	}
	
    function f_IFW_CoapPeer_setMessageToSend(
      in integer p_peerIdx, 
      CoAP_ReqResp p_msg, 
      MID_Generation p_genMid := GENERATE_NEW_MID,
      Token_Generation p_genToken := USE_GIVEN_TOKEN
    ) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];	  
	  if (v_peer == null) { log("CFW: No user found"); return false; }	  
	  f_isRunningGuard(v_peer);
	  
	  if (p_genMid == GENERATE_NEW_MID)
	  {
	    p_msg.header.message_id := mid;
	    mid := mid + 1;
	    p_genMid := USE_GIVEN_MID;
	  }
	  
	  v_peer.start(f_CoAP_Peer_setMessageToSend(p_msg, p_genMid, p_genToken));
          v_peer.done;
      
	  return true;
	}
	
	function f_IFW_CoapPeer_send(in integer p_peerIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];	  
	  if (v_peer == null) { log("CFW: No user found"); return false; }	  
	  f_isRunningGuard(v_peer);
	  
	  v_peer.start(f_CoAP_Peer_send());
      v_peer.done;
      
	  return true;
	}
	
	function f_IFW_CoapPeer_receive(in integer p_peerIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];	  
	  if (v_peer == null) { log("CFW: No user found"); return false; }	  
	  f_isRunningGuard(v_peer);
	  
	  v_peer.start(f_CoAP_Peer_receive());
      v_peer.done;
      
	  return true;
	}
	
	function f_IFW_CoapPeer_check(in integer p_peerIdx, template CoAP_ReqResp p_msg, MID_Check p_checkMid := CHECK_MID) runs on IFW_MAIN_CT
	return boolean
	{
	  var boolean v_ret;
	  var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];	  
	  if (v_peer == null) { log("CFW: No user found"); return false; }	  
	  f_isRunningGuard(v_peer);
	  
	  v_peer.start(f_CoAP_Peer_check(p_msg, p_checkMid));
      v_peer.done(ReturnBoolean:?) -> value v_ret; 
      
	  return v_ret;
	}
	
	function f_IFW_CoapPeer_saveLocationPath(in integer p_peerIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];	  
	  if (v_peer == null) { log("CFW: No user found"); return false; }	  
	  f_isRunningGuard(v_peer);
	  
	  v_peer.start(f_CoAP_Peer_saveLocationPath());
      v_peer.done; 
      
	  return true;
	}
	
	function f_IFW_CoapPeer_addUriPath(in integer p_peerIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];	  
	  if (v_peer == null) { log("CFW: No user found"); return false; }	  
	  f_isRunningGuard(v_peer);
	  
	  v_peer.start(f_CoAP_Peer_addUriPath());
      v_peer.done; 
      
	  return true;
	}

}
