Merge branch 'master' into 'security-basecamp' 13/2113/1
authorSachin Agrawal <sachin.agrawal@intel.com>
Wed, 5 Aug 2015 07:14:02 +0000 (00:14 -0700)
committerSachin Agrawal <sachin.agrawal@intel.com>
Wed, 5 Aug 2015 07:14:02 +0000 (00:14 -0700)
Conflicts:
auto_build.sh
resource/csdk/security/include/internal/srmresourcestrings.h
resource/csdk/security/src/srmresourcestrings.c
resource/csdk/security/unittest/pstatresource.cpp
resource/csdk/stack/src/ocstack.c

Change-Id: I16af21ba19da38a5d0ec6d6ba0c236308f394676
Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
13 files changed:
1  2 
resource/csdk/connectivity/api/cainterface.h
resource/csdk/connectivity/inc/caadapternetdtls.h
resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c
resource/csdk/security/SConscript
resource/csdk/security/include/internal/srmresourcestrings.h
resource/csdk/security/src/amaclresource.c
resource/csdk/security/src/resourcemanager.c
resource/csdk/security/src/secureresourcemanager.c
resource/csdk/security/src/srmresourcestrings.c
resource/csdk/security/src/svcresource.c
resource/csdk/security/unittest/aclresourcetest.cpp
resource/csdk/security/unittest/pstatresource.cpp
resource/csdk/stack/src/ocstack.c

Simple merge
  extern const char * SVR_DB_FILE_NAME;
  extern const char * OIC_MI_DEF;
  
- extern const char * OIC_RSRC_CORE_URI;
- extern const char * OIC_RSRC_CORE_D_URI;
- extern const char * OIC_RSRC_CORE_P_URI;
- extern const char * OIC_RSRC_PRESENCE_URI;
- extern const char * OIC_RSRC_TYPES_D_URI;
 +//AMACL
 +extern const char * OIC_RSRC_TYPE_SEC_AMACL;
 +extern const char * OIC_RSRC_AMACL_URI;
 +extern const char * OIC_JSON_AMACL_NAME;
 +
  //ACL
  extern const char * OIC_RSRC_TYPE_SEC_ACL;
  extern const char * OIC_RSRC_ACL_URI;
index e34b6bd,0000000..89e3791
mode 100644,000000..100644
--- /dev/null
@@@ -1,402 -1,0 +1,403 @@@
-             int i = 0;
 +//******************************************************************
 +//
 +// Copyright 2015 Intel Mobile Communications GmbH 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.
 +//
 +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 +
 +
 +#include <stdlib.h>
 +#include <string.h>
 +#include "ocstack.h"
 +#include "logger.h"
 +#include "oic_malloc.h"
 +#include "oic_string.h"
 +#include "cJSON.h"
 +#include "base64.h"
 +#include "resourcemanager.h"
 +#include "psinterface.h"
 +#include "utlist.h"
 +#include "srmresourcestrings.h"
 +#include "amaclresource.h"
 +#include "srmutility.h"
 +#include <stdlib.h>
 +#include <string.h>
 +
 +#define TAG  PCF("SRM-AMACL")
 +
 +OicSecAmacl_t *gAmacl = NULL;
 +static OCResourceHandle gAmaclHandle = NULL;
 +
 +void DeleteAmaclList(OicSecAmacl_t* amacl)
 +{
 +    if (amacl)
 +    {
 +        OicSecAmacl_t *amaclTmp1 = NULL, *amaclTmp2 = NULL;
 +        LL_FOREACH_SAFE(amacl, amaclTmp1, amaclTmp2)
 +        {
-             for (int i = 0; i < amacl->resourcesLen; i++)
++            unsigned int i = 0;
 +
 +            LL_DELETE(amacl, amaclTmp1);
 +
 +            // Clean Resources
 +            for (i = 0; i < amaclTmp1->resourcesLen; i++)
 +            {
 +                OICFree(amaclTmp1->resources[i]);
 +            }
 +            OICFree(amaclTmp1->resources);
 +
 +            // Clean Amss
 +            OICFree(amaclTmp1->amss);
 +
 +            // Clean Owners
 +            OICFree(amaclTmp1->owners);
 +
 +            // Clean Amacl node itself
 +            OICFree(amaclTmp1);
 +        }
 +    }
 +}
 +
 +/*
 + * This internal method converts AMACL data into JSON format.
 + *
 + * Note: Caller needs to invoke 'free' when finished using the return string.
 + */
 +char * BinToAmaclJSON(const OicSecAmacl_t * amacl)
 +{
 +    cJSON *jsonRoot = NULL;
 +    char *jsonStr = NULL;
 +
 +    if (amacl)
 +    {
 +        jsonRoot = cJSON_CreateObject();
 +        VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
 +
 +        cJSON *jsonAmaclArray = NULL;
 +        cJSON_AddItemToObject (jsonRoot, OIC_JSON_AMACL_NAME, jsonAmaclArray = cJSON_CreateArray());
 +        VERIFY_NON_NULL(TAG, jsonAmaclArray, ERROR);
 +
 +        while(amacl)
 +        {
 +            char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
 +            uint32_t outLen = 0;
 +            B64Result b64Ret = B64_OK;
 +
 +            cJSON *jsonAmacl = cJSON_CreateObject();
 +
 +            // Resources -- Mandatory
 +            cJSON *jsonRsrcArray = NULL;
 +            cJSON_AddItemToObject(jsonAmacl, OIC_JSON_RESOURCES_NAME, jsonRsrcArray =
 +                    cJSON_CreateArray());
 +            VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR);
-             for (int i = 0; i < amacl->amssLen; i++)
++            for (unsigned int i = 0; i < amacl->resourcesLen; i++)
 +            {
 +                cJSON_AddItemToArray(jsonRsrcArray, cJSON_CreateString(amacl->resources[i]));
 +            }
 +
 +            // Amss -- Mandatory
 +            cJSON *jsonAmsArray = NULL;
 +            cJSON_AddItemToObject(jsonAmacl, OIC_JSON_AMSS_NAME, jsonAmsArray =
 +                    cJSON_CreateArray());
 +            VERIFY_NON_NULL(TAG, jsonAmsArray, ERROR);
-             for (int i = 0; i < amacl->ownersLen; i++)
++            for (unsigned int i = 0; i < amacl->amssLen; i++)
 +            {
 +                outLen = 0;
 +
 +                b64Ret = b64Encode(amacl->amss[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
 +                        sizeof(base64Buff), &outLen);
 +                VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
 +
 +                cJSON_AddItemToArray(jsonAmsArray, cJSON_CreateString(base64Buff));
 +            }
 +
 +            // Owners -- Mandatory
 +            cJSON *jsonOwnrArray = NULL;
 +            cJSON_AddItemToObject(jsonAmacl, OIC_JSON_OWNERS_NAME, jsonOwnrArray =
 +                    cJSON_CreateArray());
 +            VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
-     VERIFY_NON_NULL(TAG, jsonAmaclArray, ERROR);
++            for (unsigned int i = 0; i < amacl->ownersLen; i++)
 +            {
 +                outLen = 0;
 +
 +                b64Ret = b64Encode(amacl->owners[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
 +                        sizeof(base64Buff), &outLen);
 +                VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
 +
 +                cJSON_AddItemToArray(jsonOwnrArray, cJSON_CreateString(base64Buff));
 +            }
 +
 +            // Attach current amacl node to Amacl Array
 +            cJSON_AddItemToArray(jsonAmaclArray, jsonAmacl);
 +            amacl = amacl->next;
 +        }
 +
 +        jsonStr = cJSON_PrintUnformatted(jsonRoot);
 +    }
 +
 +exit:
 +    if (jsonRoot)
 +    {
 +        cJSON_Delete(jsonRoot);
 +    }
 +    return jsonStr;
 +}
 +
 +
 +
 +
 +/*
 + * This internal method converts JSON AMACL into binary AMACL.
 + */
 +OicSecAmacl_t * JSONToAmaclBin(const char * jsonStr)
 +{
 +    OCStackResult ret = OC_STACK_ERROR;
 +    OicSecAmacl_t * headAmacl = NULL;
 +    OicSecAmacl_t * prevAmacl = NULL;
 +    cJSON *jsonRoot = NULL;
 +    cJSON *jsonAmaclArray = NULL;
 +
 +    VERIFY_NON_NULL(TAG, jsonStr, ERROR);
 +
 +    jsonRoot = cJSON_Parse(jsonStr);
 +    VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
 +
 +    jsonAmaclArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME);
-     OicSecAmacl_t* newAmacl = JSONToAmaclBin((char *)(ehRequest->reqJSONPayload));
++    VERIFY_NON_NULL(TAG, jsonAmaclArray, INFO);
 +
 +    if (cJSON_Array == jsonAmaclArray->type)
 +    {
 +        int numAmacl = cJSON_GetArraySize(jsonAmaclArray);
 +        int idx = 0;
 +
 +        VERIFY_SUCCESS(TAG, numAmacl > 0, INFO);
 +        do
 +        {
 +            cJSON *jsonAmacl = cJSON_GetArrayItem(jsonAmaclArray, idx);
 +            VERIFY_NON_NULL(TAG, jsonAmacl, ERROR);
 +
 +            OicSecAmacl_t *amacl = (OicSecAmacl_t*)OICCalloc(1, sizeof(OicSecAmacl_t));
 +            VERIFY_NON_NULL(TAG, amacl, ERROR);
 +
 +            headAmacl = (headAmacl) ? headAmacl : amacl;
 +            if (prevAmacl)
 +            {
 +                prevAmacl->next = amacl;
 +            }
 +
 +            size_t jsonObjLen = 0;
 +            cJSON *jsonObj = NULL;
 +
 +            // Resources -- Mandatory
 +            jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_RESOURCES_NAME);
 +            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
 +            VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
 +
 +            amacl->resourcesLen = cJSON_GetArraySize(jsonObj);
 +            VERIFY_SUCCESS(TAG, amacl->resourcesLen > 0, ERROR);
 +            amacl->resources = (char**)OICCalloc(amacl->resourcesLen, sizeof(char*));
 +            VERIFY_NON_NULL(TAG, (amacl->resources), ERROR);
 +
 +            int idxx = 0;
 +            do
 +            {
 +                cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
 +                VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
 +
 +                jsonObjLen = strlen(jsonRsrc->valuestring) + 1;
 +                amacl->resources[idxx] = (char*)OICMalloc(jsonObjLen);
 +                VERIFY_NON_NULL(TAG, (amacl->resources[idxx]), ERROR);
 +                OICStrcpy(amacl->resources[idxx], jsonObjLen, jsonRsrc->valuestring);
 +            } while ( ++idxx < amacl->resourcesLen);
 +
 +            // Amss -- Mandatory
 +            VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_AMSS_NAME,
 +                               &(amacl->amssLen), &(amacl->amss)), ERROR);
 +
 +            // Owners -- Mandatory
 +            VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_OWNERS_NAME,
 +                               &(amacl->ownersLen), &(amacl->owners)), ERROR);
 +
 +            prevAmacl = amacl;
 +        } while( ++idx < numAmacl);
 +    }
 +
 +    ret = OC_STACK_OK;
 +
 +exit:
 +    cJSON_Delete(jsonRoot);
 +    if (OC_STACK_OK != ret)
 +    {
 +        DeleteAmaclList(headAmacl);
 +        headAmacl = NULL;
 +    }
 +    return headAmacl;
 +}
 +
 +static OCEntityHandlerResult HandleAmaclGetRequest (const OCEntityHandlerRequest * ehRequest)
 +{
 +    // Convert Amacl data into JSON for transmission
 +    char* jsonStr = BinToAmaclJSON(gAmacl);
 +
 +    OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
 +
 +    // Send response payload to request originator
 +    SendSRMResponse(ehRequest, ehRet, jsonStr);
 +
 +    OICFree(jsonStr);
 +
 +    OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
 +    return ehRet;
 +}
 +
 +static OCEntityHandlerResult HandleAmaclPostRequest (const OCEntityHandlerRequest * ehRequest)
 +{
 +    OCEntityHandlerResult ehRet = OC_EH_ERROR;
 +
 +    // Convert JSON Amacl data into binary. This will also validate the Amacl data received.
++    OicSecAmacl_t* newAmacl = JSONToAmaclBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
 +
 +    if (newAmacl)
 +    {
 +        // Append the new Amacl to existing Amacl
 +        LL_APPEND(gAmacl, newAmacl);
 +
 +        // Convert Amacl data into JSON for update to persistent storage
 +        char *jsonStr = BinToAmaclJSON(gAmacl);
 +        if (jsonStr)
 +        {
 +            cJSON *jsonAmacl = cJSON_Parse(jsonStr);
 +            OICFree(jsonStr);
 +
 +            if ((jsonAmacl) &&
 +                (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_AMACL_NAME, jsonAmacl)))
 +            {
 +                ehRet = OC_EH_RESOURCE_CREATED;
 +            }
 +            cJSON_Delete(jsonAmacl);
 +        }
 +    }
 +
 +    // Send payload to request originator
 +    SendSRMResponse(ehRequest, ehRet, NULL);
 +
 +    OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
 +    return ehRet;
 +}
 +
 +/*
 + * This internal method is the entity handler for Amacl resources and
 + * will handle REST request (GET/PUT/POST/DEL) for them.
 + */
 +OCEntityHandlerResult AmaclEntityHandler (OCEntityHandlerFlag flag,
 +                                          OCEntityHandlerRequest * ehRequest,
 +                                          void* callbackParameter)
 +{
++    (void) callbackParameter;
 +    OCEntityHandlerResult ehRet = OC_EH_ERROR;
 +
 +    if (!ehRequest)
 +    {
 +        return ehRet;
 +    }
 +
 +    if (flag & OC_REQUEST_FLAG)
 +    {
 +        OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
 +        switch (ehRequest->method)
 +        {
 +            case OC_REST_GET:
 +                ehRet = HandleAmaclGetRequest(ehRequest);
 +                break;
 +
 +            case OC_REST_POST:
 +                ehRet = HandleAmaclPostRequest(ehRequest);
 +                break;
 +
 +            default:
 +                ehRet = OC_EH_ERROR;
 +                SendSRMResponse(ehRequest, ehRet, NULL);
 +        }
 +    }
 +
 +    return ehRet;
 +}
 +
 +/*
 + * This internal method is used to create '/oic/sec/amacl' resource.
 + */
 +OCStackResult CreateAmaclResource()
 +{
 +    OCStackResult ret;
 +
 +    ret = OCCreateResource(&gAmaclHandle,
 +                           OIC_RSRC_TYPE_SEC_AMACL,
 +                           OIC_MI_DEF,
 +                           OIC_RSRC_AMACL_URI,
 +                           AmaclEntityHandler,
 +                           NULL,
 +                           OC_OBSERVABLE);
 +
 +    if (OC_STACK_OK != ret)
 +    {
 +        OC_LOG (FATAL, TAG, PCF("Unable to instantiate Amacl resource"));
 +        DeInitAmaclResource();
 +    }
 +    return ret;
 +}
 +
 +/**
 + * Initialize Amacl resource by loading data from persistent storage.
 + *
 + * @retval  OC_STACK_OK for Success, otherwise some error value
 + */
 +OCStackResult InitAmaclResource()
 +{
 +    OCStackResult ret = OC_STACK_ERROR;
 +
 +    // Read Amacl resource from PS
 +    char* jsonSVRDatabase = GetSVRDatabase();
 +
 +    if (jsonSVRDatabase)
 +    {
 +        // Convert JSON Amacl into binary format
 +        gAmacl = JSONToAmaclBin(jsonSVRDatabase);
 +        OICFree(jsonSVRDatabase);
 +    }
 +
 +    // Instantiate 'oic/sec/amacl' resource
 +    ret = CreateAmaclResource();
 +
 +    if (OC_STACK_OK != ret)
 +    {
 +        DeInitAmaclResource();
 +    }
 +    return ret;
 +}
 +
 +/**
 + * Perform cleanup for Amacl resources.
 + *
 + * @retval  none
 + */
 +void DeInitAmaclResource()
 +{
 +    OCDeleteResource(gAmaclHandle);
 +    gAmaclHandle = NULL;
 +
 +    DeleteAmaclList(gAmacl);
 +    gAmacl = NULL;
 +}
  #include "pstatresource.h"
  #include "doxmresource.h"
  #include "credresource.h"
 +#include "svcresource.h"
 +#include "amaclresource.h"
  #include "oic_malloc.h"
+ #include "oic_string.h"
  #include "logger.h"
  #include "utlist.h"
  #include <string.h>
@@@ -236,7 -236,7 +236,6 @@@ OCStackResult SRMRegisterPersistentStor
  
  OCPersistentStorage* SRMGetPersistentStorageHandler()
  {
--    OC_LOG(INFO, TAG, PCF("SRMGetPersistentStorageHandler !!"));
      return gPersistentStorageHandler;
  }
  
  const char * SVR_DB_FILE_NAME = "oic_svr_db.json";
  const char * OIC_MI_DEF = "oic.mi.def";
  
- const char * OIC_RSRC_CORE_URI =  "/oic/res";
- const char * OIC_RSRC_CORE_D_URI =  "/oic/res/d";
- const char * OIC_RSRC_CORE_P_URI =  "/oic/p";
- const char * OIC_RSRC_PRESENCE_URI =  "/oic/ad";
- const char * OIC_RSRC_TYPES_D_URI =  "/oic/res/types/d";
 +//AMACL
 +const char * OIC_RSRC_TYPE_SEC_AMACL = "oic.sec.amacl";
 +const char * OIC_RSRC_AMACL_URI =  "/oic/sec/amacl";
 +const char * OIC_JSON_AMACL_NAME = "amacl";
 +
  //ACL
  const char * OIC_RSRC_TYPE_SEC_ACL = "oic.sec.acl";
  const char * OIC_RSRC_ACL_URI =  "/oic/sec/acl";
index 21db59d,0000000..890dcbc
mode 100644,000000..100644
--- /dev/null
@@@ -1,382 -1,0 +1,383 @@@
-             for (int i = 0; i < svc->ownersLen; i++)
 +//******************************************************************
 +//
 +// Copyright 2015 Intel Mobile Communications GmbH 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.
 +//
 +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 +
 +#include "ocstack.h"
 +#include "logger.h"
 +#include "oic_malloc.h"
 +#include "cJSON.h"
 +#include "base64.h"
 +#include "resourcemanager.h"
 +#include "psinterface.h"
 +#include "svcresource.h"
 +#include "utlist.h"
 +#include "srmresourcestrings.h"
 +#include "srmutility.h"
 +#include <stdlib.h>
 +#include <string.h>
 +
 +#define TAG  PCF("SRM-SVC")
 +
 +OicSecSvc_t        *gSvc = NULL;
 +static OCResourceHandle    gSvcHandle = NULL;
 +
 +void DeleteSVCList(OicSecSvc_t* svc)
 +{
 +    if (svc)
 +    {
 +        OicSecSvc_t *svcTmp1 = NULL, *svcTmp2 = NULL;
 +        LL_FOREACH_SAFE(svc, svcTmp1, svcTmp2)
 +        {
 +            LL_DELETE(svc, svcTmp1);
 +
 +            // Clean Owners
 +            OICFree(svcTmp1->owners);
 +
 +            // Clean SVC node itself
 +            OICFree(svcTmp1);
 +        }
 +    }
 +}
 +
 +/*
 + * This internal method converts SVC data into JSON format.
 + *
 + * Note: Caller needs to invoke 'free' when finished done using
 + * return string.
 + */
 +char * BinToSvcJSON(const OicSecSvc_t * svc)
 +{
 +    cJSON *jsonRoot = NULL;
 +    char *jsonStr = NULL;
 +
 +    if (svc)
 +    {
 +        jsonRoot = cJSON_CreateObject();
 +        VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
 +
 +        cJSON *jsonSvcArray = NULL;
 +        cJSON_AddItemToObject (jsonRoot, OIC_JSON_SVC_NAME, jsonSvcArray = cJSON_CreateArray());
 +        VERIFY_NON_NULL(TAG, jsonSvcArray, ERROR);
 +
 +        while(svc)
 +        {
 +            char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
 +            uint32_t outLen = 0;
 +            B64Result b64Ret = B64_OK;
 +
 +            cJSON *jsonSvc = cJSON_CreateObject();
 +
 +            // Service Device Identity
 +            outLen = 0;
 +            b64Ret = b64Encode(svc->svcdid.id, sizeof(OicUuid_t), base64Buff,
 +                    sizeof(base64Buff), &outLen);
 +            VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
 +            cJSON_AddStringToObject(jsonSvc, OIC_JSON_SERVICE_DEVICE_ID, base64Buff );
 +
 +            // Service Type
 +            cJSON_AddNumberToObject (jsonSvc, OIC_JSON_SERVICE_TYPE, svc->svct);
 +
 +            // Owners
 +            cJSON *jsonOwnrArray = NULL;
 +            cJSON_AddItemToObject (jsonSvc, OIC_JSON_OWNERS_NAME, jsonOwnrArray = cJSON_CreateArray());
 +            VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
-     VERIFY_NON_NULL(TAG, jsonSvcArray, ERROR);
++            for (unsigned int i = 0; i < svc->ownersLen; i++)
 +            {
 +                outLen = 0;
 +
 +                b64Ret = b64Encode(svc->owners[i].id, sizeof(((OicUuid_t*)0)->id), base64Buff,
 +                        sizeof(base64Buff), &outLen);
 +                VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
 +
 +                cJSON_AddItemToArray (jsonOwnrArray, cJSON_CreateString(base64Buff));
 +            }
 +
 +            // Attach current svc node to Svc Array
 +            cJSON_AddItemToArray(jsonSvcArray, jsonSvc);
 +            svc = svc->next;
 +        }
 +
 +        jsonStr = cJSON_PrintUnformatted(jsonRoot);
 +    }
 +
 +exit:
 +    if (jsonRoot)
 +    {
 +        cJSON_Delete(jsonRoot);
 +    }
 +    return jsonStr;
 +}
 +
 +/*
 + * This internal method converts JSON SVC into binary SVC.
 + */
 +OicSecSvc_t * JSONToSvcBin(const char * jsonStr)
 +{
 +    OCStackResult ret = OC_STACK_ERROR;
 +    OicSecSvc_t * headSvc = NULL;
 +    OicSecSvc_t * prevSvc = NULL;
 +    cJSON *jsonRoot = NULL;
 +    cJSON *jsonSvcArray = NULL;
 +
 +    VERIFY_NON_NULL(TAG, jsonStr, ERROR);
 +
 +    jsonRoot = cJSON_Parse(jsonStr);
 +    VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
 +
 +    jsonSvcArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_SVC_NAME);
-     OicSecSvc_t* newSvc = JSONToSvcBin((char *)(ehRequest->reqJSONPayload));
++    VERIFY_NON_NULL(TAG, jsonSvcArray, INFO);
 +
 +    if (cJSON_Array == jsonSvcArray->type)
 +    {
 +        int numSvc = cJSON_GetArraySize(jsonSvcArray);
 +        int idx = 0;
 +
 +        VERIFY_SUCCESS(TAG, numSvc > 0, INFO);
 +        do
 +        {
 +            cJSON *jsonSvc = cJSON_GetArrayItem(jsonSvcArray, idx);
 +            VERIFY_NON_NULL(TAG, jsonSvc, ERROR);
 +
 +            OicSecSvc_t *svc = (OicSecSvc_t*)OICCalloc(1, sizeof(OicSecSvc_t));
 +            VERIFY_NON_NULL(TAG, svc, ERROR);
 +
 +            headSvc = (headSvc) ? headSvc : svc;
 +            if (prevSvc)
 +            {
 +                prevSvc->next = svc;
 +            }
 +
 +            cJSON *jsonObj = NULL;
 +
 +            unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
 +            uint32_t outLen = 0;
 +            B64Result b64Ret = B64_OK;
 +
 +            // Service Device Identity
 +            jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_DEVICE_ID);
 +            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
 +            VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
 +            outLen = 0;
 +            b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
 +                        sizeof(base64Buff), &outLen);
 +            VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->svcdid.id)), ERROR);
 +            memcpy(svc->svcdid.id, base64Buff, outLen);
 +
 +            // Service Type
 +            jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_TYPE);
 +            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
 +            VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
 +            svc->svct = (OicSecSvcType_t)jsonObj->valueint;
 +
 +            // Resource Owners
 +            jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_OWNERS_NAME);
 +            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
 +            VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
 +
 +            svc->ownersLen = cJSON_GetArraySize(jsonObj);
 +            VERIFY_SUCCESS(TAG, svc->ownersLen > 0, ERROR);
 +            svc->owners = (OicUuid_t*)OICCalloc(svc->ownersLen, sizeof(OicUuid_t));
 +            VERIFY_NON_NULL(TAG, (svc->owners), ERROR);
 +
 +            int idxx = 0;
 +            do
 +            {
 +                cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, idxx);
 +                VERIFY_NON_NULL(TAG, jsonOwnr, ERROR);
 +                VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR);
 +
 +                outLen = 0;
 +                b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff,
 +                            sizeof(base64Buff), &outLen);
 +
 +                VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->owners[idxx].id)),
 +                                    ERROR);
 +                memcpy(svc->owners[idxx].id, base64Buff, outLen);
 +            } while ( ++idxx < svc->ownersLen);
 +
 +            prevSvc = svc;
 +        } while( ++idx < numSvc);
 +    }
 +
 +    ret = OC_STACK_OK;
 +
 +exit:
 +    cJSON_Delete(jsonRoot);
 +    if (OC_STACK_OK != ret)
 +    {
 +        DeleteSVCList(headSvc);
 +        headSvc = NULL;
 +    }
 +    return headSvc;
 +}
 +
 +static OCEntityHandlerResult HandleSVCGetRequest (const OCEntityHandlerRequest * ehRequest)
 +{
 +    // Convert SVC data into JSON for transmission
 +    char* jsonStr = BinToSvcJSON(gSvc);
 +
 +    OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
 +
 +    // Send response payload to request originator
 +    SendSRMResponse(ehRequest, ehRet, jsonStr);
 +
 +    OICFree(jsonStr);
 +
 +    OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
 +    return ehRet;
 +}
 +
 +static OCEntityHandlerResult HandleSVCPostRequest (const OCEntityHandlerRequest * ehRequest)
 +{
 +    OCEntityHandlerResult ehRet = OC_EH_ERROR;
 +
 +    // Convert JSON SVC data into binary. This will also validate the SVC data received.
++    OicSecSvc_t* newSvc = JSONToSvcBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
 +
 +    if (newSvc)
 +    {
 +        // Append the new SVC to existing SVC
 +        LL_APPEND(gSvc, newSvc);
 +
 +        // Convert SVC data into JSON for update to persistent storage
 +        char *jsonStr = BinToSvcJSON(gSvc);
 +        if (jsonStr)
 +        {
 +            cJSON *jsonSvc = cJSON_Parse(jsonStr);
 +            OICFree(jsonStr);
 +
 +            if ((jsonSvc) &&
 +                (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_SVC_NAME, jsonSvc)))
 +            {
 +                ehRet = OC_EH_RESOURCE_CREATED;
 +            }
 +            cJSON_Delete(jsonSvc);
 +        }
 +    }
 +
 +    // Send payload to request originator
 +    SendSRMResponse(ehRequest, ehRet, NULL);
 +
 +    OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
 +    return ehRet;
 +}
 +
 +/*
 + * This internal method is the entity handler for SVC resources and
 + * will handle REST request (GET/PUT/POST/DEL) for them.
 + */
 +OCEntityHandlerResult SVCEntityHandler (OCEntityHandlerFlag flag,
 +                                        OCEntityHandlerRequest * ehRequest,
 +                                        void* callbackParameter)
 +{
++    (void) callbackParameter;
 +    OCEntityHandlerResult ehRet = OC_EH_ERROR;
 +
 +    if (!ehRequest)
 +    {
 +        return ehRet;
 +    }
 +
 +    if (flag & OC_REQUEST_FLAG)
 +    {
 +        switch (ehRequest->method)
 +        {
 +            case OC_REST_GET:
 +                ehRet = HandleSVCGetRequest(ehRequest);
 +                break;
 +
 +            case OC_REST_POST:
 +                ehRet = HandleSVCPostRequest(ehRequest);
 +                break;
 +
 +            default:
 +                ehRet = OC_EH_ERROR;
 +                SendSRMResponse(ehRequest, ehRet, NULL);
 +        }
 +    }
 +
 +    return ehRet;
 +}
 +
 +/*
 + * This internal method is used to create '/oic/sec/svc' resource.
 + */
 +OCStackResult CreateSVCResource()
 +{
 +    OCStackResult ret;
 +
 +    ret = OCCreateResource(&gSvcHandle,
 +                           OIC_RSRC_TYPE_SEC_SVC,
 +                           OIC_MI_DEF,
 +                           OIC_RSRC_SVC_URI,
 +                           SVCEntityHandler,
 +                           NULL,
 +                           OC_OBSERVABLE);
 +
 +    if (OC_STACK_OK != ret)
 +    {
 +        OC_LOG (FATAL, TAG, PCF("Unable to instantiate SVC resource"));
 +        DeInitSVCResource();
 +    }
 +    return ret;
 +}
 +
 +
 +OCStackResult InitSVCResource()
 +{
 +    OCStackResult ret = OC_STACK_ERROR;
 +
 +    OC_LOG_V (INFO, TAG, PCF("Begin %s "), __func__ );
 +
 +    // Read SVC resource from PS
 +    char* jsonSVRDatabase = GetSVRDatabase();
 +
 +    if (jsonSVRDatabase)
 +    {
 +        // Convert JSON SVC into binary format
 +        gSvc = JSONToSvcBin(jsonSVRDatabase);
 +        OICFree(jsonSVRDatabase);
 +    }
 +
 +    // Instantiate 'oic.sec.svc'
 +    ret = CreateSVCResource();
 +
 +    if (OC_STACK_OK != ret)
 +    {
 +        DeInitSVCResource();
 +    }
 +
 +    OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ret);
 +    return ret;
 +}
 +
 +/**
 + * Perform cleanup for SVC resources.
 + *
 + * @retval  none
 + */
 +void DeInitSVCResource()
 +{
 +    OCDeleteResource(gSvcHandle);
 +    gSvcHandle = NULL;
 +
 +    DeleteSVCList(gSvc);
 +    gSvc = NULL;
 +}
 +
@@@ -27,7 -27,7 +27,8 @@@
  #include "base64.h"
  #include "cainterface.h"
  #include "secureresourcemanager.h"
 +#include "srmtestcommon.h"
+ #include "ocpayload.h"
  #include <unistd.h>
  #ifdef __cplusplus
  extern "C" {
Simple merge