| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // Copyright (c) 2000-2021 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_JSON_EncDec.ttcn |
| // Description: |
| // Rev: R1B |
| // Prodnr: CNL 113 859 |
| // Updated: 2021-02-03 |
| // Contact: http://ttcn.ericsson.se |
| /////////////////////////////////////////////////////////////////////////////// |
| module LWM2M_JSON_EncDec |
| { |
| import from LWM2M_JSON_Types all; |
| import from LightweightM2M_Types all; |
| import from TCCConversion_Functions all; |
| |
| modulepar boolean tsp_LWM2M_JSON_EncDec_debug := false; |
| const boolean c_LWM2M_JSON_debugSwitch := false; |
| |
| external function f_enc_LwM2M_JSON_Resources(in LwM2M_JSON_Resources p_res) return octetstring |
| with { extension "prototype(convert) encode(JSON) printing(pretty)" } |
| |
| external function f_dec_LwM2M_JSON_Resources(in octetstring p_res) return LwM2M_JSON_Resources |
| with { extension "prototype(convert) decode(JSON)" } |
| |
| external function f_enc_SenML_JSON_Resources(in SenML_JSON_Resources p_res) return octetstring |
| with { extension "prototype(convert) encode(JSON) printing(pretty)" } |
| |
| external function f_dec_SenML_JSON_Resources(in octetstring p_res) return SenML_JSON_Resources |
| with { extension "prototype(convert) decode(JSON)" } |
| |
| /////////////////// ENCODING |
| |
| function f_enc_LwM2M_Resources_to_LwM2M_JSON(in LwM2M_Resource_List p_res_list) return octetstring |
| { |
| var charstring v_result := |
| "{\"bn\":\"/\",\n"& |
| "\"e\":[\n"; |
| |
| for (var integer i:=0; i<sizeof(p_res_list); i:=i+1) |
| { |
| v_result := v_result & f_enc_LwM2M_Resource_to_LwM2M_JSON(p_res_list[i]); |
| if (i != sizeof(p_res_list)-1) { v_result := v_result & ",\n"} |
| else { v_result := v_result & "\n"} |
| } |
| |
| v_result := v_result & "]}"; |
| |
| return char2oct(v_result); |
| } |
| |
| function f_enc_LwM2M_Resource_to_LwM2M_JSON(in LwM2M_Resource p_res) return charstring |
| { |
| var charstring v_ret := ""; |
| |
| // "n":"65/3/3" |
| var charstring v_name := ""; |
| |
| if (p_res.objId != -1) { |
| v_name := v_name & int2str(p_res.objId) |
| } |
| if (p_res.objInstId != -1) { |
| if (lengthof(v_name) > 0) { v_name := v_name & "/" & int2str(p_res.objInstId) } |
| else { v_name := int2str(p_res.objInstId) } |
| } |
| if (p_res.id != -1) { |
| if (lengthof(v_name) > 0) { v_name := v_name & "/" & int2str(p_res.id) } |
| else { v_name := int2str(p_res.id) } |
| } |
| v_name := "\"n\":\"" & v_name & "\""; |
| |
| var charstring v_value := ""; |
| |
| if (ischosen(p_res.val.intValue)) { |
| v_value := "\"v\":" & int2str(p_res.val.intValue); |
| } |
| else if (ischosen(p_res.val.floatValue)) { |
| v_value := "\"v\":" & float2str(p_res.val.floatValue); |
| } |
| else if (ischosen(p_res.val.strValue)) { |
| v_value := "\"sv\":" & "\"" & p_res.val.strValue & "\""; |
| } |
| else if (ischosen(p_res.val.boolValue)) { |
| //v_value := "\"bv\":" & "\"" & f_bool2str(p_res.val.boolValue) & "\""; |
| v_value := "\"bv\":" & f_bool2str(p_res.val.boolValue); |
| } |
| else if (ischosen(p_res.val.opaqueValue)) { |
| v_value := "\"ov\":" & "\"" & oct2str(p_res.val.opaqueValue) & "\""; |
| } |
| |
| v_ret := "{" & v_name & ", " & v_value & "}"; |
| |
| return v_ret; |
| } |
| |
| function f_enc_LwM2M_Resources_to_JSON_create(in LwM2M_Resource_List p_res_list) return octetstring |
| { |
| var charstring v_result := "{\"bn\":\"/"; |
| |
| if(sizeof(p_res_list) == 1) |
| { |
| v_result := |
| v_result & int2str(p_res_list[0].objId) |
| & "/" & int2str(p_res_list[0].objInstId) & "/" |
| & int2str(p_res_list[0].id) & "\"\n" & "\"e\":[\n"; |
| |
| for (var integer i:=0; i<sizeof(p_res_list); i:=i+1) |
| { |
| v_result := v_result & f_enc_LwM2M_Resource_to_JSON_create(p_res_list[i], FULL_PATH); |
| if (i != sizeof(p_res_list)-1) { v_result := v_result & ",\n"} |
| else { v_result := v_result & "\n"} |
| } |
| } |
| else if(f_match_instanceIds(p_res_list)) |
| { |
| v_result := |
| v_result & int2str(p_res_list[0].objId) |
| & "/" & int2str(p_res_list[0].objInstId) & "/" & "\n" & "\"e\":[\n"; |
| |
| for (var integer i:=0; i<sizeof(p_res_list); i:=i+1) |
| { |
| v_result := v_result & f_enc_LwM2M_Resource_to_JSON_create(p_res_list[i], OBJECT_OBJECTINSTANCE); |
| if (i != sizeof(p_res_list)-1) { v_result := v_result & ",\n"} |
| else { v_result := v_result & "\n"} |
| } |
| } |
| else if(f_match_objIds(p_res_list)) |
| { |
| v_result := |
| v_result & int2str(p_res_list[0].objId) & "/" & "\n" & "\"e\":[\n"; |
| for (var integer i:=0; i<sizeof(p_res_list); i:=i+1) |
| { |
| v_result := v_result & f_enc_LwM2M_Resource_to_JSON_create(p_res_list[i], JUST_OBJECT); |
| if (i != sizeof(p_res_list)-1) { v_result := v_result & ",\n"} |
| else { v_result := v_result & "\n"} |
| } |
| } |
| else |
| { |
| v_result := v_result & "\n" & "\"e\":[\n"; |
| for (var integer i:=0; i<sizeof(p_res_list); i:=i+1) |
| { |
| v_result := v_result & f_enc_LwM2M_Resource_to_JSON_create(p_res_list[i], EMPTY); |
| if (i != sizeof(p_res_list)-1) { v_result := v_result & ",\n"} |
| else { v_result := v_result & "\n"} |
| } |
| } |
| v_result := v_result & "]}"; |
| |
| //log("v_result_str: ", v_result, "v_result_oct: ", char2oct(v_result)); |
| |
| return char2oct(v_result); |
| } |
| |
| function f_enc_LwM2M_Resource_to_JSON_create(in LwM2M_Resource p_res, in JSON_BaseName_Type p_t) return charstring |
| { |
| var charstring v_ret := ""; |
| if(p_t == FULL_PATH) { |
| v_ret := "\"n\":\"\""; |
| } |
| else if(p_t == OBJECT_OBJECTINSTANCE) { |
| v_ret := "\"n\":\"" & int2str(p_res.id) & "\"" |
| } |
| else if(p_t == JUST_OBJECT){ |
| v_ret := "\"n\":\"" & int2str(p_res.id) & "/" |
| & int2str(p_res.objInstId) & "\"" |
| } |
| else { |
| v_ret := "\"n\":\"" & int2str(p_res.objId) & "/" |
| & int2str(p_res.objInstId) & "/" |
| & int2str(p_res.id) & "\"" |
| } |
| |
| var charstring v_value := ""; |
| |
| if (ischosen(p_res.val.intValue)) { |
| v_value := "\"v\":" & int2str(p_res.val.intValue); |
| } |
| else if (ischosen(p_res.val.floatValue)) { |
| v_value := "\"v\":" & float2str(p_res.val.floatValue); |
| } |
| else if (ischosen(p_res.val.strValue)) { |
| v_value := "\"sv\":" & "\"" & p_res.val.strValue & "\""; |
| } |
| else if (ischosen(p_res.val.boolValue)) { |
| v_value := "\"bv\":" & "\"" & f_bool2str(p_res.val.boolValue) & "\""; |
| } |
| else if (ischosen(p_res.val.opaqueValue)) { |
| v_value := "\"ov\":" & "\"" & oct2str(p_res.val.opaqueValue) & "\""; |
| } |
| else { return "" } |
| |
| v_ret := "{" & v_ret & ", " & v_value & "}"; |
| |
| return v_ret; |
| } |
| |
| function f_enc_LwM2M_Resources_to_SenML_JSON(in LwM2M_Resource_List p_res_list) return octetstring |
| { |
| var charstring v_result := |
| "["; |
| |
| for (var integer i:=0; i<sizeof(p_res_list); i:=i+1) |
| { |
| v_result := v_result & f_enc_LwM2M_Resource_to_SenML_JSON(p_res_list[i]); |
| if (i != sizeof(p_res_list)-1) { v_result := v_result & ",\n"} |
| else { v_result := v_result & "\n"} |
| } |
| |
| v_result := v_result & "]"; |
| |
| return char2oct(v_result); |
| } |
| |
| function f_enc_LwM2M_Resource_to_SenML_JSON(in LwM2M_Resource p_res) return charstring |
| { |
| var charstring v_ret := ""; |
| |
| // "n":"/65/3/3" |
| var charstring v_name := "/"; |
| |
| if (p_res.objId != -1) { |
| v_name := v_name & int2str(p_res.objId) |
| } |
| if (p_res.objInstId != -1) { |
| if (lengthof(v_name) > 0) { v_name := v_name & "/" & int2str(p_res.objInstId) } |
| else { v_name := int2str(p_res.objInstId) } |
| } |
| if (p_res.id != -1) { |
| if (lengthof(v_name) > 0) { v_name := v_name & "/" & int2str(p_res.id) } |
| else { v_name := int2str(p_res.id) } |
| } |
| v_name := "\"n\":\"" & v_name & "\""; |
| |
| var charstring v_value := ""; |
| |
| if (ischosen(p_res.val.intValue)) { |
| v_value := "\"v\":" & int2str(p_res.val.intValue); |
| } |
| else if (ischosen(p_res.val.floatValue)) { |
| v_value := "\"v\":" & float2str(p_res.val.floatValue); |
| } |
| else if (ischosen(p_res.val.strValue)) { |
| v_value := "\"vs\":" & "\"" & p_res.val.strValue & "\""; |
| } |
| else if (ischosen(p_res.val.boolValue)) { |
| //v_value := "\"bv\":" & "\"" & f_bool2str(p_res.val.boolValue) & "\""; |
| v_value := "\"vb\":" & f_bool2str(p_res.val.boolValue); |
| } |
| else if (ischosen(p_res.val.opaqueValue)) { |
| v_value := "\"vd\":" & "\"" & oct2str(p_res.val.opaqueValue) & "\""; |
| } |
| else { return "" } |
| |
| v_ret := "{" & v_name & ", " & v_value & "}"; |
| |
| return v_ret; |
| } |
| |
| function f_bool2str(in boolean p_b) return charstring { if (p_b) {return "true"} else {return "false" }} |
| |
| |
| /////////////////// DECODING |
| |
| function f_dec_LwM2M_Resources_from_LwM2M_JSON(in octetstring p_payload, inout LwM2M_Resource_List p_resources) |
| return boolean |
| { |
| var LwM2M_JSON_Resources v_decoded_json := f_dec_LwM2M_JSON_Resources(p_payload); |
| //f_JSON_debug(log2str("Decoded json: ", v_decoded_json)); |
| p_resources := f_LwM2M_JSON_Resources_toResources(v_decoded_json); |
| return true; |
| } |
| |
| function f_LwM2M_JSON_Resources_toResources(in LwM2M_JSON_Resources p_json_res_list) |
| return LwM2M_Resource_List |
| { |
| var LwM2M_Resource_List v_ret := {}; |
| var charstring v_bn := ""; |
| |
| if (ispresent(p_json_res_list.bn)) { v_bn := p_json_res_list.bn; } |
| |
| for (var integer i:=0; i<sizeof(p_json_res_list.e); i:=i+1) { |
| v_ret[sizeof(v_ret)] := f_LwM2M_JSON_Resource_toResource(p_json_res_list.e[i], v_bn); |
| } |
| |
| return v_ret; |
| } |
| |
| function f_LwM2M_JSON_Resource_toResource(in LwM2M_JSON_Resource p_json_res, in charstring p_bn) |
| return LwM2M_Resource |
| { |
| var LwM2M_Resource v_ret := c_LwM2M_Resource_init; |
| |
| var charstring vl_id := p_bn & p_json_res.n & "/"; |
| var TCC_Conversion_ch_list vl_ids := f_substr_all_tokens(vl_id, "", "/"); |
| |
| if (sizeof(vl_ids)>=4) |
| { |
| f_isNumber(vl_ids[1], v_ret.objId); |
| f_isNumber(vl_ids[2], v_ret.objInstId); |
| f_isNumber(vl_ids[3], v_ret.id); |
| } |
| |
| if (ispresent(p_json_res.bv)) { v_ret.val.boolValue := p_json_res.bv; } |
| if (ispresent(p_json_res.sv)) { v_ret.val.strValue := p_json_res.sv; } |
| if (ispresent(p_json_res.v)) { |
| if (ischosen(p_json_res.v.f)) { v_ret.val.floatValue := p_json_res.v.f; } |
| else if (ischosen(p_json_res.v.i)) { v_ret.val.intValue := p_json_res.v.i; } |
| } |
| if (ispresent(p_json_res.ov)) { v_ret.val.opaqueValue := str2oct(p_json_res.ov); } |
| |
| return v_ret; |
| } |
| |
| function f_dec_LwM2M_Resources_from_SenML_JSON(in octetstring p_payload, inout LwM2M_Resource_List p_resources) |
| return boolean |
| { |
| var SenML_JSON_Resources v_decoded_json := f_dec_SenML_JSON_Resources(p_payload); |
| //f_JSON_debug(log2str("Decoded json: ", v_decoded_json)); |
| p_resources := f_SenML_JSON_Resources_toResources(v_decoded_json); |
| return true; |
| } |
| |
| function f_SenML_JSON_Resources_toResources(in SenML_JSON_Resources p_json_res_list) |
| return LwM2M_Resource_List |
| { |
| var LwM2M_Resource_List v_ret := {}; |
| |
| var charstring v_bn := ""; |
| |
| for (var integer i:=0; i<sizeof(p_json_res_list); i:=i+1) { |
| v_ret[sizeof(v_ret)] := f_SenML_JSON_Resource_toResource(p_json_res_list[i], v_bn); |
| } |
| |
| return v_ret; |
| } |
| |
| function f_SenML_JSON_Resource_toResource(in SenML_JSON_Resource p_json_res, inout charstring p_bn) |
| return LwM2M_Resource |
| { |
| var LwM2M_Resource v_ret := c_LwM2M_Resource_init; |
| |
| if (ispresent(p_json_res.bn)) |
| { |
| p_bn := p_json_res.bn; |
| } |
| |
| var charstring vl_id := p_bn & p_json_res.n & "/"; |
| var TCC_Conversion_ch_list vl_ids := f_substr_all_tokens(vl_id, "", "/"); |
| |
| if (sizeof(vl_ids)>=4) |
| { |
| f_isNumber(vl_ids[1], v_ret.objId); |
| f_isNumber(vl_ids[2], v_ret.objInstId); |
| f_isNumber(vl_ids[3], v_ret.id); |
| } |
| |
| if (ispresent(p_json_res.vb)) { v_ret.val.boolValue := p_json_res.vb; } |
| if (ispresent(p_json_res.vs)) { v_ret.val.strValue := p_json_res.vs; } |
| if (ispresent(p_json_res.v)) { |
| if (ischosen(p_json_res.v.f)) { v_ret.val.floatValue := p_json_res.v.f; } |
| else if (ischosen(p_json_res.v.i)) { v_ret.val.intValue := p_json_res.v.i; } |
| } |
| if (ispresent(p_json_res.vd)) { v_ret.val.opaqueValue := str2oct(p_json_res.vd); } |
| |
| return v_ret; |
| } |
| |
| function f_match_instanceIds(in LwM2M_Resource_List p_res_list) return boolean |
| { |
| var integer firstObjId := p_res_list[0].objId; |
| var integer firstObjInstId := p_res_list[0].objInstId; |
| |
| for (var integer i:=1; i<sizeof(p_res_list); i:=i+1){ |
| if(p_res_list[i].objId != firstObjId or p_res_list[i].objInstId != firstObjInstId) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| function f_match_objIds(in LwM2M_Resource_List p_res_list) return boolean |
| { |
| var integer firstObjId := p_res_list[0].objId; |
| |
| for (var integer i:=1; i<sizeof(p_res_list); i:=i+1){ |
| if(p_res_list[i].objId != firstObjId) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| function f_JSON_debug(in @lazy charstring pl_message) |
| { |
| if (c_LWM2M_JSON_debugSwitch) { |
| if (tsp_LWM2M_JSON_EncDec_debug) { log(pl_message); } |
| } |
| } |
| } |