Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions examples/gcoap/gcoap_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "net/utils.h"
#include "od.h"
#include "fmt.h"
#include "net/sock/util.h"

#define ENABLE_DEBUG 0
#include "debug.h"
Expand Down Expand Up @@ -59,8 +60,7 @@ static char proxy_uri[64];

static ssize_t _encode_link(const coap_resource_t *resource, char *buf,
size_t maxlen, coap_link_encoder_ctx_t *context);
static void _resp_handler(const gcoap_request_memo_t *memo, coap_pkt_t* pdu,
const sock_udp_ep_t *remote);
static void _resp_handler(const gcoap_request_memo_t *memo, coap_pkt_t* pdu);
static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx);
static ssize_t _riot_board_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx);

Expand Down Expand Up @@ -113,10 +113,18 @@ static ssize_t _encode_link(const coap_resource_t *resource, char *buf,
/*
* Response callback.
*/
static void _resp_handler(const gcoap_request_memo_t *memo, coap_pkt_t* pdu,
const sock_udp_ep_t *remote)
static void _resp_handler(const gcoap_request_memo_t *memo, coap_pkt_t* pdu)
{
(void)remote; /* not interested in the source currently */
if (IS_ACTIVE(ENABLE_DEBUG)) {
char saddr[IPV6_ADDR_MAX_STR_LEN + 6];
uint16_t port;
sock_udp_ep_fmt(pdu->remote, saddr, &port);
printf("remote [%s]:%u\n", saddr, port);
if (pdu->local) {
sock_udp_ep_fmt(pdu->local, saddr, &port);
printf("local [%s]:%u\n", saddr, port);
}
}

if (memo->state == GCOAP_MEMO_TIMEOUT) {
printf("gcoap: timeout for msg ID %02u\n", coap_get_id(pdu));
Expand Down Expand Up @@ -185,7 +193,7 @@ static void _resp_handler(const gcoap_request_memo_t *memo, coap_pkt_t* pdu,
}

int len = coap_opt_finish(pdu, COAP_OPT_FINISH_NONE);
gcoap_req_send((uint8_t *)pdu->hdr, len, remote,
gcoap_req_send((uint8_t *)pdu->hdr, len, pdu->remote,
_resp_handler, memo->context);
}
else {
Expand All @@ -206,6 +214,17 @@ static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *c
{
(void)ctx;

if (IS_ACTIVE(ENABLE_DEBUG)) {
char saddr[IPV6_ADDR_MAX_STR_LEN + 6];
uint16_t port;
sock_udp_ep_fmt(pdu->remote, saddr, &port);
printf("remote [%s]:%u\n", saddr, port);
if (pdu->local) {
sock_udp_ep_fmt(pdu->local, saddr, &port);
printf("local [%s]:%u\n", saddr, port);
}
}

/* read coap method type in packet */
unsigned method_flag = coap_method2flag(coap_get_code_detail(pdu));

Expand Down Expand Up @@ -239,6 +258,18 @@ static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *c
static ssize_t _riot_board_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx)
{
(void)ctx;

if (IS_ACTIVE(ENABLE_DEBUG)) {
char saddr[IPV6_ADDR_MAX_STR_LEN + 6];
uint16_t port;
sock_udp_ep_fmt(pdu->remote, saddr, &port);
printf("remote [%s]:%u\n", saddr, port);
if (pdu->local) {
sock_udp_ep_fmt(pdu->local, saddr, &port);
printf("local [%s]:%u\n", saddr, port);
}
}

gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT);
coap_opt_add_format(pdu, COAP_FORMAT_TEXT);
size_t resp_len = coap_opt_finish(pdu, COAP_OPT_FINISH_PAYLOAD);
Expand Down
3 changes: 1 addition & 2 deletions sys/include/net/gcoap.h
Original file line number Diff line number Diff line change
Expand Up @@ -737,8 +737,7 @@ typedef struct gcoap_request_memo gcoap_request_memo_t;
* If request timed out, the packet header is for the request.
*/
typedef void (*gcoap_resp_handler_t)(const gcoap_request_memo_t *memo,
coap_pkt_t* pdu,
const sock_udp_ep_t *remote);
coap_pkt_t* pdu);

/**
* @brief Extends request memo for resending a confirmable request.
Expand Down
9 changes: 9 additions & 0 deletions sys/include/net/nanocoap.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ typedef struct {
uint16_t offset; /**< offset in packet */
} coap_optpos_t;

/**
* @brief This is a workaround until RIOT
* gets an abstraction of CoAP endpoints
* to support CoAP not only over UDP
*/
typedef void coap_ep_t;

/**
* @brief CoAP PDU parsing context structure
*/
Expand All @@ -192,6 +199,8 @@ typedef struct {
#ifdef MODULE_GCOAP
uint32_t observe_value; /**< observe value */
#endif
const coap_ep_t *remote; /**< remote endpoint */
const coap_ep_t *local; /**< local endpoint, NULL if unknown */
} coap_pkt_t;

/**
Expand Down
73 changes: 73 additions & 0 deletions sys/include/net/sock/udp.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,79 @@ typedef struct {
sock_aux_flags_t flags; /**< Flags used request information */
} sock_udp_aux_tx_t;


/**
* @brief Access local UDP endpoint information
*
* @param[in] aux_rx Received UDP auxiliary data
*
* @return Pointer to local UDP endpoint information
* @return NULL if no information is available
*/
static inline sock_udp_ep_t *sock_udp_aux_rx_local(sock_udp_aux_rx_t *aux_rx)
{
#if defined(MODULE_SOCK_AUX_LOCAL)
return &aux_rx->local;
#else
(void)aux_rx;
return NULL;
#endif
}

/**
* @brief Access auxiliary timestamp of a received datagram
*
* @param[in] aux_rx Received UDP auxiliary data
*
* @return Pointer to auxiliary timestamp
* @return NULL if no information is available
*/
static inline uint64_t *sock_udp_aux_rx_timestamp(sock_udp_aux_rx_t *aux_rx)
{
#if defined(MODULE_SOCK_AUX_TIMESTAMP)
return &aux_rx->timestamp;
#else
(void)aux_rx;
return NULL;
#endif
}

/**
* @brief Access auxiliary RSSI of a received datagram
*
* @param[in] aux_rx Received UDP auxiliary data
*
* @return Pointer to auxiliary RSSI value
* @return NULL if no information is available
*/
static inline int16_t *sock_udp_aux_rx_rss(sock_udp_aux_rx_t *aux_rx)
{
#if defined(MODULE_SOCK_AUX_RSSI)
return &aux_rx->rssi;
#else
(void)aux_rx;
return NULL;
#endif
}

/**
* @brief Access auxiliary timestamp of a transmitted datagram
*
* @param[in] aux_tx Auxiliary data of transmitted UDP datagram
*
* @return Pointer to auxiliary timestamp
* @return NULL if no information is available
*/
static inline uint64_t *sock_udp_aux_tx_timestamp(sock_udp_aux_tx_t *aux_tx)
{
#if defined(MODULE_SOCK_AUX_TIMESTAMP)
return &aux_tx->timestamp;
#else
(void)aux_tx;
return NULL;
#endif
}

/**
* @brief Creates a new UDP sock object
*
Expand Down
13 changes: 4 additions & 9 deletions sys/net/application_layer/cord/ep/cord_ep.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ static int _sync(void)
}
}

static void _on_register(const gcoap_request_memo_t *memo, coap_pkt_t* pdu,
const sock_udp_ep_t *remote)
static void _on_register(const gcoap_request_memo_t *memo, coap_pkt_t* pdu)
{
thread_flags_t flag = FLAG_ERR;

Expand All @@ -91,7 +90,7 @@ static void _on_register(const gcoap_request_memo_t *memo, coap_pkt_t* pdu,
/* read the location header and save the RD details on success */
if (coap_get_location_path(pdu, (uint8_t *)_rd_loc,
sizeof(_rd_loc)) > 0) {
memcpy(&_rd_remote, remote, sizeof(_rd_remote));
memcpy(&_rd_remote, pdu->remote, sizeof(_rd_remote));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it makes sense to have a dedicated function for this. This function could assert() that the endpoint indeed of a UDP flavor, once multiple protocols are supported.

flag = FLAG_SUCCESS;
}
else {
Expand Down Expand Up @@ -120,17 +119,13 @@ static void _on_update_remove(unsigned req_state, coap_pkt_t *pdu, uint8_t code)
thread_flags_set(_waiter, flag);
}

static void _on_update(const gcoap_request_memo_t *memo, coap_pkt_t *pdu,
const sock_udp_ep_t *remote)
static void _on_update(const gcoap_request_memo_t *memo, coap_pkt_t *pdu)
{
(void)remote;
_on_update_remove(memo->state, pdu, COAP_CODE_CHANGED);
}

static void _on_remove(const gcoap_request_memo_t *memo, coap_pkt_t *pdu,
const sock_udp_ep_t *remote)
static void _on_remove(const gcoap_request_memo_t *memo, coap_pkt_t *pdu)
{
(void)remote;
_on_update_remove(memo->state, pdu, COAP_CODE_DELETED);
}

Expand Down
36 changes: 20 additions & 16 deletions sys/net/application_layer/gcoap/gcoap.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
static void *_event_loop(void *arg);
static void _on_sock_udp_evt(sock_udp_t *sock, sock_async_flags_t type, void *arg);
static void _process_coap_pdu(gcoap_socket_t *sock, sock_udp_ep_t *remote,
uint8_t *buf, size_t len);
sock_udp_ep_t *local, uint8_t *buf, size_t len);
static void _tl_init_coap_socket(gcoap_socket_t *sock);
static ssize_t _tl_send(gcoap_socket_t *sock, const void *data, size_t len,
const sock_udp_ep_t *remote);
Expand Down Expand Up @@ -249,15 +249,17 @@ static void _on_sock_dtls_evt(sock_dtls_t *sock, sock_async_flags_t type, void *
}

if (type & SOCK_ASYNC_MSG_RECV) {
ssize_t res = sock_dtls_recv(sock, &socket.ctx_dtls_session, _listen_buf,
sizeof(_listen_buf), 0);
sock_udp_aux_rx_t aux = { .flags = SOCK_AUX_GET_LOCAL };
ssize_t res = sock_dtls_recv_aux(sock, &socket.ctx_dtls_session, _listen_buf,
sizeof(_listen_buf), 0, &aux);
if (res <= 0) {
DEBUG("gcoap: DTLS recv failure: %d\n", (int)res);
return;
}
sock_udp_ep_t ep;
sock_udp_ep_t *local = sock_udp_aux_rx_local(&aux);
sock_dtls_session_get_udp_ep(&socket.ctx_dtls_session, &ep);
_process_coap_pdu(&socket, &ep, _listen_buf, res);
_process_coap_pdu(&socket, &ep, local, _listen_buf, res);
}
}

Expand All @@ -284,22 +286,25 @@ static void _on_sock_udp_evt(sock_udp_t *sock, sock_async_flags_t type, void *ar
sock_udp_ep_t remote;

if (type & SOCK_ASYNC_MSG_RECV) {
ssize_t res = sock_udp_recv(sock, _listen_buf, sizeof(_listen_buf),
0, &remote);
sock_udp_aux_rx_t aux = { .flags = SOCK_AUX_GET_LOCAL };
ssize_t res = sock_udp_recv_aux(sock, _listen_buf, sizeof(_listen_buf),
0, &remote, &aux);
if (res <= 0) {
DEBUG("gcoap: udp recv failure: %d\n", (int)res);
return;
}
gcoap_socket_t socket = { .type = GCOAP_SOCKET_TYPE_UDP, .socket.udp = sock };
_process_coap_pdu(&socket, &remote, _listen_buf, res);
sock_udp_ep_t *local = sock_udp_aux_rx_local(&aux);
_process_coap_pdu(&socket, &remote, local, _listen_buf, res);
}
}

/* Processes and evaluates the coap pdu */
static void _process_coap_pdu(gcoap_socket_t *sock, sock_udp_ep_t *remote,
static void _process_coap_pdu(gcoap_socket_t *sock,
sock_udp_ep_t *remote, sock_udp_ep_t *local,
uint8_t *buf, size_t len)
{
coap_pkt_t pdu;
coap_pkt_t pdu = { .remote = remote, .local = local };
gcoap_request_memo_t *memo = NULL;
/* Code paths that necessitate a response on the message layer can set a
* response type here (COAP_TYPE_RST or COAP_TYPE_ACK). If set, at the end
Expand Down Expand Up @@ -345,8 +350,7 @@ static void _process_coap_pdu(gcoap_socket_t *sock, sock_udp_ep_t *remote,
size_t pdu_len = _handle_req(&pdu, _listen_buf, sizeof(_listen_buf),
remote);
if (pdu_len > 0) {
ssize_t bytes = _tl_send(sock, _listen_buf, pdu_len,
remote);
ssize_t bytes = _tl_send(sock, _listen_buf, pdu_len, remote);
if (bytes <= 0) {
DEBUG("gcoap: send response failed: %d\n", (int)bytes);
}
Expand Down Expand Up @@ -375,7 +379,7 @@ static void _process_coap_pdu(gcoap_socket_t *sock, sock_udp_ep_t *remote,
}
memo->state = GCOAP_MEMO_RESP;
if (memo->resp_handler) {
memo->resp_handler(memo, &pdu, remote);
memo->resp_handler(memo, &pdu);
}

if (memo->send_limit >= 0) { /* if confirmable */
Expand Down Expand Up @@ -406,8 +410,7 @@ static void _process_coap_pdu(gcoap_socket_t *sock, sock_udp_ep_t *remote,
* */
pdu.hdr->ver_t_tkl &= 0xf0;

ssize_t bytes = _tl_send(sock, buf,
sizeof(coap_hdr_t), remote);
ssize_t bytes = _tl_send(sock, buf, sizeof(coap_hdr_t), remote);
if (bytes <= 0) {
DEBUG("gcoap: empty response failed: %d\n", (int)bytes);
}
Expand Down Expand Up @@ -490,6 +493,7 @@ static void _cease_retransmission(gcoap_request_memo_t *memo) {
static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
sock_udp_ep_t *remote)
{
assert(pdu->remote);
const coap_resource_t *resource = NULL;
gcoap_listener_t *listener = NULL;
sock_udp_ep_t *observer = NULL;
Expand Down Expand Up @@ -750,14 +754,14 @@ static void _expire_request(gcoap_request_memo_t *memo)
memo->state = GCOAP_MEMO_TIMEOUT;
/* Pass response to handler */
if (memo->resp_handler) {
coap_pkt_t req;
coap_pkt_t req = { .remote = &memo->remote_ep, .local = NULL };
if (memo->send_limit == GCOAP_SEND_LIMIT_NON) {
req.hdr = (coap_hdr_t *)&memo->msg.hdr_buf[0]; /* for reference */
}
else {
req.hdr = (coap_hdr_t *)memo->msg.data.pdu_buf;
}
memo->resp_handler(memo, &req, NULL);
memo->resp_handler(memo, &req);
}
if (memo->send_limit != GCOAP_SEND_LIMIT_NON) {
*memo->msg.data.pdu_buf = 0; /* clear resend buffer */
Expand Down