From d5dab0b21f0ba98ddfab58cf0311e19be2987793 Mon Sep 17 00:00:00 2001 From: Jani Suonpera Date: Wed, 5 Apr 2017 09:36:04 +0300 Subject: [PATCH 1/7] Add support for TLV binary integer If resource type is INTEGER then value will convert to 64-bit binary buffer. Format is two's complement big endian word. See, OMA-TS-LightweightM2M-V1_0-20170208-A, Appendix C, data Types, Integer, TLV Format. --- mbed-client/m2mresourceinstance.h | 2 +- source/include/m2mtlvserializer.h | 2 + source/m2mresourceinstance.cpp | 10 ++-- source/m2mtlvserializer.cpp | 52 ++++++++++++++++++- .../utest/stub/m2mresourceinstance_stub.cpp | 10 ++-- 5 files changed, 59 insertions(+), 17 deletions(-) diff --git a/mbed-client/m2mresourceinstance.h b/mbed-client/m2mresourceinstance.h index e927ecad..ef159650 100644 --- a/mbed-client/m2mresourceinstance.h +++ b/mbed-client/m2mresourceinstance.h @@ -199,7 +199,7 @@ friend class M2MResource; * \brief Converts a value to integer and returns it. Note: Conversion * errors are not detected. */ - int get_value_int(); + int64_t get_value_int() const; /** * Get the value as a string object. No encoding/charset conversions diff --git a/source/include/m2mtlvserializer.h b/source/include/m2mtlvserializer.h index a31a0486..686f852c 100644 --- a/source/include/m2mtlvserializer.h +++ b/source/include/m2mtlvserializer.h @@ -95,4 +95,6 @@ private : static void serialize_id(uint16_t id, uint32_t &size, uint8_t *id_ptr); static void serialize_length(uint32_t length, uint32_t &size, uint8_t *length_ptr); + + template static void set_value_int(T value, uint8_t *buffer, uint32_t &size); }; diff --git a/source/m2mresourceinstance.cpp b/source/m2mresourceinstance.cpp index 3bd7b8ac..72d19e81 100644 --- a/source/m2mresourceinstance.cpp +++ b/source/m2mresourceinstance.cpp @@ -337,17 +337,13 @@ void M2MResourceInstance::get_value(uint8_t *&value, uint32_t &value_length) } } -int M2MResourceInstance::get_value_int() +int64_t M2MResourceInstance::get_value_int() const { int value_int = 0; - // Get the value and convert it into integer. This is not the most - // efficient way, as it takes pointless heap copy to get the zero termination. - uint8_t* buffer = NULL; - uint32_t length; - get_value(buffer,length); + uint8_t* buffer = _value; + if(buffer) { value_int = atoi((const char*)buffer); - free(buffer); } return value_int; } diff --git a/source/m2mtlvserializer.cpp b/source/m2mtlvserializer.cpp index 07a381b2..f3899b19 100644 --- a/source/m2mtlvserializer.cpp +++ b/source/m2mtlvserializer.cpp @@ -126,8 +126,21 @@ bool M2MTLVSerializer::serialize_resource(const M2MResource *resource, uint8_t * { bool success = false; if(resource->name_id() != -1) { - success = serialize_TILV(TYPE_RESOURCE, resource->name_id(), + if ( resource->resource_instance_type() == M2MResourceInstance::INTEGER) { + int64_t valueInt = resource->get_value_int(); + uint32_t buf_size; + /* max len 8 bytes */ + uint8_t buffer[8]; + + // write bytes to big endian order in buffer + set_value_int(valueInt, buffer, buf_size); + success = serialize_TILV(TYPE_RESOURCE, resource->name_id(), + buffer, buf_size, data, size); + } + else { + success = serialize_TILV(TYPE_RESOURCE, resource->name_id(), resource->value(), resource->value_length(), data, size); + } } return success; } @@ -164,9 +177,44 @@ bool M2MTLVSerializer::serialize_multiple_resource(const M2MResource *resource, return success; } +/* See, OMA-TS-LightweightM2M-V1_0-20170208-A, Appendix C, + * Data Types, Integer, TLV Format + * + * This is easy to change to support 8, 16 or 32 interger. */ +template void M2MTLVSerializer::set_value_int(T value, uint8_t *buffer, uint32_t &size) +{ + size = sizeof(value); + + /* write bytes to big endian order in buffer */ + for (uint8_t ind=0;ind> (ind*8)) & 0xFF); + } +} + +template void M2MTLVSerializer::set_value_int(int8_t value, uint8_t *buffer, uint32_t &size); +template void M2MTLVSerializer::set_value_int(int16_t value, uint8_t *buffer, uint32_t &size); +template void M2MTLVSerializer::set_value_int(int32_t value, uint8_t *buffer, uint32_t &size); +template void M2MTLVSerializer::set_value_int(int64_t value, uint8_t *buffer, uint32_t &size); + bool M2MTLVSerializer::serialize_resource_instance(uint16_t id, const M2MResourceInstance *resource, uint8_t *&data, uint32_t &size) { - return serialize_TILV(TYPE_RESOURCE_INSTANCE, id, resource->value(), resource->value_length(), data, size); + bool success; + + if ( resource->resource_instance_type() == M2MResourceInstance::INTEGER) { + int64_t valueInt = resource->get_value_int(); + uint32_t buf_size; + /* max len 8 bytes */ + uint8_t buffer[8]; + + // write bytes to big endian order in buffer + set_value_int(valueInt, buffer, buf_size); + success=serialize_TILV(TYPE_RESOURCE_INSTANCE, id, buffer, buf_size, data, size); + } + else { + success=serialize_TILV(TYPE_RESOURCE_INSTANCE, id, resource->value(), resource->value_length(), data, size); + } + + return success; } bool M2MTLVSerializer::serialize_TILV(uint8_t type, uint16_t id, uint8_t *value, uint32_t value_length, uint8_t *&data, uint32_t &size) diff --git a/test/mbedclient/utest/stub/m2mresourceinstance_stub.cpp b/test/mbedclient/utest/stub/m2mresourceinstance_stub.cpp index aeb611e2..dbe743d8 100755 --- a/test/mbedclient/utest/stub/m2mresourceinstance_stub.cpp +++ b/test/mbedclient/utest/stub/m2mresourceinstance_stub.cpp @@ -170,20 +170,16 @@ void M2MResourceInstance::get_value(uint8_t *&value, uint32_t &value_length) } } -int M2MResourceInstance::get_value_int() +int64_t M2MResourceInstance::get_value_int() const { // Note: this is a copy-paste from the original version, as the tests // set only m2mresourceinstance_stub::value. int value_int = 0; - // Get the value and convert it into integer. This is not the most - // efficient way, as it takes pointless heap copy to get the zero termination. - uint8_t* buffer = NULL; - uint32_t length; - get_value(buffer,length); + uint8_t* buffer = m2mresourceinstance_stub::value; + if(buffer) { value_int = atoi((const char*)buffer); - free(buffer); } return value_int; } From 5ca417de9230917edddb643bd31597ba2ea6628b Mon Sep 17 00:00:00 2001 From: Jani Suonpera Date: Mon, 10 Apr 2017 13:06:19 +0300 Subject: [PATCH 2/7] Change atoi to atoll --- source/m2mresourceinstance.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/m2mresourceinstance.cpp b/source/m2mresourceinstance.cpp index 72d19e81..57df2114 100644 --- a/source/m2mresourceinstance.cpp +++ b/source/m2mresourceinstance.cpp @@ -339,11 +339,11 @@ void M2MResourceInstance::get_value(uint8_t *&value, uint32_t &value_length) int64_t M2MResourceInstance::get_value_int() const { - int value_int = 0; + int64_t value_int = 0; uint8_t* buffer = _value; if(buffer) { - value_int = atoi((const char*)buffer); + value_int = atoll((const char*)buffer); } return value_int; } From 0e7590ce844fbb1beb85e19e0304baaf125f6873 Mon Sep 17 00:00:00 2001 From: Jani Suonpera Date: Tue, 11 Apr 2017 14:18:03 +0300 Subject: [PATCH 3/7] Add support for TLV binary boolean --- source/include/m2mtlvserializer.h | 1 + source/m2mtlvserializer.cpp | 47 ++++++++++++++++++------------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/source/include/m2mtlvserializer.h b/source/include/m2mtlvserializer.h index 686f852c..292142fd 100644 --- a/source/include/m2mtlvserializer.h +++ b/source/include/m2mtlvserializer.h @@ -97,4 +97,5 @@ private : static void serialize_length(uint32_t length, uint32_t &size, uint8_t *length_ptr); template static void set_value_int(T value, uint8_t *buffer, uint32_t &size); + template static bool serialize_TLV_binary_int(T *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size); }; diff --git a/source/m2mtlvserializer.cpp b/source/m2mtlvserializer.cpp index f3899b19..59467751 100644 --- a/source/m2mtlvserializer.cpp +++ b/source/m2mtlvserializer.cpp @@ -126,16 +126,9 @@ bool M2MTLVSerializer::serialize_resource(const M2MResource *resource, uint8_t * { bool success = false; if(resource->name_id() != -1) { - if ( resource->resource_instance_type() == M2MResourceInstance::INTEGER) { - int64_t valueInt = resource->get_value_int(); - uint32_t buf_size; - /* max len 8 bytes */ - uint8_t buffer[8]; - - // write bytes to big endian order in buffer - set_value_int(valueInt, buffer, buf_size); - success = serialize_TILV(TYPE_RESOURCE, resource->name_id(), - buffer, buf_size, data, size); + if ( (resource->resource_instance_type() == M2MResourceInstance::INTEGER) || + ( resource->resource_instance_type() == M2MResourceInstance::BOOLEAN)) { + success = serialize_TLV_binary_int(resource, TYPE_RESOURCE, resource->name_id(), data, size); } else { success = serialize_TILV(TYPE_RESOURCE, resource->name_id(), @@ -200,16 +193,10 @@ bool M2MTLVSerializer::serialize_resource_instance(uint16_t id, const M2MResourc { bool success; - if ( resource->resource_instance_type() == M2MResourceInstance::INTEGER) { - int64_t valueInt = resource->get_value_int(); - uint32_t buf_size; - /* max len 8 bytes */ - uint8_t buffer[8]; - - // write bytes to big endian order in buffer - set_value_int(valueInt, buffer, buf_size); - success=serialize_TILV(TYPE_RESOURCE_INSTANCE, id, buffer, buf_size, data, size); - } + if ( (resource->resource_instance_type() == M2MResourceInstance::INTEGER) || + ( resource->resource_instance_type() == M2MResourceInstance::BOOLEAN)) { + success=serialize_TLV_binary_int(resource, TYPE_RESOURCE_INSTANCE, id, data, size); + } else { success=serialize_TILV(TYPE_RESOURCE_INSTANCE, id, resource->value(), resource->value_length(), data, size); } @@ -217,6 +204,26 @@ bool M2MTLVSerializer::serialize_resource_instance(uint16_t id, const M2MResourc return success; } +template bool M2MTLVSerializer::serialize_TLV_binary_int(T *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size) +{ + int64_t valueInt = resource->get_value_int(); + uint32_t buffer_size; + /* max len 8 bytes */ + uint8_t buffer[8]; + + if (resource->resource_instance_type() == M2MResourceInstance::BOOLEAN) { + set_value_int((int8_t)valueInt, buffer, buffer_size); + } + else { + set_value_int(valueInt, buffer, buffer_size); + } + + return serialize_TILV(type, id, buffer, buffer_size, data, size); +} + +template bool M2MTLVSerializer::serialize_TLV_binary_int(const M2MResourceInstance *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size); +template bool M2MTLVSerializer::serialize_TLV_binary_int(const M2MResource *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size); + bool M2MTLVSerializer::serialize_TILV(uint8_t type, uint16_t id, uint8_t *value, uint32_t value_length, uint8_t *&data, uint32_t &size) { uint8_t *tlv = 0; From ae2509c2d114541494da71cafed3d48acbe4fa5e Mon Sep 17 00:00:00 2001 From: Jani Suonpera Date: Wed, 19 Apr 2017 12:54:07 +0300 Subject: [PATCH 4/7] Add support for TLV binary time --- source/m2mtlvserializer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/m2mtlvserializer.cpp b/source/m2mtlvserializer.cpp index 59467751..38649698 100644 --- a/source/m2mtlvserializer.cpp +++ b/source/m2mtlvserializer.cpp @@ -127,7 +127,8 @@ bool M2MTLVSerializer::serialize_resource(const M2MResource *resource, uint8_t * bool success = false; if(resource->name_id() != -1) { if ( (resource->resource_instance_type() == M2MResourceInstance::INTEGER) || - ( resource->resource_instance_type() == M2MResourceInstance::BOOLEAN)) { + (resource->resource_instance_type() == M2MResourceInstance::BOOLEAN) || + (resource->resource_instance_type() == M2MResourceInstance::TIME) ) { success = serialize_TLV_binary_int(resource, TYPE_RESOURCE, resource->name_id(), data, size); } else { @@ -194,7 +195,8 @@ bool M2MTLVSerializer::serialize_resource_instance(uint16_t id, const M2MResourc bool success; if ( (resource->resource_instance_type() == M2MResourceInstance::INTEGER) || - ( resource->resource_instance_type() == M2MResourceInstance::BOOLEAN)) { + (resource->resource_instance_type() == M2MResourceInstance::BOOLEAN) || + (resource->resource_instance_type() == M2MResourceInstance::TIME) ) { success=serialize_TLV_binary_int(resource, TYPE_RESOURCE_INSTANCE, id, data, size); } else { From 7c1bafe101a641799160c00d42ee52b5813976f8 Mon Sep 17 00:00:00 2001 From: Jani Suonpera Date: Mon, 24 Apr 2017 15:53:01 +0300 Subject: [PATCH 5/7] Review fixes --- source/include/m2mtlvserializer.h | 2 +- source/m2mresourceinstance.cpp | 5 ++--- source/m2mtlvserializer.cpp | 4 +--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/source/include/m2mtlvserializer.h b/source/include/m2mtlvserializer.h index 292142fd..c4b20582 100644 --- a/source/include/m2mtlvserializer.h +++ b/source/include/m2mtlvserializer.h @@ -97,5 +97,5 @@ private : static void serialize_length(uint32_t length, uint32_t &size, uint8_t *length_ptr); template static void set_value_int(T value, uint8_t *buffer, uint32_t &size); - template static bool serialize_TLV_binary_int(T *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size); + static bool serialize_TLV_binary_int(const M2MResourceInstance *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size); }; diff --git a/source/m2mresourceinstance.cpp b/source/m2mresourceinstance.cpp index 57df2114..58c9499b 100644 --- a/source/m2mresourceinstance.cpp +++ b/source/m2mresourceinstance.cpp @@ -340,10 +340,9 @@ void M2MResourceInstance::get_value(uint8_t *&value, uint32_t &value_length) int64_t M2MResourceInstance::get_value_int() const { int64_t value_int = 0; - uint8_t* buffer = _value; - if(buffer) { - value_int = atoll((const char*)buffer); + if(_value) { + value_int = atoll((const char*)_value); } return value_int; } diff --git a/source/m2mtlvserializer.cpp b/source/m2mtlvserializer.cpp index 38649698..ba828667 100644 --- a/source/m2mtlvserializer.cpp +++ b/source/m2mtlvserializer.cpp @@ -206,7 +206,7 @@ bool M2MTLVSerializer::serialize_resource_instance(uint16_t id, const M2MResourc return success; } -template bool M2MTLVSerializer::serialize_TLV_binary_int(T *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size) +bool M2MTLVSerializer::serialize_TLV_binary_int(const M2MResourceInstance *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size) { int64_t valueInt = resource->get_value_int(); uint32_t buffer_size; @@ -223,8 +223,6 @@ template bool M2MTLVSerializer::serialize_TLV_binary_int(T *resourc return serialize_TILV(type, id, buffer, buffer_size, data, size); } -template bool M2MTLVSerializer::serialize_TLV_binary_int(const M2MResourceInstance *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size); -template bool M2MTLVSerializer::serialize_TLV_binary_int(const M2MResource *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size); bool M2MTLVSerializer::serialize_TILV(uint8_t type, uint16_t id, uint8_t *value, uint32_t value_length, uint8_t *&data, uint32_t &size) { From d543dc311733cbca511a55dedfc03ae74777e2be Mon Sep 17 00:00:00 2001 From: Jani Suonpera Date: Thu, 27 Apr 2017 11:06:31 +0300 Subject: [PATCH 6/7] Review fixes. --- module.json | 3 +- source/include/m2mtlvserializer.h | 1 - source/m2mtlvserializer.cpp | 29 +++++-------------- .../utest/m2mtlvdeserializer/CMakeLists.txt | 1 + 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/module.json b/module.json index 39447fa7..f899ef22 100644 --- a/module.json +++ b/module.json @@ -8,7 +8,8 @@ "license": "Apache-2.0", "dependencies": { "mbed-client-c": "^5.0.0", - "mbed-trace": ">=0.2.0,<2.0.0" + "mbed-trace": ">=0.2.0,<2.0.0", + "nanostack-libservice": "^3.0.0" }, "targetDependencies": { "arm": { diff --git a/source/include/m2mtlvserializer.h b/source/include/m2mtlvserializer.h index c4b20582..7bd945cf 100644 --- a/source/include/m2mtlvserializer.h +++ b/source/include/m2mtlvserializer.h @@ -96,6 +96,5 @@ private : static void serialize_length(uint32_t length, uint32_t &size, uint8_t *length_ptr); - template static void set_value_int(T value, uint8_t *buffer, uint32_t &size); static bool serialize_TLV_binary_int(const M2MResourceInstance *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size); }; diff --git a/source/m2mtlvserializer.cpp b/source/m2mtlvserializer.cpp index ba828667..73c5e506 100644 --- a/source/m2mtlvserializer.cpp +++ b/source/m2mtlvserializer.cpp @@ -17,6 +17,7 @@ #include "include/nsdllinker.h" #include "mbed-client/m2mconstants.h" #include +#include "common_functions.h" #define TRACE_GROUP "mClt" @@ -171,25 +172,6 @@ bool M2MTLVSerializer::serialize_multiple_resource(const M2MResource *resource, return success; } -/* See, OMA-TS-LightweightM2M-V1_0-20170208-A, Appendix C, - * Data Types, Integer, TLV Format - * - * This is easy to change to support 8, 16 or 32 interger. */ -template void M2MTLVSerializer::set_value_int(T value, uint8_t *buffer, uint32_t &size) -{ - size = sizeof(value); - - /* write bytes to big endian order in buffer */ - for (uint8_t ind=0;ind> (ind*8)) & 0xFF); - } -} - -template void M2MTLVSerializer::set_value_int(int8_t value, uint8_t *buffer, uint32_t &size); -template void M2MTLVSerializer::set_value_int(int16_t value, uint8_t *buffer, uint32_t &size); -template void M2MTLVSerializer::set_value_int(int32_t value, uint8_t *buffer, uint32_t &size); -template void M2MTLVSerializer::set_value_int(int64_t value, uint8_t *buffer, uint32_t &size); - bool M2MTLVSerializer::serialize_resource_instance(uint16_t id, const M2MResourceInstance *resource, uint8_t *&data, uint32_t &size) { bool success; @@ -206,6 +188,9 @@ bool M2MTLVSerializer::serialize_resource_instance(uint16_t id, const M2MResourc return success; } +/* See, OMA-TS-LightweightM2M-V1_0-20170208-A, Appendix C, + * Data Types, Integer, Boolean and TY + * Yime, TLV Format */ bool M2MTLVSerializer::serialize_TLV_binary_int(const M2MResourceInstance *resource, uint8_t type, uint16_t id, uint8_t *&data, uint32_t &size) { int64_t valueInt = resource->get_value_int(); @@ -214,10 +199,12 @@ bool M2MTLVSerializer::serialize_TLV_binary_int(const M2MResourceInstance *resou uint8_t buffer[8]; if (resource->resource_instance_type() == M2MResourceInstance::BOOLEAN) { - set_value_int((int8_t)valueInt, buffer, buffer_size); + buffer_size = 1; + buffer[0] = valueInt; } else { - set_value_int(valueInt, buffer, buffer_size); + buffer_size = 8; + common_write_64_bit(valueInt, buffer); } return serialize_TILV(type, id, buffer, buffer_size, data, size); diff --git a/test/mbedclient/utest/m2mtlvdeserializer/CMakeLists.txt b/test/mbedclient/utest/m2mtlvdeserializer/CMakeLists.txt index 498b1e65..d554cbd6 100644 --- a/test/mbedclient/utest/m2mtlvdeserializer/CMakeLists.txt +++ b/test/mbedclient/utest/m2mtlvdeserializer/CMakeLists.txt @@ -21,6 +21,7 @@ add_executable(m2mtlv target_link_libraries(m2mtlv CppUTest CppUTestExt + nanostack-libservice ) set_target_properties(m2mtlv PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" From 940339e3d1d0646c37b4ec413453b7f0177f06c8 Mon Sep 17 00:00:00 2001 From: Jani Suonpera Date: Thu, 27 Apr 2017 13:23:03 +0300 Subject: [PATCH 7/7] Fix unit tests coverage --- run_unit_tests.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/run_unit_tests.sh b/run_unit_tests.sh index 04939785..f6c734fa 100755 --- a/run_unit_tests.sh +++ b/run_unit_tests.sh @@ -32,7 +32,8 @@ find ./build -name '*.xml' | xargs cp -t ./results/ find ./build/x86-linux-native-coverage/test -name '*.gcno' | xargs cp -t ./coverage/ find ./build/x86-linux-native-coverage/test -name '*.gcda' | xargs cp -t ./coverage/ touch coverage/*.gcda -exclude_files="${PWD}/test/" +exclude_files="${PWD}/test/|${PWD}/yotta_modules*" +#exclude_files2="${PWD}/yotta_modules*" gcovr -r ./ --gcov-filter='.*source*.' --exclude-unreachable-branches --exclude $exclude_files --object-directory ./coverage -x -o ./results/gcovr.xml echo echo "Create coverage document"