Files
libcoap/include/coap2/subscribe.h
T
Jon Shallow 7a4d2db8f3 Fix RST deleting observer for non-confirmable observe
Code works as expected for confirmable observes as the sent pdu is
retained for potential re-transmission.

For non-confirmable observes, the RST is seen in the response packet but
previously had no way of finding the observe/subscription to cancel.

Keep the last sent message id in coap_subscription_t (as tid) and when the
RST comes in, search for the subscription that has the same message id as
the pdu and remove that subscription.

include/coap2/subscribe.h:

Add in tid to coap_subscription_t (as per coap_pdu_t).

src/net.c:

Match tid in incoming RST pdu with a subscription.  If found, delete the
subscription.

src/resource.c:

Save tid in both pdu and subscription when sending off an observe response.

To test code, make the following temporary change to coap-client

diff --git a/examples/client.c b/examples/client.c
index 4d3e4c7..0020b68 100644
--- a/examples/client.c
+++ b/examples/client.c
@@ -348,7 +348,8 @@ message_handler(struct coap_context_t *ctx,
 #endif

   /* check if this is a response to our original request */
-  if (!check_token(received)) {
+static int count = 0;
+  if (!check_token(received) || ++count == 5) {
     /* drop if this was just some message, or send RST in case of notification */
     if (!sent && (received->type == COAP_MESSAGE_CON ||
                   received->type == COAP_MESSAGE_NON))

and run (coap-server running on the same host)

coap-client -N -s 10 coap://127.0.0.1/time
2019-04-25 08:45:19 +01:00

78 lines
2.4 KiB
C

/*
* subscribe.h -- subscription handling for CoAP
* see RFC7641
*
* Copyright (C) 2010-2012,2014-2015 Olaf Bergmann <bergmann@tzi.org>
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/
#ifndef COAP_SUBSCRIBE_H_
#define COAP_SUBSCRIBE_H_
#include "address.h"
#include "coap_io.h"
#include "block.h"
/**
* @defgroup observe Resource observation
* API functions for interfacing with the observe handling (RFC7641)
* @{
*/
/**
* The value COAP_OBSERVE_ESTABLISH in a GET request indicates a new observe
* relationship for (sender address, token) is requested.
*/
#define COAP_OBSERVE_ESTABLISH 0
/**
* The value COAP_OBSERVE_CANCEL in a GET request indicates that the observe
* relationship for (sender address, token) must be cancelled.
*/
#define COAP_OBSERVE_CANCEL 1
#ifndef COAP_OBS_MAX_NON
/**
* Number of notifications that may be sent non-confirmable before a confirmable
* message is sent to detect if observers are alive. The maximum allowed value
* here is @c 15.
*/
#define COAP_OBS_MAX_NON 5
#endif /* COAP_OBS_MAX_NON */
#ifndef COAP_OBS_MAX_FAIL
/**
* Number of confirmable notifications that may fail (i.e. time out without
* being ACKed) before an observer is removed. The maximum value for
* COAP_OBS_MAX_FAIL is @c 3.
*/
#define COAP_OBS_MAX_FAIL 3
#endif /* COAP_OBS_MAX_FAIL */
/** Subscriber information */
typedef struct coap_subscription_t {
struct coap_subscription_t *next; /**< next element in linked list */
coap_session_t *session; /**< subscriber session */
unsigned int non_cnt:4; /**< up to 15 non-confirmable notifies allowed */
unsigned int fail_cnt:2; /**< up to 3 confirmable notifies can fail */
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 */
uint16_t tid; /**< transaction id, if any, in regular host byte order */
coap_block_t block2; /**< GET request Block2 definition */
size_t token_length; /**< actual length of token */
unsigned char token[8]; /**< token used for subscription */
coap_string_t *query; /**< query string used for subscription, if any */
} coap_subscription_t;
void coap_subscription_init(coap_subscription_t *);
/** @} */
#endif /* COAP_SUBSCRIBE_H_ */