Skip to content

Commit

Permalink
Add test TCP client
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielius1922 authored and Daniel Adam committed Nov 24, 2023
1 parent 20e66f8 commit 4eec81c
Show file tree
Hide file tree
Showing 65 changed files with 4,750 additions and 2,611 deletions.
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ file(GLOB COMMON_SRC
${PROJECT_SOURCE_DIR}/util/*.c
)

if(UNIX)
if(UNIX OR WIN32)
file(GLOB COMMON_POSIX_SRC
${PROJECT_SOURCE_DIR}/port/common/posix/*.c
)
Expand Down Expand Up @@ -985,10 +985,10 @@ if(BUILD_TESTING AND(UNIX OR MINGW))
list(APPEND OC_UNITTESTS ${OC_PACKAGE_ADD_TEST_TARGET})
endmacro()

file(GLOB COMMONTEST_SRC tests/gtest/*.cpp tests/gtest/tls/*.cpp)
file(GLOB COMMONTEST_SRC tests/gtest/*.cpp tests/gtest/coap/*.cpp tests/gtest/tls/*.cpp)

# Unit tests
file(GLOB APITEST_SRC api/unittest/*.cpp api/unittest/encoder/*.cpp api/client/unittest/*.cpp)
file(GLOB APITEST_SRC api/unittest/*.cpp api/unittest/discovery/*.cpp api/unittest/encoder/*.cpp api/client/unittest/*.cpp)
set(apitest_files)
if (OC_INTROSPECTION_ENABLED AND OC_IDD_API_ENABLED)
set(apitest_files ${PROJECT_SOURCE_DIR}/api/unittest/introspectiontest_IDD.cbor)
Expand Down
110 changes: 15 additions & 95 deletions api/oc_collection.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,16 +664,17 @@ collection_encode_mandatory_rts(const oc_collection_t *collection)
}

static bool
collection_encode_links(const oc_collection_t *collection,
const oc_request_t *request)
collection_encode_links(CborEncoder *container, const oc_request_t *request)
{
oc_rep_set_array(root, links);
for (const oc_link_t *link = (oc_link_t *)oc_list_head(collection->links);
const oc_collection_t *collection =
(const oc_collection_t *)request->resource;
for (const oc_link_t *link =
(const oc_link_t *)oc_list_head(collection->links);
link != NULL; link = link->next) {
if (!oc_filter_resource_by_rt(link->resource, request)) {
continue;
}
oc_rep_object_array_start_item(links);
oc_rep_begin_object(container, links);
oc_rep_set_text_string_v1(links, href, oc_string(link->resource->uri),
oc_string_len(link->resource->uri));
oc_rep_set_string_array(links, rt, link->resource->types);
Expand Down Expand Up @@ -743,9 +744,8 @@ collection_encode_links(const oc_collection_t *collection,
}
oc_rep_close_array(links, eps);

oc_rep_object_array_end_item(links);
oc_rep_end_object(container, links);
}
oc_rep_close_array(root, links);
return g_err == CborNoError;
}

Expand Down Expand Up @@ -784,7 +784,9 @@ oc_handle_collection_baseline_request(oc_method_t method, oc_request_t *request)
collection_encode_mandatory_rts(collection);

/* links */
collection_encode_links(collection, request);
oc_rep_open_array(root, links);
collection_encode_links(oc_rep_array(links), request);
oc_rep_close_array(root, links);

/* custom properties */
if (collection->res.get_properties.cb.get_props != NULL) {
Expand All @@ -805,95 +807,16 @@ oc_handle_collection_baseline_request(oc_method_t method, oc_request_t *request)
}

static void
oc_handle_collection_linked_list_request(oc_request_t *request)
oc_handle_collection_linked_list_request(const oc_request_t *request)
{
const oc_collection_t *collection = (oc_collection_t *)request->resource;
oc_link_t *link = (oc_link_t *)oc_list_head(collection->links);
oc_rep_start_links_array();
while (link != NULL) {
if (oc_filter_resource_by_rt(link->resource, request)) {
oc_rep_object_array_start_item(links);
oc_rep_set_text_string_v1(links, href, oc_string(link->resource->uri),
oc_string_len(link->resource->uri));
oc_rep_set_string_array(links, rt, link->resource->types);
oc_core_encode_interfaces_mask(oc_rep_object(links), link->interfaces,
false);
oc_rep_set_string_array(links, rel, link->rel);
oc_rep_set_int(links, ins, link->ins);
oc_link_params_t *p = (oc_link_params_t *)oc_list_head(link->params);
while (p) {
oc_rep_set_key_v1(oc_rep_object(links), oc_string(p->key),
oc_string_len(p->key));
oc_rep_set_value_text_string_v1(links, oc_string(p->value),
oc_string_len(p->value));
p = p->next;
}
oc_rep_set_object(links, p);
oc_rep_set_uint(
p, bm,
(uint8_t)(link->resource->properties & ~(OC_PERIODIC | OC_SECURE)));
oc_rep_close_object(links, p);

// tag-pos-desc
if (link->resource->tag_pos_desc > 0) {
const char *desc =
oc_enum_pos_desc_to_str(link->resource->tag_pos_desc);
if (desc) {
// clang-format off
oc_rep_set_text_string(links, tag-pos-desc, desc);
// clang-format on
}
}

// tag-func-desc
if (link->resource->tag_func_desc > 0) {
const char *func = oc_enum_to_str(link->resource->tag_func_desc);
if (func) {
// clang-format off
oc_rep_set_text_string(links, tag-func-desc, func);
// clang-format on
}
}

// tag-pos-rel
const double *pos = link->resource->tag_pos_rel;
if (pos[0] != 0 || pos[1] != 0 || pos[2] != 0) {
oc_rep_set_key(oc_rep_object(links), "tag-pos-rel");
oc_rep_start_array(oc_rep_object(links), tag_pos_rel);
oc_rep_add_double(tag_pos_rel, pos[0]);
oc_rep_add_double(tag_pos_rel, pos[1]);
oc_rep_add_double(tag_pos_rel, pos[2]);
oc_rep_end_array(oc_rep_object(links), tag_pos_rel);
}

// eps
oc_rep_set_array(links, eps);
oc_endpoint_t *eps =
oc_connectivity_get_endpoints(link->resource->device);
for (; eps != NULL; eps = eps->next) {
if (oc_filter_out_ep_for_resource(eps, link->resource, request->origin,
link->resource->device, false)) {
continue;
}
oc_rep_object_array_start_item(eps);
oc_string64_t ep;
if (oc_endpoint_to_string64(eps, &ep)) {
oc_rep_set_text_string_v1(eps, ep, oc_string(ep), oc_string_len(ep));
}
oc_rep_object_array_end_item(eps);
}
oc_rep_close_array(links, eps);

oc_rep_object_array_end_item(links);
}
link = link->next;
}
collection_encode_links(oc_rep_array(links), request);
oc_rep_end_links_array();
}

static bool
collection_invoke_handler(const oc_collection_t *collection,
oc_resource_t *resource, oc_request_t *request)
const oc_resource_t *resource, oc_request_t *request)
{
oc_interface_mask_t iface = resource->default_interface;
if (resource == &collection->res) {
Expand Down Expand Up @@ -935,7 +858,6 @@ collection_batch_request_process_links(const oc_collection_t *collection,
rest_request.request_payload = payload;
}

CborEncoder prev_link;
for (oc_link_t *link = (oc_link_t *)oc_list_head(collection->links);
link != NULL; link = link->next) {
if (link->resource == NULL ||
Expand All @@ -951,6 +873,7 @@ collection_batch_request_process_links(const oc_collection_t *collection,
oc_string_len(*href)) != 0)) {
continue;
}
CborEncoder prev_link;
memcpy(&prev_link, &links_array, sizeof(CborEncoder));
oc_rep_object_array_start_item(links);
rest_request.query = NULL;
Expand Down Expand Up @@ -991,14 +914,11 @@ collection_batch_request_process_links(const oc_collection_t *collection,
&rest_request)) {
ecode = oc_status_code_unsafe(OC_STATUS_METHOD_NOT_ALLOWED);
memcpy(&links_array, &prev_link, sizeof(CborEncoder));
continue;
continue; // NOLINT(bugprone-terminating-continue)
}
}
}

if ((method == OC_PUT || method == OC_POST) &&
response_buffer.code < oc_status_code_unsafe(OC_STATUS_BAD_REQUEST)) {
}
if (response_buffer.code < oc_status_code_unsafe(OC_STATUS_BAD_REQUEST)) {
pcode = response_buffer.code;
} else {
Expand Down
5 changes: 3 additions & 2 deletions api/oc_rep_encode_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,9 @@ bool oc_rep_encoder_get_content_format(oc_content_format_t *format)
OC_NONNULL();

/** @brief Write raw data to encoder */
int oc_rep_encoder_write_raw(oc_rep_encoder_t *encoder, const uint8_t *data,
size_t len) OC_NONNULL(1);
CborError oc_rep_encoder_write_raw(oc_rep_encoder_t *encoder,
const uint8_t *data, size_t len)
OC_NONNULL(1);

/** @brief Write null representation to encoder */
CborError oc_rep_encoder_write_null(oc_rep_encoder_t *encoder,
Expand Down
2 changes: 0 additions & 2 deletions api/oc_server_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,6 @@ oc_send_response_with_callback(oc_request_t *request, oc_status_t response_code,
content_format = APPLICATION_CBOR;
}
#endif /* OC_SPEC_VER_OIC */
// method == OC_GET and response_code == OC_STATUS_OK nepouzit response_length
// ale poslat payload length skutocny
if (!oc_send_response_internal(request, response_code, content_format,
response_length(), trigger_cb)) {
OC_ERR("could not send response: invalid response code");
Expand Down
57 changes: 46 additions & 11 deletions api/oc_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,18 @@ oc_tcp_on_connect_event_free(oc_tcp_on_connect_event_t *event)
#endif /* OC_HAS_FEATURE_TCP_ASYNC_CONNECT */

bool
oc_tcp_is_valid_header(const oc_message_t *message)
oc_tcp_is_valid_header(const uint8_t *data, size_t data_size, bool is_tls)
{
assert(message != NULL);
#ifdef OC_SECURITY
if ((message->endpoint.flags & SECURED) != 0) {
if (message->length < 3) {
OC_ERR("TLS header too short: %lu", (long unsigned)message->length);
if (is_tls) {
if (data_size < 3) {
OC_ERR("TLS header too short: %zu", data_size);
return false;
}
// Parse the header fields
uint8_t type = message->data[0];
uint8_t major_version = message->data[1];
uint8_t minor_version = message->data[2];
uint8_t type = data[0];
uint8_t major_version = data[1];
uint8_t minor_version = data[2];
OC_DBG("TLS header: record type: %d, major %d, minor %d", type,
major_version, minor_version);
// Validate the header fields
Expand Down Expand Up @@ -134,9 +133,15 @@ oc_tcp_is_valid_header(const oc_message_t *message)
}
return true;
}
#else /* !OC_SECURITY */
(void)is_tls;
#endif /* OC_SECURITY */
int token_len = (COAP_HEADER_TOKEN_LEN_MASK & message->data[0]) >>
COAP_HEADER_TOKEN_LEN_POSITION;
if (data_size < 1) {
OC_ERR("TCP header too short: %zu", data_size);
return false;
}
int token_len =
(COAP_HEADER_TOKEN_LEN_MASK & data[0]) >> COAP_HEADER_TOKEN_LEN_POSITION;
if (token_len > COAP_TOKEN_LEN) {
OC_ERR("invalid token length: %d", token_len);
// Invalid token length
Expand All @@ -155,7 +160,7 @@ oc_tcp_is_valid_message(oc_message_t *message)
return true;
}
#ifdef OC_OSCORE
if (oscore_is_oscore_message(message) >= 0) {
if (oscore_is_oscore_message(message)) {
// it is oscore message
return true;
}
Expand All @@ -172,4 +177,34 @@ oc_tcp_is_valid_message(oc_message_t *message)
return true;
}

long
oc_tcp_get_total_length_from_message_header(const oc_message_t *message)
{
return oc_tcp_get_total_length_from_header(
message->data, message->length, (message->endpoint.flags & SECURED) != 0);
}

long
oc_tcp_get_total_length_from_header(const uint8_t *data, size_t data_size,
bool is_tls)
{
if (!oc_tcp_is_valid_header(data, data_size, is_tls)) {
OC_ERR("invalid header");
return -1;
}

#ifdef OC_SECURITY
#define OC_TLS_HEADER_SIZE (5)
if (is_tls) {
if (data_size < OC_TLS_HEADER_SIZE) {
OC_ERR("TLS header too short: %zu", data_size);
return -1;
}
//[3][4] bytes in tls header are tls payload length
return OC_TLS_HEADER_SIZE + ((data[3] << 8) | data[4]);
}
#endif /* OC_SECURITY */
return coap_tcp_get_packet_size(data, data_size);
}

#endif /* OC_TCP */
27 changes: 24 additions & 3 deletions api/oc_tcp_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,19 @@

#ifdef OC_TCP

#include "messaging/coap/constants.h"
#include "port/oc_connectivity.h"
#include "oc_endpoint.h"

#ifdef __cplusplus
extern "C" {
#endif

#define OC_TCP_DEFAULT_RECEIVE_SIZE \
(COAP_TCP_DEFAULT_HEADER_LEN + COAP_TCP_MAX_EXTENDED_LENGTH_LEN)

#ifdef OC_HAS_FEATURE_TCP_ASYNC_CONNECT

typedef struct oc_tcp_on_connect_event_s
{
struct oc_tcp_on_connect_data_s *next;
Expand All @@ -49,15 +54,31 @@ void oc_tcp_on_connect_event_free(oc_tcp_on_connect_event_t *event);

#endif /* OC_HAS_FEATURE_TCP_ASYNC_CONNECT */

/** @brief Check if the message is a valid CoAP/TLS header */
bool oc_tcp_is_valid_header(const oc_message_t *message);
/** @brief Check if data is a valid CoAP/TLS header */
bool oc_tcp_is_valid_header(const uint8_t *data, size_t data_size, bool is_tls);

/** @brief Check if the message is a valid for CoAP TCP */
bool oc_tcp_is_valid_message(oc_message_t *message);
bool oc_tcp_is_valid_message(oc_message_t *message) OC_NONNULL();

/**
* @brief Read total length from TCP or TLS header
*
* @param data the data
* @param data_size size of the data
* @param is_tls true if the data is TLS
* @return long
*/
long oc_tcp_get_total_length_from_header(const uint8_t *data, size_t data_size,
bool is_tls);

/** Convenience wrapper for oc_tcp_get_total_length_from_header */
long oc_tcp_get_total_length_from_message_header(const oc_message_t *message)
OC_NONNULL();

#ifdef __cplusplus
}
#endif

#endif /* OC_TCP */

#endif /* OC_TCP_INTERNAL_H */
2 changes: 1 addition & 1 deletion api/oc_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ oc_udp_is_valid_message(oc_message_t *message)
return true;
}
#ifdef OC_OSCORE
if (oscore_is_oscore_message(message) >= 0) {
if (oscore_is_oscore_message(message)) {
// it is oscore message
return true;
}
Expand Down
Loading

0 comments on commit 4eec81c

Please sign in to comment.