Skip to content

Commit

Permalink
fixup! Calcuate crc64 for a resource
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielius1922 committed Oct 19, 2023
1 parent 3baebdb commit 4e153e8
Show file tree
Hide file tree
Showing 18 changed files with 173 additions and 51 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/cmake-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ jobs:
- args: "-DOC_DYNAMIC_ALLOCATION_ENABLED=OFF -DOC_SECURITY_ENABLED=OFF -DOC_PKI_ENABLED=OFF -DOC_IDD_API_ENABLED=OFF -DOC_OSCORE_ENABLED=OFF -DOC_WKCORE_ENABLED=OFF -DOC_SOFTWARE_UPDATE_ENABLED=OFF -DOC_MNT_ENABLED=OFF -DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=OFF -DOC_PUSH_ENABLED=OFF -DPLGD_DEV_TIME_ENABLED=OFF -DOC_INTROSPECTION_ENABLED=OFF -DOC_ETAG_ENABLED=OFF"
uses: ./.github/workflows/unit-test-with-cfg.yml
with:
build_args: -DOC_LOG_MAXIMUM_LOG_LEVEL=INFO -DOC_WKCORE_ENABLED=ON -DOC_SOFTWARE_UPDATE_ENABLED=ON -DOC_MNT_ENABLED=ON -DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DPLGD_DEV_TIME_ENABLED=ON -DOC_ETAG_ENABLED=ON ${{ matrix.args }}
# build_args: -DOC_LOG_MAXIMUM_LOG_LEVEL=INFO -DOC_WKCORE_ENABLED=ON -DOC_SOFTWARE_UPDATE_ENABLED=ON -DOC_MNT_ENABLED=ON -DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DPLGD_DEV_TIME_ENABLED=ON -DOC_ETAG_ENABLED=ON ${{ matrix.args }}
build_args: -DOC_DEBUG_ENABLED=ON -DOC_WKCORE_ENABLED=ON -DOC_SOFTWARE_UPDATE_ENABLED=ON -DOC_MNT_ENABLED=ON -DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON -DOC_PUSH_ENABLED=ON -DPLGD_DEV_TIME_ENABLED=ON -DOC_ETAG_ENABLED=ON ${{ matrix.args }}
build_type: ${{ (github.event_name == 'workflow_dispatch' && inputs.build_type) || 'Debug' }}
clang: ${{ github.event_name == 'workflow_dispatch' && inputs.clang }}
coverage: false
Expand Down
61 changes: 49 additions & 12 deletions api/oc_etag.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "port/oc_log_internal.h"
#include "port/oc_random.h"
#include "util/oc_macros_internal.h"
#include "util/oc_mmem_internal.h"

#ifdef OC_SECURITY
#include "oc_csr.h"
Expand Down Expand Up @@ -240,8 +241,11 @@ etag_iterate_encode_resource(oc_resource_t *resource, void *data)
}

uint64_t crc64 = 0;
bool include_hash =
oc_resource_get_crc64(resource, &crc64) == OC_RESOURCE_CRC64_OK;
if (oc_resource_get_crc64(resource, &crc64) != OC_RESOURCE_CRC64_OK) {
OC_DBG("cannot calculate crc64 for device(%zu) resource(%s)",
resource->device, oc_string(resource->uri));
return true;
}

CborError err =
oc_rep_encode_text_string(oc_rep_object(root), oc_string(resource->uri),
Expand All @@ -253,11 +257,8 @@ etag_iterate_encode_resource(oc_resource_t *resource, void *data)
err |=
oc_rep_encode_text_string(&etag_map, "etag", OC_CHAR_ARRAY_LEN("etag"));
err |= oc_rep_encode_uint(&etag_map, etag);
if (include_hash) {
err |=
oc_rep_encode_text_string(&etag_map, "hash", OC_CHAR_ARRAY_LEN("hash"));
err |= oc_rep_encode_uint(&etag_map, crc64);
}
err |= oc_rep_encode_text_string(&etag_map, "crc", OC_CHAR_ARRAY_LEN("crc"));
err |= oc_rep_encode_uint(&etag_map, crc64);
err |= oc_rep_encoder_close_container(oc_rep_object(root), &etag_map);

if (err != CborNoError) {
Expand Down Expand Up @@ -317,17 +318,41 @@ etag_iterate_update_resources_by_rep(oc_resource_t *resource, void *data)
etag_update_from_rep_data_t *rep_data = (etag_update_from_rep_data_t *)data;
oc_rep_t *res_rep;
if (!oc_rep_get_object(rep_data->rep, oc_string(resource->uri), &res_rep)) {
OC_DBG("no representation for resource %s", oc_string(resource->uri));
OC_DBG("no representation for resource %zu:%s", resource->device,
oc_string(resource->uri));
return true;
}

int64_t etag = 0;
if (!oc_rep_get_int(res_rep, "etag", &etag) || etag < 0 ||
etag == OC_ETAG_UNINITIALIZED) {
OC_DBG("ignoring invalid etag for resource %s", oc_string(resource->uri));
OC_DBG("ignoring invalid etag for resource %zu:%s", resource->device,
oc_string(resource->uri));
return true;
}

// int64_t crc64_store = 0;
// if (!oc_rep_get_int(res_rep, "crc", &crc64_store)) {
// OC_DBG("no checksum for resource %zu:%s", resource->device,
// oc_string(resource->uri));
// return true;
// }

// uint64_t crc64 = 0;
// if (oc_resource_get_crc64(resource, &crc64) != OC_RESOURCE_CRC64_OK) {
// OC_DBG("cannot calculate crc64 for resource %zu:%s", resource->device,
// oc_string(resource->uri));
// return true;
// }

// if ((uint64_t)crc64_store != crc64) {
// OC_DBG("ignoring invalid checksum for resource %zu:%s: store (%" PRIu64
// ") vs current(%" PRIu64 ")",
// resource->device, oc_string(resource->uri), (uint64_t)crc64_store,
// crc64);
// return true;
// }

oc_resource_set_etag(resource, (uint64_t)etag);
if ((uint64_t)etag > *rep_data->etag) {
*rep_data->etag = (uint64_t)etag;
Expand Down Expand Up @@ -484,6 +509,13 @@ resource_print_payload(oc_resource_t *resource, oc_interface_mask_t iface)
#ifdef OC_DYNAMIC_ALLOCATION
// might have been reallocated by the handler
buffer = response_buffer.buffer;
#else /* !OC_DYNAMIC_ALLOCATION */
size_t avail_bytes = oc_mmem_available_size(BYTE_POOL);
if (avail_bytes < response_buffer.response_length) {
OC_DBG("not enough memory to print payload of resource(%s)",
oc_string(resource->uri));
return;
}
#endif /* OC_DYNAMIC_ALLOCATION */

oc_rep_decoder_t decoder = oc_rep_decoder(OC_REP_CBOR_DECODER);
Expand All @@ -498,14 +530,19 @@ resource_print_payload(oc_resource_t *resource, oc_interface_mask_t iface)
#endif /* OC_DYNAMIC_ALLOCATION */
return;
}
#ifdef OC_DYNAMIC_ALLOCATION
size_t json_size = oc_rep_to_json(rep, NULL, 0, true);
char *json = (char *)malloc(json_size + 1);
oc_rep_to_json(rep, json, json_size + 1, true);
#else /* !OC_DYNAMIC_ALLOCATION */
char json[4096] = { 0 };
oc_rep_to_json(rep, json, OC_ARRAY_SIZE(json), true);
#endif /* OC_DYNAMIC_ALLOCATION */
OC_DBG("Resource(%s) payload: %s", oc_string(resource->uri), json);
free(json);
oc_free_rep(rep);
oc_rep_set_pool(prev_rep_objects);
#ifdef OC_DYNAMIC_ALLOCATION
free(json);
free(buffer);
#endif /* OC_DYNAMIC_ALLOCATION */
}
Expand Down Expand Up @@ -583,8 +620,8 @@ oc_resource_set_etag(oc_resource_t *resource, uint64_t etag)
{
assert(resource != NULL);
resource->etag = etag;
OC_DBG("oc_etag: set resource %s etag to %" PRIu64, oc_string(resource->uri),
etag);
OC_DBG("oc_etag: set resource %zu:%s etag to %" PRIu64, resource->device,
oc_string(resource->uri), etag);
}

uint64_t
Expand Down
29 changes: 18 additions & 11 deletions api/oc_introspection.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "oc_endpoint.h"
#include "oc_introspection.h"
#include "port/oc_log_internal.h"
#include "port/oc_storage_internal.h"
#include "util/oc_macros_internal.h"

#ifdef OC_HAS_FEATURE_CRC_ENCODER
Expand Down Expand Up @@ -82,6 +83,9 @@ oc_introspection_get_data(size_t device, uint8_t *buffer, size_t buffer_size)
OC_ERR("cannot get introspection data: failed to generate tag");
return -1;
}
if (buffer == NULL) {
return oc_storage_size(idd_tag);
}
long ret = oc_storage_read(idd_tag, buffer, buffer_size);
if (ret < 0) {
OC_ERR("cannot get introspection data: failed to read data(error=%ld)",
Expand All @@ -91,6 +95,9 @@ oc_introspection_get_data(size_t device, uint8_t *buffer, size_t buffer_size)
return ret;
#else /* !OC_IDD_API */
(void)device;
if (buffer == NULL) {
return introspection_data_size;
}
if (introspection_data_size < buffer_size) {
memcpy(buffer, introspection_data, introspection_data_size);
return introspection_data_size;
Expand Down Expand Up @@ -141,29 +148,25 @@ introspection_data_handler_crc(oc_request_t *request)
ret);
return;
}
oc_string_t idd_data;
oc_alloc_string(&idd_data, (size_t)ret);
if (idd_data.size == 0) {
OC_ERR("cannot encode introspection data: failed to allocate memory");
return;
}
ret = oc_storage_read(idd_tag, oc_cast(idd_data, uint8_t), idd_data.size);
uint8_t idd_data[ret];
memset(idd_data, 0, (size_t)ret);
ret = oc_storage_read(idd_tag, idd_data, (size_t)ret);
if (ret < 0) {
OC_ERR("cannot encode introspection data: failed to read data(error=%ld)",
ret);
oc_free_string(&idd_data);
return;
}
crc = oc_crc64(0, oc_cast(idd_data, uint8_t), idd_data.size);
oc_free_string(&idd_data);
crc = oc_crc64(0, idd_data, (size_t)ret);
#else /* !OC_IDD_API */
crc = oc_crc64(0, introspection_data, introspection_data_size);
#endif /* OC_IDD_API */

if (oc_rep_encoder_write_uint(oc_rep_global_encoder(), oc_rep_get_encoder(),
crc) != CborNoError) {
OC_ERR("cannot encode introspection data: failed to encode data");
}

request->response->response_buffer->response_length = sizeof(crc);
request->response->response_buffer->code = CONTENT_2_05;
}

#endif /* OC_HAS_FEATURE_CRC_ENCODER */
Expand Down Expand Up @@ -244,8 +247,12 @@ oc_core_introspection_wk_handler(oc_request_t *request,

int if_index =
(request->origin != NULL) ? (int)request->origin->interface_index : -1;
#ifdef OC_IPV4
transport_flags flags =
(request->origin != NULL && (request->origin->flags & IPV6)) ? IPV6 : IPV4;
#else /* !OC_IPV4 */
transport_flags flags = IPV6;
#endif /* OC_IPV4 */
oc_string_t uri;
memset(&uri, 0, sizeof(oc_string_t));
if (!oc_introspection_wk_get_uri(request->resource->device, if_index, flags,
Expand Down
5 changes: 4 additions & 1 deletion api/oc_introspection_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,12 @@ extern "C" {
* @param buffer_size size of the buffer
* @return long size of the introspection data
* @return -1 on error
*
* @note if buffer is NULL, the function will return the size of the
* introspection data
*/
long oc_introspection_get_data(size_t device, uint8_t *buffer,
size_t buffer_size) OC_NONNULL();
size_t buffer_size);

/**
* @brief Find endpoint from given device with the given transport flags and
Expand Down
14 changes: 7 additions & 7 deletions api/oc_rep_encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ rep_buffer_realloc(oc_rep_encoder_t *encoder, size_t needed)
}
if (encoder->buffer.size + needed > encoder->buffer.max_size) {
OC_WRN("Insufficient memory: Increase OC_MAX_APP_DATA_SIZE to accomodate a "
"larger payload(+%d)",
(int)needed);
"larger payload(+%zu)",
needed);
return CborErrorOutOfMemory;
}

Expand Down Expand Up @@ -332,8 +332,8 @@ oc_rep_encoder_payload_size(oc_rep_encoder_t *encoder)
oc_rep_encoder_convert_ptr_to_offset(encoder, &encoder->ctx);
if (g_err == CborErrorOutOfMemory) {
OC_WRN("Insufficient memory: Increase OC_MAX_APP_DATA_SIZE to "
"accomodate a larger payload(+%d)",
(int)needed);
"accomodate a larger payload(+%zu)",
needed);
(void)needed;
}
if (g_err != CborNoError) {
Expand All @@ -355,7 +355,8 @@ oc_rep_encoder_remaining_size(oc_rep_encoder_t *encoder)
OC_WRN("encoder has not set end pointer.");
return -1;
}
return encoder->buffer.size - (size_t)encoder->ctx.data.ptr;
assert(encoder->buffer.size >= (size_t)encoder->ctx.data.ptr);
return (ssize_t)(encoder->buffer.size - (size_t)encoder->ctx.data.ptr);
}

CborError
Expand All @@ -382,10 +383,9 @@ oc_rep_encoder_write_raw(oc_rep_encoder_t *encoder, const uint8_t *data,
}
memcpy(&encoder->ctx, &prevEncoder, sizeof(prevEncoder));
#else /* OC_DYNAMIC_ALLOCATION */
size_t needed = len - remaining;
OC_WRN("Insufficient memory: Increase OC_MAX_APP_DATA_SIZE to "
"accomodate a larger payload(+%zu)",
(int)needed);
len - remaining);
return CborErrorOutOfMemory;
#endif /* !OC_DYNAMIC_ALLOCATION */
}
Expand Down
3 changes: 2 additions & 1 deletion api/oc_rep_encode_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ typedef CborError (*oc_rep_encode_double_t)(CborEncoder *encoder, double value)

typedef CborError (*oc_rep_encode_text_string_t)(CborEncoder *encoder,
const char *string,
size_t length) OC_NONNULL();
size_t length) OC_NONNULL(1);

typedef CborError (*oc_rep_encode_byte_string_t)(CborEncoder *encoder,
const uint8_t *string,
Expand All @@ -85,6 +85,7 @@ typedef CborError (*oc_rep_encoder_create_array_t)(CborEncoder *encoder,
typedef CborError (*oc_rep_encoder_create_map_t)(CborEncoder *encoder,
CborEncoder *mapEncoder,
size_t length) OC_NONNULL();

typedef CborError (*oc_rep_encoder_close_container_t)(
CborEncoder *encoder, const CborEncoder *containerEncoder) OC_NONNULL();

Expand Down
8 changes: 8 additions & 0 deletions api/oc_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "port/oc_connectivity.h"
#include "port/oc_log_internal.h"
#include "port/oc_storage.h"
#include "util/oc_macros_internal.h"

#include <stdio.h>

Expand Down Expand Up @@ -165,11 +166,18 @@ storage_print_data(const uint8_t *buf, size_t size)
if (CborNoError != decoder.parse(buf, size, &rep)) {
return;
}
#ifdef OC_DYNAMIC_ALLOCATION
size_t json_size = oc_rep_to_json(rep, NULL, 0, true);
char *json = (char *)malloc(json_size + 1);
oc_rep_to_json(rep, json, json_size + 1, true);
#else /* !OC_DYNAMIC_ALLOCATION */
char json[4096] = { 0 };
oc_rep_to_json(rep, json, OC_ARRAY_SIZE(json), true);
#endif /* OC_DYNAMIC_ALLOCATION */
OC_DBG("payload %s", json);
#ifdef OC_DYNAMIC_ALLOCATION
free(json);
#endif /* OC_DYNAMIC_ALLOCATION */
oc_free_rep(rep);
oc_rep_set_pool(prev_rep_objects);
}
Expand Down
8 changes: 8 additions & 0 deletions api/unittest/etagtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,11 +621,19 @@ TEST_F(TestETagWithServer, DumpAndLoad)
oc_string_len(resource->uri))) {
return;
}
#ifdef OC_INTROSPECTION
if (std::string(oc_string(resource->uri)) == OC_INTROSPECTION_DATA_URI &&
oc_introspection_get_data(resource->device, nullptr, 0) <= 0) {
return;
}
#endif /* OC_INTROSPECTION */

if (std::find(std::begin(dynResources), std::end(dynResources), resource) !=
std::end(dynResources)) {
EXPECT_NE(0, oc_resource_get_etag(resource));
return;
}

EXPECT_EQ(1337, oc_resource_get_etag(resource));
});

Expand Down
2 changes: 1 addition & 1 deletion api/unittest/reptest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ TEST_F(TestRepWithPool, OCRepSetGetByteString)
/* add text string value "hal9000":"Dave" to root object */
oc_rep_start_root_object();
ASSERT_EQ(CborNoError, oc_rep_get_cbor_errno());
oc_rep_set_byte_string(root, empty_byte_string, nullptr, 0);
oc_rep_set_byte_string(root, empty_byte_string, (const uint8_t *)"", 0);
ASSERT_EQ(CborNoError, oc_rep_get_cbor_errno());
const uint8_t test_byte_string[] = { 0x01, 0x02, 0x03, 0x04, 0x02, 0x00 };
oc_rep_set_byte_string(root, test_byte_string, test_byte_string,
Expand Down
7 changes: 6 additions & 1 deletion security/oc_oscore_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,12 @@ oc_oscore_context_derive_param(const uint8_t *id, uint8_t id_len,
/* Array of 5 elements */
err |= cbor_encoder_create_array(&e, &a, 5);
/* Sender ID, Recipient ID or empty string for Common IV */
err |= cbor_encode_byte_string(&a, id, id_len);
if (id_len > 0) {
err |= cbor_encode_byte_string(&a, id, id_len);
} else {
// we need a non-NULL pointer otherwise UBSAN detects an issue
err |= cbor_encode_byte_string(&a, (const uint8_t *)"", 0);
}
/* id_context or null if not provided */
if (id_ctx_len > 0) {
err |= cbor_encode_byte_string(&a, id_ctx, id_ctx_len);
Expand Down
Loading

0 comments on commit 4e153e8

Please sign in to comment.