Skip to content

Commit

Permalink
Anjay 3.1.0
Browse files Browse the repository at this point in the history
BREAKING CHANGES:
Note: the following changes, while technically breaking, are minor, and should
not cause problems in most pratical usages. See also:
https://avsystem.github.io/Anjay-doc/Migrating/MigratingFromAnjay30.html

- Changed error handling semantics of anjay_attr_storage_restore() to match
  other persistence restore functions
- TLS 1.2 is no longer implicitly set as the default (D)TLS version; the
  underlying crypto library's default is now used

Features:
- Factory provisioning feature that allows to perform "Factory bootstrap" based
  on SenML CBOR data stream
- New API: anjay_access_control_set_owner(), allowing to set Owner resource in
  the Access Control object during the "Factory bootstrap" phase
- New APIs for changing the CoAP transmission parameters, CoAP exchange timeout
  and DTLS handshake timeouts while the library is running

Improvements:
- Migrated the Observe/Notify subsystem to use the new AVS_SORTED_SET API from
  avs_commons; this means that avs_rbtree can be disabled, in which case a more
  lightweight list-based implementation will be used
- Minor code size optimizations in the Server object implementation
- Added documentation for the OSCORE commercial feature
- (D)TLS version can now be set from command line in the demo application

Bugfixes:
- Fixed a bug in anjay_ongoing_registration_exists() that could cause it to
  always return true if disable_legacy_server_initiated_bootstrap is set to true
- Fixed improper formatting of the payload describing the data model in the
  Register message during initial negotiation of the LwM2M version
- Fixed handling of persistence format versioning for the Security object, that
  could cause crashes if Anjay was compiled without LwM2M 1.1 support
- Changed the "Bootstrap on Registration Failure" resource in the Server object
  to be readable, as specified in LwM2M TS 1.2
- (commercial feature only) Added persistence of runtime LwM2M version in the
  core persistence feature; previously the client could erroneously use a
  different LwM2M version than it registered with after core persistence restore
  • Loading branch information
Mateusz Kwiatkowski committed Jul 6, 2022
1 parent 81db73d commit e36d21a
Show file tree
Hide file tree
Showing 121 changed files with 4,462 additions and 820 deletions.
15 changes: 13 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
cmake_minimum_required(VERSION 3.6.0)

project(anjay C)
set(ANJAY_VERSION "3.0.0" CACHE STRING "Anjay library version")
set(ANJAY_VERSION "3.1.0" CACHE STRING "Anjay library version")
set(ANJAY_BINARY_VERSION 1.0.0)

set(ANJAY_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
Expand Down Expand Up @@ -115,13 +115,16 @@ option(WITH_THREAD_SAFETY "Enable guarding of all accesses to anjay_t with a mut
################# LIBRARIES ####################################################

# avs_commons required components.
set(AVS_COMMONS_COMPONENTS algorithm crypto list rbtree buffer net sched stream stream_net url utils compat_threading)
set(AVS_COMMONS_COMPONENTS algorithm crypto list buffer net sched stream stream_net url utils compat_threading)
if(WITH_HTTP_DOWNLOAD)
list(APPEND AVS_COMMONS_COMPONENTS http)
endif()
if(WITH_AVS_PERSISTENCE)
list(APPEND AVS_COMMONS_COMPONENTS persistence)
endif()
if(NOT DEFINED WITH_AVS_RBTREE OR WITH_AVS_RBTREE)
set(WITH_AVS_RBTREE ON CACHE INTERNAL "")
endif()

set(AVS_COMMONS_LIBRARIES)
foreach(_component ${AVS_COMMONS_COMPONENTS})
Expand Down Expand Up @@ -317,6 +320,7 @@ option(WITH_MODULE_ipso_objects "Generic implementation of certain kinds of IPSO
option(WITH_MODULE_security "Security object module" ON)
option(WITH_MODULE_server "Server object module" ON)
option(WITH_MODULE_fw_update "Firmware Update object module" ON)
cmake_dependent_option(WITH_MODULE_factory_provisioning "Factory provisioning module" ON "WITH_BOOTSTRAP;WITH_CBOR" OFF)

################# CODE #########################################################

Expand All @@ -327,6 +331,7 @@ add_library(anjay
include_public/anjay/core.h
include_public/anjay/dm.h
include_public/anjay/download.h
include_public/anjay/factory_provisioning.h
include_public/anjay/fw_update.h
include_public/anjay/io.h
include_public/anjay/ipso_objects.h
Expand Down Expand Up @@ -459,6 +464,7 @@ add_library(anjay
src/modules/access_control/anjay_access_control_persistence.c
src/modules/access_control/anjay_mod_access_control.c
src/modules/access_control/anjay_mod_access_control.h
src/modules/factory_provisioning/anjay_provisioning.c
src/modules/fw_update/anjay_fw_update.c
src/modules/ipso/anjay_ipso_3d_sensor.c
src/modules/ipso/anjay_ipso_basic_sensor.c
Expand Down Expand Up @@ -515,6 +521,7 @@ set(ANJAY_WITH_OBSERVATION_STATUS "${WITH_OBSERVATION_STATUS}")
set(ANJAY_WITH_OBSERVE "${WITH_OBSERVE}")
set(ANJAY_WITH_THREAD_SAFETY "${WITH_THREAD_SAFETY}")
set(ANJAY_WITH_TRACE_LOGS "${WITH_ANJAY_TRACE_LOGS}")
set(ANJAY_WITH_MODULE_FACTORY_PROVISIONING "${WITH_MODULE_factory_provisioning}")

set(ANJAY_WITH_CBOR "${WITH_CBOR}")
set(ANJAY_WITH_LWM2M11 "${WITH_LWM2M11}")
Expand Down Expand Up @@ -839,6 +846,10 @@ if(WITH_MODULE_server)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/include_public/anjay/server.h"
DESTINATION include/anjay)
endif()
if(WITH_MODULE_factory_provisioning)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/include_public/anjay/factory_provisioning.h"
DESTINATION include/anjay)
endif()

# install CMake package
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/anjay-config.cmake.in
Expand Down
1 change: 1 addition & 0 deletions demo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ find_package(Threads REQUIRED)
add_executable(demo ${ALL_SOURCES})
target_link_libraries(demo PRIVATE anjay m ${CMAKE_THREAD_LIBS_INIT})


add_custom_target(demo_firmware
COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/../tests/integration/framework/firmware_package.py
-i ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/demo
Expand Down
27 changes: 26 additions & 1 deletion demo/demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
#include <anjay/security.h>
#include <anjay/server.h>

#ifdef ANJAY_WITH_MODULE_FACTORY_PROVISIONING
# include <anjay/factory_provisioning.h>
#endif // ANJAY_WITH_MODULE_FACTORY_PROVISIONING

static int security_object_reload(anjay_demo_t *demo) {
anjay_security_object_purge(demo->anjay);
const server_connection_args_t *args = demo->connection_args;
Expand Down Expand Up @@ -450,7 +454,7 @@ static int demo_init(anjay_demo_t *demo, cmdline_args_t *cmdline_args) {
anjay_configuration_t config = {
.endpoint_name = cmdline_args->endpoint_name,
.udp_listen_port = cmdline_args->udp_listen_port,
.dtls_version = AVS_NET_SSL_VERSION_TLSv1_2,
.dtls_version = cmdline_args->dtls_version,
.in_buffer_size = (size_t) cmdline_args->inbuf_size,
.out_buffer_size = (size_t) cmdline_args->outbuf_size,
.msg_cache_size = (size_t) cmdline_args->msg_cache_size,
Expand Down Expand Up @@ -604,6 +608,27 @@ static int demo_init(anjay_demo_t *demo, cmdline_args_t *cmdline_args) {

if (!dm_persistence_restored) {
demo_reload_servers(demo);

#ifdef ANJAY_WITH_MODULE_FACTORY_PROVISIONING
if (cmdline_args->provisioning_file) {
avs_stream_t *data =
avs_stream_file_create(cmdline_args->provisioning_file,
AVS_STREAM_FILE_READ);
avs_error_t err = AVS_OK;
if (!data) {
err = avs_errno(AVS_EIO);
} else {
err = anjay_factory_provision(demo->anjay, data);
avs_stream_cleanup(&data);
}
if (avs_is_err(err)) {
demo_log(ERROR, "Cannot provision client from file %s",
cmdline_args->provisioning_file);
return -1;
}
demo_log(DEBUG, "Factory provisioning complete");
}
#endif // ANJAY_WITH_MODULE_FACTORY_PROVISIONING
}

#ifdef ANJAY_WITH_MODULE_FW_UPDATE
Expand Down
72 changes: 69 additions & 3 deletions demo/demo_args.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ static const cmdline_args_t DEFAULT_CMDLINE_ARGS = {
.disable_legacy_server_initiated_bootstrap = false,
#ifdef AVS_COMMONS_STREAM_WITH_FILE
#endif // AVS_COMMONS_STREAM_WITH_FILE
#ifdef ANJAY_WITH_MODULE_FACTORY_PROVISIONING
.provisioning_file = NULL,
#endif // ANJAY_WITH_MODULE_FACTORY_PROVISIONING
.tx_params = ANJAY_COAP_DEFAULT_UDP_TX_PARAMS,
.dtls_hs_tx_params = ANJAY_DTLS_DEFAULT_UDP_HS_TX_PARAMS,
#ifdef ANJAY_WITH_MODULE_FW_UPDATE
Expand Down Expand Up @@ -141,6 +144,42 @@ static int parse_security_mode(const char *mode_string,
return -1;
}

static int parse_tls_version(const char *str,
avs_net_ssl_version_t *out_version) {
assert(str);
if (strcmp(str, "default") == 0) {
*out_version = AVS_NET_SSL_VERSION_DEFAULT;
return 0;
} else if (strcmp(str, "SSLv23") == 0) {
*out_version = AVS_NET_SSL_VERSION_SSLv2_OR_3;
return 0;
} else if (strcmp(str, "SSLv2") == 0 || strcmp(str, "SSLv2.0") == 0
|| strcmp(str, "2.0") == 0) {
*out_version = AVS_NET_SSL_VERSION_SSLv2;
return 0;
} else if (strcmp(str, "SSLv3") == 0 || strcmp(str, "SSLv3.0") == 0
|| strcmp(str, "3.0") == 0) {
*out_version = AVS_NET_SSL_VERSION_SSLv3;
return 0;
} else if (strcmp(str, "TLSv1") == 0 || strcmp(str, "TLSv1.0") == 0
|| strcmp(str, "1.0") == 0) {
*out_version = AVS_NET_SSL_VERSION_TLSv1;
return 0;
} else if (strcmp(str, "TLSv1.1") == 0 || strcmp(str, "1.1") == 0) {
*out_version = AVS_NET_SSL_VERSION_TLSv1_1;
return 0;
} else if (strcmp(str, "TLSv1.2") == 0 || strcmp(str, "1.2") == 0) {
*out_version = AVS_NET_SSL_VERSION_TLSv1_2;
return 0;
} else if (strcmp(str, "TLSv1.3") == 0 || strcmp(str, "1.3") == 0) {
*out_version = AVS_NET_SSL_VERSION_TLSv1_3;
return 0;
} else {
demo_log(ERROR, "Invalid TLS version: %s", str);
return -1;
}
}

static size_t get_screen_width(void) {
#ifndef _WIN32
struct winsize ws;
Expand Down Expand Up @@ -300,6 +339,10 @@ static void print_help(const struct option *options) {
"store it at shutdown" },
#endif // defined(ANJAY_WITH_ATTR_STORAGE) &&
// defined(AVS_COMMONS_STREAM_WITH_FILE)
#ifdef ANJAY_WITH_MODULE_FACTORY_PROVISIONING
{ 'F', "PROVISIONING_FILE", NULL,
"File where factory provisioning data is contained." },
#endif // ANJAY_WITH_MODULE_FACTORY_PROVISIONING
{ 267, "ACK_RANDOM_FACTOR", "1.5",
"Configures ACK_RANDOM_FACTOR (defined in RFC7252)" },
{ 268, "ACK_TIMEOUT", "2.0",
Expand Down Expand Up @@ -385,6 +428,8 @@ static void print_help(const struct option *options) {
"details)" },
{ 308, NULL, NULL,
"Provide key from ASCII string (see -k parameter for more details)" },
{ 317, "VERSION", "TLS library default",
"Minimum (D)TLS version to use." },
};

const size_t screen_width = get_screen_width();
Expand Down Expand Up @@ -598,7 +643,8 @@ load_buffer_from_file(uint8_t **out, size_t *out_size, const char *filename) {
}

#ifdef ANJAY_WITH_LWM2M11
static int parse_version(const char *str, anjay_lwm2m_version_t *out_version) {
static int parse_lwm2m_version(const char *str,
anjay_lwm2m_version_t *out_version) {
assert(str);
if (strcmp(str, "1.0") == 0) {
*out_version = ANJAY_LWM2M_VERSION_1_0;
Expand Down Expand Up @@ -673,6 +719,9 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
#if defined(ANJAY_WITH_ATTR_STORAGE) && defined(AVS_COMMONS_STREAM_WITH_FILE)
{ "attribute-storage-persistence-file", required_argument, 0, 261 },
#endif // defined(ANJAY_WITH_ATTR_STORAGE) && defined(AVS_COMMONS_STREAM_WITH_FILE)
#ifdef ANJAY_WITH_MODULE_FACTORY_PROVISIONING
{ "factory-provisioning-file", required_argument, 0, 'F' },
#endif // ANJAY_WITH_MODULE_FACTORY_PROVISIONING
{ "ack-random-factor", required_argument, 0, 267 },
{ "ack-timeout", required_argument, 0, 268 },
{ "max-retransmit", required_argument, 0, 269 },
Expand Down Expand Up @@ -715,6 +764,7 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
{ "alternative-logger", no_argument, 0, 306 },
{ "identity-as-string", required_argument, 0, 307 },
{ "key-as-string", required_argument, 0, 308 },
{ "tls-version", required_argument, 0, 317 },
{ 0, 0, 0, 0 }
// clang-format on
};
Expand Down Expand Up @@ -995,14 +1045,14 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
break;
#ifdef ANJAY_WITH_LWM2M11
case 'v':
if (parse_version(
if (parse_lwm2m_version(
optarg,
&parsed_args->lwm2m_version_config.minimum_version)) {
goto finish;
}
break;
case 'V':
if (parse_version(
if (parse_lwm2m_version(
optarg,
&parsed_args->lwm2m_version_config.maximum_version)) {
goto finish;
Expand Down Expand Up @@ -1117,6 +1167,14 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
break;
#endif // defined(ANJAY_WITH_ATTR_STORAGE) &&
// defined(AVS_COMMONS_STREAM_WITH_FILE)
#ifdef ANJAY_WITH_MODULE_FACTORY_PROVISIONING
case 'F':
if (!optarg || strlen(optarg) < 1) {
goto finish;
}
parsed_args->provisioning_file = optarg;
break;
#endif // ANJAY_WITH_MODULE_FACTORY_PROVISIONING
case 267:
if (parse_double(optarg,
&parsed_args->tx_params.ack_random_factor)) {
Expand Down Expand Up @@ -1360,6 +1418,11 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
}
break;
}
case 317:
if (parse_tls_version(optarg, &parsed_args->dtls_version)) {
goto finish;
}
break;
case 0:
goto process;
}
Expand All @@ -1380,6 +1443,9 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) {
# endif // _WIN32
)
# endif // AVS_COMMONS_WITH_AVS_PERSISTENCE
# ifdef ANJAY_WITH_MODULE_FACTORY_PROVISIONING
&& !parsed_args->provisioning_file
# endif // ANJAY_WITH_MODULE_FACTORY_PROVISIONING
#endif // AVS_COMMONS_STREAM_WITH_FILE
) {
demo_log(ERROR, "At least one LwM2M Server URI needs to be specified, "
Expand Down
4 changes: 4 additions & 0 deletions demo/demo_args.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ typedef struct access_entry {
typedef struct cmdline_args {
const char *endpoint_name;
uint16_t udp_listen_port;
avs_net_ssl_version_t dtls_version;
server_connection_args_t connection_args;
const char *location_csv;
time_t location_update_frequency_s;
Expand Down Expand Up @@ -65,6 +66,9 @@ typedef struct cmdline_args {
#ifdef AVS_COMMONS_STREAM_WITH_FILE
#endif // AVS_COMMONS_STREAM_WITH_FILE

#ifdef ANJAY_WITH_MODULE_FACTORY_PROVISIONING
const char *provisioning_file;
#endif // ANJAY_WITH_MODULE_FACTORY_PROVISIONING
avs_coap_udp_tx_params_t tx_params;
avs_net_dtls_handshake_timeouts_t dtls_hs_tx_params;
#ifdef ANJAY_WITH_MODULE_FW_UPDATE
Expand Down
Loading

0 comments on commit e36d21a

Please sign in to comment.