initial code commit
Signed-off-by: Eszter Susanszky <eszter.susanszky@ericsson.com>
diff --git a/IFW_CoAP_Peer_Definitions.ttcn b/IFW_CoAP_Peer_Definitions.ttcn
new file mode 100644
index 0000000..e043b50
--- /dev/null
+++ b/IFW_CoAP_Peer_Definitions.ttcn
@@ -0,0 +1,112 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IFW_CoAP_Peer_Definitions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IFW_CoAP_Peer_Definitions
+{
+ import from CoAP_Types all;
+ import from IPL4asp_PortType all;
+ import from IFW_Common all;
+
+ type component IFW_COAP_CT extends IFW_BASE_CT
+ {
+ var CoapContext ctx := CoapContext_empty;
+
+ var CoAP_ReqResp msgToSend := c_CoAP_ReqResp_empty;
+ var CoAP_ReqResp lastReceived := c_CoAP_ReqResp_empty;
+
+ port IPL4asp_PT IPL4_PCO;
+ }
+
+ type record CoapContext
+ {
+ integer connId,
+ integer connId_listen,
+ charstring remoteHost,
+ integer remotePort,
+ charstring localHost,
+ integer localPort,
+ boolean cherryPickOptionsCheck,
+ Charstring_List locationPath
+ }
+ with { extension "done" }
+
+ const CoapContext CoapContext_empty :=
+ {
+ connId := -1,
+ connId_listen := -1,
+ remoteHost := "",
+ remotePort := -1,
+ localHost := "",
+ localPort := -1,
+ cherryPickOptionsCheck := false,
+ locationPath := {}
+ }
+
+ const CoAP_ReqResp c_CoAP_ReqResp_empty :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code :=
+ {
+ class := 0,
+ detail := 0
+ },
+ message_id := 0
+ },
+ token := ''O,
+ options := omit,
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_CoAP_ReqResp_empty :=
+ {
+ header :=
+ {
+ version := ?,
+ msg_type := ?,
+ code :=
+ {
+ class := ?,
+ detail := ?
+ },
+ message_id := ?
+ },
+ token := ?,
+ options := *,
+ payload := *
+ }
+
+ type record of UCHAR0_255 Charstring_List;
+
+ type enumerated MID_Generation {
+ GENERATE_NEW_MID,
+ USE_GIVEN_MID,
+ USE_LAST_RECEIVED_MID
+ }
+
+ type enumerated Token_Generation {
+ GENERATE_NEW_TOKEN,
+ USE_GIVEN_TOKEN,
+ USE_LAST_RECEIVED_TOKEN
+ }
+
+ type enumerated MID_Check {
+ CHECK_MID,
+ DO_NOT_CHECK_MID
+ }
+}
diff --git a/IFW_CoAP_Peer_Functions.ttcn b/IFW_CoAP_Peer_Functions.ttcn
new file mode 100644
index 0000000..1c1d707
--- /dev/null
+++ b/IFW_CoAP_Peer_Functions.ttcn
@@ -0,0 +1,256 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IFW_CoAP_Peer_Functions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IFW_CoAP_Peer_Functions
+{
+ import from IFW_CoAP_Peer_Definitions all;
+ import from CoAP_Types all;
+ import from IPL4asp_Types all;
+ import from IPL4asp_PortType all;
+ import from IFW_Common all;
+
+ modulepar
+ {
+ float tsp_CoapPeer_maxResponseTime := 0.0;
+ boolean tsp_cherryPickOptionCheck := true;
+ }
+
+ function f_CoAP_Peer_init() runs on IFW_COAP_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_COAP_getMsgLength);
+ f_IPL4_setGetMsgLen(IPL4_PCO, -1, vl_f, {});
+
+ log("Setting up the listening socket");
+ vl_result := f_IPL4_listen(IPL4_PCO, ctx.localHost, ctx.localPort, {udp := {}}, {{reuseAddress := {enable := true}}});
+ f_checkResult(vl_result);
+ ctx.connId_listen := vl_result.connId;
+
+ log("Connecting the socket to the remote");
+ vl_result := f_IPL4_connect(IPL4_PCO, ctx.remoteHost, ctx.remotePort, ctx.localHost, ctx.localPort, -1,{udp := {}}, {{reuseAddress := {enable := true}}});
+ f_checkResult(vl_result);
+ ctx.connId := vl_result.connId;
+
+ ctx.cherryPickOptionsCheck := tsp_cherryPickOptionCheck;
+
+ log(%definitionId, " finished");
+ }
+
+ function f_CoAP_Peer_getContext() runs on IFW_COAP_CT
+ return CoapContext
+ {
+ return ctx;
+ }
+
+ function f_CoAP_Peer_setContext(in CoapContext p_ctx) runs on IFW_COAP_CT
+ {
+ ctx := p_ctx;
+ }
+
+ function f_CoAP_Peer_setMessageToSend(in CoAP_ReqResp p_msg, in MID_Generation p_genMid, in Token_Generation p_genToken) runs on IFW_COAP_CT
+ {
+ msgToSend := p_msg;
+
+ if (p_genMid == GENERATE_NEW_MID)
+ {
+ msgToSend.header.message_id := float2int(int2float(65000)*rnd());
+ }
+ else if (p_genMid == USE_LAST_RECEIVED_MID) {
+ if (lastReceived != c_CoAP_ReqResp_empty) {
+ msgToSend.header.message_id := lastReceived.header.message_id;
+ }
+ }
+
+ if (p_genToken == GENERATE_NEW_TOKEN)
+ {
+ msgToSend.token := int2oct(float2int(int2float(65000)*rnd()),4);
+ }
+ if (p_genToken == USE_LAST_RECEIVED_TOKEN) {
+ if (lastReceived != c_CoAP_ReqResp_empty) {
+ msgToSend.token := lastReceived.token;
+ }
+ }
+ }
+
+ function f_CoAP_Peer_send() runs on IFW_COAP_CT
+ {
+ var octetstring v_encoded;
+
+ f_CoAP_enc(CoAP_Message: {msg := msgToSend}, v_encoded);
+
+ var ASP_SendTo vl_send;
+
+ vl_send.connId := ctx.connId;
+ vl_send.remName := ctx.remoteHost;
+ vl_send.remPort := ctx.remotePort;
+ vl_send.proto := {udp := {}}
+
+ vl_send.msg := v_encoded;
+
+ log("COAP PDU: ", msgToSend);
+ IPL4_PCO.send(vl_send);
+ }
+
+ function f_CoAP_Peer_receive() runs on IFW_COAP_CT
+ {
+ // Activate default
+
+ timer t_Timeout := tsp_CoapPeer_maxResponseTime;
+ if (tsp_CoapPeer_maxResponseTime > 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);
+
+ var CoAP_Message v_coapMsg;
+ f_CoAP_dec(v_ipl4Recv.msg, v_coapMsg);
+
+ if (ischosen(v_coapMsg.msg))
+ {
+ lastReceived := v_coapMsg.msg;
+ log("COAP PDU: ", lastReceived);
+ }
+ }
+ [] IPL4_PCO.receive(ASP_Event:?) -> value v_ipl4Event
+ {
+ log("Received: ", v_ipl4Event);
+ repeat;
+ }
+ [] t_Timeout.timeout
+ {
+ lastReceived := c_CoAP_ReqResp_empty;
+ }
+
+ // Deactivate default
+ }
+ }
+
+ function f_CoAP_Peer_check(in template CoAP_ReqResp p_expected, in MID_Check p_checkMid := CHECK_MID) runs on IFW_COAP_CT
+ return ReturnBoolean
+ {
+ // TODO: checks
+ if (not f_COAP_isRequest(lastReceived) and lastReceived.header.msg_type == CONFIRMABLE and p_checkMid == CHECK_MID) {
+ // Check if the mid is the same in the req and in the rsp
+ if (not msgToSend.header.message_id == lastReceived.header.message_id) {
+ log("CHECK: header.message_id mismatch in request and response");
+ return false;
+ }
+ }
+
+ if (ctx.cherryPickOptionsCheck) {
+
+ var template CoAP_ReqResp v_expected_withoutOptions := p_expected;
+ v_expected_withoutOptions.options := *;
+ if (not match(lastReceived, v_expected_withoutOptions)) {
+ log("CHECK: last received is not matching with expected template");
+ return false;
+ }
+
+ // Check options 1-by-1
+ if (ispresent(p_expected.options) and sizeof(p_expected.options)>0)
+ {
+ if (not ispresent(lastReceived.options)) {
+ log("CHECK: Options are epxected but last received messages have them omitted");
+ return false;
+ }
+ var boolean optionsCheck := true;
+ for (var integer i:=0; i<sizeof(p_expected.options); i:=i+1) {
+ var template CoAP_Options v_currentExpectedOption := p_expected.options[i];
+ var boolean optionCheck := false;
+ for (var integer j:=0; j<sizeof(lastReceived.options); j:=j+1) {
+ var CoAP_Options v_currentReceivedOption := lastReceived.options[j];
+ if (match(v_currentReceivedOption, v_currentExpectedOption)) {
+ optionCheck := true;
+ }
+ }
+ if (not optionCheck) {
+ log("CHECK: Option mismatch!");
+ log("EXPECTED: ",v_currentExpectedOption);
+ log("RECEIVED: ",lastReceived.options);
+ optionsCheck := false;
+ }
+ }
+ if (not optionsCheck) {
+ return false;
+ }
+ }
+ }
+ else {
+ 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_CoAP_Peer_saveLocationPath()
+ runs on IFW_COAP_CT
+ {
+ ctx.locationPath := {};
+
+ for (var integer i:=0; i<sizeof(lastReceived.options); i:=i+1)
+ {
+ if (ischosen(lastReceived.options[i].location_path))
+ {
+ ctx.locationPath[sizeof(ctx.locationPath)] := lastReceived.options[i].location_path;
+ }
+ }
+ }
+
+ function f_CoAP_Peer_addUriPath()
+ runs on IFW_COAP_CT
+ {
+ for (var integer i:=0; i<sizeof(ctx.locationPath); i:=i+1)
+ {
+ msgToSend.options[sizeof(msgToSend.options)] :=
+ {
+ uri_path := ctx.locationPath[i]
+ }
+ }
+ }
+
+ function f_COAP_getMsgLength(in octetstring stream, inout ro_integer args)
+ return integer
+ {
+ return lengthof(stream);
+ // Only for UDP
+ // For TCP other frameing is needed (see IETF: COAP mapping to TCP);
+ }
+
+ function f_COAP_isRequest(in CoAP_ReqResp p_msg)
+ return boolean
+ {
+ if (p_msg.header.code.class == 0) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+}
diff --git a/IFW_CoAP_Peer_TestSteps.ttcn b/IFW_CoAP_Peer_TestSteps.ttcn
new file mode 100644
index 0000000..fac9476
--- /dev/null
+++ b/IFW_CoAP_Peer_TestSteps.ttcn
@@ -0,0 +1,172 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IFW_CoAP_Peer_TestSteps.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IFW_CoAP_Peer_TestSteps
+{
+ import from IoT_FT_Framework_Definitions all;
+ import from IFW_Common all;
+ import from IFW_CoAP_Peer_Definitions all;
+ import from IFW_CoAP_Peer_Functions all;
+ import from CoAP_Types all;
+
+
+ function f_IFW_CoapPeer_init(in integer p_peerIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];
+ if (v_peer == null) { log("CFW: No coap peer found"); return false; }
+ f_isRunningGuard(v_peer);
+
+ v_peer.start(f_CoAP_Peer_init());
+ v_peer.done;
+
+ return true;
+ }
+
+ function f_IFW_CoapPeer_setRemote(in integer p_peerIdx, in charstring p_remoteAddrId) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var NamedHostPort v_addr;
+ if (f_lookupAddress(p_remoteAddrId, v_addr))
+ {
+ var CoapContext v_ctx;
+ f_IFW_CoapPeer_getContext(p_peerIdx, v_ctx);
+ v_ctx.remoteHost := v_addr.hostName;
+ v_ctx.remotePort := v_addr.portNumber;
+
+ f_IFW_CoapPeer_setContext(p_peerIdx, v_ctx);
+ }
+ return true;
+ }
+
+ function f_IFW_CoapPeer_getContext(in integer p_peerIdx, out CoapContext p_coapContext) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];
+ if (v_peer == null) { log("CFW: No user found"); return false; }
+ f_isRunningGuard(v_peer);
+
+ v_peer.start(f_CoAP_Peer_getContext());
+ v_peer.done(CoapContext:?) -> value p_coapContext;
+
+ return true;
+ }
+
+ function f_IFW_CoapPeer_setContext(in integer p_peerIdx, in CoapContext p_coapContext) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];
+ if (v_peer == null) { log("CFW: No user found"); return false; }
+ f_isRunningGuard(v_peer);
+
+ v_peer.start(f_CoAP_Peer_setContext(p_coapContext));
+ v_peer.done;
+
+ return true;
+ }
+
+ function f_IFW_CoapPeer_setMessageToSend(
+ in integer p_peerIdx,
+ CoAP_ReqResp p_msg,
+ MID_Generation p_genMid := GENERATE_NEW_MID,
+ Token_Generation p_genToken := USE_GIVEN_TOKEN
+ ) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];
+ if (v_peer == null) { log("CFW: No user found"); return false; }
+ f_isRunningGuard(v_peer);
+
+ if (p_genMid == GENERATE_NEW_MID)
+ {
+ p_msg.header.message_id := mid;
+ mid := mid + 1;
+ p_genMid := USE_GIVEN_MID;
+ }
+
+ v_peer.start(f_CoAP_Peer_setMessageToSend(p_msg, p_genMid, p_genToken));
+ v_peer.done;
+
+ return true;
+ }
+
+ function f_IFW_CoapPeer_send(in integer p_peerIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];
+ if (v_peer == null) { log("CFW: No user found"); return false; }
+ f_isRunningGuard(v_peer);
+
+ v_peer.start(f_CoAP_Peer_send());
+ v_peer.done;
+
+ return true;
+ }
+
+ function f_IFW_CoapPeer_receive(in integer p_peerIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];
+ if (v_peer == null) { log("CFW: No user found"); return false; }
+ f_isRunningGuard(v_peer);
+
+ v_peer.start(f_CoAP_Peer_receive());
+ v_peer.done;
+
+ return true;
+ }
+
+ function f_IFW_CoapPeer_check(in integer p_peerIdx, template CoAP_ReqResp p_msg, MID_Check p_checkMid := CHECK_MID) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var boolean v_ret;
+ var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];
+ if (v_peer == null) { log("CFW: No user found"); return false; }
+ f_isRunningGuard(v_peer);
+
+ v_peer.start(f_CoAP_Peer_check(p_msg, p_checkMid));
+ v_peer.done(ReturnBoolean:?) -> value v_ret;
+
+ return v_ret;
+ }
+
+ function f_IFW_CoapPeer_saveLocationPath(in integer p_peerIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];
+ if (v_peer == null) { log("CFW: No user found"); return false; }
+ f_isRunningGuard(v_peer);
+
+ v_peer.start(f_CoAP_Peer_saveLocationPath());
+ v_peer.done;
+
+ return true;
+ }
+
+ function f_IFW_CoapPeer_addUriPath(in integer p_peerIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_COAP_CT v_peer := coapPeers[p_peerIdx];
+ if (v_peer == null) { log("CFW: No user found"); return false; }
+ f_isRunningGuard(v_peer);
+
+ v_peer.start(f_CoAP_Peer_addUriPath());
+ v_peer.done;
+
+ return true;
+ }
+
+}
diff --git a/IFW_Common.ttcn b/IFW_Common.ttcn
new file mode 100644
index 0000000..e7c0704
--- /dev/null
+++ b/IFW_Common.ttcn
@@ -0,0 +1,196 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IFW_Common.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IFW_Common {
+
+ import from IPL4asp_Types all;
+
+ modulepar
+ {
+ Address_List tsp_addresses := {};
+ }
+
+ type record of integer IntegerList;
+
+ type record of NamedHostPort Address_List;
+
+ type record NamedHostPort
+ {
+ charstring id,
+ charstring hostName,
+ integer portNumber
+ }
+
+ type boolean ReturnBoolean
+ with { extension "done"};
+
+ type record of charstring ro_charstring;
+
+ type component IFW_BASE_CT
+ {
+ var IFW_Logging_Context v_IFW_logging := c_IFW_Logging_Context_init;
+ };
+
+ type record IFW_Logging_Context
+ {
+ IFW_Logging_Params error_,
+ IFW_Logging_Params warning,
+ IFW_Logging_Params debug,
+ IFW_Logging_Params debugv
+ }
+
+ const IFW_Logging_Context c_IFW_Logging_Context_init :=
+ {
+ error_ := { 0, ACTION },
+ warning := { 0, ACTION },
+ debug := { 0, LOG },
+ debugv := { 0, LOG }
+ }
+
+ type record IFW_Logging_Params
+ {
+ integer counter,
+ IFW_Logging_Filter filter
+ }
+
+ type enumerated IFW_Logging_Filter
+ {
+ ACTION, LOG, SILENT
+ }
+
+ function f_isRunningGuard(in IFW_BASE_CT p_comp, in float p_timeout := 10.0)
+ {
+ timer T_wait;
+ if(p_comp.running)
+ {
+ T_wait.start(p_timeout);
+ log(%definitionId
+ & ": waiting for function to stop executing on component "
+ & log2str(p_comp) & ", timeout in "
+ & log2str(p_timeout) & " seconds.");
+ alt
+ {
+ [] p_comp.done
+ {
+ log(%definitionId
+ & ": component " & log2str(p_comp)
+ & " returned done properly after waiting for "
+ & log2str(T_wait.read) & " seconds.");
+ }
+ [] T_wait.timeout
+ {
+ log(%definitionId
+ & ": Stopping function running on component " & log2str(p_comp)
+ & " due to timeout.");
+ p_comp.stop;
+ }
+ [else]
+ {
+ // busy loop to ensure no default altsteps are executed and
+ // unexpectedly ends our alt-statement by not calling 'repeat'
+ // correctly.
+ // v_dummy exists only to avoid busy-loop warning during compilation
+ var integer v_dummy;
+ repeat;
+ }
+ }
+ }
+ }
+
+ function f_checkResult(in Result pl_result)
+ {
+ if (ispresent(pl_result.errorCode))
+ {
+ log("Error: ", pl_result.errorCode, pl_result.os_error_text);
+ setverdict(fail);
+ stop;
+ }
+ }
+
+ function f_lookupAddress(charstring p_id, out NamedHostPort v_addr)
+ return boolean
+ {
+
+ for (var integer i:=0; i<sizeof(tsp_addresses); i:=i+1)
+ {
+ if (tsp_addresses[i].id == p_id)
+ {
+ v_addr := tsp_addresses[i];
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function f_IFW_wait(in float p_timeout)
+ {
+ timer t:=p_timeout;
+ t.start;
+ t.timeout;
+ }
+
+ function f_IFW_log_error(in charstring p_log)
+ runs on IFW_BASE_CT
+ {
+ v_IFW_logging.error_.counter := v_IFW_logging.error_.counter + 1;
+ var charstring v_toLog := "[ERROR]["&int2str(v_IFW_logging.error_.counter)&"]: "&p_log
+ if (v_IFW_logging.error_.filter == ACTION) {
+ action(v_toLog);
+ }
+ else if (v_IFW_logging.error_.filter == LOG) {
+ action(v_toLog);
+ }
+ }
+
+ function f_IFW_log_warning(in charstring p_log)
+ runs on IFW_BASE_CT
+ {
+ v_IFW_logging.warning.counter := v_IFW_logging.warning.counter + 1;
+ var charstring v_toLog := "[WARNING]["&int2str(v_IFW_logging.warning.counter)&"]: "&p_log
+ if (v_IFW_logging.warning.filter == ACTION) {
+ action(v_toLog);
+ }
+ else if (v_IFW_logging.warning.filter == LOG) {
+ action(v_toLog);
+ }
+ }
+
+ function f_IFW_log_debug(in charstring p_log)
+ runs on IFW_BASE_CT
+ {
+ v_IFW_logging.debug.counter := v_IFW_logging.debug.counter + 1;
+ var charstring v_toLog := "[DEBUG]: "&p_log
+ if (v_IFW_logging.debug.filter == ACTION) {
+ action(v_toLog);
+ }
+ else if (v_IFW_logging.debug.filter == LOG) {
+ action(v_toLog);
+ }
+ }
+
+ function f_IFW_log_verbose(in charstring p_log)
+ runs on IFW_BASE_CT
+ {
+ v_IFW_logging.debugv.counter := v_IFW_logging.debugv.counter + 1;
+ var charstring v_toLog := "[DEBUGV]: "&p_log
+ if (v_IFW_logging.debugv.filter == ACTION) {
+ action(v_toLog);
+ }
+ else if (v_IFW_logging.debugv.filter == LOG) {
+ action(v_toLog);
+ }
+ }
+}
diff --git a/IFW_HTTP_Client_Definitions.ttcn b/IFW_HTTP_Client_Definitions.ttcn
new file mode 100644
index 0000000..2264db8
--- /dev/null
+++ b/IFW_HTTP_Client_Definitions.ttcn
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IFW_HTTP_Client_Definitions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IFW_HTTP_Client_Definitions
+{
+
+ import from HTTPmsg_Types all;
+ import from IPL4asp_PortType all;
+ import from IFW_Common all;
+
+ type component IFW_HTTP_Client_CT extends IFW_BASE_CT
+ {
+ var HttpClientContext ctx := c_HttpClientContext_empty;
+
+ var HTTPMessage msgToSend := c_HTTPMessage_empty;
+ var HTTPMessage lastReceived := c_HTTPMessage_empty;
+
+ port IPL4asp_PT IPL4_PCO;
+ }
+
+ type record HttpClientContext
+ {
+ integer connId,
+ charstring remoteHost,
+ integer remotePort,
+ charstring localHost,
+ integer localPort,
+ HeaderLines requestHeaders
+ }
+ with { extension "done" }
+
+ const HttpClientContext c_HttpClientContext_empty :=
+ {
+ connId := -1,
+ remoteHost := "",
+ remotePort := -1,
+ localHost := "",
+ localPort := -1,
+ requestHeaders := {}
+ }
+
+ const HTTPMessage c_HTTPMessage_empty :=
+ {
+ erronous_msg :=
+ {
+ client_id := omit,
+ msg := ""
+ }
+ }
+}
diff --git a/IFW_HTTP_Client_Functions.ttcn b/IFW_HTTP_Client_Functions.ttcn
new file mode 100644
index 0000000..2034120
--- /dev/null
+++ b/IFW_HTTP_Client_Functions.ttcn
@@ -0,0 +1,178 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IFW_HTTP_Client_Functions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IFW_HTTP_Client_Functions
+{
+ import from IFW_HTTP_Client_Definitions all;
+ import from HTTPmsg_Types all;
+ import from IPL4asp_Types all;
+ import from IPL4asp_PortType all;
+ import from IFW_Common all;
+ import from TCCMessageHandling_Functions all;
+
+ modulepar
+ {
+ float tsp_HTTP_Client_maxResponseTime := 0.0;
+ }
+
+ function f_HTTP_Client_init() runs on IFW_HTTP_Client_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_HTTP_Client_getMessageLength);
+ f_IPL4_setGetMsgLen(IPL4_PCO, -1, vl_f, {});
+
+ log("Connecting the socket to the remote");
+ vl_result := f_IPL4_connect(IPL4_PCO, ctx.remoteHost, ctx.remotePort, ctx.localHost, ctx.localPort, -1, {tcp := {}}, {{reuseAddress := {enable := true}}});
+ f_checkResult(vl_result);
+ ctx.connId := vl_result.connId;
+
+ log(%definitionId, " finished");
+ }
+
+ function f_HTTP_Client_cleanUp() runs on IFW_HTTP_Client_CT
+ {
+ log(%definitionId, " started");
+ var Result vl_result;
+
+ log("Closing connection");
+ if (ctx.connId >= 0)
+ {
+ vl_result := f_IPL4_close(IPL4_PCO, ctx.connId, {tcp := {}});
+ //f_checkResult(vl_result);
+ }
+
+ log(%definitionId, " finished");
+ }
+
+ function f_HTTP_Client_getContext() runs on IFW_HTTP_Client_CT
+ return HttpClientContext
+ {
+ return ctx;
+ }
+
+ function f_HTTP_Client_setContext(in HttpClientContext p_ctx) runs on IFW_HTTP_Client_CT
+ {
+ ctx := p_ctx;
+ }
+
+ function f_HTTP_Client_setMessageToSend(in HTTPMessage p_msg) runs on IFW_HTTP_Client_CT
+ {
+ msgToSend := p_msg;
+
+ if (ischosen(msgToSend.request))
+ {
+ for (var integer i:=0; i<sizeof(ctx.requestHeaders); i:=i+1)
+ {
+ if (f_HTTP_lookupHeader(ctx.requestHeaders[i].header_name, msgToSend.request.header) == -1)
+ {
+ msgToSend.request.header[sizeof(msgToSend.request.header)] := ctx.requestHeaders[i];
+ }
+ else
+ {
+ log("HTTP Client: Didn't add request header because a header with the same name is already there ", ctx.requestHeaders[i]);
+ }
+ }
+ }
+ }
+
+ function f_HTTP_Client_send() runs on IFW_HTTP_Client_CT
+ {
+ var octetstring v_encoded;
+
+ v_encoded := enc_HTTPMessage(msgToSend);
+
+ var ASP_SendTo vl_send;
+
+ vl_send.connId := ctx.connId;
+ vl_send.remName := ctx.remoteHost;
+ vl_send.remPort := ctx.remotePort;
+ vl_send.proto := {tcp := {}}
+
+ vl_send.msg := v_encoded;
+
+ log("HTTP PDU: ", msgToSend);
+ IPL4_PCO.send(vl_send);
+ }
+
+ function f_HTTP_Client_receive() runs on IFW_HTTP_Client_CT
+ {
+ // Activate default
+
+ timer t_Timeout := tsp_HTTP_Client_maxResponseTime;
+ if (tsp_HTTP_Client_maxResponseTime > 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);
+
+ var HTTPMessage v_httpMsg;
+ dec_HTTPMessage(v_ipl4Recv.msg, v_httpMsg);
+
+ lastReceived := v_httpMsg;
+ log("HTTP PDU: ", lastReceived);
+ }
+ [] IPL4_PCO.receive(ASP_Event:?) -> value v_ipl4Event
+ {
+ log("Received: ", v_ipl4Event);
+ repeat;
+ }
+ [] t_Timeout.timeout
+ {
+ lastReceived := c_HTTPMessage_empty;
+ }
+
+ // Deactivate default
+ }
+ }
+
+ function f_HTTP_Client_check(in template HTTPMessage p_expected) runs on IFW_HTTP_Client_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_HTTP_Client_getMessageLength(in octetstring stream, inout ro_integer args)
+ return integer
+ {
+ return f_TCCMessageHandling_getMessageLength(stream)
+ }
+
+ function f_HTTP_lookupHeader(charstring p_headerName, in HeaderLines p_headers)
+ return integer
+ {
+ for (var integer i:=0; i<sizeof(p_headers); i:=i+1)
+ {
+ if (p_headers[i].header_name == p_headerName) { return i; }
+ }
+ return -1;
+ }
+}
diff --git a/IFW_HTTP_Client_TestSteps.ttcn b/IFW_HTTP_Client_TestSteps.ttcn
new file mode 100644
index 0000000..acf9a0e
--- /dev/null
+++ b/IFW_HTTP_Client_TestSteps.ttcn
@@ -0,0 +1,158 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IFW_HTTP_Client_Functions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IFW_HTTP_Client_TestSteps {
+
+ import from IoT_FT_Framework_Definitions all;
+ import from IFW_Common all;
+ import from IFW_HTTP_Client_Definitions all;
+ import from IFW_HTTP_Client_Functions all;
+ import from HTTPmsg_Types all;
+
+
+ function f_IFW_HttpClient_init(in integer p_clientIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No http client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_HTTP_Client_init());
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_HttpClient_cleanUp(in integer p_clientIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No http client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_HTTP_Client_cleanUp());
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_HttpClient_setRemote(in integer p_clientIdx, in charstring p_remoteAddrId) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var NamedHostPort v_addr;
+ if (f_lookupAddress(p_remoteAddrId, v_addr))
+ {
+ var HttpClientContext v_ctx;
+ f_IFW_HttpClient_getContext(p_clientIdx, v_ctx);
+ v_ctx.remoteHost := v_addr.hostName;
+ v_ctx.remotePort := v_addr.portNumber;
+
+ f_IFW_HttpClient_setContext(p_clientIdx, v_ctx);
+ }
+ return true;
+ }
+
+ function f_IFW_HttpClient_getContext(in integer p_clientIdx, out HttpClientContext p_httpClientContext) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No http client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_HTTP_Client_getContext());
+ v_client.done(HttpClientContext:?) -> value p_httpClientContext;
+
+ return true;
+ }
+
+ function f_IFW_HttpClient_setContext(in integer p_clientIdx, in HttpClientContext p_httpClientContext) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No http client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_HTTP_Client_setContext(p_httpClientContext));
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_HttpClient_setMessageToSend(in integer p_clientIdx, HTTPMessage p_msg) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No http client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_HTTP_Client_setMessageToSend(p_msg));
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_HttpClient_send(in integer p_clientIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No http client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_HTTP_Client_send());
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_HttpClient_receive(in integer p_clientIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No http client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_HTTP_Client_receive());
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_HttpClient_check(in integer p_clientIdx, template HTTPMessage p_msg) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var boolean v_ret;
+ var IFW_HTTP_Client_CT v_client := httpClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No http client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_HTTP_Client_check(p_msg));
+ v_client.done(ReturnBoolean:?) -> value v_ret;
+
+ return v_ret;
+ }
+
+ function f_HTTP_setCommonRequestHeaders(in integer p_clientIdx) runs on IFW_MAIN_CT
+ {
+ var HttpClientContext v_httpClientCtx;
+ f_IFW_HttpClient_getContext(p_clientIdx, v_httpClientCtx);
+ v_httpClientCtx.requestHeaders :=
+ {
+ {"Host", v_httpClientCtx.remoteHost & ":" & int2str(v_httpClientCtx.remotePort)},
+ {"User-Agent", "IoT_FT_Framework"}
+ }
+ f_IFW_HttpClient_setContext(p_clientIdx, v_httpClientCtx);
+ }
+}
diff --git a/IFW_MQTT_Client_Definitions.ttcn b/IFW_MQTT_Client_Definitions.ttcn
new file mode 100644
index 0000000..0b8ddea
--- /dev/null
+++ b/IFW_MQTT_Client_Definitions.ttcn
@@ -0,0 +1,61 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IFW_MQTT_Client_Definitions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IFW_MQTT_Client_Definitions {
+
+ import from MQTT_v3_1_1_Types all;
+ import from IPL4asp_PortType all;
+ import from IFW_Common all;
+
+ type component IFW_MQTT_Client_CT extends IFW_BASE_CT
+ {
+ var MqttClientContext ctx := c_MqttClientContext_empty;
+
+ var MQTT_v3_1_1_ReqResp msgToSend := c_MQTTMessage_empty;
+ var MQTT_v3_1_1_ReqResp lastReceived := c_MQTTMessage_empty;
+
+ port IPL4asp_PT IPL4_PCO;
+ }
+
+ type record MqttClientContext
+ {
+ integer connId,
+ charstring remoteHost,
+ integer remotePort,
+ charstring localHost,
+ integer localPort
+ }
+ with { extension "done" }
+
+ const MqttClientContext c_MqttClientContext_empty :=
+ {
+ connId := -1,
+ remoteHost := "",
+ remotePort := -1,
+ localHost := "",
+ localPort := -1
+ }
+
+ const MQTT_v3_1_1_ReqResp c_MQTTMessage_empty :=
+ {
+ pingreq :=
+ {
+ header := {
+ flags := '0000'B
+ }
+ }
+ }
+}
diff --git a/IFW_MQTT_Client_Functions.ttcn b/IFW_MQTT_Client_Functions.ttcn
new file mode 100644
index 0000000..a392366
--- /dev/null
+++ b/IFW_MQTT_Client_Functions.ttcn
@@ -0,0 +1,153 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IFW_MQTT_Client_Functions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IFW_MQTT_Client_Functions
+{
+ import from IFW_MQTT_Client_Definitions all;
+ import from MQTT_v3_1_1_Types all;
+ import from IPL4asp_Types all;
+ import from IPL4asp_PortType all;
+ import from IFW_Common all;
+ import from MQTT_v3_1_1_IPL4SizeFunction all;
+
+ modulepar
+ {
+ float tsp_MQTT_Client_maxResponseTime := 0.0;
+ }
+
+ function f_MQTT_Client_init() runs on IFW_MQTT_Client_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("Connecting the socket to the remote");
+ vl_result := f_IPL4_connect(IPL4_PCO, ctx.remoteHost, ctx.remotePort, ctx.localHost, ctx.localPort, -1, {tcp := {}}, {{reuseAddress := {enable := true}}});
+ f_checkResult(vl_result);
+ ctx.connId := vl_result.connId;
+
+ log(%definitionId, " finished");
+ }
+
+ function f_MQTT_Client_cleanUp() runs on IFW_MQTT_Client_CT
+ {
+ log(%definitionId, " started");
+ var Result vl_result;
+
+ log("Closing connection");
+ if (ctx.connId >= 0)
+ {
+ vl_result := f_IPL4_close(IPL4_PCO, ctx.connId, {tcp := {}});
+ //f_checkResult(vl_result);
+ }
+
+ log(%definitionId, " finished");
+ }
+
+ function f_MQTT_Client_getContext() runs on IFW_MQTT_Client_CT
+ return MqttClientContext
+ {
+ return ctx;
+ }
+
+ function f_MQTT_Client_setContext(in MqttClientContext p_ctx) runs on IFW_MQTT_Client_CT
+ {
+ ctx := p_ctx;
+ }
+
+ function f_MQTT_Client_setMessageToSend(in MQTT_v3_1_1_ReqResp p_msg) runs on IFW_MQTT_Client_CT
+ {
+ msgToSend := p_msg;
+ }
+
+ function f_MQTT_Client_send() runs on IFW_MQTT_Client_CT
+ {
+ var octetstring v_encoded;
+
+ f_MQTT_v3_1_1_enc({ msg := msgToSend}, v_encoded);
+
+ var ASP_SendTo vl_send;
+
+ vl_send.connId := ctx.connId;
+ vl_send.remName := ctx.remoteHost;
+ vl_send.remPort := ctx.remotePort;
+ vl_send.proto := {tcp := {}}
+
+ vl_send.msg := v_encoded;
+
+ log("MQTT PDU: ", msgToSend);
+ IPL4_PCO.send(vl_send);
+ }
+
+ function f_MQTT_Client_receive() runs on IFW_MQTT_Client_CT
+ {
+ // Activate default
+
+ timer t_Timeout := tsp_MQTT_Client_maxResponseTime;
+ if (tsp_MQTT_Client_maxResponseTime > 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);
+
+ 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);
+ }
+ }
+ [] IPL4_PCO.receive(ASP_Event:?) -> value v_ipl4Event
+ {
+ log("Received: ", v_ipl4Event);
+ repeat;
+ }
+ [] t_Timeout.timeout
+ {
+ lastReceived := c_MQTTMessage_empty;
+ }
+
+ // Deactivate default
+ }
+ }
+
+ function f_MQTT_Client_check(in template MQTT_v3_1_1_ReqResp p_expected) runs on IFW_MQTT_Client_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;
+ }
+}
diff --git a/IFW_MQTT_Client_TestSteps.ttcn b/IFW_MQTT_Client_TestSteps.ttcn
new file mode 100644
index 0000000..95e6006
--- /dev/null
+++ b/IFW_MQTT_Client_TestSteps.ttcn
@@ -0,0 +1,146 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IFW_MQTT_Client_TestSteps.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IFW_MQTT_Client_TestSteps
+{
+ import from IoT_FT_Framework_Definitions all;
+ import from IFW_Common all;
+ import from IFW_MQTT_Client_Definitions all;
+ import from IFW_MQTT_Client_Functions all;
+ import from MQTT_v3_1_1_Types all;
+
+ function f_IFW_MqttClient_init(in integer p_clientIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No mqtt client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_MQTT_Client_init());
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_MqttClient_cleanUp(in integer p_clientIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No mqtt client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_MQTT_Client_cleanUp());
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_MqttClient_setRemote(in integer p_clientIdx, in charstring p_remoteAddrId) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var NamedHostPort v_addr;
+ if (f_lookupAddress(p_remoteAddrId, v_addr))
+ {
+ var MqttClientContext v_ctx;
+ f_IFW_MqttClient_getContext(p_clientIdx, v_ctx);
+ v_ctx.remoteHost := v_addr.hostName;
+ v_ctx.remotePort := v_addr.portNumber;
+
+ f_IFW_MqttClient_setContext(p_clientIdx, v_ctx);
+ }
+ return true;
+ }
+
+ function f_IFW_MqttClient_getContext(in integer p_clientIdx, out MqttClientContext p_mqttClientContext) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No mqtt client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_MQTT_Client_getContext());
+ v_client.done(MqttClientContext:?) -> value p_mqttClientContext;
+
+ return true;
+ }
+
+ function f_IFW_MqttClient_setContext(in integer p_clientIdx, in MqttClientContext p_mqttClientContext) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No mqtt client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_MQTT_Client_setContext(p_mqttClientContext));
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_MqttClient_setMessageToSend(in integer p_clientIdx, MQTT_v3_1_1_ReqResp p_msg) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No mqtt client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_MQTT_Client_setMessageToSend(p_msg));
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_MqttClient_send(in integer p_clientIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No mqtt client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_MQTT_Client_send());
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_MqttClient_receive(in integer p_clientIdx) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No mqtt client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_MQTT_Client_receive());
+ v_client.done;
+
+ return true;
+ }
+
+ function f_IFW_MqttClient_check(in integer p_clientIdx, template MQTT_v3_1_1_ReqResp p_msg) runs on IFW_MAIN_CT
+ return boolean
+ {
+ var boolean v_ret;
+ var IFW_MQTT_Client_CT v_client := mqttClients[p_clientIdx];
+ if (v_client == null) { log("IFW: No mqtt client found"); return false; }
+ f_isRunningGuard(v_client);
+
+ v_client.start(f_MQTT_Client_check(p_msg));
+ v_client.done(ReturnBoolean:?) -> value v_ret;
+
+ return v_ret;
+ }
+
+}
diff --git a/IoT_FT_Framework_Definitions.ttcn b/IoT_FT_Framework_Definitions.ttcn
new file mode 100644
index 0000000..8b0a674
--- /dev/null
+++ b/IoT_FT_Framework_Definitions.ttcn
@@ -0,0 +1,44 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IoT_FT_Framework_Definitions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IoT_FT_Framework_Definitions
+{
+ import from IFW_Common all;
+ import from IFW_CoAP_Peer_Definitions all;
+ import from IFW_HTTP_Client_Definitions all;
+ import from IFW_MQTT_Client_Definitions all;
+
+ type component IFW_MAIN_CT
+ extends IFW_BASE_CT
+ {
+ var IFW_COAP_CT_List coapPeers := {};
+ var IFW_HTTP_Client_CT_List httpClients := {};
+ var IFW_MQTT_Client_CT_List mqttClients := {};
+
+ var integer mid := 0;
+ }
+
+ type record of IFW_COAP_CT IFW_COAP_CT_List;
+ type record of IFW_HTTP_Client_CT IFW_HTTP_Client_CT_List;
+ type record of IFW_MQTT_Client_CT IFW_MQTT_Client_CT_List;
+
+ type enumerated IFW_ComponentTypes
+ {
+ COAP_PEER,
+ HTTP_CLIENT,
+ MQTT_CLIENT
+ }
+}
diff --git a/IoT_FT_Framework_Functions.ttcn b/IoT_FT_Framework_Functions.ttcn
new file mode 100644
index 0000000..d4add85
--- /dev/null
+++ b/IoT_FT_Framework_Functions.ttcn
@@ -0,0 +1,139 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: IoT_FT_Framework_Functions.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module IoT_FT_Framework_Functions
+{
+ import from IoT_FT_Framework_Definitions all;
+ import from IFW_CoAP_Peer_Definitions all;
+ import from IFW_CoAP_Peer_TestSteps all;
+ import from IFW_HTTP_Client_Definitions all;
+ import from IFW_HTTP_Client_TestSteps all;
+ import from IFW_MQTT_Client_Definitions all;
+ import from IFW_MQTT_Client_TestSteps all;
+ import from IFW_Common all;
+
+ function f_IFW_addComponent(IFW_ComponentTypes p_componentType, charstring p_addrId := "")
+ runs on IFW_MAIN_CT
+ return integer
+ {
+ if (p_componentType == COAP_PEER) {
+ return f_IFW_addCoapPeerComponent(p_addrId);
+ }
+ else if (p_componentType == HTTP_CLIENT)
+ {
+ return f_IFW_addHttpClientComponent(p_addrId);
+ }
+ else if (p_componentType == MQTT_CLIENT)
+ {
+ return f_IFW_addMqttClientComponent(p_addrId);
+ }
+
+ return -1;
+ }
+
+ function f_IFW_addCoapPeerComponent(charstring p_addrId := "") runs on IFW_MAIN_CT
+ return integer
+ {
+ var IFW_COAP_CT v_peer := IFW_COAP_CT.create alive;
+ var integer v_peerIdx := sizeof(coapPeers);
+
+ coapPeers[v_peerIdx] := v_peer;
+
+ var NamedHostPort v_addr;
+ if (f_lookupAddress(p_addrId, v_addr))
+ {
+ var CoapContext v_ctx;
+ f_IFW_CoapPeer_getContext(v_peerIdx, v_ctx);
+ v_ctx.localHost := v_addr.hostName;
+ v_ctx.localPort := v_addr.portNumber;
+
+ f_IFW_CoapPeer_setContext(v_peerIdx, v_ctx);
+ }
+
+ return v_peerIdx;
+ }
+
+ function f_IFW_addHttpClientComponent(charstring p_addrId := "") runs on IFW_MAIN_CT
+ return integer
+ {
+ var IFW_HTTP_Client_CT v_client := IFW_HTTP_Client_CT.create alive;
+ var integer v_clientIdx := sizeof(httpClients);
+
+ httpClients[v_clientIdx] := v_client;
+
+ var NamedHostPort v_addr;
+ if (f_lookupAddress(p_addrId, v_addr))
+ {
+ var HttpClientContext v_ctx;
+ f_IFW_HttpClient_getContext(v_clientIdx, v_ctx);
+ v_ctx.localHost := v_addr.hostName;
+ v_ctx.localPort := v_addr.portNumber;
+
+ f_IFW_HttpClient_setContext(v_clientIdx, v_ctx);
+ }
+
+ return v_clientIdx;
+ }
+
+ function f_IFW_addMqttClientComponent(charstring p_addrId := "") runs on IFW_MAIN_CT
+ return integer
+ {
+ var IFW_MQTT_Client_CT v_client := IFW_MQTT_Client_CT.create alive;
+ var integer v_clientIdx := sizeof(mqttClients);
+
+ mqttClients[v_clientIdx] := v_client;
+
+ var NamedHostPort v_addr;
+ if (f_lookupAddress(p_addrId, v_addr))
+ {
+ var MqttClientContext v_ctx;
+ f_IFW_MqttClient_getContext(v_clientIdx, v_ctx);
+ v_ctx.localHost := v_addr.hostName;
+ v_ctx.localPort := v_addr.portNumber;
+
+ f_IFW_MqttClient_setContext(v_clientIdx, v_ctx);
+ }
+
+ return v_clientIdx;
+ }
+
+ function f_IFW_initComponents() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+ mid := float2int(int2float(65000)*rnd());
+
+ for (var integer i:=0; i<sizeof(coapPeers); i:=i+1) {
+ f_IFW_CoapPeer_init(i);
+ }
+ for (var integer i:=0; i<sizeof(httpClients); i:=i+1) {
+ f_IFW_HttpClient_init(i);
+ }
+ for (var integer i:=0; i<sizeof(mqttClients); i:=i+1) {
+ f_IFW_MqttClient_init(i);
+ }
+ }
+
+ function f_IFW_cleanUp() runs on IFW_MAIN_CT
+ {
+ for (var integer i:=0; i<sizeof(httpClients); i:=i+1) {
+ f_IFW_HttpClient_cleanUp(i);
+ }
+ for (var integer i:=0; i<sizeof(mqttClients); i:=i+1) {
+ f_IFW_MqttClient_cleanUp(i);
+ }
+ stop;
+ }
+}
diff --git a/tests/CoapTestSuite_Etsi.ttcn b/tests/CoapTestSuite_Etsi.ttcn
new file mode 100644
index 0000000..4363552
--- /dev/null
+++ b/tests/CoapTestSuite_Etsi.ttcn
@@ -0,0 +1,701 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: CoapTestSuite_Etsi.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module CoapTestSuite_Etsi
+{
+ import from IoT_FT_Framework_Definitions all;
+ import from IoT_FT_Framework_Functions all;
+ import from IFW_CoAP_Peer_TestSteps all;
+ import from CoAP_Types all;
+
+ testcase tc_client_TD_COAP_CORE_01() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_CORE_01_req00));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_CORE_01_rsp01))
+ {
+ setverdict(fail);
+ }
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_01_req00 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_GET,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_path := "test"
+ }
+ },
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_01_rsp01 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Content,
+ message_id := ?
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ content_format := 0
+ }
+ },
+ payload := ?
+ }
+
+ testcase tc_client_TD_COAP_CORE_02() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_CORE_02_req00));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_CORE_02_rsp01))
+ {
+ setverdict(fail);
+ }
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_02_req00 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_POST,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_path := "test"
+ },
+ {
+ content_format := 0
+ }
+ },
+ payload := char2oct("Some payload")
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_02_rsp01 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Created,
+ message_id := ?
+ },
+ token := ''O,
+ options :=
+ {
+ },
+ payload := omit
+ }
+
+ testcase tc_client_TD_COAP_CORE_03() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_CORE_03_req00));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_CORE_03_rsp01))
+ {
+ setverdict(fail);
+ }
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_03_req00 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_PUT,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_path := "test"
+ },
+ {
+ content_format := 0
+ }
+ },
+ payload := char2oct("Some payload")
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_03_rsp01 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Changed,
+ message_id := ?
+ },
+ token := ''O,
+ options :=
+ {
+ },
+ payload := omit
+ }
+
+ testcase tc_client_TD_COAP_CORE_04() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_CORE_04_req00));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_CORE_04_rsp01))
+ {
+ setverdict(fail);
+ }
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_04_req00 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_DELETE,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_path := "test"
+ }
+ },
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_04_rsp01 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Deleted,
+ message_id := ?
+ },
+ token := ''O,
+ options := omit,
+ payload := omit
+ }
+
+ testcase tc_client_TD_COAP_CORE_05() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_CORE_05_req00));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_CORE_05_rsp01))
+ {
+ setverdict(fail);
+ }
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_05_req00 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := NON_CONFIRMABLE,
+ code := METHOD_GET,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_path := "test"
+ }
+ },
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_05_rsp01 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := NON_CONFIRMABLE,
+ code := RESPONSE_CODE_Content,
+ message_id := ?
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ content_format := 0
+ }
+ },
+ payload := ?
+ }
+
+ testcase tc_client_TD_COAP_CORE_06() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_CORE_06_req00));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_CORE_06_rsp01))
+ {
+ setverdict(fail);
+ }
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_06_req00 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := NON_CONFIRMABLE,
+ code := METHOD_POST,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_path := "test"
+ },
+ {
+ content_format := 0
+ }
+ },
+ payload := char2oct("Some payload")
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_06_rsp01 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := NON_CONFIRMABLE,
+ code := RESPONSE_CODE_Created,
+ message_id := ?
+ },
+ token := ''O,
+ options :=
+ {
+ },
+ payload := omit
+ }
+
+ testcase tc_client_TD_COAP_CORE_07() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_CORE_07_req00));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_CORE_07_rsp01))
+ {
+ setverdict(fail);
+ }
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_07_req00 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := NON_CONFIRMABLE,
+ code := METHOD_PUT,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_path := "test"
+ },
+ {
+ content_format := 0
+ }
+ },
+ payload := char2oct("Some payload")
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_07_rsp01 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := NON_CONFIRMABLE,
+ code := RESPONSE_CODE_Changed,
+ message_id := ?
+ },
+ token := ''O,
+ options :=
+ {
+ },
+ payload := omit
+ }
+
+ testcase tc_client_TD_COAP_CORE_08() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_CORE_08_req00));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_CORE_08_rsp01))
+ {
+ setverdict(fail);
+ }
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_08_req00 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := NON_CONFIRMABLE,
+ code := METHOD_DELETE,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_path := "test"
+ }
+ },
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_CORE_08_rsp01 :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := NON_CONFIRMABLE,
+ code := RESPONSE_CODE_Deleted,
+ message_id := ?
+ },
+ token := ''O,
+ options := omit,
+ payload := omit
+ }
+
+ testcase tc_client_TD_COAP_BLOCK_01() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ var boolean getNext := true;
+ var integer num := 0;
+
+ while (getNext)
+ {
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_BLOCK_01_req00(num)));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+
+ // Check the expected answer
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_BLOCK_01_rsp01(num, ?))) {
+ getNext := false;
+ setverdict(fail);
+ }
+
+ // Check if it is the last
+ if (f_IFW_CoapPeer_check(client, t_client_TD_COAP_BLOCK_01_rsp01(num, false))) {
+ getNext := false;
+ }
+
+ num := num + 1;
+ }
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_BLOCK_01_req00(integer p_num) :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_GET,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_path := "large"
+ },
+ {
+ block2 := {
+ num := p_num,
+ m := false,
+ szx := 2
+ }
+ }
+ },
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_BLOCK_01_rsp01(template integer p_num, template boolean p_m) :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Content,
+ message_id := ?
+ },
+ token := ''O,
+ options := {
+ {
+ block2 := {
+ num := p_num,
+ m := p_m,
+ szx := 2
+ }
+ }
+ },
+ payload := ?
+ }
+
+
+
+ testcase tc_client_TD_COAP_OBS_01() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_OBS_01_register));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_OBS_01_registered))
+ {
+ setverdict(fail);
+ }
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_OBS_01_notification, DO_NOT_CHECK_MID))
+ {
+ setverdict(fail);
+ }
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_OBS_01_acknowledgement), USE_LAST_RECEIVED_MID);
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_TD_COAP_OBS_01_notification, DO_NOT_CHECK_MID))
+ {
+ setverdict(fail);
+ }
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_TD_COAP_OBS_01_reset), USE_LAST_RECEIVED_MID);
+ f_IFW_CoapPeer_send(client);
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_OBS_01_register :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_GET,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_path := "obs"
+ },
+ {
+ observe := 0
+ }
+ },
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_OBS_01_registered :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Content,
+ message_id := ?
+ },
+ token := ''O,
+ options := {
+ {
+ observe := ?
+ }
+ },
+ payload := ?
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_OBS_01_notification :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := RESPONSE_CODE_Content,
+ message_id := ?
+ },
+ token := ''O,
+ options := {
+ {
+ observe := ?
+ }
+ },
+ payload := ?
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_OBS_01_acknowledgement :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := EMPTY_MESSAGE,
+ message_id := 0
+ },
+ token := ''O,
+ options := omit,
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_client_TD_COAP_OBS_01_reset :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := RESET,
+ code := EMPTY_MESSAGE,
+ message_id := 0
+ },
+ token := ''O,
+ options := omit,
+ payload := omit
+ }
+
+ control
+ {
+ execute(tc_client_TD_COAP_CORE_01());
+ execute(tc_client_TD_COAP_CORE_02());
+ execute(tc_client_TD_COAP_CORE_03());
+ execute(tc_client_TD_COAP_CORE_04());
+ execute(tc_client_TD_COAP_CORE_05());
+ execute(tc_client_TD_COAP_CORE_06());
+ execute(tc_client_TD_COAP_CORE_07());
+ execute(tc_client_TD_COAP_CORE_08());
+ execute(tc_client_TD_COAP_BLOCK_01());
+ execute(tc_client_TD_COAP_OBS_01());
+ }
+
+}
diff --git a/tests/CoapTestSuite_Fw.ttcn b/tests/CoapTestSuite_Fw.ttcn
new file mode 100644
index 0000000..2c9bf13
--- /dev/null
+++ b/tests/CoapTestSuite_Fw.ttcn
@@ -0,0 +1,163 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: CoapTestSuite_Fw.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module CoapTestSuite_Fw
+{
+
+ import from IoT_FT_Framework_Definitions all;
+ import from IoT_FT_Framework_Functions all;
+ import from IFW_CoAP_Peer_TestSteps all;
+ import from CoAP_Types all;
+
+ testcase tc_example() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+ var integer server := f_IFW_addComponent(COAP_PEER, "server");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+ f_IFW_CoapPeer_setRemote(server, "client");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_coap));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(server);
+ if (not f_IFW_CoapPeer_check(server, valueof(t_coap)))
+ {
+ setverdict(fail);
+ }
+ }
+
+ testcase tc_client() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_coap));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_coap))
+ {
+ setverdict(fail);
+ }
+ }
+
+ template CoAP_ReqResp t_coap :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_GET,
+ message_id := 0
+ },
+ token := ''O,
+ options := omit,
+ payload := omit
+ }
+
+ testcase tc_block_encdec() runs on IFW_MAIN_CT
+ {
+ var template CoAP_Message t_msg;
+
+ log("1 byte long block options");
+ f_test_encdec(t_coap_block1(1, true, 1));
+ f_test_encdec(t_coap_block2(2, false, 3));
+
+ log("2 bytes long block options");
+ f_test_encdec(t_coap_block1(16, true, 1));
+ f_test_encdec(t_coap_block2(17, false, 3));
+
+ log("3 bytes long block options");
+ f_test_encdec(t_coap_block1(1024, true, 1));
+ f_test_encdec(t_coap_block2(1025, false, 3));
+ }
+
+ function f_test_encdec(template CoAP_Message p_msg) {
+ var octetstring v_enc;
+ var CoAP_Message v_dec;
+
+ f_CoAP_enc(valueof(p_msg), v_enc);
+
+ log("Encoded: ", v_enc);
+
+ f_CoAP_dec(v_enc, v_dec);
+
+ if (not match(v_dec, p_msg)) {
+ setverdict(fail);
+ }
+ else {
+ setverdict(pass);
+ }
+ }
+
+ template CoAP_Message t_coap_block1(integer p_num, boolean p_m, integer p_szx) :=
+ {
+ msg := {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_GET,
+ message_id := 0
+ },
+ token := ''O,
+ options := {
+ {
+ block1 := {
+ num := p_num,
+ m := p_m,
+ szx := p_szx
+ }
+ }
+ },
+ payload := omit
+ }
+ }
+
+ template CoAP_Message t_coap_block2(integer p_num, boolean p_m, integer p_szx) :=
+ {
+ msg := {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_GET,
+ message_id := 0
+ },
+ token := ''O,
+ options := {
+ {
+ block2 := {
+ num := p_num,
+ m := p_m,
+ szx := p_szx
+ }
+ }
+ },
+ payload := omit
+ }
+ }
+}
diff --git a/tests/LeshanTestSuite.ttcn b/tests/LeshanTestSuite.ttcn
new file mode 100644
index 0000000..fe3470b
--- /dev/null
+++ b/tests/LeshanTestSuite.ttcn
@@ -0,0 +1,322 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: LeshanTestSuite.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module LeshanTestSuite
+{
+ import from IoT_FT_Framework_Definitions all;
+ import from IoT_FT_Framework_Functions all;
+ import from IFW_CoAP_Peer_TestSteps all;
+ import from IFW_HTTP_Client_Definitions all;
+ import from IFW_HTTP_Client_TestSteps all;
+ import from CoAP_Types all;
+ import from HTTPmsg_Types all;
+ import from LightweightM2M_Types all;
+ import from LightweightM2M_CoAP_Binding all;
+
+ testcase tc_Leshan_checkHttpInterface() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer http_client := f_IFW_addComponent(HTTP_CLIENT, "http_client");
+
+ f_IFW_HttpClient_setRemote(http_client, "http_server");
+
+ f_IFW_initComponents();
+
+ f_HTTP_setCommonRequestHeaders(http_client);
+
+ f_IFW_HttpClient_setMessageToSend(http_client, valueof(t_HTTP_request("GET", "/api/objectspecs")));
+ f_IFW_HttpClient_send(http_client);
+
+ f_IFW_HttpClient_receive(http_client);
+ f_handleVerdict(f_IFW_HttpClient_check(http_client, tr_HTTP_response(200)));
+
+ f_IFW_cleanUp();
+ }
+
+ testcase tc_COAP_register() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer iot_client := f_IFW_addComponent(COAP_PEER, "iot_client");
+ var integer http_client := f_IFW_addComponent(HTTP_CLIENT, "http_client");
+
+ f_IFW_CoapPeer_setRemote(iot_client, "coap_server");
+ f_IFW_HttpClient_setRemote(http_client, "http_server");
+
+ f_IFW_initComponents();
+
+ f_COAP_register(iot_client);
+
+ f_HTTP_setCommonRequestHeaders(http_client);
+
+ f_IFW_HttpClient_setMessageToSend(http_client,
+ valueof(t_HTTP_request("GET", "/api/clients/"&"client_"&int2str(iot_client)))
+ );
+ f_IFW_HttpClient_send(http_client);
+
+ f_IFW_HttpClient_receive(http_client);
+ f_handleVerdict(f_IFW_HttpClient_check(http_client, tr_HTTP_response(200)));
+
+ f_COAP_deregister(iot_client);
+
+ f_IFW_cleanUp();
+ }
+
+ testcase tc_COAP_read() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer iot_client := f_IFW_addComponent(COAP_PEER, "iot_client");
+ var integer http_client := f_IFW_addComponent(HTTP_CLIENT, "http_client");
+
+ f_IFW_CoapPeer_setRemote(iot_client, "coap_server");
+ f_IFW_HttpClient_setRemote(http_client, "http_server");
+
+ f_IFW_initComponents();
+
+ f_COAP_register(iot_client);
+
+ f_HTTP_setCommonRequestHeaders(http_client);
+
+ f_IFW_HttpClient_setMessageToSend(http_client,
+ valueof(t_HTTP_request(
+ "GET",
+ "/api/clients/"&"client_"&int2str(iot_client)&"/1/0/6?format=JSON")
+ )
+ );
+ f_IFW_HttpClient_send(http_client);
+
+ f_IFW_CoapPeer_receive(iot_client);
+ f_handleVerdict(f_IFW_CoapPeer_check(iot_client, tr_COAP_READ_req));
+
+ f_IFW_CoapPeer_setMessageToSend(iot_client,
+ valueof(t_COAP_READ_resp),
+ USE_LAST_RECEIVED_MID,
+ USE_LAST_RECEIVED_TOKEN
+ );
+ f_IFW_CoapPeer_send(iot_client);
+
+ f_IFW_HttpClient_receive(http_client);
+ f_handleVerdict(f_IFW_HttpClient_check(http_client, tr_HTTP_response(200)))
+
+ f_COAP_deregister(iot_client);
+
+ f_IFW_cleanUp();
+ }
+
+ template CoAP_ReqResp tr_COAP_READ_req :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_GET,
+ message_id := ?
+ },
+ token := ?,
+ options :=
+ {
+ { uri_path := "1" },
+ { uri_path := "0" },
+ { uri_path := "6" },
+ { accept := 1543 }
+ },
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_COAP_READ_resp :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Content,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ content_format := 1543
+ }
+ },
+ payload := char2oct("{\"e\":[{\"n\":\"\",\"bv\":true}]}")
+ }
+
+ template LWM2M_PDU tr_LWM2M_READ_req :=
+ {
+ Read_ := {
+ path := { 1, 0, 6 },
+ accept := { 1543 }
+ }
+ }
+
+ template LWM2M_PDU t_LWM2M_READ_resp :=
+ {
+ Response := {
+ location := {},
+ code := 205,
+ contentFormat := 1543,
+ resources := {
+ {
+ id := -1,
+ objId := -1,
+ objInstId := -1,
+ val := { boolValue := true }
+ }
+ }
+ }
+ }
+
+ template HTTPMessage t_HTTP_request(in charstring p_method, in charstring p_uri) :=
+ {
+ request :=
+ {
+ client_id := omit,
+ method := "GET",
+ uri := p_uri,
+ version_major := 1,
+ version_minor := 1,
+ header :=
+ {
+ {"Accept", "application/json, text/plain, */*"},
+ {"Accept-Language", "en-US,en;q=0.5"},
+ {"Accept-Encoding", "gzip, deflate"},
+ {"Connection", "keep-alive"}
+ },
+ body := ""
+ }
+ }
+
+ template HTTPMessage tr_HTTP_response(in template integer p_respCode) :=
+ {
+ response :=
+ {
+ client_id := *,
+ version_major := ?,
+ version_minor := ?,
+ statuscode := p_respCode,
+ statustext := ?,
+ header := ?,
+ body := ?
+ }
+ }
+
+ function f_COAP_register(in integer p_clientIdx) runs on IFW_MAIN_CT
+ {
+ var CoAP_ReqResp v_coap_encoded;
+
+ f_enc_LWM2M_to_COAP(valueof(t_LwM2M_register(p_clientIdx)), v_coap_encoded);
+ f_IFW_CoapPeer_setMessageToSend(p_clientIdx, v_coap_encoded);
+ f_IFW_CoapPeer_send(p_clientIdx);
+
+ f_IFW_CoapPeer_receive(p_clientIdx);
+ f_handleVerdict(f_IFW_CoapPeer_check(p_clientIdx, t_COAP_registered));
+ f_IFW_CoapPeer_saveLocationPath(p_clientIdx);
+ }
+
+ template LWM2M_PDU t_LwM2M_register(in integer p_clientIdx) :=
+ {
+ Register :=
+ {
+ endpointClientName := "client_"&int2str(p_clientIdx),
+ lifetime := 60,
+ version := omit,
+ bindingMode := U,
+ smsNumber := omit,
+ objectsAndObjectInstances :=
+ {
+ {0, 0, omit},
+ {1, 0, omit},
+ {3, 0, omit}
+ }
+ }
+ }
+
+ template CoAP_ReqResp t_COAP_registered :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Created,
+ message_id := ?
+ },
+ token := ''O,
+ options := {},
+ payload := omit
+ }
+
+ template LWM2M_PDU t_LWM2M_response(in template integer p_code) :=
+ {
+ Response :=
+ {
+ location := ?,
+ code := p_code,
+ contentFormat := *,
+ resources := ?
+ }
+ }
+
+ function f_COAP_deregister(in integer p_clientIdx) runs on IFW_MAIN_CT
+ {
+ var CoAP_ReqResp v_coap_encoded;
+
+ f_enc_LWM2M_to_COAP(valueof(t_LwM2M_deregister), v_coap_encoded);
+ f_IFW_CoapPeer_setMessageToSend(p_clientIdx, v_coap_encoded);
+ f_IFW_CoapPeer_addUriPath(p_clientIdx);
+ f_IFW_CoapPeer_send(p_clientIdx);
+
+ f_IFW_CoapPeer_receive(p_clientIdx);
+ f_handleVerdict(f_IFW_CoapPeer_check(p_clientIdx, t_COAP_deregistered));
+ }
+
+ template LWM2M_PDU t_LwM2M_deregister :=
+ {
+ Deregister :=
+ {
+ location := {}
+ }
+ }
+
+ template CoAP_ReqResp t_COAP_deregistered :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Deleted,
+ message_id := ?
+ },
+ token := ''O,
+ options := {},
+ payload := omit
+ }
+
+ function f_handleVerdict(in boolean p_verdict)
+ {
+ if (p_verdict) { setverdict(pass) }
+ else { setverdict(fail) }
+ }
+
+ control
+ {
+ execute(tc_Leshan_checkHttpInterface());
+ execute(tc_COAP_register());
+ execute(tc_COAP_read());
+ }
+}
diff --git a/tests/Lwm2mTestSuite.ttcn b/tests/Lwm2mTestSuite.ttcn
new file mode 100644
index 0000000..97ab0c5
--- /dev/null
+++ b/tests/Lwm2mTestSuite.ttcn
@@ -0,0 +1,291 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: Lwm2mTestSuite.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module Lwm2mTestSuite
+{
+ import from IoT_FT_Framework_Definitions all;
+ import from IoT_FT_Framework_Functions all;
+ import from IFW_CoAP_Peer_TestSteps all;
+ import from CoAP_Types all;
+ import from LightweightM2M_Types all;
+ import from LightweightM2M_CoAP_Binding all;
+
+ testcase tc_client_LightweightM2M_10_int_101_102_103_regdereg() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_LightweightM2M_10_int_101_register));
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_LightweightM2M_10_int_101_registered))
+ {
+ setverdict(fail); stop;
+ }
+ f_IFW_CoapPeer_saveLocationPath(client);
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_LightweightM2M_10_int_102_update));
+ f_IFW_CoapPeer_addUriPath(client);
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_LightweightM2M_10_int_102_updated))
+ {
+ setverdict(fail); stop;
+ }
+
+ f_IFW_CoapPeer_setMessageToSend(client, valueof(t_client_LightweightM2M_10_int_103_deregister));
+ f_IFW_CoapPeer_addUriPath(client);
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_LightweightM2M_10_int_103_deregistered))
+ {
+ setverdict(fail); stop;
+ }
+ }
+
+ template CoAP_ReqResp t_client_LightweightM2M_10_int_101_register :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_POST,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_path := "rd"
+ },
+ {
+ content_format := 40
+ },
+ {
+ uri_query := "ep=client1"
+ },
+ {
+ uri_query := "lt=60"
+ },
+ {
+ uri_query := "b=U"
+ }
+ },
+ payload := char2oct("</0/0>,</1/0>,</3/0>")
+ }
+
+ template CoAP_ReqResp t_client_LightweightM2M_10_int_101_registered :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Created,
+ message_id := ?
+ },
+ token := ''O,
+ options := {},
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_client_LightweightM2M_10_int_102_update :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_PUT,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ {
+ uri_query := "lt=60"
+ },
+ {
+ uri_query := "b=U"
+ }
+ },
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_client_LightweightM2M_10_int_102_updated :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Changed,
+ message_id := ?
+ },
+ token := ''O,
+ options := {},
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_client_LightweightM2M_10_int_103_deregister :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := CONFIRMABLE,
+ code := METHOD_DELETE,
+ message_id := 0
+ },
+ token := ''O,
+ options :=
+ {
+ },
+ payload := omit
+ }
+
+ template CoAP_ReqResp t_client_LightweightM2M_10_int_103_deregistered :=
+ {
+ header :=
+ {
+ version := 1,
+ msg_type := ACKNOWLEDGEMENT,
+ code := RESPONSE_CODE_Deleted,
+ message_id := ?
+ },
+ token := ''O,
+ options := {},
+ payload := omit
+ }
+
+ testcase tc_client_LightweightM2M_10_int_101_102_103_regdereg_lwm2mPDU() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var CoAP_ReqResp v_coap_encoded;
+
+ var integer client := f_IFW_addComponent(COAP_PEER, "client");
+
+ f_IFW_CoapPeer_setRemote(client, "server");
+
+ f_IFW_initComponents();
+
+ f_enc_LWM2M_to_COAP(valueof(t_client_LightweightM2M_10_int_101_register_lwm2mPDU), v_coap_encoded);
+ f_IFW_CoapPeer_setMessageToSend(client, v_coap_encoded);
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_LightweightM2M_10_int_101_registered))
+ {
+ setverdict(fail); stop;
+ }
+ f_IFW_CoapPeer_saveLocationPath(client);
+
+ f_enc_LWM2M_to_COAP(valueof(t_client_LightweightM2M_10_int_102_update_lwm2mPDU), v_coap_encoded);
+ f_IFW_CoapPeer_setMessageToSend(client, v_coap_encoded);
+ f_IFW_CoapPeer_addUriPath(client);
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_LightweightM2M_10_int_102_updated))
+ {
+ setverdict(fail); stop;
+ }
+
+ f_enc_LWM2M_to_COAP(valueof(t_client_LightweightM2M_10_int_103_deregister_lwm2mPDU), v_coap_encoded);
+ f_IFW_CoapPeer_setMessageToSend(client, v_coap_encoded);
+ f_IFW_CoapPeer_addUriPath(client);
+ f_IFW_CoapPeer_send(client);
+
+ f_IFW_CoapPeer_receive(client);
+ if (not f_IFW_CoapPeer_check(client, t_client_LightweightM2M_10_int_103_deregistered))
+ {
+ setverdict(fail); stop;
+ }
+ }
+
+ template LWM2M_PDU t_client_LightweightM2M_10_int_101_register_lwm2mPDU :=
+ {
+ Register :=
+ {
+ endpointClientName := "client1",
+ lifetime := 60,
+ version := omit,
+ bindingMode := U,
+ smsNumber := omit,
+ objectsAndObjectInstances :=
+ {
+ {0, 0, omit},
+ {1, 0, omit},
+ {3, 0, omit}
+ }
+ }
+ }
+
+ template LWM2M_PDU t_client_LightweightM2M_10_int_102_update_lwm2mPDU :=
+ {
+ Update :=
+ {
+ location := {},
+ lifetime := 60,
+ bindingMode := U,
+ smsNumber := omit,
+ objectsAndObjectInstances := {}
+ }
+ }
+
+ template LWM2M_PDU t_client_LightweightM2M_10_int_103_deregister_lwm2mPDU :=
+ {
+ Deregister :=
+ {
+ location := {}
+ }
+ }
+
+ testcase tc_json_encdec() runs on IFW_MAIN_CT
+ {
+ log("data: ",t_res);
+
+ var octetstring v_encoded := f_enc_LwM2M_JSON_Resources(valueof(t_res));
+
+ log("encoded: ", oct2char(v_encoded), "\n", v_encoded);
+
+ var LwM2M_JSON_Resources v_decoded := f_dec_LwM2M_JSON_Resources(v_encoded);
+
+ if (match(v_decoded, t_res)) { setverdict(pass)}
+ else { setverdict(fail) }
+ }
+
+ template LwM2M_JSON_Resources t_res :=
+ {
+ e := {
+ { n := "0", sv := "sg" },
+ { n := "7/1", bv := true },
+ { n := "11", v := 4.0 }
+ }
+ }
+
+ control
+ {
+ execute(tc_client_LightweightM2M_10_int_101_102_103_regdereg());
+ execute(tc_client_LightweightM2M_10_int_101_102_103_regdereg_lwm2mPDU());
+ execute(tc_json_encdec());
+ }
+}
diff --git a/tests/MqttTestSuite_Interop.ttcn b/tests/MqttTestSuite_Interop.ttcn
new file mode 100644
index 0000000..d6e26ee
--- /dev/null
+++ b/tests/MqttTestSuite_Interop.ttcn
@@ -0,0 +1,346 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2000-2017 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: MqttTestSuite_Interop.ttcn
+// Description:
+// Rev: R1A
+// Prodnr: LPA 108 661
+// Updated: 2017-09-01
+// Contact: http://ttcn.ericsson.se
+///////////////////////////////////////////////////////////////////////////////
+module MqttTestSuite_Interop
+{
+ import from IoT_FT_Framework_Definitions all;
+ import from IoT_FT_Framework_Functions all;
+ import from IFW_MQTT_Client_TestSteps all;
+ import from MQTT_v3_1_1_Types all;
+
+ testcase tc_Mqtt_client_connect_disconnect() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer mqtt_client := f_IFW_addComponent(MQTT_CLIENT, "mqtt_client");
+
+ f_IFW_MqttClient_setRemote(mqtt_client, "mqtt_server");
+
+ f_IFW_initComponents();
+
+ f_connect(mqtt_client);
+
+ f_disconnect(mqtt_client);
+
+ f_IFW_cleanUp();
+ }
+
+ testcase tc_Mqtt_client_subscribe() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer mqtt_client := f_IFW_addComponent(MQTT_CLIENT, "mqtt_client");
+
+ f_IFW_MqttClient_setRemote(mqtt_client, "mqtt_server");
+
+ f_IFW_initComponents();
+
+ f_connect(mqtt_client);
+
+ f_IFW_MqttClient_setMessageToSend(mqtt_client, valueof(t_subscribe("#", 2, AT_MOST_ONCE_DELIVERY)));
+ f_IFW_MqttClient_send(mqtt_client);
+
+ f_IFW_MqttClient_receive(mqtt_client);
+ f_handleVerdict(f_IFW_MqttClient_check(mqtt_client, tr_suback({0}, 2)));
+
+ f_disconnect(mqtt_client);
+
+ f_IFW_cleanUp();
+ }
+
+ testcase tc_Mqtt_client_unsubscribe() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer mqtt_client := f_IFW_addComponent(MQTT_CLIENT, "mqtt_client");
+ var integer vl_id := 2;
+
+ f_IFW_MqttClient_setRemote(mqtt_client, "mqtt_server");
+
+ f_IFW_initComponents();
+
+ f_connect(mqtt_client);
+
+ f_subscribe(mqtt_client, "room/topic", vl_id, AT_MOST_ONCE_DELIVERY);
+
+ // Unsubscribe
+ f_IFW_MqttClient_setMessageToSend(mqtt_client, valueof(t_unsubscribe("room/topic", 3)));
+ f_IFW_MqttClient_send(mqtt_client);
+
+ f_IFW_MqttClient_receive(mqtt_client);
+ f_handleVerdict(f_IFW_MqttClient_check(mqtt_client, tr_unsuback(3)));
+
+ f_disconnect(mqtt_client);
+
+ f_IFW_cleanUp();
+ }
+
+ testcase tc_Mqtt_client_publish_qos0() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer mqtt_client_A := f_IFW_addComponent(MQTT_CLIENT, "mqtt_client");
+ var integer mqtt_client_B := f_IFW_addComponent(MQTT_CLIENT, "mqtt_client2");
+
+ var charstring vl_topic := "room/topic";
+ var integer vl_id := 1;
+
+ f_IFW_MqttClient_setRemote(mqtt_client_A, "mqtt_server");
+ f_IFW_MqttClient_setRemote(mqtt_client_B, "mqtt_server");
+
+ f_IFW_initComponents();
+
+ f_connect(mqtt_client_A);
+ f_connect(mqtt_client_B);
+
+ f_subscribe(mqtt_client_B, vl_topic, vl_id, AT_MOST_ONCE_DELIVERY);
+
+ // Publish - QoS 0
+ f_IFW_MqttClient_setMessageToSend(mqtt_client_A,
+ valueof(t_publish(vl_topic, omit, AT_MOST_ONCE_DELIVERY))
+ );
+ f_IFW_MqttClient_send(mqtt_client_A);
+
+ f_IFW_MqttClient_receive(mqtt_client_B);
+ f_handleVerdict(f_IFW_MqttClient_check(mqtt_client_B,
+ t_publish(vl_topic, omit, AT_MOST_ONCE_DELIVERY))
+ );
+
+ f_disconnect(mqtt_client_A);
+ f_disconnect(mqtt_client_B);
+
+ f_IFW_cleanUp();
+ }
+
+ testcase tc_Mqtt_client_publish_qos1() runs on IFW_MAIN_CT
+ {
+ setverdict(pass);
+
+ var integer mqtt_client_A := f_IFW_addComponent(MQTT_CLIENT, "mqtt_client");
+ var integer mqtt_client_B := f_IFW_addComponent(MQTT_CLIENT, "mqtt_client2");
+
+ var charstring vl_topic := "room/topic";
+ var integer vl_id := 1;
+
+ f_IFW_MqttClient_setRemote(mqtt_client_A, "mqtt_server");
+ f_IFW_MqttClient_setRemote(mqtt_client_B, "mqtt_server");
+
+ f_IFW_initComponents();
+
+ f_connect(mqtt_client_A);
+ f_connect(mqtt_client_B);
+
+ f_subscribe(mqtt_client_B, vl_topic, vl_id, AT_MOST_ONCE_DELIVERY);
+
+ // Publish - QoS 0
+ f_IFW_MqttClient_setMessageToSend(mqtt_client_A,
+ valueof(t_publish(vl_topic, vl_id, AT_LEAST_ONCE_DELIVERY))
+ );
+ f_IFW_MqttClient_send(mqtt_client_A);
+
+ f_IFW_MqttClient_receive(mqtt_client_A);
+ f_handleVerdict(f_IFW_MqttClient_check(mqtt_client_A,
+ t_puback(vl_id))
+ );
+
+ f_IFW_MqttClient_receive(mqtt_client_B);
+ f_handleVerdict(f_IFW_MqttClient_check(mqtt_client_B,
+ t_publish(vl_topic, *, AT_MOST_ONCE_DELIVERY))
+ );
+
+ f_disconnect(mqtt_client_A);
+ f_disconnect(mqtt_client_B);
+
+ f_IFW_cleanUp();
+ }
+
+ template MQTT_v3_1_1_ReqResp t_publish(
+ in charstring p_topic,
+ in template integer p_id,
+ in QoS p_qos) :=
+ {
+ publish := {
+ header := {
+ dup_flag := '0'B,
+ qos_level := p_qos,
+ retain_flag := '0'B
+ },
+ topic_name := p_topic,
+ packet_identifier := p_id,
+ payload := char2oct("publish qos 0 payload")
+ }
+ }
+
+ template MQTT_v3_1_1_ReqResp t_puback(
+ in template integer p_id) :=
+ {
+ puback := {
+ header := { flags := '0000'B },
+ packet_identifier := p_id
+ }
+ }
+
+ function f_subscribe(
+ in integer p_client,
+ in charstring p_topic,
+ inout integer p_id,
+ in QoS p_qos)
+ runs on IFW_MAIN_CT
+ {
+ f_IFW_MqttClient_setMessageToSend(p_client, valueof(t_subscribe(p_topic, p_id, p_qos)));
+ f_IFW_MqttClient_send(p_client);
+
+ f_IFW_MqttClient_receive(p_client);
+ f_handleVerdict(f_IFW_MqttClient_check(p_client, tr_suback({?}, p_id)));
+
+ f_nextPacketId(p_id);
+ }
+
+ template MQTT_v3_1_1_ReqResp t_subscribe(
+ in charstring p_topic,
+ in integer p_id,
+ in QoS p_qos) :=
+ {
+ subscribe := {
+ header := { flags := '0010'B },
+ packet_identifier := p_id,
+ payload := {
+ {
+ topic_filter := p_topic,
+ requested_qos := p_qos
+ }
+ }
+ }
+ }
+
+ template MQTT_v3_1_1_ReqResp tr_suback(in template IntegerList p_code, in template integer p_id) :=
+ {
+ suback := {
+ header := { flags := '0000'B },
+ packet_identifier := p_id,
+ payload := {
+ return_code := p_code
+ }
+ }
+ }
+
+ function f_unsubscribe(in integer p_client, in charstring p_topic, inout integer p_id)
+ runs on IFW_MAIN_CT
+ {
+ f_IFW_MqttClient_setMessageToSend(p_client, valueof(t_unsubscribe(p_topic, p_id)));
+ f_IFW_MqttClient_send(p_client);
+
+ f_IFW_MqttClient_receive(p_client);
+ f_handleVerdict(f_IFW_MqttClient_check(p_client, tr_unsuback(p_id)));
+
+ f_nextPacketId(p_id);
+ }
+
+ template MQTT_v3_1_1_ReqResp t_unsubscribe(in charstring p_topic, in integer p_id) :=
+ {
+ unsubscribe := {
+ header := { flags := '0010'B },
+ packet_identifier := p_id,
+ payload := {
+ topic_filter := { p_topic }
+ }
+ }
+ }
+
+ template MQTT_v3_1_1_ReqResp tr_unsuback(in template integer p_id) :=
+ {
+ unsuback := {
+ header := { flags := '0000'B },
+ packet_identifier := p_id
+ }
+ }
+
+ function f_connect(in integer p_client) runs on IFW_MAIN_CT
+ {
+ f_IFW_MqttClient_setMessageToSend(p_client, valueof(t_connect(p_client)));
+ f_IFW_MqttClient_send(p_client);
+
+ f_IFW_MqttClient_receive(p_client);
+ f_handleVerdict(f_IFW_MqttClient_check(p_client, tr_connectAck));
+ }
+
+ function f_disconnect(in integer p_client) runs on IFW_MAIN_CT
+ {
+ f_IFW_MqttClient_setMessageToSend(p_client, valueof(t_disconnect));
+ f_IFW_MqttClient_send(p_client);
+ }
+
+ template MQTT_v3_1_1_ReqResp t_connect(integer p_id) :=
+ {
+ connect_msg := {
+ header := { flags := '0000'B },
+ name := "MQTT",
+ protocol_level := 4,
+ flags := {
+ user_name_flag := '0'B,
+ password_flag := '0'B,
+ will_retain := '0'B,
+ will_qos := AT_MOST_ONCE_DELIVERY,
+ will_flag := '0'B,
+ clean_session := '1'B
+ },
+ keep_alive := 0,
+ payload := {
+ client_identifier := "myclientid_"&int2str(p_id),
+ will_topic := omit,
+ will_message := omit,
+ user_name := omit,
+ password := omit
+ }
+ }
+ }
+
+ template MQTT_v3_1_1_ReqResp tr_connectAck :=
+ {
+ connack := {
+ header := { flags := '0000'B },
+ session_present_flag := '0'B,
+ connect_return_code := 0
+ }
+ }
+
+ template MQTT_v3_1_1_ReqResp t_disconnect :=
+ {
+ disconnect_msg := {
+ header := { flags := '0000'B }
+ }
+ }
+
+ function f_handleVerdict(in boolean p_verdict)
+ {
+ if (p_verdict) { setverdict(pass) }
+ else { setverdict(fail) }
+ }
+
+ function f_nextPacketId(inout integer p_id)
+ {
+ p_id := p_id + 1;
+ }
+
+ control
+ {
+ execute(tc_Mqtt_client_connect_disconnect());
+ execute(tc_Mqtt_client_subscribe());
+ execute(tc_Mqtt_client_unsubscribe());
+ execute(tc_Mqtt_client_publish_qos0());
+ execute(tc_Mqtt_client_publish_qos1());
+ }
+}