[IOT-1645] Resovle the MOT's side effect
authorJongmin Choi <jminl.choi@samsung.com>
Thu, 8 Dec 2016 05:23:53 +0000 (14:23 +0900)
committerRandeep Singh <randeep.s@samsung.com>
Thu, 8 Dec 2016 08:34:16 +0000 (08:34 +0000)
from https://gerrit.iotivity.org/gerrit/#/c/14221/

Change-Id: Ie2ccfbeaae597a89e1e46d9d7e774b631aa686f4
Signed-off-by: Chul Lee <chuls.lee@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/15143
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Joonghwan Lee <jh05.lee@samsung.com>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
(cherry picked from commit 04a8fe396014002d030e10958293e5389875c016)
Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/15159

resource/csdk/security/provisioning/sample/SConscript
resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.dat [new file with mode: 0644]
resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.json [new file with mode: 0644]
resource/csdk/security/provisioning/sample/sampleserver_preconfpin.cpp [new file with mode: 0644]

index 7a4887b..f816c1f 100644 (file)
@@ -1,4 +1,4 @@
-# //******************************************************************
+7# //******************************************************************
 # //
 # // Copyright 2015 Samsung Electronics All Rights Reserved.
 # //
@@ -107,6 +107,7 @@ sampleserver_mvjustworks = provisioning_env.Program('sampleserver_mvjustworks',
 
 if provisioning_env.get('MULTIPLE_OWNER') == '1':
        subownerclient = provisioning_env.Program('subownerclient', 'subownerclient.c')
+       sampleserver_preconfpin = provisioning_env.Program('sampleserver_preconfpin', 'sampleserver_preconfpin.cpp')
 
 if provisioning_env.get('WITH_TCP') == True:
     cloud_src = [
@@ -138,6 +139,8 @@ mvjustworksdat = provisioning_env.Install(sec_provisioning_build_dir,
 if provisioning_env.get('MULTIPLE_OWNER') == '1':
        subownerclientdat = provisioning_env.Install(sec_provisioning_build_dir,
                                                sec_provisioning_src_dir + 'oic_svr_db_subowner_client.dat')
+       preconfserverdat = provisioning_env.Install(sec_provisioning_build_dir,
+                                               sec_provisioning_src_dir + 'oic_svr_db_server_preconfpin.dat')
 
 if provisioning_env.get('WITH_TCP') == True:
     clouddat = provisioning_env.Install(sec_provisioning_build_dir,
diff --git a/resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.dat b/resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.dat
new file mode 100644 (file)
index 0000000..a3dce21
Binary files /dev/null and b/resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.dat differ
diff --git a/resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.json b/resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.json
new file mode 100644 (file)
index 0000000..43eeff1
--- /dev/null
@@ -0,0 +1,79 @@
+{\r
+    "acl": {\r
+        "aclist": {\r
+            "aces": [\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/res",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.res"],\r
+                            "if": ["oic.if.ll"]\r
+                        },{\r
+                            "href": "/oic/d",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.d"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        },{\r
+                            "href": "/oic/p",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.p"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                },\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/sec/doxm",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.doxm"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/pstat",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.pstat"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/acl",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.acl"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/cred",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.cred"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 6\r
+                }\r
+            ]\r
+        },\r
+        "rowneruuid" : "50726563-6F6E-6669-6775-72656450494E"\r
+    },\r
+    "pstat": {\r
+        "isop": false,\r
+        "deviceuuid": "50726563-6F6E-6669-6775-72656450494E",\r
+        "rowneruuid": "50726563-6F6E-6669-6775-72656450494E",\r
+        "cm": 2,\r
+        "tm": 0,\r
+        "om": 4,\r
+        "sm": 4\r
+        },\r
+    "doxm": {\r
+        "oxms": [0, 65280],\r
+        "oxmsel": 0,\r
+        "sct": 1,\r
+        "owned": false,\r
+        "deviceuuid": "50726563-6F6E-6669-6775-72656450494E",\r
+        "devowneruuid": "",\r
+        "rowneruuid": "50726563-6F6E-6669-6775-72656450494E"\r
+    }\r
+}\r
diff --git a/resource/csdk/security/provisioning/sample/sampleserver_preconfpin.cpp b/resource/csdk/security/provisioning/sample/sampleserver_preconfpin.cpp
new file mode 100644 (file)
index 0000000..0e315ec
--- /dev/null
@@ -0,0 +1,482 @@
+/******************************************************************
+*
+* Copyright 2015 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+///////////////////////////////////////////////////////////////////////
+//NOTE :  This sample server is generated based on ocserverbasicops.cpp
+///////////////////////////////////////////////////////////////////////
+#include "iotivity_config.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#include <signal.h>
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "pinoxmcommon.h"
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+/** @todo stop-gap for naming issue. Windows.h does not like us to use ERROR */
+#ifdef ERROR
+#undef ERROR
+#endif //ERROR
+#endif //HAVE_WINDOWS_H
+#include "platform_features.h"
+#include "logger.h"
+
+
+#define TAG "SAMPLE_PRECONF_PIN"
+
+int gQuitFlag = 0;
+
+/* Structure to represent a LED resource */
+typedef struct LEDRESOURCE{
+    OCResourceHandle handle;
+    bool state;
+    int power;
+} LEDResource;
+
+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;
+#define SAMPLE_MAX_NUM_POST_INSTANCE  2
+static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
+
+char *gResourceUri= (char *)"/a/led";
+
+//Secure Virtual Resource database for Iotivity Server
+//It contains Server's Identity and the PSK credentials
+//of other devices which the server trusts
+static char CRED_FILE[] = "oic_svr_db_server_preconfpin.dat";
+
+/* Function that creates a new LED resource by calling the
+ * OCCreateResource() method.
+ */
+int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower);
+
+/* This method converts the payload to JSON format */
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
+
+/* Following methods process the PUT, GET, POST
+ * requests
+ */
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+                                         OCRepPayload **payload);
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+                                         OCRepPayload **payload);
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+                                        OCEntityHandlerResponse *response,
+                                        OCRepPayload **payload);
+
+/* Entity Handler callback functions */
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest,
+        void* callbackParam);
+
+const char *getResult(OCStackResult result) {
+    switch (result) {
+    case OC_STACK_OK:
+        return "OC_STACK_OK";
+    case OC_STACK_RESOURCE_CREATED:
+        return "OC_STACK_RESOURCE_CREATED";
+    case OC_STACK_RESOURCE_DELETED:
+        return "OC_STACK_RESOURCE_DELETED";
+    case OC_STACK_INVALID_URI:
+        return "OC_STACK_INVALID_URI";
+    case OC_STACK_INVALID_QUERY:
+        return "OC_STACK_INVALID_QUERY";
+    case OC_STACK_INVALID_IP:
+        return "OC_STACK_INVALID_IP";
+    case OC_STACK_INVALID_PORT:
+        return "OC_STACK_INVALID_PORT";
+    case OC_STACK_INVALID_CALLBACK:
+        return "OC_STACK_INVALID_CALLBACK";
+    case OC_STACK_INVALID_METHOD:
+        return "OC_STACK_INVALID_METHOD";
+    case OC_STACK_NO_MEMORY:
+        return "OC_STACK_NO_MEMORY";
+    case OC_STACK_COMM_ERROR:
+        return "OC_STACK_COMM_ERROR";
+    case OC_STACK_INVALID_PARAM:
+        return "OC_STACK_INVALID_PARAM";
+    case OC_STACK_NOTIMPL:
+        return "OC_STACK_NOTIMPL";
+    case OC_STACK_NO_RESOURCE:
+        return "OC_STACK_NO_RESOURCE";
+    case OC_STACK_RESOURCE_ERROR:
+        return "OC_STACK_RESOURCE_ERROR";
+    case OC_STACK_SLOW_RESOURCE:
+        return "OC_STACK_SLOW_RESOURCE";
+    case OC_STACK_NO_OBSERVERS:
+        return "OC_STACK_NO_OBSERVERS";
+    #ifdef WITH_PRESENCE
+    case OC_STACK_PRESENCE_STOPPED:
+        return "OC_STACK_PRESENCE_STOPPED";
+    #endif
+    case OC_STACK_ERROR:
+        return "OC_STACK_ERROR";
+    default:
+        return "UNKNOWN";
+    }
+}
+
+OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
+        return NULL;
+    }
+
+    OCRepPayloadSetUri(payload, uri);
+    OCRepPayloadSetPropBool(payload, "state", state);
+    OCRepPayloadSetPropInt(payload, "power", power);
+
+    return payload;
+}
+
+//This function takes the request as an input and returns the response
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest)
+{
+    if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+    {
+        OIC_LOG(ERROR, TAG, "Incoming payload not a representation");
+        return NULL;
+    }
+
+    OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
+
+    LEDResource *currLEDResource = &LED;
+
+    if (ehRequest->resource == gLedInstance[0].handle)
+    {
+        currLEDResource = &gLedInstance[0];
+        gResourceUri = (char *) "/a/led/0";
+    }
+    else if (ehRequest->resource == gLedInstance[1].handle)
+    {
+        currLEDResource = &gLedInstance[1];
+        gResourceUri = (char *) "/a/led/1";
+    }
+
+    if(OC_REST_PUT == ehRequest->method)
+    {
+        // Get pointer to query
+        int64_t pow;
+        if(OCRepPayloadGetPropInt(input, "power", &pow))
+        {
+            currLEDResource->power =pow;
+        }
+
+        bool state;
+        if(OCRepPayloadGetPropBool(input, "state", &state))
+        {
+            currLEDResource->state = state;
+        }
+    }
+
+    return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state);
+}
+
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
+{
+    OCEntityHandlerResult ehResult;
+
+    OCRepPayload *getResp = constructResponse(ehRequest);
+
+    if(getResp)
+    {
+        *payload = getResp;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
+{
+    OCEntityHandlerResult ehResult;
+
+    OCRepPayload *putResp = constructResponse(ehRequest);
+
+    if(putResp)
+    {
+        *payload = putResp;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+        OCEntityHandlerResponse *response, OCRepPayload **payload)
+{
+    OCRepPayload *respPLPost_led = NULL;
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+
+    /*
+     * 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
+     * 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)
+     */
+
+    if (ehRequest->resource == LED.handle)
+    {
+        if (gCurrLedInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
+        {
+            // Create new LED instance
+            char newLedUri[15] = "/a/led/";
+            int newLedUriLength = strlen(newLedUri);
+            snprintf (newLedUri + newLedUriLength, sizeof(newLedUri)-newLedUriLength, "%d", gCurrLedInstance);
+
+            respPLPost_led = OCRepPayloadCreate();
+            OCRepPayloadSetUri(respPLPost_led, gResourceUri);
+            OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri);
+
+            if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0))
+            {
+                OIC_LOG (INFO, TAG, "Created new LED instance");
+                gLedInstance[gCurrLedInstance].state = 0;
+                gLedInstance[gCurrLedInstance].power = 0;
+                gCurrLedInstance++;
+                strncpy ((char *)response->resourceUri, newLedUri, sizeof(response->resourceUri));
+                ehResult = OC_EH_RESOURCE_CREATED;
+            }
+        }
+        else
+        {
+            respPLPost_led = constructResponse(ehRequest);
+        }
+    }
+    else
+    {
+        for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
+        {
+            if (ehRequest->resource == gLedInstance[i].handle)
+            {
+                if (i == 0)
+                {
+                    respPLPost_led = constructResponse(ehRequest);
+                    break;
+                }
+                else if (i == 1)
+                {
+                    respPLPost_led = constructResponse(ehRequest);
+                }
+            }
+        }
+    }
+
+    if (respPLPost_led != NULL)
+    {
+        *payload = respPLPost_led;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        OIC_LOG_V (INFO, TAG, "Payload was NULL");
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest,
+        void* callbackParam)
+{
+    OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
+    (void)callbackParam;
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+    OCEntityHandlerResponse response;
+    memset(&response, 0, sizeof(response));
+
+    // Validate pointer
+    if (!entityHandlerRequest)
+    {
+        OIC_LOG (ERROR, TAG, "Invalid request pointer");
+        return OC_EH_ERROR;
+    }
+
+    OCRepPayload* payload = NULL;
+
+    if (flag & OC_REQUEST_FLAG)
+    {
+        OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
+        if (entityHandlerRequest)
+        {
+            if (OC_REST_GET == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
+                ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
+            }
+            else if (OC_REST_PUT == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+                ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
+            }
+            else if (OC_REST_POST == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
+                ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
+            }
+            else
+            {
+                OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
+                        entityHandlerRequest->method);
+                ehResult = OC_EH_ERROR;
+            }
+
+            if (ehResult == OC_EH_OK && 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 = (OCPayload*)(payload);
+                response.numSendVendorSpecificHeaderOptions = 0;
+                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;
+
+                // Send the response
+                if (OCDoResponse(&response) != OC_STACK_OK)
+                {
+                    OIC_LOG(ERROR, TAG, "Error sending response");
+                    ehResult = OC_EH_ERROR;
+                }
+            }
+        }
+    }
+
+    OCPayloadDestroy(response.payload);
+    return ehResult;
+}
+
+/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
+void handleSigInt(int signum)
+{
+    if (signum == SIGINT)
+    {
+        gQuitFlag = 1;
+    }
+}
+
+FILE* server_fopen(const char *path, const char *mode)
+{
+    (void)path;
+    return fopen(CRED_FILE, mode);
+}
+
+int main()
+{
+    struct timespec timeout;
+
+    OIC_LOG(DEBUG, TAG, "OCServer is starting...");
+
+    // Initialize Persistent Storage for SVR database
+    OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
+
+    OCRegisterPersistentStorageHandler(&ps);
+
+    if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack init error");
+        return 0;
+    }
+
+    /*
+     * Declare and create the example resource: LED
+     */
+    createLEDResource(gResourceUri, &LED, false, 0);
+
+    timeout.tv_sec  = 0;
+    timeout.tv_nsec = 100000000L;
+
+    // Break from loop with Ctrl-C
+    OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
+    signal(SIGINT, handleSigInt);
+    while (!gQuitFlag)
+    {
+        if (OCProcess() != OC_STACK_OK)
+        {
+            OIC_LOG(ERROR, TAG, "OCStack process error");
+            return 0;
+        }
+        nanosleep(&timeout, NULL);
+    }
+
+    OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
+
+    if (OCStop() != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack process error");
+    }
+
+    return 0;
+}
+
+int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower)
+{
+    if (!uri)
+    {
+        OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
+        return -1;
+    }
+
+    ledResource->state = resourceState;
+    ledResource->power= resourcePower;
+    OCStackResult res = OCCreateResource(&(ledResource->handle),
+            "core.led",
+            OC_RSRVD_INTERFACE_DEFAULT,
+            uri,
+            OCEntityHandlerCb,
+            NULL,
+            OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE);
+    OIC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
+
+    return 0;
+}