blob: 3d4651c3041142b3218ad46ebf5c2d4fdc875539 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2019 Ericsson Telecom AB
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v2.0
// which accompanies this distribution, and is available at
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
///////////////////////////////////////////////////////////////////////////////
// File: LWM2M_TLV_EncDec.ttcn
// Description:
// Rev: R1A
// Prodnr: CNL 113 859
// Updated: 2019-08-27
// Contact: http://ttcn.ericsson.se
///////////////////////////////////////////////////////////////////////////////
module LWM2M_TLV_EncDec
{
import from LWM2M_TLV_Types all;
import from LightweightM2M_Types all;
modulepar boolean tsp_LWM2M_TLV_EncDec_debug := false;
const boolean c_LWM2M_TLV_debugSwitch := false;
function f_dec_LwM2M_TLV_Resources(in octetstring p_raw_msg) return LWM2M_TLV_Resources {
var integer v_procedBits := 0;
var bitstring v_msgInBits := oct2bit(p_raw_msg);
var LWM2M_TLV_Resources v_ret_tlvs := {};
while(v_procedBits != lengthof(v_msgInBits)) {
v_ret_tlvs[sizeof(v_ret_tlvs)] := f_dec_LwM2M_TLV_Resource(v_msgInBits, v_procedBits);
}
return v_ret_tlvs;
}
//TODO: Multiple resource TLV
function f_dec_LwM2M_TLV_Resource(in bitstring p_raw_msg, inout integer p_firstBit) return LWM2M_TLV_Resource
{
var LWM2M_TLV_Resource v_ret_tlv;
f_TLV_debug("-----------------------------TLV Decoding-----------------------------");
f_dec_TLV_Type(substr(p_raw_msg, p_firstBit, 8), v_ret_tlv.tlv_type);
p_firstBit := p_firstBit + 8;
v_ret_tlv.id := bit2int(substr(p_raw_msg, p_firstBit, v_ret_tlv.tlv_type.length_of_id))
p_firstBit := p_firstBit + 8;
if(v_ret_tlv.tlv_type.type_of_length == 0) {
v_ret_tlv.length_of_value := v_ret_tlv.tlv_type.length_of_value;
}
else{
v_ret_tlv.length_of_value := bit2int(substr(p_raw_msg, p_firstBit, v_ret_tlv.tlv_type.type_of_length)) * 8;
p_firstBit := p_firstBit + v_ret_tlv.tlv_type.type_of_length;
}
f_TLV_debug(log2str("tlv_type: ", v_ret_tlv));
var bitstring v_rawValue := substr(p_raw_msg, p_firstBit, v_ret_tlv.length_of_value);
//f_TLV_debug(log2str("v_rawValue: ", v_rawValue));
if(v_ret_tlv.tlv_type.type_of_id == OBJECT_INSTANCE or v_ret_tlv.tlv_type.type_of_id == MULTIPLE_RESOURCE){
f_TLV_debug("Decoding internal TLV");
var integer v_tmpLength := 0;
var integer idx := 0;
while(v_tmpLength != lengthof(v_rawValue)){
v_ret_tlv.tlv_value.internal_tlvs[idx] := f_dec_LwM2M_TLV_Resource(v_rawValue, v_tmpLength);
idx := idx + 1;
}
p_firstBit := p_firstBit + v_ret_tlv.length_of_value;
}
else {
v_ret_tlv.tlv_value.raw_resource_value := v_rawValue;
p_firstBit := p_firstBit + v_ret_tlv.length_of_value;
}
f_TLV_debug(log2str("Decoded TLV: ", v_ret_tlv));
return v_ret_tlv;
}
function f_dec_TLV_Type(in bitstring p_bitstring, inout TLV_Type p_tlv_type)
{
p_tlv_type.length_of_value := bit2int(p_bitstring[5] & p_bitstring[6] & p_bitstring[7]) * 8;
p_tlv_type.type_of_length := bit2int(p_bitstring[3] & p_bitstring[4]) * 8;
p_tlv_type.length_of_id := bit2int(p_bitstring[2]) * 8 + 8;
var bitstring v_tmp := p_bitstring[0] & p_bitstring[1]
if(v_tmp == '00'B) {
p_tlv_type.type_of_id := OBJECT_INSTANCE;
}
else if(v_tmp == '01'B) {
p_tlv_type.type_of_id := RESOURCE_INSTANCE;
}
else if(v_tmp == '10'B) {
p_tlv_type.type_of_id := MULTIPLE_RESOURCE;
}
else {
p_tlv_type.type_of_id := VALUE;
}
}
function f_dec_resource_value(in bitstring p_raw_value, in Value_Type p_vType, inout LwM2M_ResourceValue p_res_value)
{
if(p_vType == STRING) {
var octetstring tmp := bit2oct(p_raw_value);
p_res_value.strValue := "";
for(var integer i := 0; i < lengthof(tmp); i := i+1){
p_res_value.strValue := p_res_value.strValue & int2char(oct2int(tmp[i]));
}
}
else if(p_vType == INTEGER) {
var integer tmp := decvalue(p_raw_value, p_res_value.intValue);
}
else if(p_vType == FLOAT) {
f_TLV_debug("Float type not yet handled");
//TODO: float
p_res_value.floatValue := 0.0
}
else if(p_vType == OPAQUE) {
p_res_value.opaqueValue := bit2oct(p_raw_value);
}
else if(p_vType == BOOL) {
p_res_value.boolValue := int2bool(bit2int(p_raw_value));
}
}
function f_LwM2M_TLV_Resources_toResources(in LWM2M_TLV_Resources p_tlv_res, Location p_loc) return LwM2M_Resource_List
{
var LwM2M_Resource_List v_resource_list;
f_TLV_debug(log2str("p_tlv_res: ", p_tlv_res));
f_TLV_debug(log2str("p_loc: ", p_loc));
for(var integer i := 0; i < sizeof(p_tlv_res); i := i+1)
{
var LWM2M_TLV_Resource v_tmpTLV := p_tlv_res[i];
v_resource_list[i].objId := str2int(oct2char(unichar2oct(p_loc[0])));
if(sizeof(p_loc) >= 2){
v_resource_list[i].objInstId := str2int(oct2char(unichar2oct(p_loc[1])));
}
v_resource_list[i].observed := false;
v_resource_list[i].dataSample := omit;
if(v_tmpTLV.tlv_type.type_of_id == VALUE or v_tmpTLV.tlv_type.type_of_id == RESOURCE_INSTANCE)
{
v_resource_list[i].id := v_tmpTLV.id;
var ObjectPath v_path := { v_resource_list[i].objId, v_resource_list[i].objInstId, v_resource_list[i].id }
f_TLV_debug(log2str("Path: ", v_path));
//v_resource_list[i].val.strValue := "";
f_dec_resource_value(v_tmpTLV.tlv_value.raw_resource_value, f_get_ResourceType(v_path), v_resource_list[i].val);
}
else if(v_tmpTLV.tlv_type.type_of_id == OBJECT_INSTANCE)
{
v_resource_list[i].objInstId := v_tmpTLV.id;
if(v_tmpTLV.tlv_value.internal_tlvs[0].tlv_type.type_of_id == RESOURCE_INSTANCE)
{
var LwM2M_Resource_List v_tmp_resource_list;
v_tmp_resource_list := f_LwM2M_TLV_Resources_toResources(v_tmpTLV.tlv_value.internal_tlvs, p_loc);
for(var integer j := 0; j < sizeof(v_tmp_resource_list); j := j+ 1) {
v_resource_list[i + j] := v_tmp_resource_list[j];
}
}
else
{
var LwM2M_Resource_List v_tmp_resource_list;
v_tmp_resource_list := f_LwM2M_TLV_Resources_toResources(v_tmpTLV.tlv_value.internal_tlvs, p_loc);
}
}
else if(v_tmpTLV.tlv_type.type_of_id == MULTIPLE_RESOURCE)
{
var LwM2M_Resource_List v_tmp_resource_list;
v_tmp_resource_list := f_LwM2M_TLV_Resources_toResources(v_tmpTLV.tlv_value.internal_tlvs, p_loc);
for(var integer j := 0; j < sizeof(v_tmp_resource_list); j := j+ 1) {
v_resource_list[i + j] := v_tmp_resource_list[j];
}
}
}
f_TLV_debug(log2str("v_resource_list: ", v_resource_list));
return v_resource_list;
}
function f_get_ResourceType(in ObjectPath p_path) return Value_Type
{
var integer v_objId := p_path.objectId;
var integer v_resId := p_path.resourceId;
for(var integer i := 0; i < sizeof(c_LWM2M_Resource_Types); i:= i+1)
{
if(c_LWM2M_Resource_Types[i].objId == v_objId)
{
for(var integer j := 0; j < sizeof(c_LWM2M_Resource_Types[i].resType); j := j+1)
{
if(c_LWM2M_Resource_Types[i].resType[j].resId == v_resId) {
f_TLV_debug(log2str("Resource type found: ", c_LWM2M_Resource_Types[i].resType[j].valType));
return c_LWM2M_Resource_Types[i].resType[j].valType;
}
}
}
}
f_TLV_debug("Resource type not found.");
return OPAQUE;
}
function int2bool(integer p_int) return boolean
{
return (p_int mod 2 == 1)
}
function f_TLV_debug(in @lazy charstring pl_message)
{
if (c_LWM2M_TLV_debugSwitch) {
if (tsp_LWM2M_TLV_EncDec_debug) { log(pl_message); }
}
}
}