Permalink
Browse files

Anjay 1.5.0

Features:
- Extracted Firmware Update logic to a separate module so that the end user
  have to implement device-specific firmware updating logic only
- Implemented API for firmware update resumption
- Implemented stub of the portfolio object (in demo client) required for the
  OMA TestFest 2017
- Added support for DTLS session resumption as well as register-after-reconnect
  semantics
- Added object versioning support
- Added support for LwM2M Server URIs with Uri-Path and Uri-Query

Bugfixes:
- Fixed travis builds on macOS
- Fixed a few misleading statements in the documentation
- Fixed anjay_codegen.py handling of Multiple Instance Resources
- Fixed Content-Format for responses on Bootstrap Discover request
- Fixed Write (replace) on Device object instance in demo client

Improvements:
- Added more tests covering OMA TestFest 2017 test cases
- Allowed configuring Security/Server IIDs from command line in demo
- Allowed Bootstrap Delete on "/"
- Added support for re-bootstrapping after failed registrations
- Added anjay_server/security_object_is_modified simiar to
  anjay_attr_storage_is_modified
- Updated porting guide
- Replaced Internal Server Error responses with more specific error
  codes in a few places

Other:
- Relaxed validator of Update location path, due to specification being
  unclear (see: OpenMobileAlliance/OMA_LwM2M_for_Developers#230)
  • Loading branch information...
sznaider committed Nov 20, 2017
1 parent 5d82cdf commit 14fda858c1d6afbcb92178a0fa78d0b9ced81870
Showing with 7,661 additions and 3,667 deletions.
  1. +2 −0 .gitignore
  2. +9 −2 CMakeLists.txt
  3. +1 −1 avs_commons/git
  4. +1 −0 config/config.h.in
  5. +3 −1 demo/CMakeLists.txt
  6. +10 −8 demo/demo.c
  7. +2 −0 demo/demo.h
  8. +57 −6 demo/demo_args.c
  9. +9 −14 demo/demo_cmds.c
  10. +640 −0 demo/firmware_update.c
  11. +50 −0 demo/firmware_update.h
  12. +5 −9 demo/objects.h
  13. +13 −0 demo/objects/apn_conn_profile.c
  14. +80 −6 demo/objects/cell_connectivity.c
  15. +35 −8 demo/objects/conn_statistics.c
  16. +17 −0 demo/objects/device.c
  17. +0 −900 demo/objects/firmware_update.c
  18. +2 −18 demo/objects/ip_ping.c
  19. +414 −0 demo/objects/portfolio.c
  20. +6 −0 doc/sphinx/source/BasicTutorial/BT5_CustomObject.rst
  21. +79 −123 doc/sphinx/source/PortingGuideForNonPOSIXPlatforms.rst
  22. +3 −3 examples/test_examples.md5
  23. +28 −0 include_modules/anjay_modules/downloader.h
  24. +16 −0 include_modules/anjay_modules/io_utils.h
  25. +5 −11 {src → include_modules/anjay_modules}/sched.h
  26. +2 −2 include_public/anjay/core.h
  27. +6 −0 include_public/anjay/dm.h
  28. +27 −4 include_public/anjay/download.h
  29. +24 −0 modules/fw_update/CMakeLists.txt
  30. +444 −0 modules/fw_update/include_public/anjay/fw_update.h
  31. +776 −0 modules/fw_update/src/fw_update.c
  32. +25 −0 modules/persistence/include_public/anjay/persistence.h
  33. +138 −26 modules/persistence/src/mod_persistence.c
  34. +7 −0 modules/security/include_public/anjay/security.h
  35. +38 −8 modules/security/src/mod_security.c
  36. +10 −0 modules/security/src/mod_security.h
  37. +30 −123 modules/security/src/security_persistence.c
  38. +6 −6 modules/security/src/security_transaction.c
  39. +0 −89 modules/security/src/security_utils.c
  40. +0 −14 modules/security/src/security_utils.h
  41. +49 −0 modules/security/src/test/persistence.c
  42. +7 −0 modules/server/include_public/anjay/server.h
  43. +22 −1 modules/server/src/mod_server.c
  44. +10 −0 modules/server/src/mod_server.h
  45. +6 −0 modules/server/src/server_persistence.c
  46. +16 −8 modules/server/src/server_transaction.c
  47. +60 −0 modules/server/src/test/persistence.c
  48. +30 −27 src/anjay_core.c
  49. +10 −3 src/anjay_core.h
  50. +5 −5 src/coap/test/utils.h
  51. +5 −0 src/dm/discover.c
  52. +20 −1 src/dm_core.c
  53. +18 −4 src/downloader.h
  54. +72 −29 src/downloader/coap.c
  55. +41 −17 src/downloader/downloader.c
  56. +21 −17 src/downloader/http.c
  57. +10 −9 src/downloader/private.h
  58. +53 −31 src/downloader/test/downloader.c
  59. +94 −40 src/interface/bootstrap_core.c
  60. +0 −1 src/interface/bootstrap_core.h
  61. +52 −37 src/interface/register.c
  62. +22 −1 src/interface/test/bootstrap.c
  63. +110 −0 src/io_utils.c
  64. +1 −1 src/notify.c
  65. +66 −27 src/observe_core.c
  66. +0 −1 src/observe_core.h
  67. +6 −1 src/sched.c
  68. +13 −32 src/servers.h
  69. +85 −3 src/servers/activate.c
  70. +149 −140 src/servers/connection_info.c
  71. +2 −2 src/servers/connection_info.h
  72. +7 −3 src/servers/offline.c
  73. +96 −99 src/servers/register_internal.c
  74. +14 −2 src/servers/register_internal.h
  75. +20 −25 src/servers/reload.c
  76. +32 −47 src/servers/servers_internal.c
  77. +14 −16 src/test/anjay.c
  78. +23 −108 src/test/observe.c
  79. +102 −224 src/utils_core.c
  80. +9 −6 src/utils_core.h
  81. +7 −0 test/integration/framework/asserts.py
  82. +13 −3 test/integration/framework/coap_file_server.py
  83. +14 −11 test/integration/framework/nsh-lwm2m/lwm2m/coap/server.py
  84. +11 −6 test/integration/framework/nsh-lwm2m/lwm2m/messages.py
  85. +31 −3 test/integration/framework/nsh-lwm2m/pymbedtls/src/pymbedtls.cpp
  86. +3 −1 test/integration/framework/pretty_test_runner.py
  87. +75 −10 test/integration/framework/test_suite.py
  88. +59 −1 test/integration/framework/test_utils.py
  89. +5 −5 test/integration/suites/default/access_control.py
  90. +19 −7 test/integration/suites/default/block_write.py
  91. +87 −0 test/integration/suites/default/bootstrap_client.py
  92. +7 −4 test/integration/suites/default/bootstrap_discover.py
  93. +10 −7 test/integration/suites/default/bootstrap_server.py
  94. +14 −16 test/integration/suites/default/bootstrap_sync.py
  95. +133 −125 test/integration/suites/default/client_block_request.py
  96. +50 −36 test/integration/suites/default/coap_download.py
  97. +197 −41 test/integration/suites/default/firmware_update.py
  98. +1 −2 test/integration/suites/default/json_encoding.py
  99. +19 −47 test/integration/suites/default/offline.py
  100. +3 −7 test/integration/suites/default/plaintext_base64.py
  101. +30 −1 test/integration/suites/default/register.py
  102. +1 −4 test/integration/suites/default/unregister.py
  103. +8 −19 test/integration/suites/default/update.py
  104. +3 −3 test/integration/suites/default/{uri_change_update.py → uri_change_reregister.py}
  105. +101 −0 test/integration/suites/testfest/bootstrap.py
  106. +226 −0 test/integration/suites/testfest/dm/connectivity_management.py
  107. +53 −60 test/integration/suites/testfest/dm/connectivity_monitoring.py
  108. +158 −36 test/integration/suites/testfest/dm/connectivity_statistics.py
  109. +83 −107 test/integration/suites/testfest/dm/device.py
  110. +779 −325 test/integration/suites/testfest/dm/firmware_update.py
  111. +50 −44 test/integration/suites/testfest/dm/location.py
  112. +85 −0 test/integration/suites/testfest/dm/portfolio.py
  113. +0 −130 test/integration/suites/testfest/dm/server.py
  114. +341 −44 test/integration/suites/testfest/dm/utils.py
  115. +282 −126 test/integration/suites/testfest/management.py
  116. +112 −0 test/integration/suites/testfest/multi_servers.py
  117. +84 −41 test/integration/suites/testfest/register.py
  118. +66 −13 test/integration/suites/testfest/reporting.py
  119. +18 −17 test/integration/suites/testfest/security.py
  120. +31 −15 tools/anjay_codegen.py
View
@@ -17,6 +17,8 @@ nbproject
CMakeFiles/
CMakeTmp/
CMakeCache.txt
CMakeDoxyfile.in
CMakeDoxygenDefaults.cmake
cmake_install.cmake
install_manifest.txt
_CPack_Packages/
View
@@ -26,7 +26,7 @@ if(WITH_FUZZ_TESTS)
endif()
project(anjay C)
set(ANJAY_VERSION "1.4.1" CACHE STRING "Anjay library version")
set(ANJAY_VERSION "1.5.0" CACHE STRING "Anjay library version")
set(ANJAY_BINARY_VERSION 1.0.0)
set(ANJAY_BUILD_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/output")
@@ -166,6 +166,7 @@ set(CORE_SOURCES
src/dm/query.c
src/anjay_core.c
src/io_core.c
src/io_utils.c
src/notify.c
src/servers/activate.c
src/servers/connection_info.c
@@ -240,7 +241,6 @@ set(CORE_PRIVATE_HEADERS
src/io/tlv.h
src/io/vtable.h
src/observe_core.h
src/sched.h
src/sched_internal.h
src/servers.h
src/servers/activate.h
@@ -253,9 +253,11 @@ set(CORE_MODULES_HEADERS
include_modules/anjay_modules/dm/attributes.h
include_modules/anjay_modules/dm/execute.h
include_modules/anjay_modules/dm/modules.h
include_modules/anjay_modules/downloader.h
include_modules/anjay_modules/io_utils.h
include_modules/anjay_modules/notify.h
include_modules/anjay_modules/observe.h
include_modules/anjay_modules/sched.h
include_modules/anjay_modules/time_defs.h
include_modules/anjay_modules/raw_buffer.h)
set(CORE_PUBLIC_HEADERS
@@ -333,6 +335,9 @@ if(WITH_MODULE_persistence)
endif()
DEFINE_MODULE(security ON "Security object module")
DEFINE_MODULE(server ON "Server object module")
if(WITH_DOWNLOADER OR WITH_BLOCK_RECEIVE)
DEFINE_MODULE(fw_update ON "Firmware Update object module")
endif()
################# LIBRARIES ####################################################
@@ -558,6 +563,8 @@ if(WITH_AVS_UNIT)
target_link_libraries(${PROJECT_NAME}_test ${DEPS_LIBRARIES} ${DEPS_LIBRARIES_WEAK})
endif()
add_subdirectory(test/codegen)
cmake_dependent_option(WITH_INTEGRATION_TESTS "Enable integration tests" OFF WITH_DEMO OFF)
if(WITH_INTEGRATION_TESTS)
add_subdirectory(test/integration)
View
@@ -41,6 +41,7 @@
#cmakedefine WITH_BLOCK_SEND
#cmakedefine WITH_BOOTSTRAP
#cmakedefine WITH_DISCOVER
#cmakedefine WITH_DOWNLOADER
#cmakedefine WITH_OBSERVE
#cmakedefine WITH_HTTP_DOWNLOAD
#cmakedefine WITH_JSON
View
@@ -20,6 +20,7 @@ set(SOURCES
demo_args.c
demo_cmds.c
demo_utils.c
firmware_update.c
iosched.c
objects/apn_conn_profile.c
objects/cell_connectivity.c
@@ -28,13 +29,14 @@ set(SOURCES
objects/download_diagnostics.c
objects/device.c
objects/ext_dev_info.c
objects/firmware_update.c
objects/geopoints.c
objects/ip_ping.c
objects/location.c
objects/portfolio.c
objects/test.c)
set(HEADERS
firmware_update.h
iosched.h
objects.h
demo_utils.h)
View
@@ -26,12 +26,14 @@
#include <anjay/access_control.h>
#include <anjay/attr_storage.h>
#include <anjay/fw_update.h>
#include <anjay/security.h>
#include <anjay/server.h>
#include "demo.h"
#include "demo_args.h"
#include "demo_cmds.h"
#include "firmware_update.h"
#include "iosched.h"
#include "objects.h"
#include "demo_utils.h"
@@ -68,7 +70,7 @@ static int security_object_reload(const anjay_dm_object_def_t *const *sec_obj,
instance.server_public_key = args->server_public_key;
instance.server_public_key_size = args->server_public_key_size;
anjay_iid_t iid = (anjay_iid_t) server->id;
anjay_iid_t iid = server->security_iid;
if (anjay_security_object_add_instance(sec_obj, &instance, &iid)) {
demo_log(ERROR, "Cannot add Security Instance");
return -1;
@@ -95,7 +97,7 @@ static int server_object_reload(const anjay_dm_object_def_t *const *serv_obj,
.binding = args->binding_mode,
.notification_storing = true
};
anjay_iid_t iid = (anjay_iid_t) server->id;
anjay_iid_t iid = server->server_iid;
if (anjay_server_object_add_instance(serv_obj, &instance, &iid)) {
demo_log(ERROR, "Cannot add Server Instance");
return -1;
@@ -148,6 +150,7 @@ static void demo_delete(anjay_demo_t *demo) {
AVS_LIST_CLEAR(&demo->objects) {
demo->objects->release_func(demo->objects->obj_ptr);
}
firmware_update_destroy(&demo->fw_update);
iosched_release(demo->iosched);
AVS_LIST_CLEAR(&demo->allocated_strings);
@@ -289,6 +292,8 @@ static int demo_init(anjay_demo_t *demo,
|| !demo->iosched
|| anjay_attr_storage_install(demo->anjay)
|| anjay_access_control_install(demo->anjay)
|| firmware_update_install(demo->anjay, &demo->fw_update,
cmdline_args->fw_updated_marker_path)
|| !iosched_poll_entry_new(demo->iosched, STDIN_FILENO,
POLLIN | POLLHUP,
demo_command_dispatch, demo, NULL)) {
@@ -318,19 +323,16 @@ static int demo_init(anjay_demo_t *demo,
|| install_object(demo, ext_dev_info_object_create(),
ext_dev_info_notify_time_dependent,
ext_dev_info_object_release)
|| install_object(demo,
firmware_update_object_create(
demo->iosched,
cmdline_args->fw_updated_marker_path),
NULL, firmware_update_object_release)
|| install_object(demo, geopoints_object_create(demo),
geopoints_notify_time_dependent,
geopoints_object_release)
|| install_object(demo, ip_ping_object_create(demo->iosched), NULL,
ip_ping_object_release)
|| install_object(demo, test_object_create(),
test_notify_time_dependent,
test_object_release)) {
test_object_release)
|| install_object(demo, portfolio_object_create(),
NULL, portfolio_object_release)) {
return -1;
}
View
@@ -25,6 +25,7 @@
#include <poll.h>
#include "firmware_update.h"
#include "objects.h"
typedef struct {
@@ -49,6 +50,7 @@ struct anjay_demo_struct {
server_connection_args_t *connection_args;
iosched_t *iosched;
fw_update_logic_t fw_update;
AVS_LIST(anjay_demo_object_t) objects;
};
View
@@ -28,6 +28,8 @@ static const cmdline_args_t DEFAULT_CMDLINE_ARGS = {
.endpoint_name = "urn:dev:os:0023C7-000001",
.connection_args = {
.servers[0] = {
.security_iid = ANJAY_IID_INVALID,
.server_iid = ANJAY_IID_INVALID,
.id = 1,
.uri = "coap://127.0.0.1:5683"
},
@@ -144,6 +146,11 @@ static void print_option_help(const struct option *opt) {
"server URI to use. Note: coap:// URIs require --security-mode nosec "
"to be set. N consecutive URIs will create N servers enumerated "
"from 1 to N." },
{ 'D', "IID", NULL, "enforce particular Security Instance IID for last "
"configured server." },
{ 'd', "IID", NULL, "enforce particular Server Instance IID for last "
"configured server. Ignored if last configured server is an LwM2M "
"Bootstrap Server." },
{ 'I', "SIZE", "4000", "Nonnegative integer representing maximum "
"size of an incoming CoAP packet the client "
"should be able to handle." },
@@ -206,6 +213,19 @@ static int parse_i32(const char *str, int32_t *out_value) {
return 0;
}
static int parse_u16(const char *str, uint16_t *out_value) {
long long_value;
if (demo_parse_long(optarg, &long_value)
|| long_value < 0
|| long_value > UINT16_MAX) {
demo_log(ERROR, "value out of range: %s", str);
return -1;
}
*out_value = (uint16_t) long_value;
return 0;
}
static int parse_hexstring(const char *str, uint8_t **out, size_t *out_size) {
if (!str) {
return -1;
@@ -335,7 +355,9 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
{ "key", required_argument, 0, 'k' },
{ "key-file", required_argument, 0, 'K' },
{ "binding", optional_argument, 0, 'q' },
{ "security-iid", required_argument, 0, 'D' },
{ "security-mode", required_argument, 0, 's' },
{ "server-iid", required_argument, 0, 'd' },
{ "server-uri", required_argument, 0, 'u' },
{ "inbuf-size", required_argument, 0, 'I' },
{ "outbuf-size", required_argument, 0, 'O' },
@@ -484,15 +506,38 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
parsed_args->connection_args.binding_mode = binding_mode;
break;
}
case 'D': {
int idx = num_servers == 0 ? 0 : num_servers - 1;
if (parse_u16(optarg,
&parsed_args->connection_args.servers[idx]
.security_iid)) {
goto error;
}
}
break;
case 's':
if (parse_security_mode(
optarg, &parsed_args->connection_args.security_mode)) {
goto error;
}
break;
case 'u':
assert(num_servers < MAX_SERVERS && "Too many servers");
parsed_args->connection_args.servers[num_servers++].uri = optarg;
case 'd': {
int idx = num_servers == 0 ? 0 : num_servers - 1;
if (parse_u16(optarg,
&parsed_args->connection_args.servers[idx]
.server_iid)) {
goto error;
}
}
break;
case 'u': {
assert(num_servers < MAX_SERVERS && "Too many servers");
server_entry_t *entry =
&parsed_args->connection_args.servers[num_servers++];
entry->uri = optarg;
entry->security_iid = ANJAY_IID_INVALID;
entry->server_iid = ANJAY_IID_INVALID;
}
break;
case 'I':
if (parse_i32(optarg, &parsed_args->inbuf_size)
@@ -523,9 +568,15 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
}
}
finish:
for (int i = 1; i < num_servers; ++i) {
// update IDs
parsed_args->connection_args.servers[i].id = (anjay_ssid_t) (i + 1);
for (int i = 0; i < AVS_MAX(num_servers, 1); ++i) {
server_entry_t *entry = &parsed_args->connection_args.servers[i];
entry->id = (anjay_ssid_t) (i + 1);
if (entry->security_iid == ANJAY_IID_INVALID) {
entry->security_iid = (anjay_iid_t) entry->id;
}
if (entry->server_iid == ANJAY_IID_INVALID) {
entry->server_iid = (anjay_iid_t) entry->id;
}
}
bool identity_set =
!!parsed_args->connection_args.public_cert_or_psk_identity_size;
View
@@ -17,6 +17,7 @@
#include "demo.h"
#include "demo_cmds.h"
#include "demo_utils.h"
#include "firmware_update.h"
#include <ctype.h>
#include <string.h>
@@ -65,20 +66,12 @@ static void cmd_reconnect(anjay_demo_t *demo,
static void cmd_set_fw_package_path(anjay_demo_t *demo,
const char *args_string) {
const anjay_dm_object_def_t **firmware_update_obj =
demo_find_object(demo, DEMO_OID_FIRMWARE_UPDATE);
if (!firmware_update_obj) {
demo_log(ERROR, "Firmware update object not registered");
return;
}
const char *path = args_string;
while (isspace(*path)) {
++path;
}
firmware_update_set_package_path(demo->anjay,
firmware_update_obj, path);
firmware_update_set_package_path(&demo->fw_update, path);
}
static void cmd_open_location_csv(anjay_demo_t *demo, const char *args_string) {
@@ -122,11 +115,13 @@ static int add_server(anjay_demo_t *demo, const char *uri) {
}
memcpy(copied_uri->data, uri, uri_size);
AVS_LIST_INSERT(&demo->allocated_strings, copied_uri);
demo->connection_args->servers[num_servers] =
demo->connection_args->servers[num_servers - 1];
demo->connection_args->servers[num_servers].id =
(anjay_ssid_t) (num_servers + 1);
demo->connection_args->servers[num_servers].uri = copied_uri->data;
server_entry_t *entry = &demo->connection_args->servers[num_servers];
*entry = demo->connection_args->servers[num_servers - 1];
entry->id = (anjay_ssid_t) (num_servers + 1);
entry->uri = copied_uri->data;
entry->security_iid = (anjay_iid_t) entry->id;
entry->server_iid = (anjay_iid_t) entry->id;
demo_log(INFO, "Added new server, ID == %d", (int) (num_servers + 1));
return 0;
}
Oops, something went wrong.

0 comments on commit 14fda85

Please sign in to comment.