Client requests to delete a resource.
authorThuyen Tran <thuyen.c.tran@intel.com>
Sat, 11 Oct 2014 03:28:48 +0000 (20:28 -0700)
committerThuyen Tran <thuyen.c.tran@intel.com>
Tue, 14 Oct 2014 20:35:42 +0000 (13:35 -0700)
*Patch 1:
  1. Process request at C apps' level.
  2. Move logic into the C stack instead of app level.
  3. C stack responds to request to a 'to be deleted' resource.
*Patch 2: Added fixes per Sachin's code review.
*Patch 3: Added improvements per Jesse's code review.
***Abandoned changeset #293
***Restarted with changeset #304
*Patch 1: Rebased and changed Makefile per Jesse's feedback.
*Patch 2: Removed 'mark to be deleted' logic per design changes
          and added checks for entity handler result code.
*Patch 3: Fixed build error due to missing newly added coap code.
*Patch 4: Added improvements per Joey's feedbacks.
*Patch 5: Removed extra semicolon in enum to avoid build error.
*Patch 6: Rebased from Joey's changeset #313 and applied my changes on top.
*Patch 7: Rebased of master which has Joey's changeset #313, and added my changes on top.
*Patch 8: Added improvements per comments from Joey and Vijay

Change-Id: Iacec6f56c9f7ce7f61bfda8a47e84368edaf822e

12 files changed:
csdk/libcoap-4.1.1/pdu.h
csdk/occoap/src/occoap.c
csdk/occoap/src/occoaphelper.c
csdk/stack/include/internal/ocresource.h
csdk/stack/include/ocstack.h
csdk/stack/samples/linux/SimpleClientServer/common.cpp
csdk/stack/samples/linux/SimpleClientServer/occlient.cpp
csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp
csdk/stack/src/occollection.c
csdk/stack/src/ocresource.c
csdk/stack/src/ocstack.c
examples/ocicuc/Makefile

index 2c8ac2f..7428e63 100644 (file)
@@ -140,9 +140,10 @@ 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_202      COAP_RESPONSE_CODE(202)  /* 2.02 Deleted */
 #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_403      COAP_RESPONSE_CODE(403)  /* 4.03 Forbidden */
 #define COAP_RESPONSE_404      COAP_RESPONSE_CODE(404)  /* 4.04 Not Found */
 #define COAP_RESPONSE_405      COAP_RESPONSE_CODE(405)  /* 4.05 Method Not Allowed */
 #define COAP_RESPONSE_415      COAP_RESPONSE_CODE(415)  /* 4.15 Unsupported Media Type */
index c449da3..1ecadf6 100644 (file)
@@ -171,6 +171,11 @@ static void HandleCoAPRequests(struct coap_context_t *ctx,
                 ocMethod = OC_REST_POST;
                 break;
             }
+        case COAP_REQUEST_DELETE:
+            {
+                ocMethod = OC_REST_DELETE;
+                break;
+            }
         case COAP_REQUEST_PUT:
             {
                 ocMethod = OC_REST_PUT;
@@ -634,6 +639,9 @@ OCStackResult OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCCoAPTo
         case OC_REST_POST:
             coapMethod = COAP_REQUEST_POST;
             break;
+        case OC_REST_DELETE:
+            coapMethod = COAP_REQUEST_DELETE;
+            break;
         case OC_REST_OBSERVE_ALL:
         case OC_REST_OBSERVE:
         case OC_REST_CANCEL_OBSERVE:
index 3636695..56d265d 100644 (file)
@@ -65,6 +65,10 @@ uint8_t OCToCoAPResponseCode(OCStackResult result)
             ret = COAP_RESPONSE_400;
             break;
 
+        case OC_STACK_RESOURCE_ERROR:
+            return COAP_RESPONSE_403;
+            break;
+
         case OC_STACK_NO_RESOURCE :
             ret = COAP_RESPONSE_404;
             break;
@@ -113,6 +117,10 @@ OCStackResult CoAPToOCResponseCode(uint8_t coapCode)
             ret = OC_STACK_INVALID_QUERY;
             break;
 
+        case COAP_RESPONSE_403 :
+            ret = OC_STACK_RESOURCE_ERROR;
+            break;
+
         case COAP_RESPONSE_404 :
             ret = OC_STACK_NO_RESOURCE;
             break;
index cb368e1..6e538ba 100644 (file)
@@ -78,4 +78,6 @@ OCStackResult
 BuildVirtualResourceResponse(OCResource *resourcePtr, uint8_t filterOn,
                         char *filterValue, char * out, uint16_t *remaining);
 
+OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult);
+
 #endif //OC_RESOURCE_H
index 1fe8f36..625b900 100644 (file)
@@ -298,7 +298,9 @@ typedef struct {
  */
 typedef enum {
     OC_EH_OK = 0,
-    OC_EH_ERROR
+    OC_EH_ERROR,
+    OC_EH_RESOURCE_DELETED,
+    OC_EH_FORBIDDEN
 } OCEntityHandlerResult;
 
 /**
index 69207a6..e40d31e 100644 (file)
@@ -54,6 +54,8 @@ const char *getResult(OCStackResult result) {
         return "OC_STACK_SLOW_RESOURCE";
     case OC_STACK_NO_OBSERVERS:
         return "OC_STACK_NO_OBSERVERS";
+    case OC_STACK_RESOURCE_DELETED:
+        return "OC_STACK_RESOURCE_DELETED";
     #ifdef WITH_PRESENCE
     case OC_STACK_PRESENCE_DO_NOT_HANDLE:
         return "OC_STACK_PRESENCE_DO_NOT_HANDLE";
index 885e78f..009adb6 100644 (file)
@@ -47,10 +47,12 @@ typedef enum {
     TEST_GET_REQ_NON,
     TEST_PUT_REQ_NON,
     TEST_POST_REQ_NON,
+    TEST_DELETE_REQ_NON,
     TEST_OBS_REQ_NON,
     TEST_GET_UNAVAILABLE_RES_REQ_NON,
     TEST_GET_REQ_CON,
     TEST_POST_REQ_CON,
+    TEST_DELETE_REQ_CON,
     TEST_OBS_REQ_CON,
     #ifdef WITH_PRESENCE
     TEST_OBS_PRESENCE,
@@ -99,6 +101,7 @@ int InitObserveRequest(OCQualityOfService qos);
 int InitPutRequest();
 int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptions);
 int InitPostRequest(OCQualityOfService qos);
+int InitDeleteRequest(OCQualityOfService qos);
 int InitGetRequest(OCQualityOfService qos);
 int InitDiscovery();
 void parseClientResponse(OCClientResponse * clientResponse);
@@ -107,20 +110,25 @@ static void PrintUsage()
 {
     OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1|2|3|4|5|6|7>");
     OC_LOG(INFO, TAG, "-u <0|1> : Perform multicast/unicast discovery of resources");
-    OC_LOG(INFO, TAG, "-t 1 : Discover Resources");
-    OC_LOG(INFO, TAG, "-t 2 : Discover Resources and Initiate Nonconfirmable Get Request");
-    OC_LOG(INFO, TAG, "-t 3 : Discover Resources and Initiate Nonconfirmable Put Requests");
-    OC_LOG(INFO, TAG, "-t 4 : Discover Resources and Initiate Nonconfirmable Post Requests");
-    OC_LOG(INFO, TAG, "-t 5 : Discover Resources and Initiate Nonconfirmable Observe Requests");
-    OC_LOG(INFO, TAG, "-t 6 : Discover Resources and Initiate Nonconfirmable Get Request for a resource which is unavailable");
-    OC_LOG(INFO, TAG, "-t 7 : Discover Resources and Initiate Confirmable Get Request");
-    OC_LOG(INFO, TAG, "-t 8 : Discover Resources and Initiate Confirmable Post Request");
-    OC_LOG(INFO, TAG, "-t 9 : Discover Resources and Initiate Confirmable Observe Requests");
+    OC_LOG(INFO, TAG, "-t 1  :  Discover Resources");
+    OC_LOG(INFO, TAG, "-t 2  :  Discover Resources and Initiate Nonconfirmable Get Request");
+    OC_LOG(INFO, TAG, "-t 3  :  Discover Resources and Initiate Nonconfirmable Put Requests");
+    OC_LOG(INFO, TAG, "-t 4  :  Discover Resources and Initiate Nonconfirmable Post Requests");
+    OC_LOG(INFO, TAG, "-t 5  :  Discover Resources and Initiate Nonconfirmable Delete Requests");
+    OC_LOG(INFO, TAG, "-t 6  :  Discover Resources and Initiate Nonconfirmable Observe Requests");
+    OC_LOG(INFO, TAG, "-t 7  :  Discover Resources and Initiate Nonconfirmable Get Request for a resource which is unavailable");
+
+    OC_LOG(INFO, TAG, "-t 8  :  Discover Resources and Initiate Confirmable Get Request");
+    OC_LOG(INFO, TAG, "-t 9  :  Discover Resources and Initiate Confirmable Post Request");
+    OC_LOG(INFO, TAG, "-t 10 :  Discover Resources and Initiate Confirmable Delete Requests");
+    OC_LOG(INFO, TAG, "-t 11 :  Discover Resources and Initiate Confirmable Observe Requests");
+
     #ifdef WITH_PRESENCE
-    OC_LOG(INFO, TAG, "-t 10 : Discover Resources and Initiate Nonconfirmable presence");
+    OC_LOG(INFO, TAG, "-t 12 :  Discover Resources and Initiate Nonconfirmable presence");
     #endif
-    OC_LOG(INFO, TAG, "-t 11 : Discover Resources and Initiate Nonconfirmable Observe Requests then cancel immediately");
-    OC_LOG(INFO, TAG, "-t 12: Discover Resources and Initiate Nonconfirmable Get Request and add  vendor specific header options");
+
+    OC_LOG(INFO, TAG, "-t 13 :  Discover Resources and Initiate Nonconfirmable Observe Requests then cancel immediately");
+    OC_LOG(INFO, TAG, "-t 14 :  Discover Resources and Initiate Nonconfirmable Get Request and add  vendor specific header options");
 }
 
 OCStackResult InvokeOCDoResource(std::ostringstream &query,
@@ -186,6 +194,21 @@ OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle, OCClientRespons
     return OC_STACK_DELETE_TRANSACTION;
 }
 
+OCStackApplicationResult deleteReqCB(void *ctx, OCDoHandle handle, OCClientResponse *clientResponse)
+{
+    if(ctx == (void*)CTX_VAL)
+    {
+        OC_LOG_V(INFO, TAG, "Callback Context for DELETE recvd successfully");
+    }
+
+    if(clientResponse)
+    {
+        OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
+        OC_LOG_V(INFO, TAG, "JSON = %s =============> Delete Response", clientResponse->resJSONPayload);
+    }
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
 OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse) {
     if(ctx == (void*)CTX_VAL)
     {
@@ -231,7 +254,7 @@ OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle handle, OCClientResponse
         OC_LOG_V(INFO, TAG, "Callback Context for OBSERVE notification recvd successfully %d", gNumObserveNotifies);
         OC_LOG_V(INFO, TAG, "JSON = %s =============> Obs Response", clientResponse->resJSONPayload);
         gNumObserveNotifies++;
-        if (gNumObserveNotifies == 5)
+        if (gNumObserveNotifies == 50) //large number to test observing in DELETE case.
         {
             printf ("************************** CANCEL OBSERVE with ");
             if(TEST_CASE == TEST_OBS_REQ_NON || TEST_CASE == TEST_OBS_REQ_CON){
@@ -274,7 +297,7 @@ OCStackApplicationResult presenceCB(void* ctx, OCDoHandle handle, OCClientRespon
         OC_LOG_V(INFO, TAG, "Callback Context for Presence notification recvd successfully %d", gNumPresenceNotifies);
         OC_LOG_V(INFO, TAG, "JSON = %s =============> Presence Response", clientResponse->resJSONPayload);
         gNumPresenceNotifies++;
-        if (gNumPresenceNotifies == 15)
+        if (gNumPresenceNotifies == 20)
         {
             printf ("************************** CANCEL PRESENCE\n");
             if (OCCancel (gPresenceHandle, OC_LOW_QOS, NULL, 0) != OC_STACK_OK){
@@ -323,6 +346,9 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
         case TEST_POST_REQ_NON:
             InitPostRequest(OC_LOW_QOS);
             break;
+        case TEST_DELETE_REQ_NON:
+            InitDeleteRequest(OC_LOW_QOS);
+            break;
         case TEST_OBS_REQ_NON:
         case TEST_OBS_REQ_NON_CANCEL_IMM:
             InitObserveRequest(OC_LOW_QOS);
@@ -336,6 +362,9 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
         case TEST_POST_REQ_CON:
             InitPostRequest(OC_HIGH_QOS);
             break;
+        case TEST_DELETE_REQ_CON:
+            InitDeleteRequest(OC_HIGH_QOS);
+            break;
         case TEST_OBS_REQ_CON:
             InitObserveRequest(OC_HIGH_QOS);
             break;
@@ -421,6 +450,61 @@ int InitPostRequest(OCQualityOfService qos)
                                postReqCB, NULL, 0));
 }
 
+void* RequestDeleteDeathResourceTask(void* myqos)
+{
+    sleep (30);        //long enough to give the server time to finish deleting the resource.
+    std::ostringstream query;
+    query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
+
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+
+    // Second DELETE operation to delete the resource that might have been removed already.
+    OCQualityOfService qos;
+    if (myqos == NULL)
+        qos = OC_LOW_QOS;
+    else
+        qos = OC_HIGH_QOS;
+
+    OCStackResult result = InvokeOCDoResource(query, OC_REST_DELETE,
+                               qos,
+                               deleteReqCB, NULL, 0);
+
+    if (OC_STACK_OK != result)
+    {
+        OC_LOG_V(INFO, TAG, "Second DELETE call did not succeed");
+    }
+
+    return NULL;
+}
+
+int InitDeleteRequest(OCQualityOfService qos)
+{
+    OCStackResult result;
+    std::ostringstream query;
+    query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
+
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+
+    // First DELETE operation
+    result = InvokeOCDoResource(query, OC_REST_DELETE,
+                               qos,
+                               deleteReqCB, NULL, 0);
+    if (OC_STACK_OK != result)
+    {
+        // Error can happen if for example, network connectivity is down
+        OC_LOG_V(INFO, TAG, "First DELETE call did not succeed");
+    }
+    else
+    {
+        //Create a thread to delete this resource again
+        pthread_t threadId;
+        pthread_create (&threadId, NULL, RequestDeleteDeathResourceTask, (void*)qos);
+    }
+
+    OC_LOG_V(INFO, TAG, "\n\nExit  %s", __func__);
+    return result;
+}
+
 int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptions)
 {
     OCHeaderOption options[MAX_HEADER_OPTIONS];
index 17ac1e5..a537de6 100644 (file)
@@ -55,6 +55,7 @@ int createLEDResource (char *uri, LEDResource *ledResource);
 typedef struct {
     OCObservationId observationId;
     bool            valid;
+    OCResourceHandle resourceHandle;
 } Observers;
 #define SAMPLE_MAX_NUM_OBSERVATIONS     8
 Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
@@ -63,6 +64,14 @@ Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
 static int stopPresenceCount = 10;
 #endif
 
+//TODO: Follow the pattern used in constructJsonResponse() when the payload is decided.
+const char responsePayloadDeleteOk[] = "{App determines payload: Delete Resource operation succeeded.}";
+const char responsePayloadDeleteNotOK[] = "{App determines payload: Delete Resource operation failed.}";
+const char responsePayloadResourceDoesNotExist[] = "{App determines payload: The resource does not exist.}";
+const char responsePayloadDeleteResourceNotSupported[] =
+        "{App determines payload: The request is received for a non-support resource.}";
+
+
 char *resourceUri= (char *)"/a/led";
 
 const char jSONResponseSkel[] = "{\"href\": \"\",\"rep\":{\"state\":\"\",\"power\":0}}";
@@ -223,6 +232,101 @@ void ProcessPostRequest (OCEntityHandlerRequest *ehRequest)
     }
 }
 
+OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
+{
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %d ", __func__, ehRequest->resource);
+
+    /*
+     * In the sample below, the application will:
+     * 1a. pass the delete request to the c stack
+     * 1b. internally, the c stack figures out what needs to be done and does it accordingly
+     *    (e.g. send observers notification, remove observers...)
+     * 1c. the c stack returns with the result whether the request is fullfilled.
+     * 2. optionally, app removes observers out of its array 'interestedObservers'
+     */
+
+    const char* deleteResponse = NULL;
+
+    if ((ehRequest != NULL) && (ehRequest->resource == LED.handle))
+    {
+        //Step 1: Ask stack to do the work.
+        OCStackResult result = OCDeleteResource(ehRequest->resource);
+
+        if (result == OC_STACK_OK)
+        {
+            OC_LOG (INFO, TAG, "\n\nDelete Resource operation succeeded.");
+            ehResult = OC_EH_OK;
+            deleteResponse = responsePayloadDeleteOk;
+
+            //Step 2: clear observers who wanted to observe this resource at the app level.
+            for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
+            {
+                if (interestedObservers[i].resourceHandle == ehRequest->resource)
+                {
+                    interestedObservers[i].valid = false;
+                    interestedObservers[i].observationId = 0;
+                    interestedObservers[i].resourceHandle = NULL;
+                }
+            }
+        }
+        else if (result == OC_STACK_NO_RESOURCE)
+        {
+            OC_LOG_V(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
+            deleteResponse = responsePayloadResourceDoesNotExist;
+            ehResult = OC_EH_RESOURCE_DELETED;
+        }
+        else
+        {
+            OC_LOG_V(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
+            deleteResponse = responsePayloadDeleteNotOK;
+            ehResult = OC_EH_ERROR;
+        }
+    }
+    else if (ehRequest->resource != LED.handle)
+    {
+        //Let's this app not supporting DELETE on some resources so
+        //consider the DELETE request is received for a non-support resource.
+        OC_LOG_V(INFO, TAG, "\n\nThe request is received for a non-support resource.");
+        deleteResponse = responsePayloadDeleteResourceNotSupported;
+        ehResult = OC_EH_FORBIDDEN;
+    }
+
+    if (ehRequest->resJSONPayloadLen > strlen ((char *)deleteResponse))
+    {
+        strncpy((char *)ehRequest->resJSONPayload, deleteResponse, strlen((char *)deleteResponse));
+    }
+    else
+    {
+        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
+                  ehRequest->resJSONPayloadLen);
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest)
+{
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
+
+    const char* response = NULL;
+    response = responsePayloadResourceDoesNotExist;
+
+    if ( (ehRequest != NULL) &&
+         (ehRequest->resJSONPayloadLen > strlen ((char *)response)) )
+    {
+        strncpy((char *)ehRequest->resJSONPayload, response, strlen((char *)response));
+    }
+    else
+    {
+        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
+                  ehRequest->resJSONPayloadLen);
+    }
+
+    return OC_EH_RESOURCE_DELETED;
+}
+
 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
 {
     OC_LOG_V (INFO, TAG, "Received observation registration request with observation Id %d",
@@ -260,12 +364,15 @@ void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
     if (clientStillObserving == false)
         gLEDUnderObservation = 0;
 }
-    OCEntityHandlerResult
+
+OCEntityHandlerResult
 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
         OCEntityHandlerRequest *entityHandlerRequest, char* uri)
 {
-
     OC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
+
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+
     if (flag & OC_INIT_FLAG)
     {
         OC_LOG (INFO, TAG, "Flag includes OC_INIT_FLAG");
@@ -275,7 +382,11 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
         OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
         if (entityHandlerRequest)
         {
-            if (OC_REST_GET == entityHandlerRequest->method)
+            if (entityHandlerRequest->resource == NULL) {
+                OC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
+                ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
+            }
+            else if (OC_REST_GET == entityHandlerRequest->method)
             {
                 OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
                 ProcessGetRequest (entityHandlerRequest);
@@ -285,6 +396,11 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
                 OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
                 ProcessPutRequest (entityHandlerRequest);
             }
+            else if (OC_REST_DELETE == entityHandlerRequest->method)
+            {
+                OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
+                ehResult = ProcessDeleteRequest (entityHandlerRequest);
+            }
             else
             {
                 OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
@@ -308,15 +424,18 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
         }
     }
 
-    return OC_EH_OK;
+    return ehResult;
 }
 
 
-    OCEntityHandlerResult
+OCEntityHandlerResult
 OCEntityHandlerCb (OCEntityHandlerFlag flag,
         OCEntityHandlerRequest *entityHandlerRequest)
 {
     OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
+
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+
     if (flag & OC_INIT_FLAG)
     {
         OC_LOG (INFO, TAG, "Flag includes OC_INIT_FLAG");
@@ -341,6 +460,11 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
                 OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
                 ProcessPostRequest (entityHandlerRequest);
             }
+            else if (OC_REST_DELETE == entityHandlerRequest->method)
+            {
+                OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
+                ehResult = ProcessDeleteRequest (entityHandlerRequest);
+            }
             else
             {
                 OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
@@ -395,7 +519,7 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
         entityHandlerRequest->numSendVendorSpecificHeaderOptions = 2;
     }
 
-    return OC_EH_OK;
+    return ehResult;
 }
 
 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
index 6b96e9b..2e4b276 100644 (file)
@@ -262,15 +262,18 @@ BuildCollectionBatchJSONResponse(OCEntityHandlerFlag flag,
                 ehRequest->resource = (OCResourceHandle) temp;
 
                 ehRet = temp->entityHandler(OC_REQUEST_FLAG, ehRequest);
+                stackRet = EntityHandlerCodeToOCStackCode(ehRet);
 
                 if(ehRet == OC_EH_OK)
                 {
                     unsigned char* buffer = ehRequest->resJSONPayload;
-                    ehRequest->resJSONPayloadLen = ehRequest->resJSONPayloadLen - strlen((char*)buffer);
+                    ehRequest->resJSONPayloadLen =
+                            ehRequest->resJSONPayloadLen - strlen((char*)buffer);
 
                     buffer += strlen((char*)buffer);
                     ehRequest->resJSONPayload = buffer;
-                    if ( resource->rsrcResources[i+1] && ehRequest->resJSONPayloadLen > sizeof(OC_JSON_SEPARATOR) )
+                    if ( resource->rsrcResources[i+1] &&
+                         ehRequest->resJSONPayloadLen > sizeof(OC_JSON_SEPARATOR) )
                     {
                         * buffer = OC_JSON_SEPARATOR;
                         buffer++;
@@ -280,7 +283,6 @@ BuildCollectionBatchJSONResponse(OCEntityHandlerFlag flag,
                 }
                 else
                 {
-                    stackRet = OC_STACK_ERROR;
                     break;
                 }
             }
index 7f3dec3..13d7927 100644 (file)
@@ -329,6 +329,30 @@ OCStackResult DetermineResourceHandling (OCRequest *request,
     }
 }
 
+OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
+{
+    OCStackResult result;
+
+    switch (ehResult)
+    {
+        case OC_EH_OK:
+            result = OC_STACK_OK;
+            break;
+        case OC_EH_ERROR:
+            result = OC_STACK_ERROR;
+            break;
+        case OC_EH_FORBIDDEN:
+            result = OC_STACK_RESOURCE_ERROR;
+            break;
+        case OC_EH_RESOURCE_DELETED:
+            result = OC_STACK_NO_RESOURCE;
+            break;
+        default:
+            result = OC_STACK_ERROR;
+    }
+
+    return result;
+}
 
 static OCStackResult
 HandleVirtualResource (OCRequest *request, OCResource* resource)
@@ -409,10 +433,14 @@ static OCStackResult
 HandleDefaultDeviceEntityHandler (OCRequest *request)
 {
     OCStackResult result = OC_STACK_OK;
+    OCEntityHandlerResult ehResult;
     OCEntityHandlerRequest *ehRequest = request->entityHandlerRequest;
 
     // At this point we know for sure that defaultDeviceHandler exists
-    defaultDeviceHandler(OC_REQUEST_FLAG, ehRequest, (char*) request->resourceUrl);
+    ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, ehRequest,
+                                  (char*) request->resourceUrl);
+
+    result = EntityHandlerCodeToOCStackCode(ehResult);
 
     ehRequest->resJSONPayloadLen = ehRequest->resJSONPayloadLen -
                                     strlen((char*)ehRequest->resJSONPayload);
@@ -427,6 +455,8 @@ HandleResourceWithEntityHandler (OCRequest *request,
                                  uint8_t collectionResource)
 {
     OCStackResult result = OC_STACK_OK;
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+
     OCEntityHandlerRequest *ehRequest = request->entityHandlerRequest;
 
     OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithEntityHandler"));
@@ -436,7 +466,8 @@ HandleResourceWithEntityHandler (OCRequest *request,
     // status code from entity handler is ignored unless observe call
     if (request->observe == NULL)
     {
-        resource->entityHandler(OC_REQUEST_FLAG, ehRequest);
+        ehResult = resource->entityHandler(OC_REQUEST_FLAG, ehRequest);
+        result = EntityHandlerCodeToOCStackCode(ehResult);
     }
     else
     {
@@ -528,8 +559,7 @@ BuildJSONResponse(ResourceHandling resHandling, OCResource *resource, OCRequest
 
         case OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER:
             {
-                ret = HandleCollectionResourceDefaultEntityHandler (request,
-                        resource);
+                ret = HandleCollectionResourceDefaultEntityHandler (request, resource);
                 break;
             }
 
index 743018f..700f68e 100644 (file)
@@ -399,6 +399,7 @@ OCStackResult OCDoResource(OCDoHandle *handle, OCMethod method, const char *requ
         case OC_REST_GET:
         case OC_REST_PUT:
         case OC_REST_POST:
+        case OC_REST_DELETE:
         case OC_REST_OBSERVE:
         case OC_REST_OBSERVE_ALL:
         case OC_REST_CANCEL_OBSERVE:
@@ -1144,30 +1145,30 @@ OCResourceHandle OCGetResourceHandle(uint8_t index) {
  * @param handle - handle of resource to be deleted
  *
  * @return
- *     OC_STACK_OK    - no errors
- *     OC_STACK_ERROR - stack process error
+ *     OC_STACK_OK              - no errors
+ *     OC_STACK_ERROR           - stack process error
+ *     OC_STACK_NO_RESOURCE     - resource not found
+ *     OC_STACK_INVALID_PARAM   - invalid param
  */
 OCStackResult OCDeleteResource(OCResourceHandle handle) {
     OC_LOG(INFO, TAG, PCF("Entering OCDeleteResource"));
 
     if (!handle) {
-        OC_LOG(ERROR, TAG, PCF("Resource not found"));
+        OC_LOG(ERROR, TAG, PCF("Invalid param"));
         return OC_STACK_INVALID_PARAM;
     }
+    
+    OCResource *resource = findResource((OCResource *) handle);
+    if (resource == NULL) {
+        OC_LOG(ERROR, TAG, PCF("Resource not found"));
+        return OC_STACK_NO_RESOURCE;
+    }
 
     if (deleteResource((OCResource *) handle) == 0) {
         OC_LOG(ERROR, TAG, PCF("Error deleting resource"));
         return OC_STACK_ERROR;
     }
 
-    #ifdef WITH_PRESENCE
-    if(presenceResource.handle)
-    {
-        ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
-        OCNotifyAllObservers(presenceResource.handle, OC_LOW_QOS);
-    }
-    #endif
-
     return OC_STACK_OK;
 }
 
@@ -1723,15 +1724,24 @@ int deleteResource(OCResource *resource) {
     temp = headResource;
     while (temp) {
         if (temp == resource) {
+            // Invalidate all Resource Properties.
+            resource->resourceProperties = (OCResourceProperty) 0;
+            OCNotifyAllObservers((OCResourceHandle)resource, OC_HIGH_QOS);
+
+            #ifdef WITH_PRESENCE
+            if(presenceResource.handle)
+            {
+                ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
+                OCNotifyAllObservers(presenceResource.handle, OC_LOW_QOS);
+            }
+            #endif
+
             if (temp == headResource) {
                 headResource = temp->next;
             } else {
                 prev->next = temp->next;
             }
 
-            resource->resourceProperties = (OCResourceProperty) 0; // Invalidate all Resource Properties.
-            OCNotifyAllObservers((OCResourceHandle)resource, OC_HIGH_QOS);
-
             deleteResourceElements(temp);
             OCFree(temp);
             return 1;
index d0da30c..0acf542 100644 (file)
@@ -44,6 +44,7 @@ CXX_INC=-I$(OCLIB)/include \
        -I../../csdk/logger/include
 
 BOOST_LIBS=-lboost_program_options
+#BOOST_LIBS=-L/usr/local/boost/lib/ -lboost_program_options    # for boost libraries at the specified path
 
 LIB_OC_LOGGER:=../../oc_logger/lib/oc_logger.a
 
@@ -80,5 +81,4 @@ clean:
        rm -f *.o $(APPS)
 
 clean_apps:
-       rm -f server client monoprocess small_example
-
+       rm -f *.o $(APPS)