-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
18134: nanocoap_link_format: add helper function to parse Link Format r=benpicco a=benpicco Co-authored-by: Benjamin Valentin <benpicco@beuth-hochschule.de> Co-authored-by: Benjamin Valentin <benjamin.valentin@ml-pa.com>
- Loading branch information
Showing
5 changed files
with
203 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
* Copyright (C) 2022 ML!PA Consulting GmbH | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @ingroup net_nanosock | ||
* @brief NanoCoAP Link Format helper functions | ||
* | ||
* @{ | ||
* | ||
* @file | ||
* @brief NanoCoAP Link Format ([RFC 6690](https://www.rfc-editor.org/rfc/rfc6690.html)) | ||
* helper functions | ||
* | ||
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com> | ||
*/ | ||
#ifndef NET_NANOCOAP_LINK_FORMAT_H | ||
#define NET_NANOCOAP_LINK_FORMAT_H | ||
|
||
#include "net/nanocoap_sock.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief Callback function called for each resource on the directory | ||
* | ||
* @param[in] entry Resource entry from the server | ||
* @param[in] ctx Optional function context | ||
* | ||
* @returns 0 on success | ||
* @returns <0 on error | ||
*/ | ||
typedef int (*coap_link_format_handler_t)(char *entry, void *ctx); | ||
|
||
/** | ||
* @brief Downloads the resource behind @p path via blockwise GET | ||
* | ||
* @param[in] sock Connection to the server | ||
* @param[in] path path of the resource | ||
* @param[in] cb Callback to execute for each resource entry | ||
* @param[in] arg Optional callback argument | ||
* | ||
* @returns 0 on success | ||
* @returns <0 on error | ||
*/ | ||
int nanocoap_link_format_get(nanocoap_sock_t *sock, const char *path, | ||
coap_link_format_handler_t cb, void *arg); | ||
|
||
/** | ||
* @brief Downloads the resource behind @p url via blockwise GET | ||
* | ||
* @param[in] url URL to the resource | ||
* @param[in] cb Callback to execute for each resource entry | ||
* @param[in] arg Optional callback argument | ||
* | ||
* @returns 0 on success | ||
* @returns <0 on error | ||
*/ | ||
int nanocoap_link_format_get_url(const char *url, | ||
coap_link_format_handler_t cb, void *arg); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif /* NET_NANOCOAP_LINK_FORMAT_H */ | ||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
* Copyright (C) 2022 ML!PA Consulting GmbH | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @ingroup net_nanocoap | ||
* @{ | ||
* | ||
* @file | ||
* @brief NanoCoAP Link Format parser | ||
* | ||
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com> | ||
* | ||
* @} | ||
*/ | ||
|
||
#include "fmt.h" | ||
#include "net/nanocoap/link_format.h" | ||
#include "net/nanocoap_sock.h" | ||
#include "net/sock/util.h" | ||
|
||
struct dir_list_ctx { | ||
char *buf; | ||
char *cur; | ||
char *end; | ||
coap_link_format_handler_t cb; | ||
void *ctx; | ||
char esc_buf[2]; | ||
uint8_t esc_idx; | ||
}; | ||
|
||
static int _dirlist_cb(void *arg, size_t offset, uint8_t *buf, size_t len, int more) | ||
{ | ||
(void)offset; | ||
|
||
struct dir_list_ctx *ctx = arg; | ||
|
||
char *end = (char *)buf + len; | ||
for (char *c = (char *)buf; c != end; ++c) { | ||
|
||
/* start of escape sequence */ | ||
if (*c == '%') { | ||
ctx->esc_idx = 1; | ||
continue; | ||
} | ||
if (ctx->esc_idx) { | ||
/* fill escape buffer */ | ||
ctx->esc_buf[ctx->esc_idx - 1] = *c; | ||
if (++ctx->esc_idx == 3) { | ||
ctx->esc_idx = 0; | ||
*c = scn_u32_hex(ctx->esc_buf, 2); | ||
} else { | ||
continue; | ||
} | ||
} | ||
|
||
if (*c == ',' || ctx->cur == ctx->end) { | ||
int res; | ||
*ctx->cur = 0; | ||
res = ctx->cb(ctx->buf, ctx->ctx); | ||
ctx->cur = ctx->buf; | ||
if (res < 0) { | ||
return res; | ||
} | ||
} else { | ||
*ctx->cur++ = *c; | ||
} | ||
} | ||
|
||
if (!more) { | ||
*ctx->cur = 0; | ||
return ctx->cb(ctx->buf, ctx->ctx); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int nanocoap_link_format_get(nanocoap_sock_t *sock, const char *path, | ||
coap_link_format_handler_t cb, void *arg) | ||
{ | ||
char buffer[CONFIG_NANOCOAP_QS_MAX]; | ||
struct dir_list_ctx ctx = { | ||
.buf = buffer, | ||
.end = buffer + sizeof(buffer), | ||
.cur = buffer, | ||
.cb = cb, | ||
.ctx = arg, | ||
}; | ||
return nanocoap_sock_get_blockwise(sock, path, CONFIG_NANOCOAP_BLOCKSIZE_DEFAULT, | ||
_dirlist_cb, &ctx); | ||
} | ||
|
||
int nanocoap_link_format_get_url(const char *url, coap_link_format_handler_t cb, void *arg) | ||
{ | ||
nanocoap_sock_t sock; | ||
int res = nanocoap_sock_url_connect(url, &sock); | ||
if (res) { | ||
return res; | ||
} | ||
|
||
res = nanocoap_link_format_get(&sock, sock_urlpath(url), cb, arg); | ||
nanocoap_sock_close(&sock); | ||
|
||
return res; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters