///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2020 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_Server_TestSteps.ttcn
//  Description:
//  Rev:                <RnXnn>
//  Prodnr:             CNL 113 910
//  Updated:            2020-03-06
//  Contact:            http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
module IFW_MQTT_Server_TestSteps 
{

 import from IoT_FT_Framework_Definitions all;
 import from IFW_Common all;
 import from IFW_MQTT_Server_Definitions all;
 import from IFW_MQTT_Server_Functions all;
 import from MQTT_v3_1_1_Types all;
	
  function f_IFW_MqttServer_init(in integer p_serverIdx) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_MQTT_Server_CT v_server := mqttServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No MQTT server found"); return false; }
    f_isRunningGuard(v_server);

    v_server.start(f_MQTT_Server_init());
    v_server.done;

    return true;	  
  }
	
  function f_IFW_MqttServer_cleanUp(in integer p_serverIdx) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_MQTT_Server_CT v_server := mqttServers[p_serverIdx];
    if (v_server == null) { log("IFW: No MQTT server found"); return false; }
    f_isRunningGuard(v_server);

    v_server.start(f_MQTT_Server_cleanUp());
    v_server.done;

    return true;	  
  }
	
  function f_IFW_MqttServer_getContext(in integer p_serverIdx, out MqttServerContext p_mqttServerContext) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_MQTT_Server_CT v_server := mqttServers[p_serverIdx];
    if (v_server == null) { log("IFW: No MQTT server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_MQTT_Server_getContext());
    v_server.done(MqttServerContext:?) -> value p_mqttServerContext;

    return true;
  }
	
  function f_IFW_MqttServer_setContext(in integer p_serverIdx, in MqttServerContext p_mqttServerContext) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_MQTT_Server_CT v_server := mqttServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No MQTT server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_MQTT_Server_setContext(p_mqttServerContext));
    v_server.done;

    return true;
  }	
	
  function f_IFW_MqttServer_setMessageToSend(in integer p_serverIdx, MQTT_v3_1_1_ReqResp p_msg) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_MQTT_Server_CT v_server := mqttServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No MQTT server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_MQTT_Server_setMessageToSend(p_msg));
    v_server.done;

    return true;
  }
	
  function f_IFW_MqttServer_send(in integer p_serverIdx) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_MQTT_Server_CT v_server := mqttServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No MQTT server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_MQTT_Server_send());
    v_server.done;

    return true;
  }

  function f_IFW_MqttServer_receive(in integer p_serverIdx) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_MQTT_Server_CT v_server := mqttServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No MQTT server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_MQTT_Server_receive());
    v_server.done;

    return true;
  }

  function f_IFW_MqttServer_check(in integer p_serverIdx, template MQTT_v3_1_1_ReqResp p_msg) runs on IFW_MAIN_CT
  return boolean
  {
    var boolean v_ret;
    var IFW_MQTT_Server_CT v_server := mqttServers[p_serverIdx];	  
    if (v_server == null) { log("IFW: No MQTT server found"); return false; }	  
    f_isRunningGuard(v_server);

    v_server.start(f_MQTT_Server_check(p_msg));
    v_server.done(ReturnBoolean:?) -> value v_ret; 

    return v_ret;
  }
	
  function f_IFW_MqttServer_close(in integer p_serverIdx) runs on IFW_MAIN_CT
  return boolean
  {
    var IFW_MQTT_Server_CT v_server := mqttServers[p_serverIdx];
    if (v_server == null) { log("IFW: No MQTT server found"); return false; }
    f_isRunningGuard(v_server);

    v_server.start(f_MQTT_Server_close());
    v_server.done;

    return true;	  
  }
}
