Skip to content

Commit

Permalink
Add oc_endpoint_to_string64
Browse files Browse the repository at this point in the history
Create an oc_string64_t struct with statically allocated buffer that fits an endpoint
address to avoid the use of the heap.
The new function oc_endpoint_to_string64 converts an oc_endpoint_t to a string
address using the oc_string64_t.

Currently used internally.
---------

Co-authored-by: Daniel Adam <[email protected]>
  • Loading branch information
jkralik and Danielius1922 authored Sep 20, 2023
1 parent 7b99f87 commit 35f679b
Show file tree
Hide file tree
Showing 19 changed files with 410 additions and 158 deletions.
11 changes: 5 additions & 6 deletions api/oc_collection.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#if defined(OC_COLLECTIONS) && defined(OC_SERVER)
#include "api/oc_collection_internal.h"
#include "api/oc_endpoint_internal.h"
#include "api/oc_helpers_internal.h"
#include "api/oc_link_internal.h"
#include "api/oc_ri_internal.h"
Expand Down Expand Up @@ -715,10 +716,9 @@ collection_encode_links(const oc_collection_t *collection,
continue;
}
oc_rep_object_array_start_item(eps);
oc_string_t ep;
if (oc_endpoint_to_string(eps, &ep) == 0) {
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_free_string(&ep);
}
oc_rep_object_array_end_item(eps);
}
Expand Down Expand Up @@ -856,10 +856,9 @@ oc_handle_collection_linked_list_request(oc_request_t *request)
continue;
}
oc_rep_object_array_start_item(eps);
oc_string_t ep;
if (oc_endpoint_to_string(eps, &ep) == 0) {
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_free_string(&ep);
}
oc_rep_object_array_end_item(eps);
}
Expand Down
23 changes: 12 additions & 11 deletions api/oc_discovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "api/oc_core_res_internal.h"
#include "api/oc_discovery_internal.h"
#include "api/oc_endpoint_internal.h"
#include "api/oc_resource_internal.h"
#include "api/oc_ri_internal.h"
#include "api/oc_server_api_internal.h"
Expand Down Expand Up @@ -122,12 +123,11 @@ discovery_encode_endpoint(CborEncoder *eps, const oc_endpoint_t *ep,
int latency)
{
oc_rep_begin_object(eps, ep);
oc_string_t ep_str;
if (oc_endpoint_to_string(ep, &ep_str) == 0) {
oc_string64_t ep_str;
if (oc_endpoint_to_string64(ep, &ep_str)) {
g_err |= oc_rep_encode_text_string(&ep_map, "ep", OC_CHAR_ARRAY_LEN("ep"));
g_err |= oc_rep_encode_text_string(&ep_map, oc_string(ep_str),
oc_string_len(ep_str));
oc_free_string(&ep_str);
}
if (latency > 0) {
g_err |=
Expand Down Expand Up @@ -1058,14 +1058,15 @@ oc_wkcore_discovery_handler(oc_request_t *request,
oc_string_t uri;
memset(&uri, 0, sizeof(oc_string_t));
while (eps != NULL) {
if (eps->flags & SECURED) {
oc_string_t ep;
if (oc_endpoint_to_string(eps, &ep) == 0) {
length = clf_add_str_to_buffer(oc_string(ep), oc_string_len(ep));
response_length += length;
oc_free_string(&ep);
break;
}
if ((eps->flags & SECURED) == 0) {
eps = eps->next;
continue;
}
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;
break;
}
eps = eps->next;
}
Expand Down
111 changes: 70 additions & 41 deletions api/oc_endpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
*
****************************************************************************/

#include "api/oc_endpoint_internal.h"
#include "api/oc_helpers_internal.h"
#include "oc_endpoint.h"
#include "oc_endpoint_internal.h"
#include "oc_core_res.h"
#include "port/common/oc_ip.h"
#include "port/oc_connectivity.h"
Expand Down Expand Up @@ -66,26 +67,41 @@ oc_endpoint_set_di(oc_endpoint_t *endpoint, const oc_uuid_t *di)
memcpy(endpoint->di.id, di->id, sizeof(di->id));
}

const char *
oc_endpoint_flags_to_scheme(unsigned flags)
static oc_string_view_t
endpoint_flags_to_scheme(unsigned flags)
{
#ifdef OC_TCP
if ((flags & TCP) != 0) {
if ((flags & SECURED) != 0) {
return OC_SCHEME_COAPS_TCP;
return OC_STRING_VIEW(OC_SCHEME_COAPS_TCP);
}
return OC_SCHEME_COAP_TCP;
return OC_STRING_VIEW(OC_SCHEME_COAP_TCP);
}
#endif
#endif /* OC_TCP */
if ((flags & SECURED) != 0) {
return OC_SCHEME_COAPS;
return OC_STRING_VIEW(OC_SCHEME_COAPS);
}
return OC_SCHEME_COAP;
return OC_STRING_VIEW(OC_SCHEME_COAP);
}

int
oc_endpoint_flags_to_scheme(unsigned flags, char *buffer, size_t buffer_size)
{
oc_string_view_t scheme = endpoint_flags_to_scheme(flags);
if (buffer == NULL) {
return (int)scheme.length;
}
if (scheme.length < buffer_size) {
memcpy(buffer, scheme.data, scheme.length);
buffer[scheme.length] = '\0';
return (int)scheme.length;
}
return -1;
}

int
oc_endpoint_host(const oc_endpoint_t *endpoint, char *buffer,
uint32_t buffer_size)
size_t buffer_size)
{
#ifdef OC_IPV4
if ((endpoint->flags & IPV4) != 0) {
Expand All @@ -99,8 +115,8 @@ oc_endpoint_host(const oc_endpoint_t *endpoint, char *buffer,
}

int
oc_endpoint_to_cstring(const oc_endpoint_t *endpoint, char *buffer,
uint32_t buffer_size)
oc_endpoint_address_and_port_to_cstring(const oc_endpoint_t *endpoint,
char *buffer, size_t buffer_size)
{
#ifdef OC_IPV4
if ((endpoint->flags & IPV4) != 0) {
Expand All @@ -115,22 +131,58 @@ oc_endpoint_to_cstring(const oc_endpoint_t *endpoint, char *buffer,
return -1;
}

int
oc_endpoint_to_cstring(const oc_endpoint_t *endpoint, char *buffer,
size_t buffer_size)
{
int written =
oc_endpoint_flags_to_scheme(endpoint->flags, buffer, buffer_size);
if (written < 0) {
return -1;
}
int len = written;
buffer += written;
buffer_size -= (size_t)written;
written =
oc_endpoint_address_and_port_to_cstring(endpoint, buffer, buffer_size);
if (written < 0) {
return -1;
}
return len + written;
}

int
oc_endpoint_to_string(const oc_endpoint_t *endpoint, oc_string_t *endpoint_str)
{
if (!endpoint || !endpoint_str) {
return -1;
}

char ip[OC_IPV6_MAXSTRLEN] = { 0 };
if (oc_endpoint_to_cstring(endpoint, ip, OC_ARRAY_SIZE(ip)) != 0) {
oc_string64_t ep_str;
if (!oc_endpoint_to_string64(endpoint, &ep_str)) {
return -1;
}
oc_concat_strings(endpoint_str, oc_endpoint_flags_to_scheme(endpoint->flags),
ip);
oc_new_string(endpoint_str, oc_string(ep_str), oc_string_len(ep_str));
return 0;
}

bool
oc_endpoint_to_string64(const oc_endpoint_t *endpoint,
oc_string64_t *endpoint_str)
{
if (!endpoint || !endpoint_str) {
return false;
}
memset(endpoint_str, 0, sizeof(oc_string64_t));
int written = oc_endpoint_to_cstring(endpoint, oc_string(*endpoint_str),
OC_ARRAY_SIZE(endpoint_str->ptr));
if (written < 0) {
return false;
}
endpoint_str->size = (size_t)written + 1;
return true;
}

int
oc_endpoint_port(const oc_endpoint_t *endpoint)
{
Expand Down Expand Up @@ -353,26 +405,8 @@ parse_endpoint_uri(const oc_string_t *endpoint_str,
return false;
}

const char *address = NULL;
switch (flags) {
#ifdef OC_TCP
case TCP | SECURED:
address = ep + OC_CHAR_ARRAY_LEN(OC_SCHEME_COAPS_TCP);
break;
case TCP:
address = ep + OC_CHAR_ARRAY_LEN(OC_SCHEME_COAP_TCP);
break;
#endif /* OC_TCP */
case SECURED:
address = ep + OC_CHAR_ARRAY_LEN(OC_SCHEME_COAPS);
break;
case 0:
address = ep + OC_CHAR_ARRAY_LEN(OC_SCHEME_COAP);
break;
default:
OC_ERR("invalid endpoint(%s) uri scheme: %d", ep != NULL ? ep : "", flags);
return false;
}
oc_string_view_t scheme = endpoint_flags_to_scheme(flags);
const char *address = ep + scheme.length;
size_t ep_len = oc_string_len(*endpoint_str);
size_t address_len = ep_len - (address - ep);

Expand Down Expand Up @@ -701,12 +735,7 @@ oc_endpoint_list_copy(oc_endpoint_t **dst, const oc_endpoint_t *src)
return count;

oc_endpoint_list_copy_err:
ep = head;
while (ep != NULL) {
oc_endpoint_t *next = ep->next;
oc_free_endpoint(ep);
ep = next;
}
oc_endpoint_list_free(head);
return -1;
}

Expand Down
53 changes: 44 additions & 9 deletions api/oc_endpoint_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@

#include "oc_endpoint.h"
#include "util/oc_compiler.h"
#include "util/oc_macros_internal.h"

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
Expand All @@ -40,28 +43,60 @@ extern "C" {

#define OC_SCHEME_OCF "ocf://"

/** @brief Get scheme string for transport flags */
const char *oc_endpoint_flags_to_scheme(unsigned flags) OC_RETURNS_NONNULL;
/**
* @brief Write the scheme string (including NUL terminator) for given transport
* flags to buffer
*
* @param flags transport flags of an endpoint
* @param buffer output buffer (if NULL the function returns the number of bytes
* that would have been written, excluding the NUL terminator)
* @param buffer_size size of output buffer
* @return return number of written bytes (excluding the NUL terminator)
* @return -1 for error
*/
int oc_endpoint_flags_to_scheme(unsigned flags, char *buffer,
size_t buffer_size);

/**
* @brief Convert the endpoint to a human readable string (e.g.
* "coaps://[fe::22]:/")
* "[fe::22]:1234")
*
* @param endpoint the endpoint
* @param buffer output buffer
* @param endpoint the endpoint (cannot be NULL)
* @param buffer output buffer (cannot be NULL)
* @param buffer_size size of output buffer
* @return int 0 success
* @return number of written bytes, -1 for error
*/
int oc_endpoint_to_cstring(const oc_endpoint_t *endpoint, char *buffer,
uint32_t buffer_size) OC_NONNULL();
int oc_endpoint_address_and_port_to_cstring(const oc_endpoint_t *endpoint,
char *buffer, size_t buffer_size)
OC_NONNULL();

/** @brief Get host of the endpoint as string */
int oc_endpoint_host(const oc_endpoint_t *endpoint, char *buffer,
uint32_t buffer_size) OC_NONNULL();
size_t buffer_size) OC_NONNULL();

/** @brief Get port of the endpoint */
int oc_endpoint_port(const oc_endpoint_t *endpoint) OC_NONNULL();

typedef struct oc_string64_s
{
size_t size;
char ptr[64];
} oc_string64_t;

#define oc_string64_cap(ocstring) \
(OC_ARRAY_SIZE((ocstring).ptr) - (ocstring).size)

/**
* @brief convert the endpoint to a human readable string (e.g.
* "coaps://[fe::22]:1234").
*
* @param endpoint the endpoint
* @param endpoint_str endpoint as human readable string
* @return true for success
*/
bool oc_endpoint_to_string64(const oc_endpoint_t *endpoint,
oc_string64_t *endpoint_str);

#ifdef __cplusplus
}
#endif
Expand Down
6 changes: 3 additions & 3 deletions api/oc_introspection.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifdef OC_INTROSPECTION

#include "api/oc_core_res_internal.h"
#include "api/oc_endpoint_internal.h"
#include "api/oc_introspection_internal.h"
#include "api/oc_ri_internal.h"
#include "api/oc_server_api_internal.h"
Expand Down Expand Up @@ -126,10 +127,9 @@ oc_introspection_wk_get_uri(size_t device, int interface_index,
if ((interface_index == -1 ||
eps->interface_index == (unsigned)interface_index) &&
(eps->flags == flags)) {
oc_string_t ep;
if (oc_endpoint_to_string(eps, &ep) == 0) {
oc_string64_t ep;
if (oc_endpoint_to_string64(eps, &ep)) {
oc_concat_strings(uri, oc_string(ep), OC_INTROSPECTION_DATA_URI);
oc_free_string(&ep);
return true;
}
}
Expand Down
Loading

0 comments on commit 35f679b

Please sign in to comment.