blob: 3f927c546cf97e7c0ba0b4df42b0cad2794d4541 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
//
// 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_Functions.ttcn
// Description:
// Rev: <RnXnn>
// Prodnr: CNL 113 910
// Updated: 2020-03-06
// Contact: http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
module IFW_MQTT_Server_Functions
{
import from IFW_MQTT_Server_Definitions all;
import from MQTT_v3_1_1_Types all;
import from MQTT_v3_1_1_IPL4SizeFunction all;
import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from IFW_Common all;
import from TCCMessageHandling_Functions all;
function f_MQTT_Server_init() runs on IFW_MQTT_Server_CT
{
log(%definitionId, " started");
var Result vl_result;
log("Mapping started");
map(self:IPL4_PCO,system:IPL4_PCO);
var f_IPL4_getMsgLen vl_f := refers(f_GetMsgLengthMQTT);
f_IPL4_setGetMsgLen(IPL4_PCO, -1, vl_f, {});
log("Creating the server socket");
vl_result := f_IPL4_listen(IPL4_PCO, ctx.localHost, ctx.localPort, {tcp := {}}, {{reuseAddress := {enable := true}}});
f_checkResult(vl_result);
ctx.serverConnId := vl_result.connId;
log(%definitionId, " finished");
}
function f_MQTT_Server_cleanUp() runs on IFW_MQTT_Server_CT
{
log(%definitionId, " started");
var Result vl_result;
log("Closing connection");
if (ctx.serverConnId >= 0)
{
vl_result := f_IPL4_close(IPL4_PCO, ctx.serverConnId, {tcp := {}});
//f_checkResult(vl_result);
}
log(%definitionId, " finished");
}
function f_MQTT_Server_getContext() runs on IFW_MQTT_Server_CT
return MqttServerContext
{
return ctx;
}
function f_MQTT_Server_setContext(in MqttServerContext p_ctx) runs on IFW_MQTT_Server_CT
{
ctx := p_ctx;
}
function f_MQTT_getPacketId(in MQTT_v3_1_1_ReqResp p_msg)
return integer
{
if (ischosen(p_msg.publish)) { return p_msg.publish.packet_identifier }
else if (ischosen(p_msg.puback)) { return p_msg.puback.packet_identifier }
else if (ischosen(p_msg.pubrec)) { return p_msg.pubrec.packet_identifier }
else if (ischosen(p_msg.pubrel)) { return p_msg.pubrel.packet_identifier }
else if (ischosen(p_msg.pubcomp)) { return p_msg.pubcomp.packet_identifier }
else if (ischosen(p_msg.subscribe)) { return p_msg.subscribe.packet_identifier }
else if (ischosen(p_msg.suback)) { return p_msg.suback.packet_identifier }
else if (ischosen(p_msg.unsubscribe)) { return p_msg.unsubscribe.packet_identifier }
else if (ischosen(p_msg.unsuback)) { return p_msg.unsuback.packet_identifier }
else {
return -1;
}
}
function f_MQTT_setPacketId(inout MQTT_v3_1_1_ReqResp p_msg, integer p_id)
return boolean
{
if (ischosen(p_msg.publish)) { p_msg.publish.packet_identifier := p_id; }
else if (ischosen(p_msg.puback)) { p_msg.puback.packet_identifier := p_id; }
else if (ischosen(p_msg.pubrec)) { p_msg.pubrec.packet_identifier := p_id; }
else if (ischosen(p_msg.pubrel)) { p_msg.pubrel.packet_identifier := p_id; }
else if (ischosen(p_msg.pubcomp)) { p_msg.pubcomp.packet_identifier := p_id; }
else if (ischosen(p_msg.subscribe)) { p_msg.subscribe.packet_identifier := p_id; }
else if (ischosen(p_msg.suback)) { p_msg.suback.packet_identifier := p_id; }
else if (ischosen(p_msg.unsubscribe)) { p_msg.unsubscribe.packet_identifier := p_id; }
else if (ischosen(p_msg.unsuback)) { p_msg.unsuback.packet_identifier := p_id; }
else { return false; }
return true;
}
function f_MQTT_Server_setMessageToSend(in MQTT_v3_1_1_ReqResp p_msg, boolean p_msgIdFromLastReceived := false) runs on IFW_MQTT_Server_CT
{
msgToSend := p_msg;
if (p_msgIdFromLastReceived)
{
var integer lastReceivedPacketId := f_MQTT_getPacketId(lastReceived);
if (lastReceivedPacketId != -1)
{
if (not f_MQTT_setPacketId(msgToSend, lastReceivedPacketId))
{
log("MQTT_Server: couldn't set packet id in msgToSend: ", msgToSend)
}
}
else { log("MQTT_Server: couldn't fetch packet id from lastReceived: ",lastReceived) };
}
}
function f_MQTT_Server_send() runs on IFW_MQTT_Server_CT
{
var octetstring v_encoded := ''O;
f_MQTT_v3_1_1_enc({ msg := msgToSend}, v_encoded);
var ASP_SendTo vl_send;
vl_send.connId := ctx.clientConnId;
vl_send.remName := ctx.remoteHost;
vl_send.remPort := ctx.remotePort;
vl_send.proto := {tcp := {}}
vl_send.msg := v_encoded;
log("MQTT PDU: ", msgToSend);
log("IPL4 PDU: ", vl_send);
IPL4_PCO.send(vl_send);
}
function f_MQTT_Server_receive(in float p_maxWait := 10.0) runs on IFW_MQTT_Server_CT
{
timer t_Timeout := p_maxWait;
if (p_maxWait > 0.0) { t_Timeout.start; }
var ASP_RecvFrom v_ipl4Recv;
var ASP_Event v_ipl4Event;
alt
{
[] IPL4_PCO.receive(ASP_RecvFrom:?) -> value v_ipl4Recv
{
log("Received: ", v_ipl4Recv);
if (ispresent(v_ipl4Recv.connId)) { ctx.clientConnId := v_ipl4Recv.connId; }
var MQTT_v3_1_1_Message v_mqttMsg;
f_MQTT_v3_1_1_dec(v_ipl4Recv.msg, v_mqttMsg);
if (ischosen(v_mqttMsg.msg))
{
lastReceived := v_mqttMsg.msg;
log("MQTT PDU: ", lastReceived);
}
else {
lastReceived := c_MQTTMessage_empty;
log("MQTT PDU [raw]:",v_mqttMsg);
}
ctx.remoteHost := v_ipl4Recv.remName;
ctx.remotePort := v_ipl4Recv.remPort;
log("IPL4 PDU: ", lastReceived);
}
[] IPL4_PCO.receive(ASP_Event:?) -> value v_ipl4Event
{
log("Received: ", v_ipl4Event);
repeat;
}
[] t_Timeout.timeout
{
lastReceived := c_MQTTMessage_empty;
}
}
}
function f_MQTT_Server_check(in template MQTT_v3_1_1_ReqResp p_expected) runs on IFW_MQTT_Server_CT
return ReturnBoolean
{
if (not match(lastReceived, p_expected))
{
log("CHECK: last received is not matching with expected template");
return false;
}
log("CHECK: return true");
return true;
}
function f_MQTT_Server_close() runs on IFW_MQTT_Server_CT
{
log(%definitionId, " started");
var Result vl_result;
log("Closing connection");
if (ctx.serverConnId >= 0)
{
vl_result := f_IPL4_close(IPL4_PCO, ctx.serverConnId, {tcp := {}});
//f_checkResult(vl_result);
}
log(%definitionId, " finished");
}
}