diff --git a/examples/client.c b/examples/client.c index 95571bd3..b90df987 100644 --- a/examples/client.c +++ b/examples/client.c @@ -966,9 +966,14 @@ set_blocksize(void) { static void cmdline_subscribe(char *arg) { + uint8_t buf[4]; + obs_seconds = atoi(arg); - coap_insert_optlist(&optlist, coap_new_optlist(COAP_OPTION_OBSERVE, - COAP_OBSERVE_ESTABLISH, NULL)); + coap_insert_optlist(&optlist, + coap_new_optlist(COAP_OPTION_OBSERVE, + coap_encode_var_safe(buf, sizeof(buf), + COAP_OBSERVE_ESTABLISH), buf) + ); } static int diff --git a/include/coap2/coap_subscribe_internal.h b/include/coap2/coap_subscribe_internal.h index 3c1ae656..9beb8f95 100644 --- a/include/coap2/coap_subscribe_internal.h +++ b/include/coap2/coap_subscribe_internal.h @@ -50,9 +50,10 @@ struct coap_subscription_t { unsigned int dirty:1; /**< set if the notification temporarily could not be * sent (in that case, the resource's partially * dirty flag is set too) */ - unsigned int has_block2:1; /**< GET request had Block2 definition */ + unsigned int has_block2:1; /**< request had Block2 definition */ + uint8_t code; /** request type code (GET/FETCH)*/ uint16_t tid; /**< transaction id, if any, in regular host byte order */ - coap_block_t block2; /**< GET request Block2 definition */ + coap_block_t block2; /**< request Block2 definition */ size_t token_length; /**< actual length of token */ unsigned char token[8]; /**< token used for subscription */ struct coap_string_t *query; /**< query string used for subscription, if any */ diff --git a/include/coap2/resource.h b/include/coap2/resource.h index b81dbb91..ccceb42c 100644 --- a/include/coap2/resource.h +++ b/include/coap2/resource.h @@ -423,6 +423,8 @@ coap_resource_t *coap_get_resource_from_uri_path(coap_context_t *context, * function returns NULL. * @param has_block2 If Option Block2 defined. * @param block2 Contents of Block2 if Block 2 defined. + * @param code Request type code. + * * @return A pointer to the added/updated subscription * information or @c NULL on error. */ @@ -431,7 +433,8 @@ coap_subscription_t *coap_add_observer(coap_resource_t *resource, const coap_binary_t *token, coap_string_t *query, int has_block2, - coap_block_t block2); + coap_block_t block2, + uint8_t code); /** * Returns a subscription object for given @p peer. diff --git a/man/coap_pdu_setup.txt.in b/man/coap_pdu_setup.txt.in index 15909484..8054190d 100644 --- a/man/coap_pdu_setup.txt.in +++ b/man/coap_pdu_setup.txt.in @@ -348,7 +348,9 @@ unsigned char *data, size_t length, int observe) { /* Indicate that we want to observe this resource */ if (!coap_insert_optlist(&optlist_chain, coap_new_optlist(COAP_OPTION_OBSERVE, - COAP_OBSERVE_ESTABLISH, NULL))) + coap_encode_var_safe(buf, sizeof(buf), + COAP_OBSERVE_ESTABLISH), buf) + )) goto error; } diff --git a/src/net.c b/src/net.c index 262c7397..20d0226b 100644 --- a/src/net.c +++ b/src/net.c @@ -2458,7 +2458,7 @@ handle_request(coap_context_t *context, coap_session_t *session, coap_pdu_t *pdu if (coap_get_block(pdu, COAP_OPTION_BLOCK2, &block2)) { has_block2 = 1; } - subscription = coap_add_observer(resource, session, &token, query, has_block2, block2); + subscription = coap_add_observer(resource, session, &token, query, has_block2, block2, pdu->code); if (subscription) { /* Ownership of query is taken by subscription if not * NULL. In this case, we must not delete query here diff --git a/src/resource.c b/src/resource.c index 4a5b7a76..5b6a3732 100644 --- a/src/resource.c +++ b/src/resource.c @@ -639,7 +639,8 @@ coap_add_observer(coap_resource_t *resource, const coap_binary_t *token, coap_string_t *query, int has_block2, - coap_block_t block2) { + coap_block_t block2, + uint8_t code) { coap_subscription_t *s; assert( session ); @@ -666,11 +667,11 @@ coap_add_observer(coap_resource_t *resource, if (s->query) coap_delete_string(s->query); s->query = query; + s->code = code; return s; } - /* s points to a different subscription, so we have to create - * another one. */ + /* Create a new subscription */ s = COAP_MALLOC_TYPE(subscription); if (!s) { @@ -693,6 +694,8 @@ coap_add_observer(coap_resource_t *resource, s->has_block2 = has_block2; s->block2 = block2; + s->code = code; + /* add subscriber to resource */ LL_PREPEND(resource->subscribers, s); @@ -767,11 +770,6 @@ coap_notify_observers(coap_context_t *context, coap_resource_t *r, if (r->observable && (r->dirty || r->partiallydirty)) { r->partiallydirty = 0; - /* retrieve GET handler, prepare response */ - h = r->handler[COAP_REQUEST_GET - 1]; - assert(h); /* we do not allow subscriptions if no - * GET handler is defined */ - LL_FOREACH(r->subscribers, obs) { if (r->dirty == 0 && obs->dirty == 0) { /* @@ -829,6 +827,10 @@ coap_notify_observers(coap_context_t *context, coap_resource_t *r, switch (deleting) { case COAP_NOT_DELETING_RESOURCE: /* fill with observer-specific data */ + + h = r->handler[obs->code - 1]; + assert(h); /* we do not allow subscriptions if no + * GET/FETCH handler is defined */ h(context, r, obs->session, NULL, &token, obs->query, response); break; case COAP_DELETING_RESOURCE: