Added logic to notify all observers when a resource has been deleted by
authorJoseph Morrow <joseph.l.morrow@intel.com>
Mon, 13 Oct 2014 18:40:52 +0000 (14:40 -0400)
committerJoseph Morrow <joseph.l.morrow@intel.com>
Mon, 13 Oct 2014 18:40:52 +0000 (14:40 -0400)
OCDeleteResource API or when OCStop() is called. This will effectively tell
all observers that "this" resource is no longer available. This information
can be used by a client to infer that the server is going down.

If any more changes are req'q to encompass the new "Client able to delete
a resource" user story, a new changeset will be generated.

To come: A changeset containing a set (server and client) of examples
using this functionality.

Patch 2: Thuyen rebased on top of mine and for some reason needed to change
the author of my changeset, but doesn't appear to have made any changes to
my changeset other than rebasing it onto master.

Patch 3: Rebased on to newest master and made changes req' by Sachin and
Sudarshan in Patch 1 comments.

Change-Id: I343a5589c2988c45da95ba6d15685c21fa4704b6

csdk/libcoap-4.1.1/pdu.h
csdk/occoap/include/occoap.h
csdk/occoap/src/occoap.c
csdk/occoap/src/occoaphelper.c
csdk/stack/include/ocstack.h
csdk/stack/src/ocobserve.c
csdk/stack/src/ocstack.c

index b89654f..2c8ac2f 100644 (file)
@@ -140,6 +140,7 @@ const char *coap_response_phrase(unsigned char code);
 #endif
 #define COAP_RESPONSE_200      COAP_RESPONSE_CODE(200)  /* 2.00 OK */
 #define COAP_RESPONSE_201      COAP_RESPONSE_CODE(201)  /* 2.01 Created */
+#define COAP_RESPONSE_202      COAP_RESPONSE_CODE(202)  /* 2.02 Created */
 #define COAP_RESPONSE_304      COAP_RESPONSE_CODE(203)  /* 2.03 Valid */
 #define COAP_RESPONSE_400      COAP_RESPONSE_CODE(400)  /* 4.00 Bad Request */
 #define COAP_RESPONSE_404      COAP_RESPONSE_CODE(404)  /* 4.04 Not Found */
index e0059f1..2c82581 100644 (file)
@@ -98,8 +98,8 @@ void OCGenerateCoAPToken(OCCoAPToken * token);
  *
  * @return 0 - success, else - TBD error
  */
-OCStackResult OCSendCoAPNotification (unsigned char * uri, OCDevAddr *dstAddr, OCStackResult result,
+OCStackResult OCSendCoAPNotification (unsigned char * uri, OCDevAddr *dstAddr,
         OCQualityOfService qos, OCCoAPToken * token,
-        unsigned char *payload, uint32_t seqNum, uint32_t maxAge);
+        unsigned char *payload, OCResource *resPtr, uint32_t maxAge);
 
 #endif /* OCCOAP_H_ */
index 16d3c61..ae1b39e 100644 (file)
@@ -669,10 +669,11 @@ exit:
     return ret;
 }
 
-OCStackResult OCSendCoAPNotification (unsigned char * uri, OCDevAddr *dstAddr, OCStackResult result,
+OCStackResult OCSendCoAPNotification (unsigned char * uri, OCDevAddr *dstAddr,
                        OCQualityOfService qos, OCCoAPToken * token,
-                       unsigned char *payload, uint32_t seqNum, uint32_t maxAge)
+                       unsigned char *payload, OCResource *resPtr, uint32_t maxAge)
 {
+    OCStackResult result = OC_STACK_ERROR;
     coap_list_t *optList = NULL;
     uint8_t coapMsgType = COAP_MESSAGE_NON;
     uint8_t mediaType = COAP_MEDIATYPE_APPLICATION_JSON;
@@ -695,13 +696,18 @@ OCStackResult OCSendCoAPNotification (unsigned char * uri, OCDevAddr *dstAddr, O
     else
     {
     #endif
-        result = FormOptionList(&optList, &mediaType, &maxAge, sizeof(seqNum),
-                &seqNum, NULL, strlen((char *)uri), uri, 0, NULL, NULL, 0);
+        result = FormOptionList(&optList, &mediaType, &maxAge, sizeof(resPtr->sequenceNum),
+                &resPtr->sequenceNum, NULL, strlen((char *)uri), uri, 0, NULL, NULL, 0);
     #ifdef WITH_PRESENCE
     }
     #endif
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
+    if(resPtr->resourceProperties == 0)
+    {
+        result = OC_STACK_RESOURCE_DELETED;
+    }
+
     sendPdu = GenerateCoAPPdu(
             coapMsgType == COAP_MESSAGE_CON ? COAP_MESSAGE_CON : COAP_MESSAGE_NON,
                     OCToCoAPResponseCode(result), coap_new_message_id(gCoAPCtx),
index b35b1a8..19fe9d7 100644 (file)
@@ -57,6 +57,10 @@ uint8_t OCToCoAPResponseCode(OCStackResult result)
             ret = COAP_RESPONSE_200;
             break;
 
+        case OC_STACK_RESOURCE_DELETED:
+            ret = COAP_RESPONSE_202;
+            break;
+
         case OC_STACK_INVALID_QUERY :
             ret = COAP_RESPONSE_400;
             break;
@@ -87,6 +91,10 @@ OCStackResult CoAPToOCResponseCode(uint8_t coapCode)
             ret = OC_STACK_OK;
             break;
 
+        case COAP_RESPONSE_202 :
+            ret = OC_STACK_RESOURCE_DELETED;
+            break;
+
         case COAP_RESPONSE_400 :
             ret = OC_STACK_INVALID_QUERY;
             break;
index 26bebdb..8f9ce69 100644 (file)
@@ -103,12 +103,21 @@ typedef enum {
 
 /**
  * Resource Properties
+ *
+ * OC_ACTIVE       - When this bit is set, the resource is initialized, otherwise the resource
+ *                   is 'inactive'. 'inactive' signifies that the resource has been marked for
+ *                   deletion or is already deleted.
+ * OC_DISCOVERABLE - When this bit is set, the resource is allowed to be discovered by clients.
+ * OC_OBSERVABLE   - When this bit is set, the resource is allowed to be observed by clients.
+ * OC_SLOW         - When this bit is set, the resource has been marked as 'slow'. 'slow' signifies
+ *                   that responses from this resource can expect delays in processing its
+ *                   requests from clients.
  */
 typedef enum {
-    OC_ACTIVE       = (1 << 0),  // set == initialized; unset == deleted
-    OC_DISCOVERABLE = (1 << 1),  // Discovery of this resource allowed
-    OC_OBSERVABLE   = (1 << 2),  // Observe allowed
-    OC_SLOW         = (1 << 3)   // Expect delay in processing requests. Send ACK to request and send response later
+    OC_ACTIVE       = (1 << 0),
+    OC_DISCOVERABLE = (1 << 1),
+    OC_OBSERVABLE   = (1 << 2),
+    OC_SLOW         = (1 << 3)
 } OCResourceProperty;
 
 /**
@@ -142,6 +151,7 @@ typedef enum {
     OC_STACK_OBSERVER_NOT_FOUND,
     OC_STACK_OBSERVER_NOT_ADDED,
     OC_STACK_OBSERVER_NOT_REMOVED,
+    OC_STACK_RESOURCE_DELETED,
     #ifdef WITH_PRESENCE
     OC_STACK_PRESENCE_STOPPED,
     OC_STACK_PRESENCE_DO_NOT_HANDLE,
index 7d63a24..71e42e5 100644 (file)
@@ -309,10 +309,8 @@ OCStackResult SendObserverNotification (OCMethod method, OCResource *resPtr, uin
                         resourceObserver->NONCount++;
                     }
                 }
-                OCSendCoAPNotification(resourceObserver->resUri, resourceObserver->addr,
-                        stackRet, qos,
-                        &(resourceObserver->token),
-                        jsonPayload, resPtr->sequenceNum, maxAge);
+                stackRet = OCSendCoAPNotification(resourceObserver->resUri, resourceObserver->addr,
+                        qos, &(resourceObserver->token), jsonPayload, resPtr, maxAge);
             }
             else
             {
index b74f61c..97f4149 100644 (file)
@@ -106,7 +106,8 @@ void HandleStackResponses(OCResponse * response)
         result = response->cbNode->callBack(response->cbNode->context,
                 response->cbNode->handle, response->clientResponse);
         if (result == OC_STACK_DELETE_TRANSACTION ||
-                response->clientResponse->result == OC_STACK_COMM_ERROR)
+                response->clientResponse->result == OC_STACK_COMM_ERROR ||
+                response->clientResponse->result == OC_STACK_RESOURCE_DELETED)
         {
             FindAndDeleteClientCB(response->cbNode);
         }
@@ -1559,9 +1560,8 @@ OCNotifyListOfObservers (OCResourceHandle handle,
                     }
                 }
                 OCSendCoAPNotification (observation->resUri, observation->addr,
-                                        OC_STACK_OK, qos,
-                                        &(observation->token),
-                                        bufNotify, resPtr->sequenceNum, maxAge);
+                                        qos, &(observation->token),
+                                        bufNotify, resPtr, maxAge);
                 numSentNotification++;
             }
         }
@@ -1722,6 +1722,10 @@ int deleteResource(OCResource *resource) {
             } else {
                 prev->next = temp->next;
             }
+
+            resource->resourceProperties = (OCResourceProperty) 0; // Invalidate all Resource Properties.
+            OCNotifyAllObservers((OCResourceHandle)resource);
+
             deleteResourceElements(temp);
             OCFree(temp);
             return 1;