From 385bdb79de66c5d21946034e443c5dd280a20f0a Mon Sep 17 00:00:00 2001 From: Michel Rottleuthner Date: Thu, 9 Nov 2023 18:33:55 +0100 Subject: [PATCH] gcoap: add api to forget a client-side observe request --- sys/include/net/gcoap.h | 27 +++++++++++++++++++++++++ sys/net/application_layer/gcoap/gcoap.c | 17 ++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/sys/include/net/gcoap.h b/sys/include/net/gcoap.h index 96f7229312489..2547bcd82457f 100644 --- a/sys/include/net/gcoap.h +++ b/sys/include/net/gcoap.h @@ -1074,6 +1074,33 @@ int gcoap_obs_init(coap_pkt_t *pdu, uint8_t *buf, size_t len, size_t gcoap_obs_send(const uint8_t *buf, size_t len, const coap_resource_t *resource); +/** + * @brief Forgets (invalidates) an existing observe request. + * + * This invalidates the internal (local) observe request state without actually + * sending a deregistration request to the server. + * This implementation functionally corresponds to the description in RFC 7641, + * Section 3.6 (Cancellation): 'A client that is no longer interested in + * receiving notifications for a resource can simply "forget" the observation.' + * + * To inform the notification sending server explicitly about the disinterest of + * this client, more steps are needed: *After* calling this function, this + * client has to send a GET request for the corresponding resource, with the + * same token of the original GET request and the observe option set to + * COAP_OBS_DEREGISTER. This will instruct the server to immediately stop + * sending further notifications. + * + * @param[in] remote remote endpoint that hosts the observed resource + * @param[in] token token of the original GET request used for registering + * an observe + * @param[in] tokenlen the length of the token in bytes + * + * @return 0 on success + * @return < 0 on error + */ +int gcoap_obs_req_forget(const sock_udp_ep_t *remote, const uint8_t *token, + size_t tokenlen); + /** * @brief Provides important operational statistics * diff --git a/sys/net/application_layer/gcoap/gcoap.c b/sys/net/application_layer/gcoap/gcoap.c index 92cff8e749c91..e6b478d94be7a 100644 --- a/sys/net/application_layer/gcoap/gcoap.c +++ b/sys/net/application_layer/gcoap/gcoap.c @@ -1534,6 +1534,23 @@ int gcoap_req_init_path_buffer(coap_pkt_t *pdu, uint8_t *buf, size_t len, return (res > 0) ? 0 : res; } +int gcoap_obs_req_forget(const sock_udp_ep_t *remote, const uint8_t *token, + size_t tokenlen) { + gcoap_request_memo_t *obs_req_memo; + mutex_lock(&_coap_state.lock); + /* Find existing request memo of the observe */ + obs_req_memo = _find_req_memo_by_token(remote, token, tokenlen); + if (obs_req_memo) { + /* forget the existing observe memo. */ + obs_req_memo->state = GCOAP_MEMO_UNUSED; + mutex_unlock(&_coap_state.lock); + return 0; + } + + mutex_unlock(&_coap_state.lock); + return -ENOENT; +} + ssize_t gcoap_req_send_tl(const uint8_t *buf, size_t len, const sock_udp_ep_t *remote, gcoap_resp_handler_t resp_handler, void *context,