///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2018 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_MQTT_Client_TestSteps.ttcn
//  Description:
//  Rev:                R1A
//  Prodnr:             LPA 108 661
//  Updated:            2017-09-01
//  Contact:            http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
module IFW_MQTT_Client_TestSteps
{
    import from IoT_FT_Framework_Definitions all;
    import from IFW_Common all;
    import from IFW_MQTT_Client_Definitions all;
    import from IFW_MQTT_Client_Functions all;
	import from MQTT_v3_1_1_Types all;

	function f_IFW_MqttClient_init(in integer p_clientIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];
	  if (v_client == null) { log("IFW: No mqtt client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_MQTT_Client_init());
      v_client.done;
      
	  return true;	  
	}
	
	function f_IFW_MqttClient_cleanUp(in integer p_clientIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No mqtt client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_MQTT_Client_cleanUp());
      v_client.done;
      
	  return true;	  
	}	
	
	function f_IFW_MqttClient_setRemote(in integer p_clientIdx, in charstring p_remoteAddrId) runs on IFW_MAIN_CT
	return boolean
	{
 		var NamedHostPort v_addr;
		if (f_lookupAddress(p_remoteAddrId, v_addr))
		{
			var MqttClientContext v_ctx;
			f_IFW_MqttClient_getContext(p_clientIdx, v_ctx);
			v_ctx.remoteHost := v_addr.hostName;
			v_ctx.remotePort := v_addr.portNumber;
			
			f_IFW_MqttClient_setContext(p_clientIdx, v_ctx);
		}
		return true;
	}	
	
	function f_IFW_MqttClient_getContext(in integer p_clientIdx, out MqttClientContext p_mqttClientContext) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];
	  if (v_client == null) { log("IFW: No mqtt client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_MQTT_Client_getContext());
      v_client.done(MqttClientContext:?) -> value p_mqttClientContext;
      
	  return true;
	}
	
	function f_IFW_MqttClient_setContext(in integer p_clientIdx, in MqttClientContext p_mqttClientContext) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No mqtt client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_MQTT_Client_setContext(p_mqttClientContext));
      v_client.done;
      
	  return true;
	}
	
    function f_IFW_MqttClient_setMessageToSend(in integer p_clientIdx, MQTT_v3_1_1_ReqResp p_msg) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No mqtt client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_MQTT_Client_setMessageToSend(p_msg));
      v_client.done;
      
	  return true;
	}
	
	function f_IFW_MqttClient_send(in integer p_clientIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No mqtt client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_MQTT_Client_send());
      v_client.done;
      
	  return true;
	}
	
	function f_IFW_MqttClient_receive(in integer p_clientIdx) runs on IFW_MAIN_CT
	return boolean
	{
	  var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No mqtt client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_MQTT_Client_receive());
      v_client.done;
      
	  return true;
	}
	
	function f_IFW_MqttClient_check(in integer p_clientIdx, template MQTT_v3_1_1_ReqResp p_msg) runs on IFW_MAIN_CT
	return boolean
	{
	  var boolean v_ret;
	  var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];	  
	  if (v_client == null) { log("IFW: No mqtt client found"); return false; }	  
	  f_isRunningGuard(v_client);
	  
	  v_client.start(f_MQTT_Client_check(p_msg));
      v_client.done(ReturnBoolean:?) -> value v_ret; 
      
	  return v_ret;
	}

}
