/******************************************************************************/
// @copyright   Copyright Notification
//   No part may be reproduced except as authorized by written permission.
//   The copyright and the foregoing restriction extend to reproduction in all media.
//   Trademark 2010, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC).
//   All rights reserved.
// @version: IWD_10wk37
// $Date: 2010-08-19 00:48:00 +0200 (Thu, 19 Aug 2010) $
// $Rev: 3727 $
/******************************************************************************/

module CommonDefs {

  //----------------------------------------------------------------------------
  // type definitions:

  type bitstring                B1_Type        length(1);
  type bitstring                B2_Type        length(2);
  type bitstring                B3_Type        length(3);
  type bitstring                B4_Type        length(4);
  type bitstring                B5_Type        length(5);
  type bitstring                B6_Type        length(6);
  type bitstring                B7_Type        length(7);
  type bitstring                B7_15_Type     length(7..15);   // NOTE: length restriction can only be a range but not two destinct lengths
  type bitstring                B8_Type        length(8);
  type bitstring                B9_Type        length(9);
  type bitstring                B10_Type       length(10);
  type bitstring                B11_Type       length(11);
  type bitstring                B12_Type       length(12);
  type bitstring                B14_Type       length(14);
  type bitstring                B15_Type       length(15);
  type bitstring                B16_Type       length(16);
  type bitstring                B20_Type       length(20);
  type bitstring                B24_Type       length(24);
  type bitstring                B27_Type       length(27);
  type bitstring                B28_Type       length(28);
  type bitstring                B32_Type       length(32);
  type bitstring                B36_Type       length(36);
  type bitstring                B40_Type       length(40);
  type bitstring                B47_Type       length(47);
  type bitstring                B48_Type       length(48);
  type bitstring                B64_Type       length(64);
  type bitstring                B80_Type       length(80);
  type bitstring                B112_Type      length(112);
  type bitstring                B128_Type      length(128);
  type bitstring                B256_Type      length(256);
  type bitstring                B32_128_Type   length(32..128);

  type B128_Type                B128_Key_Type;      /* 128 bit security key */
  type B256_Type                B256_Key_Type;      /* 256 bit security key */

  type octetstring              O1_Type         length(1);
  type octetstring              O2_Type         length(2);
  type octetstring              O3_Type         length(3);
  type octetstring              O4_Type         length(4);
  type octetstring              O5_Type         length(5);
  type octetstring              O6_Type         length(6);
  type octetstring              O8_Type         length(8);
  type octetstring              O9_Type         length(9);
  type octetstring              O10_Type        length(10);
  type octetstring              O14_Type        length(14);
  type octetstring              O13_Type        length(14);
  type octetstring              O15_Type        length(15);
  type octetstring              O16_Type        length(16);
  type octetstring              O32_Type        length(32);

  type hexstring                H2_Type         length(2);

  type boolean Null_Type  (true);    // dummy type for 'typeless' fields in unions
  type boolean Dummy_Type (true);    // dummy type for temporary purposes only

  const integer tsc_UInt8Max  := 255;
  const integer tsc_UInt16Max := 65535;
  const integer tsc_UInt32Max := 4294967295;

  type integer  UInt_Type    (0 .. infinity);
  type integer  UInt8_Type   (0 .. tsc_UInt8Max);
  type integer  UInt16_Type  (0 .. tsc_UInt16Max);
  type integer  UInt32_Type  (0 .. tsc_UInt32Max);

  type charstring Char1_Type length (1);
  type record of Char1_Type Char1List_Type;
  type record of charstring CharStringList_Type;

  type enumerated EUTRA_ATTACH_TESTED_Type { EPS_ATTACH_ONLY, COMBINED_ATTACH};
  type enumerated NAS_ATTACH_STATE_Type {ATTACHED, DETACHED};

  //----------------------------------------------------------------------------
  // common functions:

  type integer LineNo_Type;

  /*
   * @desc      local function
   * @param     p_FileName
   * @param     p_LineNo
   * @param     p_Msg
   * @return    charstring
   * @status    APPROVED
   */
  function fl_FormatLog(charstring p_FileName,
                        LineNo_Type p_LineNo,
                        charstring p_Msg) return charstring
  {
    var charstring v_LineNoStr := int2str(p_LineNo);

    return p_FileName & ":" & v_LineNoStr & ": " & p_Msg;   /* common "UNIX style" format as e.g. used by grep;
                                                             * the final format for this output is FFS */

  }

  //----------------------------------------------------------------------------
  /*
   * @desc      function for common error logging
   * @param     p_FileName
   * @param     p_LineNo
   * @param     p_Msg
   * @status    APPROVED
   */
  function f_ErrorLog(charstring p_FileName,
                      LineNo_Type p_LineNo,
                      charstring p_Msg)
  {
    log(fl_FormatLog(p_FileName, p_LineNo, p_Msg));
  };

  //----------------------------------------------------------------------------
  /*
   * @desc      common function for verdict assignment
   * @param     p_Verdict
   * @param     p_FileName
   * @param     p_LineNo
   * @param     p_Msg
   * @status    APPROVED
   */
  function f_SetVerdict(verdicttype p_Verdict,
                        charstring p_FileName,
                        LineNo_Type p_LineNo,
                        charstring p_Msg)
  {
    var charstring v_OutputLine := fl_FormatLog(p_FileName, p_LineNo, p_Msg);
    setverdict(p_Verdict, v_OutputLine);
  }

  //----------------------------------------------------------------------------
  /*
   * @desc      Common functions to be called in case unrecoverable errors
   *            (i.e. runtimer errors generated by TTCN)
   * @param     p_FileName
   * @param     p_LineNo
   * @param     p_Msg
   * @status    APPROVED
   */
  function FatalError(charstring p_FileName,
                      LineNo_Type p_LineNo,
                      charstring p_Msg)
  {
    var integer i := 1;
    var integer k := 0;
    // setverdict(inconc);  // setverdict causes problems when FatalError is used in a function called from within a template => we do it the hard way (see below)
    f_ErrorLog(p_FileName, p_LineNo, p_Msg);
    // self.kill;   // self.kill causes problems when FatalError is used in a function called from within a template ...


    /* the hard way:
       until there is no way to terminate a test by means of TTCN-3 from within a template we generate a run-time error
       what causes the test case being terminated with verdict 'error' */
    i := i / k;
  };

  //----------------------------------------------------------------------------
  /*
   * @desc      Common function to delay the test case for the given time
   * @param     p_DelayTime
   * @status    APPROVED
   */
  function f_Delay ( float p_DelayTime )
  {
    timer t_Delay;

    t_Delay.start ( p_DelayTime );
    t_Delay.timeout;
  };

  //----------------------------------------------------------------------------

  function f_TemplateBit2Int(template (present) integer p_Val,
                             integer p_Length) return template bitstring
  { /* Auxiliary function
     * note: there is no possibility in TTCN-3 to check whether a template parameter
     *       which is not a value is "*", "?" or omit
     *       => we restrict p_Val to "template (present)", i.e it shall be a value or "?" */
    if (isvalue(p_Val)) {
      return int2bit(valueof(p_Val), p_Length);
    } else {
      return ?;
    }
  }

  //----------------------------------------------------------------------------
  /*
   * @desc      returns index of first occurency of any char of p_CharList in p_String starting from p_StartIndex;
   *            returns -1 if there is no occurency
   * @param     p_String
   * @param     p_CharList
   * @param     p_StartIndex
   * @return    integer
   * @status    APPROVED
   */
  function f_StringFindChar(charstring p_String,
                            Char1List_Type p_CharList,
                            UInt_Type p_StartIndex) return integer
  {
    var integer v_NoOfChars := lengthof(p_CharList);
    var integer v_Index;
    var integer i;
    var Char1_Type v_Char;

    if (v_NoOfChars == 0) {
      return -1;
    }

    for (v_Index:=p_StartIndex; v_Index<lengthof(p_String); v_Index:=v_Index+1) {
      v_Char := p_String[v_Index];
      for (i:=0; i<v_NoOfChars; i:=i+1) {
        if (v_Char == p_CharList[i]) {
          return v_Index;
        }
      }
    }
    return -1;
  }

  //----------------------------------------------------------------------------
  /*
   * @desc      returns list of strings after split
   * @param     p_String
   * @param     p_SplitCharList
   * @return    CharStringList_Type
   * @status    APPROVED
   */
  function f_StringSplit(charstring p_String,
                         Char1List_Type p_SplitCharList) return CharStringList_Type
  {
    var CharStringList_Type v_StringList;
    var integer v_Index;
    var integer v_SubStrLen;
    var integer v_StartIndex := 0;
    var integer v_StrLen := lengthof(p_String);
    var integer v_StrCnt := 0;
    var boolean v_Break := false;

    while (not v_Break) {
      v_Index := f_StringFindChar(p_String, p_SplitCharList, v_StartIndex);
      if (v_Index<0) {
        v_SubStrLen := v_StrLen - v_StartIndex;
        v_Break := true;
      } else {
        v_SubStrLen := v_Index - v_StartIndex;
      }
      v_StringList[v_StrCnt] := substr(p_String, v_StartIndex, v_SubStrLen);
      v_StrCnt := v_StrCnt + 1;
      v_StartIndex := v_Index + 1;  // skip the split char
    }
    return v_StringList;
  }

  //----------------------------------------------------------------------------

  function f_ConvertBoolToBit (boolean p_Bool) return B1_Type
  {
    var B1_Type v_Bit := '0'B;
    if (p_Bool) {
      v_Bit := '1'B;
    }
    return v_Bit;
  }

  //----------------------------------------------------------------------------
  /*
   * @desc      return octet-aligned bitstring
   * @param     p_Bitstring
   * @return    bitstring
   * @status    APPROVED
   */
  function f_OctetAlignedBitString( bitstring p_Bitstring) return bitstring
  { // @sic R5s100324 change 3 sic@
    var bitstring v_Bitstring := p_Bitstring;
    var integer v_BitLength := lengthof(p_Bitstring);
    var integer v_PaddingLength;
    var integer i;

    if ((v_BitLength mod 8) > 0)         // if not already byte aligned
      {
        v_PaddingLength := 8 - (v_BitLength mod 8);
        for (i:=0; i < v_PaddingLength; i := i+1)
          {
            v_Bitstring := v_Bitstring & '0'B;
          }
      }
    
    return v_Bitstring;
  }
  
  //----------------------------------------------------------------------------
  /*
   * @desc      External function giving back the name of the test case currently running
   * @return    charstring
   * @status    APPROVED
   */
  external function fx_GetCurrentTestcaseName() return charstring;

  //----------------------------------------------------------------------------
  function f_TestcaseIsL2Testcase() return boolean
  {
    var charstring v_TestcaseName := fx_GetCurrentTestcaseName();
    var template charstring v_L2TestcasePattern := pattern "TC_7_*";  /* @sic R5s100136 sic@ */
    return (match(v_TestcaseName, v_L2TestcasePattern));
  }

  //----------------------------------------------------------------------------
  /* system time acc. to default C library (see time.h) */

  type record Struct_tm_Type {  /* TTCN-3 equivalent for the "struct tm" as defined on C standard library (time.h or ctime.h for C or C++) */
    integer tm_sec,             /* seconds after the minute    0..61 (tm_sec is generally 0-59. Extra range to accommodate for leap seconds in certain systems) */
    integer tm_min,             /* minutes after the hour      0..59   */
    integer tm_hour,            /* hours since midnight        0..23   */
    integer tm_mday,            /* day of the month            1..31   */
    integer tm_mon,             /* months since January        0..11   */
    integer tm_year,            /* years since 1900                    */
    integer tm_wday,            /* days since Sunday           0..6    */
    integer tm_yday,            /* days since January 1        0..365  */
    integer tm_isdst            /* Daylight Saving Time flag           */
  };

  external function fx_GetSystemTime(out Struct_tm_Type p_Struct_tm,    /* p_Struct_tm returns local system time;
                                                                         * C implementation:
                                                                         *         time_t v_Now = time(NULL);
                                                                         *         struct tm *v_Tm = localtime(&v_Now);
                                                                         */
                                     out integer p_TimezoneInfo);       /* p_TimezoneInfo returns the difference (in seconds) between the UTC time (GMT) and the local time;
                                                                         * C implementation:
                                                                         *         int timezone = (int)difftime(mktime(gmtime(&v_Now)), v_Now);
                                                                         * NOTE: p_TimezoneInfo does not consider daylight saving e.g. it is always 3600 for CET independent of summer/winter
                                                                         */
}
