replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / stack / src / occlientcb.c
old mode 100644 (file)
new mode 100755 (executable)
index a60d444..82f46ce
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
-
+#include "iotivity_config.h"
 #include "occlientcb.h"
-#include "utlist.h"
 #include "logger.h"
-#include "ocmalloc.h"
+#include "trace.h"
+#include "oic_malloc.h"
 #include <string.h>
 
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_ARDUINO_TIME_H
+#include "Time.h"
+#endif
+
 #include "cacommon.h"
 #include "cainterface.h"
+#include <coap/coap.h>
 
 /// Module Name
-#define TAG PCF("occlientcb")
+#define TAG "OIC_RI_CLIENTCB"
 
 struct ClientCB *cbList = NULL;
-static OCMulticastNode * mcPresenceNodes = NULL;
 
 OCStackResult
 AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
              CAToken_t token, uint8_t tokenLength,
              OCDoHandle *handle, OCMethod method,
-             char * requestUri, char * resourceTypeName, OCConnectivityType conType)
+             OCDevAddr *devAddr, char * requestUri,
+             char * resourceTypeName, uint32_t ttl)
 {
-    if(!clientCB || !cbData || !handle || !requestUri || tokenLength > CA_MAX_TOKEN_LEN)
+    if (!clientCB || !cbData || !handle || tokenLength > CA_MAX_TOKEN_LEN)
     {
         return OC_STACK_INVALID_PARAM;
     }
 
+    OIC_TRACE_BEGIN(%s:AddClientCB, TAG);
+
     ClientCB *cbNode = NULL;
 
-    #ifdef WITH_PRESENCE
-    if(method == OC_REST_PRESENCE)
+#ifdef WITH_PRESENCE
+    if (method == OC_REST_PRESENCE)
     {   // Retrieve the presence callback structure for this specific requestUri.
         cbNode = GetClientCB(NULL, 0, NULL, requestUri);
     }
-    #endif // WITH_PRESENCE
 
-    if(!cbNode)// If it does not already exist, create new node.
+    if (!cbNode)// If it does not already exist, create new node.
+#endif // WITH_PRESENCE
     {
-        cbNode = (ClientCB*) OCMalloc(sizeof(ClientCB));
-        if(!cbNode)
+        cbNode = (ClientCB*) OICMalloc(sizeof(ClientCB));
+        if (!cbNode)
         {
             *clientCB = NULL;
             goto exit;
         }
         else
         {
+            OIC_LOG(INFO, TAG, "Adding client callback with token");
+            OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
+            OIC_TRACE_BUFFER("OIC_RI_CLIENTCB:AddClientCB:token",
+                             (const uint8_t *) token, tokenLength);
             cbNode->callBack = cbData->cb;
             cbNode->context = cbData->context;
             cbNode->deleteCallback = cbData->cd;
@@ -74,16 +88,33 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
             cbNode->handle = *handle;
             cbNode->method = method;
             cbNode->sequenceNumber = 0;
-            #ifdef WITH_PRESENCE
+#ifdef WITH_PRESENCE
             cbNode->presence = NULL;
             cbNode->filterResourceType = NULL;
-            #endif // WITH_PRESENCE
-            cbNode->requestUri = requestUri;
-            cbNode->conType = conType;
+#endif // WITH_PRESENCE
+
+            if (
+#ifdef WITH_PRESENCE
+                method == OC_REST_PRESENCE ||
+#endif
+                method == OC_REST_OBSERVE  ||
+                method == OC_REST_OBSERVE_ALL)
+            {
+                cbNode->TTL = 0;
+            }
+            else
+            {
+                cbNode->TTL = ttl;
+            }
+            cbNode->requestUri = requestUri;    // I own it now
+            cbNode->devAddr = devAddr;          // I own it now
+            OIC_LOG_V(INFO, TAG, "Added Callback for uri : %s", requestUri);
+            OIC_TRACE_MARK(%s:AddClientCB:uri:%s, TAG, requestUri);
             LL_APPEND(cbList, cbNode);
             *clientCB = cbNode;
         }
     }
+#ifdef WITH_PRESENCE
     else
     {
         // Ensure that the handle the SDK hands back up to the application layer for the
@@ -95,111 +126,162 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
             cbData->cd(cbData->context);
         }
 
-        OCFree(token);
-        OCFree(*handle);
-        OCFree(requestUri);
+        OICFree(token);
+        OICFree(*handle);
+        OICFree(requestUri);
+        OICFree(devAddr);
         *handle = cbNode->handle;
     }
 
-    #ifdef WITH_PRESENCE
-    if(method == OC_REST_PRESENCE && resourceTypeName)
+    if (method == OC_REST_PRESENCE && resourceTypeName)
     {
+        OIC_TRACE_END();
         // Amend the found or created node by adding a new resourceType to it.
         return InsertResourceTypeFilter(cbNode,(char *)resourceTypeName);
+        // I own resourceTypName now.
     }
     else
     {
-        OCFree(resourceTypeName);
+        OICFree(resourceTypeName);
     }
-    #else
-    OCFree(resourceTypeName);
-    #endif
+#else
+    OICFree(resourceTypeName);
+#endif
 
+    OIC_TRACE_END();
     return OC_STACK_OK;
 
-    exit:
-        return OC_STACK_NO_MEMORY;
+exit:
+    OIC_TRACE_END();
+    return OC_STACK_NO_MEMORY;
 }
 
 void DeleteClientCB(ClientCB * cbNode)
 {
-    if(cbNode) {
+    OIC_TRACE_BEGIN(%s:DeleteClientCB, TAG);
+    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);
+        OIC_LOG (INFO, TAG, "Deleting token");
+        OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, cbNode->tokenLength);
+        OIC_TRACE_BUFFER("OIC_RI_CLIENTCB:DeleteClientCB:token",
+                         (const uint8_t *)cbNode->token, cbNode->tokenLength);
         CADestroyToken (cbNode->token);
-        OCFree(cbNode->handle);
-        OCFree(cbNode->requestUri);
-        if(cbNode->deleteCallback)
+        OICFree(cbNode->devAddr);
+        OICFree(cbNode->handle);
+        if (cbNode->requestUri)
+        {
+            OIC_LOG_V (INFO, TAG, "Deleting callback with uri %s", cbNode->requestUri);
+            OIC_TRACE_MARK(%s:DeleteClientCB:uri:%s, TAG, cbNode->requestUri);
+            OICFree(cbNode->requestUri);
+        }
+        if (cbNode->deleteCallback)
         {
             cbNode->deleteCallback(cbNode->context);
         }
 
-        #ifdef WITH_PRESENCE
-        if(cbNode->presence) {
-            OCFree(cbNode->presence->timeOut);
-            OCFree(cbNode->presence);
+#ifdef WITH_PRESENCE
+        if (cbNode->presence)
+        {
+            OICFree(cbNode->presence->timeOut);
+            OICFree(cbNode->presence);
         }
-        if(cbNode->method == OC_REST_PRESENCE)
+        if (cbNode->method == OC_REST_PRESENCE)
         {
             OCResourceType * pointer = cbNode->filterResourceType;
             OCResourceType * next = NULL;
             while(pointer)
             {
                 next = pointer->next;
-                OCFree(pointer->resourcetypename);
-                OCFree(pointer);
+                OICFree(pointer->resourcetypename);
+                OICFree(pointer);
                 pointer = next;
             }
         }
-        #endif // WITH_PRESENCE
-        OCFree(cbNode);
+#endif // WITH_PRESENCE
+        OICFree(cbNode);
         cbNode = NULL;
     }
+    OIC_TRACE_END();
 }
 
-ClientCB* GetClientCB(const CAToken_t token, uint8_t tokenLength,
-        OCDoHandle handle, const char * requestUri)
+/*
+ * 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)
+    {
+        OIC_LOG(INFO, TAG, "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 && tokenLength <= CA_MAX_TOKEN_LEN && tokenLength > 0)
     {
+        OIC_LOG (INFO, TAG,  "Looking for token");
+        OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
         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)
+            /* de-annotate below line if want to see all token in cbList */
+            //OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength);
+            if (memcmp(out->token, token, tokenLength) == 0)
             {
+                OIC_LOG(INFO, TAG, "Found in callback list");
                 return out;
             }
+            CheckAndDeleteTimedOutCB(out);
         }
     }
-    else if(handle)
+    else if (handle)
     {
+        OIC_LOG (INFO, TAG,  "Looking for handle");
         LL_FOREACH(cbList, out)
         {
-            if(out->handle == handle)
+            if (out->handle == handle)
             {
+                OIC_LOG(INFO, TAG, "Found in callback list");
                 return out;
             }
+            CheckAndDeleteTimedOutCB(out);
         }
     }
-    else if(requestUri)
+    else if (requestUri)
     {
+        OIC_LOG_V(INFO, TAG, "Looking for uri %s", requestUri);
         LL_FOREACH(cbList, out)
         {
-            if(out->requestUri && strcmp(out->requestUri, requestUri ) == 0)
+            /* de-annotate below line if want to see all uri in cbList */
+            //OIC_LOG_V(INFO, TAG, "%s", out->requestUri);
+            if (out->requestUri && strcmp(out->requestUri, requestUri ) == 0)
             {
+                OIC_LOG(INFO, TAG, "Found in callback list");
                 return out;
             }
+            CheckAndDeleteTimedOutCB(out);
         }
     }
-    OC_LOG(INFO, TAG, PCF("Callback Not found !!"));
+    OIC_LOG(INFO, TAG, "Callback Not found !!");
     return NULL;
 }
 
@@ -207,11 +289,11 @@ ClientCB* GetClientCB(const CAToken_t token, uint8_t tokenLength,
 OCStackResult InsertResourceTypeFilter(ClientCB * cbNode, char * resourceTypeName)
 {
     OCResourceType * newResourceType = NULL;
-    if(cbNode && resourceTypeName)
+    if (cbNode && resourceTypeName)
     {
         // Form a new resourceType member.
-        newResourceType = (OCResourceType *) OCMalloc(sizeof(OCResourceType));
-        if(!newResourceType)
+        newResourceType = (OCResourceType *) OICMalloc(sizeof(OCResourceType));
+        if (!newResourceType)
         {
             return OC_STACK_NO_MEMORY;
         }
@@ -226,18 +308,21 @@ OCStackResult InsertResourceTypeFilter(ClientCB * cbNode, char * resourceTypeNam
 }
 #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)
+    if (cbNode)
     {
         LL_FOREACH(cbList, tmp)
         {
@@ -249,40 +334,3 @@ void FindAndDeleteClientCB(ClientCB * cbNode) {
         }
     }
 }
-
-OCStackResult AddMCPresenceNode(OCMulticastNode** outnode, char* uri, uint32_t nonce)
-{
-    if(!outnode)
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    OCMulticastNode *node;
-
-    node = (OCMulticastNode*) OCMalloc(sizeof(OCMulticastNode));
-
-    if (node) {
-        node->nonce = nonce;
-        node->uri = uri;
-        LL_APPEND(mcPresenceNodes, node);
-        *outnode = node;
-        return OC_STACK_OK;
-    }
-    *outnode = NULL;
-    return OC_STACK_NO_MEMORY;
-}
-
-OCMulticastNode* GetMCPresenceNode(const char * uri) {
-    OCMulticastNode* out = NULL;
-
-    if(uri) {
-        LL_FOREACH(mcPresenceNodes, out) {
-            if(out->uri && strcmp(out->uri, uri) == 0) {
-                return out;
-            }
-        }
-    }
-    OC_LOG(INFO, TAG, PCF("MulticastNode Not found !!"));
-    return NULL;
-}
-