///////////////////////////////////////////////////////////////////////////////
//
// 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 v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
///////////////////////////////////////////////////////////////////////////////
//
//  File:     MBT_Qtronic_TestHarness.ttcn
//  Rev:      <RnXnn>
//  Prodnr:   CNL 113 659
//  Updated:  2010-10-01
//  Contact:  http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
/* -*- ttcn-3 -*- */

/**
* @file
*    C:\Users\eantwuh\workspace\GGSN_Goteborg\MBT_Qtronic_TestHarness.ttcn
* @author
*    Conformiq TTCN-3 scripting backend
* @version
*    Tue Sep 14 14:48:48 CEST 2010
* @desc
*    This is a template file with TTCN-3 function stubs for the implementation 
*    of test harness code for the test suites generated from the Conformiq '
*    GGSN_Goteborg' project.
* @remark
*    All function definitions must be edited as instructed in their comments in
*     order for the test suite to execute properly.
*/
module MBT_Qtronic_TestHarness
{
    import from MBT_Qtronic_Types all;
    import from MBT_Qtronic_TestSystem all;
    import from MBT_Qtronic_Main all;
    import from EPTF_MBT_LGen_Definitions all;
    import from EPTF_MBT_LGen_Functions all;
    import from EPTF_TELNET_LGen_Definitions all;

    modulepar
    {
      boolean tsp_enableLogging := true;
    }
            
    /**
    * @desc
    *    This function performs manipulation needed and sends a p_Restart
    *    via the abstract test interface to the SUT.
    * @param
    *    p_Restart Message data generated by CQ Designerto be sent to the SUT
    */
    function f_cq_send_Restart_to_CLIin(template Restart p_Restart) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_Restart); }
      
        // Steps that need to be implemented here are:
        // (modify and uncomment example code as needed)
        // 1. transform data from a Restart to the TTCN-3 data value used by the test harness (if needed)
        // var <T3RestartType> v_T3Restart := f_transformRestartCQtoT3(p_Restart);
        // 2. replace symbolic values (if any) with real values in TTCN-3 data value
        // 3. send TTCN-3 data value via TTCN-3 port which corresponds toCLIinmodel port
        // CLIin.send(v_T3Restart);
             //CLIin.send(p_Restart);
        // Remove or comment the following generated code
      log("CQ_INFO: Warning: f_cq_send_Restart_to_CLIin: function is not implemented)");
    }

    /**
    * @desc
    *    This function performs manipulation needed and sends a p_Configure
    *    via the abstract test interface to the SUT.
    * @param
    *    p_Configure Message data generated by CQ Designerto be sent to the SUT
    */
    function f_cq_send_Configure_to_CLIin(template Configure p_Configure) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_Configure); }
        // Steps that need to be implemented here are:
        // (modify and uncomment example code as needed)
        // 1. transform data from a Configure to the TTCN-3 data value used by the test harness (if needed)
        // var <T3ConfigureType> v_T3Configure := f_transformConfigureCQtoT3(p_Configure);
        // 2. replace symbolic values (if any) with real values in TTCN-3 data value
        // 3. send TTCN-3 data value via TTCN-3 port which corresponds toCLIinmodel port
        // CLIin.send(v_T3Configure);
             //CLIin.send(p_Configure);
        // Remove or comment the following generated code
        log("CQ_INFO: Warning: f_cq_send_Configure_to_CLIin: function is not implemented)");
    }

    /**
    * @desc
    *    This function performs manipulation needed and sends a p_OverrideConfiguration
    *    via the abstract test interface to the SUT.
    * @param
    *    p_OverrideConfiguration Message data generated by CQ Designerto be sent to the SUT
    */
    function f_cq_send_OverrideConfiguration_to_CLIin(template OverrideConfiguration p_OverrideConfiguration) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_OverrideConfiguration); }
        // Steps that need to be implemented here are:
        // (modify and uncomment example code as needed)
        // 1. transform data from a OverrideConfiguration to the TTCN-3 data value used by the test harness (if needed)
        // var <T3OverrideConfigurationType> v_T3OverrideConfiguration := f_transformOverrideConfigurationCQtoT3(p_OverrideConfiguration);
        // 2. replace symbolic values (if any) with real values in TTCN-3 data value
        // 3. send TTCN-3 data value via TTCN-3 port which corresponds toCLIinmodel port
        // CLIin.send(v_T3OverrideConfiguration);
             //CLIin.send(p_OverrideConfiguration);
        // Remove or comment the following generated code
        log("CQ_INFO: Warning: f_cq_send_OverrideConfiguration_to_CLIin: function is not implemented)");
    }

    /**
    * @desc
    *    This function performs manipulation needed and sends a p_Prepare
    *    via the abstract test interface to the SUT.
    * @param
    *    p_Prepare Message data generated by CQ Designerto be sent to the SUT
    */
    function f_cq_send_Prepare_to_CLIin(template Prepare p_Prepare) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_Prepare); }

      f_MBT_execute(c_EPTF_TELNET_stepName_init, valueof(t_addr(0)), {0});
      f_MBT_execute(c_EPTF_TELNET_stepName_connect, valueof(t_addr(0)), {0});
      f_MBT_waitFor(c_EPTF_TELNET_behavior, c_EPTF_TELNET_inputName_autoLoginFinished, valueof(t_addr(0)));

      timer t_wait := 30.0;

      f_MBT_execute(c_EPTF_TELNET_stepName_playList, valueof(t_addr(0)));
      t_wait.start;

      alt
      {
        [] EPTF_MBT_TESTER_PCO.receive(EPTF_MBT_TestStepResponse:{ bName := c_EPTF_TELNET_behavior, iName := c_EPTF_TELNET_inputName_matchingPlayListResp, addr := valueof(t_addr(0))})
        { 
          t_wait.stop;
          action(%definitionId, "Received: matchingPlayListRespReceived"); 
          f_MBT_execute(c_EPTF_TELNET_stepName_playList, valueof(t_addr(0)));
          t_wait.start;
          repeat;
        }
        [] EPTF_MBT_TESTER_PCO.receive(EPTF_MBT_TestStepResponse:{ bName := c_EPTF_TELNET_behavior, iName := c_EPTF_TELNET_inputName_lastMatchingPlayListResp, addr := valueof(t_addr(0))})
        { 
          action(%definitionId, "Received: lastMatchingPlayListRespReceived"); 
          t_wait.stop; 
        }
        [] EPTF_MBT_TESTER_PCO.receive
        { 
          log(%definitionId, "Dropping unexpected message!"); 
          repeat;
        }
        [] t_wait.timeout
        {
          action(%definitionId, "Timeout!"); 
        }
      }
    }

    /**
    * @desc
    *    This function performs manipulation needed and sends a p_Restore
    *    via the abstract test interface to the SUT.
    * @param
    *    p_Restore Message data generated by CQ Designerto be sent to the SUT
    */
    function f_cq_send_Restore_to_CLIin(template Restore p_Restore) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_Restore); }
        // Steps that need to be implemented here are:
        // (modify and uncomment example code as needed)
        // 1. transform data from a Restore to the TTCN-3 data value used by the test harness (if needed)
        // var <T3RestoreType> v_T3Restore := f_transformRestoreCQtoT3(p_Restore);
        // 2. replace symbolic values (if any) with real values in TTCN-3 data value
        // 3. send TTCN-3 data value via TTCN-3 port which corresponds toCLIinmodel port
        // CLIin.send(v_T3Restore);
             //CLIin.send(p_Restore);
        // Remove or comment the following generated code
        log("CQ_INFO: Warning: f_cq_send_Restore_to_CLIin: function is not implemented)");
    }

    /**
    * @desc
    *    This function performs manipulation needed and sends a p_UDPpdu
    *    via the abstract test interface to the SUT.
    * @param
    *    p_UDPpdu Message data generated by CQ Designerto be sent to the SUT
    */
    function f_cq_send_UDPpdu_to_GiIn(template UDPpdu p_UDPpdu) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_UDPpdu); }
        // Steps that need to be implemented here are:
        // (modify and uncomment example code as needed)
        // 1. transform data from a UDPpdu to the TTCN-3 data value used by the test harness (if needed)
        // var <T3UDPpduType> v_T3UDPpdu := f_transformUDPpduCQtoT3(p_UDPpdu);
        // 2. replace symbolic values (if any) with real values in TTCN-3 data value
        // 3. send TTCN-3 data value via TTCN-3 port which corresponds toGiInmodel port
        // GiIn.send(v_T3UDPpdu);
             //GiIn.send(p_UDPpdu);
        // Remove or comment the following generated code
      //log("CQ_INFO: Warning: f_cq_send_UDPpdu_to_GiIn: function is not implemented)");
      f_Model_sendUDPpdu(valueof(p_UDPpdu));
    }

    /**
    * @desc
    *    This function performs manipulation needed and sends a p_RadiusAccessAccept
    *    via the abstract test interface to the SUT.
    * @param
    *    p_RadiusAccessAccept Message data generated by CQ Designerto be sent to the SUT
    */
    function f_cq_send_RadiusAccessAccept_to_GiRadiusIn(template RadiusAccessAccept p_RadiusAccessAccept) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_RadiusAccessAccept); }
        // Steps that need to be implemented here are:
        // (modify and uncomment example code as needed)
        // 1. transform data from a RadiusAccessAccept to the TTCN-3 data value used by the test harness (if needed)
        // var <T3RadiusAccessAcceptType> v_T3RadiusAccessAccept := f_transformRadiusAccessAcceptCQtoT3(p_RadiusAccessAccept);
        // 2. replace symbolic values (if any) with real values in TTCN-3 data value
        // 3. send TTCN-3 data value via TTCN-3 port which corresponds toGiRadiusInmodel port
        // GiRadiusIn.send(v_T3RadiusAccessAccept);
             //GiRadiusIn.send(p_RadiusAccessAccept);
        // Remove or comment the following generated code
        log("CQ_INFO: Warning: f_cq_send_RadiusAccessAccept_to_GiRadiusIn: function is not implemented)");
    }

    /**
    * @desc
    *    This function performs manipulation needed and sends a p_CreatePDPcontext
    *    via the abstract test interface to the SUT.
    * @param
    *    p_CreatePDPcontext Message data generated by CQ Designerto be sent to the SUT
    */
    function f_cq_send_CreatePDPcontext_to_GnIn(template CreatePDPcontext p_CreatePDPcontext) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_CreatePDPcontext); }
      f_Model_sendCreatePDPContext(valueof(p_CreatePDPcontext));
    }

    /**
    * @desc
    *    This function performs manipulation needed and sends a p_UpdatePDPcontext
    *    via the abstract test interface to the SUT.
    * @param
    *    p_UpdatePDPcontext Message data generated by CQ Designerto be sent to the SUT
    */
    function f_cq_send_UpdatePDPcontext_to_GnIn(template UpdatePDPcontext p_UpdatePDPcontext) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_UpdatePDPcontext); }
      f_Model_sendUpdatePDPContext(valueof(p_UpdatePDPcontext));
    }

    /**
    * @desc
    *    This function performs manipulation needed and sends a p_DeletePDPcontext
    *    via the abstract test interface to the SUT.
    * @param
    *    p_DeletePDPcontext Message data generated by CQ Designerto be sent to the SUT
    */
    function f_cq_send_DeletePDPcontext_to_GnIn(template DeletePDPcontext p_DeletePDPcontext) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_DeletePDPcontext); }
      f_Model_sendDeletePDPContext(valueof(p_DeletePDPcontext));
    }

    /**
    * @desc
    *    This function performs manipulation needed and sends a p_GPDU
    *    via the abstract test interface to the SUT.
    * @param
    *    p_GPDU Message data generated by CQ Designerto be sent to the SUT
    */
    function f_cq_send_GPDU_to_GnIn(template GPDU p_GPDU) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_GPDU); }
        // Steps that need to be implemented here are:
        // (modify and uncomment example code as needed)
        // 1. transform data from a GPDU to the TTCN-3 data value used by the test harness (if needed)
        // var <T3GPDUType> v_T3GPDU := f_transformGPDUCQtoT3(p_GPDU);
        // 2. replace symbolic values (if any) with real values in TTCN-3 data value
        // 3. send TTCN-3 data value via TTCN-3 port which corresponds toGnInmodel port
        // GnIn.send(v_T3GPDU);
             //GnIn.send(p_GPDU);
      // Remove or comment the following generated code
      //log("CQ_INFO: Warning: f_cq_send_GPDU_to_GnIn: function is not implemented)");
      f_Model_sendGPDU(valueof(p_GPDU));
    }

    /**
    * @desc
    *    This function receives a TTCN-3 value corresponding to a UDPpdu
    *    via the abstract test system interface from the SUT, performs any
    *    manipulation and transformation needed to convert it to a UDPpdu
    *    value, and then attempts to match it to the p_expectedUDPpdu generated by CQ Designer
    * @param
    *    p_expectedUDPpduExpected data generated by CQ Designer
    */
    function f_cq_receive_UDPpdu_from_GiOut(template UDPpdu p_expectedUDPpdu) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_expectedUDPpdu); }
        //Steps that need to be implemented    here are:
        //1. receive and store (any) TTCN-3 data value via TTCN-3 port which corresponds to the GiOut model port
        // var <T3_UDPpduType> v_recvT3UDPpdu;
        // GiOut.receive(<T3_UDPpduType>:?) -> value v_recvT3UDPpdu;
        // 2. replace real with symbolic values (if any) in the received TTCN-3 data value
        // 3. transform data from a TTCN-3 to UDPpdu data value (if needed)
        // varUDPpduv_recvUDPpdu = f_transformUDPpduT3toCQ(v_recvT3UDPpdu);
        // 4. set the verdict to fail if if there is a mismatch of the transformed value and p_expectedUDPpdu
        // if ( !match( v_recvUDPpdu p_expectedUDPpdu) {
        //  log(CQ_INFO: f_cq_receive_UDPpdu_from_GiOut: FAIL: Mismatch in received and expected UDPpdu values. Stopping test case.â?);
        //   setverdict(fail);
        //   f_cq_f_MBT_Qtronic_endTestcase();
        //   stop; }
             GiOut.receive(p_expectedUDPpdu);
        // Remove or comment the following generated code
        //log("CQ_INFO: Warning: f_cq_receive_UDPpdu_from_GiOut: function is not implemented)");
    }

    /**
    * @desc
    *    This function receives a TTCN-3 value corresponding to a RadiusAccessRequest
    *    via the abstract test system interface from the SUT, performs any
    *    manipulation and transformation needed to convert it to a RadiusAccessRequest
    *    value, and then attempts to match it to the p_expectedRadiusAccessRequest generated by CQ Designer
    * @param
    *    p_expectedRadiusAccessRequestExpected data generated by CQ Designer
    */
    function f_cq_receive_RadiusAccessRequest_from_GiRadiusOut(template RadiusAccessRequest p_expectedRadiusAccessRequest) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_expectedRadiusAccessRequest); }
        //Steps that need to be implemented    here are:
        //1. receive and store (any) TTCN-3 data value via TTCN-3 port which corresponds to the GiRadiusOut model port
        // var <T3_RadiusAccessRequestType> v_recvT3RadiusAccessRequest;
        // GiRadiusOut.receive(<T3_RadiusAccessRequestType>:?) -> value v_recvT3RadiusAccessRequest;
        // 2. replace real with symbolic values (if any) in the received TTCN-3 data value
        // 3. transform data from a TTCN-3 to RadiusAccessRequest data value (if needed)
        // varRadiusAccessRequestv_recvRadiusAccessRequest = f_transformRadiusAccessRequestT3toCQ(v_recvT3RadiusAccessRequest);
        // 4. set the verdict to fail if if there is a mismatch of the transformed value and p_expectedRadiusAccessRequest
        // if ( !match( v_recvRadiusAccessRequest p_expectedRadiusAccessRequest) {
        //  log(CQ_INFO: f_cq_receive_RadiusAccessRequest_from_GiRadiusOut: FAIL: Mismatch in received and expected RadiusAccessRequest values. Stopping test case.â?);
        //   setverdict(fail);
        //   f_cq_f_MBT_Qtronic_endTestcase();
        //   stop; }
             //GiRadiusOut.receive(p_expectedRadiusAccessRequest);
        // Remove or comment the following generated code
        log("CQ_INFO: Warning: f_cq_receive_RadiusAccessRequest_from_GiRadiusOut: function is not implemented)");
    }

    /**
    * @desc
    *    This function receives a TTCN-3 value corresponding to a CreatePDPresponse
    *    via the abstract test system interface from the SUT, performs any
    *    manipulation and transformation needed to convert it to a CreatePDPresponse
    *    value, and then attempts to match it to the p_expectedCreatePDPresponse generated by CQ Designer
    * @param
    *    p_expectedCreatePDPresponseExpected data generated by CQ Designer
    */
    function f_cq_receive_CreatePDPresponse_from_GnOut(template CreatePDPresponse p_expectedCreatePDPresponse) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_expectedCreatePDPresponse); }
      GnOut.receive(p_expectedCreatePDPresponse);
    }

    /**
    * @desc
    *    This function receives a TTCN-3 value corresponding to a UpdatePDPresponse
    *    via the abstract test system interface from the SUT, performs any
    *    manipulation and transformation needed to convert it to a UpdatePDPresponse
    *    value, and then attempts to match it to the p_expectedUpdatePDPresponse generated by CQ Designer
    * @param
    *    p_expectedUpdatePDPresponseExpected data generated by CQ Designer
    */
    function f_cq_receive_UpdatePDPresponse_from_GnOut(template UpdatePDPresponse p_expectedUpdatePDPresponse) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_expectedUpdatePDPresponse); }
      GnOut.receive(p_expectedUpdatePDPresponse);
    }

    /**
    * @desc
    *    This function receives a TTCN-3 value corresponding to a DeletePDPresponse
    *    via the abstract test system interface from the SUT, performs any
    *    manipulation and transformation needed to convert it to a DeletePDPresponse
    *    value, and then attempts to match it to the p_expectedDeletePDPresponse generated by CQ Designer
    * @param
    *    p_expectedDeletePDPresponseExpected data generated by CQ Designer
    */
    function f_cq_receive_DeletePDPresponse_from_GnOut(template DeletePDPresponse p_expectedDeletePDPresponse) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_expectedDeletePDPresponse); }
      GnOut.receive(p_expectedDeletePDPresponse);
    }

    /**
    * @desc
    *    This function receives a TTCN-3 value corresponding to a GPDU
    *    via the abstract test system interface from the SUT, performs any
    *    manipulation and transformation needed to convert it to a GPDU
    *    value, and then attempts to match it to the p_expectedGPDU generated by CQ Designer
    * @param
    *    p_expectedGPDUExpected data generated by CQ Designer
    */
    function f_cq_receive_GPDU_from_GnOut(template GPDU p_expectedGPDU) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_expectedGPDU); }
        //Steps that need to be implemented    here are:
        //1. receive and store (any) TTCN-3 data value via TTCN-3 port which corresponds to the GnOut model port
        // var <T3_GPDUType> v_recvT3GPDU;
        // GnOut.receive(<T3_GPDUType>:?) -> value v_recvT3GPDU;
        // 2. replace real with symbolic values (if any) in the received TTCN-3 data value
        // 3. transform data from a TTCN-3 to GPDU data value (if needed)
        // varGPDUv_recvGPDU = f_transformGPDUT3toCQ(v_recvT3GPDU);
        // 4. set the verdict to fail if if there is a mismatch of the transformed value and p_expectedGPDU
        // if ( !match( v_recvGPDU p_expectedGPDU) {
        //  log(CQ_INFO: f_cq_receive_GPDU_from_GnOut: FAIL: Mismatch in received and expected GPDU values. Stopping test case.â?);
        //   setverdict(fail);
        //   f_cq_f_MBT_Qtronic_endTestcase();
        //   stop; }
      
      GnOut.receive(p_expectedGPDU);
        // Remove or comment the following generated code
        //log("CQ_INFO: Warning: f_cq_receive_GPDU_from_GnOut: function is not implemented)");
    }

    /**
    * @desc
    *    This function receives a TTCN-3 value corresponding to a CDRinfo
    *    via the abstract test system interface from the SUT, performs any
    *    manipulation and transformation needed to convert it to a CDRinfo
    *    value, and then attempts to match it to the p_expectedCDRinfo generated by CQ Designer
    * @param
    *    p_expectedCDRinfoExpected data generated by CQ Designer
    */
    function f_cq_receive_CDRinfo_from_GnOut(template CDRinfo p_expectedCDRinfo) runs on QtronicCT
    {
      if (tsp_enableLogging) { log(%definitionId, " enter: ", p_expectedCDRinfo); }
        //Steps that need to be implemented    here are:
        //1. receive and store (any) TTCN-3 data value via TTCN-3 port which corresponds to the GnOut model port
        // var <T3_CDRinfoType> v_recvT3CDRinfo;
        // GnOut.receive(<T3_CDRinfoType>:?) -> value v_recvT3CDRinfo;
        // 2. replace real with symbolic values (if any) in the received TTCN-3 data value
        // 3. transform data from a TTCN-3 to CDRinfo data value (if needed)
        // varCDRinfov_recvCDRinfo = f_transformCDRinfoT3toCQ(v_recvT3CDRinfo);
        // 4. set the verdict to fail if if there is a mismatch of the transformed value and p_expectedCDRinfo
        // if ( !match( v_recvCDRinfo p_expectedCDRinfo) {
        //  log(CQ_INFO: f_cq_receive_CDRinfo_from_GnOut: FAIL: Mismatch in received and expected CDRinfo values. Stopping test case.â?);
        //   setverdict(fail);
        //   f_cq_f_MBT_Qtronic_endTestcase();
        //   stop; }
             //GnOut.receive(p_expectedCDRinfo);
        // Remove or comment the following generated code
        log("CQ_INFO: Warning: f_cq_receive_CDRinfo_from_GnOut: function is not implemented)");
    }
}
