From 3989ca5dba1e561aff281ee48d1194ace2a323db Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Mon, 13 Apr 2020 15:51:28 +0100 Subject: [PATCH] resource.c: Send out a 4.04 to any observer when deleting resource As per RFC7641: However, in the event that the state of a resource changes in a way that would cause a normal GET request at that time to return a non-2.xx response (for example, when the resource is deleted), the server SHOULD notify the client by sending a notification with an appropriate response code (such as 4.04 Not Found) and subsequently MUST remove the associated entry from the list of observers of the resource. src/resource.c: Send out a 4.04 response to all observers of a resource when deleting it. --- src/resource.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/resource.c b/src/resource.c index 507f4ecf..5eda13dc 100644 --- a/src/resource.c +++ b/src/resource.c @@ -420,6 +420,14 @@ coap_delete_attr(coap_attr_t *attr) { #endif } +typedef enum coap_deleting_resource_t { + COAP_DELETING_RESOURCE, + COAP_NOT_DELETING_RESOURCE +} coap_deleting_resource_t; + +static void coap_notify_observers(coap_context_t *context, coap_resource_t *r, + coap_deleting_resource_t deleting); + static void coap_free_resource(coap_resource_t *resource) { coap_attr_t *attr, *tmp; @@ -427,6 +435,9 @@ coap_free_resource(coap_resource_t *resource) { assert(resource); + coap_resource_notify_observers(resource, NULL); + coap_notify_observers(resource->context, resource, COAP_DELETING_RESOURCE); + /* delete registered attributes */ LL_FOREACH_SAFE(resource->link_attr, attr, tmp) coap_delete_attr(attr); @@ -745,7 +756,8 @@ coap_delete_observers(coap_context_t *context, coap_session_t *session) { } static void -coap_notify_observers(coap_context_t *context, coap_resource_t *r) { +coap_notify_observers(coap_context_t *context, coap_resource_t *r, + coap_deleting_resource_t deleting) { coap_method_handler_t h; coap_subscription_t *obs; coap_binary_t token; @@ -813,8 +825,16 @@ coap_notify_observers(coap_context_t *context, coap_resource_t *r) { } else { response->type = COAP_MESSAGE_CON; } - /* fill with observer-specific data */ - h(context, r, obs->session, NULL, &token, obs->query, response); + switch (deleting) { + case COAP_NOT_DELETING_RESOURCE: + /* fill with observer-specific data */ + h(context, r, obs->session, NULL, &token, obs->query, response); + break; + case COAP_DELETING_RESOURCE: + default: + response->code = COAP_RESPONSE_CODE(404); + break; + } /* TODO: do not send response and remove observer when * COAP_RESPONSE_CLASS(response->hdr->code) > 2 @@ -904,7 +924,7 @@ coap_check_notify(coap_context_t *context) { if (context->observe_pending) { context->observe_pending = 0; RESOURCES_ITER(context->resources, r) { - coap_notify_observers(context, r); + coap_notify_observers(context, r, COAP_NOT_DELETING_RESOURCE); } } }