blob: 28cdcea34593cb3a39212fb609d13d965cb2ca4e [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2016 Ericsson 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
*
* Contributors:
* Mate Kovacs - initial implementation and initial documentation
* Bence Janos Szabo - negative testing branch
******************************************************************************/
//
// File: Mqtt_v3.1.1_Types.ttcn
// Rev: R1A
// Prodnr: CNL 113 831
module MQTT_v3_1_1_Types
{
// RAW encoding will produce a remLength of 4 bytes;
// this function reads this 4 bytes and encodes as
// it is written in the MQTT standard
function f_adjustLength(in octetstring p_os) return octetstring
{
// get the remLength from thr RAW encoded octetstring
var integer remLength := oct2int(substr(p_os, 1, 4));
var octetstring encodedRemLenght := ''O;
var integer encodedByte;
do {
encodedByte := remLength mod 128;
remLength := remLength / 128;
if (remLength > 0) {
encodedByte := bit2int(int2bit(encodedByte, 8) or4b '10000000'B);
}
encodedRemLenght := encodedRemLenght & int2oct(encodedByte, 1);
} while (remLength > 0 );
p_os := replace(p_os, 1, 4, encodedRemLenght);
return p_os
}
function f_trimLength(in octetstring p_os) return octetstring
{
//decoding expects remLength of 4 bytes ; anything shorter will b4 completed to 4 bytes
var octetstring v_os:=''O;
var integer v_l:= lengthof(p_os) //unadjusted length
//X Y 0N--127N
if((v_l >=0+2) and (v_l<=127+2))//1 octet for length
{
v_os:= substr(p_os,0,1)&'000000'O&substr(p_os,1,v_l-1 )
}
else if ((v_l >= 128+2) and (v_l <=16383+2 )) //2 octets for length
{
v_os:= substr(p_os,0,1)&'0000'O&substr(p_os,1,v_l-1 )
}
else if ((v_l >= 16384+2) and (v_l <=2097151+2 ))//3 octets for length
{
v_os:= substr(p_os,0,1)&'00'O&substr(p_os,1,v_l-1 )
}
else if ((v_l >= 2097152+2) and (v_l <=268435455+2 ))//4 octets for length
{
v_os:=p_os
}
else {}
return v_os
}
external function f_MQTT_v3_1_1_enc(in MQTT_v3_1_1_Message msg, out octetstring str) return integer;
external function f_MQTT_v3_1_1_dec(in octetstring str, out MQTT_v3_1_1_Message msg) return integer;
external function f_MQTT_enc(in MQTT_v3_1_1_Message msg) return octetstring
with { extension "prototype(convert) encode(RAW)" };
// RAW decoding does not work correctly.
external function f_MQTT_dec(in octetstring stream) return MQTT_v3_1_1_Message
with { extension "prototype(convert) decode(RAW)" };
function f_MQTT_decode(in octetstring msg) return MQTT_v3_1_1_Message
{
return f_MQTT_dec(f_trimLength(msg))
}
function f_MQTT_encode(in MQTT_v3_1_1_Message msg) return octetstring
{
return f_adjustLength(f_MQTT_enc(msg))
}
type octetstring OCT0_65535 length(0..65535);
type universal charstring UCHAR0_65535 length(0..65535) with { variant ""; };
type bitstring BIT1n length(1) with { variant "FIELDLENGTH(1),BITORDER(msb)"; };
type bitstring BIT4n length(4) with { variant "FIELDLENGTH(4)"; };
type octetstring OCT4 length(4) with { variant "FIELDLENGTH(4)"; };
type integer INT0_255 (0..255) with { variant "FIELDLENGTH(8)"; };
type integer INT_BIT16_MSB (0..65335) with { variant "FIELDLENGTH(16), BITORDER(msb)"; };
type record UTF8EncodedString
{
INT_BIT16_MSB stringLength,
UCHAR0_65535 stringItem
} with {
variant "FIELDORDER(msb)"
variant (stringLength) "BITORDERINFIELD(msb)" ;
variant (stringLength) "LENGTHTO(stringItem)" ;
}
type record OctStringWithLength
{
INT_BIT16_MSB stringLength,
OCT0_65535 stringItem
} with {
variant "FIELDORDER(msb)"
variant (stringLength) "BITORDERINFIELD(msb)" ;
variant (stringLength) "LENGTHTO(stringItem)" ;
}
type enumerated QoS
{
AT_MOST_ONCE_DELIVERY(0),
AT_LEAST_ONCE_DELIVERY(1),
EXACTLY_ONE_DELIVERY(2),
RESERVED(3)
} with { variant "FIELDLENGTH(2)"; }
type record Header
{
BIT4n packetType,
BIT4n flags,
OCT4 remLength
} with {
variant "FIELDORDER(msb)";
}
type record MQTT_v3_1_1_PublishHeader
{
BIT4n packetType,
BIT1n dup_flag,
QoS qos_level,
BIT1n retain_flag,
OCT4 remLength
} with { variant "FIELDORDER(msb)"; }
type record MQTT_v3_1_1_ConnectFlags
{
BIT1n user_name_flag,
BIT1n password_flag,
BIT1n will_retain,
QoS will_qos,
BIT1n will_flag,
BIT1n clean_session,
BIT1n reserved
} with { variant "FIELDORDER(msb)"; }
type record MQTT_v3_1_1_ConnectPayload
{
UTF8EncodedString client_identifier,
UTF8EncodedString will_topic optional,
OctStringWithLength will_message optional,
UTF8EncodedString user_name optional,
OctStringWithLength password optional
} with { variant "FIELDORDER(msb)"; }
type record MQTT_v3_1_1_Connect
{
Header header,
INT_BIT16_MSB nameLength,
UCHAR0_65535 name,
integer protocol_level (0..255),
MQTT_v3_1_1_ConnectFlags flags,
integer keep_alive (0..65535),
MQTT_v3_1_1_ConnectPayload payload
} with {
variant "FIELDORDER(msb)";
variant (nameLength) "BITORDERINFIELD(msb)";
variant (nameLength) "LENGTHTO(name)";
variant (protocol_level) "FIELDLENGTH(8)";
variant (keep_alive) "FIELDLENGTH(16)";
}
type record MQTT_v3_1_1_Connack
{
Header header,
BIT1n session_present_flag,
integer connect_return_code (0..255)
} with {
variant "FIELDORDER(msb)";
variant (session_present_flag) "BITORDERINFIELD(msb)" ;
variant (session_present_flag) "FIELDLENGTH(8)";
variant (connect_return_code) "BITORDERINFIELD(lsb)";
variant (connect_return_code) "FIELDLENGTH(8)";
}
type record MQTT_v3_1_1_Publish
{
MQTT_v3_1_1_PublishHeader header,
INT_BIT16_MSB nameLength,
UCHAR0_65535 topic_name,
integer packet_identifier (0..65535) optional,
octetstring payload
} with {
variant "FIELDORDER(msb)";
variant (packet_identifier) "BYTEORDER(last)" ;
variant (packet_identifier) "FIELDLENGTH(16)";
variant (nameLength) "BITORDERINFIELD(msb)" ;
variant (nameLength) "LENGTHTO(topic_name)";
}
type record MQTT_v3_1_1_Identifier
{
Header header,
integer packet_identifier (0..65535)
} with {
variant "FIELDORDER(msb)";
variant (header.remLength) "LENGTHTO(packet_identifier)" ;
variant (packet_identifier) "BYTEORDER(last)";
variant (packet_identifier) "FIELDLENGTH(16)";
}
type record MQTT_v3_1_1_SubscribePayload
{
INT_BIT16_MSB filterLength,
UCHAR0_65535 topic_filter,
QoS requested_qos
} with {
variant "FIELDORDER(msb)";
variant (filterLength) "BITORDERINFIELD(msb)" ;
variant (filterLength) "LENGTHTO(topic_filter)";
variant (requested_qos) "BITORDERINFIELD(msb)" ;
variant (requested_qos) "FIELDLENGTH(8)" ;
variant (requested_qos) "BITORDER(msb)" ;
}
type record of MQTT_v3_1_1_SubscribePayload MQTT_v3_1_1_SubscribePayloadList;
type record MQTT_v3_1_1_Subscribe
{
Header header,
integer packet_identifier (0..65535),
MQTT_v3_1_1_SubscribePayloadList payload
} with {
variant "FIELDORDER(msb)";
variant (packet_identifier) "BYTEORDER(last)";
variant (packet_identifier) "FIELDLENGTH(16)";
}
type record of INT0_255 IntegerList;
type record MQTT_v3_1_1_SubackPayload
{
IntegerList return_code
}
type record MQTT_v3_1_1_Suback
{
Header header,
integer packet_identifier (0..65535),
MQTT_v3_1_1_SubackPayload payload
} with {
variant "FIELDORDER(msb)";
variant (packet_identifier) "BYTEORDER(last)";
variant (packet_identifier) "FIELDLENGTH(16)";
}
type record MQTT_v3_1_1_UnsubscribePayload
{
INT_BIT16_MSB filterLength,
UCHAR0_65535 topic_filter
} with {
variant "FIELDORDER(msb)";
variant (filterLength) "BITORDERINFIELD(msb)" ;
variant (filterLength) "LENGTHTO(topic_filter)";
}
type record of MQTT_v3_1_1_UnsubscribePayload MQTT_v3_1_1_UnsubscribePayloadList
type record MQTT_v3_1_1_Unsubscribe
{
Header header,
integer packet_identifier (0..65535),
MQTT_v3_1_1_UnsubscribePayloadList payload
} with {
variant "FIELDORDER(msb)";
variant (packet_identifier) "BYTEORDER(last)";
variant (packet_identifier) "FIELDLENGTH(16)";
}
type record MQTT_v3_1_1_Empty
{
Header header
}
type union MQTT_v3_1_1_ReqResp
{
MQTT_v3_1_1_Connect connect_msg,
MQTT_v3_1_1_Connack connack,
MQTT_v3_1_1_Publish publish,
MQTT_v3_1_1_Identifier puback,
MQTT_v3_1_1_Identifier pubrec,
MQTT_v3_1_1_Identifier pubrel,
MQTT_v3_1_1_Identifier pubcomp,
MQTT_v3_1_1_Subscribe subscribe,
MQTT_v3_1_1_Suback suback,
MQTT_v3_1_1_Unsubscribe unsubscribe,
MQTT_v3_1_1_Identifier unsuback,
MQTT_v3_1_1_Empty pingreq,
MQTT_v3_1_1_Empty pingresp,
MQTT_v3_1_1_Empty disconnect_msg
} with { variant "TAG(
connect_msg, header.packetType = '0001'B;
connack, header.packetType = '0010'B;
publish, header.packetType = '0011'B;
puback, header.packetType = '0100'B;
pubrec, header.packetType = '0101'B;
pubrel, header.packetType = '0110'B;
pubcomp, header.packetType = '0111'B;
subscribe, header.packetType = '1000'B;
suback, header.packetType = '1001'B;
unsubscribe, header.packetType = '1010'B;
unsuback, header.packetType = '1011'B;
pingreq, header.packetType = '1100'B;
pingresp, header.packetType = '1101'B;
disconnect_msg, header.packetType = '1110'B; )"
}
type union MQTT_v3_1_1_Message
{
MQTT_v3_1_1_ReqResp msg,
octetstring raw_message
} with { variant "" }
} with { encode "RAW" }