Merge remote-tracking branch 'origin/routing-manager'
[platform/upstream/iotivity.git] / resource / csdk / stack / samples / linux / SimpleClientServer / ocserver.cpp
index c190a4c..65d7075 100644 (file)
 
 #include <stdio.h>
 #include <string.h>
+#include <string>
 #include <stdlib.h>
 #include <unistd.h>
 #include <signal.h>
 #include <pthread.h>
+#include <array>
 #include "ocstack.h"
 #include "logger.h"
-#include "cJSON.h"
+#include "ocpayload.h"
 #include "ocserver.h"
 
+//string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
+// 9 + 9 + 1 = 19
+const int URI_MAXSIZE = 19;
 
 static int gObserveNotifyType = 3;
 
 int gQuitFlag = 0;
-int gLEDUnderObservation = 0;
+int gLightUnderObservation = 0;
 
-static LEDResource LED;
-// This variable determines instance number of the LED resource.
-// Used by POST method to create a new instance of LED resource.
-static int gCurrLedInstance = 0;
+static LightResource Light;
+// This variable determines instance number of the Light resource.
+// Used by POST method to create a new instance of Light resource.
+static int gCurrLightInstance = 0;
 
-static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
+static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
 
 Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
 
 #ifdef WITH_PRESENCE
 static int stopPresenceCount = 10;
+#define numPresenceResources (2)
 #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 *gResourceUri= (char *)"/a/light";
+const char *dateOfManufacture = "myDateOfManufacture";
+const char *deviceName = "myDeviceName";
+const char *deviceUUID = "myDeviceUUID";
+const char *firmwareVersion = "myFirmwareVersion";
+const char *manufacturerName = "myName";
+const char *operatingSystemVersion = "myOS";
+const char *hardwareVersion = "myHardwareVersion";
+const char* platformID = "myPlatformID";
+const char *manufacturerUrl = "myManufacturerUrl";
+const char *modelNumber = "myModelNumber";
+const char *platformVersion = "myPlatformVersion";
+const char *supportUrl = "mySupportUrl";
+const char *version = "myVersion";
+const char *systemTime = "2015-05-15T11.04";
+
+// Entity handler should check for resourceTypeName and ResourceInterface in order to GET
+// the existence of a known resource
+const char *resourceTypeName = "core.light";
+const char *resourceInterface = OC_RSRVD_INTERFACE_DEFAULT;
+
+OCPlatformInfo platformInfo;
+OCDeviceInfo deviceInfo;
+
+OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
+        return nullptr;
+    }
 
-char *gResourceUri= (char *)"/a/led";
+    OCRepPayloadSetUri(payload, uri);
+    OCRepPayloadSetPropBool(payload, "state", state);
+    OCRepPayloadSetPropInt(payload, "power", power);
 
-static uint16_t OC_WELL_KNOWN_PORT = 5683;
+    return payload;
+}
 
 //This function takes the request as an input and returns the response
-//in JSON format.
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
+OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
 {
-    cJSON *json = cJSON_CreateObject();
-    cJSON *format;
-    char *jsonResponse;
-    LEDResource *currLEDResource = &LED;
+    if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+    {
+        OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
+        return nullptr;
+    }
+
+    OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
+
+    LightResource *currLightResource = &Light;
 
-    if (ehRequest->resource == gLedInstance[0].handle)
+    if (ehRequest->resource == gLightInstance[0].handle)
     {
-        currLEDResource = &gLedInstance[0];
-        gResourceUri = (char *) "a/led/0";
+        currLightResource = &gLightInstance[0];
+        gResourceUri = (char *) "a/light/0";
     }
-    else if (ehRequest->resource == gLedInstance[1].handle)
+    else if (ehRequest->resource == gLightInstance[1].handle)
     {
-        currLEDResource = &gLedInstance[1];
-        gResourceUri = (char *) "a/led/1";
+        currLightResource = &gLightInstance[1];
+        gResourceUri = (char *) "a/light/1";
     }
 
     if(OC_REST_PUT == ehRequest->method)
     {
-        cJSON *putJson = cJSON_Parse((char *)ehRequest->reqJSONPayload);
-        currLEDResource->state = ( !strcmp(cJSON_GetObjectItem(putJson,"state")->valuestring , "on") ? true:false);
-        currLEDResource->power = cJSON_GetObjectItem(putJson,"power")->valuedouble;
-        cJSON_Delete(putJson);
+        // Get pointer to query
+        int64_t pow;
+        if(OCRepPayloadGetPropInt(input, "power", &pow))
+        {
+            currLightResource->power =pow;
+        }
+
+        bool state;
+        if(OCRepPayloadGetPropBool(input, "state", &state))
+        {
+            currLightResource->state = state;
+        }
     }
 
-    cJSON_AddStringToObject(json,"href",gResourceUri);
-    cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-    cJSON_AddStringToObject(format, "state", (char *) (currLEDResource->state ? "on":"off"));
-    cJSON_AddNumberToObject(format, "power", currLEDResource->power);
+    return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
+}
 
-    jsonResponse = cJSON_Print(json);
-    cJSON_Delete(json);
+/*
+ * Very simple example of query parsing.
+ * The query may have multiple filters separated by ';'.
+ * It is upto the entity handler to parse the query for the individual filters,
+ * VALIDATE them and respond as it sees fit.
+
+ * This function only returns false if the query is exactly "power<X" and
+ * current power is greater than X. If X cannot be parsed for an int,
+ * true is returned.
+ */
+bool checkIfQueryForPowerPassed(char * query)
+{
+    if (query && strncmp(query, "power<", strlen("power<")) == 0)
+    {
+        char * pointerToOperator = strstr(query, "<");
 
-    return jsonResponse;
+        if (pointerToOperator)
+        {
+            int powerRequested = atoi(pointerToOperator + 1);
+            if (Light.power > powerRequested)
+            {
+                OC_LOG_V(INFO, TAG, "Current power: %d. Requested: <%d", Light.power
+                            , powerRequested);
+                return false;
+            }
+        }
+    }
+    return true;
 }
 
-void ProcessGetRequest (OCEntityHandlerRequest *ehRequest)
+/*
+ * Application should validate and process these as desired.
+ */
+OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
 {
-    char *getResp = constructJsonResponse(ehRequest);
+    OC_LOG_V(INFO, TAG, PCF("Received query %s"), entityHandlerRequest->query);
+    OC_LOG(INFO, TAG, PCF("Not processing query"));
+    return OC_EH_OK;
+}
 
-    if (ehRequest->resJSONPayloadLen > strlen ((char *)getResp))
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
+{
+    OCEntityHandlerResult ehResult;
+    bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
+
+    // Empty payload if the query has no match.
+    if (queryPassed)
     {
-        strncpy((char *)ehRequest->resJSONPayload, getResp,
-                strlen((char *)getResp));
+        OCRepPayload *getResp = constructResponse(ehRequest);
+        if(!getResp)
+        {
+            OC_LOG(ERROR, TAG, "constructResponse failed");
+            return OC_EH_ERROR;
+        }
+
+        *payload = getResp;
+        ehResult = OC_EH_OK;
     }
     else
     {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                ehRequest->resJSONPayloadLen);
+        ehResult = OC_EH_OK;
     }
 
-    free(getResp);
+    return ehResult;
 }
 
-void ProcessPutRequest (OCEntityHandlerRequest *ehRequest)
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload** payload)
 {
-    char *putResp = constructJsonResponse(ehRequest);
+    OCEntityHandlerResult ehResult;
+    OCRepPayload *putResp = constructResponse(ehRequest);
 
-    if (ehRequest->resJSONPayloadLen > strlen ((char *)putResp))
-    {
-        strncpy((char *)ehRequest->resJSONPayload, putResp,
-                strlen((char *)putResp));
-    }
-    else
+    if(!putResp)
     {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                ehRequest->resJSONPayloadLen);
+        OC_LOG(ERROR, TAG, "Failed to construct Json response");
+        return OC_EH_ERROR;
     }
 
-    free(putResp);
+    *payload = putResp;
+    ehResult = OC_EH_OK;
+
+    return ehResult;
 }
 
-OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest)
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+        OCEntityHandlerResponse *response, OCRepPayload** payload)
 {
     OCEntityHandlerResult ehResult = OC_EH_OK;
-    char *respPLPost_led = NULL;
-    cJSON *json;
-    cJSON *format;
+    OCRepPayload *respPLPost_light = nullptr;
 
     /*
      * The entity handler determines how to process a POST request.
      * Per the REST paradigm, POST can also be used to update representation of existing
      * resource or create a new resource.
-     * In the sample below, if the POST is for /a/led then a new instance of the LED
+     * In the sample below, if the POST is for /a/light then a new instance of the Light
      * resource is created with default representation (if representation is included in
      * POST payload it can be used as initial values) as long as the instance is
      * lesser than max new instance count. Once max instance count is reached, POST on
-     * /a/led updated the representation of /a/led (just like PUT)
+     * /a/light updated the representation of /a/light (just like PUT)
      */
 
-    if (ehRequest->resource == LED.handle)
+    if (ehRequest->resource == Light.handle)
     {
-        if (gCurrLedInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
+        if (gCurrLightInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
         {
-            // Create new LED instance
-            char newLedUri[15] = "/a/led/";
-            sprintf (newLedUri + strlen(newLedUri), "%d", gCurrLedInstance);
-            json = cJSON_CreateObject();
-            cJSON_AddStringToObject(json,"href",gResourceUri);
-            cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-            cJSON_AddStringToObject(format, "createduri", (char *) newLedUri);
+            // Create new Light instance
+            char newLightUri[URI_MAXSIZE];
+            snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
+
+            respPLPost_light = OCRepPayloadCreate();
+            OCRepPayloadSetUri(respPLPost_light, gResourceUri);
+            OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
 
-            if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance]))
+            if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
             {
-                OC_LOG (INFO, TAG, "Created new LED instance\n");
-                gLedInstance[gCurrLedInstance].state = 0;
-                gLedInstance[gCurrLedInstance].power = 0;
-                gCurrLedInstance++;
-                respPLPost_led = cJSON_Print(json);
-                strncpy ((char *)ehRequest->newResourceUri, newLedUri, MAX_URI_LENGTH);
+                OC_LOG (INFO, TAG, "Created new Light instance\n");
+                gLightInstance[gCurrLightInstance].state = 0;
+                gLightInstance[gCurrLightInstance].power = 0;
+                gCurrLightInstance++;
+                strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
                 ehResult = OC_EH_RESOURCE_CREATED;
             }
-
-            cJSON_Delete(json);
         }
         else
         {
-            // Update repesentation of /a/led
-            LED.state = true;
-            LED.power = 11;
-            respPLPost_led = constructJsonResponse(ehRequest);
+            // Update repesentation of /a/light
+            Light.state = true;
+            Light.power = 11;
+            respPLPost_light = constructResponse(ehRequest);
         }
     }
     else
     {
         for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
         {
-            if (ehRequest->resource == gLedInstance[i].handle)
+            if (ehRequest->resource == gLightInstance[i].handle)
             {
-                gLedInstance[i].state = true;
-                gLedInstance[i].power = 22;
+                gLightInstance[i].state = true;
+                gLightInstance[i].power = 22;
                 if (i == 0)
                 {
-                    respPLPost_led = constructJsonResponse(ehRequest);
+                    respPLPost_light = constructResponse(ehRequest);
                     break;
                 }
                 else if (i == 1)
                 {
-                    respPLPost_led = constructJsonResponse(ehRequest);
+                    respPLPost_light = constructResponse(ehRequest);
                 }
             }
         }
     }
 
-    if (respPLPost_led != NULL && ehRequest->resJSONPayloadLen > strlen ((char *)respPLPost_led))
+    if ((respPLPost_light != NULL))
     {
-        strncpy((char *)ehRequest->resJSONPayload, respPLPost_led,
-                strlen((char *)respPLPost_led));
+        *payload = respPLPost_light;
     }
     else
     {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                ehRequest->resJSONPayloadLen);
+        OC_LOG(INFO, TAG, "Payload was NULL");
+        ehResult = OC_EH_ERROR;
     }
 
-    free(respPLPost_led);
     return ehResult;
 }
 
 OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
 {
+    if(ehRequest == NULL)
+    {
+        OC_LOG(INFO, TAG, "The ehRequest is NULL");
+        return OC_EH_ERROR;
+    }
     OCEntityHandlerResult ehResult = OC_EH_OK;
 
     OC_LOG_V(INFO, TAG, "\n\nExecuting %s for resource %d ", __func__, ehRequest->resource);
@@ -238,9 +324,7 @@ OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
      * 2. optionally, app removes observers out of its array 'interestedObservers'
      */
 
-    const char* deleteResponse = NULL;
-
-    if ((ehRequest != NULL) && (ehRequest->resource == LED.handle))
+    if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
     {
         //Step 1: Ask stack to do the work.
         OCStackResult result = OCDeleteResource(ehRequest->resource);
@@ -249,7 +333,6 @@ OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
         {
             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++)
@@ -265,70 +348,43 @@ OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
         else if (result == OC_STACK_NO_RESOURCE)
         {
             OC_LOG(INFO, TAG, "\n\nThe resource doesn't exist or it might have been deleted.");
-            deleteResponse = responsePayloadResourceDoesNotExist;
             ehResult = OC_EH_RESOURCE_DELETED;
         }
         else
         {
             OC_LOG(INFO, TAG, "\n\nEncountered error from OCDeleteResource().");
-            deleteResponse = responsePayloadDeleteNotOK;
             ehResult = OC_EH_ERROR;
         }
     }
-    else if (ehRequest->resource != LED.handle)
+    else if (ehRequest->resource != Light.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)
+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;
+    return OC_EH_RESOURCE_NOT_FOUND;
 }
 
 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest)
 {
     OC_LOG_V (INFO, TAG, "Received observation registration request with observation Id %d",
-            ehRequest->obsInfo->obsId);
+            ehRequest->obsInfo.obsId);
     for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
     {
         if (interestedObservers[i].valid == false)
         {
-            interestedObservers[i].observationId = ehRequest->obsInfo->obsId;
+            interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
             interestedObservers[i].valid = true;
-            gLEDUnderObservation = 1;
+            gLightUnderObservation = 1;
             break;
         }
     }
@@ -339,10 +395,10 @@ void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
     bool clientStillObserving = false;
 
     OC_LOG_V (INFO, TAG, "Received observation deregistration request for observation Id %d",
-            ehRequest->obsInfo->obsId);
+            ehRequest->obsInfo.obsId);
     for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
     {
-        if (interestedObservers[i].observationId == ehRequest->obsInfo->obsId)
+        if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
         {
             interestedObservers[i].valid = false;
         }
@@ -353,174 +409,244 @@ void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest)
         }
     }
     if (clientStillObserving == false)
-        gLEDUnderObservation = 0;
+        gLightUnderObservation = 0;
 }
 
 OCEntityHandlerResult
 OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *entityHandlerRequest, char* uri)
+                         OCEntityHandlerRequest *entityHandlerRequest,
+                         char* uri,
+                         void* /*callbackParam*/)
 {
     OC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
 
     OCEntityHandlerResult ehResult = OC_EH_OK;
+    OCEntityHandlerResponse response;
 
-    if (flag & OC_INIT_FLAG)
+    // Validate pointer
+    if (!entityHandlerRequest)
     {
-        OC_LOG (INFO, TAG, "Flag includes OC_INIT_FLAG");
+        OC_LOG (ERROR, TAG, "Invalid request pointer");
+        return OC_EH_ERROR;
     }
+    // Initialize certain response fields
+    response.numSendVendorSpecificHeaderOptions = 0;
+    memset(response.sendVendorSpecificHeaderOptions, 0,
+            sizeof response.sendVendorSpecificHeaderOptions);
+    memset(response.resourceUri, 0, sizeof response.resourceUri);
+    OCRepPayload* payload = nullptr;
+
+
     if (flag & OC_REQUEST_FLAG)
     {
         OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
-        if (entityHandlerRequest)
+
+        if (entityHandlerRequest->resource == NULL)
         {
-            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);
-            }
-            else if (OC_REST_PUT == entityHandlerRequest->method)
-            {
-                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 (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");
+            ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
+        }
+        else if (OC_REST_PUT == entityHandlerRequest->method)
+        {
+            OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+            ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
+        }
+        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",
+                      entityHandlerRequest->method);
+            ehResult = OC_EH_ERROR;
+        }
+               // If the result isn't an error or forbidden, send response
+        if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
+        {
+            // Format the response.  Note this requires some info about the request
+            response.requestHandle = entityHandlerRequest->requestHandle;
+            response.resourceHandle = entityHandlerRequest->resource;
+            response.ehResult = ehResult;
+            response.payload = reinterpret_cast<OCPayload*>(payload);
+            // Indicate that response is NOT in a persistent buffer
+            response.persistentBufferFlag = 0;
+
+            // Send the response
+            if (OCDoResponse(&response) != OC_STACK_OK)
             {
-                OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
-                        entityHandlerRequest->method);
+                OC_LOG(ERROR, TAG, "Error sending response");
+                ehResult = OC_EH_ERROR;
             }
         }
     }
     if (flag & OC_OBSERVE_FLAG)
     {
         OC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
-        if (entityHandlerRequest)
+        if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
         {
-            if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo->action)
-            {
-                OC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
-            }
-            else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo->action)
-            {
-                OC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
-            }
+            OC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
+        }
+        else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
+        {
+            OC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
         }
     }
 
     return ehResult;
 }
 
+OCEntityHandlerResult
+OCNOPEntityHandlerCb (OCEntityHandlerFlag /*flag*/,
+                      OCEntityHandlerRequest * /*entityHandlerRequest*/,
+                      void* /*callbackParam*/)
+{
+    // This is callback is associated with the 2 presence notification
+    // resources. They are non-operational.
+    return OC_EH_OK;
+}
 
 OCEntityHandlerResult
 OCEntityHandlerCb (OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *entityHandlerRequest)
+        OCEntityHandlerRequest *entityHandlerRequest, void* /*callback*/)
 {
     OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
 
     OCEntityHandlerResult ehResult = OC_EH_OK;
+    OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, { },{ 0 }, false };
 
-    if (flag & OC_INIT_FLAG)
+    // Validate pointer
+    if (!entityHandlerRequest)
     {
-        OC_LOG (INFO, TAG, "Flag includes OC_INIT_FLAG");
+        OC_LOG (ERROR, TAG, "Invalid request pointer");
+        return OC_EH_ERROR;
     }
+
+    // Initialize certain response fields
+    response.numSendVendorSpecificHeaderOptions = 0;
+    memset(response.sendVendorSpecificHeaderOptions,
+            0, sizeof response.sendVendorSpecificHeaderOptions);
+    memset(response.resourceUri, 0, sizeof response.resourceUri);
+    OCRepPayload* payload = nullptr;
+
     if (flag & OC_REQUEST_FLAG)
     {
         OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
-        if (entityHandlerRequest)
+
+        if (OC_REST_GET == entityHandlerRequest->method)
         {
-            if (OC_REST_GET == entityHandlerRequest->method)
-            {
-                OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-                ProcessGetRequest (entityHandlerRequest);
-            }
-            else if (OC_REST_PUT == entityHandlerRequest->method)
-            {
-                OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
-                ProcessPutRequest (entityHandlerRequest);
-            }
-            else if (OC_REST_POST == entityHandlerRequest->method)
-            {
-                OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
-                ehResult = ProcessPostRequest (entityHandlerRequest);
-            }
-            else if (OC_REST_DELETE == entityHandlerRequest->method)
+            OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
+            ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
+        }
+        else if (OC_REST_PUT == entityHandlerRequest->method)
+        {
+            OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+            ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
+        }
+        else if (OC_REST_POST == entityHandlerRequest->method)
+        {
+            OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
+            ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
+        }
+        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",
+                      entityHandlerRequest->method);
+            ehResult = OC_EH_ERROR;
+        }
+        // If the result isn't an error or forbidden, send response
+        if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
+        {
+            // Format the response.  Note this requires some info about the request
+            response.requestHandle = entityHandlerRequest->requestHandle;
+            response.resourceHandle = entityHandlerRequest->resource;
+            response.ehResult = ehResult;
+            response.payload = reinterpret_cast<OCPayload*>(payload);
+            // Indicate that response is NOT in a persistent buffer
+            response.persistentBufferFlag = 0;
+
+            // Handle vendor specific options
+            if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
+                    entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
             {
-                OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
-                ehResult = ProcessDeleteRequest (entityHandlerRequest);
+                OC_LOG (INFO, TAG, "Received vendor specific options");
+                uint8_t i = 0;
+                OCHeaderOption * rcvdOptions =
+                        entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
+                for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
+                {
+                    if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
+                    {
+                        OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
+                                ((OCHeaderOption)rcvdOptions[i]).optionID );
+
+                        OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
+                            MAX_HEADER_OPTION_DATA_LENGTH);
+                    }
+                }
+                OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;
+                uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
+                uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
+                sendOptions[0].protocolID = OC_COAP_ID;
+                sendOptions[0].optionID = 2248;
+                memcpy(sendOptions[0].optionData, option2, sizeof(option2));
+                sendOptions[0].optionLength = 10;
+                sendOptions[1].protocolID = OC_COAP_ID;
+                sendOptions[1].optionID = 2600;
+                memcpy(sendOptions[1].optionData, option3, sizeof(option3));
+                sendOptions[1].optionLength = 10;
+                response.numSendVendorSpecificHeaderOptions = 2;
             }
-            else
+
+            // Send the response
+            if (OCDoResponse(&response) != OC_STACK_OK)
             {
-                OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
-                        entityHandlerRequest->method);
+                OC_LOG(ERROR, TAG, "Error sending response");
+                ehResult = OC_EH_ERROR;
             }
         }
     }
     if (flag & OC_OBSERVE_FLAG)
     {
         OC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG");
-        if (entityHandlerRequest)
+
+        if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
         {
-            if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo->action)
-            {
-                OC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
-                ProcessObserveRegister (entityHandlerRequest);
-            }
-            else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo->action)
-            {
-                OC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
-                ProcessObserveDeregister (entityHandlerRequest);
-            }
+            OC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client");
+            ProcessObserveRegister (entityHandlerRequest);
         }
-    }
-    if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions &&
-            entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)
-    {
-        OC_LOG (INFO, TAG, "Received vendor specific options");
-        uint8_t i = 0;
-        OCHeaderOption * rcvdOptions = entityHandlerRequest->rcvdVendorSpecificHeaderOptions;
-        for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)
+        else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
         {
-            if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID)
-            {
-                OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with",
-                        ((OCHeaderOption)rcvdOptions[i]).optionID );
-                OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,
-                        ((OCHeaderOption)rcvdOptions[i]).optionLength);
-            }
+            OC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client");
+            ProcessObserveDeregister (entityHandlerRequest);
         }
-        OCHeaderOption * sendOptions = entityHandlerRequest->sendVendorSpecificHeaderOptions;
-        uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30};
-        uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40};
-        sendOptions[0].protocolID = OC_COAP_ID;
-        sendOptions[0].optionID = 2248;
-        memcpy(sendOptions[0].optionData, option2, sizeof(option2));
-        sendOptions[0].optionLength = 10;
-        sendOptions[1].protocolID = OC_COAP_ID;
-        sendOptions[1].optionID = 2600;
-        memcpy(sendOptions[1].optionData, option3, sizeof(option3));
-        sendOptions[1].optionLength = 10;
-        entityHandlerRequest->numSendVendorSpecificHeaderOptions = 2;
     }
 
+    OCPayloadDestroy(response.payload);
     return ehResult;
 }
 
 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
-void handleSigInt(int signum) {
-    if (signum == SIGINT) {
+void handleSigInt(int signum)
+{
+    if (signum == SIGINT)
+    {
         gQuitFlag = 1;
     }
 }
 
-void *ChangeLEDRepresentation (void *param)
+void *ChangeLightRepresentation (void *param)
 {
     (void)param;
     OCStackResult result = OC_STACK_ERROR;
@@ -529,13 +655,13 @@ void *ChangeLEDRepresentation (void *param)
     uint8_t numNotifies = (SAMPLE_MAX_NUM_OBSERVATIONS)/2;
     OCObservationId obsNotify[numNotifies];
 
-    while (1)
+    while (!gQuitFlag)
     {
-        sleep(10);
-        LED.power += 5;
-        if (gLEDUnderObservation)
+        sleep(3);
+        Light.power += 5;
+        if (gLightUnderObservation)
         {
-            OC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", LED.power);
+            OC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", Light.power);
             if (gObserveNotifyType == 1)
             {
                 // Notify list of observers. Alternate observers on the list will be notified.
@@ -549,27 +675,20 @@ void *ChangeLEDRepresentation (void *param)
                     }
                 }
 
-                cJSON *json = cJSON_CreateObject();
-                cJSON *format;
-                cJSON_AddStringToObject(json,"href",gResourceUri);
-                cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-                cJSON_AddStringToObject(format, "state", (char *) (LED.state ? "on":"off"));
-                cJSON_AddNumberToObject(format, "power", LED.power);
-                char * obsResp = cJSON_Print(json);
-                cJSON_Delete(json);
-                result = OCNotifyListOfObservers (LED.handle, obsNotify, j,
-                        (unsigned char *)obsResp, OC_NA_QOS);
-                free(obsResp);
+                OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
+                result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
+                        payload, OC_NA_QOS);
+                OCRepPayloadDestroy(payload);
             }
             else if (gObserveNotifyType == 0)
             {
                 // Notifying all observers
-                result = OCNotifyAllObservers (LED.handle, OC_NA_QOS);
+                result = OCNotifyAllObservers (Light.handle, OC_NA_QOS);
                 if (OC_STACK_NO_OBSERVERS == result)
                 {
                     OC_LOG (INFO, TAG,
                             "=======> No more observers exist, stop sending observations");
-                    gLEDUnderObservation = 0;
+                    gLightUnderObservation = 0;
                 }
             }
             else
@@ -578,7 +697,10 @@ void *ChangeLEDRepresentation (void *param)
             }
         }
 #ifdef WITH_PRESENCE
-        OC_LOG_V(INFO, TAG, "================ presence count %d",stopPresenceCount);
+        if(stopPresenceCount > 0)
+        {
+            OC_LOG_V(INFO, TAG, "================  Counting down to stop presence %d", stopPresenceCount);
+        }
         if(!stopPresenceCount--)
         {
             OC_LOG(INFO, TAG, "================ stopping presence");
@@ -589,6 +711,216 @@ void *ChangeLEDRepresentation (void *param)
     return NULL;
 }
 
+#ifdef WITH_PRESENCE
+void *presenceNotificationGenerator(void *param)
+{
+    sleep(10);
+    (void)param;
+    OCDoHandle presenceNotificationHandles[numPresenceResources];
+    OCStackResult res = OC_STACK_OK;
+
+    std::array<std::string, numPresenceResources> presenceNotificationResources { {
+        std::string("core.fan"),
+        std::string("core.led") } };
+    std::array<std::string, numPresenceResources> presenceNotificationUris { {
+        std::string("/a/fan"),
+        std::string("/a/led") } };
+
+    for(int i=0; i<numPresenceResources; i++)
+    {
+        if(res == OC_STACK_OK)
+        {
+            sleep(1);
+            res = OCCreateResource(&presenceNotificationHandles[i],
+                    presenceNotificationResources.at(i).c_str(),
+                    OC_RSRVD_INTERFACE_DEFAULT,
+                    presenceNotificationUris.at(i).c_str(),
+                    OCNOPEntityHandlerCb,
+                    NULL,
+                    OC_DISCOVERABLE|OC_OBSERVABLE);
+        }
+        if(res != OC_STACK_OK)
+        {
+            OC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to create resource "
+                    "%s with result %s.", presenceNotificationResources.at(i).c_str(),
+                    getResult(res));
+            break;
+        }
+        OC_LOG_V(INFO, TAG, PCF("Created %s for presence notification"),
+                                presenceNotificationUris[i].c_str());
+    }
+    sleep(5);
+    for(int i=0; i<numPresenceResources; i++)
+    {
+        if(res == OC_STACK_OK)
+        {
+            res = OCDeleteResource(presenceNotificationHandles[i]);
+        }
+        if(res != OC_STACK_OK)
+        {
+            OC_LOG_V(ERROR, TAG, "\"Presence Notification Generator\" failed to delete "\
+                    "resource %s.", presenceNotificationResources.at(i).c_str());
+            break;
+        }
+        OC_LOG_V(INFO, TAG, PCF("Deleted %s for presence notification"),
+                                presenceNotificationUris[i].c_str());
+    }
+    return NULL;
+}
+#endif
+
+int createLightResource (char *uri, LightResource *lightResource)
+{
+    if (!uri)
+    {
+        OC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
+        return -1;
+    }
+
+    lightResource->state = false;
+    lightResource->power= 0;
+    OCStackResult res = OCCreateResource(&(lightResource->handle),
+            "core.light",
+            "oc.mi.def",
+            uri,
+            OCEntityHandlerCb,
+            NULL,
+            OC_DISCOVERABLE|OC_OBSERVABLE);
+    OC_LOG_V(INFO, TAG, "Created Light resource with result: %s", getResult(res));
+
+    return 0;
+}
+
+void DeletePlatformInfo()
+{
+    free (platformInfo.platformID);
+    free (platformInfo.manufacturerName);
+    free (platformInfo.manufacturerUrl);
+    free (platformInfo.modelNumber);
+    free (platformInfo.dateOfManufacture);
+    free (platformInfo.platformVersion);
+    free (platformInfo.operatingSystemVersion);
+    free (platformInfo.hardwareVersion);
+    free (platformInfo.firmwareVersion);
+    free (platformInfo.supportUrl);
+    free (platformInfo.systemTime);
+}
+
+void DeleteDeviceInfo()
+{
+    free (deviceInfo.deviceName);
+}
+
+bool DuplicateString(char** targetString, const char* sourceString)
+{
+    if(!sourceString)
+    {
+        return false;
+    }
+    else
+    {
+        *targetString = (char *) malloc(strlen(sourceString) + 1);
+
+        if(*targetString)
+        {
+            strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
+            return true;
+        }
+    }
+    return false;
+}
+
+OCStackResult SetPlatformInfo(const char* platformID, const char *manufacturerName,
+    const char *manufacturerUrl, const char *modelNumber, const char *dateOfManufacture,
+    const char *platformVersion, const char* operatingSystemVersion, const char* hardwareVersion,
+    const char *firmwareVersion, const char* supportUrl, const char* systemTime)
+{
+
+    bool success = true;
+
+    if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH))
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH))
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    if(!DuplicateString(&platformInfo.platformID, platformID))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&platformInfo.manufacturerName, manufacturerName))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&platformInfo.manufacturerUrl, manufacturerUrl))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&platformInfo.modelNumber, modelNumber))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&platformInfo.dateOfManufacture, dateOfManufacture))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&platformInfo.platformVersion, platformVersion))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&platformInfo.operatingSystemVersion, operatingSystemVersion))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&platformInfo.hardwareVersion, hardwareVersion))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&platformInfo.firmwareVersion, firmwareVersion))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&platformInfo.supportUrl, supportUrl))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&platformInfo.systemTime, systemTime))
+    {
+        success = false;
+    }
+
+    if(success)
+    {
+        return OC_STACK_OK;
+    }
+
+    DeletePlatformInfo();
+    return OC_STACK_ERROR;
+}
+
+OCStackResult SetDeviceInfo(const char* deviceName)
+{
+    if(!DuplicateString(&deviceInfo.deviceName, deviceName))
+    {
+        return OC_STACK_ERROR;
+    }
+    return OC_STACK_OK;
+}
+
 static void PrintUsage()
 {
     OC_LOG(INFO, TAG, "Usage : ocserver -o <0|1>");
@@ -598,11 +930,8 @@ static void PrintUsage()
 
 int main(int argc, char* argv[])
 {
-    uint8_t addr[20] = {0};
-    uint8_t* paddr = NULL;
-    uint16_t port = OC_WELL_KNOWN_PORT;
-    uint8_t ifname[] = "eth0";
     pthread_t threadId;
+    pthread_t threadId_presence;
     int opt;
 
     while ((opt = getopt(argc, argv, "o:")) != -1)
@@ -623,34 +952,75 @@ int main(int argc, char* argv[])
         PrintUsage();
         return -1;
     }
+#ifdef RA_ADAPTER
+    OCRAInfo_t rainfo;
+    rainfo.hostname = "localhost";
+    rainfo.port = 5222;
+    rainfo.xmpp_domain = "localhost";
+    rainfo.username = "test1";
+    rainfo.password = "intel123";
+    rainfo.resource = "";
+    rainfo.user_jid = "";
+
+    OCSetRAInfo(&rainfo);
+#endif
 
     OC_LOG(DEBUG, TAG, "OCServer is starting...");
-    /*Get Ip address on defined interface and initialize coap on it with random port number
-     * this port number will be used as a source port in all coap communications*/
-    if ( OCGetInterfaceAddress(ifname, sizeof(ifname), AF_INET, addr,
-                sizeof(addr)) == ERR_SUCCESS)
-    {
-        OC_LOG_V(INFO, TAG, "Starting ocserver on address %s:%d",addr,port);
-        paddr = addr;
-    }
 
-    if (OCInit((char *) paddr, port, OC_SERVER) != OC_STACK_OK) {
+    if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+    {
         OC_LOG(ERROR, TAG, "OCStack init error");
         return 0;
     }
 #ifdef WITH_PRESENCE
-    if (OCStartPresence(0) != OC_STACK_OK) {
+    if (OCStartPresence(0) != OC_STACK_OK)
+    {
         OC_LOG(ERROR, TAG, "OCStack presence/discovery error");
         return 0;
     }
 #endif
 
-    OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb);
+    OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb, NULL);
+
+    OCStackResult registrationResult =
+        SetPlatformInfo(platformID, manufacturerName, manufacturerUrl, modelNumber,
+            dateOfManufacture, platformVersion,  operatingSystemVersion,  hardwareVersion,
+            firmwareVersion,  supportUrl, systemTime);
+
+    if (registrationResult != OC_STACK_OK)
+    {
+        OC_LOG(INFO, TAG, "Platform info setting failed locally!");
+        exit (EXIT_FAILURE);
+    }
+
+    registrationResult = OCSetPlatformInfo(platformInfo);
+
+    if (registrationResult != OC_STACK_OK)
+    {
+        OC_LOG(INFO, TAG, "Platform Registration failed!");
+        exit (EXIT_FAILURE);
+    }
+
+    registrationResult = SetDeviceInfo(deviceName);
+
+    if (registrationResult != OC_STACK_OK)
+    {
+        OC_LOG(INFO, TAG, "Device info setting failed locally!");
+        exit (EXIT_FAILURE);
+    }
+
+    registrationResult = OCSetDeviceInfo(deviceInfo);
+
+    if (registrationResult != OC_STACK_OK)
+    {
+        OC_LOG(INFO, TAG, "Device Registration failed!");
+        exit (EXIT_FAILURE);
+    }
 
     /*
-     * Declare and create the example resource: LED
+     * Declare and create the example resource: Light
      */
-    createLEDResource(gResourceUri, &LED);
+    createLightResource(gResourceUri, &Light);
 
     // Initialize observations data structure for the resource
     for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
@@ -659,54 +1029,53 @@ int main(int argc, char* argv[])
     }
 
     /*
-     * Create a thread for changing the representation of the LED
+     * Create a thread for changing the representation of the Light
+     */
+    pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);
+
+    /*
+     * Create a thread for generating changes that cause presence notifications
+     * to be sent to clients
      */
-    pthread_create (&threadId, NULL, ChangeLEDRepresentation, (void *)NULL);
+
+    #ifdef WITH_PRESENCE
+    pthread_create(&threadId_presence, NULL, presenceNotificationGenerator, (void *)NULL);
+    #endif
 
     // Break from loop with Ctrl-C
     OC_LOG(INFO, TAG, "Entering ocserver main loop...");
+
+    DeletePlatformInfo();
+    DeleteDeviceInfo();
+
     signal(SIGINT, handleSigInt);
-    while (!gQuitFlag) {
-        if (OCProcess() != OC_STACK_OK) {
+
+    while (!gQuitFlag)
+    {
+        if (OCProcess() != OC_STACK_OK)
+        {
             OC_LOG(ERROR, TAG, "OCStack process error");
             return 0;
         }
-
+#ifndef ROUTING_GATEWAY
         sleep(2);
+#endif
     }
 
     /*
-     * Cancel the LED thread and wait for it to terminate
+     * Cancel the Light thread and wait for it to terminate
      */
     pthread_cancel(threadId);
     pthread_join(threadId, NULL);
+    pthread_cancel(threadId_presence);
+    pthread_join(threadId_presence, NULL);
 
     OC_LOG(INFO, TAG, "Exiting ocserver main loop...");
 
-    if (OCStop() != OC_STACK_OK) {
-        OC_LOG(ERROR, TAG, "OCStack process error");
-    }
-
-    return 0;
-}
-
-int createLEDResource (char *uri, LEDResource *ledResource)
-{
-    if (!uri)
+    if (OCStop() != OC_STACK_OK)
     {
-        OC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
-        return -1;
+        OC_LOG(ERROR, TAG, "OCStack process error");
     }
 
-    ledResource->state = false;
-    ledResource->power= 0;
-    OCStackResult res = OCCreateResource(&(ledResource->handle),
-            "core.led",
-            "oc.mi.def",
-            uri,
-            OCEntityHandlerCb,
-            OC_DISCOVERABLE|OC_OBSERVABLE);
-    OC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
-
     return 0;
 }