Skip to content

Commit

Permalink
Add JSON Encoder and Decoder
Browse files Browse the repository at this point in the history
Allow the used encoder and decoder to be configurable. By default
the JSON encoder and decoders are disabled in compile time.

Use oc_rep_encoder_set_type from oc_rep.h to set the encoder that
will be used to encode payloads.
  • Loading branch information
Danielius1922 authored and Daniel Adam committed Oct 12, 2023
1 parent fc89bd6 commit e95e8cd
Show file tree
Hide file tree
Showing 57 changed files with 5,673 additions and 1,007 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ jobs:
include:
# default (ip4 on, secure on, pki on, dynamic allocation on, tcp on, cloud on, java on, IDD on)
- args: ""
# debug on
- args: "DEBUG=1"
# debug on, json encoder on
- args: "DEBUG=1 JSON_ENCODER=1"
# secure off
- args: "SECURE=0"
# TODO: reenable when dynamic allocation is fixed
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/coverity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
-DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON
-DPLGD_DEV_TIME_ENABLED=ON
-DOC_ETAG_ENABLED=ON
-DOC_JSON_ENCODER_ENABLED=ON
-B ${{github.workspace}}/build

- uses: vapier/coverity-scan-action@v1
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/sonar-cloud-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ jobs:
- build_args: "-DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON"
# security off, ipv4 on, collection create on, push on, rfotm on
- build_args: "-DOC_SECURITY_ENABLED=OFF -DOC_IPV4_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_PUSH_ENABLED=ON"
# ipv6 dns on, oscore off, rep realloc on
- build_args: "-DOC_DNS_LOOKUP_IPV6_ENABLED=ON -DOC_OSCORE_ENABLED=OFF -DOC_REPRESENTATION_REALLOC_ENCODING_ENABLED=ON"
# ipv6 dns on, oscore off, rep realloc on, json encoder on
- build_args: "-DOC_DNS_LOOKUP_IPV6_ENABLED=ON -DOC_OSCORE_ENABLED=OFF -DOC_REPRESENTATION_REALLOC_ENCODING_ENABLED=ON -DOC_JSON_ENCODER_ENABLED=ON"
# ipv4 on, tcp on, dynamic allocation off, rfotm on, push off (because it forces dynamic allocation)
- build_args: "-DOC_IPV4_ENABLED=ON -DOC_TCP_ENABLED=ON -DOC_DYNAMIC_ALLOCATION_ENABLED=OFF -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON"
# security off, dynamic allocation off, push off (because it forces dynamic allocation)
- build_args: "-DOC_SECURITY_ENABLED=OFF -DOC_DYNAMIC_ALLOCATION_ENABLED=OFF"
# security off, dynamic allocation off, push off (because it forces dynamic allocation), json encoder on
- build_args: "-DOC_SECURITY_ENABLED=OFF -DOC_DYNAMIC_ALLOCATION_ENABLED=OFF -DOC_JSON_ENCODER_ENABLED=ON"
# security off, cloud (ipv4+tcp), collection create on, introspection IDD off
- build_args: "-DOC_SECURITY_ENABLED=OFF -DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DOC_IDD_API_ENABLED=OFF"

Expand Down Expand Up @@ -104,7 +104,7 @@ jobs:
mkdir build && cd build
# sonar-scanner currently cannot handle multi configuration configuration (ie. compilation of the same file with different defines),
# so we enable as many features as possible so we get max. amount of code analysis
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_VERBOSE_MAKEFILE=ON -DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_MNT_ENABLED=ON -DOC_WKCORE_ENABLED=ON -DOC_SOFTWARE_UPDATE_ENABLED=ON -DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON -DPLGD_DEV_TIME_ENABLED=ON -DOC_ETAG_ENABLED=ON -DBUILD_TESTING=ON ..
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_VERBOSE_MAKEFILE=ON -DOC_CLOUD_ENABLED=ON -DOC_COLLECTIONS_IF_CREATE_ENABLED=ON -DOC_MNT_ENABLED=ON -DOC_WKCORE_ENABLED=ON -DOC_SOFTWARE_UPDATE_ENABLED=ON -DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DOC_RESOURCE_ACCESS_IN_RFOTM_ENABLED=ON -DPLGD_DEV_TIME_ENABLED=ON -DOC_ETAG_ENABLED=ON -DOC_JSON_ENCODER_ENABLED=ON -DBUILD_TESTING=ON ..
cd ..
# for files defined in multiple cmake targets, sonar-scanner seems to take the configuration from the first compilation of the file,
# so we force client-server target to be compiled first so we get analysis of code with both OC_CLIENT and OC_SERVER enabled
Expand Down
29 changes: 28 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ set(OC_APP_DATA_BUFFER_SIZE "" CACHE STRING "Custom static buffer size for appli
set(OC_APP_DATA_BUFFER_POOL "" CACHE STRING "Custom static size of application messages.")
set(OC_VERSION_1_1_0_ENABLED OFF CACHE BOOL "Enable OCF version 1.1")
set(OC_ETAG_ENABLED OFF CACHE BOOL "Enable Entity Tag (ETag) support.")
set(OC_JSON_ENCODER_ENABLED OFF CACHE BOOL "Enable JSON encoder/decoder support.")
set(PLGD_DEV_TIME_ENABLED OFF CACHE BOOL "Enable plgd time feature.")

set(CMAKE_POSITION_INDEPENDENT_CODE ON)
Expand Down Expand Up @@ -99,8 +100,16 @@ if(UNIX)

if(OC_UBSAN_ENABLED)
message(STATUS "Undefined behaviour sanitizer enabled")
add_compile_options(${CMAKE_C_FLAGS_DEBUG} -fsanitize=undefined -fno-omit-frame-pointer)
if(OC_COMPILER_IS_CLANG)
# -fno-sanitize-recover=undefined,local-bounds,nullability
add_compile_options(${CMAKE_C_FLAGS_DEBUG} -fsanitize=undefined,local-bounds,nullability -fno-omit-frame-pointer)
else()
# -fno-sanitize-recover=undefined
add_compile_options(${CMAKE_C_FLAGS_DEBUG} -fsanitize=undefined -fno-omit-frame-pointer)
endif()
add_link_options(-fsanitize=undefined)
# halt_on_error=1
set(OC_UBSAN_OPTIONS "print_stacktrace=1")
endif()

if(OC_COMPILER_IS_CLANG)
Expand Down Expand Up @@ -411,6 +420,10 @@ if(OC_ETAG_ENABLED)
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_ETAG")
endif()

if(OC_JSON_ENCODER_ENABLED)
list(APPEND PUBLIC_COMPILE_DEFINITIONS "OC_JSON_ENCODER")
endif()

if(PLGD_DEV_TIME_ENABLED)
list(APPEND PUBLIC_COMPILE_DEFINITIONS "PLGD_DEV_TIME")
if(BUILD_MBEDTLS)
Expand Down Expand Up @@ -474,6 +487,13 @@ if(OC_PKI_ENABLED)
)
endif()

if(OC_JSON_ENCODER_ENABLED)
file(GLOB JSMN_SRC
${PROJECT_SOURCE_DIR}/util/jsmn/*.c
)
list(APPEND COMMON_SRC ${JSMN_SRC})
endif()

if(PLGD_DEV_TIME_ENABLED)
file(GLOB PLGD_SRC
${PROJECT_SOURCE_DIR}/api/plgd/*.c
Expand Down Expand Up @@ -971,6 +991,7 @@ if(BUILD_TESTING AND(UNIX OR MINGW))
FILES ${apitest_files}
ENVIRONMENT "ASAN_OPTIONS=${OC_ASAN_OPTIONS}"
"TSAN_OPTIONS=${OC_TSAN_OPTIONS}"
"UBSAN_OPTIONS=${OC_UBSAN_OPTIONS}"
)

file(GLOB TIMESTAMPTEST_SRC api/c-timestamp/unittest/*.cpp)
Expand All @@ -979,6 +1000,7 @@ if(BUILD_TESTING AND(UNIX OR MINGW))
SOURCES ${TIMESTAMPTEST_SRC}
ENVIRONMENT "ASAN_OPTIONS=${OC_ASAN_OPTIONS}"
"TSAN_OPTIONS=${OC_TSAN_OPTIONS}"
"UBSAN_OPTIONS=${OC_UBSAN_OPTIONS}"
)

file(GLOB PLATFORMTEST_SRC port/unittest/*.cpp)
Expand All @@ -988,6 +1010,7 @@ if(BUILD_TESTING AND(UNIX OR MINGW))
SOURCES ${COMMONTEST_SRC} ${PLATFORMTEST_SRC}
ENVIRONMENT "ASAN_OPTIONS=${OC_ASAN_OPTIONS}"
"TSAN_OPTIONS=${OC_TSAN_OPTIONS}"
"UBSAN_OPTIONS=${OC_UBSAN_OPTIONS}"
)

file(GLOB MESSAGINGTEST_SRC messaging/coap/unittest/*.cpp)
Expand All @@ -996,6 +1019,7 @@ if(BUILD_TESTING AND(UNIX OR MINGW))
SOURCES ${COMMONTEST_SRC} ${MESSAGINGTEST_SRC}
ENVIRONMENT "ASAN_OPTIONS=${OC_ASAN_OPTIONS}"
"TSAN_OPTIONS=${OC_TSAN_OPTIONS}"
"UBSAN_OPTIONS=${OC_UBSAN_OPTIONS}"
)

if(OC_SECURITY_ENABLED)
Expand All @@ -1005,6 +1029,7 @@ if(BUILD_TESTING AND(UNIX OR MINGW))
SOURCES ${COMMONTEST_SRC} ${SECURITYTEST_SRC}
ENVIRONMENT "ASAN_OPTIONS=${OC_ASAN_OPTIONS}"
"TSAN_OPTIONS=${OC_TSAN_OPTIONS}"
"UBSAN_OPTIONS=${OC_UBSAN_OPTIONS}"
)

file(COPY ${PROJECT_SOURCE_DIR}/apps/pki_certs
Expand All @@ -1018,6 +1043,7 @@ if(BUILD_TESTING AND(UNIX OR MINGW))
SOURCES ${COMMONTEST_SRC} ${UTILTEST_SRC}
ENVIRONMENT "ASAN_OPTIONS=${OC_ASAN_OPTIONS}"
"TSAN_OPTIONS=${OC_TSAN_OPTIONS}"
"UBSAN_OPTIONS=${OC_UBSAN_OPTIONS}"
)

if(OC_CLOUD_ENABLED)
Expand All @@ -1028,6 +1054,7 @@ if(BUILD_TESTING AND(UNIX OR MINGW))
SOURCES ${COMMONTEST_SRC} ${CLOUDTEST_SRC}
ENVIRONMENT "ASAN_OPTIONS=${OC_ASAN_OPTIONS}"
"TSAN_OPTIONS=${OC_TSAN_OPTIONS}"
"UBSAN_OPTIONS=${OC_UBSAN_OPTIONS}"
)
endif()

Expand Down
6 changes: 2 additions & 4 deletions api/cloud/unittest/cloud_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,8 @@ TEST_F(TestCloud, cloud_set_last_error)
oc_cloud_context_t *ctx = oc_cloud_get_context(kDeviceID);
ASSERT_NE(nullptr, ctx);

int err = 123;

cloud_set_last_error(ctx, (oc_cloud_error_t)err);
ASSERT_EQ((oc_cloud_error_t)err, ctx->last_error);
cloud_set_last_error(ctx, CLOUD_ERROR_RESPONSE);
ASSERT_EQ(CLOUD_ERROR_RESPONSE, ctx->last_error);
}

TEST_F(TestCloud, cloud_update_by_resource)
Expand Down
1 change: 1 addition & 0 deletions api/oc_blockwise_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ typedef struct oc_blockwise_state_s
oc_string_t href;
oc_endpoint_t endpoint;
oc_method_t method;
oc_content_format_t content_format;
oc_blockwise_role_t role;
uint32_t payload_size;
uint32_t next_block_offset;
Expand Down
13 changes: 8 additions & 5 deletions api/oc_client_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@

#ifdef OC_CLIENT

#include "api/client/oc_client_cb_internal.h"
#include "api/oc_client_api_internal.h"
#include "api/oc_discovery_internal.h"
#include "api/oc_helpers_internal.h"
#include "oc_message_internal.h"
#include "api/client/oc_client_cb_internal.h"
#include "api/oc_rep_encode_internal.h"
#include "messaging/coap/coap.h"
#include "messaging/coap/coap_options.h"
#include "messaging/coap/transactions.h"
#include "oc_api.h"
#include "oc_message_internal.h"
#include "oc_ri_internal.h"

#ifdef OC_TCP
Expand Down Expand Up @@ -106,7 +107,8 @@ dispatch_coap_request(void)
} else
#endif /* OC_SPEC_VER_OIC */
{
coap_options_set_content_format(g_request, APPLICATION_VND_OCF_CBOR);
coap_options_set_content_format(g_request,
oc_rep_encoder_get_content_format());
}
}

Expand Down Expand Up @@ -210,7 +212,7 @@ prepare_coap_request(oc_client_cb_t *cb, coap_configure_request_fn_t configure,
} else
#endif /* OC_SPEC_VER_OIC */
{
coap_options_set_accept(g_request, APPLICATION_VND_OCF_CBOR);
coap_options_set_accept(g_request, oc_rep_encoder_get_content_format());
}

coap_set_token(g_request, cb->token, cb->token_len);
Expand Down Expand Up @@ -270,7 +272,8 @@ oc_do_multicast_update(void)
(uint32_t)payload_size);

if (payload_size > 0) {
coap_options_set_content_format(g_request, APPLICATION_VND_OCF_CBOR);
coap_options_set_content_format(g_request,
oc_rep_encoder_get_content_format());
}

g_multicast_update->length = coap_serialize_message(
Expand Down
42 changes: 26 additions & 16 deletions api/oc_core_res.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,29 @@ core_update_device_data(uint32_t device_count, oc_add_new_device_t cfg)
g_oc_device_info[device_count].data = cfg.add_device_cb_data;
}

static void
oc_create_device_resource(size_t device_count, const char *uri, const char *rt)
{
/* Construct device resource */
int properties = OC_DISCOVERABLE;
#ifdef OC_CLOUD
properties |= OC_OBSERVABLE;
#endif /* OC_CLOUD */
if (oc_strnlen(rt, OC_CHAR_ARRAY_LEN(OCF_D_RT) + 1) ==
OC_CHAR_ARRAY_LEN(OCF_D_RT) &&
strncmp(rt, OCF_D_RT, OC_CHAR_ARRAY_LEN(OCF_D_RT)) == 0) {
oc_core_populate_resource(OCF_D, device_count, uri,
OC_IF_R | OC_IF_BASELINE, OC_IF_R, properties,
oc_core_device_handler, /*put*/ NULL,
/*post*/ NULL, /*delete*/ NULL, 1, rt);
} else {
oc_core_populate_resource(OCF_D, device_count, uri,
OC_IF_R | OC_IF_BASELINE, OC_IF_R, properties,
oc_core_device_handler, /*put*/ NULL,
/*post*/ NULL, /*delete*/ NULL, 2, rt, OCF_D_RT);
}
}

oc_device_info_t *
oc_core_add_new_device(oc_add_new_device_t cfg)
{
Expand Down Expand Up @@ -336,20 +359,7 @@ oc_core_add_new_device(oc_add_new_device_t cfg)

core_update_device_data(device_count, cfg);

/* Construct device resource */
int properties = OC_DISCOVERABLE;
#ifdef OC_CLOUD
properties |= OC_OBSERVABLE;
#endif /* OC_CLOUD */
if (strlen(cfg.rt) == 8 && strncmp(cfg.rt, "oic.wk.d", 8) == 0) {
oc_core_populate_resource(OCF_D, device_count, cfg.uri,
OC_IF_R | OC_IF_BASELINE, OC_IF_R, properties,
oc_core_device_handler, 0, 0, 0, 1, cfg.rt);
} else {
oc_core_populate_resource(
OCF_D, device_count, cfg.uri, OC_IF_R | OC_IF_BASELINE, OC_IF_R,
properties, oc_core_device_handler, 0, 0, 0, 2, cfg.rt, "oic.wk.d");
}
oc_create_device_resource(device_count, cfg.uri, cfg.rt);

if (oc_get_con_res_announced()) {
/* Construct oic.wk.con resource for this device. */
Expand Down Expand Up @@ -705,8 +715,8 @@ oc_core_get_resource_type_by_uri(const char *uri, size_t uri_len)
OC_CHAR_ARRAY_LEN("/oic/p"))) {
return OCF_P;
}
if (core_is_resource_uri(uri, uri_len, "/oic/d",
OC_CHAR_ARRAY_LEN("/oic/p"))) {
if (core_is_resource_uri(uri, uri_len, OCF_D_URI,
OC_CHAR_ARRAY_LEN(OCF_D_URI))) {
return OCF_D;
}
if (core_is_resource_uri(uri, uri_len, OCF_RES_URI,
Expand Down
3 changes: 3 additions & 0 deletions api/oc_core_res_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
extern "C" {
#endif

#define OCF_D_URI "/oic/d"
#define OCF_D_RT "oic.wk.d"

/**
* @brief initialize the core functionality
*/
Expand Down
22 changes: 8 additions & 14 deletions api/oc_discovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -1201,8 +1201,8 @@ oc_wkcore_discovery_handler(oc_request_t *request,
const char *rt_device = NULL;
size_t rt_devlen = 0;
size_t device = request->resource->device;
oc_resource_t *resource =
oc_core_get_resource_by_uri_v1("oic/d", OC_CHAR_ARRAY_LEN("oic/d"), device);
oc_resource_t *resource = oc_core_get_resource_by_uri_v1(
OCF_D_URI, OC_CHAR_ARRAY_LEN(OCF_D_URI), device);
for (size_t i = 0; i < oc_string_array_get_allocated_size(resource->types);
++i) {
size_t size = oc_string_array_get_item_size(resource->types, i);
Expand All @@ -1227,7 +1227,6 @@ oc_wkcore_discovery_handler(oc_request_t *request,
// oic.d.sensor";if="oic.if.11 oic.if.baseline"

size_t length = clf_add_line_to_buffer("<");
response_length += length;

oc_endpoint_t *eps =
oc_connectivity_get_endpoints(request->resource->device);
Expand All @@ -1240,22 +1239,17 @@ oc_wkcore_discovery_handler(oc_request_t *request,
}
oc_string64_t ep;
if (oc_endpoint_to_string64(eps, &ep)) {
length = clf_add_str_to_buffer(oc_string(ep), oc_string_len(ep));
response_length += length;
length += clf_add_str_to_buffer(oc_string(ep), oc_string_len(ep));
break;
}
eps = eps->next;
}

length = clf_add_line_to_buffer("/oic/res>;");
response_length += length;
length = clf_add_line_to_buffer("rt=\"oic.wk.res ");
response_length += length;
length = clf_add_str_to_buffer(rt_device, rt_devlen);
response_length += length;
length = clf_add_line_to_buffer("\";");
response_length += length;
length =
length += clf_add_line_to_buffer("/oic/res>;");
length += clf_add_line_to_buffer("rt=\"oic.wk.res ");
length += clf_add_str_to_buffer(rt_device, rt_devlen);
length += clf_add_line_to_buffer("\";");
length +=
clf_add_line_to_buffer("if=\"oic.if.ll oic.if.baseline\";ct=10000");
response_length += length;
}
Expand Down
3 changes: 3 additions & 0 deletions api/oc_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ bool
oc_string_is_cstr_equal(const oc_string_t *str1, const char *str2,
size_t str2_len)
{
if (str1 == NULL || oc_string(*str1) == NULL) {
return str2 == NULL;
}
return oc_string_view_is_equal(oc_string_view2(str1),
oc_string_view(str2, str2_len));
}
Expand Down
6 changes: 3 additions & 3 deletions api/oc_helpers_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,14 @@ bool oc_string_is_equal(const oc_string_t *str1, const oc_string_t *str2)
/**
* @brief Compare an oc_string with a C-string
*
* @param str1 oc_string (cannot be NULL)
* @param str2 C-string (cannot be NULL)
* @param str1 oc_string
* @param str2 C-string
* @param str2_len length of \p str2
* @return true strings are equal
* @return false strings are not equal
*/
bool oc_string_is_cstr_equal(const oc_string_t *str1, const char *str2,
size_t str2_len) OC_NONNULL();
size_t str2_len);

/**
* @brief Fill buffer with random values.
Expand Down
Loading

0 comments on commit e95e8cd

Please sign in to comment.