#endif
// The connectivity type on which the request was sent on.
OCConnectivityType conType;
+ // The TTL for this callback. Holds the time till when this callback can
+ // still be used. TTL is set to 0 when the callback is for presence and observe.
+ // Presence has ttl mechanism in the "presence" member of this struct and observes
+ // can be explicitly cancelled.
+ uint32_t TTL;
// next node in this list
struct ClientCB *next;
} ClientCB;
* the resourceType associated with a presence request.
* @param[in] conType
* the connectivity type on which the associated request for this clientCB was sent on.
- *
+ * @param[in] ttl
+ * time to live in coap_ticks for the callback.
* @brief If the handle you're looking for does not exist, the stack will reply with a RST message.
*
* @return OC_STACK_OK for Success, otherwise some error value
AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
CAToken_t token, uint8_t tokenLength,
OCDoHandle *handle, OCMethod method,
- char * requestUri, char * resourceTypeName, OCConnectivityType conType);
+ char * requestUri, char * resourceTypeName, OCConnectivityType conType, uint32_t ttl);
/** @ingroup ocstack
*
#include "ocmalloc.h"
#include <string.h>
+#ifdef WITH_ARDUINO
+#include "Time.h"
+#else
+#include <sys/time.h>
+#endif
+#include "coap_time.h"
+
#include "cacommon.h"
#include "cainterface.h"
AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
CAToken_t token, uint8_t tokenLength,
OCDoHandle *handle, OCMethod method,
- char * requestUri, char * resourceTypeName, OCConnectivityType conType)
+ char * requestUri, char * resourceTypeName, OCConnectivityType conType, uint32_t ttl)
{
if(!clientCB || !cbData || !handle || !requestUri || tokenLength > CA_MAX_TOKEN_LEN)
{
cbNode->presence = NULL;
cbNode->filterResourceType = NULL;
#endif // WITH_PRESENCE
+
+ if (method == OC_REST_PRESENCE ||
+ method == OC_REST_OBSERVE ||
+ method == OC_REST_OBSERVE_ALL)
+ {
+ cbNode->TTL = 0;
+ }
+ else
+ {
+ cbNode->TTL = ttl;
+ }
cbNode->requestUri = requestUri;
cbNode->conType = conType;
LL_APPEND(cbList, cbNode);
void DeleteClientCB(ClientCB * cbNode)
{
- if(cbNode) {
+ if(cbNode)
+ {
LL_DELETE(cbList, cbNode);
OC_LOG(INFO, TAG, PCF("deleting tokens"));
OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, cbNode->tokenLength);
}
#ifdef WITH_PRESENCE
- if(cbNode->presence) {
+ if(cbNode->presence)
+ {
OCFree(cbNode->presence->timeOut);
OCFree(cbNode->presence);
}
}
}
+/*
+ * This function checks if the node is past its time to live and
+ * deletes it if timed-out. Calling this function with a presence or observe
+ * callback with ttl set to 0 will not delete anything as presence nodes have
+ * their own mechanisms for timeouts. A null argument will cause the function to
+ * silently return.
+ */
+static void CheckAndDeleteTimedOutCB(ClientCB* cbNode)
+{
+ if (!cbNode)
+ {
+ return;
+ }
+ if (cbNode->TTL == 0)
+ {
+ return;
+ }
+ coap_tick_t now;
+ coap_ticks(&now);
+
+ if (cbNode->TTL < now)
+ {
+ OC_LOG(INFO, TAG, PCF("Deleting timed-out callback"));
+ DeleteClientCB(cbNode);
+ }
+}
+
ClientCB* GetClientCB(const CAToken_t token, uint8_t tokenLength,
OCDoHandle handle, const char * requestUri)
{
ClientCB* out = NULL;
- if(token && *token &&
- tokenLength <= CA_MAX_TOKEN_LEN && tokenLength > 0)
+ if(token && *token && tokenLength <= CA_MAX_TOKEN_LEN && tokenLength > 0)
{
LL_FOREACH(cbList, out)
{
OC_LOG(INFO, TAG, PCF("comparing tokens"));
OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength);
+
if(memcmp(out->token, token, tokenLength) == 0)
- if(memcmp(out->token, token, CA_MAX_TOKEN_LEN) == 0)
{
return out;
}
+ CheckAndDeleteTimedOutCB(out);
}
}
else if(handle)
{
return out;
}
+ CheckAndDeleteTimedOutCB(out);
}
}
else if(requestUri)
{
return out;
}
+ CheckAndDeleteTimedOutCB(out);
}
}
OC_LOG(INFO, TAG, PCF("Callback Not found !!"));
}
#endif // WITH_PRESENCE
-void DeleteClientCBList() {
+void DeleteClientCBList()
+{
ClientCB* out;
ClientCB* tmp;
- LL_FOREACH_SAFE(cbList, out, tmp) {
+ LL_FOREACH_SAFE(cbList, out, tmp)
+ {
DeleteClientCB(out);
}
cbList = NULL;
}
-void FindAndDeleteClientCB(ClientCB * cbNode) {
+void FindAndDeleteClientCB(ClientCB * cbNode)
+{
ClientCB* tmp;
if(cbNode)
{
node = (OCMulticastNode*) OCMalloc(sizeof(OCMulticastNode));
- if (node) {
+ if (node)
+ {
node->nonce = nonce;
node->uri = uri;
LL_APPEND(mcPresenceNodes, node);
return OC_STACK_NO_MEMORY;
}
-OCMulticastNode* GetMCPresenceNode(const char * uri) {
+OCMulticastNode* GetMCPresenceNode(const char * uri)
+{
OCMulticastNode* out = NULL;
- if(uri) {
- LL_FOREACH(mcPresenceNodes, out) {
- if(out->uri && strcmp(out->uri, uri) == 0) {
+ if(uri)
+ {
+ LL_FOREACH(mcPresenceNodes, out)
+ {
+ if(out->uri && strcmp(out->uri, uri) == 0)
+ {
return out;
}
}
{
FindAndDeleteClientCB(cbNode);
}
+ else
+ {
+ // To keep discovery callbacks active.
+ cbNode->TTL = GetTicks(MAX_CB_TIMEOUT_SECONDS *
+ MILLISECONDS_PER_SECOND);
+ }
}
//Need to send ACK when the response is CON
goto exit;
}
- if((result = AddClientCB(&clientCB, cbData, token, tokenLength, &resHandle, method,
- requestUri, resourceType, conType)) != OC_STACK_OK)
+ result = AddClientCB(&clientCB, cbData, token, tokenLength, &resHandle, method,
+ requestUri, resourceType, conType,
+ GetTicks(MAX_CB_TIMEOUT_SECONDS * MILLISECONDS_PER_SECOND));
+ if(result != OC_STACK_OK)
{
result = OC_STACK_NO_MEMORY;
goto exit;