blob: 90b9607586866b5caa29b72fd3df76b0db887828 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
//
// 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: LightweightM2M_CoAP_Binding.ttcn
// Description:
// Rev: R1A
// Prodnr: LPA 108 661
// Updated: 2017-09-01
// Contact: http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
module LightweightM2M_CoAP_Binding {
import from LightweightM2M_Types all;
import from CoAP_Types all;
function f_enc_LWM2M_to_COAP(in LWM2M_PDU p_lwm2m, inout CoAP_ReqResp p_coap)
return boolean
{
if (ischosen(p_lwm2m.Register))
{
p_coap := valueof(t_coap_base(METHOD_POST, CONFIRMABLE));
f_addOption(p_coap, { uri_path := "rd" });
f_addOption(p_coap, { content_format := 40 });
f_addOption(p_coap, { uri_query := "ep=" & p_lwm2m.Register.endpointClientName });
if (ispresent(p_lwm2m.Register.lifetime)) {
f_addOption(p_coap, { uri_query := "lt=" & int2str(p_lwm2m.Register.lifetime) });
}
if (ispresent(p_lwm2m.Register.version)) {
f_addOption(p_coap, { uri_query := "lwm2m=" & p_lwm2m.Register.version });
}
if (ispresent(p_lwm2m.Register.bindingMode)) {
f_addOption(p_coap, { uri_query := "b=" & f_BindingMode2str(p_lwm2m.Register.bindingMode) });
}
if (ispresent(p_lwm2m.Register.smsNumber)) {
f_addOption(p_coap, { uri_query := "sms=" & int2str(p_lwm2m.Register.smsNumber) });
}
if (sizeof(p_lwm2m.Register.objectsAndObjectInstances)>0) {
f_addOption(p_coap, { content_format := 40 });
p_coap.payload := char2oct(f_ObjectPathList2str(p_lwm2m.Register.objectsAndObjectInstances));
}
}
else if (ischosen(p_lwm2m.Update))
{
p_coap := valueof(t_coap_base(METHOD_PUT, CONFIRMABLE));
f_addLocation(p_coap, p_lwm2m.Update.location);
if (ispresent(p_lwm2m.Update.lifetime)) {
f_addOption(p_coap, { uri_query := "lt=" & int2str(p_lwm2m.Update.lifetime) });
}
if (ispresent(p_lwm2m.Update.bindingMode)) {
f_addOption(p_coap, { uri_query := "b=" & f_BindingMode2str(p_lwm2m.Update.bindingMode) });
}
if (ispresent(p_lwm2m.Update.smsNumber)) {
f_addOption(p_coap, { uri_query := "sms=" & int2str(p_lwm2m.Update.smsNumber) });
}
if (sizeof(p_lwm2m.Update.objectsAndObjectInstances)>0) {
f_addOption(p_coap, { content_format := 40 });
p_coap.payload := char2oct(f_ObjectPathList2str(p_lwm2m.Update.objectsAndObjectInstances));
}
}
else if (ischosen(p_lwm2m.Deregister))
{
p_coap := valueof(t_coap_base(METHOD_DELETE, CONFIRMABLE));
f_addLocation(p_coap, p_lwm2m.Deregister.location);
}
else if (ischosen(p_lwm2m.Response))
{
p_coap := valueof(t_coap_base(f_int2Code(p_lwm2m.Response.code), ACKNOWLEDGEMENT));
f_addLocation(p_coap, p_lwm2m.Response.location);
if (ispresent(p_lwm2m.Response.contentFormat)) {
f_addContentFormat(p_coap, p_lwm2m.Response.contentFormat);
}
//if (ispresent(p_lwm2m.Response.observe)) {
// f_addOption(p_coap, {observe := p_lwm2m.Response.observe.observe});
// p_coap.token := p_lwm2m.Response.observe.token;
//}
p_coap.payload := f_enc_LwM2M_Resources_to_JSON(p_lwm2m.Response.resources);
}
else
{
log(%definitionId," Unhandled message type in LWM2M_PDU");
return false;
}
return true;
}
function f_dec_COAP_to_LWM2M(in CoAP_ReqResp p_coap, inout LWM2M_PDU p_lwm2m)
return boolean
{
if (p_coap.header.code.class > 0)
{
p_lwm2m := c_LWM2M_Response_init;
p_lwm2m.Response.code := f_Code2int(p_coap.header.code);
if (ispresent(p_coap.options)) {
f_fetchLocation(p_coap.options, p_lwm2m.Response.location);
}
return true;
}
else if (p_coap.header.code == METHOD_GET)
{
p_lwm2m := c_LWM2M_Read_init;
var Location v_loc := {};
f_fetchUriPath(p_coap.options, v_loc);
f_LocationToObjectPath(v_loc, p_lwm2m.Read_.path);
f_fetchAccept(p_coap.options, p_lwm2m.Read_.accept);
var integer p_obs := -1;
/*
if (f_fetchObserve(p_coap.options, p_obs)) {
p_lwm2m.Read_.observe := {
observe := p_obs,
token := p_coap.token
}
}
*/
return true;
}
else if (p_coap.header.code == METHOD_PUT)
{
p_lwm2m := c_LWM2M_Write_init;
var Location v_loc := {};
f_fetchUriPath(p_coap.options, v_loc);
f_LocationToObjectPath(v_loc, p_lwm2m.Write.path);
f_fetchContentFormat(p_coap.options, p_lwm2m.Write.contentFormat);
if (p_lwm2m.Write.contentFormat == 1543)
{ // JSON
var LwM2M_JSON_Resources v_decoded_json;
v_decoded_json := f_dec_LwM2M_JSON_Resources(p_coap.payload);
action("Decoded json: ", v_decoded_json);
p_lwm2m.Write.resources := f_LwM2M_JSON_Resources_toResources(v_decoded_json);
p_lwm2m.Write.resources[0].objId := p_lwm2m.Write.path.objectId;
p_lwm2m.Write.resources[0].objInstId := p_lwm2m.Write.path.objectInstanceId;
p_lwm2m.Write.resources[0].id:= p_lwm2m.Write.path.resourceId;
}
return true;
}
else if (p_coap.header.code == METHOD_POST)
{
var Location v_loc := {};
f_fetchUriPath(p_coap.options, v_loc);
if (sizeof(v_loc)==3)
{ // Execute
p_lwm2m := c_LWM2M_Execute_init;
f_LocationToObjectPath(v_loc, p_lwm2m.Execute.path);
}
else
{ // Create
p_lwm2m := c_LWM2M_Create_init;
f_LocationToObjectPath(v_loc, p_lwm2m.Execute.path);
}
return true;
}
else if (p_coap.header.code == METHOD_DELETE)
{
p_lwm2m := c_LWM2M_Delete_init;
var Location v_loc := {};
f_fetchUriPath(p_coap.options, v_loc);
f_LocationToObjectPath(v_loc, p_lwm2m.Delete.path);
return true;
}
else
{
log(%definitionId," Unrecognized lwm2m pdu in coap ", p_coap);
return false;
}
return false;
}
function f_ObjectPath2str(ObjectPath p_op)
return charstring
{
var charstring v_ret := "</" & int2str(p_op.objectId);
if (ispresent(p_op.objectInstanceId)) {
v_ret := v_ret & "/" & int2str(p_op.objectInstanceId);
}
if (ispresent(p_op.resourceId)) {
v_ret := v_ret & "/" & int2str(p_op.resourceId);
}
return v_ret & ">";
}
function f_ObjectPathList2str(ObjectPath_List p_ol)
return charstring
{
var charstring v_ret := "";
for (var integer i:=0; i<sizeof(p_ol); i:=i+1)
{
v_ret := v_ret & f_ObjectPath2str(p_ol[i]);
if (i != sizeof(p_ol)-1) { v_ret := v_ret & "," }
}
return v_ret;
}
function f_LocationToObjectPath(in Location p_location, inout ObjectPath p_path)
{
if (sizeof(p_location) >= 1) { p_path.objectId := str2int(oct2char(unichar2oct(p_location[0]))); }
else { p_path.objectId := -1 }
if (sizeof(p_location) >= 2) { p_path.objectInstanceId := str2int(oct2char(unichar2oct(p_location[1]))); }
else { p_path.objectInstanceId := omit }
if (sizeof(p_location) >= 3) { p_path.resourceId := str2int(oct2char(unichar2oct(p_location[2]))); }
else { p_path.resourceId := omit }
}
function f_BindingMode2str(BindingMode p_b)
return charstring
{
if (p_b == U) {
return "U";
}
else if (p_b == UQ) {
return "UQ";
}
else if (p_b == S) {
return "S";
}
else if (p_b == SQ) {
return "SQ";
}
else if (p_b == US) {
return "US";
}
else if (p_b == UQS) {
return "UQS";
}
else {
log(%definitionId," Unrecognized binding mode: ", p_b)
return "";
}
return "";
}
function f_addLocation(inout CoAP_ReqResp p_coap, in Location p_location)
{
for (var integer i:=0; i<sizeof(p_location); i:=i+1)
{
f_addOption(p_coap, { uri_path := p_location[i] } );
}
}
function f_addContentFormat(inout CoAP_ReqResp p_coap, in integer p_cf)
{
f_addOption(p_coap, { content_format := p_cf } );
}
function f_addOption(inout CoAP_ReqResp p_coap, in CoAP_Options p_option)
{
if (not ispresent(p_coap.options)) { p_coap.options := {} }
p_coap.options[sizeof(p_coap.options)] := p_option;
}
function f_Code2int(in Code p_code)
return integer
{
return p_code.class*100+p_code.detail;
}
function f_int2Code(in integer p_code)
return Code
{
var Code v_ret;
v_ret.class := p_code/100;
v_ret.detail := p_code rem 100;
return v_ret;
}
function f_fetchLocation(in CoAP_OptionsList p_options, inout Location p_location)
{
for (var integer i:=0; i<sizeof(p_options); i:=i+1) {
if (ischosen(p_options[i].location_path)) {
p_location[sizeof(p_location)] := p_options[i].location_path;
}
}
}
function f_fetchUriPath(in CoAP_OptionsList p_options, inout Location p_location)
{
for (var integer i:=0; i<sizeof(p_options); i:=i+1) {
if (ischosen(p_options[i].uri_path)) {
p_location[sizeof(p_location)] := p_options[i].uri_path;
}
}
}
function f_fetchAccept(in CoAP_OptionsList p_options, inout Integer_List p_accept)
{
for (var integer i:=0; i<sizeof(p_options); i:=i+1) {
if (ischosen(p_options[i].accept)) {
p_accept[sizeof(p_accept)] := p_options[i].accept;
}
}
}
/*
function f_fetchObserve(in CoAP_OptionsList p_options, inout integer p_observe)
return boolean
{
for (var integer i:=0; i<sizeof(p_options); i:=i+1) {
if (ischosen(p_options[i].observe)) {
p_observe := p_options[i].observe;
return true;
}
}
return false;
}
*/
function f_fetchContentFormat(in CoAP_OptionsList p_options, inout integer p_cf)
{
for (var integer i:=0; i<sizeof(p_options); i:=i+1) {
if (ischosen(p_options[i].content_format)) {
p_cf := p_options[i].content_format;
}
}
}
template CoAP_ReqResp t_coap_base(Code p_code, Type p_type) :=
{
header :=
{
version := 1,
msg_type := p_type,
code := p_code,
message_id := 0
},
token := ''O,
options := {},
payload := omit
}
}