From 64e4a81f66355e4dab14a27d8590b040beed4290 Mon Sep 17 00:00:00 2001 From: Yogesh Pande Date: Tue, 6 Sep 2016 19:54:31 +0300 Subject: [PATCH 1/2] Error fixes and some feature enhancement from mbed-client ** mbed-client-c - [v2.9.0](https://github.com/ARMmbed/mbed-client-c/releases/tag/v2.9.0) (05-Sep-2016) [Full Changelog](https://github.com/ARMmbed/mbed-client-c/compare/mbed-os-5.0-rc1...v2.9.0) ** New feature ** - Add option to pass incoming blocks to application instead storing them internally - Added API for deleting one message from resending **Closed issues:** - IOTCLT-1001 - mDS does not sent RST anymore for Client after DELETE /subscriptions ** mbed-client - [v1.15.0](https://github.com/ARMmbed/mbed-client/releases/tag/v1.15.0) (06-Sep-2016) [Full Changelog](https://github.com/ARMmbed/mbed-client/compare/v1.13.4...v1.15.0) ** New feature ** - Introduce new API's to handle block-wise messages in application level **Closed issues:** - IOTCLT-1001 - mDS does not sent RST anymore for Client after DELETE /subscriptions ** mbed-client-classic - mbed-os-5.1.4-rc1 [Full Changelog](https://github.com/ARMmbed/mbed-client-classic/compare/e35a2aeb46bf31bfc53a4379441c0eaab72bd902...586e697365999fc7d976afc8360e26e068f264ae) --- .../mbed-client-classic/CHANGELOG.md | 26 +++ .../source/m2mconnectionhandlerpimpl.cpp | 48 ++--- .../FEATURE_CLIENT/mbed-client/CHANGELOG.md | 78 ++++++++ features/FEATURE_CLIENT/mbed-client/Makefile | 59 ++++++ .../FEATURE_CLIENT/mbed-client/docs/Howto.md | 45 ++++- .../mbed-client/docs/Introduction.md | 6 +- .../mbed-client/mbed-client/functionpointer.h | 166 +++++++++++++++++ .../mbed-client/mbed-client/m2mbase.h | 9 +- .../mbed-client/mbed-client/m2mblockmessage.h | 113 +++++++++++ .../mbed-client/mbed-client/m2mresource.h | 3 +- .../mbed-client/m2mresourceinstance.h | 31 ++- .../FEATURE_CLIENT/mbed-client/mbed_lib.json | 19 +- .../FEATURE_CLIENT/mbed-client/module.json | 2 +- .../source/include/m2mnsdlinterface.h | 2 + .../mbed-client/source/m2mbase.cpp | 3 +- .../mbed-client/source/m2mblockmessage.cpp | 152 +++++++++++++++ .../mbed-client/source/m2minterfaceimpl.cpp | 5 +- .../mbed-client/source/m2mnsdlinterface.cpp | 35 +++- .../mbed-client/source/m2mresource.cpp | 24 ++- .../source/m2mresourceinstance.cpp | 176 ++++++++++++------ .../mbed-client/source/nsdlaccesshelper.cpp | 4 +- .../test/helloworld-mbedclient/Makefile | 23 +++ .../test/lwm2mtestapplication/Makefile | 101 ++++++++++ .../utest/m2mblockmessage/CMakeLists.txt | 20 ++ .../m2mblockmessage/m2mblockmessagetest.cpp | 42 +++++ .../mbedclient/utest/m2mblockmessage/main.cpp | 25 +++ .../m2mblockmessage/test_m2mblockmessage.cpp | 107 +++++++++++ .../m2mblockmessage/test_m2mblockmessage.h | 34 ++++ .../test_m2mnsdlinterface.cpp | 14 +- .../utest/m2mresource/test_m2mresource.cpp | 15 +- .../utest/m2mresourceinstance/CMakeLists.txt | 5 +- .../test_m2mresourceinstance.cpp | 90 ++++++++- .../mbedclient/utest/stub/common_stub.cpp | 2 +- .../mbedclient/utest/stub/m2mbase_stub.cpp | 2 +- .../utest/stub/m2mblockmessage_stub.cpp | 96 ++++++++++ .../utest/stub/m2mblockmessage_stub.h | 30 +++ .../utest/stub/m2mnsdlinterface_stub.cpp | 1 + .../utest/stub/m2mresource_stub.cpp | 4 +- .../utest/stub/m2mresourceinstance_stub.cpp | 14 ++ .../test/mbedclient_linux/Makefile | 17 ++ .../mbed-client-c/CHANGELOG.md | 78 ++++++++ .../FEATURE_COMMON_PAL/mbed-client-c/Makefile | 45 +++++ .../mbed-client-c/module.json | 2 +- .../mbed-client-c/nsdl-c/sn_coap_protocol.h | 24 +++ .../mbed-client-c/nsdl-c/sn_nsdl_lib.h | 13 ++ .../mbed-client-c/run_unit_tests.sh | 0 .../run_unit_tests_with_valgrind.sh | 0 .../src/include/sn_coap_protocol_internal.h | 9 + .../source/libCoap/src/sn_coap_protocol.c | 76 +++++++- .../source/libNsdl/src/include/sn_grs.h | 0 .../mbed-client-c/source/libNsdl/src/sn_grs.c | 1 + .../source/libNsdl/src/sn_nsdl.c | 50 ++++- .../test/multithread-linux-test/tester.sh | 0 .../test/nsdl-c/unittest/Makefile | 19 ++ .../test/nsdl-c/unittest/MakefileWorker.mk | 0 .../test/nsdl-c/unittest/makefile_defines.txt | 0 .../test/nsdl-c/unittest/run_tests | 0 .../nsdl-c/unittest/sn_coap_builder/Makefile | 16 ++ .../unittest/sn_coap_header_check/Makefile | 14 ++ .../nsdl-c/unittest/sn_coap_parser/Makefile | 17 ++ .../nsdl-c/unittest/sn_coap_protocol/Makefile | 17 ++ .../libCoap_protocol_test.cpp | 106 ++++++++++- .../test/nsdl-c/unittest/sn_grs/Makefile | 20 ++ .../test/nsdl-c/unittest/sn_nsdl/Makefile | 21 +++ .../nsdl-c/unittest/sn_nsdl/test_sn_nsdl.c | 49 +++++ .../unittest/stubs/sn_coap_protocol_stub.c | 3 + .../test/nsdl-c/unittest/stubs/sn_grs_stub.c | 0 .../test/nsdl-c/unittest/stubs/sn_nsdl_stub.c | 0 .../unittest/test_libNsdl/Test.c | 25 +++ .../mbed-client-c/xsl_script.sh | 0 70 files changed, 2093 insertions(+), 160 deletions(-) create mode 100644 features/FEATURE_CLIENT/mbed-client-classic/CHANGELOG.md create mode 100644 features/FEATURE_CLIENT/mbed-client/CHANGELOG.md create mode 100644 features/FEATURE_CLIENT/mbed-client/Makefile create mode 100644 features/FEATURE_CLIENT/mbed-client/mbed-client/m2mblockmessage.h create mode 100644 features/FEATURE_CLIENT/mbed-client/source/m2mblockmessage.cpp create mode 100644 features/FEATURE_CLIENT/mbed-client/test/helloworld-mbedclient/Makefile create mode 100644 features/FEATURE_CLIENT/mbed-client/test/lwm2mtestapplication/Makefile create mode 100644 features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/CMakeLists.txt create mode 100644 features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/m2mblockmessagetest.cpp create mode 100644 features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/main.cpp create mode 100755 features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/test_m2mblockmessage.cpp create mode 100755 features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/test_m2mblockmessage.h create mode 100755 features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mblockmessage_stub.cpp create mode 100755 features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mblockmessage_stub.h create mode 100644 features/FEATURE_CLIENT/mbed-client/test/mbedclient_linux/Makefile create mode 100644 features/FEATURE_COMMON_PAL/mbed-client-c/CHANGELOG.md create mode 100644 features/FEATURE_COMMON_PAL/mbed-client-c/Makefile mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/nsdl-c/sn_nsdl_lib.h mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/run_unit_tests.sh mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/run_unit_tests_with_valgrind.sh mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/include/sn_grs.h mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_grs.c mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_nsdl.c mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/test/multithread-linux-test/tester.sh create mode 100755 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/Makefile mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/MakefileWorker.mk mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/makefile_defines.txt mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/run_tests create mode 100755 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_builder/Makefile create mode 100755 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_header_check/Makefile create mode 100644 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_parser/Makefile create mode 100644 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_protocol/Makefile create mode 100644 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_grs/Makefile create mode 100644 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_nsdl/Makefile mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_grs_stub.c mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_nsdl_stub.c mode change 100644 => 100755 features/FEATURE_COMMON_PAL/mbed-client-c/xsl_script.sh diff --git a/features/FEATURE_CLIENT/mbed-client-classic/CHANGELOG.md b/features/FEATURE_CLIENT/mbed-client-classic/CHANGELOG.md new file mode 100644 index 00000000000..1bc6820b777 --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client-classic/CHANGELOG.md @@ -0,0 +1,26 @@ +# Change Log + +## mbed-os-5.1.4-rc1 +[Full Changelog](https://github.com/ARMmbed/mbed-client-classic/compare/e35a2aeb46bf31bfc53a4379441c0eaab72bd902...586e697365999fc7d976afc8360e26e068f264ae) + +**Closed issues:** + +- IOTCLT-966 - Mbed-cloud-client-example dead after running over night (possible memory leak) + +**Merged pull requests:** + +commit 586e697365999fc7d976afc8360e26e068f264ae (HEAD, tag: mbed-os-5.1.4-rc1, origin/master, origin/HEAD, master) +Merge: e35a2ae 8e0b173 +Author: Yogesh Pande +Date: Tue Sep 6 18:54:56 2016 +0300 + + Merge pull request #36 from ARMmbed/socket-callback-task-identifier + + Socket callback cleanup and change task identifier usage + +commit 8e0b17320e0f3014e3e5af1b966639dfa5077ca5 +Author: Jaakko Kukkohovi +Date: Fri Sep 2 17:16:31 2016 +0300 + + Socket callback cleanup and change task identifier usage + diff --git a/features/FEATURE_CLIENT/mbed-client-classic/source/m2mconnectionhandlerpimpl.cpp b/features/FEATURE_CLIENT/mbed-client-classic/source/m2mconnectionhandlerpimpl.cpp index 8a061b987d5..fdec8968f55 100644 --- a/features/FEATURE_CLIENT/mbed-client-classic/source/m2mconnectionhandlerpimpl.cpp +++ b/features/FEATURE_CLIENT/mbed-client-classic/source/m2mconnectionhandlerpimpl.cpp @@ -44,11 +44,21 @@ static MemoryPooldata_ptr; - M2MConnectionHandlerPimpl* pimpl = (M2MConnectionHandlerPimpl*)task_id->pimpl; + M2MConnectionHandlerPimpl* pimpl = NULL; + M2MConnectionHandlerPimpl::TaskIdentifier *task_id = NULL; + + if (event->event_type == M2MConnectionHandlerPimpl::ESocketSend) { + task_id = (M2MConnectionHandlerPimpl::TaskIdentifier*)event->data_ptr; + pimpl = (M2MConnectionHandlerPimpl*)(task_id->pimpl); + } + else { + pimpl = (M2MConnectionHandlerPimpl*)event->data_ptr; + } + if(pimpl) { eventOS_scheduler_set_active_tasklet(pimpl->connection_tasklet_handler()); } + switch (event->event_type) { case M2MConnectionHandlerPimpl::ESocketIdle: tr_debug("Connection Tasklet Generated"); @@ -71,7 +81,7 @@ extern "C" void connection_tasklet_event_handler(arm_event_s *event) break; case M2MConnectionHandlerPimpl::ESocketSend: tr_debug("connection_tasklet_event_handler - ESocketSend"); - if(pimpl) { + if(pimpl && task_id) { pimpl->send_socket_data((uint8_t*)task_id->data_ptr,(uint16_t)event->event_data); if (task_id->data_ptr) { free(task_id->data_ptr); @@ -81,6 +91,8 @@ extern "C" void connection_tasklet_event_handler(arm_event_s *event) default: break; } + + // Free the task identifier if we had it if (task_id) { memory_pool.free(task_id); } @@ -157,17 +169,12 @@ bool M2MConnectionHandlerPimpl::resolve_server_address(const String& server_addr _server_port = server_port; _server_type = server_type; _server_address = server_address; - TaskIdentifier* task = memory_pool.alloc(); - if (!task) { - return false; - } - task->pimpl = this; arm_event_s event; event.receiver = M2MConnectionHandlerPimpl::_tasklet_id; event.sender = 0; event.event_type = ESocketDnsHandler; - event.data_ptr = task; + event.data_ptr = this; event.priority = ARM_LIB_HIGH_PRIORITY_EVENT; return eventOS_event_send(&event) == 0 ? true : false; } @@ -280,7 +287,14 @@ bool M2MConnectionHandlerPimpl::send_data(uint8_t *data, event.event_data = data_len; event.priority = ARM_LIB_HIGH_PRIORITY_EVENT; - return eventOS_event_send(&event) == 0 ? true : false; + if (eventOS_event_send(&event) == 0) { + return true; + } + + // Event push failed, free task identifier and buffer + free(buffer); + memory_pool.free(task); + return false; } void M2MConnectionHandlerPimpl::send_socket_data(uint8_t *data, @@ -326,23 +340,13 @@ int8_t M2MConnectionHandlerPimpl::connection_tasklet_handler() void M2MConnectionHandlerPimpl::socket_event() { - TaskIdentifier* task = memory_pool.alloc(); - if (!task) { - _observer.socket_error(M2MConnectionHandler::SOCKET_READ_ERROR, true); - return; - } - task->pimpl = this; - arm_event_s event; event.receiver = M2MConnectionHandlerPimpl::_tasklet_id; event.sender = 0; event.event_type = ESocketReadytoRead; - event.data_ptr = task; + event.data_ptr = this; event.priority = ARM_LIB_HIGH_PRIORITY_EVENT; - int8_t error = eventOS_event_send(&event); - if(error != 0) { - _observer.socket_error(M2MConnectionHandler::SOCKET_READ_ERROR, true); - } + eventOS_event_send(&event); } bool M2MConnectionHandlerPimpl::start_listening_for_data() diff --git a/features/FEATURE_CLIENT/mbed-client/CHANGELOG.md b/features/FEATURE_CLIENT/mbed-client/CHANGELOG.md new file mode 100644 index 00000000000..7d6954d3fcf --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/CHANGELOG.md @@ -0,0 +1,78 @@ +# Change Log + +## [v1.15.0](https://github.com/ARMmbed/mbed-client/releases/tag/v1.15.0) (06-Sep-2016) +[Full Changelog](https://github.com/ARMmbed/mbed-client/compare/v1.13.4...v1.15.0) + +** New feature ** + +- Introduce new API's to handle block-wise messages in application level + +**Closed issues:** + +- IOTCLT-1001 - mDS does not sent RST anymore for Client after DELETE /subscriptions + +**Merged pull requests:** + +commit ce709e08039407ee69ce1f638543652261742439 (HEAD, tag: v1.15.0, origin/master, origin/HEAD, master) +Author: Teemu Takaluoma +Date: Tue Sep 6 18:52:15 2016 +0300 + + version v1.15.0 + +commit a2158dd9abf35fe98ef675ebfb77cd77b5a13747 +Merge: 783678e c4bf82c +Author: Teemu Takaluoma +Date: Tue Sep 6 18:51:42 2016 +0300 + + Merge pull request #278 from ARMmbed/IOTCLT-1001 + + implement platform agnostic IP handling, Fix IOTCLT-1001 + +commit c4bf82cc792c9e5f5bc2ddcfc062234c31d586d9 +Author: Teemu Takaluoma +Date: Tue Sep 6 18:17:22 2016 +0300 + + update doxygen in header + +commit d4c802be2e43fe60e19b416917d60e7bf4ae7375 +Author: Teemu Takaluoma +Date: Mon Sep 5 19:34:28 2016 +0300 + + fix unittests + +commit 0cb20925e00ac4641e7b40c08c9798133d6c0755 +Author: Teemu Takaluoma +Date: Sat Sep 3 14:20:46 2016 +0300 + + remove unnessary assignments + +commit 0d7f1080aa2f9c236f9740d6fcbd7e34d8cc9ed7 +Author: Teemu Takaluoma +Date: Sat Sep 3 13:56:43 2016 +0300 + + Fix for IOTCLT-1001, implement platform agnostic IP handling + +commit 783678ef926a4e52609b3f7e67eedcf60ff05161 +Author: Antti Yli-Tokola +Date: Tue Sep 6 15:26:36 2016 +0300 + + Update documentation to cover external block-wise message storing (#274) + + * Update documentation to cover external block-wise message storing + +commit 98bb9cf8652d9fa3f7882d5c3d5e15c21a1e55a9 (tag: v1.14.0) +Author: Antti Yli-Tokola +Date: Tue Sep 6 09:19:08 2016 +0300 + + version v1.14.0 + +commit 32cd77e498dda4cb54688fbab6032634a2ee909c +Author: Antti Yli-Tokola +Date: Tue Sep 6 09:05:31 2016 +0300 + + Introduce new API's to handle block-wise messages in application level (#272) + + * Introduce new API's in resource level. + * set_incoming_block_message_callback(), used when application wants to store block-wise messages in their own memory + * set_outgoing_block_message_callback, used to read block wise message data from application memory + diff --git a/features/FEATURE_CLIENT/mbed-client/Makefile b/features/FEATURE_CLIENT/mbed-client/Makefile new file mode 100644 index 00000000000..afdf8a4c2ba --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/Makefile @@ -0,0 +1,59 @@ +# +# Makefile for mbed Client C++ Library +# +# List of subdirectories to build +TEST_FOLDER := ./test/ + +# Define compiler toolchain with CC or PLATFORM variables +# Example (GCC toolchains, default $CC and $AR are used) +# make +# +# OR (Cross-compile GCC toolchain) +# make PLATFORM=arm-linux-gnueabi- +# +# OR (ArmCC/Keil) +# make CC=ArmCC AR=ArmAR +# +# OR (IAR-ARM) +# make CC=iccarm + +LIB = libmbedclient.a + +# List of unit test directories for libraries +UNITTESTS := $(sort $(dir $(wildcard $(TEST_FOLDER)*/utest/*))) + +# If configuration is not specified, use linux +ifeq (,$(CONFIG)) +CONFIG := linux +endif + +include sources.mk +include include_dirs.mk +include config/$(CONFIG).mk + +SERVLIB_DIR := ../../libService +NSDL_C_DIR := ../../nsdl-c +override CFLAGS += -I$(SERVLIB_DIR)/libService +override CFLAGS += -I$(NSDL_C_DIR)/nsdl-c +override CFLAGS += $(addprefix -I,$(INCLUDE_DIRS)) +override CFLAGS += $(addprefix -D,$(FLAGS)) +ifeq ($(DEBUG),1) +override CFLAGS += -DHAVE_DEBUG +endif + +COVERAGEFILE := ./lcov/coverage.info + +# +# Define compiler toolchain +# +include ../../libService/toolchain_rules.mk + +$(eval $(call generate_rules,$(LIB),$(SRCS))) + +# Extend default clean rule +clean: clean-extra + +$(CLEANDIRS): + @make -C $(@:clean-%=%) clean + +clean-extra: $(CLEANDIRS) diff --git a/features/FEATURE_CLIENT/mbed-client/docs/Howto.md b/features/FEATURE_CLIENT/mbed-client/docs/Howto.md index 9b61c33e3fd..37bbe0e81da 100644 --- a/features/FEATURE_CLIENT/mbed-client/docs/Howto.md +++ b/features/FEATURE_CLIENT/mbed-client/docs/Howto.md @@ -414,4 +414,47 @@ static void c_style_function(void *) { } resource->set_execute_function(&c_style_function); ``` -There are additional APIs that provide getter and remove functions for Resource and Resource Instances in the `M2MResource` and `M2MResourceInstance` classes. Check [the API documentation](https://docs.mbed.com/docs/mbed-client-guide/en/latest/api/annotated.html) for their usage. +There are additional APIs that provide getter and remove functions for Resource and Resource Instances in the `M2MResource` and `M2MResourceInstance` classes. Check [the API documentation](https://docs.mbed.com/docs/mbed-client-guide/en/latest/api/annotated.html) for their usage. + +##### Setting an external handler for block-wise messages + +For dynamic Resources, you can pass a function pointer to the Resource Instance. It will be executed when mbed Device Server calls a `PUT` method on that resource with large payload using block-wise operation. The Resource must support the `PUT` operation mode for this feature to work. If the callback is set, the application will be notified for every incoming block-wise message and the message is not stored in mbed Client side anymore. In such case, it is application's responsibility to store each block-wise message and combine them when the last block has arrived. + +**Note:** Due to a limitation in the mbed-client-c library, GET request can only contain data up to 65KB. + +To pass the function pointer for an incoming block-wise message: + +``` +virtual void set_incoming_block_message_callback(incoming_block_message_callback callback); +void block_message_received(M2MBlockMessage *argument) { +// Code +} +resource->set_incoming_block_message_callback(incoming_block_message_callback(this, &block_message_received)); +``` + +To pass the function pointer for an outgoing block-wise message: + +``` +virtual void set_outgoing_block_message_callback(outgoing_block_message_callback callback); +void block_message_requested(const String& resource, uint8_t *&data, uint32_t &len) { +// Code +} +resource->set_outgoing_block_message_callback(outgoing_block_message_callback(this, &block_message_requested)); +``` + +Applications can define their own maximum incoming message size in bytes at build time. For mbed OS, create a `mbed_app.json` file in the application level and overwrite the value as described below: + +``` +"target_overrides": { + "*": { + "mbed-client.sn-coap-max-incoming-message-size": 100000 + } + +``` +For yotta based builds, you need to create a `config.json` file in the application level: + +``` +{ +"coap_max_incoming_block_message_size": 100000 +} +``` diff --git a/features/FEATURE_CLIENT/mbed-client/docs/Introduction.md b/features/FEATURE_CLIENT/mbed-client/docs/Introduction.md index 66e10b12e5d..31d08c809d3 100644 --- a/features/FEATURE_CLIENT/mbed-client/docs/Introduction.md +++ b/features/FEATURE_CLIENT/mbed-client/docs/Introduction.md @@ -99,9 +99,9 @@ _interface->set_entropy_callback(ent_cb); The maximum single UDP message size that mbed Client can receive is 1152 bytes. The actual payload size is 1137 bytes, the header information using the remaining 15 bytes. -For transferring larger amounts of data, the Blockwise feature must be deployed. When using this feature, mbed Client can handle messages up to 64KB. This feature is disabled by default. +For transferring larger amounts of data, the Blockwise feature must be deployed. When using this feature, mbed Client can handle messages up to 65KB by default. This feature is disabled by default. To receive more than 65KB, see [Setting an external handler for block-wise messages](Howto.md#setting-an-external-handler-for-block-wise-messages). -For mbed OS, to enable Blockwise feature , create a `mbed_app.json` file in the application level and overwrite Blockwise value as described below: +To enable the Blockwise feature in mbed OS, create a `mbed_app.json` file in the application level and overwrite Blockwise value as described below: *Example:* ``` @@ -112,7 +112,7 @@ For mbed OS, to enable Blockwise feature , create a `mbed_app.json` file in the ``` -For yotta based builds, to enable the Blockwise feature, you need to create a `config.json` file in the application level. +To enable the Blockwise feature in yotta based builds, you need to create a `config.json` file in the application level. *Example:* ``` diff --git a/features/FEATURE_CLIENT/mbed-client/mbed-client/functionpointer.h b/features/FEATURE_CLIENT/mbed-client/mbed-client/functionpointer.h index e970e7dbf8c..c62eaeeab27 100644 --- a/features/FEATURE_CLIENT/mbed-client/mbed-client/functionpointer.h +++ b/features/FEATURE_CLIENT/mbed-client/mbed-client/functionpointer.h @@ -190,7 +190,173 @@ class FP1{ R (*_membercaller)(void*, uintptr_t*, A1); // registered membercaller function to convert back and call _m.member on _object }; +/** A class for storing and calling a pointer to a static or member void function + */ +template +class FP2{ +public: + /** Create a FP, attaching a static function + * + * \param function The void static function to attach (default is none) + */ + FP2(R (*function)(A1, A2) = 0) { + attach(function); + } + + /** Create a FP, attaching a member function + * + * \param object The object pointer to invoke the member function on (i.e. the this pointer) + * \param function The address of the void member function to attach + */ + template + FP2(T *object, R (T::*member)(A1, A2)) { + attach(object, member); + } + + /** Attach a static function + * + * \param function The void static function to attach (default is none) + */ + void attach(R (*function)(A1, A2)) { + _p.function = function; + _membercaller = 0; + } + + /** Attach a member function + * + * \param object The object pointer to invoke the member function on (i.e. the this pointer) + * \param function The address of the void member function to attach + */ + template + void attach(T *object, R (T::*member)(A1, A2)) { + _p.object = static_cast(object); + *reinterpret_cast(_member) = member; + _membercaller = &FP2::membercaller; + } + + /** Call the attached static or member function + */ + R call(A1 a1, A2 a2){ + if (_membercaller == 0 && _p.function) { + return _p.function(a1, a2); + } else if (_membercaller && _p.object) { + return _membercaller(_p.object, _member, a1, a2); + } + return (R)0; + } + + typedef R (*static_fp)(); + static_fp get_function() const { + return (R(*)())_p.function; + } + + R operator ()(A1 a1, A2 a2) { + return call(a1, a2); + } + operator bool(void) + { + void *q = &_p.function; + return (_membercaller != NULL) && _p.object != NULL && (*static_cast(q) != NULL); + } +private: + template + static void membercaller(void *object, uintptr_t *member, A1 a1, A2 a2) { + T* o = static_cast(object); + R (T::**m)(A1, A2) = reinterpret_cast(member); + (o->**m)(a1, a2); + } + + union { + R (*function)(A1, A2); // static function pointer - 0 if none attached + void *object; // object this pointer - 0 if none attached + } _p; + uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller + R (*_membercaller)(void*, uintptr_t*, A1, A2); // registered membercaller function to convert back and call _m.member on _object +}; +/** A class for storing and calling a pointer to a static or member void function + */ +template +class FP3{ +public: + /** Create a FP, attaching a static function + * + * \param function The void static function to attach (default is none) + */ + FP3(R (*function)(A1, A2, A3) = 0) { + attach(function); + } + + /** Create a FP, attaching a member function + * + * \param object The object pointer to invoke the member function on (i.e. the this pointer) + * \param function The address of the void member function to attach + */ + template + FP3(T *object, R (T::*member)(A1, A2, A3)) { + attach(object, member); + } + + /** Attach a static function + * + * \param function The void static function to attach (default is none) + */ + void attach(R (*function)(A1, A2, A3)) { + _p.function = function; + _membercaller = 0; + } + + /** Attach a member function + * + * \param object The object pointer to invoke the member function on (i.e. the this pointer) + * \param function The address of the void member function to attach + */ + template + void attach(T *object, R (T::*member)(A1, A2, A3)) { + _p.object = static_cast(object); + *reinterpret_cast(_member) = member; + _membercaller = &FP3::membercaller; + } + + /** Call the attached static or member function + */ + R call(A1 a1, A2 a2, A3 a3){ + if (_membercaller == 0 && _p.function) { + return _p.function(a1, a2, a3); + } else if (_membercaller && _p.object) { + return _membercaller(_p.object, _member, a1, a2, a3); + } + return (R)0; + } + + typedef R (*static_fp)(); + static_fp get_function() const { + return (R(*)())_p.function; + } + + R operator ()(A1 a1, A2 a2, A3 a3) { + return call(a1, a2, a3); + } + operator bool(void) + { + void *q = &_p.function; + return (_membercaller != NULL) && _p.object != NULL && (*static_cast(q) != NULL); + } +private: + template + static void membercaller(void *object, uintptr_t *member, A1 a1, A2 a2, A3 a3) { + T* o = static_cast(object); + R (T::**m)(A1, A2, A3) = reinterpret_cast(member); + (o->**m)(a1, a2, a3); + } + + union { + R (*function)(A1, A2, A3); // static function pointer - 0 if none attached + void *object; // object this pointer - 0 if none attached + } _p; + uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller + R (*_membercaller)(void*, uintptr_t*, A1, A2, A3); // registered membercaller function to convert back and call _m.member on _object +}; typedef FP0 FP; diff --git a/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mbase.h b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mbase.h index 62d6ef61548..880197415fd 100644 --- a/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mbase.h +++ b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mbase.h @@ -27,6 +27,9 @@ struct sn_coap_hdr_; typedef sn_coap_hdr_ sn_coap_hdr_s; struct nsdl_s; +struct sn_nsdl_addr_; +typedef sn_nsdl_addr_ sn_nsdl_addr_s; + typedef FP1 value_updated_callback; typedef void(*value_updated_callback2) (const char* object_name); class M2MObservationHandler; @@ -37,9 +40,6 @@ class M2MReportHandler; * This class is the base class based on which all LWM2M object models * can be created. This serves base class for Object, ObjectInstances and Resources. */ - - - class M2MBase : public M2MReportObserver { public: @@ -340,7 +340,8 @@ class M2MBase : public M2MReportObserver { virtual sn_coap_hdr_s* handle_post_request(nsdl_s *nsdl, sn_coap_hdr_s *received_coap_header, M2MObservationHandler *observation_handler, - bool &execute_value_updated); + bool &execute_value_updated, + sn_nsdl_addr_s *address = NULL); /** * \brief Sets whether this resource will be published to server or not. diff --git a/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mblockmessage.h b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mblockmessage.h new file mode 100644 index 00000000000..21e24a60af8 --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mblockmessage.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef M2MBLOCKMESSAGE_H +#define M2MBLOCKMESSAGE_H + +#include "ns_types.h" +#include "nsdl-c/sn_coap_header.h" + +/** + * \brief M2MBlockMessage. + * This class contains the data of incoming block message. + */ +class M2MBlockMessage { + +public: + + /** + * \brief Enum defining different kinds of errors + * that can occur during block-wise operation. + */ + typedef enum { + ErrorNone = 0, + EntityTooLarge + }Error; + + /** + * Constructor. + */ + M2MBlockMessage(); + + /** + * Destructor. + */ + virtual ~M2MBlockMessage(); + + /** + * \brief Store the data from coap message. + * \param coap_header Message to parse. + */ + void set_message_info(sn_coap_hdr_s *coap_header); + + /** + * \brief Clear values. + */ + void clear_values(); + + /** + * \brief Check if the message is block message. + * \param coap_header Message to check. + * \return True if block message else false. + */ + bool is_block_message() const; + + /** + * \brief Returns number of incoming block. + * \return Block number, starting from 0. + */ + uint16_t block_number() const; + + /** + * \brief Returns total size of the message. + * \return Total size in bytes. + */ + uint32_t total_message_size() const; + + /** + * \brief Check if last block. + * \return True if last block else false. + */ + bool is_last_block() const; + + /** + * \brief Returns payload of the message. + * \return Payload + */ + uint8_t* block_data() const; + + /** + * \brief Returns length of the payload. + * \return Payload length. + */ + uint32_t block_data_len() const; + + /** + * \brief Returns error code. + * \return Error code. + */ + Error error_code() const; + +private: + uint16_t _block_number; + uint32_t _total_message_size; + bool _is_last_block; + uint8_t *_block_data_ptr; + uint16_t _block_data_len; + Error _error_code; + bool _is_block_message; +}; + +#endif // M2MBLOCKMESSAGE_H diff --git a/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mresource.h b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mresource.h index 598fa203863..fdaf3d4e6a8 100644 --- a/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mresource.h +++ b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mresource.h @@ -225,7 +225,8 @@ class M2MResource : public M2MResourceInstance, M2MResourceCallback { virtual sn_coap_hdr_s* handle_post_request(nsdl_s *nsdl, sn_coap_hdr_s *received_coap_header, M2MObservationHandler *observation_handler, - bool &execute_value_updated); + bool &execute_value_updated, + sn_nsdl_addr_s *address = NULL); protected: virtual void notification_update(); diff --git a/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mresourceinstance.h b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mresourceinstance.h index 85df331a983..6b5b8727cce 100644 --- a/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mresourceinstance.h +++ b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mresourceinstance.h @@ -29,8 +29,11 @@ class M2MObjectInstanceCallback { * This class is the base class for mbed Client Resources. All defined * LWM2M resource models can be created based on it. */ +class M2MBlockMessage; typedef FP1 execute_callback; typedef void(*execute_callback_2) (void *arguments); +typedef FP1 incoming_block_message_callback; +typedef FP3 outgoing_block_message_callback; class M2MResourceCallback; @@ -222,7 +225,7 @@ friend class M2MResource; * \return sn_coap_hdr_s The message that needs to be sent to the server. */ virtual sn_coap_hdr_s* handle_put_request(nsdl_s *nsdl, - sn_coap_hdr_s *received_coap_header, + sn_coap_hdr_s *received_coap_header, M2MObservationHandler *observation_handler, bool &execute_value_updated); @@ -238,6 +241,28 @@ friend class M2MResource; */ const String& object_name() const; + /** + * @brief Sets the function that is executed when this + * object receives block-wise message. + * @param callback The function pointer that is called. + */ + virtual void set_incoming_block_message_callback(incoming_block_message_callback callback); + + /** + * @brief Sets the function that is executed when this + * object receives a GET request. + * This is called if resource values is stored in application side. + * NOTE! Due to limitation in mbed-client-c library GET request can only contain data size up to 65KB. + * @param callback The function pointer that is called. + */ + virtual void set_outgoing_block_message_callback(outgoing_block_message_callback callback); + + /** + * \brief Returns the block message object. + * \return Block message. + */ + virtual M2MBlockMessage* block_message() const; + protected: /** @@ -261,9 +286,11 @@ friend class M2MResource; M2MResourceCallback *_resource_callback; // Not owned String _object_name; FP1 *_function_pointer; - uint16_t _object_instance_id; ResourceType _resource_type; + incoming_block_message_callback _incoming_block_message_cb; + outgoing_block_message_callback _outgoing_block_message_cb; + M2MBlockMessage *_block_message_data; friend class Test_M2MResourceInstance; friend class Test_M2MResource; diff --git a/features/FEATURE_CLIENT/mbed-client/mbed_lib.json b/features/FEATURE_CLIENT/mbed-client/mbed_lib.json index ba1d5a30d3f..58379511fce 100644 --- a/features/FEATURE_CLIENT/mbed-client/mbed_lib.json +++ b/features/FEATURE_CLIENT/mbed-client/mbed_lib.json @@ -1,13 +1,14 @@ { "name": "mbed-client", - "config": { - "event-loop-size": 1024, - "reconnection-count": 3, - "reconnection-interval": 5, - "tcp-keepalive-time": 300, - "disable-bootstrap-feature": null, - "coap-disable-obs-feature":null, - "sn-coap-max-blockwise-payload-size" : 0, - "sn-coap-duplication-max-msgs-count": 0 + "config": { + "event-loop-size": 1024, + "reconnection-count": 3, + "reconnection-interval": 5, + "tcp-keepalive-time": 300, + "disable-bootstrap-feature": null, + "coap-disable-obs-feature":null, + "sn-coap-max-blockwise-payload-size" : 0, + "sn-coap-duplication-max-msgs-count": 0, + "sn-coap-max-incoming-message-size": null } } diff --git a/features/FEATURE_CLIENT/mbed-client/module.json b/features/FEATURE_CLIENT/mbed-client/module.json index 7c554ab4fc4..db3d45eff93 100644 --- a/features/FEATURE_CLIENT/mbed-client/module.json +++ b/features/FEATURE_CLIENT/mbed-client/module.json @@ -1,6 +1,6 @@ { "name": "mbed-client", - "version": "1.13.4", + "version": "1.15.0", "description": "mbed Client C++ API", "keywords": [], "author": "Yogesh Pande ", diff --git a/features/FEATURE_CLIENT/mbed-client/source/include/m2mnsdlinterface.h b/features/FEATURE_CLIENT/mbed-client/source/include/m2mnsdlinterface.h index 14d78e4246e..ce915094bd3 100644 --- a/features/FEATURE_CLIENT/mbed-client/source/include/m2mnsdlinterface.h +++ b/features/FEATURE_CLIENT/mbed-client/source/include/m2mnsdlinterface.h @@ -107,11 +107,13 @@ class M2MNsdlInterface : public M2MTimerObserver, /** * @brief Sends the register message to the server. * @param address M2MServer address. + * @param address_length M2MServer address length. * @param port M2MServer port. * @param address_type IP Address type. * @return true if register sent successfully else false. */ bool send_register_message(uint8_t* address, + uint8_t address_length, const uint16_t port, sn_nsdl_addr_type_e address_type); diff --git a/features/FEATURE_CLIENT/mbed-client/source/m2mbase.cpp b/features/FEATURE_CLIENT/mbed-client/source/m2mbase.cpp index a518a080e48..c48db2cea81 100644 --- a/features/FEATURE_CLIENT/mbed-client/source/m2mbase.cpp +++ b/features/FEATURE_CLIENT/mbed-client/source/m2mbase.cpp @@ -366,7 +366,8 @@ sn_coap_hdr_s* M2MBase::handle_put_request(nsdl_s */*nsdl*/, sn_coap_hdr_s* M2MBase::handle_post_request(nsdl_s */*nsdl*/, sn_coap_hdr_s */*received_coap_header*/, M2MObservationHandler */*observation_handler*/, - bool &) + bool &, + sn_nsdl_addr_s *) { //Handled in M2MResource, M2MObjectInstance and M2MObject classes return NULL; diff --git a/features/FEATURE_CLIENT/mbed-client/source/m2mblockmessage.cpp b/features/FEATURE_CLIENT/mbed-client/source/m2mblockmessage.cpp new file mode 100644 index 00000000000..a474fa84b82 --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/source/m2mblockmessage.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed-client/m2mblockmessage.h" +#include +#include + +M2MBlockMessage::M2MBlockMessage() : + _block_number(0), + _total_message_size(0), + _is_last_block(false), + _block_data_ptr(NULL), + _block_data_len(0), + _error_code(M2MBlockMessage::ErrorNone), + _is_block_message(false) +{ +} + +M2MBlockMessage::~M2MBlockMessage() +{ + free(_block_data_ptr); + _block_data_ptr = NULL; +} + +void M2MBlockMessage::set_message_info(sn_coap_hdr_s *coap_header) +{ + _is_block_message = (coap_header && + coap_header->options_list_ptr && + coap_header->options_list_ptr->block1_ptr && + coap_header->options_list_ptr->block1_len > 0) ? true : false; + + if (coap_header && coap_header->options_list_ptr) { + // Check total size + if (coap_header->options_list_ptr->size1_ptr) { + for(int i=0;i < coap_header->options_list_ptr->size1_len; i++) { + _total_message_size += (*(coap_header->options_list_ptr->size1_ptr + i) & 0xff) << + 8*(coap_header->options_list_ptr->size1_len- 1 - i); + } + } + + // Default value in coap library is 65kb + uint32_t max_size = UINT16_MAX; + #if YOTTA_CFG_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE + max_size = YOTTA_CFG_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE; + #endif + #if MBED_CONF_MBED_CLIENT_SN_COAP_MAX_INCOMING_MESSAGE_SIZE + max_size = MBED_CONF_MBED_CLIENT_SN_COAP_MAX_INCOMING_MESSAGE_SIZE; + #endif + if (_total_message_size > max_size) { + _error_code = M2MBlockMessage::EntityTooLarge; + } else { + _error_code = M2MBlockMessage::ErrorNone; + } + if (M2MBlockMessage::ErrorNone == _error_code) { + // Is last block + if (coap_header->options_list_ptr->block1_ptr) { + if (!(*(coap_header->options_list_ptr->block1_ptr + (coap_header->options_list_ptr->block1_len - 1)) & 0x08)) { + _is_last_block = true; + } else { + _is_last_block = false; + } + } + + // Block number + if (coap_header->options_list_ptr->block1_len == 3) { + _block_number = *(coap_header->options_list_ptr->block1_ptr) << 12; + _block_number |= *(coap_header->options_list_ptr->block1_ptr + 1) << 4; + _block_number |= (*(coap_header->options_list_ptr->block1_ptr + 2)) >> 4; + } + + else if (coap_header->options_list_ptr->block1_len == 2) { + _block_number = *(coap_header->options_list_ptr->block1_ptr) << 4; + _block_number |= (*(coap_header->options_list_ptr->block1_ptr + 1)) >> 4; + } + else if (coap_header->options_list_ptr->block1_len == 1) { + _block_number = (*coap_header->options_list_ptr->block1_ptr) >> 4; + } + else { + _block_number = 0; + } + + // Payload + free(_block_data_ptr); + _block_data_ptr = NULL; + _block_data_len = coap_header->payload_len; + if(_block_data_len > 0) { + _block_data_ptr = (uint8_t *)malloc(_block_data_len); + if (_block_data_ptr) { + memcpy(_block_data_ptr, coap_header->payload_ptr, _block_data_len); + } + } + } + } +} + +void M2MBlockMessage::clear_values() +{ + free(_block_data_ptr); + _block_data_ptr = NULL; + _block_data_len = 0; + _block_number = 0; + _total_message_size = 0; + _is_last_block = false; + _error_code = M2MBlockMessage::ErrorNone; +} + +bool M2MBlockMessage::is_block_message() const +{ + return _is_block_message; +} + +uint16_t M2MBlockMessage::block_number() const +{ + return _block_number; +} + +uint32_t M2MBlockMessage::total_message_size() const +{ + return _total_message_size; +} + +bool M2MBlockMessage::is_last_block() const +{ + return _is_last_block; +} + +uint8_t* M2MBlockMessage::block_data() const +{ + return _block_data_ptr; +} + +uint32_t M2MBlockMessage::block_data_len() const +{ + return _block_data_len; +} + +M2MBlockMessage::Error M2MBlockMessage::error_code() const +{ + return _error_code; +} diff --git a/features/FEATURE_CLIENT/mbed-client/source/m2minterfaceimpl.cpp b/features/FEATURE_CLIENT/mbed-client/source/m2minterfaceimpl.cpp index 9761ad4d1bd..2d8c7ccb928 100644 --- a/features/FEATURE_CLIENT/mbed-client/source/m2minterfaceimpl.cpp +++ b/features/FEATURE_CLIENT/mbed-client/source/m2minterfaceimpl.cpp @@ -594,12 +594,10 @@ void M2MInterfaceImpl::state_bootstrap_address_resolved( EventData *data) if(M2MInterface::LwIP_IPv4 == stack) { tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv4 address"); address.type = SN_NSDL_ADDRESS_TYPE_IPV4; - address.addr_len = 4; } else if((M2MInterface::LwIP_IPv6 == stack) || (M2MInterface::Nanostack_IPv6 == stack)) { tr_debug("M2MInterfaceImpl::state_bootstrap_address_resolved : IPv6 address"); address.type = SN_NSDL_ADDRESS_TYPE_IPV6; - address.addr_len = 16; } address.port = event->_port; address.addr_ptr = (uint8_t*)event->_address->_address; @@ -732,7 +730,8 @@ void M2MInterfaceImpl::state_register_address_resolved( EventData *data) address_type = SN_NSDL_ADDRESS_TYPE_IPV6; } _connection_handler->start_listening_for_data(); - if(_nsdl_interface->send_register_message((uint8_t*)event->_address->_address,event->_port, address_type)) { + if(_nsdl_interface->send_register_message((uint8_t*)event->_address->_address,event->_address->_length, + event->_port, address_type)) { internal_event(STATE_REGISTER_RESOURCE_CREATED); } else { // If resource creation fails then inform error to application diff --git a/features/FEATURE_CLIENT/mbed-client/source/m2mnsdlinterface.cpp b/features/FEATURE_CLIENT/mbed-client/source/m2mnsdlinterface.cpp index 449b9ab9148..bd239e1a03c 100644 --- a/features/FEATURE_CLIENT/mbed-client/source/m2mnsdlinterface.cpp +++ b/features/FEATURE_CLIENT/mbed-client/source/m2mnsdlinterface.cpp @@ -76,7 +76,6 @@ M2MNsdlInterface::M2MNsdlInterface(M2MNsdlObserver &observer) _nsdl_handle = sn_nsdl_init(&(__nsdl_c_send_to_server), &(__nsdl_c_received_from_server), &(__nsdl_c_memory_alloc), &(__nsdl_c_memory_free)); - _server = new M2MServer(); initialize(); } @@ -270,6 +269,7 @@ bool M2MNsdlInterface::create_bootstrap_resource(sn_nsdl_addr_s *address, const } bool M2MNsdlInterface::send_register_message(uint8_t* address, + uint8_t address_length, const uint16_t port, sn_nsdl_addr_type_e address_type) { @@ -279,7 +279,7 @@ bool M2MNsdlInterface::send_register_message(uint8_t* address, M2MTimerObserver::NsdlExecution, false); bool success = false; - if(set_NSP_address(_nsdl_handle,address, port, address_type) == 0) { + if(set_NSP_address_2(_nsdl_handle, address, address_length, port, address_type) == 0) { if(!_register_ongoing) { _register_ongoing = true; success = sn_nsdl_register_endpoint(_nsdl_handle,_endpoint) != 0; @@ -565,6 +565,7 @@ uint8_t M2MNsdlInterface::received_from_server_callback(struct nsdl_s * nsdl_han return value; } + uint8_t M2MNsdlInterface::resource_callback(struct nsdl_s */*nsdl_handle*/, sn_coap_hdr_s *received_coap_header, sn_nsdl_addr_s *address, @@ -590,7 +591,11 @@ uint8_t M2MNsdlInterface::resource_callback(struct nsdl_s */*nsdl_handle*/, if(base->base_type() == M2MBase::ResourceInstance) { msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; } else { - coap_response = base->handle_post_request(_nsdl_handle, received_coap_header,this, execute_value_updated); + coap_response = base->handle_post_request(_nsdl_handle, + received_coap_header, + this, + execute_value_updated, + address); } } else if(COAP_MSG_CODE_REQUEST_DELETE == received_coap_header->msg_code) { // Delete the object instance @@ -644,20 +649,24 @@ uint8_t M2MNsdlInterface::resource_callback(struct nsdl_s */*nsdl_handle*/, received_coap_header, msg_code); } + if(coap_response && + coap_response->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING && + coap_response->msg_code != COAP_MSG_CODE_EMPTY) { - if(coap_response) { tr_debug("M2MNsdlInterface::resource_callback() - send CoAP response"); (sn_nsdl_send_coap_message(_nsdl_handle, address, coap_response) == 0) ? result = 0 : result = 1; if(coap_response->payload_ptr) { free(coap_response->payload_ptr); coap_response->payload_ptr = NULL; } - sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response); } - if (execute_value_updated) { + sn_nsdl_release_allocated_coap_msg_mem(_nsdl_handle, coap_response); + + if (execute_value_updated && + coap_response && + coap_response->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING) { value_updated(base,base->uri_path()); } - return result; } @@ -984,9 +993,15 @@ bool M2MNsdlInterface::create_nsdl_resource(M2MBase *base, const String &name, b } if(M2MBase::Dynamic == base->mode()){ - // Dynamic resource is updated - _resource->mode = SN_GRS_DYNAMIC; - _resource->sn_grs_dyn_res_callback = __nsdl_c_callback; + // Dynamic resource is updated + _resource->mode = SN_GRS_DYNAMIC; + _resource->sn_grs_dyn_res_callback = __nsdl_c_callback; + if(M2MBase::Resource == base->base_type()) { + M2MResource *res = (M2MResource*)base; + if (res) { + _resource->external_memory_block = (res->block_message()) ? 1 : 0; + } + } } if( _resource->path != NULL ){ diff --git a/features/FEATURE_CLIENT/mbed-client/source/m2mresource.cpp b/features/FEATURE_CLIENT/mbed-client/source/m2mresource.cpp index a88afeb53c4..a397a39dfc8 100644 --- a/features/FEATURE_CLIENT/mbed-client/source/m2mresource.cpp +++ b/features/FEATURE_CLIENT/mbed-client/source/m2mresource.cpp @@ -135,8 +135,17 @@ bool M2MResource::send_delayed_post_response() void M2MResource::get_delayed_token(uint8_t *&token, uint8_t &token_length) { - token = _delayed_token; - token_length = _delayed_token_len; + token_length = 0; + if(token) { + free(token); + token = NULL; + } + if(_delayed_token && _delayed_token_len > 0) { + token = alloc_copy(_delayed_token, _delayed_token_len); + if(token) { + token_length = _delayed_token_len; + } + } } bool M2MResource::remove_resource_instance(uint16_t inst_id) @@ -512,7 +521,8 @@ sn_coap_hdr_s* M2MResource::handle_put_request(nsdl_s *nsdl, sn_coap_hdr_s* M2MResource::handle_post_request(nsdl_s *nsdl, sn_coap_hdr_s *received_coap_header, M2MObservationHandler */*observation_handler*/, - bool &/*execute_value_updated*/) + bool &/*execute_value_updated*/, + sn_nsdl_addr_s *address) { tr_debug("M2MResource::handle_post_request()"); sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04 @@ -549,25 +559,27 @@ sn_coap_hdr_s* M2MResource::handle_post_request(nsdl_s *nsdl, } if(COAP_MSG_CODE_RESPONSE_CHANGED == msg_code) { tr_debug("M2MResource::handle_post_request - Execute resource function"); - execute(exec_params); if(_delayed_response) { + msg_code = COAP_MSG_CODE_EMPTY; coap_response->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT; - coap_response->msg_code = COAP_MSG_CODE_EMPTY; + coap_response->msg_code = msg_code; coap_response->msg_id = received_coap_header->msg_id; if(received_coap_header->token_len) { free(_delayed_token); + _delayed_token = NULL; _delayed_token_len = 0; - _delayed_token = alloc_copy(received_coap_header->token_ptr, received_coap_header->token_len); if(_delayed_token) { _delayed_token_len = received_coap_header->token_len; } + sn_nsdl_send_coap_message(nsdl, address, coap_response); } } else { uint32_t length = 0; get_value(coap_response->payload_ptr, length); coap_response->payload_len = length; } + execute(exec_params); } delete exec_params; } else { // if ((object->operation() & SN_GRS_POST_ALLOWED) != 0) diff --git a/features/FEATURE_CLIENT/mbed-client/source/m2mresourceinstance.cpp b/features/FEATURE_CLIENT/mbed-client/source/m2mresourceinstance.cpp index 38108e546b1..c9a49713327 100644 --- a/features/FEATURE_CLIENT/mbed-client/source/m2mresourceinstance.cpp +++ b/features/FEATURE_CLIENT/mbed-client/source/m2mresourceinstance.cpp @@ -20,6 +20,7 @@ #include "mbed-client/m2mobjectinstance.h" #include "include/m2mreporthandler.h" #include "include/nsdllinker.h" +#include "mbed-client/m2mblockmessage.h" #include "mbed-trace/mbed_trace.h" #define TRACE_GROUP "mClt" @@ -49,7 +50,8 @@ M2MResourceInstance::M2MResourceInstance(const M2MResourceInstance& other) _object_name(other._object_name), _function_pointer(NULL), _object_instance_id(other._object_instance_id), - _resource_type(M2MResourceInstance::STRING) + _resource_type(M2MResourceInstance::STRING), + _block_message_data(NULL) { this->operator=(other); } @@ -70,7 +72,8 @@ M2MResourceInstance::M2MResourceInstance(const String &res_name, _object_name(object_name), _function_pointer(NULL), _object_instance_id(object_instance_id), - _resource_type(type) + _resource_type(type), + _block_message_data(NULL) { M2MBase::set_resource_type(resource_type); M2MBase::set_base_type(M2MBase::ResourceInstance); @@ -94,7 +97,8 @@ M2MResourceInstance::M2MResourceInstance(const String &res_name, _object_name(object_name), _function_pointer(NULL), _object_instance_id(object_instance_id), - _resource_type(type) + _resource_type(type), + _block_message_data(NULL) { M2MBase::set_resource_type(resource_type); M2MBase::set_base_type(M2MBase::Resource); @@ -110,6 +114,7 @@ M2MResourceInstance::~M2MResourceInstance() { free(_value); delete _function_pointer; + delete _block_message_data; } M2MBase::BaseType M2MResourceInstance::base_type() const @@ -255,7 +260,7 @@ bool M2MResourceInstance::is_value_changed(const uint8_t* value, const uint32_t changed = true; } else if(_value && !value) { changed = true; - } else { + } else { if (_value) { if (strcmp((char*)value, (char*)_value) != 0) { changed = true; @@ -311,7 +316,7 @@ String M2MResourceInstance::get_value_string() const if (_value) { value.append_raw((char*)_value, _value_length); } - + return value; } @@ -347,13 +352,20 @@ sn_coap_hdr_s* M2MResourceInstance::handle_get_request(nsdl_s *nsdl, m2m::String::convert_integer_to_array(0, coap_response->content_type_len); } - // fill in the CoAP response payload coap_response->payload_ptr = NULL; uint32_t payload_len = 0; - get_value(coap_response->payload_ptr,payload_len); - coap_response->payload_len = payload_len; + //If handler exists it means that resource value is stored in application side + if (block_message() && block_message()->is_block_message()) { + if(_outgoing_block_message_cb) { + _outgoing_block_message_cb(uri_path(), coap_response->payload_ptr, payload_len); + } + } else { + get_value(coap_response->payload_ptr,payload_len); + } + + coap_response->payload_len = payload_len; coap_response->options_list_ptr = (sn_coap_options_list_s*)malloc(sizeof(sn_coap_options_list_s)); memset(coap_response->options_list_ptr, 0, sizeof(sn_coap_options_list_s)); @@ -423,71 +435,95 @@ sn_coap_hdr_s* M2MResourceInstance::handle_put_request(nsdl_s *nsdl, bool &execute_value_updated) { tr_debug("M2MResourceInstance::handle_put_request()"); - sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04 - sn_coap_hdr_s * coap_response = sn_nsdl_build_response(nsdl, - received_coap_header, - msg_code); - // process the PUT if we have registered a callback for it - if(received_coap_header) { - uint16_t coap_content_type = 0; - if(received_coap_header->content_type_ptr) { - if(coap_response) { - coap_response->content_type_ptr = alloc_copy(received_coap_header->content_type_ptr, - received_coap_header->content_type_len); - if(coap_response->content_type_ptr) { - coap_response->content_type_len = received_coap_header->content_type_len; - for(uint8_t i = 0; i < coap_response->content_type_len; i++) { - coap_content_type = (coap_content_type << 8) + - (coap_response->content_type_ptr[i] & 0xFF); + + + sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04 + sn_coap_hdr_s *coap_response = sn_nsdl_build_response(nsdl, + received_coap_header, + msg_code); + // process the PUT if we have registered a callback for it + if(received_coap_header) { + uint16_t coap_content_type = 0; + if(received_coap_header->content_type_ptr) { + if(coap_response) { + coap_response->content_type_ptr = alloc_copy(received_coap_header->content_type_ptr, + received_coap_header->content_type_len); + if(coap_response->content_type_ptr) { + coap_response->content_type_len = received_coap_header->content_type_len; + for(uint8_t i = 0; i < coap_response->content_type_len; i++) { + coap_content_type = (coap_content_type << 8) + + (coap_response->content_type_ptr[i] & 0xFF); + } } } } - } - if(received_coap_header->options_list_ptr && - received_coap_header->options_list_ptr->uri_query_ptr) { - char *query = (char*)alloc_string_copy(received_coap_header->options_list_ptr->uri_query_ptr, - received_coap_header->options_list_ptr->uri_query_len); - if (query){ - tr_debug("M2MResourceInstance::handle_put_request() - Query %s", query); - - // if anything was updated, re-initialize the stored notification attributes - if (!handle_observation_attribute(query)){ - tr_debug("M2MResourceInstance::handle_put_request() - Invalid query"); - msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00 + if(received_coap_header->options_list_ptr && + received_coap_header->options_list_ptr->uri_query_ptr) { + char *query = (char*)alloc_string_copy(received_coap_header->options_list_ptr->uri_query_ptr, + received_coap_header->options_list_ptr->uri_query_len); + if (query){ + tr_debug("M2MResourceInstance::handle_put_request() - Query %s", query); + + // if anything was updated, re-initialize the stored notification attributes + if (!handle_observation_attribute(query)){ + tr_debug("M2MResourceInstance::handle_put_request() - Invalid query"); + msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; // 4.00 + } + free(query); } - free(query); - } - } else if ((operation() & SN_GRS_PUT_ALLOWED) != 0) { - tr_debug("M2MResourceInstance::handle_put_request() - Request Content-Type %d", coap_content_type); + } else if ((operation() & SN_GRS_PUT_ALLOWED) != 0) { + tr_debug("M2MResourceInstance::handle_put_request() - Request Content-Type %d", coap_content_type); - if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) { - msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; - } else { - set_value(received_coap_header->payload_ptr, received_coap_header->payload_len); - if(received_coap_header->payload_ptr) { - tr_debug("M2MResourceInstance::handle_put_request() - Update Resource with new values"); - if(observation_handler) { - String value = ""; - if (received_coap_header->uri_path_ptr != NULL && - received_coap_header->uri_path_len > 0) { - - value.append_raw((char*)received_coap_header->uri_path_ptr, received_coap_header->uri_path_len); + if(COAP_CONTENT_OMA_TLV_TYPE == coap_content_type) { + msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT; + } else { + bool external_block_store = false; + if (block_message()) { + block_message()->set_message_info(received_coap_header); + if (block_message()->is_block_message()) { + external_block_store = true; + if(_incoming_block_message_cb) { + _incoming_block_message_cb(_block_message_data); + } + if (block_message()->is_last_block()) { + block_message()->clear_values(); + coap_response->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED; + } else { + coap_response->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING; + } + if (block_message()->error_code() != M2MBlockMessage::ErrorNone) { + block_message()->clear_values(); + } + } + } + if (!external_block_store) { + set_value(received_coap_header->payload_ptr, received_coap_header->payload_len); + } + if(received_coap_header->payload_ptr) { + tr_debug("M2MResourceInstance::handle_put_request() - Update Resource with new values"); + if(observation_handler) { + String value = ""; + if (received_coap_header->uri_path_ptr != NULL && + received_coap_header->uri_path_len > 0) { + value.append_raw((char*)received_coap_header->uri_path_ptr, received_coap_header->uri_path_len); + } + + execute_value_updated = true; } - execute_value_updated = true; } } + } else { + // Operation is not allowed. + tr_error("M2MResourceInstance::handle_put_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); + msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; } } else { - // Operation is not allowed. - tr_error("M2MResourceInstance::handle_put_request() - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; } - } else { - msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; - } - if(coap_response) { - coap_response->msg_code = msg_code; - } + if(coap_response) { + coap_response->msg_code = msg_code; + } + return coap_response; } @@ -505,3 +541,21 @@ uint16_t M2MResourceInstance::object_instance_id() const { return _object_instance_id; } + +M2MBlockMessage* M2MResourceInstance::block_message() const +{ + return _block_message_data; +} + +void M2MResourceInstance::set_incoming_block_message_callback(incoming_block_message_callback callback) +{ + _incoming_block_message_cb = callback; + delete _block_message_data; + _block_message_data = NULL; + _block_message_data = new M2MBlockMessage(); +} + +void M2MResourceInstance::set_outgoing_block_message_callback(outgoing_block_message_callback callback) +{ + _outgoing_block_message_cb = callback; +} diff --git a/features/FEATURE_CLIENT/mbed-client/source/nsdlaccesshelper.cpp b/features/FEATURE_CLIENT/mbed-client/source/nsdlaccesshelper.cpp index aa535296d07..075ff725cb7 100644 --- a/features/FEATURE_CLIENT/mbed-client/source/nsdlaccesshelper.cpp +++ b/features/FEATURE_CLIENT/mbed-client/source/nsdlaccesshelper.cpp @@ -34,9 +34,7 @@ uint8_t __nsdl_c_callback(struct nsdl_s *nsdl_handle, status = interface->resource_callback(nsdl_handle,received_coap_ptr, address, nsdl_capab); // Payload freeing must be done in app level if blockwise message - if (received_coap_ptr && - received_coap_ptr->options_list_ptr && - received_coap_ptr->options_list_ptr->block1_len > 0) { + if (received_coap_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) { free(received_coap_ptr->payload_ptr); received_coap_ptr->payload_ptr = NULL; } diff --git a/features/FEATURE_CLIENT/mbed-client/test/helloworld-mbedclient/Makefile b/features/FEATURE_CLIENT/mbed-client/test/helloworld-mbedclient/Makefile new file mode 100644 index 00000000000..87b122fd7fb --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/test/helloworld-mbedclient/Makefile @@ -0,0 +1,23 @@ +PLATFORM= +OS = LINUX +TARGET = helloworld_mbedclient +OBJECTS = main.o mbedclient.o +CFLAGS = -std=c++11 -Wall -D_REENTRANT -D$(OS) -I ../../lwm2m-client \ + -I ../../source/include -I ../../../../libService/libService \ + -I ../../ -I ../../../ -DTARGET_LIKE_LINUX -DHAVE_DEBUG + +LDFLAGS = -D_REENTRANT -L../../ -lmbedclient_gcc -L ../../../../nsdl-c -lnsdl_gcc \ + -L ../../../../libService -lservice_gcc -lpthread\ + -L../../../../mbedtls/library -lmbedtls -lmbedcrypto -lmbedx509 + +all: $(TARGET) + +$(TARGET): $(OBJECTS) + $(PLATFORM)g++ -g -o $(TARGET) $(OBJECTS) $(LDFLAGS) + +.cpp.o: + $(PLATFORM)g++ -c -g -O2 $(CFLAGS) $< + +clean: + rm -f $(TARGET) $(OBJECTS) + diff --git a/features/FEATURE_CLIENT/mbed-client/test/lwm2mtestapplication/Makefile b/features/FEATURE_CLIENT/mbed-client/test/lwm2mtestapplication/Makefile new file mode 100644 index 00000000000..88f4b021475 --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/test/lwm2mtestapplication/Makefile @@ -0,0 +1,101 @@ +# Makefile for LWM2M Test Application +# +# Define compiler toolchain with PLATFORM variable +# Example +# make PLATFORM=arm-linux-gnueabi- +# + +ROOT := ../../../.. +LWM2M_ROOT := $(ROOT)/lwm2m +ROUTER_ROOT := $(ROOT)/Applications/NanoRouter + +VERSION := $(shell cd $(ROOT) && git describe --tags --long --dirty --always) + +# Specify list of sources to build +LWM2M_SRC := \ + main.cpp \ + cmd_commands.cpp \ + cmd_lwm2m.cpp \ + lwm2mtest.cpp \ + +CXX_SRCS += $(LWM2M_SRC) + +HAL_SRCS += \ + linux/arm_hal_interrupt.c \ + linux/arm_hal_timer.c \ + linux/ccm_mutex.c \ + +SRCS += $(addprefix $(ROOT)/Platforms/,$(HAL_SRCS)) + +EXE = lwm2mtestapplication + +override CFLAGS += -DENDPOINT -DUSE_LINUX +override CFLAGS += -Wall -Wextra +override CFLAGS += -g +override CFLAGS += -pthread +override CFLAGS += -std=gnu99 +override CFLAGS += -D'MEM_ALLOC=malloc' -D'MEM_FREE=free' + +override CFLAGS += -DVERSION='"$(VERSION)"' + +override CXXFLAGS += -I$(ROOT) -I$(NSDL_DIR)/nsdl-c -I$(LIBSERVICE_DIR)/libService -I$(ROOT)/nanostack/nanostack -I$(ROOT)/event-loop/nanostack-event-loop +override CXXFLAGS += -I$(LWM2M_ROOT) -I$(LWM2M_ROOT)/lwm2m-client +override CXXFLAGS += -DTARGET_LIKE_LINUX +override CXXFLAGS += -DHAVE_DEBUG +override CXXFLAGS += -g +# Generate dependency files when building +override CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" + +# Build with coverage +ifeq ($(COVERAGE), 1) +override CFLAGS += --coverage +override CXXFLAGS += --coverage +endif + +# +# Libraries +# +NSDL_DIR := $(ROOT)/nsdl-c +LWM2M_DIR := $(ROOT)/lwm2m/lwm2m-client +MBEDTLS_DIR := $(ROOT)/mbedtls/library +LIBSERVICE_DIR := $(ROOT)/libService +override CFLAGS += -I$(ROOT) -I$(NSDL_DIR)/nsdl-c -I$(LIBSERVICE_DIR)/libService -I$(ROOT)/nanostack/nanostack -I$(ROOT)/event-loop/nanostack-event-loop +override CFLAGS += -I$(ROOT)/nanostack/Core/include -I$(ROOT)/Platforms/linux/include -I$(ROOT)/nanostack/HAL/common +override CFLAGS += -I$(ROUTER_ROOT)/include +override CFLAGS += -I$(ROOT)/Platforms/linux/include -I$(ROOT)/Drivers/linux -I$(ROOT)/Boards/linux +LDFLAGS += -D_REENTRANT +LDFLAGS += -L$(ROOT)/event-loop -leventOS_gcc +LDFLAGS += -L$(LWM2M_DIR) -lmbedclient_gcc +LDFLAGS += -L$(NSDL_DIR) -lnsdl_gcc +LDFLAGS += -L$(LIBSERVICE_DIR) -lCmdline_gcc -lservice_gcc +LDFLAGS += -L$(MBEDTLS_DIR) -lmbedtls -lmbedx509 -lmbedcrypto +LDFLAGS += -lpthread + + +# Main build goal, specify here before dependecy parsing +.DEFAULT_GOAL: all +.PHONY: all +all: $(EXE) + +# Create a list of objects and depencies to build +OBJS := $(SRCS:.c=.o) +CXX_OBJS := $(CXX_SRCS:.cpp=.o) +DEPS += $$(SRCS:.c=.d) $$(CXX_SRCS:.cpp=.d) + +# Include depencies +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(DEPS)),) +-include $(DEPS) +endif +endif + +# Linking +$(EXE): $(OBJS) $(CXX_OBJS) + @echo 'Building target: $@' + g++ $(CXXFLAGS) $(CFLAGS) -o $@ $(OBJS) $(CXX_OBJS) $(LDFLAGS) + @echo 'Finished building target: $@' + @echo ' ' + +.PHONY: clean +clean: + -$(RM) $(OBJS) $(CXX_OBJS) $(DEPS) $(EXE) diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/CMakeLists.txt b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/CMakeLists.txt new file mode 100644 index 00000000000..be15282d4b6 --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/CMakeLists.txt @@ -0,0 +1,20 @@ +if(TARGET_LIKE_LINUX) +include("../includes.txt") +add_executable(m2mblockmessage + "main.cpp" + "m2mblockmessagetest.cpp" + "test_m2mblockmessage.cpp" + "../../../../source/m2mblockmessage.cpp" +) + +target_link_libraries(m2mblockmessage + CppUTest + CppUTestExt +) +set_target_properties(m2mblockmessage +PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" + LINK_FLAGS "${UTEST_LINK_FLAGS}") +set(binary "m2mblockmessage") +add_test(m2mblockmessage ${binary}) + +endif() diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/m2mblockmessagetest.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/m2mblockmessagetest.cpp new file mode 100644 index 00000000000..6e7e258a31b --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/m2mblockmessagetest.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//CppUTest includes should be after your and system includes +#include "CppUTest/TestHarness.h" +#include "test_m2mblockmessage.h" + +TEST_GROUP(M2MBlockMessage) +{ + Test_M2MBlockMessage* block_message; + void setup() + { + block_message = new Test_M2MBlockMessage(); + } + void teardown() + { + delete block_message; + } +}; + +TEST(M2MBlockMessage, Create) +{ + CHECK(block_message->block_message != NULL); +} + +TEST(M2MBlockMessage, test_set_message_info) +{ + block_message->test_set_message_info(); +} + diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/main.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/main.cpp new file mode 100644 index 00000000000..8b6e7a0104e --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/main.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/TestPlugin.h" +#include "CppUTest/TestRegistry.h" +#include "CppUTestExt/MockSupportPlugin.h" +int main(int ac, char** av) +{ + return CommandLineTestRunner::RunAllTests(ac, av); +} + +IMPORT_TEST_GROUP( M2MBlockMessage ); diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/test_m2mblockmessage.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/test_m2mblockmessage.cpp new file mode 100755 index 00000000000..f018b020c06 --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/test_m2mblockmessage.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "CppUTest/TestHarness.h" +#include "test_m2mblockmessage.h" +#include "sn_coap_header.h" +#include +Test_M2MBlockMessage::Test_M2MBlockMessage() +{ + block_message = new M2MBlockMessage(); +} + +Test_M2MBlockMessage::~Test_M2MBlockMessage() +{ + delete block_message; +} + +void Test_M2MBlockMessage::test_set_message_info() +{ + sn_coap_hdr_s *coap_header = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); + memset(coap_header, 0, sizeof(sn_coap_hdr_s)); + block_message->set_message_info(NULL); + CHECK(block_message->is_block_message() == false); + CHECK(block_message->total_message_size() == 0); + + coap_header->options_list_ptr = (sn_coap_options_list_s *)malloc(sizeof(sn_coap_options_list_s)); + memset(coap_header->options_list_ptr, 0, sizeof(sn_coap_options_list_s)); + coap_header->options_list_ptr->size1_ptr = (uint8_t*)malloc(2); + coap_header->options_list_ptr->size1_ptr[0] = 0xff; + coap_header->options_list_ptr->size1_ptr[1] = 0xff; + coap_header->options_list_ptr->size1_len = 2; + + block_message->set_message_info(coap_header); + CHECK(block_message->total_message_size() == 0xffff); + CHECK(!block_message->is_block_message()); + block_message->clear_values(); + + free(coap_header->options_list_ptr->size1_ptr); + coap_header->options_list_ptr->size1_ptr = NULL; + coap_header->options_list_ptr->size1_ptr = (uint8_t*)malloc(3); + coap_header->options_list_ptr->size1_ptr[0] = 0xff; + coap_header->options_list_ptr->size1_ptr[1] = 0xff; + coap_header->options_list_ptr->size1_ptr[2] = 0xff; + coap_header->options_list_ptr->size1_len = 3; + + block_message->set_message_info(coap_header); + CHECK(block_message->error_code() == M2MBlockMessage::EntityTooLarge); + block_message->clear_values(); + + coap_header->options_list_ptr->size1_len = 2; + coap_header->options_list_ptr->block1_ptr = (uint8_t *)malloc(3); + coap_header->options_list_ptr->block1_ptr[0] = 0x1; + coap_header->options_list_ptr->block1_ptr[1] = 0x1; + coap_header->options_list_ptr->block1_ptr[2] = 0x1; + coap_header->options_list_ptr->block1_len = 3; + block_message->set_message_info(coap_header); + CHECK(block_message->is_block_message()); + CHECK(block_message->block_number() == 4112); + block_message->clear_values(); + + coap_header->options_list_ptr->block1_len = 2; + block_message->set_message_info(coap_header); + CHECK(block_message->is_block_message()); + CHECK(block_message->block_number() == 16); + block_message->clear_values(); + + coap_header->options_list_ptr->block1_len = 1; + block_message->set_message_info(coap_header); + CHECK(block_message->is_block_message()); + CHECK(block_message->block_number() == 0); + block_message->clear_values(); + + coap_header->options_list_ptr->block1_len = 3; + coap_header->options_list_ptr->block1_ptr[0] = 0x1; + coap_header->options_list_ptr->block1_ptr[1] = 0x1; + coap_header->options_list_ptr->block1_ptr[2] = 0x8; + block_message->set_message_info(coap_header); + CHECK(!block_message->is_last_block()); + block_message->clear_values(); + + coap_header->payload_len = 10; + coap_header->payload_ptr = (uint8_t *)malloc(10); + memset(coap_header->payload_ptr, 'x', 10); + block_message->set_message_info(coap_header); + CHECK(!block_message->is_last_block()); + CHECK(block_message->block_data_len() == 10); + CHECK(memcmp(coap_header->payload_ptr, block_message->block_data(),10) == 0); + block_message->clear_values(); + + free(coap_header->payload_ptr); + free(coap_header->options_list_ptr->block1_ptr); + free(coap_header->options_list_ptr->size1_ptr); + free(coap_header->options_list_ptr); + free(coap_header); +} diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/test_m2mblockmessage.h b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/test_m2mblockmessage.h new file mode 100755 index 00000000000..64af1078462 --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mblockmessage/test_m2mblockmessage.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef TEST_M2M_BLOCKMESSAGE_H +#define TEST_M2M_BLOCKMESSAGE_H + +#include "m2mblockmessage.h" + +class Test_M2MBlockMessage +{ +public: + Test_M2MBlockMessage(); + virtual ~Test_M2MBlockMessage(); + + void test_set_message_info(); + + M2MBlockMessage* block_message; + +}; + +#endif // TEST_M2M_BLOCKMESSAGE_H + diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mnsdlinterface/test_m2mnsdlinterface.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mnsdlinterface/test_m2mnsdlinterface.cpp index be4b48418fe..68f82351ebc 100755 --- a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mnsdlinterface/test_m2mnsdlinterface.cpp +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mnsdlinterface/test_m2mnsdlinterface.cpp @@ -182,12 +182,14 @@ void Test_M2MNsdlInterface::test_create_nsdl_list_structure() m2mbase_stub::string_value = name; m2mbase_stub::mode_value = M2MBase::Static; + CHECK(nsdl->create_nsdl_list_structure(list)== true); m2mresource_stub::bool_value = true; m2mbase_stub::mode_value = M2MBase::Dynamic; m2mresource_stub::list.push_back(res_instance); + m2mresourceinstance_stub::base_type = M2MBase::Resource; CHECK(nsdl->create_nsdl_list_structure(list)== true); @@ -234,10 +236,10 @@ void Test_M2MNsdlInterface::test_create_bootstrap_resource() void Test_M2MNsdlInterface::test_send_register_message() { common_stub::uint_value = 12; - CHECK(nsdl->send_register_message(NULL,100,SN_NSDL_ADDRESS_TYPE_IPV6) == true); + CHECK(nsdl->send_register_message(NULL,4,100,SN_NSDL_ADDRESS_TYPE_IPV6) == true); common_stub::uint_value = 0; - CHECK(nsdl->send_register_message(NULL,100,SN_NSDL_ADDRESS_TYPE_IPV6) == false); + CHECK(nsdl->send_register_message(NULL,4,100,SN_NSDL_ADDRESS_TYPE_IPV6) == false); } void Test_M2MNsdlInterface::test_send_update_registration() @@ -899,7 +901,7 @@ void Test_M2MNsdlInterface::test_resource_callback() common_stub::int_value = 0; - coap_header->msg_code = COAP_MSG_CODE_REQUEST_GET; + common_stub::coap_header->msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; CHECK(nsdl->resource_callback(NULL,coap_header,address,SN_NSDL_PROTOCOL_HTTP) ==0); @@ -980,7 +982,7 @@ void Test_M2MNsdlInterface::test_resource_callback_put() common_stub::coap_header = (sn_coap_hdr_ *)malloc(sizeof(sn_coap_hdr_)); memset(common_stub::coap_header,0,sizeof(sn_coap_hdr_)); - + common_stub::coap_header->msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; CHECK(nsdl->resource_callback(NULL,coap_header,address,SN_NSDL_PROTOCOL_HTTP) ==0); m2mobject_stub::base_type = M2MBase::Resource; @@ -1074,7 +1076,7 @@ void Test_M2MNsdlInterface::test_resource_callback_post() common_stub::coap_header = (sn_coap_hdr_ *)malloc(sizeof(sn_coap_hdr_)); memset(common_stub::coap_header,0,sizeof(sn_coap_hdr_)); - + common_stub::coap_header->msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; CHECK(nsdl->resource_callback(NULL,coap_header,address,SN_NSDL_PROTOCOL_HTTP) ==0); m2mobject_stub::base_type = M2MBase::Resource; @@ -1141,7 +1143,7 @@ void Test_M2MNsdlInterface::test_resource_callback_delete() coap_header->uri_path_len = sizeof(value); coap_header->msg_code = COAP_MSG_CODE_REQUEST_DELETE; - + common_stub::coap_header->msg_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST; common_stub::int_value = 0; CHECK(nsdl->resource_callback(NULL,coap_header,address,SN_NSDL_PROTOCOL_HTTP) ==0); diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresource/test_m2mresource.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresource/test_m2mresource.cpp index 553e808aff3..bb0541074d0 100755 --- a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresource/test_m2mresource.cpp +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresource/test_m2mresource.cpp @@ -157,7 +157,7 @@ void Test_M2MResource::test_handle_observation_attribute() TestReportObserver obs; m2mbase_stub::report = new M2MReportHandler(obs); - m2mbase_stub::bool_value = true; + m2mbase_stub::bool_value = true; CHECK(false == resource->handle_observation_attribute(d)); resource->_resource_type = M2MResourceInstance::INTEGER; @@ -694,7 +694,7 @@ void Test_M2MResource::test_handle_put_request() } void Test_M2MResource::test_handle_post_request() -{ +{ uint8_t value[] = {"name"}; bool execute_value_updated = false; sn_coap_hdr_s *coap_header = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); @@ -733,7 +733,7 @@ void Test_M2MResource::test_handle_post_request() *coap_header->token_ptr = 1; coap_header->token_len = 1; - m2mbase_stub::bool_value = false; + m2mbase_stub::bool_value = false; m2mresourceinstance_stub::string_value = name; CHECK(resource->handle_post_request(NULL,coap_header,handler,execute_value_updated) != NULL); @@ -804,6 +804,15 @@ void Test_M2MResource::test_get_delayed_token() memcpy(resource->_delayed_token,value,1); resource->get_delayed_token(token,token_len); CHECK(token != NULL); + free(token); + + token = NULL; + token = (uint8_t*)malloc(1); + token_len = 1; + resource->get_delayed_token(token,token_len); + CHECK(token != NULL); + free(token); + } void Test_M2MResource::test_delayed_response() diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresourceinstance/CMakeLists.txt b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresourceinstance/CMakeLists.txt index f63ef1257db..ce5ad2ce823 100644 --- a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresourceinstance/CMakeLists.txt +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresourceinstance/CMakeLists.txt @@ -2,14 +2,15 @@ if(TARGET_LIKE_LINUX) include("../includes.txt") add_executable(m2mresourceinstance "../../../../source/m2mresourceinstance.cpp" - "main.cpp" + "main.cpp" "../stub/m2mbase_stub.cpp" "../stub/m2mstring_stub.cpp" "../stub/m2mtimer_stub.cpp" "../stub/m2mreporthandler_stub.cpp" "../stub/common_stub.cpp" "../stub/m2mtlvdeserializer_stub.cpp" - "m2mresourceinstancetest.cpp" + "../stub/m2mblockmessage_stub.cpp" + "m2mresourceinstancetest.cpp" "test_m2mresourceinstance.cpp" ) target_link_libraries(m2mresourceinstance diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresourceinstance/test_m2mresourceinstance.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresourceinstance/test_m2mresourceinstance.cpp index 5af453d8b7c..d3198987285 100755 --- a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresourceinstance/test_m2mresourceinstance.cpp +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/m2mresourceinstance/test_m2mresourceinstance.cpp @@ -22,6 +22,7 @@ #include "m2mreporthandler_stub.h" #include "common_stub.h" #include "m2mtlvdeserializer_stub.h" +#include "m2mblockmessage_stub.h" static bool cb_visited = false; static void callback_function(void *args) { @@ -33,8 +34,15 @@ class MyTest{ void execute_function(void */*argument*/) { visited = true; } - + void block_message_received(M2MBlockMessage */*argument*/) { + block_received = true; + } + void block_message_requested(const String& /*resource*/, uint8_t *&/*data*/, uint32_t &/*len*/) { + block_requested = true; + } bool visited; + bool block_received; + bool block_requested; }; class TestReportObserver : public M2MReportObserver{ @@ -93,7 +101,7 @@ class Callback : public M2MObjectInstanceCallback { Test_M2MResourceInstance::Test_M2MResourceInstance() { - callback = new Callback(); + callback = new Callback(); handler = new Handler(); resource_instance = new M2MResourceInstance("name", "resource_type", @@ -106,7 +114,7 @@ Test_M2MResourceInstance::~Test_M2MResourceInstance() { delete resource_instance; delete handler; - delete callback; + delete callback; } void Test_M2MResourceInstance::test_copy_constructor() @@ -211,7 +219,7 @@ void Test_M2MResourceInstance::test_execute() MyTest test; void *args = NULL; - resource_instance->set_execute_function(execute_callback(&test,&MyTest::execute_function)); + resource_instance->set_execute_function(execute_callback(&test,&MyTest::execute_function)); resource_instance->execute(args); cb_visited = false; @@ -264,7 +272,7 @@ void Test_M2MResourceInstance::test_set_value() resource_instance->_value = (u_int8_t*)malloc(sizeof(value)+1); memset(resource_instance->_value,0,sizeof(value)+1); memcpy(resource_instance->_value,value,sizeof(value)); - resource_instance->_value_length = sizeof(value); + resource_instance->_value_length = sizeof(value); TestReportObserver obs; m2mbase_stub::report = new M2MReportHandler(obs); @@ -324,7 +332,7 @@ void Test_M2MResourceInstance::test_clear_value() u_int8_t value[] = {"value"}; resource_instance->_value = (u_int8_t*)malloc(sizeof(u_int8_t)); - m2mbase_stub::observe = handler; + m2mbase_stub::observe = handler; TestReportObserver obs; m2mbase_stub::report = new M2MReportHandler(obs); @@ -411,6 +419,33 @@ void Test_M2MResourceInstance::test_handle_get_request() coap_header->content_type_ptr = NULL; } + if(common_stub::coap_header->content_type_ptr) { + free(common_stub::coap_header->content_type_ptr); + common_stub::coap_header->content_type_ptr = NULL; + } + if(common_stub::coap_header->options_list_ptr->max_age_ptr) { + free(common_stub::coap_header->options_list_ptr->max_age_ptr); + common_stub::coap_header->options_list_ptr->max_age_ptr = NULL; + } + if(common_stub::coap_header->options_list_ptr) { + free(common_stub::coap_header->options_list_ptr); + common_stub::coap_header->options_list_ptr = NULL; + } + MyTest test; + test.block_requested = false; + resource_instance->set_incoming_block_message_callback( + incoming_block_message_callback(&test, &MyTest::block_message_received)); + resource_instance->set_outgoing_block_message_callback( + outgoing_block_message_callback(&test,&MyTest::block_message_requested)); + m2mblockmessage_stub::is_block_message = true; + CHECK(resource_instance->handle_get_request(NULL,coap_header,handler) != NULL); + CHECK(test.block_requested == true); + m2mblockmessage_stub::is_block_message = false; + if(coap_header->content_type_ptr) { + free(coap_header->content_type_ptr); + coap_header->content_type_ptr = NULL; + } + if(common_stub::coap_header->content_type_ptr) { free(common_stub::coap_header->content_type_ptr); common_stub::coap_header->content_type_ptr = NULL; @@ -748,6 +783,49 @@ void Test_M2MResourceInstance::test_handle_put_request() } } + MyTest test; + test.block_received = false; + m2mbase_stub::operation = M2MBase::PUT_ALLOWED; + m2mblockmessage_stub::is_block_message = true; + m2mblockmessage_stub::is_last_block = false; + resource_instance->set_incoming_block_message_callback( + incoming_block_message_callback(&test, &MyTest::block_message_received)); + coap_response = resource_instance->handle_put_request(NULL,coap_header,handler,execute_value_updated); + CHECK(test.block_received == true); + CHECK( coap_response != NULL); + if(coap_response) { + if(coap_response->content_type_ptr) { + free(coap_response->content_type_ptr); + coap_response->content_type_ptr = NULL; + } + } + + test.block_received = false; + m2mblockmessage_stub::is_block_message = true; + m2mblockmessage_stub::is_last_block = true; + coap_response = resource_instance->handle_put_request(NULL,coap_header,handler,execute_value_updated); + CHECK(test.block_received == true); + CHECK( coap_response != NULL); + if(coap_response) { + if(coap_response->content_type_ptr) { + free(coap_response->content_type_ptr); + coap_response->content_type_ptr = NULL; + } + } + + test.block_received = false; + m2mblockmessage_stub::is_block_message = false; + m2mblockmessage_stub::is_last_block = false; + coap_response = resource_instance->handle_put_request(NULL,coap_header,handler,execute_value_updated); + CHECK(test.block_received == false); + CHECK( coap_response != NULL); + if(coap_response) { + if(coap_response->content_type_ptr) { + free(coap_response->content_type_ptr); + coap_response->content_type_ptr = NULL; + } + } + free(coap_header->content_type_ptr); free(coap_header->options_list_ptr); free(coap_header->payload_ptr); diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/common_stub.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/common_stub.cpp index af0ee476320..5296a14bc67 100644 --- a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/common_stub.cpp +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/common_stub.cpp @@ -199,7 +199,7 @@ int8_t sn_nsdl_update_resource(struct nsdl_s *, sn_nsdl_resource_info_s *) return common_stub::int_value; } -int8_t set_NSP_address(struct nsdl_s *, uint8_t *, uint16_t, sn_nsdl_addr_type_e) +int8_t set_NSP_address_2(struct nsdl_s *, uint8_t *, uint8_t, uint16_t, sn_nsdl_addr_type_e) { return common_stub::int_value; } diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mbase_stub.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mbase_stub.cpp index 5d3ba2ebf7a..884a35b4225 100755 --- a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mbase_stub.cpp +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mbase_stub.cpp @@ -286,7 +286,7 @@ sn_coap_hdr_s* M2MBase::handle_put_request(nsdl_s */*nsdl*/, sn_coap_hdr_s* M2MBase::handle_post_request(nsdl_s */*nsdl*/, sn_coap_hdr_s */*received_coap_header*/, M2MObservationHandler */*observation_handler*/, - bool &) + bool &, sn_nsdl_addr_s *address) { //Handled in M2MResource, M2MObjectInstance and M2MObject classes return NULL; diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mblockmessage_stub.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mblockmessage_stub.cpp new file mode 100755 index 00000000000..004f07ea9bc --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mblockmessage_stub.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "m2mblockmessage_stub.h" + +bool m2mblockmessage_stub::is_block_message; +bool m2mblockmessage_stub::is_last_block; +void m2mblockmessage_stub::clear() +{ + +} + +/* + * Copyright (c) 2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed-client/m2mblockmessage.h" +#include +#include +#include +M2MBlockMessage::M2MBlockMessage() +{ +} + +M2MBlockMessage::~M2MBlockMessage() +{ + +} + +void M2MBlockMessage::set_message_info(sn_coap_hdr_s *coap_header) +{ + +} + +void M2MBlockMessage::clear_values() +{ + +} + +bool M2MBlockMessage::is_block_message() const +{ + return m2mblockmessage_stub::is_block_message; +} + +uint16_t M2MBlockMessage::block_number() const +{ + +} + +uint32_t M2MBlockMessage::total_message_size() const +{ + +} + +bool M2MBlockMessage::is_last_block() const +{ + return m2mblockmessage_stub::is_last_block; +} + +uint8_t* M2MBlockMessage::block_data() const +{ + +} + +uint32_t M2MBlockMessage::block_data_len() const +{ + +} + +M2MBlockMessage::Error M2MBlockMessage::error_code() const +{ + +} diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mblockmessage_stub.h b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mblockmessage_stub.h new file mode 100755 index 00000000000..c06afdbde20 --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mblockmessage_stub.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef M2M_BLOCKMESSAGE_STUB_H +#define M2M_BLOCKMESSAGE_STUB_H + +#include "m2mblockmessage.h" + +//some internal test related stuff +namespace m2mblockmessage_stub +{ + extern bool is_block_message; + extern bool is_last_block; + void clear(); +} + +#endif // M2M_BLOCKMESSAGE_STUB_H + diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mnsdlinterface_stub.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mnsdlinterface_stub.cpp index f77c1eb260e..0ac58059656 100755 --- a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mnsdlinterface_stub.cpp +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mnsdlinterface_stub.cpp @@ -71,6 +71,7 @@ bool M2MNsdlInterface::create_bootstrap_resource(sn_nsdl_addr_s *, const String& } bool M2MNsdlInterface::send_register_message(uint8_t*, + uint8_t, const uint16_t, sn_nsdl_addr_type_e) { diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mresource_stub.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mresource_stub.cpp index cd2c2576e17..3506d90aa8b 100755 --- a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mresource_stub.cpp +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mresource_stub.cpp @@ -20,7 +20,7 @@ uint8_t* m2mresource_stub::delayed_token; uint8_t m2mresource_stub::delayed_token_len; bool m2mresource_stub::bool_value; -// The statically initialized list must be bigh enough to cater +// The statically initialized list must be bigh enough to cater // for all the tests, or the utest framework will complain for memory leak. M2MResourceInstanceList m2mresource_stub::list(12); @@ -156,7 +156,7 @@ sn_coap_hdr_s* M2MResource::handle_put_request(nsdl_s *, sn_coap_hdr_s* M2MResource::handle_post_request(nsdl_s *, sn_coap_hdr_s *, M2MObservationHandler *, - bool &) + bool &, sn_nsdl_addr_s *) { return m2mresource_stub::header; } diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mresourceinstance_stub.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mresourceinstance_stub.cpp index 794da3e30ff..304c7e348ce 100755 --- a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mresourceinstance_stub.cpp +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mresourceinstance_stub.cpp @@ -213,3 +213,17 @@ uint16_t M2MResourceInstance::object_instance_id() const void M2MResourceInstance::set_execute_function(execute_callback_2 callback) { } + +M2MBlockMessage* M2MResourceInstance::block_message() const +{ + +} + +void M2MResourceInstance::set_incoming_block_message_callback(incoming_block_message_callback callback) +{ +} + +void M2MResourceInstance::set_outgoing_block_message_callback(outgoing_block_message_callback callback) +{ + +} diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient_linux/Makefile b/features/FEATURE_CLIENT/mbed-client/test/mbedclient_linux/Makefile new file mode 100644 index 00000000000..bfcdd6b1e4f --- /dev/null +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient_linux/Makefile @@ -0,0 +1,17 @@ +PLATFORM= +OS = LINUX +TARGET = mbedclient_linux +OBJECTS = main.o +CFLAGS = -std=c++11 -Wall -D_REENTRANT -D$(OS) -I ../../lwm2m-client -I ../../source/include -I ../../../../libService/libService -I ../../ -DTARGET_LIKE_LINUX -DHAVE_DEBUG +LDFLAGS = -D_REENTRANT -L../../ -lmbedclient_gcc -L ../../../../nsdl-c -lnsdl_gcc -L ../../../../libService -lservice_gcc -L ../../../../mbedtls/library -lmbedtls -lmbedx509 -lmbedcrypto -lpthread +all: $(TARGET) + +$(TARGET): $(OBJECTS) + $(PLATFORM)g++ -g -o $(TARGET) $(OBJECTS) $(LDFLAGS) + +.cpp.o: + $(PLATFORM)g++ -c -g -O2 $(CFLAGS) $< + +clean: + rm -f $(TARGET) $(OBJECTS) + diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/CHANGELOG.md b/features/FEATURE_COMMON_PAL/mbed-client-c/CHANGELOG.md new file mode 100644 index 00000000000..6358aa3d14b --- /dev/null +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/CHANGELOG.md @@ -0,0 +1,78 @@ +# Change Log + +## [v2.9.0](https://github.com/ARMmbed/mbed-client-c/releases/tag/v2.9.0) (05-Sep-2016) +[Full Changelog](https://github.com/ARMmbed/mbed-client-c/compare/mbed-os-5.0-rc1...v2.9.0) + +** New feature ** + +- Add option to pass incoming blocks to application instead storing them internally +- Added API for deleting one message from resending + +**Closed issues:** + +- IOTCLT-1001 - mDS does not sent RST anymore for Client after DELETE /subscriptions + +**Merged pull requests:** + +commit 45e836b9a7b9a46dc9a97c7aae5570cb00f2d284 (HEAD, tag: v2.9.0, origin/master, origin/HEAD, master) +Author: Teemu Takaluoma +Date: Mon Sep 5 15:27:34 2016 +0300 + + version v2.9.0 + +commit 9022e05adb231fd8f619bb4fc2b0f05da99413a9 +Merge: ec0b281 87dfd6f +Author: Teemu Takaluoma +Date: Mon Sep 5 15:26:26 2016 +0300 + + Merge pull request #73 from ARMmbed/IOTCLT-1001 + + implement platform agnostic IP handling, Iotclt 1001 + +commit 87dfd6f11fc5a8a724e090e34540a8fc9bf8b290 +Author: Teemu Takaluoma +Date: Mon Sep 5 08:51:21 2016 +0300 + + add unit test + +commit b8ddefdcbfb58d355e170e8411eebc23ffe3c25c +Author: Teemu Takaluoma +Date: Sat Sep 3 14:14:28 2016 +0300 + + refactor address handling + +commit d89b6266fd52322fd7beafcd51365c980afbff05 +Author: Teemu Takaluoma +Date: Sat Sep 3 14:10:31 2016 +0300 + + Fix for IOTCLT-1001, implement platform agnostic IP handling + +commit ec0b281264f4859f28cfe207b89816835c56f392 (tag: v2.8.0) +Author: Antti Yli-Tokola +Date: Fri Aug 12 14:33:56 2016 +0300 + + version v2.8.0 + +commit 5ab0f01c31d6551547388307e0c0cfda272b611e +Author: Antti Yli-Tokola +Date: Fri Aug 12 14:30:24 2016 +0300 + + Add option to pass incoming blocks to application instead storing them internally (#71) + + * Add option to pass incoming blocks to application. If external_memory_block variable is set blocks are passed into application and not stored anymore internally. + +commit 168739c81618d105bfb3ccf77d14b0d38340ba6b +Merge: 758fd1e fbe4eeb +Author: Antti Yli-Tokola +Date: Wed Aug 10 12:49:42 2016 +0300 + + Merge pull request #65 from ARMmbed/retransmission_delete + + Added API for deleting one message from resending + +commit fbe4eeb8db1c7ed107dc3da6fd2fa5e3e9062ccb (origin/retransmission_delete) +Author: Tero Heinonen +Date: Fri Aug 5 11:48:17 2016 +0300 + + Added API for deleting one message from resending + queue. diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/Makefile b/features/FEATURE_COMMON_PAL/mbed-client-c/Makefile new file mode 100644 index 00000000000..7371210d28e --- /dev/null +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/Makefile @@ -0,0 +1,45 @@ +# +# Makefile for combined NSDL+COAP library +# + +# Define compiler toolchain with CC or PLATFORM variables +# Example (GCC toolchains, default $CC and $AR are used) +# make +# +# OR (Cross-compile GCC toolchain) +# make PLATFORM=arm-linux-gnueabi- +# +# OR (armcc/Keil) +# make CC=armcc AR=ArmAR +# +# OR (IAR-ARM) +# make CC=iccarm + +LIB = libnsdl.a +SRCS := \ + source/libNsdl/src/sn_grs.c \ + source/libNsdl/src/sn_nsdl.c \ + source/libCoap/src/sn_coap_protocol.c \ + source/libCoap/src/sn_coap_parser.c \ + source/libCoap/src/sn_coap_header_check.c \ + source/libCoap/src/sn_coap_builder.c \ + +override CFLAGS += -DVERSION='"$(VERSION)"' + +override CFLAGS += -Isource/libNsdl/src/include/ +override CFLAGS += -Isource/libCoap/src/include/ +SERVLIB_DIR := ../libService +override CFLAGS += -I$(SERVLIB_DIR)/libService +override CFLAGS += -Insdl-c/ + +include ../libService/toolchain_rules.mk + +$(eval $(call generate_rules,$(LIB),$(SRCS))) + +.PHONY: release +release: + 7z a nsdl-c_$(VERSION).zip *.a *.lib include + +.PHONY: deploy_to +deploy_to: all + tar --transform 's,^,nsdl-c/,' --append -f $(TO) *.a nsdl-c diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/module.json b/features/FEATURE_COMMON_PAL/mbed-client-c/module.json index 9f6ddcfffc6..6b38dfaec23 100644 --- a/features/FEATURE_COMMON_PAL/mbed-client-c/module.json +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/module.json @@ -1,6 +1,6 @@ { "name": "mbed-client-c", - "version": "2.7.7", + "version": "2.9.0", "description": "Nanostack NSDL and COAP library", "keywords": [ "coap", diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/nsdl-c/sn_coap_protocol.h b/features/FEATURE_COMMON_PAL/mbed-client-c/nsdl-c/sn_coap_protocol.h index f3959f453df..add1e94a92b 100644 --- a/features/FEATURE_COMMON_PAL/mbed-client-c/nsdl-c/sn_coap_protocol.h +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/nsdl-c/sn_coap_protocol.h @@ -188,6 +188,30 @@ extern int8_t sn_coap_protocol_set_retransmission_buffer(struct coap_s *handle, */ extern void sn_coap_protocol_clear_retransmission_buffer(struct coap_s *handle); +/** + * \fn sn_coap_protocol_block_remove + * + * \brief Remove saved block data. Can be used to remove the data from RAM to enable storing it to other place. + * + * \param handle Pointer to CoAP library handle + * \param source_address Addres from where the block has been received. + * \param payload_length Length of the coap payload of the block. + * \param payload Coap payload of the block. + * + */ +extern void sn_coap_protocol_block_remove(struct coap_s *handle, sn_nsdl_addr_s *source_address, uint16_t payload_length, void *payload); + +/** + * \fn void sn_coap_protocol_delete_retransmission(struct coap_s *handle) + * + * \param *handle Pointer to CoAP library handle + * \msg_id message ID to be removed + * \return returns 0 when success, -1 for invalid parameter, -2 if message was not found + * + * \brief If re-transmissions are enabled, this function removes message from retransmission buffer. + */ +extern int8_t sn_coap_protocol_delete_retransmission(struct coap_s *handle, uint16_t msg_id); + #endif /* SN_COAP_PROTOCOL_H_ */ #ifdef __cplusplus diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/nsdl-c/sn_nsdl_lib.h b/features/FEATURE_COMMON_PAL/mbed-client-c/nsdl-c/sn_nsdl_lib.h old mode 100644 new mode 100755 index c6ee7ff5e03..deda839f53a --- a/features/FEATURE_COMMON_PAL/mbed-client-c/nsdl-c/sn_nsdl_lib.h +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/nsdl-c/sn_nsdl_lib.h @@ -201,6 +201,8 @@ typedef struct sn_nsdl_resource_info_ { uint8_t publish_uri; + uint8_t external_memory_block; + } sn_nsdl_resource_info_s; /** @@ -555,6 +557,17 @@ extern int8_t sn_nsdl_send_coap_message(struct nsdl_s *handle, sn_nsdl_addr_s *a */ extern int8_t set_NSP_address(struct nsdl_s *handle, uint8_t *NSP_address, uint16_t port, sn_nsdl_addr_type_e address_type); +/** + * \fn extern int8_t set_NSP_address(struct nsdl_s *handle, uint8_t *NSP_address, uint8_t address_length, uint16_t port, sn_nsdl_addr_type_e address_type); + * + * \brief This function is used to set the mbed Device Server address given by an application. + * + * \param *handle Pointer to nsdl-library handle + * \return 0 Success + * \return -1 Failed to indicate that internal address pointer is not allocated (call nsdl_init() first). + */ +extern int8_t set_NSP_address_2(struct nsdl_s *handle, uint8_t *NSP_address, uint8_t address_length, uint16_t port, sn_nsdl_addr_type_e address_type); + /** * \fn extern int8_t sn_nsdl_destroy(struct nsdl_s *handle); * diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/run_unit_tests.sh b/features/FEATURE_COMMON_PAL/mbed-client-c/run_unit_tests.sh old mode 100644 new mode 100755 diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/run_unit_tests_with_valgrind.sh b/features/FEATURE_COMMON_PAL/mbed-client-c/run_unit_tests_with_valgrind.sh old mode 100644 new mode 100755 diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/source/libCoap/src/include/sn_coap_protocol_internal.h b/features/FEATURE_COMMON_PAL/mbed-client-c/source/libCoap/src/include/sn_coap_protocol_internal.h index bb536e1cf9d..7cedb2fc219 100644 --- a/features/FEATURE_COMMON_PAL/mbed-client-c/source/libCoap/src/include/sn_coap_protocol_internal.h +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/source/libCoap/src/include/sn_coap_protocol_internal.h @@ -98,6 +98,15 @@ extern "C" { #define SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED 10 /**< Maximum time in seconds of data (messages and payload) to be stored for blockwising */ #endif +#ifdef YOTTA_CFG_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE +#define SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE YOTTA_CFG_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE +#elif defined MBED_CONF_MBED_CLIENT_SN_COAP_MAX_INCOMING_MESSAGE_SIZE +#define SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE MBED_CONF_MBED_CLIENT_SN_COAP_MAX_INCOMING_MESSAGE_SIZE +#endif + +#ifndef SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE +#define SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE UINT16_MAX +#endif /* * * * * * * * * * * * * * */ diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/source/libCoap/src/sn_coap_protocol.c b/features/FEATURE_COMMON_PAL/mbed-client-c/source/libCoap/src/sn_coap_protocol.c index ada7e66cdf9..76ef0bd5b5a 100644 --- a/features/FEATURE_COMMON_PAL/mbed-client-c/source/libCoap/src/sn_coap_protocol.c +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/source/libCoap/src/sn_coap_protocol.c @@ -327,6 +327,27 @@ void sn_coap_protocol_clear_retransmission_buffer(struct coap_s *handle) #endif } +int8_t sn_coap_protocol_delete_retransmission(struct coap_s *handle, uint16_t msg_id) +{ +#if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */ + if (handle == NULL) { + return -1; + } + ns_list_foreach_safe(coap_send_msg_s, tmp, &handle->linked_list_resent_msgs) { + if (tmp->send_msg_ptr && tmp->send_msg_ptr->packet_ptr ) { + uint16_t temp_msg_id = (tmp->send_msg_ptr->packet_ptr[2] << 8); + temp_msg_id += (uint16_t)tmp->send_msg_ptr->packet_ptr[3]; + if(temp_msg_id == msg_id){ + ns_list_remove(&handle->linked_list_resent_msgs, tmp); + --handle->count_resent_msgs; + sn_coap_protocol_release_allocated_send_msg_mem(handle, tmp); + return 0; + } + } + } +#endif + return -2; +} int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, void *param) @@ -1508,8 +1529,38 @@ static uint16_t sn_coap_count_linked_list_size(const coap_send_msg_list_t *linke #endif -#if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */ +#if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE +void sn_coap_protocol_block_remove(struct coap_s *handle, sn_nsdl_addr_s *source_address, uint16_t payload_length, void *payload) +{ + if(!handle || !source_address || !payload){ + return; + } + + /* Loop all stored blockwise payloads in Linked list */ + ns_list_foreach(coap_blockwise_payload_s, stored_payload_info_ptr, &handle->linked_list_blockwise_received_payloads) { + /* If payload's Source address is not the same than is searched */ + if (memcmp(source_address->addr_ptr, stored_payload_info_ptr->addr_ptr, source_address->addr_len)) { + continue; + } + + /* If payload's Source address port is not the same than is searched */ + if (stored_payload_info_ptr->port != source_address->port) { + continue; + } + /* Check the payload */ + if(payload_length != stored_payload_info_ptr->payload_len){ + continue; + } + + if(!memcmp(stored_payload_info_ptr->payload_ptr, payload, stored_payload_info_ptr->payload_len)) + { + /* Everything matches, remove and return. */ + sn_coap_protocol_linked_list_blockwise_payload_remove(handle, stored_payload_info_ptr); + return; + } + } +} /**************************************************************************//** * \fn static int8_t sn_coap_handle_blockwise_message(void) * @@ -1709,13 +1760,26 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn } tr_debug("sn_coap_handle_blockwise_message - block1 received - incoming size: [%d]", total_message_size); - if (total_message_size > UINT16_MAX) { + uint32_t max_size = SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE; + if (total_message_size > max_size) { + // Include maximum size that stack can handle into response src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE; - src_coap_blockwise_ack_msg_ptr->options_list_ptr->size1_ptr = handle->sn_coap_protocol_malloc(2); + uint8_t size = 0; + if(max_size < 0xFF) { + size = 1; + } else if(max_size < 0xFFFF) { + size = 2; + } else if(max_size < 0xFFFFFF) { + size = 3; + } else if(max_size < 0xFFFFFFFF) { + size = 4; + } + src_coap_blockwise_ack_msg_ptr->options_list_ptr->size1_ptr = handle->sn_coap_protocol_malloc(size); if (src_coap_blockwise_ack_msg_ptr->options_list_ptr->size1_ptr) { - src_coap_blockwise_ack_msg_ptr->options_list_ptr->size1_ptr[0] = 0xff; - src_coap_blockwise_ack_msg_ptr->options_list_ptr->size1_ptr[1] = 0xff; - src_coap_blockwise_ack_msg_ptr->options_list_ptr->size1_len = 2; + for (int i = 0; i < size; i++) { + src_coap_blockwise_ack_msg_ptr->options_list_ptr->size1_ptr[i] = (max_size >> ((size - i - 1) * 8)); + } + src_coap_blockwise_ack_msg_ptr->options_list_ptr->size1_len = size; } } else if (received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) { src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_CONTENT; diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/include/sn_grs.h b/features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/include/sn_grs.h old mode 100644 new mode 100755 diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_grs.c b/features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_grs.c old mode 100644 new mode 100755 index 7c868b2e409..f1dd0cd15cb --- a/features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_grs.c +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_grs.c @@ -827,6 +827,7 @@ static int8_t sn_grs_add_resource_to_list(struct grs_s *handle, sn_nsdl_resource resource_copy_ptr->sn_grs_dyn_res_callback = resource_ptr->sn_grs_dyn_res_callback; resource_copy_ptr->access = resource_ptr->access; resource_copy_ptr->publish_uri = resource_ptr->publish_uri; + resource_copy_ptr->external_memory_block = resource_ptr->external_memory_block; /* Remove '/' - chars from the beginning and from the end */ diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_nsdl.c b/features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_nsdl.c old mode 100644 new mode 100755 index 3827500fd6c..9ce2090c335 --- a/features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_nsdl.c +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_nsdl.c @@ -482,7 +482,7 @@ int8_t sn_nsdl_set_endpoint_location(struct nsdl_s *handle, uint8_t *location_pt if(!handle || !location_ptr || (location_len == 0)) { return -1; } - + handle->sn_nsdl_free(handle->ep_information_ptr->location_ptr); handle->ep_information_ptr->location_ptr = handle->sn_nsdl_alloc(location_len); memcpy(handle->ep_information_ptr->location_ptr, location_ptr, location_len); @@ -875,7 +875,7 @@ int8_t sn_nsdl_process_coap(struct nsdl_s *handle, uint8_t *packet_ptr, uint16_t { sn_coap_hdr_s *coap_packet_ptr = NULL; sn_coap_hdr_s *coap_response_ptr = NULL; - + sn_nsdl_resource_info_s *resource = NULL; /* Check parameters */ if (handle == NULL) { return SN_NSDL_FAILURE; @@ -888,9 +888,24 @@ int8_t sn_nsdl_process_coap(struct nsdl_s *handle, uint8_t *packet_ptr, uint16_t if (coap_packet_ptr == (sn_coap_hdr_s *)NULL) { return SN_NSDL_FAILURE; } - +#if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE + // Pass block to application if external_memory_block is set + if(coap_packet_ptr->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING) { + resource = sn_nsdl_get_resource(handle, coap_packet_ptr->uri_path_len, coap_packet_ptr->uri_path_ptr); + if(resource && resource->external_memory_block) { + sn_coap_protocol_block_remove(handle->grs->coap, + src_ptr, + coap_packet_ptr->payload_len, + coap_packet_ptr->payload_ptr); + } else { + resource = NULL; + } + } +#endif /* Check, if coap itself sends response, or block receiving is ongoing... */ - if (coap_packet_ptr->coap_status != COAP_STATUS_OK && coap_packet_ptr->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) { + if (coap_packet_ptr->coap_status != COAP_STATUS_OK && + coap_packet_ptr->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED &&coap_packet_ptr && + !resource) { sn_coap_parser_release_allocated_coap_msg_mem(handle->grs->coap, coap_packet_ptr); return SN_NSDL_SUCCESS; } @@ -1851,6 +1866,33 @@ int8_t set_NSP_address(struct nsdl_s *handle, uint8_t *NSP_address, uint16_t por return SN_NSDL_SUCCESS; } +extern int8_t set_NSP_address_2(struct nsdl_s *handle, uint8_t *NSP_address, uint8_t address_length, uint16_t port, sn_nsdl_addr_type_e address_type) +{ + /* Check parameters and source pointers */ + if (!handle || !handle->nsp_address_ptr || !handle->nsp_address_ptr->omalw_address_ptr || !NSP_address) { + return SN_NSDL_FAILURE; + } + + handle->nsp_address_ptr->omalw_address_ptr->type = address_type; + handle->nsp_address_ptr->omalw_server_security = SEC_NOT_SET; + + if (handle->nsp_address_ptr->omalw_address_ptr->addr_ptr) { + handle->sn_nsdl_free(handle->nsp_address_ptr->omalw_address_ptr->addr_ptr); + } + + handle->nsp_address_ptr->omalw_address_ptr->addr_len = address_length; + + handle->nsp_address_ptr->omalw_address_ptr->addr_ptr = handle->sn_nsdl_alloc(handle->nsp_address_ptr->omalw_address_ptr->addr_len); + if (!handle->nsp_address_ptr->omalw_address_ptr->addr_ptr) { + return SN_NSDL_FAILURE; + } + + memcpy(handle->nsp_address_ptr->omalw_address_ptr->addr_ptr, NSP_address, handle->nsp_address_ptr->omalw_address_ptr->addr_len); + handle->nsp_address_ptr->omalw_address_ptr->port = port; + + return SN_NSDL_SUCCESS; +} + static uint8_t sn_nsdl_itoa_len(uint8_t value) { diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/multithread-linux-test/tester.sh b/features/FEATURE_COMMON_PAL/mbed-client-c/test/multithread-linux-test/tester.sh old mode 100644 new mode 100755 diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/Makefile b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/Makefile new file mode 100755 index 00000000000..c03b7dc6ead --- /dev/null +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/Makefile @@ -0,0 +1,19 @@ +#scan for folders having "Makefile" in them and remove 'this' to prevent loop +DIRS := $(filter-out ./, $(sort $(dir $(shell find . -name 'Makefile')))) + +all: + for dir in $(DIRS); do \ + cd $$dir; make gcov; cd ..;\ + done + +clean: + for dir in $(DIRS); do \ + cd $$dir; make clean; cd ..;\ + done + rm -rf ../source/*gcov ../source/*gcda ../source/*o + rm -rf stubs/*gcov stubs/*gcda stubs/*o + rm -rf results/* + rm -rf coverages/* + rm -rf results + rm -rf coverages + diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/MakefileWorker.mk b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/MakefileWorker.mk old mode 100644 new mode 100755 diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/makefile_defines.txt b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/makefile_defines.txt old mode 100644 new mode 100755 diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/run_tests b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/run_tests old mode 100644 new mode 100755 diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_builder/Makefile b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_builder/Makefile new file mode 100755 index 00000000000..82ef67b86f4 --- /dev/null +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_builder/Makefile @@ -0,0 +1,16 @@ +include ../makefile_defines.txt + +COMPONENT_NAME = sn_coap_builder_unit +SRC_FILES = \ + ../../../../source/libCoap/src/sn_coap_builder.c + +TEST_SRC_FILES = \ + main.cpp \ + libCoap_builder_test.cpp \ + ../stubs/sn_coap_header_check_stub.c \ + ../stubs/sn_coap_parser_stub.c \ + +include ../MakefileWorker.mk + + + diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_header_check/Makefile b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_header_check/Makefile new file mode 100755 index 00000000000..53623cd184b --- /dev/null +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_header_check/Makefile @@ -0,0 +1,14 @@ +include ../makefile_defines.txt + +COMPONENT_NAME = sn_coap_header_check_unit +SRC_FILES = \ + ../../../../source/libCoap/src/sn_coap_header_check.c + +TEST_SRC_FILES = \ + main.cpp \ + libCoap_header_test.cpp \ + +include ../MakefileWorker.mk + +CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT + diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_parser/Makefile b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_parser/Makefile new file mode 100644 index 00000000000..41230e994d1 --- /dev/null +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_parser/Makefile @@ -0,0 +1,17 @@ +include ../makefile_defines.txt + +COMPONENT_NAME = sn_coap_parser_unit + +#This must be changed manually +SRC_FILES = \ + ../../../../source/libCoap/src/sn_coap_parser.c + +TEST_SRC_FILES = \ + main.cpp \ + sn_coap_parsertest.cpp \ + test_sn_coap_parser.c \ + +include ../MakefileWorker.mk + +CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT + diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_protocol/Makefile b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_protocol/Makefile new file mode 100644 index 00000000000..533d0229b80 --- /dev/null +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_protocol/Makefile @@ -0,0 +1,17 @@ +include ../makefile_defines.txt + +COMPONENT_NAME = sn_coap_protocol_unit +SRC_FILES = \ + ../../../../source/libCoap/src/sn_coap_protocol.c + +TEST_SRC_FILES = \ + main.cpp \ + libCoap_protocol_test.cpp \ + ../stubs/sn_coap_builder_stub.c \ + ../stubs/sn_coap_parser_stub.c \ + ../stubs/sn_coap_header_check_stub.c \ + ../stubs/ns_list_stub.c \ + +include ../MakefileWorker.mk + +CPPUTESTFLAGS += -DSN_COAP_DUPLICATION_MAX_MSGS_COUNT=4 -DYOTTA_CFG_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE=16 -DENABLE_RESENDINGS=1 -DSN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE=65535 diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_protocol/libCoap_protocol_test.cpp b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_protocol/libCoap_protocol_test.cpp index 0079a0c0a85..88f0cb82c70 100644 --- a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_protocol/libCoap_protocol_test.cpp +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_coap_protocol/libCoap_protocol_test.cpp @@ -143,9 +143,40 @@ TEST(libCoap_protocol, sn_coap_protocol_set_retransmission_buffer) //{ // sn_coap_protocol_clear_retransmission_buffer(); //} - #include +TEST(libCoap_protocol, sn_coap_protocol_delete_retransmission) +{ +#if ENABLE_RESENDINGS + retCounter = 6; + sn_nsdl_addr_s dst_addr_ptr; + sn_coap_hdr_s src_coap_msg_ptr; + uint8_t temp_addr[4] = {0}; + uint8_t dst_packet_data_ptr[4] = {0x40, 0x00, 0x00, 0x63}; + + memset(&dst_addr_ptr, 0, sizeof(sn_nsdl_addr_s)); + memset(&src_coap_msg_ptr, 0, sizeof(sn_coap_hdr_s)); + + dst_addr_ptr.addr_ptr = temp_addr; + dst_addr_ptr.addr_len = 4; + dst_addr_ptr.type = SN_NSDL_ADDRESS_TYPE_IPV4; + + struct coap_s * handle = sn_coap_protocol_init(myMalloc, myFree, null_tx_cb, NULL); + + CHECK( -1 == sn_coap_protocol_delete_retransmission(NULL, 0)); + + CHECK( -2 == sn_coap_protocol_delete_retransmission(handle, 0)); + + sn_coap_builder_stub.expectedInt16 = 4; + + CHECK( 0 < sn_coap_protocol_build(handle, &dst_addr_ptr, dst_packet_data_ptr, &src_coap_msg_ptr, NULL)); + + CHECK( 0 == sn_coap_protocol_delete_retransmission(handle, 99)); + + sn_coap_protocol_destroy(handle); +#endif +} + TEST(libCoap_protocol, sn_coap_protocol_build) { retCounter = 1; @@ -2293,3 +2324,76 @@ TEST(libCoap_protocol, sn_coap_protocol_exec2) sn_coap_protocol_destroy(handle); } +TEST(libCoap_protocol, sn_coap_protocol_block_remove) +{ + sn_coap_protocol_block_remove(0,0,0,0); + retCounter = 9; + sn_nsdl_addr_s* addr = (sn_nsdl_addr_s*)malloc(sizeof(sn_nsdl_addr_s)); + memset(addr, 0, sizeof(sn_nsdl_addr_s)); + addr->addr_ptr = (uint8_t*)malloc(5); + memset(addr->addr_ptr,'a',5); + addr->addr_len = 5; + struct coap_s * handle = sn_coap_protocol_init(myMalloc, myFree, null_tx_cb, NULL); + uint8_t *packet_data_ptr = (uint8_t*)malloc(5); + memset(packet_data_ptr,'x',5); + uint16_t packet_data_len = 5; + sn_coap_parser_stub.expectedHeader = NULL; + sn_coap_parser_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); + memset(sn_coap_parser_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); + sn_coap_parser_stub.expectedHeader->msg_type = COAP_MSG_TYPE_ACKNOWLEDGEMENT; + sn_coap_parser_stub.expectedHeader->msg_id = 13; + + sn_coap_options_list_s* list = (sn_coap_options_list_s*)malloc(sizeof(sn_coap_options_list_s)); + memset(list, 0, sizeof(sn_coap_options_list_s)); + sn_coap_parser_stub.expectedHeader->options_list_ptr = list; + sn_coap_parser_stub.expectedHeader->options_list_ptr->block1_ptr = (uint8_t*)malloc(1); + sn_coap_parser_stub.expectedHeader->options_list_ptr->block1_len = 1; + sn_coap_parser_stub.expectedHeader->options_list_ptr->block1_ptr[0] = 0x08; + sn_coap_parser_stub.expectedHeader->msg_type = COAP_MSG_TYPE_CONFIRMABLE; + sn_coap_parser_stub.expectedHeader->msg_code = COAP_MSG_CODE_REQUEST_PUT; + uint8_t* payload = (uint8_t*)malloc(17); + sn_coap_parser_stub.expectedHeader->payload_ptr = packet_data_ptr; + sn_coap_parser_stub.expectedHeader->payload_len = packet_data_len; + sn_coap_builder_stub.expectedUint16 = 1; + + // Success + retCounter = 9; + sn_coap_protocol_parse(handle, addr, packet_data_len, packet_data_ptr, NULL); + CHECK(ns_list_count(&handle->linked_list_blockwise_received_payloads) == 1); + sn_coap_protocol_block_remove(handle,addr,packet_data_len,packet_data_ptr); + CHECK(ns_list_count(&handle->linked_list_blockwise_received_payloads) == 0); + + // Ports does not match + retCounter = 18; + sn_coap_parser_stub.expectedHeader->msg_id = 14; + addr->port = 5600; + sn_coap_protocol_parse(handle, addr, packet_data_len, packet_data_ptr, NULL); + CHECK(ns_list_count(&handle->linked_list_blockwise_received_payloads) == 1); + addr->port = 5601; + sn_coap_protocol_block_remove(handle,addr,packet_data_len,packet_data_ptr); + CHECK(ns_list_count(&handle->linked_list_blockwise_received_payloads) == 1); + + // Addresses does not match + retCounter = 18; + sn_coap_parser_stub.expectedHeader->msg_id = 15; + sn_coap_protocol_parse(handle, addr, packet_data_len, packet_data_ptr, NULL); + CHECK(ns_list_count(&handle->linked_list_blockwise_received_payloads) == 2); + addr->addr_ptr[0] = 'x'; + sn_coap_protocol_block_remove(handle,addr,packet_data_len,packet_data_ptr); + CHECK(ns_list_count(&handle->linked_list_blockwise_received_payloads) == 2); + + // Payload length does not match + addr->addr_ptr[0] = 'a'; + sn_coap_protocol_block_remove(handle,addr,packet_data_len+1,packet_data_ptr); + CHECK(ns_list_count(&handle->linked_list_blockwise_received_payloads) == 2); + + free(sn_coap_parser_stub.expectedHeader->options_list_ptr->block1_ptr); + free(sn_coap_parser_stub.expectedHeader->options_list_ptr); + free(sn_coap_parser_stub.expectedHeader); + free(addr->addr_ptr); + free(addr); + free(payload); + free(packet_data_ptr); + sn_coap_protocol_destroy(handle); +} + diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_grs/Makefile b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_grs/Makefile new file mode 100644 index 00000000000..8cc88e776cc --- /dev/null +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_grs/Makefile @@ -0,0 +1,20 @@ +include ../makefile_defines.txt + +COMPONENT_NAME = sn_grs_unit + +#This must be changed manually +SRC_FILES = \ + ../../../../source/libNsdl/src/sn_grs.c + +TEST_SRC_FILES = \ + main.cpp \ + sn_grstest.cpp \ + test_sn_grs.c \ + ../stubs/sn_coap_protocol_stub.c \ + ../stubs/sn_coap_parser_stub.c \ + ../stubs/sn_coap_builder_stub.c \ + ../stubs/sn_nsdl_stub.c \ + ../stubs/ns_list_stub.c \ + +include ../MakefileWorker.mk + diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_nsdl/Makefile b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_nsdl/Makefile new file mode 100644 index 00000000000..c263ff4d420 --- /dev/null +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_nsdl/Makefile @@ -0,0 +1,21 @@ +include ../makefile_defines.txt + +COMPONENT_NAME = sn_nsdl_unit + +#This must be changed manually +SRC_FILES = \ + ../../../../source/libNsdl/src/sn_nsdl.c + +TEST_SRC_FILES = \ + main.cpp \ + sn_nsdltest.cpp \ + test_sn_nsdl.c \ + ../stubs/sn_coap_protocol_stub.c \ + ../stubs/sn_grs_stub.c \ + ../stubs/sn_coap_parser_stub.c \ + ../stubs/sn_coap_builder_stub.c \ + +include ../MakefileWorker.mk + +CPPUTESTFLAGS += -DYOTTA_CFG_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE=16 + diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_nsdl/test_sn_nsdl.c b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_nsdl/test_sn_nsdl.c index 75142b72823..fef02c46d80 100644 --- a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_nsdl/test_sn_nsdl.c +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/sn_nsdl/test_sn_nsdl.c @@ -2613,6 +2613,55 @@ bool test_sn_nsdl_process_coap() if( SN_NSDL_SUCCESS != sn_nsdl_process_coap(handle, NULL, 0, addr) ){ return false; } + + sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s*)malloc(sizeof(sn_coap_hdr_s)); + memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); + sn_coap_protocol_stub.expectedHeader->coap_status = 3; + sn_coap_protocol_stub.expectedHeader->msg_code = 0; + sn_coap_protocol_stub.expectedHeader->content_type_len = 1; + sn_coap_protocol_stub.expectedHeader->content_type_ptr = (uint8_t*)malloc(1); + *sn_coap_protocol_stub.expectedHeader->content_type_ptr = 97; + sn_coap_protocol_stub.expectedHeader->uri_path_ptr = (uint8_t*)malloc(1); + sn_coap_protocol_stub.expectedHeader->uri_path_ptr[0] = '0'; + sn_coap_protocol_stub.expectedHeader->uri_path_len = 1; + + payload_ptr[0] = '/'; + payload_ptr[1] = '/'; + payload_ptr[2] = ':'; + payload_ptr[3] = ':'; + sn_coap_protocol_stub.expectedHeader->payload_len = 4; + sn_coap_protocol_stub.expectedHeader->payload_ptr = payload_ptr; + + if( SN_NSDL_SUCCESS != sn_nsdl_process_coap(handle, NULL, 0, addr) ){ + return false; + } + + sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s*)malloc(sizeof(sn_coap_hdr_s)); + memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); + sn_coap_protocol_stub.expectedHeader->coap_status = 3; + sn_coap_protocol_stub.expectedHeader->msg_code = 0; + sn_coap_protocol_stub.expectedHeader->content_type_len = 1; + sn_coap_protocol_stub.expectedHeader->content_type_ptr = (uint8_t*)malloc(1); + *sn_coap_protocol_stub.expectedHeader->content_type_ptr = 97; + sn_coap_protocol_stub.expectedHeader->uri_path_ptr = (uint8_t*)malloc(1); + sn_coap_protocol_stub.expectedHeader->uri_path_ptr[0] = '0'; + sn_coap_protocol_stub.expectedHeader->uri_path_len = 1; + + payload_ptr[0] = '/'; + payload_ptr[1] = '/'; + payload_ptr[2] = ':'; + payload_ptr[3] = ':'; + sn_coap_protocol_stub.expectedHeader->payload_len = 4; + sn_coap_protocol_stub.expectedHeader->payload_ptr = payload_ptr; + + sn_grs_stub.expectedInfo = (sn_nsdl_resource_info_s*)malloc(sizeof(sn_nsdl_resource_info_s)); + memset( sn_grs_stub.expectedInfo, 0, sizeof(sn_nsdl_resource_info_s)); + sn_grs_stub.expectedInfo->external_memory_block = 1; + if( SN_NSDL_SUCCESS != sn_nsdl_process_coap(handle, NULL, 0, addr) ){ + return false; + } + free(sn_grs_stub.expectedInfo); + sn_grs_stub.expectedInfo = NULL; free(sn_grs_stub.expectedGrs->coap); free(payload_ptr); free(addr); diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_coap_protocol_stub.c b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_coap_protocol_stub.c index b5acd3272e6..142950642db 100644 --- a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_coap_protocol_stub.c +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_coap_protocol_stub.c @@ -105,5 +105,8 @@ coap_send_msg_s *sn_coap_protocol_allocate_mem_for_msg(struct coap_s *handle, sn return sn_coap_protocol_stub.expectedSendMsg; } +void sn_coap_protocol_block_remove(struct coap_s *handle, sn_nsdl_addr_s *source_address, uint16_t payload_length, void *payload) +{ +} diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_grs_stub.c b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_grs_stub.c old mode 100644 new mode 100755 diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_nsdl_stub.c b/features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_nsdl_stub.c old mode 100644 new mode 100755 diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/unittest/test_libNsdl/Test.c b/features/FEATURE_COMMON_PAL/mbed-client-c/unittest/test_libNsdl/Test.c index 135ba69f39d..577a74ccbdc 100644 --- a/features/FEATURE_COMMON_PAL/mbed-client-c/unittest/test_libNsdl/Test.c +++ b/features/FEATURE_COMMON_PAL/mbed-client-c/unittest/test_libNsdl/Test.c @@ -75,6 +75,7 @@ static uint8_t response_changed[4] = {0x60, 0x44, 0x12, 0x34}; static uint8_t response_created[4] = {0x60, 0x41, 0x12, 0x34}; static uint8_t response_deleted[4] = {0x60, 0x42, 0x12, 0x34}; +#define NSP_ADDRESS_LEN 4 #define NSP_PORT 5683 #define NSP_REGISTRATION_MESSAGE_LEN 72 @@ -340,6 +341,30 @@ void test_libnsdl_set_nsp_address(void) TEST_ASSERT_EQUAL(0, ret_val); } +/** + * \fn test_libnsdl_set_nsp_address_2(void) + * + * \brief Sets NSP address to nsdl-library + * + * Negative test cases: + * - call function with null parameter + */ +void test_libnsdl_set_nsp_address_2(void) +{ + int8_t ret_val = 0; + + /* with null pointer */ + ret_val = set_NSP_address_2(handle, NULL, NSP_ADDRESS_LEN, NSP_PORT, SN_NSDL_ADDRESS_TYPE_IPV4); + TEST_ASSERT_EQUAL(-1, ret_val); + + ret_val = set_NSP_address_2(NULL, address, NSP_ADDRESS_LEN, NSP_PORT, SN_NSDL_ADDRESS_TYPE_IPV4); + TEST_ASSERT_EQUAL(-1, ret_val); + + /* OK case */ + ret_val = set_NSP_address_2(handle, address, NSP_ADDRESS_LEN, NSP_PORT, SN_NSDL_ADDRESS_TYPE_IPV4); + TEST_ASSERT_EQUAL(0, ret_val); +} + /** * \fn test_libnsdl_register(void) * diff --git a/features/FEATURE_COMMON_PAL/mbed-client-c/xsl_script.sh b/features/FEATURE_COMMON_PAL/mbed-client-c/xsl_script.sh old mode 100644 new mode 100755 From c04628c38a616e26483bac06e96613cf4bbd78a9 Mon Sep 17 00:00:00 2001 From: Yogesh Pande Date: Wed, 7 Sep 2016 20:11:56 +0300 Subject: [PATCH 2/2] Fix for regression in mbed-client POST request handling. --- .../FEATURE_CLIENT/mbed-client/CHANGELOG.md | 25 +++++++++++++++++-- .../mbed-client/mbed-client/m2mobject.h | 5 ++-- .../mbed-client/m2mobjectinstance.h | 3 ++- .../FEATURE_CLIENT/mbed-client/module.json | 2 +- .../mbed-client/source/m2mobject.cpp | 9 ++++--- .../mbed-client/source/m2mobjectinstance.cpp | 13 +++++----- .../mbedclient/utest/stub/m2mobject_stub.cpp | 5 ++-- .../utest/stub/m2mobjectinstance_stub.cpp | 5 ++-- 8 files changed, 47 insertions(+), 20 deletions(-) diff --git a/features/FEATURE_CLIENT/mbed-client/CHANGELOG.md b/features/FEATURE_CLIENT/mbed-client/CHANGELOG.md index 7d6954d3fcf..1b088a79c61 100644 --- a/features/FEATURE_CLIENT/mbed-client/CHANGELOG.md +++ b/features/FEATURE_CLIENT/mbed-client/CHANGELOG.md @@ -1,7 +1,7 @@ # Change Log -## [v1.15.0](https://github.com/ARMmbed/mbed-client/releases/tag/v1.15.0) (06-Sep-2016) -[Full Changelog](https://github.com/ARMmbed/mbed-client/compare/v1.13.4...v1.15.0) +## [v1.15.1](https://github.com/ARMmbed/mbed-client/releases/tag/v1.15.1) (07-Sep-2016) +[Full Changelog](https://github.com/ARMmbed/mbed-client/compare/v1.13.4...v1.15.1) ** New feature ** @@ -13,6 +13,27 @@ **Merged pull requests:** +commit ae89da57afcafb68d02e1e591db0bc2c9b03d5bd (HEAD, tag: v1.15.1, origin/master, origin/HEAD, master) +Author: Antti Yli-Tokola +Date: Wed Sep 7 17:58:16 2016 +0300 + + version v1.15.1 + +commit 7bf71c457443b7806137d128da66b4c3c5f0333a +Merge: ce709e0 6d07835 +Author: Antti Yli-Tokola +Date: Wed Sep 7 17:55:51 2016 +0300 + + Merge pull request #280 from ARMmbed/post_req_fix + + Fix post request handling in object and object instance level + +commit 6d078357fb5fc16f7328d11dc98c2290091f2199 +Author: Antti Yli-Tokola +Date: Wed Sep 7 14:42:57 2016 +0300 + + Fix post request handling in object and object instance level + commit ce709e08039407ee69ce1f638543652261742439 (HEAD, tag: v1.15.0, origin/master, origin/HEAD, master) Author: Teemu Takaluoma Date: Tue Sep 6 18:52:15 2016 +0300 diff --git a/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mobject.h b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mobject.h index 4aafa07939d..c0a20ff1010 100644 --- a/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mobject.h +++ b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mobject.h @@ -149,7 +149,8 @@ protected : virtual sn_coap_hdr_s* handle_post_request(nsdl_s *nsdl, sn_coap_hdr_s *received_coap_header, M2MObservationHandler *observation_handler, - bool &execute_value_updated); + bool &execute_value_updated, + sn_nsdl_addr_s *address = NULL); protected : @@ -157,7 +158,7 @@ protected : private: - M2MObjectInstanceList _instance_list; // owned + M2MObjectInstanceList _instance_list; // owned uint16_t _max_instance_count; friend class Test_M2MObject; diff --git a/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mobjectinstance.h b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mobjectinstance.h index bb2a1f3498c..3df3869135f 100644 --- a/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mobjectinstance.h +++ b/features/FEATURE_CLIENT/mbed-client/mbed-client/m2mobjectinstance.h @@ -235,7 +235,8 @@ friend class M2MObject; virtual sn_coap_hdr_s* handle_post_request(nsdl_s *nsdl, sn_coap_hdr_s *received_coap_header, M2MObservationHandler *observation_handler, - bool &execute_value_updated); + bool &execute_value_updated, + sn_nsdl_addr_s *address = NULL); protected : diff --git a/features/FEATURE_CLIENT/mbed-client/module.json b/features/FEATURE_CLIENT/mbed-client/module.json index db3d45eff93..eb3a3dc4878 100644 --- a/features/FEATURE_CLIENT/mbed-client/module.json +++ b/features/FEATURE_CLIENT/mbed-client/module.json @@ -1,6 +1,6 @@ { "name": "mbed-client", - "version": "1.15.0", + "version": "1.15.1", "description": "mbed Client C++ API", "keywords": [], "author": "Yogesh Pande ", diff --git a/features/FEATURE_CLIENT/mbed-client/source/m2mobject.cpp b/features/FEATURE_CLIENT/mbed-client/source/m2mobject.cpp index 93e61618c45..7ec652ff84f 100644 --- a/features/FEATURE_CLIENT/mbed-client/source/m2mobject.cpp +++ b/features/FEATURE_CLIENT/mbed-client/source/m2mobject.cpp @@ -347,11 +347,12 @@ sn_coap_hdr_s* M2MObject::handle_put_request(nsdl_s *nsdl, sn_coap_hdr_s* M2MObject::handle_post_request(nsdl_s *nsdl, sn_coap_hdr_s *received_coap_header, M2MObservationHandler *observation_handler, - bool &execute_value_updated) + bool &execute_value_updated, + sn_nsdl_addr_s *) { - tr_debug("M2MObject::handle_post_request()"); + tr_debug("M2MObject::handle_post_request()"); sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04 - // process the POST if we have registered a callback for it + // process the POST if we have registered a callback for it sn_coap_hdr_s *coap_response = sn_nsdl_build_response(nsdl, received_coap_header, msg_code); @@ -470,7 +471,7 @@ sn_coap_hdr_s* M2MObject::handle_post_request(nsdl_s *nsdl, case M2MTLVDeserializer::NotFound: msg_code = COAP_MSG_CODE_RESPONSE_NOT_FOUND; break; - } + } } } else { tr_debug("M2MObject::handle_post_request() - COAP_MSG_CODE_RESPONSE_BAD_REQUEST"); diff --git a/features/FEATURE_CLIENT/mbed-client/source/m2mobjectinstance.cpp b/features/FEATURE_CLIENT/mbed-client/source/m2mobjectinstance.cpp index 60f02888154..38023266e81 100644 --- a/features/FEATURE_CLIENT/mbed-client/source/m2mobjectinstance.cpp +++ b/features/FEATURE_CLIENT/mbed-client/source/m2mobjectinstance.cpp @@ -148,7 +148,7 @@ M2MResourceInstance* M2MObjectInstance::create_static_resource_instance(const St return instance; } M2MResource *res = resource(resource_name); - if(!res) { + if(!res) { res = new M2MResource(*this,resource_name, resource_type, type, value, value_length, M2MBase::instance_id(), M2MBase::name(), true); @@ -187,7 +187,7 @@ M2MResourceInstance* M2MObjectInstance::create_dynamic_resource_instance(const S false, M2MBase::instance_id(), M2MBase::name(), true); _resource_list.push_back(res); res->set_register_uri(false); - res->set_operation(M2MBase::GET_ALLOWED); + res->set_operation(M2MBase::GET_ALLOWED); } if(res->supports_multiple_instances() && (res->resource_instance(instance_id) == NULL)) { instance = new M2MResourceInstance(resource_name, resource_type, type, *this, @@ -372,7 +372,7 @@ sn_coap_hdr_s* M2MObjectInstance::handle_get_request(nsdl_s *nsdl, received_coap_header, msg_code); uint8_t * data = NULL; - uint32_t data_length = 0; + uint32_t data_length = 0; if(received_coap_header) { // process the GET if we have registered a callback for it if ((operation() & SN_GRS_GET_ALLOWED) != 0) { @@ -477,7 +477,7 @@ sn_coap_hdr_s* M2MObjectInstance::handle_get_request(nsdl_s *nsdl, tr_error("M2MObjectInstance::handle_get_request - Return COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED"); // Operation is not allowed. msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; - } + } } else { msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; } @@ -584,7 +584,8 @@ sn_coap_hdr_s* M2MObjectInstance::handle_put_request(nsdl_s *nsdl, sn_coap_hdr_s* M2MObjectInstance::handle_post_request(nsdl_s *nsdl, sn_coap_hdr_s *received_coap_header, M2MObservationHandler *observation_handler, - bool &execute_value_updated) + bool &execute_value_updated, + sn_nsdl_addr_s *) { tr_debug("M2MObjectInstance::handle_post_request()"); sn_coap_msg_code_e msg_code = COAP_MSG_CODE_RESPONSE_CHANGED; // 2.04 @@ -631,7 +632,7 @@ sn_coap_hdr_s* M2MObjectInstance::handle_post_request(nsdl_s *nsdl, case M2MTLVDeserializer::None: if(observation_handler) { execute_value_updated = true; - } + } coap_response->options_list_ptr = (sn_coap_options_list_s*)malloc(sizeof(sn_coap_options_list_s)); if (coap_response->options_list_ptr) { memset(coap_response->options_list_ptr, 0, sizeof(sn_coap_options_list_s)); diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mobject_stub.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mobject_stub.cpp index 1451556ee3a..b3187a13a57 100755 --- a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mobject_stub.cpp +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mobject_stub.cpp @@ -19,7 +19,7 @@ u_int16_t m2mobject_stub::int_value; bool m2mobject_stub::bool_value; M2MObjectInstance* m2mobject_stub::inst; -// The statically initialized object list must be bigh enough to cater +// The statically initialized object list must be bigh enough to cater // for all the tests, or the utest framework will complain for memory leak. M2MObjectInstanceList m2mobject_stub::instance_list(12); @@ -114,7 +114,8 @@ sn_coap_hdr_s* M2MObject::handle_put_request(nsdl_s *, sn_coap_hdr_s* M2MObject::handle_post_request(nsdl_s *, sn_coap_hdr_s *, M2MObservationHandler *, - bool &) + bool &, + sn_nsdl_addr_s *) { return m2mobject_stub::header; } diff --git a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mobjectinstance_stub.cpp b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mobjectinstance_stub.cpp index 4b1cacf5d01..a5c7347d19b 100755 --- a/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mobjectinstance_stub.cpp +++ b/features/FEATURE_CLIENT/mbed-client/test/mbedclient/utest/stub/m2mobjectinstance_stub.cpp @@ -20,7 +20,7 @@ bool m2mobjectinstance_stub::bool_value; M2MResource* m2mobjectinstance_stub::resource; M2MResource* m2mobjectinstance_stub::create_resource; -// The statically initialized list must be bigh enough to cater +// The statically initialized list must be bigh enough to cater // for all the tests, or the utest framework will complain for memory leak. M2MResourceList m2mobjectinstance_stub::resource_list(12); @@ -162,7 +162,8 @@ sn_coap_hdr_s* M2MObjectInstance::handle_put_request(nsdl_s *, sn_coap_hdr_s* M2MObjectInstance::handle_post_request(nsdl_s *, sn_coap_hdr_s *, M2MObservationHandler *, - bool &execute) + bool &execute, + sn_nsdl_addr_s *) { execute = m2mobjectinstance_stub::bool_value; return m2mobjectinstance_stub::header;