///////////////////////////////////////////////////////////////////////////////
//
// 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:               STUN_Types.ttcn
//  Description:        
//  Rev:                R2B
//  Prodnr:             CNL 113 778
//  Updated:            2013-05-24
//  Contact:            http://ttcn.ericsson.se
//  Reference:          IETF RFC 5389, IETF RFC 5245           
//
//
module STUN_Types {

import from General_Types all;

modulepar {
  boolean tsp_calculate_while_encode := true;
}

external function ef_STUN_enc(
  in PDU_STUN pl_pdu,
  in OCT16 pl_key,
  out octetstring pl_result,
  in boolean pl_calculate_HMAC_CRC := tsp_calculate_while_encode
);

external function ef_STUN_dec(in octetstring pl_stream, out PDU_STUN pl_result) with {
  extension "decode(RAW)";
  extension "prototype(fast)";
}

external function ef_STUN_Check_Message_Integrity(
  in octetstring pl_stream, 
  in OCT16 pl_key,
  in STUN_Attribute_Type pl_last_attribute_type
) return boolean;
external function ef_STUN_Generate_Transaction_Id() return OCT12;
external function ef_STUN_get_Message_Length(in octetstring pl_stream) return integer;


type record PDU_STUN{
  STUN_Message_Header        STUN_message_header,
  STUN_Attributes            STUN_attributes
} with {
  variant (STUN_message_header) "LENGTHTO(STUN_attributes)";
  variant (STUN_message_header) "LENGTHINDEX (message_length)";
  variant "PADDING(dword32)";
}

// 6.
type record STUN_Message_Header {
  STUN_Message_Type        message_type,
  LIN2_BO_LAST             message_length,
  OCT4                     magic_cookie(cg_magic_cookie),
  OCT12                    transaction_id
}

type enumerated STUN_Message_Type {
  BINDING_REQUEST(1),
  BINDING_INDICATION(17),
  BINDING_SUCCESS_RESPONSE(257),
  BINDING_ERROR_RESPONSE (273)
} with {
  variant "FIELDLENGTH(16)";
  variant "BYTEORDER(last)";
  variant "PADDING(yes)";
}

// 15.
type record of STUN_Attribute_Padding STUN_Attributes;

type STUN_Attribute STUN_Attribute_Padding with {
  variant "PADDING(dword32)";
}

type record STUN_Attribute {
  STUN_Attribute_Type        attribute_type,
  LIN2_BO_LAST               attribute_length,
  STUN_Attribute_Value       attribute_value optional
} with {
  variant (attribute_length) "LENGTHTO(attribute_value)";
  variant (attribute_value) "CROSSTAG(
  mapped_address,  attribute_type = MAPPED_ADDRESS;
  xor_mapped_address, attribute_type = XOR_MAPPED_ADDRESS;
  username, attribute_type = USERNAME;
  message_integrity, attribute_type = MESSAGE_INTEGRITY;
  fingerprint, attribute_type = FINGERPRINT;
  error_code, attribute_type = ERROR_CODE;
  realm, attribute_type = REALM;
  nonce, attribute_type = NONCE;
  priority, attribute_type = PRIORITY;
  unknown_attributes, attribute_type = UNKNOWN_ATTRIBUTES;
  software, attribute_type = SOFTWARE;
  alternate_server, attribute_type = ALTERNATE_SERVER;
  ice_controlled, attribute_type = ICE_CONTROLLED;
  ice_controlling, attribute_type = ICE_CONTROLLING;
  )";
}


// 18.2
type enumerated STUN_Attribute_Type {
  // required range 0x0000-0x7FFFF
  MAPPED_ADDRESS(1),
  USERNAME (6),
  MESSAGE_INTEGRITY(8),
  ERROR_CODE(9),
  UNKNOWN_ATTRIBUTES (10),
  REALM (20),
  NONCE (21),
  PRIORITY (36),
  USE_CANDIDATE (37),
  XOR_MAPPED_ADDRESS(32),
  // optional range (0x8000-0xFFFF)
  SOFTWARE (32802),
  ALTERNATE_SERVER (32803),
  FINGERPRINT (32808),
  ICE_CONTROLLED (32809),
  ICE_CONTROLLING (32810)  
} with {
  variant "FIELDLENGTH(16)";
  variant "BYTEORDER(last)";
}


type union STUN_Attribute_Value {
  STUN_Address            mapped_address,                   // 15.1
  STUN_Address            xor_mapped_address,               // 15.2
  charstring              username,                         // 15.3
  OCT20                   message_integrity,                // 15.4
  OCT4                    fingerprint,                      // 15.5
  STUN_Error_Code         error_code,                       // 15.6
  charstring              realm,                            // 15.7
  octetstring             nonce,                            // 15.8
  LIN4_BO_LAST            priority,                         // RFC 5245 19.1
  STUN_Unknown_Attributes unknown_attributes,               // 15.9
  charstring              software,                         // 15.10
  STUN_Address            alternate_server,                 // 15.11
  OCT8                    ice_controlled,                   // RFC 5245 19.1
  OCT8                    ice_controlling                   // RFC 5245 19.1
}

// 15.1
type record STUN_Address {
   STUN_Address_Family     family,
   LIN2_BO_LAST            port_id,
   STUN_Address_Stream     ip_address
} with {
  variant (ip_address) " CROSSTAG(
    ip4_address, family = IP4;
    ip6_address, family = IP6;
  )";
}

type union STUN_Address_Stream {
  OCT4         ip4_address,
  OCT16        ip6_address
}

type enumerated STUN_Address_Family {
  IP4 (1),
  IP6 (2)
} with {
  variant "FIELDLENGTH(16)";
  variant "BYTEORDER(last)";
  variant "PADDING(yes)";
}

// 15.6
type record STUN_Error_Code {
  STUN_Error_Code_Type  error_code_type,
  charstring            reason_phrase
}

type enumerated STUN_Error_Code_Type {
  //              class (3 bit)| number (8 bit)
  TRY_ALTERNATE (768),     // 3 00
  BAD_REQUEST (1024),      // 4 00
  UNAUTHORIZED (1025),     // 4 01
  UNKNOWN_ATTRIBUTE(1044), // 4 20
  STALE_NONCE (1062),      // 4 38
  ROLE_CONFLICT (1111),    // 4 87
  SERVER_ERROR (1280)      // 5 00
} with {
  variant "FIELDLENGTH(32)";
  variant "BYTEORDER(last)";
  variant "PADDING(yes)";   
}

type set of OCT2 STUN_Unknown_Attributes;

const OCT4 cg_magic_cookie := '2112A442'O;

} //end of module
with {
extension "version R2B"
encode "RAW";  
}

