Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / resource / csdk / stack / samples / linux / SimpleClientServer / ocserverslow.cpp
index e1184e1..99a0b52 100644 (file)
 #include <sys/time.h>
 #include <list>
 #include "ocstack.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
 #include "logger.h"
 #include "cJSON.h"
 #include "ocserverslow.h"
+#include "ocpayload.h"
 
 volatile sig_atomic_t gQuitFlag = 0;
 
@@ -38,27 +39,20 @@ static std::list<OCEntityHandlerRequest *> gRequestList;
 static constexpr unsigned int SLOW_RESPONSE_DELAY_SEC = 5;
 
 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 unsigned int gCurrLedInstance = 0;
+
 static constexpr unsigned int SAMPLE_MAX_NUM_POST_INSTANCE = 2;
 static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
 
 //char *gResourceUri= const_cast<char *>("/a/led");
 char *gResourceUri= (char *)"/a/led";
 
-static constexpr uint16_t OC_WELL_KNOWN_PORT = 5683;
-
 //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;
 
-    OC_LOG(INFO, TAG, "Entering constructJsonResponse");
+    OC_LOG(INFO, TAG, "Entering constructResponse");
 
     if (ehRequest->resource == gLedInstance[0].handle)
     {
@@ -75,42 +69,63 @@ char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
 
     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);
+        if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+        {
+            OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
+            return nullptr;
+        }
+
+        OCRepPayload *putPayload = reinterpret_cast<OCRepPayload*> (ehRequest->payload);
+
+        int64_t power;
+        bool state;
+
+        if (OCRepPayloadGetPropBool(putPayload, "state", &state))
+        {
+            currLEDResource->state = state;
+        }
+        if (OCRepPayloadGetPropInt (putPayload, "power", &power))
+        {
+            currLEDResource->power = power;
+        }
     }
 
-    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);
+    OCRepPayload *response = OCRepPayloadCreate();
 
-    OC_LOG(INFO, TAG, "Before constructJsonResponse print");
-    jsonResponse = cJSON_Print(json);
-    OC_LOG(INFO, TAG, "Before constructJsonResponse delete");
-    cJSON_Delete(json);
+    if (!response)
+    {
+        OC_LOG_V(ERROR, TAG, "Memory allocation for response payload failed.");
+    }
+
+    OCRepPayloadSetUri (response, gResourceUri);
+    OCRepPayloadSetPropBool(response, "state", currLEDResource->state);
+    OCRepPayloadSetPropInt(response, "power", currLEDResource->power);
 
-    OC_LOG(INFO, TAG, "Before constructJsonResponse return");
-    return jsonResponse;
+    return response;
 }
 
-void ProcessGetRequest (OCEntityHandlerRequest *ehRequest)
+void ProcessGetPutRequest (OCEntityHandlerRequest *ehRequest)
 {
-    OC_LOG(INFO, TAG, "Entering ProcessGetRequest");
-    char *getResp = constructJsonResponse(ehRequest);
-    OC_LOG(INFO, TAG, "After constructJsonResponse");
+    OC_LOG(INFO, TAG, "Entering ProcessGetPutRequest");
+
+    OCRepPayload *getResp = constructResponse(ehRequest);
+
+    if(!getResp)
+    {
+        OC_LOG(ERROR, TAG, "Failed to construct response");
+        return;
+    }
+
     OCEntityHandlerResponse response;
 
     // Format the response.  Note this requires some info about the request
     response.requestHandle = ehRequest->requestHandle;
     response.resourceHandle = ehRequest->resource;
     response.ehResult = OC_EH_OK;
-    response.payload = (unsigned char *)getResp;
-    response.payloadSize = strlen(getResp) + 1;
+    response.payload = reinterpret_cast<OCPayload*> (getResp);
     response.numSendVendorSpecificHeaderOptions = 0;
-    memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
+    memset(response.sendVendorSpecificHeaderOptions,
+            0, sizeof response.sendVendorSpecificHeaderOptions);
     memset(response.resourceUri, 0, sizeof(response.resourceUri));
     // Indicate that response is NOT in a persistent buffer
     response.persistentBufferFlag = 0;
@@ -127,42 +142,37 @@ void ProcessGetRequest (OCEntityHandlerRequest *ehRequest)
 OCEntityHandlerRequest *CopyRequest(OCEntityHandlerRequest *entityHandlerRequest)
 {
     OC_LOG(INFO, TAG, "Copying received request for slow response");
-    OCEntityHandlerRequest *request = (OCEntityHandlerRequest *)OCMalloc(sizeof(OCEntityHandlerRequest));
-    if (request)
+
+    OCEntityHandlerRequest *copyOfRequest =
+            (OCEntityHandlerRequest *)OICMalloc(sizeof(OCEntityHandlerRequest));
+
+    if (copyOfRequest)
     {
         // Do shallow copy
-        memcpy(request, entityHandlerRequest, sizeof(OCEntityHandlerRequest));
-        // Do deep copy of query
-        request->query = (unsigned char * )OCMalloc(strlen((const char *)entityHandlerRequest->query) + 1);
-        if (request->query)
-        {
-            strcpy((char *)request->query, (const char *)entityHandlerRequest->query);
+        memcpy(copyOfRequest, entityHandlerRequest, sizeof(OCEntityHandlerRequest));
 
-            // Copy the request payload
-            request->reqJSONPayload = (unsigned char * )OCMalloc(strlen((const char *)entityHandlerRequest->reqJSONPayload) + 1);
-            if (request->reqJSONPayload)
-            {
-                strcpy((char *)request->reqJSONPayload, (const char *)entityHandlerRequest->reqJSONPayload);
 
-                // Ignore vendor specific header options for example
-                request->numRcvdVendorSpecificHeaderOptions = 0;
-                request->rcvdVendorSpecificHeaderOptions = NULL;
-            }
-            else
-            {
-                OCFree(request->query);
-                OCFree(request);
-                request = NULL;
-            }
+        if (copyOfRequest->query)
+        {
+            // Do deep copy of query
+            copyOfRequest->query = (char *) OICMalloc(
+                    strlen((const char *)entityHandlerRequest->query) + 1);
+
+            strcpy((char *)copyOfRequest->query, (const char *)entityHandlerRequest->query);
         }
-        else
+
+        if (entityHandlerRequest->payload)
         {
-            OCFree(request);
-            request = NULL;
+            copyOfRequest->payload = reinterpret_cast<OCPayload*>
+                    (OCRepPayloadClone ((OCRepPayload*) entityHandlerRequest->payload));
         }
+
+        // Ignore vendor specific header options for example
+        copyOfRequest->numRcvdVendorSpecificHeaderOptions = 0;
+        copyOfRequest->rcvdVendorSpecificHeaderOptions = NULL;
     }
 
-    if (request)
+    if (copyOfRequest)
     {
         OC_LOG(INFO, TAG, "Copied client request");
     }
@@ -170,22 +180,17 @@ OCEntityHandlerRequest *CopyRequest(OCEntityHandlerRequest *entityHandlerRequest
     {
         OC_LOG(ERROR, TAG, "Error copying client request");
     }
-    return request;
+    return copyOfRequest;
 }
 
-OCEntityHandlerResult
-OCEntityHandlerCb (OCEntityHandlerFlag flag,
-        OCEntityHandlerRequest *entityHandlerRequest)
+OCEntityHandlerResult OCEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest, void* callbackParam)
 {
     OCEntityHandlerResult result = OC_EH_ERROR;
     OCEntityHandlerRequest *request = NULL;
 
     OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
-    if (flag & OC_INIT_FLAG)
-    {
-        OC_LOG(INFO, TAG, "Flag includes OC_INIT_FLAG");
-        result = OC_EH_OK;
-    }
+
     if (flag & OC_REQUEST_FLAG)
     {
         OC_LOG(INFO, TAG, "Flag includes OC_REQUEST_FLAG");
@@ -193,10 +198,11 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
         {
             OC_LOG_V (INFO, TAG, "request query %s from client",
                                         entityHandlerRequest->query);
-            OC_LOG_V (INFO, TAG, "request payload %s from client",
-                                        entityHandlerRequest->reqJSONPayload);
+            OC_LOG_PAYLOAD (INFO, TAG, entityHandlerRequest->payload);
+
             // Make deep copy of received request and queue it for slow processing
             request = CopyRequest(entityHandlerRequest);
+
             if (request)
             {
 
@@ -251,7 +257,12 @@ void AlarmHandler(int sig)
         if (entityHandlerRequest->method == OC_REST_GET)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-            ProcessGetRequest (entityHandlerRequest);
+            ProcessGetPutRequest (entityHandlerRequest);
+        }
+        else if (entityHandlerRequest->method == OC_REST_PUT)
+        {
+            OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+            ProcessGetPutRequest (entityHandlerRequest);
         }
         else
         {
@@ -259,9 +270,9 @@ void AlarmHandler(int sig)
                     entityHandlerRequest->method);
         }
         // Free the request
-        OCFree(entityHandlerRequest->query);
-        OCFree(entityHandlerRequest->reqJSONPayload);
-        OCFree(entityHandlerRequest);
+        OICFree(entityHandlerRequest->query);
+        OCPayloadDestroy(entityHandlerRequest->payload);
+        OICFree(entityHandlerRequest);
 
         // If there are more requests in list, re-arm the alarm signal
         if (gRequestList.empty())
@@ -273,32 +284,16 @@ void AlarmHandler(int sig)
 
 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";
-
-
     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;
     }
 
-    /*
-     * Declare and create the example resource: LED
-     */
-    createLEDResource(gResourceUri, &LED, false, 0);
+    // Declare and create the example resource: LED
+    createLEDResource(gResourceUri, &LED, false, 42);
 
     // Initialize slow response alarm
     signal(SIGALRM, AlarmHandler);
@@ -314,7 +309,6 @@ int main(int argc, char* argv[])
             OC_LOG(ERROR, TAG, "OCStack process error");
             return 0;
         }
-
         sleep(2);
     }
 
@@ -325,9 +319,9 @@ int main(int argc, char* argv[])
     {
         for (auto iter = gRequestList.begin(); iter != gRequestList.end(); ++iter)
         {
-            OCFree((*iter)->query);
-            OCFree((*iter)->reqJSONPayload);
-            OCFree(*iter);
+            OICFree((*iter)->query);
+            OCPayloadDestroy((*iter)->payload);
+            OICFree(*iter);
         }
         gRequestList.clear();
     }
@@ -352,11 +346,13 @@ int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState,
     ledResource->power= resourcePower;
     OCStackResult res = OCCreateResource(&(ledResource->handle),
             "core.led",
-            "oc.mi.def",
+            OC_RSRVD_INTERFACE_DEFAULT,
             uri,
             OCEntityHandlerCb,
+            NULL,
             OC_DISCOVERABLE|OC_OBSERVABLE);
     OC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
 
     return 0;
 }
+