CBOR rebase onto master for merge/review 13/1613/12
authorOmkar Hegde <omkar.m.hegde@intel.com>
Fri, 10 Jul 2015 21:41:46 +0000 (14:41 -0700)
committerErich Keane <erich.keane@intel.com>
Tue, 14 Jul 2015 20:03:42 +0000 (20:03 +0000)
The CA layer has been converted to use binary data, rather
than string data to support CBOR as a transport.  The CSDK has
been changed to use the OCPlatform object model instead of json
strings.  Underneath this, the JSON encoding has been replaced
with CBOR.

Also, some of the previous blockwise transfer functionality has
been removed, since the blockwise-transfer functionality has been
pushed ot the CA stack.

Change-Id: I6423a5180643cea3d311ec7497b246117f7c02b0
Signed-off-by: Erich Keane <erich.keane@intel.com>
Signed-off-by: Omkar Hegde <omkar.m.hegde@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1613
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
88 files changed:
.gitignore
NOTICE.md
Readme.scons.txt
android/android_api/base/jni/JniOcRepresentation.cpp
android/android_api/base/jni/JniOcRepresentation.h
build_common/external_libs.scons
examples/OICMiddle/LineInput.cpp
examples/OICMiddle/WrapResource.cpp
extlibs/buildDependencies.sh
extlibs/cereal/SConscript [deleted file]
extlibs/tinycbor/SConscript [new file with mode: 0644]
extra_options.scons
gbsbuild.sh
resource/c_common/oic_malloc/include/oic_malloc.h
resource/c_common/oic_malloc/src/oic_malloc.c
resource/csdk/SConscript
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/common/src/caremotehandler.c
resource/csdk/connectivity/inc/caprotocolmessage.h
resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c
resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h
resource/csdk/connectivity/samples/arduino/casample.cpp
resource/csdk/connectivity/src/camessagehandler.c
resource/csdk/connectivity/src/caprotocolmessage.c
resource/csdk/connectivity/test/ca_api_unittest.cpp
resource/csdk/security/provisioning/SConscript
resource/csdk/security/provisioning/src/provisioningmanager.c
resource/csdk/security/src/aclresource.c
resource/csdk/security/src/credresource.c
resource/csdk/security/src/doxmresource.c
resource/csdk/security/src/pstatresource.c
resource/csdk/security/src/resourcemanager.c
resource/csdk/security/unittest/aclresourcetest.cpp
resource/csdk/security/unittest/pstatresource.cpp
resource/csdk/stack/include/internal/ocobserve.h
resource/csdk/stack/include/internal/ocpayloadcbor.h [new file with mode: 0644]
resource/csdk/stack/include/internal/ocresource.h
resource/csdk/stack/include/internal/ocresourcehandler.h
resource/csdk/stack/include/internal/ocserverrequest.h
resource/csdk/stack/include/internal/ocstackinternal.h
resource/csdk/stack/include/ocpayload.h [new file with mode: 0644]
resource/csdk/stack/include/ocpresence.h [new file with mode: 0644]
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/include/ocstackconfig.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/samples/arduino/SimpleClientServer/ocserver/ocserver.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlientbasicops.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlientcoll.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlientslow.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlientslow.h
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.h
resource/csdk/stack/samples/linux/SimpleClientServer/ocserverbasicops.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserverbasicops.h
resource/csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserverslow.cpp
resource/csdk/stack/samples/linux/secure/SConscript
resource/csdk/stack/samples/linux/secure/occlientbasicops.cpp
resource/csdk/stack/samples/linux/secure/ocserverbasicops.cpp
resource/csdk/stack/samples/linux/secure/ocserverbasicops.h
resource/csdk/stack/src/occlientcb.c
resource/csdk/stack/src/occollection.c
resource/csdk/stack/src/ocobserve.c
resource/csdk/stack/src/ocpayload.c [new file with mode: 0644]
resource/csdk/stack/src/ocpayloadconvert.c [new file with mode: 0644]
resource/csdk/stack/src/ocpayloadparse.c [new file with mode: 0644]
resource/csdk/stack/src/ocresource.c
resource/csdk/stack/src/ocserverrequest.c
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/src/oicgroup.c
resource/csdk/stack/test/stacktests.cpp
resource/include/InProcClientWrapper.h
resource/include/OCApi.h
resource/include/OCRepresentation.h
resource/include/OCResourceRequest.h
resource/include/OCResourceResponse.h
resource/include/OCSerialization.h
resource/include/OicJsonSerializer.hpp [deleted file]
resource/patches/cereal_gcc46.patch [deleted file]
resource/src/InProcClientWrapper.cpp
resource/src/InProcServerWrapper.cpp
resource/src/OCPlatform_impl.cpp
resource/src/OCRepresentation.cpp
resource/src/OCResourceRequest.cpp
resource/src/SConscript
service/notification-manager/NotificationManager/src/hosting.c
tools/vagrant/iotivity-setup.sh

index 6adba9d..c891e5c 100644 (file)
@@ -96,6 +96,7 @@ extlibs/android/gradle/gradle-2.2.1
 extlibs/android/ndk/android-ndk-r10d
 extlibs/android/sdk/android-sdk_r24.2
 extlibs/boost/boost_1_58_0
+extlibs/tinycbor/tinycbor
 *.tgz
 *.zip
 extlibs/arduino/arduino-1.5.8
index 6d243f8..027511d 100644 (file)
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -40,20 +40,13 @@ license can be found at
 The original software is available from
   http://sourceforge.net/projects/boost/files/boost
 
-JSON serialization is provided by the cereal package,
-which is open source software, written by Philip Hazel, and copyright
-by the University of Cambridge, England. The original software is
-available from
-  ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
-
+CBOR serialization is provided by the tinycbor package,
+which is open source software, written by Thiago Macieira and is
+copyright by the Intel Corporation.  The original software is available
+from
+  https://github.com/01org/tinycbor/
 JSON serialization is provided by the cjson package,
 which is open source software, written and copyright by Dave Gamble
 with an MIT license. The original software is available from
   http://sourceforge.net/projects/cjson/
 
-JSON serialization is provided by the rapidjson package,
-which is open source software, written and copyright by Milo Yip
-with an MIT license. The original software is available from
-  http://code.google.com/p/rapidjson/
-
-
index 4ea28b1..a66dbb4 100644 (file)
@@ -9,8 +9,8 @@ command in this directory)
 
     Build release binaries:
       $ scons
-(Note: C++ sdk requires cereal. Please follow the instruction in the build
-message to install cereal)
+(Note: C sdk requires tiny-cbor. Please follow the instruction in the build
+message to install tiny-cbor)
 
     Build debug binaries:
       $scons RELEASE=false
@@ -116,13 +116,10 @@ so you don't need to add it in command line each time. The build script will
 guide you to do that.)
 
 Tizen:
-To build for tizen platform cereal library is needed.
-Please download cereal if it is not present in extlibs/cereal folder
-and apply the patch as following:
-       $ git clone https://github.com/USCiLab/cereal.git extlibs/cereal/cereal
-       $ cd  extlibs/cereal/cereal
-       $ git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245
-       $ git apply ../../../resource/patches/cereal_gcc46.patch
+To build for tizen platform tiny-cbor library is needed.
+Please download tiny-cbor if it is not present in extlibs/tiny-cbor folder
+by doing the following:
+       $ git clone https://github.com/01org/tinycbor.git extlibs/tinycbor/tinycbor
 
 
 * 3. External libraries
index e2c2cd0..c143069 100644 (file)
@@ -720,22 +720,6 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueRepresent
     rep->setValue(key, value);\r
 }\r
 \r
-/*\r
-* Class:     org_iotivity_base_OcRepresentation\r
-* Method:    getJSONRepresentation\r
-* Signature: ()Ljava/lang/String;\r
-*/\r
-JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcRepresentation_getJSONRepresentation\r
-(JNIEnv *env, jobject thiz)\r
-{\r
-    LOGD("OcRepresentation_getJSONRepresentation");\r
-    OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz);\r
-    if (!rep) return nullptr;\r
-\r
-    std::string jsonStr = rep->getJSONRepresentation();\r
-    return env->NewStringUTF(jsonStr.c_str());\r
-}\r
-\r
 /*\r
 * Class:     org_iotivity_base_OcRepresentation\r
 * Method:    addChild\r
@@ -1037,4 +1021,4 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_dispose
     {\r
         delete rep;\r
     }\r
-}
\ No newline at end of file
+}\r
index 3f25c29..fbf3131 100644 (file)
@@ -619,14 +619,6 @@ extern "C" {
     JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueRepresentation3DArray\r
         (JNIEnv *, jobject, jstring, jobjectArray);\r
 \r
-    /*\r
-    * Class:     org_iotivity_base_OcRepresentation\r
-    * Method:    getJSONRepresentation\r
-    * Signature: ()Ljava/lang/String;\r
-    */\r
-    JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcRepresentation_getJSONRepresentation\r
-        (JNIEnv *, jobject);\r
-\r
     /*\r
     * Class:     org_iotivity_base_OcRepresentation\r
     * Method:    addChild\r
@@ -766,4 +758,4 @@ extern "C" {
 #ifdef __cplusplus\r
 }\r
 #endif\r
-#endif
\ No newline at end of file
+#endif
index 432bbe5..cc60e2d 100644 (file)
@@ -121,6 +121,9 @@ def __install_lib(ienv, lib):
 
 SConscript('tools/UnpackAll.py')
 
+# tinycbor build/fetch
+SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'tinycbor', 'SConscript'))
+
 env.AddMethod(__prepare_lib, "PrepareLib")
 env.AddMethod(__configure, "Configure")
 env.AddMethod(__download, "Download")
index 685d33a..5fac3ed 100644 (file)
@@ -235,7 +235,7 @@ LineResult LineInput::processGet(elements_t& elems, stringstream& ss)
         return LR_Timeout;
     }
 
-    std::string jsonRep = wreq->m_rep.getJSONRepresentation();
+    std::string jsonRep ;//= wreq->m_rep.getJSONRepresentation();
     //ss << jsonRep << endl;
     printJSONAsTable(jsonRep);
         return LR_OK;
@@ -356,7 +356,7 @@ void LineInput::obsCB(token_t token, const HeaderOptions& headerOptions, const O
     if (!m_observer)
         return;
     cout << "cb " << eCode << " " << sequenceNumber << '\n';
-    cout << rep.getJSONRepresentation() << "\n";
+    //cout << rep.getJSONRepresentation() << "\n";
 }
 
 ParseState LineInput::finishElem(char*& e, elements_t& elems)
index 3cadb7d..a064d28 100644 (file)
@@ -164,7 +164,7 @@ void WrapResource::parseJSON(WrapRequest *wreq)
 {
     string sep = "\":";
     string anchor = "\"rep\":{";
-    string json = wreq->m_rep.getJSONRepresentation();
+    string json;// = wreq->m_rep.getJSONRepresentation();
     string name, type, value, next;
     size_t r, e, e1, s, c;
 
index 4ebe318..acd236e 100755 (executable)
@@ -7,15 +7,6 @@ cd "$(dirname "$0")"
 
 EXTDIR=$(pwd)
 
-# Check for cereal existence
-if [ ! -d "cereal" ]; then
-    git clone https://github.com/USCiLab/cereal.git cereal
-    pushd cereal
-    git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245
-    git apply ../../resource/patches/cereal_gcc46.patch
-    popd
-fi
-
 # Pick the preferred version of boost to use
 BOOST_MAJOR=1
 BOOST_MINOR=57
@@ -44,8 +35,8 @@ function buildBoost {
     if [ ! -d "boost" ]; then
         cloneBoost
     fi
-    
-    # Determine the 
+
+    # Determine the
     TOOLCHAIN=${ANDROID_NDK}/toolchains/${TOOLSET}-${VERSION}/prebuilt/${HOST_ARCH}/bin
 
     OLDPATH=$PATH
diff --git a/extlibs/cereal/SConscript b/extlibs/cereal/SConscript
deleted file mode 100644 (file)
index 946a483..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-######################################################################
-# Cereal library build script
-#
-# Only 'hpp' is used by Iotivity, it's unnecessary to build it
-######################################################################
-import os
-
-Import('env')
-
-src_dir = env.get('SRC_DIR')
-
-# In the pass, cereal library is in extlibs/cereal, according to external
-# library management rule, cereal should be put in extlibs/cereal/cereal.
-# jenkins of gerrit server, still follow the old, to avoid jenkins fail
-# both places are handled.
-old = os.path.join(src_dir, 'extlibs', 'cereal', 'include')
-cur = os.path.join(src_dir, 'extlibs', 'cereal', 'cereal', 'include')
-
-# check 'cereal' library, if it doesn't exits, ask user to download it
-if not os.path.exists(old) and not os.path.exists(cur):
-       cereal_env = Environment(ENV = os.environ)
-       c = cereal_env.Action(['git clone https://github.com/USCiLab/cereal.git cereal',
-               'cd cereal && git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245 && git apply ../../../resource/patches/cereal_gcc46.patch',
-               ])
-
-       print 'Downloading cereal library ...'
-       if cereal_env.Execute(c):
-               print '''
-*********************************** Error: ************************************
-* Please download cereal and apply the patch as following:                    *
-*     $ git clone https://github.com/USCiLab/cereal.git extlibs/cereal/cereal *
-*     $ cd  extlibs/cereal/cereal                                             *
-*     $ git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245             *
-*     $ git apply ../../../resource/patches/cereal_gcc46.patch                *
-*******************************************************************************
-'''
-               Exit(1)
-       else:
-               print 'Download cereal library complete'
-
-env.AppendUnique(CPPPATH = [old, cur])
diff --git a/extlibs/tinycbor/SConscript b/extlibs/tinycbor/SConscript
new file mode 100644 (file)
index 0000000..fc12833
--- /dev/null
@@ -0,0 +1,46 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+import os
+
+Import('env')
+
+src_dir = env.get('SRC_DIR')
+
+cborDir = os.path.join(src_dir, 'extlibs','tinycbor','tinycbor')
+
+if not os.path.exists(cborDir):
+    print '''
+*********************************** Error: ****************************************
+* Please download cbor using the following command:                               *
+*     $ git clone https://github.com/01org/tinycbor.git extlibs/tinycbor/tinycbor *
+***********************************************************************************
+'''
+    Exit(1)
+
+cbor_src = [
+    os.path.join(cborDir,'src/cborparser.c'),
+    os.path.join(cborDir,'src/cborencoder.c')
+    ]
+
+env['cbor_files'] = cbor_src
+env.AppendUnique(CPPPATH  = [os.path.join(cborDir, 'src')])
+
+
index 6cd51b7..4403138 100644 (file)
@@ -30,5 +30,3 @@ Import('env')
 target_os = env.get('TARGET_OS')
 target_arch = env.get('TARGET_ARCH')
 src_dir = env.get('SRC_DIR')
-
-env.SConscript('extlibs/cereal/SConscript')
index d4542f0..749da0a 100644 (file)
@@ -20,7 +20,7 @@ mkdir ./tmp/extlibs/
 mkdir ./tmp/packaging
 cp -R ./build_common $sourcedir/tmp
 cp -R ./examples $sourcedir/tmp
-cp -R ./extlibs/cereal $sourcedir/tmp/extlibs
+cp -R ./extlibs/tinycbor $sourcedir/tmp/extlibs
 cp -R ./extlibs/cjson $sourcedir/tmp/extlibs
 cp -R ./extlibs/tinydtls $sourcedir/tmp/extlibs
 cp -R ./extlibs/timer $sourcedir/tmp/extlibs
@@ -35,7 +35,7 @@ cp ./tools/tizen/.gbs.conf ./tmp
 cd $sourcedir/tmp
 
 echo `pwd`
-rm -rf ./extlibs/cereal/cereal/.git*
+rm -rf ./extlibs/tinycbor/tinycbor/.git*
 
 # Initialize Git repository
 if [ ! -d .git ]; then
index df0b7b2..dc7ae45 100644 (file)
@@ -67,6 +67,26 @@ extern "C"
  */
 void *OICMalloc(size_t size);
 
+/**
+ * Re-allocates a block of memory, pointed to by ptr to the size specified
+ * in size.  The returned value contains a pointer to the new location, with
+ * all data copied into it.  If the new size of the memory-object require movement,
+ * the previous space is freed.  If the new size is larger, the newly allocated
+ * area has non-deterministic content. If the space cannot be allocated, the value
+ * ptr is left unchanged.
+ *
+ * @param ptr - Pointer to a block of memory previously allocated by OICCalloc,
+ *              OICMalloc, or a previous call to this function.  If this value is
+ *              NULL, this function will work identically to a call to OICMalloc.
+ *
+ * @param size - Size of the new memory block in bytes, where size > 0
+ *
+ * @return
+ *      on success, a pointer to the newly sized memory block
+ *      on failure, a null pointer is returned, and the memory pointed to by *ptr is untouched
+ */
+void *OICRealloc(void *ptr, size_t size);
+
 /**
  * Allocates a block of memory for an array of num elements, each of them
  * size bytes long and initializes all its bits to zero.
@@ -86,7 +106,7 @@ void *OICCalloc(size_t num, size_t size);
  * NOTE: This function is intended to be used internally by the TB Stack.
  *       It is not intended to be used by applications.
  *
- * @param ptr - Pointer to block of memory previously allocated by OCMalloc.
+ * @param ptr - Pointer to block of memory previously allocated by OICMalloc.
  *              If ptr is a null pointer, the function does nothing.
  */
 void OICFree(void *ptr);
index 40b7363..99df106 100644 (file)
@@ -98,6 +98,29 @@ void *OICCalloc(size_t num, size_t size)
 #endif
 }
 
+void *OICRealloc(void* ptr, size_t size)
+{
+    if(size == 0)
+    {
+        OICFree(ptr);
+        return NULL;
+    }
+
+#ifdef ENABLE_MALLOC_DEBUG
+    if(ptr == NULL)
+    {
+        return OICMalloc(size);
+    }
+
+    void* newptr = NULL;
+    newptr = realloc(ptr, size);
+    OIC_LOG_V(INFO, TAG, "realloc: ptr=%p, newptr=%p, size=%u", ptr, newptr, size);
+    return ptr;
+#else
+    return realloc(ptr, size);
+#endif
+}
+
 void OICFree(void *ptr)
 {
 #ifdef ENABLE_MALLOC_DEBUG
index 14bfd03..9519797 100644 (file)
@@ -102,6 +102,9 @@ liboctbstack_src = [
        '../../extlibs/cjson/cJSON.c',
        '../../extlibs/timer/timer.c',
        OCTBSTACK_SRC + 'ocstack.c',
+       OCTBSTACK_SRC + 'ocpayload.c',
+       OCTBSTACK_SRC + 'ocpayloadparse.c',
+       OCTBSTACK_SRC + 'ocpayloadconvert.c',
        OCTBSTACK_SRC + 'occlientcb.c',
        OCTBSTACK_SRC + 'ocresource.c',
        OCTBSTACK_SRC + 'ocobserve.c',
@@ -112,6 +115,8 @@ liboctbstack_src = [
        'ocrandom/src/ocrandom.c'
        ]
 
+liboctbstack_src.extend(env['cbor_files'])
+
 if target_os in ['arduino','darwin','ios'] :
        static_liboctbstack = liboctbstack_env.StaticLibrary('octbstack', liboctbstack_src)
        liboctbstack_env.InstallTarget(static_liboctbstack, 'liboctbstack')
index f821fba..3970fc5 100644 (file)
@@ -98,7 +98,7 @@ extern "C"
 /**
  * @brief Payload information from resource model
  */
-typedef char *CAPayload_t;
+typedef uint8_t *CAPayload_t;
 
 /**
  * @brief URI for the OIC base.CA considers relative URI as the URI.
@@ -303,6 +303,7 @@ typedef struct
     CAHeaderOption_t *options;  /** Header Options for the request */
     uint8_t numOptions;         /**< Number of Header options */
     CAPayload_t payload;        /**< payload of the request  */
+    size_t payloadSize;         /**< size in bytes of the payload */
     CAURI_t resourceUri;        /**< Resource URI information **/
 } CAInfo_t;
 
index eaa9ff0..49eb444 100644 (file)
@@ -115,7 +115,7 @@ CARequestInfo_t *CACloneRequestInfo(const CARequestInfo_t *rep)
     if (NULL != rep->info.payload)
     {
         // allocate payload field
-        char *temp = OICStrdup(rep->info.payload);
+        uint8_t *temp = OICMalloc(rep->info.payloadSize);
         if (NULL == temp)
         {
             OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
@@ -124,6 +124,7 @@ CARequestInfo_t *CACloneRequestInfo(const CARequestInfo_t *rep)
 
             return NULL;
         }
+        memcpy(temp, rep->info.payload, rep->info.payloadSize);
 
         // save the payload
         clone->info.payload = temp;
@@ -242,7 +243,7 @@ CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *rep)
     if (NULL != rep->info.payload)
     {
         // allocate payload field
-        char *temp = OICStrdup(rep->info.payload);
+        uint8_t *temp = (uint8_t *) OICMalloc(rep->info.payloadSize);
         if (NULL == temp)
         {
             OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
@@ -251,6 +252,7 @@ CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *rep)
 
             return NULL;
         }
+        memcpy(temp, rep->info.payload, rep->info.payloadSize);
 
         // save the payload
         clone->info.payload = temp;
index b71c9b9..591aac1 100644 (file)
@@ -94,7 +94,7 @@ CAResult_t CAGetErrorInfoFromPDU(const coap_pdu_t *pdu, CAErrorInfo_t *errorInfo
  * @return  generated pdu
  */
 coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t *info,
-                              const char *payload, size_t payloadSize);
+                              const uint8_t *payload, size_t payloadSize);
 
 /**
  * @brief   parse the URI and creates the options
index 5762007..d246654 100644 (file)
@@ -276,7 +276,7 @@ int coap_add_data(coap_pdu_t *pdu, unsigned int len, const unsigned char *data)
     return 1;
 }
 
-int coap_get_data(coap_pdu_t *pdu, size_t *len, unsigned char **data)
+int coap_get_data(const coap_pdu_t *pdu, size_t *len, unsigned char **data)
 {
     assert(pdu);
     assert(len);
index c469b24..f45831a 100644 (file)
@@ -346,6 +346,6 @@ int coap_add_data(coap_pdu_t *pdu, unsigned int len, const unsigned char *data);
  * or 1 if *len and *data have correct values. Note that these values are
  * destroyed with the pdu.
  */
-int coap_get_data(coap_pdu_t *pdu, size_t *len, unsigned char **data);
+int coap_get_data(const coap_pdu_t *pdu, size_t *len, unsigned char **data);
 
 #endif /* _PDU_H_ */
index 52040c2..a254ec4 100644 (file)
@@ -432,7 +432,7 @@ void SendRequestAll()
     CAInfo_t requestData = {CA_MSG_RESET};
     requestData.token = token;
     requestData.tokenLength = tokenLength;
-    requestData.payload = "Temp Json Payload";
+    requestData.payload = (CAPayload_t)"Temp Json Payload";
     requestData.type = CA_MSG_NONCONFIRM;
     requestData.resourceUri = (char *)OICMalloc(strlen(resourceUri) + 1);
     strcpy(requestData.resourceUri, resourceUri);
@@ -704,7 +704,7 @@ void RequestHandler(const CAEndpoint_t *object, const CARequestInfo_t *requestIn
     Serial.print("uri: ");
     Serial.println(requestInfo->info.resourceUri);
     Serial.print("data: ");
-    Serial.println(requestInfo->info.payload);
+    Serial.println((char*)requestInfo->info.payload);
     Serial.print("Type: ");
     Serial.println(requestInfo->info.type);
 
@@ -739,7 +739,7 @@ void ResponseHandler(const CAEndpoint_t *object, const CAResponseInfo_t *respons
         Serial.print("uri: ");
         Serial.println(responseInfo->info.resourceUri);
         Serial.print("data: ");
-        Serial.println(responseInfo->info.payload);
+        Serial.println((char*)responseInfo->info.payload);
         Serial.print("Type: ");
         Serial.println(responseInfo->info.type);
         Serial.print("res result=");
@@ -765,7 +765,7 @@ void ErrorHandler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
         Serial.print("resourceUri: ");
         Serial.println(info->resourceUri);
         Serial.print("payload: ");
-        Serial.println(info->payload);
+        Serial.println((char*)info->payload);
     }
 
     return;
@@ -838,7 +838,7 @@ void SendResponse(CAEndpoint_t *endpoint, const CAInfo_t* info)
     {
         responseData.token = (info != NULL) ? info->token : NULL;
         responseData.tokenLength = (info != NULL) ? info->tokenLength : 0;
-        responseData.payload = static_cast<CAPayload_t>("response payload");
+        responseData.payload = reinterpret_cast<CAPayload_t>(const_cast<char*>("response payload"));
     }
     CAResponseInfo_t responseInfo = {CA_BAD_REQ, {CA_MSG_RESET}};
     responseInfo.result = static_cast<CAResponseResult_t>(respCode);
index d839c95..a4e37c3 100644 (file)
@@ -368,10 +368,6 @@ static void CAReceivedPacketCallback(const CAEndpoint_t *endpoint, void *data, u
             }
         }
 
-        if (NULL != ReqInfo->info.payload)
-        {
-            OIC_LOG_V(DEBUG, TAG, "Request- payload: %s", ReqInfo->info.payload);
-        }
         OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method);
         if (NULL != ReqInfo->info.token)
         {
@@ -379,6 +375,7 @@ static void CAReceivedPacketCallback(const CAEndpoint_t *endpoint, void *data, u
             OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) ReqInfo->info.token,
                            ReqInfo->info.tokenLength);
         }
+
         OIC_LOG_V(DEBUG, TAG, "Request- msgID : %d", ReqInfo->info.messageId);
         // store the data at queue.
         CAData_t *cadata = NULL;
@@ -429,7 +426,8 @@ static void CAReceivedPacketCallback(const CAEndpoint_t *endpoint, void *data, u
 
         if (NULL != ResInfo->info.payload)
         {
-            OIC_LOG_V(DEBUG, TAG, "Response- payload: %s", ResInfo->info.payload);
+            OIC_LOG_V(DEBUG, TAG, "Response- payload: %p(%u) from %s", ResInfo->info.payload,
+                    ResInfo->info.payloadSize, endpoint->addr);
         }
         OIC_LOG_V(DEBUG, TAG, "Response- code: %d", ResInfo->result);
         if (NULL != ResInfo->info.token)
index 7c7fefc..3883c82 100644 (file)
@@ -188,8 +188,7 @@ coap_pdu_t *CAGeneratePDU(uint32_t code, const CAInfo_t *info)
             coap_delete_list(optlist);
             return NULL;
         }
-        size_t lenPayload = info->payload ? strlen(info->payload) : 0;
-        pdu = CAGeneratePDUImpl((code_t)code, optlist, info, info->payload, lenPayload);
+        pdu = CAGeneratePDUImpl((code_t)code, optlist, info, info->payload, info->payloadSize);
         if (NULL == pdu)
         {
             OIC_LOG(ERROR, TAG, "pdu NULL");
@@ -240,7 +239,7 @@ coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode)
 }
 
 coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t *info,
-                              const char *payload, size_t payloadSize)
+                              const uint8_t *payload, size_t payloadSize)
 {
     OIC_LOG(DEBUG, TAG, "IN");
     VERIFY_NON_NULL_RET(info, TAG, "info is NULL", NULL);
@@ -300,7 +299,6 @@ coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t
 
     if (NULL != payload)
     {
-        OIC_LOG_V(DEBUG, TAG, "add data, payload:%s", payload);
         coap_add_data(pdu, payloadSize, (const unsigned char *) payload);
     }
 
@@ -716,11 +714,12 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *
     outInfo->tokenLength = pdu->hdr->token_length;
 
     // set payload data
-    if (NULL != pdu->data)
+    size_t dataSize;
+    uint8_t *data;
+    if (coap_get_data(pdu, &dataSize, &data))
     {
-        uint32_t payloadLength = strlen((char*) pdu->data);
         OIC_LOG(DEBUG, TAG, "inside pdu->data");
-        outInfo->payload = (char *) OICMalloc(payloadLength + 1);
+        outInfo->payload = (uint8_t *) OICMalloc(dataSize);
         if (NULL == outInfo->payload)
         {
             OIC_LOG(ERROR, TAG, "Out of memory");
@@ -728,8 +727,8 @@ CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *
             OICFree(outInfo->token);
             return CA_MEMORY_ALLOC_FAILED;
         }
-        memcpy(outInfo->payload, pdu->data, payloadLength);
-        outInfo->payload[payloadLength] = '\0';
+        memcpy(outInfo->payload, pdu->data, dataSize);
+        outInfo->payloadSize = dataSize;
     }
 
     uint32_t length = strlen(optionResult);
index 1a4a20b..3449647 100644 (file)
@@ -265,7 +265,8 @@ TEST(SendRequestTest, DISABLED_TC_16_Positive_01)
         CADestroyToken(tempToken);
         FAIL() << "requestData.payload allocation failed";
     }
-    snprintf(requestData.payload, length, NORMAL_INFO_DATA, "a/light");
+    snprintf((char*)requestData.payload, length, NORMAL_INFO_DATA, "a/light");
+    requestData.payloadSize = length + 1;
     requestData.type = CA_MSG_NONCONFIRM;
 
     memset(&requestInfo, 0, sizeof(CARequestInfo_t));
@@ -308,7 +309,9 @@ TEST(SendResponseTest, DISABLED_TC_19_Positive_01)
     memset(&responseData, 0, sizeof(CAInfo_t));
     responseData.type = CA_MSG_NONCONFIRM;
     responseData.messageId = 1;
-    responseData.payload = (char *) "response payload";
+    responseData.payload = (CAPayload_t)malloc(sizeof("response payload"));
+    memcpy(responseData.payload, "response payload", sizeof("response payload"));
+    responseData.payloadSize = sizeof("response payload");
 
     CAGenerateToken(&tempToken, tokenLength);
     requestData.token = tempToken;
@@ -322,6 +325,7 @@ TEST(SendResponseTest, DISABLED_TC_19_Positive_01)
 
     CADestroyToken(tempToken);
     CADestroyEndpoint(tempRep);
+    free(responseData.payload);
     tempRep = NULL;
 }
 
@@ -334,7 +338,9 @@ TEST(SendResponseTest, DISABLED_TC_20_Negative_01)
     memset(&responseData, 0, sizeof(CAInfo_t));
     responseData.type = CA_MSG_NONCONFIRM;
     responseData.messageId = 1;
-    responseData.payload = (char *) "response payload";
+    responseData.payload = (CAPayload_t)malloc(sizeof("response payload"));
+    memcpy(responseData.payload, "response payload", sizeof("response payload"));
+    responseData.payloadSize = sizeof("response payload");
 
     CAGenerateToken(&tempToken, tokenLength);
     requestData.token = tempToken;
@@ -352,6 +358,7 @@ TEST(SendResponseTest, DISABLED_TC_20_Negative_01)
         CADestroyEndpoint(tempRep);
         tempRep = NULL;
     }
+    free (responseData.payload);
 }
 
 // check return value NULL is passed instead of a valid CAResponseInfo_t address
@@ -378,7 +385,9 @@ TEST(SendNotificationTest, DISABLED_TC_22_Positive_01)
 
     memset(&responseData, 0, sizeof(CAInfo_t));
     responseData.type = CA_MSG_NONCONFIRM;
-    responseData.payload = (char *) "Temp Notification Data";
+    responseData.payload = (CAPayload_t)malloc(sizeof("Temp Notification Data"));
+    memcpy(responseData.payload, "Temp Notification Data", sizeof("Temp Notification Data"));
+    responseData.payloadSize = sizeof("Temp Notification Data");
 
     CAGenerateToken(&tempToken, tokenLength);
     requestData.token = tempToken;
@@ -396,6 +405,7 @@ TEST(SendNotificationTest, DISABLED_TC_22_Positive_01)
         CADestroyEndpoint(tempRep);
         tempRep = NULL;
     }
+    free(responseData.payload);
 }
 
 // CASelectNewwork TC
index a58e868..d093b12 100644 (file)
@@ -28,6 +28,7 @@ provisioning_env = env.Clone()
 ######################################################################
 provisioning_env.AppendUnique(CPPPATH = [
                '../../stack/include',
+               '../../stack/include/internal',
                '../../ocrandom/include',
                '../../logger/include',
                '../../../oc_logger/include',
index 47b0657..14eed5f 100644 (file)
 #include <stdbool.h>
 
 #include "cJSON.h"
+#include "ocpayload.h"
+#include "ocpayloadcbor.h"
 #include "oic_malloc.h"
 #include "logger.h"
 #include "cacommon.h"
+#include "ocpayload.h"
 #include "cainterface.h"
 #include "provisioningmanager.h"
 #include "credentialgenerator.h"
@@ -313,7 +316,6 @@ static CAResult_t sendCARequest(CAMethod_t method,
         OC_LOG(ERROR, TAG, "Error while generating token");
         return CA_MEMORY_ALLOC_FAILED;
     }
-
     CAEndpoint_t *endpoint = NULL;
     if (CA_STATUS_OK != CACreateEndpoint((CATransportFlags_t)secure,
                                          devAddr->adapter, devAddr->addr,
@@ -324,20 +326,25 @@ static CAResult_t sendCARequest(CAMethod_t method,
         return CA_STATUS_FAILED;
     }
     CAMessageType_t msgType = CA_MSG_CONFIRM;
-    CAInfo_t requestData = { 0 };
-    requestData.token = gToken;
-    requestData.tokenLength  = CA_MAX_TOKEN_LEN;
     if (payload && '\0' != (*(payload + payloadLen)))
     {
         OC_LOG(ERROR, TAG, "Payload not properly terminated.");
         CADestroyEndpoint(endpoint);
         return CA_STATUS_INVALID_PARAM;
     }
-    requestData.payload = payload;
-    requestData.type = msgType;
+    OCSecurityPayload secPayload;
+    secPayload.securityData = payload;
+    secPayload.base.type = PAYLOAD_TYPE_SECURITY;
     CARequestInfo_t requestInfo = { 0 };
     requestInfo.method = method;
-    requestInfo.info = requestData;
+    requestInfo.isMulticast = false;
+    OCConvertPayload((OCPayload*)(&secPayload), &requestInfo.info.payload,
+            &requestInfo.info.payloadSize);
+    requestInfo.info.type = msgType;
+    requestInfo.info.token = gToken;
+    requestInfo.info.tokenLength  = CA_MAX_TOKEN_LEN;
+    requestInfo.info.resourceUri  = resourceUri;
+
     requestInfo.isMulticast = false;
     CAResult_t caResult = CA_STATUS_OK;
     caResult = CASendRequest(endpoint, &requestInfo);
@@ -421,6 +428,7 @@ static SPResult selectProvisioningMethod(OicSecOxm_t *supportedMethods, size_t n
     return SP_RESULT_SUCCESS;
 }
 
+OCStackResult OCParsePayload(OCPayload** outPayload, const uint8_t* payload, size_t payloadSize);
 /**
  * Response handler for discovery.
  *
@@ -442,22 +450,17 @@ static void ProvisionDiscoveryHandler(const CAEndpoint_t *object,
             }
             else
             {
-                // temp logic for trimming oc attribute from the json.
-                // JSONToBin should handle oc attribute.
-                char *pTempPayload = (char *)OICMalloc(strlen(responseInfo->info.payload));
-                if (NULL == pTempPayload)
+                OCPayload* payload;
+                OCStackResult result = OCParsePayload(&payload, responseInfo->info.payload,
+                        responseInfo->info.payloadSize);
+
+                OicSecDoxm_t *ptrDoxm = NULL;
+
+                if(result == OC_STACK_OK && payload->type == PAYLOAD_TYPE_SECURITY)
                 {
-                    OC_LOG(ERROR, TAG, "Error while Memory allocation.");
-                    gStateManager = gStateManager | SP_DISCOVERY_ERROR;
-                    return;
+                    ptrDoxm = JSONToDoxmBin(((OCSecurityPayload*)payload)->securityData);
                 }
 
-                strcpy(pTempPayload, responseInfo->info.payload + 8);
-                pTempPayload[strlen(pTempPayload) - 2] = '\0';
-                OC_LOG_V(DEBUG, TAG, "Trimmed payload: %s", pTempPayload);
-                OicSecDoxm_t *ptrDoxm = JSONToDoxmBin(pTempPayload);
-                OICFree(pTempPayload);
-
                 if (NULL == ptrDoxm)
                 {
                     OC_LOG(INFO, TAG, "Ignoring malformed JSON");
@@ -539,26 +542,23 @@ static void ListMethodsHandler(const CAEndpoint_t *object,
                     return;
                 }
 
-                char *pTempPayload = (char *)OICMalloc(strlen(responseInfo->info.payload));
-                if (NULL == pTempPayload)
+                OCPayload* payload;
+                OCStackResult result = OCParsePayload(&payload, responseInfo->info.payload,
+                        responseInfo->info.payloadSize);
+
+                OicSecPstat_t *pstat = NULL;
+
+                if(result == OC_STACK_OK && payload->type == PAYLOAD_TYPE_SECURITY)
                 {
-                    OC_LOG(ERROR, TAG, "Error in memory allocation.");
-                    gStateManager |= SP_LIST_METHODS_ERROR;
-                    return;
+                    pstat =  JSONToPstatBin(((OCSecurityPayload*)payload)->securityData);
                 }
 
-                strcpy(pTempPayload, responseInfo->info.payload + 8);
-                pTempPayload[strlen(pTempPayload) - 2] = '\0';
-
-                OicSecPstat_t *pstat =  JSONToPstatBin(pTempPayload);
                 if (NULL == pstat)
                 {
                     OC_LOG(ERROR, TAG, "Error while converting json to pstat bin");
-                    OICFree(pTempPayload);
                     gStateManager |= SP_LIST_METHODS_ERROR;
                     return;
                 }
-                OICFree(pTempPayload);
                 DeletePstatBinData(gPstat);
 
                 gPstat = pstat;
@@ -781,6 +781,7 @@ static SPResult findResource(unsigned short timeout)
     requestData.token = gToken;
     requestData.tokenLength  = CA_MAX_TOKEN_LEN;
     requestData.payload = NULL;
+    requestData.payloadSize = 0;
     requestData.type = msgType;
     requestData.resourceUri = DOXM_OWNED_FALSE_MULTICAST_QUERY;
     CARequestInfo_t requestInfo = { 0 };
@@ -958,7 +959,7 @@ static SPResult updateOperationMode(unsigned short timeout,
  * @param[in]  deviceInfo  Provisioning context
  * @return SP_SUCCESS on success
  */
-static SPResult initiateDtlsHandshake(const SPTargetDeviceInfo_t *deviceInfo)
+static SPResult initiateDtlsHandshake(SPTargetDeviceInfo_t *deviceInfo)
 {
     CAResult_t caresult = CASelectCipherSuite(TLS_ECDH_anon_WITH_AES_128_CBC_SHA);
 
@@ -976,6 +977,8 @@ static SPResult initiateDtlsHandshake(const SPTargetDeviceInfo_t *deviceInfo)
     }
     OC_LOG(INFO, TAG, "Anonymous cipher suite Enabled.");
 
+    //TODO: It is a temporary fix. Revisit it.
+    deviceInfo->endpoint.port = CA_SECURE_PORT;
     caresult = CAInitiateHandshake((CAEndpoint_t *)&deviceInfo->endpoint);
     if (CA_STATUS_OK != caresult)
     {
@@ -1322,7 +1325,7 @@ SPResult SPProvisionACL(unsigned short timeout, const SPTargetDeviceInfo_t *sele
     CAResult_t result = sendCARequest(CA_POST,
                                       &selectedDeviceInfo->endpoint,
                                       OC_SECURE,
-                                      OIC_RSRC_DOXM_URI,
+                                      OIC_RSRC_ACL_URI,
                                       aclString, payloadLen);
     OICFree(aclString);
     if (CA_STATUS_OK != result)
index 8e6e7c0..7921b0b 100644 (file)
@@ -305,7 +305,7 @@ static OCEntityHandlerResult HandleACLPostRequest (const OCEntityHandlerRequest
     OCEntityHandlerResult ehRet = OC_EH_ERROR;
 
     // Convert JSON ACL data into binary. This will also validate the ACL data received.
-    OicSecAcl_t* newAcl = JSONToAclBin((char *)(ehRequest->reqJSONPayload));
+    OicSecAcl_t* newAcl = JSONToAclBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
 
     if (newAcl)
     {
index 1ceb2d9..af21b26 100755 (executable)
@@ -506,7 +506,7 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh
     OCEntityHandlerResult ret = OC_EH_ERROR;
 
     //Get binary representation of json
-    OicSecCred_t * cred  = JSONToCredBin((char *)ehRequest->reqJSONPayload);
+    OicSecCred_t * cred  = JSONToCredBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
 
     if(cred)
     {
index a9a9696..310ffe5 100755 (executable)
@@ -419,7 +419,7 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest
      * Convert JSON Doxm data into binary. This will also validate
      * the Doxm data received.
      */
-    OicSecDoxm_t* newDoxm = JSONToDoxmBin((char *)(ehRequest->reqJSONPayload));
+    OicSecDoxm_t* newDoxm = JSONToDoxmBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
 
     if (newDoxm)
     {
index b0b0a58..aa798e0 100644 (file)
@@ -220,7 +220,7 @@ static OCEntityHandlerResult HandlePstatPutRequest(const OCEntityHandlerRequest
 
     if (ehRequest->resource)
     {
-        postJson = cJSON_Parse((char *) ehRequest->reqJSONPayload);
+        postJson = cJSON_Parse(((OCSecurityPayload*)ehRequest->payload)->securityData);
         VERIFY_NON_NULL(TAG, postJson, INFO);
         cJSON *jsonPstat = cJSON_GetObjectItem(postJson, OIC_JSON_PSTAT_NAME);
         VERIFY_NON_NULL(TAG, jsonPstat, INFO);
index 64725cc..f167855 100644 (file)
@@ -25,6 +25,7 @@
 #include "doxmresource.h"
 #include "credresource.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 #include "logger.h"
 #include "utlist.h"
 #include <string.h>
@@ -50,8 +51,9 @@ OCStackResult SendSRMResponse(const OCEntityHandlerRequest *ehRequest,
         response.requestHandle = ehRequest->requestHandle;
         response.resourceHandle = ehRequest->resource;
         response.ehResult = ehRet;
-        response.payload = (char *)rspPayload;
-        response.payloadSize = (rspPayload ? strlen(rspPayload) : 0);
+        response.payload = (OCPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+        response.payload->type = PAYLOAD_TYPE_SECURITY;
+        ((OCSecurityPayload*)response.payload)->securityData = OICStrdup(rspPayload);
         response.persistentBufferFlag = 0;
 
         return OCDoResponse(&response);
index 5608e16..2cdb0f8 100644 (file)
@@ -192,7 +192,9 @@ TEST(ACLResourceTest, ACLPostTest)
 
         // Create Entity Handler POST request payload
         ehReq.method = OC_REST_POST;
-        ehReq.reqJSONPayload = jsonStr;
+        ehReq.payload = (OCPayload*)calloc(1, sizeof(OCSecurityPayload));
+        ehReq.payload->type = PAYLOAD_TYPE_SECURITY;
+        ((OCSecurityPayload*)ehReq.payload)->securityData = jsonStr;
 
         OCEntityHandlerResult ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
         EXPECT_TRUE(OC_EH_ERROR == ehRet);
index 4ccdb86..10398c5 100644 (file)
@@ -73,7 +73,10 @@ TEST(PstatEntityHandlerTest, PstatEntityHandlerWithPostRequest)
 {
     OCEntityHandlerRequest req;
     req.method = OC_REST_POST;
-    req.reqJSONPayload = (char*)"{ \"pstat\": { \"tm\": 0, \"om\": 3 }}";
+    req.payload = (OCPayload*)calloc(1, sizeof(OCSecurityPayload));
+    req.payload->type = PAYLOAD_TYPE_SECURITY;
+    ((OCSecurityPayload*)req.payload)->securityData =
+        (char*)"{ \"pstat\": { \"tm\": 0, \"om\": 3 }}";
     EXPECT_EQ(OC_EH_ERROR, PstatEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
 }
 
index 7a5749a..37c8c09 100644 (file)
@@ -92,14 +92,14 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
  * @param resource Observed resource
  * @param obsIdList List of observation ids that need to be notified.
  * @param numberOfIds Number of observation ids included in obsIdList.
- * @param notificationJSONPayload - JSON encoded payload to send in notification.
+ * @param payload - OCRepresentationPayload object representing the message
  * @param maxAge Time To Live (in seconds) of observation.
  * @param qos Desired quality of service of the observation notifications.
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
 OCStackResult SendListObserverNotification (OCResource * resource,
         OCObservationId  *obsIdList, uint8_t numberOfIds,
-        const char *notificationJSONPayload, uint32_t maxAge,
+        const OCRepPayload *payload, uint32_t maxAge,
         OCQualityOfService qos);
 
 /**
diff --git a/resource/csdk/stack/include/internal/ocpayloadcbor.h b/resource/csdk/stack/include/internal/ocpayloadcbor.h
new file mode 100644 (file)
index 0000000..5d3c16e
--- /dev/null
@@ -0,0 +1,29 @@
+//******************************************************************
+//
+// Copyright 2014 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef OC_PAYLOAD_CBOR_H
+#define OC_PAYLOAD_CBOR_H
+
+#include "octypes.h"
+
+OCStackResult OCParsePayload(OCPayload** outPayload, const uint8_t* payload, size_t payloadSize);
+
+OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* size);
+#endif
index e38806a..6fe298e 100644 (file)
@@ -126,8 +126,8 @@ typedef struct resourceinterface_t {
     /*** Future placeholder for access control and policy ***/
 } OCResourceInterface;
 
-typedef struct rsrc_t {
-    struct rsrc_t *next; // Points to next resource in list
+typedef struct OCResource {
+    struct OCResource *next; // Points to next resource in list
     // Relative path on the device; will be combined with base url to create fully qualified path
     char *uri;
     OCResourceType *rsrcType; // Resource type(s); linked list
@@ -135,7 +135,7 @@ typedef struct rsrc_t {
     OCAttribute *rsrcAttributes; // Resource interface(s); linked list
     // Array of pointers to resources; can be used to represent a container of resources
     // (i.e. hierarchies of resources) or for reference resources (i.e. for a resource collection)
-    struct rsrc_t *rsrcResources[MAX_CONTAINED_RESOURCES];
+    struct OCResource *rsrcResources[MAX_CONTAINED_RESOURCES];
     //struct rsrc_t *rsrcResources;
     // Pointer to function that handles the entity bound to the resource.
     // This handler has to be explicitly defined by the programmer
index b0776b3..4b8efcd 100644 (file)
@@ -138,8 +138,7 @@ void DeleteDeviceInfo();
  * Prepares a JSON string for response.
  */
 OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
-                                           char * out,
-                                           uint16_t *remaining,
+                                           OCDiscoveryPayload* payload,
                                            CATransportAdapter_t adapter);
 
 /**
index fce897a..16f8dc6 100644 (file)
@@ -63,16 +63,16 @@ typedef struct OCServerRequest
     // Flag indicating slow response
     uint8_t slowFlag;
     uint8_t notificationFlag;
-    // reqJSON is retrieved from the payload of the received request PDU
-    char reqJSONPayload[1];
+    size_t payloadSize;
+    // payload is retrieved from the payload of the received request PDU
+    uint8_t payload[1];
 } OCServerRequest;
 
 // following structure will be created in ocstack to aggregate responses (in future: for block transfer)
 typedef struct OCServerResponse {
     struct OCServerResponse * next;
     // this is the pointer to server payload data to be transferred
-    char *payload;
-    uint16_t remainingPayloadSize;
+    OCPayload* payload;
     OCRequestHandle requestHandle;
 } OCServerResponse;
 
@@ -159,7 +159,7 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
         uint8_t numRcvdVendorSpecificHeaderOptions, uint32_t observationOption,
         OCQualityOfService qos, char * query,
         OCHeaderOption * rcvdVendorSpecificHeaderOptions,
-        char * reqJSONPayload, CAToken_t requestToken,
+        uint8_t * payload, CAToken_t requestToken,
         uint8_t tokenLength,
         char * resourceUrl, size_t reqTotalSize,
         const OCDevAddr *devAddr);
@@ -172,7 +172,8 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
  * @param method           - RESTful method
  * @param resource         - resource handle
  * @param queryBuf         - resource query of request
- * @param bufReqPayload    - JSON payload of request
+ * @param payload          - payload of request
+ * @param payloadSize      - size of the payload request
  * @param numVendorOptions - number of vendor options
  * @param vendorOptions    - vendor options
  * @param observeAction    - observe action flag
@@ -181,8 +182,10 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
  * @return
  *     OCStackResult
  */
-OCStackResult FormOCEntityHandlerRequest(OCEntityHandlerRequest * entityHandlerRequest, OCRequestHandle request,
-        OCMethod method, OCResourceHandle resource, char * queryBuf, char * bufReqPayload,
+OCStackResult FormOCEntityHandlerRequest(OCEntityHandlerRequest * entityHandlerRequest,
+        OCRequestHandle request,
+        OCMethod method, OCResourceHandle resource, char * queryBuf,
+        uint8_t * payload, size_t payloadSize,
         uint8_t numVendorOptions, OCHeaderOption * vendorOptions, OCObserveAction observeAction,
         OCObservationId observeID);
 
index 1fd936b..709a4b0 100644 (file)
@@ -69,7 +69,7 @@ typedef struct
     // resource query send by client
     char query[MAX_QUERY_LENGTH];
     // reqJSON is retrieved from the payload of the received request PDU
-    char reqJSONPayload[MAX_REQUEST_LENGTH];
+    uint8_t payload[MAX_REQUEST_LENGTH];
     // qos is indicating if the request is CON or NON
     OCQualityOfService qos;
     // An array of the received vendor specific header options
@@ -136,26 +136,6 @@ OCStackResult SendDirectStackResponse(const CAEndpoint_t* endPoint, const uint16
         CAToken_t token, uint8_t tokenLength);
 
 #ifdef WITH_PRESENCE
-/**
- * The OCPresenceTrigger enum delineates the three spec-compliant modes for
- * "Trigger." These enum values are then mapped to JSON strings
- * "create", "change", "delete", respectively, before getting encoded into
- * the JSON payload.
- *
- * @enum OC_PRESENCE_TRIGGER_CREATE The creation of a resource is associated with
- *                            this invocation of @ref SendPresenceNotification.
- * @enum OC_PRESENCE_TRIGGER_CHANGE The change/update of a resource is associated
- *                            this invocation of @ref SendPresenceNotification.
- * @enum OC_PRESENCE_TRIGGER_DELETE The deletion of a resource is associated with
- *                            this invocation of @ref SendPresenceNotification.
- *
- */
-typedef enum
-{
-    OC_PRESENCE_TRIGGER_CREATE = 0,
-    OC_PRESENCE_TRIGGER_CHANGE = 1,
-    OC_PRESENCE_TRIGGER_DELETE = 2
-} OCPresenceTrigger;
 
 /**
  * Notify Presence subscribers that a resource has been modified.
diff --git a/resource/csdk/stack/include/ocpayload.h b/resource/csdk/stack/include/ocpayload.h
new file mode 100644 (file)
index 0000000..91776c4
--- /dev/null
@@ -0,0 +1,384 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef OCPAYLOAD_H_
+#define OCPAYLOAD_H_
+
+#include <stdbool.h>
+#include <inttypes.h>
+#include "logger.h"
+#include "octypes.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct OCResource OCResource;
+
+#ifdef TB_LOG
+    #define OC_LOG_PAYLOAD(level, tag, payload) OCPayloadLog((level),(tag),(payload))
+    #define UUID_SIZE (16)
+    #define UUID_LENGTH (37)
+const char *convertTriggerEnumToString(OCPresenceTrigger trigger);
+OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr);
+
+static inline void OCPayloadLogRep(LogLevel level, const char* tag, OCRepPayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Representation"));
+    OCRepPayload* rep = payload;
+    int i = 1;
+    while(rep)
+    {
+        OC_LOG_V(level, tag, "\tResource #%d", i);
+        OC_LOG_V(level, tag, "\tURL:%s", rep->uri);
+        OC_LOG(level, tag, PCF("\tResource Types:"));
+        OCStringLL* strll =  rep->types;
+        while(strll)
+        {
+            OC_LOG_V(level, tag, "\t\t%s", strll->value);
+            strll = strll->next;
+        }
+        OC_LOG(level, tag, PCF("\tInterfaces:"));
+        strll =  rep->interfaces;
+        while(strll)
+        {
+            OC_LOG_V(level, tag, "\t\t%s", strll->value);
+            strll = strll->next;
+        }
+
+        // TODO Finish Logging: Values
+        OCRepPayloadValue* val = rep->values;
+
+        OC_LOG(level, tag, PCF("\tValues:"));
+
+        while(val)
+        {
+            switch(val->type)
+            {
+                case OCREP_PROP_NULL:
+                    OC_LOG_V(level, tag, "\t\t%s: NULL", val->name);
+                    break;
+                case OCREP_PROP_INT:
+                    OC_LOG_V(level, tag, "\t\t%s(int):%lld", val->name, val->i);
+                    break;
+                case OCREP_PROP_DOUBLE:
+                    OC_LOG_V(level, tag, "\t\t%s(double):%f", val->name, val->d);
+                    break;
+                case OCREP_PROP_BOOL:
+                    OC_LOG_V(level, tag, "\t\t%s(bool):%s", val->name, val->b ? "true" : "false");
+                    break;
+                case OCREP_PROP_STRING:
+                    OC_LOG_V(level, tag, "\t\t%s(string):%s", val->name, val->str);
+                    break;
+                case OCREP_PROP_OBJECT:
+                    // Note: Only prints the URI (if available), to print further, you'll
+                    // need to dig into the object better!
+                    OC_LOG_V(level, tag, "\t\t%s(OCRep):%s", val->name, val->obj->uri);
+                    break;
+                case OCREP_PROP_ARRAY:
+                    switch(val->arr.type)
+                    {
+                        case OCREP_PROP_INT:
+                            OC_LOG_V(level, tag, "\t\t%s(int array):%lld x %lld x %lld",
+                                    val->name,
+                                    val->arr.dimensions[0], val->arr.dimensions[1],
+                                    val->arr.dimensions[2]);
+                            break;
+                        case OCREP_PROP_DOUBLE:
+                            OC_LOG_V(level, tag, "\t\t%s(double array):%lld x %lld x %lld",
+                                    val->name,
+                                    val->arr.dimensions[0], val->arr.dimensions[1],
+                                    val->arr.dimensions[2]);
+                            break;
+                        case OCREP_PROP_BOOL:
+                            OC_LOG_V(level, tag, "\t\t%s(bool array):%lld x %lld x %lld",
+                                    val->name,
+                                    val->arr.dimensions[0], val->arr.dimensions[1],
+                                    val->arr.dimensions[2]);
+                            break;
+                        case OCREP_PROP_STRING:
+                            OC_LOG_V(level, tag, "\t\t%s(string array):%lld x %lld x %lld",
+                                    val->name,
+                                    val->arr.dimensions[0], val->arr.dimensions[1],
+                                    val->arr.dimensions[2]);
+                            break;
+                        case OCREP_PROP_OBJECT:
+                            OC_LOG_V(level, tag, "\t\t%s(OCRep array):%lld x %lld x %lld",
+                                    val->name,
+                                    val->arr.dimensions[0], val->arr.dimensions[1],
+                                    val->arr.dimensions[2]);
+                            break;
+                        default:
+                            OC_LOG_V(ERROR, tag, "\t\t%s <-- Unknown/unsupported array type!",
+                                    val->name);
+                            break;
+                    }
+                    break;
+                default:
+                    OC_LOG_V(ERROR, tag, "\t\t%s <-- Unknown type!", val->name);
+                    break;
+            }
+            val = val -> next;
+        }
+
+        ++i;
+        rep = rep->next;
+    }
+
+}
+
+static inline void OCPayloadLogDiscovery(LogLevel level, const char* tag,
+        OCDiscoveryPayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Discovery"));
+    int i = 1;
+
+    if(!payload->resources)
+    {
+        OC_LOG(level, tag, PCF("\tNO Resources"));
+        return;
+    }
+
+    OCResourcePayload* res = payload->resources;
+
+    while(res)
+    {
+        OC_LOG_V(level, tag, "\tResource #%d", i);
+        OC_LOG_V(level, tag, "\tURI:%s", res->uri);
+        OC_LOG(level, tag, PCF("\tSID:"));
+        OC_LOG_BUFFER(level, tag, res->sid, UUID_SIZE);
+        OC_LOG(level, tag, PCF("\tResource Types:"));
+        OCStringLL* strll =  res->types;
+        while(strll)
+        {
+            OC_LOG_V(level, tag, "\t\t%s", strll->value);
+            strll = strll->next;
+        }
+        OC_LOG(level, tag, PCF("\tInterfaces:"));
+        strll =  res->interfaces;
+        while(strll)
+        {
+            OC_LOG_V(level, tag, "\t\t%s", strll->value);
+            strll = strll->next;
+        }
+
+        OC_LOG_V(level, tag, "\tBitmap: %u", res->bitmap);
+        OC_LOG_V(level, tag, "\tSecure?: %s", res->secure ? "true" : "false");
+        OC_LOG_V(level, tag, "\tPort: %u", res->port);
+        OC_LOG(level, tag, PCF(""));
+        res = res->next;
+        ++i;
+    }
+}
+
+static inline void OCPayloadLogDevice(LogLevel level, const char* tag, OCDevicePayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Device"));
+    OC_LOG_V(level, tag, "\tURI:%s", payload->uri);
+    OC_LOG(level, tag, PCF("\tSID:"));
+    OC_LOG_BUFFER(level, tag, payload->sid, UUID_SIZE);
+    OC_LOG_V(level, tag, "\tDevice Name:%s", payload->deviceName);
+    OC_LOG_V(level, tag, "\tSpec Version%s", payload->specVersion);
+    OC_LOG_V(level, tag, "\tData Model Version:%s", payload->dataModelVersion);
+}
+
+static inline void OCPayloadLogPlatform(LogLevel level, const char* tag, OCPlatformPayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Platform"));
+    OC_LOG_V(level, tag, "\tURI:%s", payload->uri);
+    OC_LOG_V(level, tag, "\tPlatform ID:%s", payload->info.platformID);
+    OC_LOG_V(level, tag, "\tMfg Name:%s", payload->info.manufacturerName);
+    OC_LOG_V(level, tag, "\tMfg URL:%s", payload->info.manufacturerUrl);
+    OC_LOG_V(level, tag, "\tModel Number:%s", payload->info.modelNumber);
+    OC_LOG_V(level, tag, "\tDate of Mfg:%s", payload->info.dateOfManufacture);
+    OC_LOG_V(level, tag, "\tPlatform Version:%s", payload->info.platformVersion);
+    OC_LOG_V(level, tag, "\tOS Version:%s", payload->info.operatingSystemVersion);
+    OC_LOG_V(level, tag, "\tHardware Version:%s", payload->info.hardwareVersion);
+    OC_LOG_V(level, tag, "\tFirmware Version:%s", payload->info.firmwareVersion);
+    OC_LOG_V(level, tag, "\tSupport URL:%s", payload->info.supportUrl);
+    OC_LOG_V(level, tag, "\tSystem Time:%s", payload->info.systemTime);
+}
+
+static inline void OCPayloadLogPresence(LogLevel level, const char* tag, OCPresencePayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Presence"));
+    OC_LOG_V(level, tag, "\tSequence Number:%u", payload->sequenceNumber);
+    OC_LOG_V(level, tag, "\tMax Age:%d", payload->maxAge);
+    OC_LOG_V(level, tag, "\tTrigger:%s", convertTriggerEnumToString(payload->trigger));
+    OC_LOG_V(level, tag, "\tResource Type:%s", payload->resourceType);
+}
+
+static inline void OCPayloadLogSecurity(LogLevel level, const char* tag,
+                                        OCSecurityPayload* payload)
+{
+    OC_LOG(level, tag, PCF("Payload Type: Security"));
+    OC_LOG_V(level, tag, "\tSecurity Data: %s", payload->securityData);
+}
+
+static inline void OCPayloadLog(LogLevel level, const char* tag, OCPayload* payload)
+{
+    if(!payload)
+    {
+        OC_LOG(level, tag, PCF("NULL Payload"));
+        return;
+    }
+    switch(payload->type)
+    {
+        case PAYLOAD_TYPE_REPRESENTATION:
+            OCPayloadLogRep(level, tag, (OCRepPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_DISCOVERY:
+            OCPayloadLogDiscovery(level, tag, (OCDiscoveryPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_DEVICE:
+            OCPayloadLogDevice(level, tag, (OCDevicePayload*)payload);
+            break;
+        case PAYLOAD_TYPE_PLATFORM:
+            OCPayloadLogPlatform(level, tag, (OCPlatformPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_PRESENCE:
+            OCPayloadLogPresence(level, tag, (OCPresencePayload*)payload);
+            break;
+        case PAYLOAD_TYPE_SECURITY:
+            OCPayloadLogSecurity(level, tag, (OCSecurityPayload*)payload);
+            break;
+        default:
+            OC_LOG_V(level, tag, "Unknown Payload Type: %d", payload->type);
+            break;
+    }
+}
+#else
+    #define OC_LOG_PAYLOAD(level, tag, payload)
+#endif
+
+void OCPayloadDestroy(OCPayload* payload);
+
+// Representation Payload
+OCRepPayload* OCRepPayloadCreate();
+
+size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+OCRepPayload* OCRepPayloadClone(const OCRepPayload* payload);
+
+void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child);
+
+bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri);
+
+bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType);
+bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* interface);
+
+bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType);
+bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* interface);
+
+bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name);
+bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name);
+
+bool OCRepPayloadSetPropInt(OCRepPayload* payload, const char* name, int64_t value);
+bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value);
+
+bool OCRepPayloadSetPropDouble(OCRepPayload* payload, const char* name, double value);
+bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value);
+
+bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value);
+bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value);
+bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, const char** value);
+
+bool OCRepPayloadSetPropBool(OCRepPayload* payload, const char* name, bool value);
+bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value);
+
+bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value);
+bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name,
+        OCRepPayload* value);
+bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value);
+
+bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
+        int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
+        const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
+        int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
+        double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
+        const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
+        double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
+        char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
+        const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
+        char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
+        bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
+        const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
+        bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
+        OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
+        const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
+        OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]);
+
+void OCRepPayloadDestroy(OCRepPayload* payload);
+
+// Discovery Payload
+OCDiscoveryPayload* OCDiscoveryPayloadCreate();
+
+OCSecurityPayload* OCSecurityPayloadCreate(char* securityData);
+void OCSecurityPayloadDestroy(OCSecurityPayload* payload);
+
+void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
+        uint16_t port);
+void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res);
+size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload);
+OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index);
+
+void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload);
+
+// Device Payload
+OCDevicePayload* OCDevicePayloadCreate(const char* uri, const uint8_t* sid, const char* dname,
+        const char* specVer, const char* dmVer);
+void OCDevicePayloadDestroy(OCDevicePayload* payload);
+
+// Platform Payload
+OCPlatformPayload* OCPlatformPayloadCreate(const char* uri, const OCPlatformInfo* platformInfo);
+OCPlatformPayload* OCPlatformPayloadCreateAsOwner(char* uri, OCPlatformInfo* platformInfo);
+
+void OCPlatformPayloadDestroy(OCPlatformPayload* payload);
+
+// Presence Payload
+OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
+        OCPresenceTrigger trigger, const char* resourceType);
+void OCPresencePayloadDestroy(OCPresencePayload* payload);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/resource/csdk/stack/include/ocpresence.h b/resource/csdk/stack/include/ocpresence.h
new file mode 100644 (file)
index 0000000..688b7d9
--- /dev/null
@@ -0,0 +1,47 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef OCPRESENCE_H_
+#define OCPRESENCE_H_
+
+#ifdef WITH_PRESENCE
+/**
+ * The OCPresenceTrigger enum delineates the three spec-compliant modes for
+ * "Trigger." These enum values are then mapped to strings
+ * "create", "change", "delete", respectively, before getting encoded into
+ * the payload payload.
+ *
+ * @enum OC_PRESENCE_TRIGGER_CREATE The creation of a resource is associated with
+ *                            this invocation of @ref SendPresenceNotification.
+ * @enum OC_PRESENCE_TRIGGER_CHANGE The change/update of a resource is associated
+ *                            this invocation of @ref SendPresenceNotification.
+ * @enum OC_PRESENCE_TRIGGER_DELETE The deletion of a resource is associated with
+ *                            this invocation of @ref SendPresenceNotification.
+ *
+ */
+typedef enum
+{
+    OC_PRESENCE_TRIGGER_CREATE = 0,
+    OC_PRESENCE_TRIGGER_CHANGE = 1,
+    OC_PRESENCE_TRIGGER_DELETE = 2
+} OCPresenceTrigger;
+#endif
+
+#endif
index fa10079..86ec2b9 100644 (file)
@@ -118,7 +118,7 @@ OCStackResult OCDoResource(OCDoHandle *handle,
                             OCMethod method,
                             const char *requestUri,
                             const OCDevAddr *destination,
-                            const char *request,
+                            OCPayload* payload,
                             OCConnectivityType connectivityType,
                             OCQualityOfService qos,
                             OCCallbackData *cbData,
@@ -438,7 +438,7 @@ OCStackResult OCNotifyAllObservers(OCResourceHandle handle, OCQualityOfService q
  * @param handle Handle of resource.
  * @param obsIdList List of observation ids that need to be notified.
  * @param numberOfIds Number of observation ids included in obsIdList.
- * @param notificationJSONPayload JSON encoded payload to send in notification.
+ * @param payload OCRepresentationPayload object representing the notification
  * @param qos Desired quality of service of the observation notifications.
  * NOTE: The memory for obsIdList and notificationJSONPayload is managed by the
  * entity invoking the API. The maximum size of the notification is 1015 bytes
@@ -450,7 +450,7 @@ OCStackResult
 OCNotifyListOfObservers (OCResourceHandle handle,
                             OCObservationId  *obsIdList,
                             uint8_t          numberOfIds,
-                            const char    *notificationJSONPayload,
+                            const OCRepPayload *payload,
                             OCQualityOfService qos);
 
 
index eb7e565..d1463eb 100644 (file)
@@ -38,9 +38,9 @@
  * They have a combined size of 10 bytes.
  */
 #ifdef WITH_ARDUINO
-#define MAX_RESPONSE_LENGTH (246)
+#define MAX_RESPONSE_LENGTH (256)
 #else
-#define MAX_RESPONSE_LENGTH (1014)
+#define MAX_RESPONSE_LENGTH (1024)
 #endif
 
 /**
index 1ee5146..58bb476 100644 (file)
 #define OCTYPES_H_
 
 #include "ocstackconfig.h"
-
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
 #ifdef __cplusplus
 #include <string.h>
 
 extern "C" {
 #endif // __cplusplus
 #define WITH_PRESENCE
+#include "ocpresence.h"
 //-----------------------------------------------------------------------------
 // Defines
 //-----------------------------------------------------------------------------
@@ -50,7 +53,7 @@ extern "C" {
 /**
  * Attributes used to form a proper OIC conforming JSON message.
  */
-#define OC_RSRVD_OC                     "oic"
+//#define OC_RSRVD_OC                     "oic"
 #define OC_RSRVD_PAYLOAD                "payload"
 #define OC_RSRVD_HREF                   "href"
 #define OC_RSRVD_PROPERTY               "prop"
@@ -498,6 +501,168 @@ typedef struct OCHeaderOption
 #endif
 } OCHeaderOption;
 
+/**
+ * This structure describes the platform properties. All non-Null properties will be included
+ * in a platform discovery request.
+ */
+typedef struct
+{
+    char *platformID;
+    char *manufacturerName;
+    char *manufacturerUrl;
+    char *modelNumber;
+    char *dateOfManufacture;
+    char *platformVersion;
+    char *operatingSystemVersion;
+    char *hardwareVersion;
+    char *firmwareVersion;
+    char *supportUrl;
+    char *systemTime;
+
+} OCPlatformInfo;
+
+/**
+ * This structure is expected as input for device properties.
+ * device name is mandatory and expected from the application.
+ * device id of type UUID will be generated by the stack.
+ */
+typedef struct
+{
+    char *deviceName;
+
+} OCDeviceInfo;
+
+// Enum to describe the type of object held by the OCPayload object
+typedef enum
+{
+    PAYLOAD_TYPE_INVALID,
+    PAYLOAD_TYPE_DISCOVERY,
+    PAYLOAD_TYPE_DEVICE,
+    PAYLOAD_TYPE_PLATFORM,
+    PAYLOAD_TYPE_REPRESENTATION,
+    PAYLOAD_TYPE_SECURITY,
+    PAYLOAD_TYPE_PRESENCE
+} OCPayloadType;
+
+typedef struct
+{
+    // The type of message that was received
+    OCPayloadType type;
+} OCPayload;
+
+typedef enum
+{
+    OCREP_PROP_NULL,
+    OCREP_PROP_INT,
+    OCREP_PROP_DOUBLE,
+    OCREP_PROP_BOOL,
+    OCREP_PROP_STRING,
+    OCREP_PROP_OBJECT,
+    OCREP_PROP_ARRAY
+}OCRepPayloadPropType;
+
+#define MAX_REP_ARRAY_DEPTH 3
+typedef struct
+{
+    OCRepPayloadPropType type;
+    size_t dimensions[MAX_REP_ARRAY_DEPTH];
+
+    union
+    {
+        int64_t* iArray;
+        double* dArray;
+        bool* bArray;
+        char** strArray;
+        struct OCRepPayload** objArray;
+    };
+} OCRepPayloadValueArray;
+
+typedef struct OCRepPayloadValue
+{
+    char* name;
+    OCRepPayloadPropType type;
+    union
+    {
+        int64_t i;
+        double d;
+        bool b;
+        char* str;
+        struct OCRepPayload* obj;
+        OCRepPayloadValueArray arr;
+    };
+    struct OCRepPayloadValue* next;
+
+} OCRepPayloadValue;
+
+typedef struct OCStringLL
+{
+    struct OCStringLL *next;
+    char* value;
+} OCStringLL;
+
+// used for get/set/put/observe/etc representations
+typedef struct OCRepPayload
+{
+    OCPayload base;
+    char* uri;
+    OCStringLL* types;
+    OCStringLL* interfaces;
+    OCRepPayloadValue* values;
+    struct OCRepPayload* next;
+} OCRepPayload;
+
+// used inside a discovery payload
+typedef struct OCResourcePayload
+{
+    char* uri;
+    uint8_t* sid;
+    OCStringLL* types;
+    OCStringLL* interfaces;
+    uint8_t bitmap;
+    bool secure;
+    uint16_t port;
+    struct OCResourcePayload* next;
+} OCResourcePayload;
+
+typedef struct
+{
+    OCPayload base;
+    OCResourcePayload* resources;
+} OCDiscoveryPayload;
+
+typedef struct
+{
+    OCPayload base;
+    char* uri;
+    uint8_t* sid;
+    char* deviceName;
+    char* specVersion;
+    char* dataModelVersion;
+} OCDevicePayload;
+
+typedef struct
+{
+    OCPayload base;
+    char* uri;
+    OCPlatformInfo info;
+} OCPlatformPayload;
+
+typedef struct
+{
+    OCPayload base;
+    char* securityData;
+} OCSecurityPayload;
+#ifdef WITH_PRESENCE
+typedef struct
+{
+    OCPayload base;
+    uint32_t sequenceNumber;
+    uint32_t maxAge;
+    OCPresenceTrigger trigger;
+    char* resourceType;
+} OCPresencePayload;
+#endif
+
 /**
  * Incoming requests handled by the server. Requests are passed in as a parameter to the
  * @ref OCEntityHandler callback API.
@@ -519,8 +684,8 @@ typedef struct
     // An array of the received vendor specific header options
     uint8_t numRcvdVendorSpecificHeaderOptions;
     OCHeaderOption * rcvdVendorSpecificHeaderOptions;
-    // reqJSON is retrieved from the payload of the received request PDU
-    char * reqJSONPayload;
+    // the payload from the request PDU
+    OCPayload *payload;
 } OCEntityHandlerRequest;
 
 /**
@@ -538,44 +703,13 @@ typedef struct
     uint32_t sequenceNumber;
     /// resourceURI
     const char * resourceUri;
-    /// resJSONPayload is retrieved from the payload of the received request PDU
-    const char * resJSONPayload;
+    // the payload for the response PDU
+    OCPayload *payload;
     /// An array of the received vendor specific header options
     uint8_t numRcvdVendorSpecificHeaderOptions;
     OCHeaderOption rcvdVendorSpecificHeaderOptions[MAX_HEADER_OPTIONS];
 } OCClientResponse;
 
-/**
- * This structure describes the platform properties. All non-Null properties will be included
- * in a platform discovery request.
- */
-typedef struct
-{
-    char *platformID;
-    char *manufacturerName;
-    char *manufacturerUrl;
-    char *modelNumber;
-    char *dateOfManufacture;
-    char *platformVersion;
-    char *operatingSystemVersion;
-    char *hardwareVersion;
-    char *firmwareVersion;
-    char *supportUrl;
-    char *systemTime;
-
-} OCPlatformInfo;
-
-/**
- * This structure is expected as input for device properties.
- * device name is mandatory and expected from the application.
- * device id of type UUID will be generated by the stack.
- */
-typedef struct
-{
-    char *deviceName;
-
-} OCDeviceInfo;
-
 typedef struct
 {
     // Request handle is passed to server via the entity handler for each incoming request.
@@ -586,9 +720,7 @@ typedef struct
     // Allow the entity handler to pass a result with the response
     OCEntityHandlerResult  ehResult;
     // this is the pointer to server payload data to be transferred
-    char *payload;
-    // size of server payload data.  I don't think we should rely on null terminated data for size
-    uint16_t payloadSize;
+    OCPayload* payload;
     // An array of the vendor specific header options the entity handler wishes to use in response
     uint8_t numSendVendorSpecificHeaderOptions;
     OCHeaderOption sendVendorSpecificHeaderOptions[MAX_HEADER_OPTIONS];
index 4da7bb6..ebde612 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "logger.h"
 #include "ocstack.h"
+#include "ocpayload.h"
 #include <string.h>
 
 #ifdef ARDUINOWIFI
@@ -57,9 +58,6 @@ typedef struct LIGHTRESOURCE{
 
 static LightResource Light;
 
-static char responsePayloadGet[] = "{\"href\":\"/a/light\",\"rep\":{\"state\":true,\"power\":10}}";
-static char responsePayloadPut[] = "{\"href\":\"/a/light\",\"rep\":{\"state\":false,\"power\":0}}";
-
 #ifdef ARDUINOWIFI
 // Arduino WiFi Shield
 // Note : Arduino WiFi Shield currently does NOT support multicast and therefore
@@ -154,7 +152,12 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandle
 {
     OCEntityHandlerResult ehRet = OC_EH_OK;
     OCEntityHandlerResponse response = {0};
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
+        return OC_EH_ERROR;
+    }
 
     if(entityHandlerRequest && (flag & OC_REQUEST_FLAG))
     {
@@ -162,28 +165,16 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandle
 
         if(OC_REST_GET == entityHandlerRequest->method)
         {
-            size_t responsePayloadGetLength = strlen(responsePayloadGet);
-            if (responsePayloadGetLength < (sizeof(payload) - 1))
-            {
-                strncpy(payload, responsePayloadGet, responsePayloadGetLength);
-            }
-            else
-            {
-                ehRet = OC_EH_ERROR;
-            }
+            OCRepPayloadSetUri(payload, "/a/light");
+            OCRepPayloadSetPropBool(payload, "state", true);
+            OCRepPayloadSetPropInt(payload, "power", 10);
         }
         else if(OC_REST_PUT == entityHandlerRequest->method)
         {
             //Do something with the 'put' payload
-            size_t responsePayloadPutLength = strlen(responsePayloadPut);
-            if (responsePayloadPutLength < (sizeof(payload) - 1))
-            {
-                strncpy((char *)payload, responsePayloadPut, responsePayloadPutLength);
-            }
-            else
-            {
-                ehRet = OC_EH_ERROR;
-            }
+            OCRepPayloadSetUri(payload, "/a/light");
+            OCRepPayloadSetPropBool(payload, "state", false);
+            OCRepPayloadSetPropInt(payload, "power", 0);
         }
 
         if (ehRet == OC_EH_OK)
@@ -192,8 +183,7 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandle
             response.requestHandle = entityHandlerRequest->requestHandle;
             response.resourceHandle = entityHandlerRequest->resource;
             response.ehResult = ehRet;
-            response.payload = payload;
-            response.payloadSize = strlen(payload);
+            response.payload = (OCPayload*) payload;
             response.numSendVendorSpecificHeaderOptions = 0;
             memset(response.sendVendorSpecificHeaderOptions, 0,
                     sizeof response.sendVendorSpecificHeaderOptions);
index d3f4b2a..c5f84c7 100644 (file)
@@ -28,6 +28,7 @@
 #include "ocstack.h"
 #include "logger.h"
 #include "occlient.h"
+#include "ocpayload.h"
 
 // Tracking user input
 static int UNICAST_DISCOVERY = 0;
@@ -44,7 +45,6 @@ static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oic/res";
 //The following variable determines the interface protocol (IPv4, IPv6, etc)
 //to be used for sending unicast messages. Default set to IPv4.
 static OCConnectivityType OC_CONNTYPE = CT_ADAPTER_IP;
-static std::string putPayload = "{\"oic\":[{\"rep\":{\"power\":15,\"state\":true}}]}";
 static std::string coapServerIP = "255.255.255.255";
 static std::string coapServerPort = "5683";
 static std::string coapServerResource = "/a/light";
@@ -77,6 +77,22 @@ void handleSigInt(int signum)
     }
 }
 
+OCPayload* putPayload()
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if(!payload)
+    {
+        std::cout << "Failed to create put payload object"<<std::endl;
+        std::exit(1);
+    }
+
+    OCRepPayloadSetPropInt(payload, "power", 15);
+    OCRepPayloadSetPropBool(payload, "state", true);
+
+    return (OCPayload*) payload;
+}
+
 static void PrintUsage()
 {
     OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1..17> -c <0|1>");
@@ -132,7 +148,7 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.cd = NULL;
 
     ret = OCDoResource(&handle, method, query.str().c_str(), 0,
-                       (method == OC_REST_PUT) ? putPayload.c_str() : NULL,
+                       (method == OC_REST_PUT) ? putPayload() : NULL,
                        (OC_CONNTYPE), qos, &cbData, options, numOptions);
 
     if (ret != OC_STACK_OK)
@@ -163,8 +179,8 @@ OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse
     if(clientResponse)
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Put Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Put Response"));
     }
     else
     {
@@ -183,8 +199,8 @@ OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle, OCClientRespons
     if(clientResponse)
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Post Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Post Response"));
     }
     else
     {
@@ -204,8 +220,8 @@ OCStackApplicationResult deleteReqCB(void *ctx,
     if(clientResponse)
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Delete Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Delete Response"));
     }
     else
     {
@@ -229,7 +245,8 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
 
     OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
     OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
-    OC_LOG_V(INFO, TAG, "JSON = %s =============> Get Response", clientResponse->resJSONPayload);
+    OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+    OC_LOG(INFO, TAG, PCF("=============> Get Response"));
 
     if(clientResponse->numRcvdVendorSpecificHeaderOptions > 0)
     {
@@ -264,8 +281,8 @@ OCStackApplicationResult obsReqCB(void* ctx, OCDoHandle handle, OCClientResponse
         OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
         OC_LOG_V(INFO, TAG, "Callback Context for OBSERVE notification recvd successfully %d",
                 gNumObserveNotifies);
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Obs Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Obs Response"));
         gNumObserveNotifies++;
         if (gNumObserveNotifies == 15) //large number to test observing in DELETE case.
         {
@@ -320,8 +337,8 @@ OCStackApplicationResult presenceCB(void* ctx, OCDoHandle handle, OCClientRespon
         OC_LOG_V(INFO, TAG, "NONCE NUMBER: %u", clientResponse->sequenceNumber);
         OC_LOG_V(INFO, TAG, "Callback Context for Presence notification recvd successfully %d",
                 gNumPresenceNotifies);
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Presence Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Presence Response"));
         gNumPresenceNotifies++;
         if (gNumPresenceNotifies == 20)
         {
@@ -356,8 +373,10 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
         std::string connectionType = getConnectivityType (clientResponse->connType);
         OC_LOG_V(INFO, TAG, "Discovered on %s", connectionType.c_str());
         OC_LOG_V(INFO, TAG,
-                "Device =============> Discovered %s @ %s:%d",
-                clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
+                "Device =============> Discovered @ %s:%d",
+                clientResponse->devAddr.addr,
+                clientResponse->devAddr.port);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
 
         parseClientResponse(clientResponse);
 
@@ -436,9 +455,8 @@ OCStackApplicationResult PlatformDiscoveryReqCB (void* ctx, OCDoHandle handle,
 
     if(clientResponse)
     {
-        //OC_LOG truncates the response as it is too long.
-        fprintf(stderr, "Discovery response: \n %s\n", clientResponse->resJSONPayload);
-        fflush(stderr);
+        OC_LOG(INFO, TAG, PCF("Discovery Response:"));
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
     }
     else
     {
@@ -458,9 +476,8 @@ OCStackApplicationResult DeviceDiscoveryReqCB (void* ctx, OCDoHandle handle,
 
     if(clientResponse)
     {
-        //OC_LOG truncates the response as it is too long.
-        fprintf(stderr, "Discovery response: \n %s\n", clientResponse->resJSONPayload);
-        fflush(stderr);
+        OC_LOG(INFO, TAG, PCF("Discovery Response:"));
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
     }
     else
     {
index 8f1eb62..70c69a1 100644 (file)
 #include <unistd.h>
 #include <stdint.h>
 #include <sstream>
+#include <iostream>
 
 #include "ocstack.h"
 #include "logger.h"
 #include "occlientbasicops.h"
-#include "cJSON.h"
+#include "ocpayload.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 
@@ -41,7 +42,6 @@ static int TEST_CASE = 0;
 static int CONNECTIVITY = 0;
 
 static const char UNICAST_DISCOVERY_QUERY[] = "coap://%s/oic/res";
-static std::string putPayload = "{\"oic\":[{\"rep\":{\"power\":15,\"state\":true}}]}";
 
 //The following variable determines the interface protocol (IP, etc)
 //to be used for sending unicast messages. Default set to IP.
@@ -62,6 +62,22 @@ void handleSigInt(int signum)
     }
 }
 
+OCPayload* putPayload()
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if(!payload)
+    {
+        std::cout << "Failed to create put payload object"<<std::endl;
+        std::exit(1);
+    }
+
+    OCRepPayloadSetPropInt(payload, "power", 15);
+    OCRepPayloadSetPropBool(payload, "state", true);
+
+    return (OCPayload*) payload;
+}
+
 static void PrintUsage()
 {
     OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1|2|3> -c <0|1>");
@@ -95,7 +111,7 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query, OCMethod method,
     cbData.cd = NULL;
 
     ret = OCDoResource(NULL, method, query.str().c_str(), 0,
-        (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload.c_str() : NULL,
+        (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload() : NULL,
          connType, qos, &cbData, options, numOptions);
 
     if (ret != OC_STACK_OK)
@@ -121,8 +137,8 @@ OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle,
 
     if(clientResponse)
     {
-        OC_LOG_V(INFO, TAG,"PUT Response: %s \nFrom %s:%d\n",
-                 clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Put Response"));
     }
     else
     {
@@ -145,8 +161,8 @@ OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle,
 
     if(clientResponse)
     {
-        OC_LOG_V(INFO, TAG,"POST Response: %s \nFrom %s:%d\n",
-                    clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Post Response"));
     }
     else
     {
@@ -170,8 +186,10 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle,
 
     if (clientResponse)
     {
-        OC_LOG_V(INFO, TAG,"Get Response: %s \nFrom %s:%d\n",
-                clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
+        OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
+        OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Get Response"));
 
         if (clientResponse->numRcvdVendorSpecificHeaderOptions > 0 )
         {
@@ -217,8 +235,10 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
     if (clientResponse)
     {
         OC_LOG_V(INFO, TAG,
-                "Device Discovered %s \n @ %s:%d\n",
-                clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
+                "Device =============> Discovered @ %s:%d",
+                clientResponse->devAddr.addr,
+                clientResponse->devAddr.port);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
 
         collectUniqueResource(clientResponse);
     }
@@ -396,99 +416,6 @@ const char *getPort(const OCClientResponse *clientResponse)
     return port;
 }
 
-int parseJSON(const char * resJSONPayload, char ** sid_c,
-              char *** uri_c, int * totalRes)
-{
-    cJSON * root = NULL;
-    cJSON * oc = NULL;
-
-    root = cJSON_Parse((char *)(resJSONPayload));
-
-    if (!root)
-    {
-        OC_LOG(ERROR, TAG, "JSON Parsing Error");
-        return OC_STACK_INVALID_JSON;
-    }
-
-    oc = cJSON_GetObjectItem(root,"oic");
-    if (!oc)
-    {
-        OC_LOG(ERROR, TAG, "Invalid JSON : Missing oc object");
-        return OC_STACK_INVALID_JSON;
-    }
-
-    * totalRes = cJSON_GetArraySize(oc);
-
-    if(oc->type == cJSON_Array)
-    {
-        cJSON * resource = cJSON_GetArrayItem(oc, 0);
-
-        if(!resource)
-        {
-            return OC_STACK_INVALID_JSON;
-        }
-
-        if (cJSON_GetObjectItem(resource, "sid"))
-        {
-            char * sid = cJSON_GetObjectItem(resource, "sid")->valuestring;
-            if((* sid_c = (char *)OICCalloc(1, strlen (sid) + 1)))
-            {
-                memcpy(* sid_c, sid, strlen(sid) + 1);
-            }
-            else
-            {
-                OC_LOG(ERROR, TAG, "Memory not allocated to sid");
-                return OC_STACK_NO_MEMORY;
-            }
-        }
-        else
-        {
-            OC_LOG(ERROR, TAG, "Invalid JSON : Missing sid object");
-            return OC_STACK_INVALID_JSON;
-        }
-
-        if(!(* uri_c =  (char ** )OICMalloc ((* totalRes) * sizeof(char *))))
-        {
-            OC_LOG(ERROR, TAG, "Memory not allocated to uri_c array");
-            return OC_STACK_NO_MEMORY;
-        }
-
-        int i = 0;
-
-        while(true)
-        {
-            if (cJSON_GetObjectItem(resource, "href"))
-            {
-                char *uri= cJSON_GetObjectItem(resource, "href")->valuestring;
-                if(((*uri_c)[i] = (char *)OICCalloc(1, strlen (uri) + 1)))
-                {
-                    memcpy((*uri_c)[i], uri, strlen(uri) + 1);
-                }
-                else
-                {
-                    OC_LOG(ERROR, TAG, "Memory not allocated to uri");
-                    return OC_STACK_NO_MEMORY;
-                }
-                i++;
-                if(i >= (* totalRes))
-                    break;
-                resource = cJSON_GetArrayItem(oc, i);
-            }
-            else
-            {
-               OC_LOG(ERROR, TAG, "Invalid JSON : Missing uri object");
-               return OC_STACK_INVALID_JSON;
-           }
-        }
-    }
-    else
-    {
-        return OC_STACK_INVALID_JSON;
-        OC_LOG(ERROR, TAG, "Invalid JSON : oc object type is not an array");
-    }
-    return OC_STACK_OK;
-}
-
 void queryResource()
 {
     switch(TEST_CASE)
@@ -514,46 +441,38 @@ void queryResource()
 
 void collectUniqueResource(const OCClientResponse * clientResponse)
 {
-    char * sid = NULL;
-    char ** uri = NULL;
-    int totalRes = 0;
-    int i;
+    OCResourcePayload* res = ((OCDiscoveryPayload*)clientResponse->payload)->resources;
+    char sidStr[UUID_LENGTH];
 
-    if(parseJSON(clientResponse->resJSONPayload, & sid, & uri, &totalRes)
-            != OC_STACK_OK)
-    {
-        OC_LOG(ERROR, TAG, "Error while parsing JSON payload in OCClientResponse");
+    while(res) {
 
-        OICFree(sid);
-        for (i = 0; i < totalRes; i++)
-        {
-            OICFree(uri[i]);
-        }
-        OICFree(uri);
+        int ret = snprintf(sidStr, UUID_LENGTH,
+                "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+                res->sid[0], res->sid[1], res->sid[2], res->sid[3],
+                res->sid[4], res->sid[5], res->sid[6], res->sid[7],
+                res->sid[8], res->sid[9], res->sid[10], res->sid[11],
+                res->sid[12], res->sid[13], res->sid[14], res->sid[15]
+                );
 
-       return;
-    }
-
-    for(i = 0; i < totalRes; i++)
-    {
-        if(insertResource(sid, uri[i], clientResponse) == 1)
+        if (ret == UUID_LENGTH - 1)
         {
-            printf("%s%s%s%s\n",sid, ":", uri[i], " is new");
-            printResourceList();
-            queryResource();
+            if(insertResource(sidStr, res->uri, clientResponse) == 1)
+            {
+                OC_LOG_V(INFO,TAG,"%s%s%s%s\n",sidStr, ":", res->uri, " is new");
+                printResourceList();
+                queryResource();
+            }
+            else {
+                OC_LOG_V(INFO,TAG,"%s%s%s%s\n",sidStr, ":", res->uri, " is old");
+            }
         }
         else
         {
-            printf("%s%s%s%s\n\n",sid, ":", uri[i], " has been seen before");
+            OC_LOG(ERROR, TAG, "Could Not Retrieve the Server ID");
         }
-    }
 
-    OICFree(sid);
-    for (i = 0; i < totalRes; i++)
-    {
-        OICFree(uri[i]);
+        res = res->next;
     }
-    OICFree(uri);
 }
 
 /* This function searches for the resource(sid:uri) in the ResourceList.
index 1180b43..8c4ce40 100644 (file)
 #include <ocstack.h>
 #include <iostream>
 #include <sstream>
+#include "ocpayload.h"
 #include "logger.h"
 const char *getResult(OCStackResult result);
 std::string getIPAddrTBServer(OCClientResponse * clientResponse);
 std::string getPortTBServer(OCClientResponse * clientResponse);
-std::string getQueryStrForGetPut(const char * responsePayload);
+std::string getQueryStrForGetPut();
 
 #define TAG PCF("occlient")
 #define DEFAULT_CONTEXT_VALUE 0x99
@@ -85,7 +86,6 @@ testToTextMap queryInterface[] = {
         {"?if=oic.if.ll", TEST_PUT_LINK_LIST},
 };
 
-static std::string putPayload = "{\"state\":\"off\",\"power\":\"0\"}";
 
 //The following variable determines the interface protocol (IP, etc)
 //to be used for sending unicast messages. Default set to IP.
@@ -115,6 +115,22 @@ int InitPutRequest(OCClientResponse * clientResponse);
 int InitGetRequest(OCClientResponse * clientResponse);
 int InitDiscovery();
 
+OCPayload* putPayload()
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if(!payload)
+    {
+        std::cout << "Failed to create put payload object"<<std::endl;
+        std::exit(1);
+    }
+
+    OCRepPayloadSetPropInt(payload, "power", 15);
+    OCRepPayloadSetPropBool(payload, "state", true);
+
+    return (OCPayload*) payload;
+}
+
 void PrintUsage()
 {
     OC_LOG(INFO, TAG, "Usage : occlientcoll -t <Test Case> -c <CA connectivity Type>");
@@ -150,7 +166,7 @@ OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse
     if(ctx == (void*)DEFAULT_CONTEXT_VALUE)
     {
         OC_LOG_V(INFO, TAG, "Callback Context for PUT query recvd successfully");
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Discovered", clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
     }
 
     return OC_STACK_KEEP_TRANSACTION;
@@ -166,13 +182,13 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
         if(clientResponse->sequenceNumber == 0)
         {
             OC_LOG_V(INFO, TAG, "Callback Context for GET query recvd successfully");
-            OC_LOG_V(INFO, TAG, "Fnd' Rsrc': %s", clientResponse->resJSONPayload);
+            OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
         }
         else
         {
             OC_LOG_V(INFO, TAG, "Callback Context for Get recvd successfully %d",
                     gNumObserveNotifies);
-            OC_LOG_V(INFO, TAG, "Fnd' Rsrc': %s", clientResponse->resJSONPayload);
+            OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);;
             gNumObserveNotifies++;
             if (gNumObserveNotifies == 3)
             {
@@ -206,8 +222,10 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
     }
 
     OC_LOG_V(INFO, TAG,
-            "Device =============> Discovered %s @ %d.%d.%d.%d:%d",
-            clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
+            "Device =============> Discovered @ %s:%d",
+            clientResponse->devAddr.addr,
+            clientResponse->devAddr.port);
+    OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
 
     if(TEST == TEST_UNKNOWN_RESOURCE_GET_DEFAULT || TEST == TEST_UNKNOWN_RESOURCE_GET_BATCH ||\
             TEST == TEST_UNKNOWN_RESOURCE_GET_LINK_LIST)
@@ -251,11 +269,12 @@ int InitObserveRequest(OCClientResponse * clientResponse)
     std::ostringstream obsReg;
     obsReg << "coap://" << clientResponse->devAddr.addr << ":" <<
             clientResponse->devAddr.addr <<
-            getQueryStrForGetPut(clientResponse->resJSONPayload);
+            getQueryStrForGetPut();
     cbData.cb = getReqCB;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
-    OC_LOG_V(INFO, TAG, "OBSERVE payload from client = %s ", putPayload.c_str());
+    OC_LOG_V(INFO, TAG, "OBSERVE payload from client =");
+    OC_LOG_PAYLOAD(INFO, TAG, putPayload());
 
     ret = OCDoResource(&handle, OC_REST_OBSERVE, obsReg.str().c_str(), 0, 0, OC_CONNTYPE,
             OC_LOW_QOS, &cbData, NULL, 0);
@@ -283,9 +302,10 @@ int InitPutRequest(OCClientResponse * clientResponse)
     cbData.cb = putReqCB;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
-    OC_LOG_V(INFO, TAG, "PUT payload from client = %s ", putPayload.c_str());
+    OC_LOG_V(INFO, TAG, "PUT payload from client = ");
+    OC_LOG_PAYLOAD(INFO, TAG, putPayload());
 
-    ret = OCDoResource(NULL, OC_REST_PUT, getQuery.str().c_str(), 0, putPayload.c_str(),
+    ret = OCDoResource(NULL, OC_REST_PUT, getQuery.str().c_str(), 0, putPayload(),
                         OC_CONNTYPE, OC_LOW_QOS, &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
@@ -411,11 +431,8 @@ int main(int argc, char* argv[])
     return 0;
 }
 
-std::string getQueryStrForGetPut(const char * responsePayload)
+std::string getQueryStrForGetPut()
 {
-
-    std::string jsonPayload(responsePayload);
-
     return "/a/room";
 }
 
index 29b22c3..e875cf2 100644 (file)
@@ -28,6 +28,7 @@
 #include "ocstack.h"
 #include "logger.h"
 #include "occlientslow.h"
+#include "ocpayload.h"
 
 // Tracking user input
 static int UNICAST_DISCOVERY = 0;
@@ -35,9 +36,8 @@ static int TEST_CASE = 0;
 static int CONNECTIVITY = 0;
 
 static const char * UNICAST_DISCOVERY_QUERY = "coap://%s/oic/res";
-static std::string putPayload = "{\"state\":\"off\",\"power\":10}";
 static std::string coapServerIP = "255.255.255.255";
-static std::string coapServerPort = "5683";
+static uint16_t coapServerPort = 5683;
 static std::string coapServerResource = "/a/led";
 
 //The following variable determines the interface protocol (IP, etc)
@@ -67,6 +67,24 @@ static void PrintUsage()
     OC_LOG(INFO, TAG, "-t 1 : Discover Resources");
     OC_LOG(INFO, TAG, "-t 2 : Discover Resources and Initiate Nonconfirmable Get Request");
     OC_LOG(INFO, TAG, "-t 3 : Discover Resources and Initiate Confirmable Get Request");
+    OC_LOG(INFO, TAG, "-t 4 : Discover Resources and Initiate NonConfirmable Put Request");
+    OC_LOG(INFO, TAG, "-t 5 : Discover Resources and Initiate Confirmable Put Request");
+}
+
+OCPayload* putPayload()
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if(!payload)
+    {
+        std::cout << "Failed to create put payload object"<<std::endl;
+        std::exit(1);
+    }
+
+    OCRepPayloadSetPropInt(payload, "power", 15);
+    OCRepPayloadSetPropBool(payload, "state", true);
+
+    return (OCPayload*) payload;
 }
 
 OCStackResult InvokeOCDoResource(std::ostringstream &query,
@@ -81,7 +99,8 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.cd = NULL;
 
     ret = OCDoResource(NULL, method, query.str().c_str(), 0,
-            NULL, OC_CONNTYPE, qos, &cbData, options, numOptions);
+            (method == OC_REST_PUT) ? putPayload() : NULL,
+            OC_CONNTYPE, qos, &cbData, options, numOptions);
 
     if (ret != OC_STACK_OK)
     {
@@ -105,8 +124,8 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
 
     OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
     OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
-    OC_LOG_V(INFO, TAG, "JSON = %s =============> Get Response",
-            clientResponse->resJSONPayload);
+    OC_LOG(INFO, TAG, "Get Response =============> ");
+    OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
 
     if(clientResponse->rcvdVendorSpecificHeaderOptions &&
             clientResponse->numRcvdVendorSpecificHeaderOptions)
@@ -142,9 +161,9 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
 
-        OC_LOG_V(INFO, TAG,
-                "Device =============> Discovered %s @ %s:%d",
-                clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
+        OC_LOG_V(INFO, TAG, "Discovered @ %s:%u =============> ",
+            clientResponse->devAddr.addr, clientResponse->devAddr.port);
+        OC_LOG_PAYLOAD (INFO, TAG, clientResponse->payload);
 
         parseClientResponse(clientResponse);
 
@@ -156,6 +175,12 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
             case TEST_CON_OP:
                 InitGetRequest(OC_HIGH_QOS);
                 break;
+            case TEST_NON_CON_PUT:
+                InitPutRequest(OC_LOW_QOS);
+                break;
+            case TEST_CON_PUT:
+                InitPutRequest(OC_HIGH_QOS);
+                break;
             default:
                 PrintUsage();
                 break;
@@ -171,11 +196,21 @@ int InitGetRequest(OCQualityOfService qos)
     OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
     std::ostringstream query;
     query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
-
+    OC_LOG_V (INFO, TAG, "Performing GET with query : %s", query.str().c_str());
     return (InvokeOCDoResource(query, OC_REST_GET, (qos == OC_HIGH_QOS)?
             OC_HIGH_QOS:OC_LOW_QOS, getReqCB, NULL, 0));
 }
 
+int InitPutRequest(OCQualityOfService qos)
+{
+    OC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+    std::ostringstream query;
+    query << "coap://" << coapServerIP << ":" << coapServerPort << coapServerResource;
+    OC_LOG_V (INFO, TAG, "Performing PUT with query : %s", query.str().c_str());
+    return (InvokeOCDoResource(query, OC_REST_PUT, (qos == OC_HIGH_QOS)?
+            OC_HIGH_QOS:OC_LOW_QOS, getReqCB, NULL, 0));
+}
+
 int InitDiscovery()
 {
     OCStackResult ret;
index 3c91393..c6e9486 100644 (file)
@@ -44,6 +44,8 @@ typedef enum
     TEST_DISCOVER_REQ = 1,
     TEST_NON_CON_OP,
     TEST_CON_OP,
+    TEST_NON_CON_PUT,
+    TEST_CON_PUT,
     MAX_TESTS
 } CLIENT_TEST;
 
@@ -77,6 +79,7 @@ std::string getQueryStrForGetPut(OCClientResponse * clientResponse);
  * POST & Discovery operations
  */
 int InitGetRequest(OCQualityOfService qos);
+int InitPutRequest(OCQualityOfService qos);
 int InitDiscovery();
 
 /* Function to retrieve ip address, port no. of the server
index 68a15fa..b0acb2c 100644 (file)
@@ -29,7 +29,7 @@
 #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'"
@@ -55,17 +55,6 @@ 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";
@@ -90,13 +79,33 @@ 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;
+    }
+
+    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
-//in JSON format.
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
+OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
 {
-    cJSON *json = cJSON_CreateObject();
-    cJSON *format;
-    char *jsonResponse;
+    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 == gLightInstance[0].handle)
@@ -112,51 +121,21 @@ char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
 
     if(OC_REST_PUT == ehRequest->method)
     {
-        // Get cJSON pointer to query
-        cJSON *putJson = cJSON_Parse(ehRequest->reqJSONPayload);
-
-        if(!putJson)
+        // Get pointer to query
+        int64_t pow;
+        if(OCRepPayloadGetPropInt(input, "power", &pow))
         {
-            OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
-            return NULL;
+            currLightResource->power =pow;
         }
 
-        // Get root of JSON payload, then the 1st resource.
-        cJSON* carrier = cJSON_GetObjectItem(putJson, "oic");
-        if (carrier)
-        {
-            carrier = cJSON_GetArrayItem(carrier, 0);
-            carrier = cJSON_GetObjectItem(carrier, "rep");
-
-            cJSON* prop = cJSON_GetObjectItem(carrier,"power");
-            if (prop)
-            {
-                currLightResource->power =prop->valueint;
-            }
-
-            prop = cJSON_GetObjectItem(carrier,"state");
-            if (prop)
-            {
-                currLightResource->state = prop->valueint;
-            }
-        }
-        else
+        bool state;
+        if(OCRepPayloadGetPropBool(input, "state", &state))
         {
-            OC_LOG_V(WARNING, TAG, "Failed to find oic node");
+            currLightResource->state = state;
         }
-
-        cJSON_Delete(putJson);
     }
 
-    cJSON_AddStringToObject(json,"href",gResourceUri);
-    cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-    cJSON_AddBoolToObject(format, "state", currLightResource->state);
-    cJSON_AddNumberToObject(format, "power", currLightResource->power);
-
-    jsonResponse = cJSON_Print(json);
-    cJSON_Delete(json);
-
-    return jsonResponse;
+    return getPayload(gResourceUri, currLightResource->power, currLightResource->state);
 }
 
 /*
@@ -200,7 +179,7 @@ OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandler
 }
 
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
-        char *payload, uint16_t maxPayloadSize)
+        OCRepPayload **payload)
 {
     OCEntityHandlerResult ehResult;
     bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
@@ -208,26 +187,15 @@ OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
     // Empty payload if the query has no match.
     if (queryPassed)
     {
-        char *getResp = constructJsonResponse(ehRequest);
+        OCRepPayload *getResp = constructResponse(ehRequest);
         if(!getResp)
         {
-            OC_LOG(ERROR, TAG, "constructJsonResponse failed");
+            OC_LOG(ERROR, TAG, "constructResponse failed");
             return OC_EH_ERROR;
         }
 
-        if (maxPayloadSize > strlen (getResp))
-        {
-            strncpy(payload, getResp, strlen(getResp));
-            ehResult = OC_EH_OK;
-        }
-        else
-        {
-            OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                    maxPayloadSize);
-            ehResult = OC_EH_ERROR;
-        }
-
-        free(getResp);
+        *payload = getResp;
+        ehResult = OC_EH_OK;
     }
     else
     {
@@ -238,10 +206,10 @@ OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
 }
 
 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
-        char *payload, uint16_t maxPayloadSize)
+        OCRepPayload** payload)
 {
     OCEntityHandlerResult ehResult;
-    char *putResp = constructJsonResponse(ehRequest);
+    OCRepPayload *putResp = constructResponse(ehRequest);
 
     if(!putResp)
     {
@@ -249,30 +217,17 @@ OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
         return OC_EH_ERROR;
     }
 
-    if (maxPayloadSize > strlen ((char *)putResp))
-    {
-        strncpy(payload, putResp, strlen((char *)putResp));
-        ehResult = OC_EH_OK;
-    }
-    else
-    {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
-        ehResult = OC_EH_ERROR;
-    }
-
-    free(putResp);
+    *payload = putResp;
+    ehResult = OC_EH_OK;
 
     return ehResult;
 }
 
 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
-        OCEntityHandlerResponse *response, char *payload, uint16_t maxPayloadSize)
+        OCEntityHandlerResponse *response, OCRepPayload** payload)
 {
     OCEntityHandlerResult ehResult = OC_EH_OK;
-    char *respPLPost_light = NULL;
-    cJSON *json;
-    cJSON *format;
+    OCRepPayload *respPLPost_light = nullptr;
 
     /*
      * The entity handler determines how to process a POST request.
@@ -293,10 +248,9 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
             char newLightUri[URI_MAXSIZE];
             snprintf(newLightUri, URI_MAXSIZE, "/a/light/%d", gCurrLightInstance);
 
-            json = cJSON_CreateObject();
-            cJSON_AddStringToObject(json,"href",gResourceUri);
-            cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-            cJSON_AddStringToObject(format, "createduri", (char *) newLightUri);
+            respPLPost_light = OCRepPayloadCreate();
+            OCRepPayloadSetUri(respPLPost_light, gResourceUri);
+            OCRepPayloadSetPropString(respPLPost_light, "createduri", newLightUri);
 
             if (0 == createLightResource (newLightUri, &gLightInstance[gCurrLightInstance]))
             {
@@ -304,19 +258,16 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
                 gLightInstance[gCurrLightInstance].state = 0;
                 gLightInstance[gCurrLightInstance].power = 0;
                 gCurrLightInstance++;
-                respPLPost_light = cJSON_Print(json);
                 strncpy ((char *)response->resourceUri, newLightUri, MAX_URI_LENGTH);
                 ehResult = OC_EH_RESOURCE_CREATED;
             }
-
-            cJSON_Delete(json);
         }
         else
         {
             // Update repesentation of /a/light
             Light.state = true;
             Light.power = 11;
-            respPLPost_light = constructJsonResponse(ehRequest);
+            respPLPost_light = constructResponse(ehRequest);
         }
     }
     else
@@ -329,34 +280,31 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
                 gLightInstance[i].power = 22;
                 if (i == 0)
                 {
-                    respPLPost_light = constructJsonResponse(ehRequest);
+                    respPLPost_light = constructResponse(ehRequest);
                     break;
                 }
                 else if (i == 1)
                 {
-                    respPLPost_light = constructJsonResponse(ehRequest);
+                    respPLPost_light = constructResponse(ehRequest);
                 }
             }
         }
     }
 
-    if ((respPLPost_light != NULL) && (maxPayloadSize > strlen ((char *)respPLPost_light)))
+    if ((respPLPost_light != NULL))
     {
-        strncpy(payload, respPLPost_light, strlen((char *)respPLPost_light));
+        *payload = respPLPost_light;
     }
     else
     {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
+        OC_LOG(INFO, TAG, "Payload was NULL");
         ehResult = OC_EH_ERROR;
     }
 
-    free(respPLPost_light);
     return ehResult;
 }
 
-OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
-        char *payload, uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest)
 {
     if(ehRequest == NULL)
     {
@@ -376,8 +324,6 @@ OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
      * 2. optionally, app removes observers out of its array 'interestedObservers'
      */
 
-    const char* deleteResponse = NULL;
-
     if ((ehRequest != NULL) && (ehRequest->resource == Light.handle))
     {
         //Step 1: Ask stack to do the work.
@@ -387,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++)
@@ -403,13 +348,11 @@ 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;
         }
     }
@@ -418,43 +361,16 @@ OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
         //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 (maxPayloadSize > strlen ((char *)deleteResponse))
-    {
-        strncpy(payload, deleteResponse, strlen((char *)deleteResponse));
-    }
-    else
-    {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
-        ehResult = OC_EH_ERROR;
-    }
-
     return ehResult;
 }
 
-OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest,
-        char *payload, uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessNonExistingResourceRequest(OCEntityHandlerRequest *ehRequest)
 {
     OC_LOG_V(INFO, TAG, "\n\nExecuting %s ", __func__);
 
-    const char* response = NULL;
-    response = responsePayloadResourceDoesNotExist;
-
-    if ( (ehRequest != NULL) &&
-         (maxPayloadSize > strlen ((char *)response)) )
-    {
-        strncpy((char *)payload, response, strlen((char *)response));
-    }
-    else
-    {
-        OC_LOG_V (ERROR, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
-    }
-
     return OC_EH_RESOURCE_NOT_FOUND;
 }
 
@@ -504,7 +420,6 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
 
     OCEntityHandlerResult ehResult = OC_EH_OK;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
 
     // Validate pointer
     if (!entityHandlerRequest)
@@ -517,6 +432,7 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
     memset(response.sendVendorSpecificHeaderOptions, 0,
             sizeof response.sendVendorSpecificHeaderOptions);
     memset(response.resourceUri, 0, sizeof response.resourceUri);
+    OCRepPayload* payload = nullptr;
 
 
     if (flag & OC_REQUEST_FLAG)
@@ -526,23 +442,22 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
         if (entityHandlerRequest->resource == NULL)
         {
             OC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
-            ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest,
-                           payload, sizeof(payload) - 1);
+            ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest);
         }
         else if (OC_REST_GET == entityHandlerRequest->method)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-            ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            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, sizeof(payload) - 1);
+            ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
         }
         else if (OC_REST_DELETE == entityHandlerRequest->method)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
-            ehResult = ProcessDeleteRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            ehResult = ProcessDeleteRequest (entityHandlerRequest);
         }
         else
         {
@@ -557,8 +472,7 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
             response.requestHandle = entityHandlerRequest->requestHandle;
             response.resourceHandle = entityHandlerRequest->resource;
             response.ehResult = ehResult;
-            response.payload = payload;
-            response.payloadSize = strlen(payload);
+            response.payload = reinterpret_cast<OCPayload*>(payload);
             // Indicate that response is NOT in a persistent buffer
             response.persistentBufferFlag = 0;
 
@@ -603,7 +517,6 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
 
     OCEntityHandlerResult ehResult = OC_EH_OK;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
 
     // Validate pointer
     if (!entityHandlerRequest)
@@ -617,6 +530,7 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
     memset(response.sendVendorSpecificHeaderOptions,
             0, sizeof response.sendVendorSpecificHeaderOptions);
     memset(response.resourceUri, 0, sizeof response.resourceUri);
+    OCRepPayload* payload = nullptr;
 
     if (flag & OC_REQUEST_FLAG)
     {
@@ -625,22 +539,22 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
         if (OC_REST_GET == entityHandlerRequest->method)
         {
             OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-            ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            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, sizeof(payload) - 1);
+            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, sizeof(payload) - 1);
+            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, payload, sizeof(payload) - 1);
+            ehResult = ProcessDeleteRequest (entityHandlerRequest);
         }
         else
         {
@@ -655,8 +569,7 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
             response.requestHandle = entityHandlerRequest->requestHandle;
             response.resourceHandle = entityHandlerRequest->resource;
             response.ehResult = ehResult;
-            response.payload = payload;
-            response.payloadSize = strlen(payload);
+            response.payload = reinterpret_cast<OCPayload*>(payload);
             // Indicate that response is NOT in a persistent buffer
             response.persistentBufferFlag = 0;
 
@@ -717,6 +630,7 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
         }
     }
 
+    OCPayloadDestroy(response.payload);
     return ehResult;
 }
 
@@ -758,18 +672,10 @@ void *ChangeLightRepresentation (void *param)
                     }
                 }
 
-                cJSON *json = cJSON_CreateObject();
-                cJSON *format;
-                cJSON_AddStringToObject(json,"href",gResourceUri);
-                cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-                cJSON_AddBoolToObject(format, "state", Light.state);
-                cJSON_AddNumberToObject(format, "power", Light.power);
-
-                char * obsResp = cJSON_Print(json);
-                cJSON_Delete(json);
+                OCRepPayload* payload = getPayload(gResourceUri, Light.power, Light.state);
                 result = OCNotifyListOfObservers (Light.handle, obsNotify, j,
-                        obsResp, OC_NA_QOS);
-                free(obsResp);
+                        payload, OC_NA_QOS);
+                OCRepPayloadDestroy(payload);
             }
             else if (gObserveNotifyType == 0)
             {
index e6d123e..8c87326 100644 (file)
@@ -62,8 +62,8 @@ const char *getResult(OCStackResult result);
  */
 int createLightResource (char *uri, LightResource *lightResource);
 
-/* This method converts the payload to JSON format */
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest);
+/* This method constructs a response from the request */
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
 
 /* This method changes the Light power using an independent thread
  * and notifies the observers of new state of the resource.
@@ -78,22 +78,15 @@ OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandler
 /* Following methods process the PUT, GET, POST, Delete,
  * & Observe requests */
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         uint16_t maxPayloadSize);
+                                         OCRepPayload **payload);
 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         uint16_t maxPayloadSize);
+                                         OCRepPayload **payload);
 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
                                           OCEntityHandlerResponse *response,
-                                          char *payload,
-                                          uint16_t maxPayloadSize);
-OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest,
-                                            char *payload,
-                                            uint16_t maxPayloadSize);
-
-OCEntityHandlerResult ProcessNonExistingResourceRequest (OCEntityHandlerRequest *ehRequest,
-                                                         char *payload,
-                                                         uint16_t maxPayloadSize);
+                                         OCRepPayload **payload);
+OCEntityHandlerResult ProcessDeleteRequest (OCEntityHandlerRequest *ehRequest);
+
+OCEntityHandlerResult ProcessNonExistingResourceRequest (OCEntityHandlerRequest *ehRequest);
 
 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest);
 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest);
index ead663c..e389865 100644 (file)
@@ -26,8 +26,8 @@
 #include <pthread.h>
 #include "ocstack.h"
 #include "logger.h"
-#include "cJSON.h"
 #include "ocserverbasicops.h"
+#include "ocpayload.h"
 
 //string length of "/a/led/" + std::numeric_limits<int>::digits10 + '\0'"
 // 7 + 9 + 1 = 17
@@ -44,21 +44,33 @@ static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
 
 char *gResourceUri= (char *)"/a/led";
 
-//This function takes the request as an input and returns the response
-//in JSON format.
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
+OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
 {
-    cJSON *json = cJSON_CreateObject();
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
+        return nullptr;
+    }
+
+    OCRepPayloadSetUri(payload, uri);
+    OCRepPayloadSetPropBool(payload, "state", state);
+    OCRepPayloadSetPropInt(payload, "power", power);
 
-    if(!json)
+    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)
     {
-        OC_LOG (ERROR, TAG, "json object not created properly");
-        return NULL;
+        OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
+        return nullptr;
     }
 
-    cJSON *format;
-    cJSON *putJson = NULL;
-    char *jsonResponse = NULL;
+    OCRepPayload* input = reinterpret_cast<OCRepPayload*>(ehRequest->payload);
+
     LEDResource *currLEDResource = &LED;
 
     if (ehRequest->resource == gLedInstance[0].handle)
@@ -74,82 +86,34 @@ char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
 
     if(OC_REST_PUT == ehRequest->method)
     {
-        cJSON* jsonObj = NULL;
-        putJson = cJSON_Parse(ehRequest->reqJSONPayload);
-        if(putJson)
+        // Get pointer to query
+        int64_t pow;
+        if(OCRepPayloadGetPropInt(input, "power", &pow))
         {
-            jsonObj = cJSON_GetObjectItem(putJson,"oic");
-            if (jsonObj)
-            {
-                jsonObj = cJSON_GetArrayItem(jsonObj, 0);
-                if (jsonObj)
-                {
-                    jsonObj = cJSON_GetObjectItem(jsonObj, "rep");
-                }
-            }
-        }
-        if (NULL == jsonObj)
-        {
-            OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
-            goto exit;
-        }
-
-        cJSON* prop = cJSON_GetObjectItem(jsonObj,"power");
-        if (prop)
-        {
-            currLEDResource->power =prop->valueint;
+            currLEDResource->power =pow;
         }
 
-        prop = cJSON_GetObjectItem(jsonObj,"state");
-        if (prop)
+        bool state;
+        if(OCRepPayloadGetPropBool(input, "state", &state))
         {
-            currLEDResource->state = prop->valueint;
+            currLEDResource->state = state;
         }
     }
 
-    cJSON_AddStringToObject(json,"href",gResourceUri);
-    format = cJSON_CreateObject();
-
-    if(!format)
-    {
-        OC_LOG (ERROR, TAG, "format object not created properly");
-        goto exit;
-    }
-
-    cJSON_AddItemToObject(json, "rep", format);
-    cJSON_AddStringToObject(format, "state", (char *) (currLEDResource->state ? "on":"off"));
-    cJSON_AddNumberToObject(format, "power", currLEDResource->power);
-
-    jsonResponse = cJSON_Print(json);
-
-exit:
-    cJSON_Delete(putJson);
-    cJSON_Delete(json);
-    return jsonResponse;
+    return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state);
 }
 
-OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest, char *payload,
-        uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
 {
     OCEntityHandlerResult ehResult;
-    char *getResp = constructJsonResponse(ehRequest);
+    OCRepPayload *getResp = constructResponse(ehRequest);
 
     if(getResp)
     {
-        if (maxPayloadSize > strlen ((char *)getResp))
-        {
-            strncpy(payload, getResp, strlen((char *)getResp));
-            ehResult = OC_EH_OK;
-        }
-        else
-        {
-            OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                    maxPayloadSize);
-            ehResult = OC_EH_ERROR;
-        }
-
-        free(getResp);
-    }
+        *payload = getResp;
+        ehResult = OC_EH_OK;
+     }
     else
     {
         ehResult = OC_EH_ERROR;
@@ -158,27 +122,16 @@ OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest, char
     return ehResult;
 }
 
-OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest, char *payload,
-        uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
 {
     OCEntityHandlerResult ehResult;
-    char *putResp = constructJsonResponse(ehRequest);
+    OCRepPayload *putResp = constructResponse(ehRequest);
 
     if(putResp)
     {
-        if (maxPayloadSize > strlen ((char *)putResp))
-        {
-            strncpy(payload, putResp, strlen((char *)putResp));
-            ehResult = OC_EH_OK;
-        }
-        else
-        {
-            OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                    maxPayloadSize);
-            ehResult = OC_EH_ERROR;
-        }
-
-        free(putResp);
+        *payload = putResp;
+        ehResult = OC_EH_OK;
     }
     else
     {
@@ -188,13 +141,11 @@ OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest, char
     return ehResult;
 }
 
-OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, char *payload,
-        uint16_t maxPayloadSize)
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+        OCEntityHandlerResponse *response, OCRepPayload **payload)
 {
-    char *respPLPost_led = NULL;
-    cJSON *json;
-    cJSON *format;
-    OCEntityHandlerResult ehResult;
+    OCRepPayload *respPLPost_led = nullptr;
+    OCEntityHandlerResult ehResult = OC_EH_OK;
 
     /*
      * The entity handler determines how to process a POST request.
@@ -215,22 +166,9 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, cha
             char newLedUri[URI_MAXSIZE ];
             snprintf(newLedUri, URI_MAXSIZE, "/a/led/%d", gCurrLedInstance);
 
-            json = cJSON_CreateObject();
-            if(!json)
-            {
-                return OC_EH_ERROR;
-            }
-
-            cJSON_AddStringToObject(json,"href",gResourceUri);
-            format = cJSON_CreateObject();
-
-            if(!format)
-            {
-                return OC_EH_ERROR;
-            }
-
-            cJSON_AddItemToObject(json, "rep", format);
-            cJSON_AddStringToObject(format, "createduri", (char *) newLedUri);
+            respPLPost_led = OCRepPayloadCreate();
+            OCRepPayloadSetUri(respPLPost_led, gResourceUri);
+            OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri);
 
             if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0))
             {
@@ -238,14 +176,13 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, cha
                 gLedInstance[gCurrLedInstance].state = 0;
                 gLedInstance[gCurrLedInstance].power = 0;
                 gCurrLedInstance++;
-                respPLPost_led = cJSON_Print(json);
+                strncpy ((char *)response->resourceUri, newLedUri, MAX_URI_LENGTH);
+                ehResult = OC_EH_RESOURCE_CREATED;
             }
-
-            cJSON_Delete(json);
         }
         else
         {
-            respPLPost_led = constructJsonResponse(ehRequest);
+            respPLPost_led = constructResponse(ehRequest);
         }
     }
     else
@@ -256,31 +193,28 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest, cha
             {
                 if (i == 0)
                 {
-                    respPLPost_led = constructJsonResponse(ehRequest);
+                    respPLPost_led = constructResponse(ehRequest);
                     break;
                 }
                 else if (i == 1)
                 {
-                    respPLPost_led = constructJsonResponse(ehRequest);
+                    respPLPost_led = constructResponse(ehRequest);
                 }
             }
         }
     }
 
-    if ((respPLPost_led != NULL) && (maxPayloadSize > strlen ((char *)respPLPost_led)))
+    if ((respPLPost_led != NULL))
     {
-        strncpy(payload, respPLPost_led, strlen((char *)respPLPost_led));
+        *payload = respPLPost_led;
         ehResult = OC_EH_OK;
     }
     else
     {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
+        OC_LOG_V (INFO, TAG, "Payload was NULL");
         ehResult = OC_EH_ERROR;
     }
 
-    free(respPLPost_led);
-
     return ehResult;
 }
 
@@ -292,7 +226,15 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
 
     OCEntityHandlerResult ehResult = OC_EH_ERROR;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+
+    // Validate pointer
+    if (!entityHandlerRequest)
+    {
+        OC_LOG (ERROR, TAG, "Invalid request pointer");
+        return OC_EH_ERROR;
+    }
+
+    OCRepPayload* payload = nullptr;
 
     if (flag & OC_REQUEST_FLAG)
     {
@@ -302,17 +244,17 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
             if (OC_REST_GET == entityHandlerRequest->method)
             {
                 OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-                ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+                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, sizeof(payload) - 1);
+                ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
             }
             else if (OC_REST_POST == entityHandlerRequest->method)
             {
                 OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
-                ehResult = ProcessPostRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+                ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
             }
             else
             {
@@ -320,14 +262,13 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
                         entityHandlerRequest->method);
             }
 
-            if (ehResult == OC_EH_OK)
+            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 = payload;
-                response.payloadSize = strlen(payload);
+                response.payload = reinterpret_cast<OCPayload*>(payload);
                 response.numSendVendorSpecificHeaderOptions = 0;
                 memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
                 memset(response.resourceUri, 0, sizeof(response.resourceUri));
@@ -343,6 +284,8 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
             }
         }
     }
+
+    OCPayloadDestroy(response.payload);
     return ehResult;
 }
 
index aec3923..bd223cf 100644 (file)
@@ -48,21 +48,19 @@ typedef struct LEDRESOURCE{
  */
 int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower);
 
-/* This method converts the payload to JSON format */
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest);
+/* This method constructs a response from the request */
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
 
 /* Following methods process the PUT, GET, POST
  * requests
  */
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         uint16_t maxPayloadSize);
+                                        OCRepPayload **payload);
 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         uint16_t maxPayloadSize);
+                                        OCRepPayload **payload);
 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
-                                          char *payload,
-                                          uint16_t maxPayloadSize);
+                                        OCEntityHandlerResponse *response,
+                                        OCRepPayload **payload);
 
 /* call getResult in common.cpp to get the result in string format. */
 const char *getResult(OCStackResult result);
index feec1f8..d58b256 100644 (file)
@@ -28,6 +28,7 @@
 #include <pthread.h>
 #include <ocstack.h>
 #include <logger.h>
+#include "ocpayload.h"
 
 const char *getResult(OCStackResult result);
 
@@ -44,32 +45,9 @@ typedef struct LIGHTRESOURCE{
 
 static LightResource light;
 
-// TODO : hard coded for now, change after Sprint10
-const char rspGetRoomDefault[] = "{\"href\":\"/a/room\",\"rep\":{\"name\":\"John's Room\"}}";
-const char rspGetRoomCollection[] = "{\"href\":\"/a/room\"}";
-// TODO : Needs to be changed to retrieve current status of room and return that in response
-const char rspPutRoomDefault[] = "{\"href\":\"/a/room\",\"rep\":{\"name\":\"John's Room\"}}";
-const char rspPutRoomCollection[] = "{\"href\":\"/a/room\"}";
-const char rspFailureRoom[] = "{\"href\":\"/a/room\",\"rep\":{\"error\":\"ROOM_OP_FAIL\"}}";
-
-// TODO : hard coded for now, change after Sprint4
-const char rspGetLightDefault[] =
-        "{\"href\":\"/a/light\",\"rep\":{\"state\":\"false\",\"color\":\"0\"}}";
-const char rspGetLightCollection[] = "{\"href\":\"/a/light\"}";
-// TODO : Needs to be changed to retrieve current status of light and return that in response
-const char rspPutLightDefault[] =
-        "{\"href\":\"/a/light\",\"rep\":{\"state\":\"true\",\"color\":\"0\"}}";
-const char rspPutLightCollection[] = "{\"href\":\"/a/light\"}";
-const char rspFailureLight[] = "{\"href\":\"/a/light\",\"rep\":{\"error\":\"LIGHT_OP_FAIL\"}}";
-
-
-// TODO : hard coded for now, change after Sprint4
-const char rspGetFanDefault[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"true\",\"speed\":10}}";
-const char rspGetFanCollection[] = "{\"href\":\"/a/fan\"}";
-// TODO : Needs to be changed to retrieve current status of fan and return that in response
-const char rspPutFanDefault[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"false\",\"speed\":0}}";
-const char rspPutFanCollection[] = "{\"href\":\"/a/fan\"}";
-const char rspFailureFan[] = "{\"href\":\"/a/fan\",\"rep\":{\"error\":\"FAN_OP_FAIL\"}}";
+char *gLightResourceUri= (char *)"/a/light";
+char *gRoomResourceUri= (char *)"/a/room";
+char *gFanResourceUri= (char *)"/a/fan";
 
 typedef enum
 {
@@ -90,34 +68,6 @@ void PrintUsage()
 
 unsigned static int TEST = TEST_INVALID;
 
-static OCEntityHandlerResult
-HandleCallback(OCEntityHandlerRequest * ehRequest,
-               const char* opStr,
-               const char* errStr,
-               char *payload,
-               uint16_t maxPayloadSize)
-{
-    OCEntityHandlerResult ret = OC_EH_OK;
-
-    // Append opStr or errStr, after making sure there is
-    // enough room in the payload
-    if (strlen(opStr) < (maxPayloadSize - strlen(payload)))
-    {
-        strncat((char*)payload, opStr, strlen(opStr));
-    }
-    else if (strlen(errStr) < (maxPayloadSize - strlen(payload)))
-    {
-        strncat((char*)payload, errStr, strlen(errStr));
-        ret = OC_EH_ERROR;
-    }
-    else
-    {
-        ret = OC_EH_ERROR;
-    }
-
-    return ret;
-}
-
 static void
 PrintReceivedMsgInfo(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest)
 {
@@ -159,7 +109,7 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
 {
     OCEntityHandlerResult ret = OC_EH_OK;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+    OCRepPayload* payload = OCRepPayloadCreate();
 
     OC_LOG_V(INFO, TAG, "Callback for Room");
     PrintReceivedMsgInfo(flag, ehRequest );
@@ -172,54 +122,45 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
         {
             if(query.find(OC_RSRVD_INTERFACE_DEFAULT) != std::string::npos)
             {
-                ret = HandleCallback(ehRequest,
-                        rspGetRoomDefault, rspFailureRoom, payload, sizeof(payload));
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetLightCollection, rspFailureLight, payload, sizeof(payload));
-                }
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetFanCollection, rspFailureFan, payload, sizeof(payload));
-                }
+                OCRepPayloadSetUri(payload, gRoomResourceUri);
+                OCRepPayloadSetPropString(payload, "name", "John's Room");
+
+                OCRepPayload *tempPayload = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload, gLightResourceUri);
+                OCRepPayloadAppend(payload, tempPayload);
+
+                OCRepPayload *tempPayload2 = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload2, gFanResourceUri);
+                OCRepPayloadAppend(payload, tempPayload2);
             }
             else if(query.find(OC_RSRVD_INTERFACE_LL) != std::string::npos)
             {
-                ret = HandleCallback(ehRequest,
-                        rspGetRoomCollection, rspFailureRoom, payload, sizeof(payload));
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetLightCollection, rspFailureLight, payload, sizeof(payload));
-                }
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetFanCollection, rspFailureFan, payload, sizeof(payload));
-                }
+                OCRepPayloadSetUri(payload, gRoomResourceUri);
+
+                OCRepPayload *tempPayload = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload, gLightResourceUri);
+                OCRepPayloadAppend(payload, tempPayload);
+
+                OCRepPayload *tempPayload2 = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload2, gFanResourceUri);
+                OCRepPayloadAppend(payload, tempPayload2);
             }
             else if(query.find(OC_RSRVD_INTERFACE_BATCH) != std::string::npos)
             {
-                ret = HandleCallback(ehRequest,
-                        rspGetRoomCollection, rspFailureRoom, payload, sizeof(payload));
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetLightDefault, rspFailureLight, payload, sizeof(payload));
-                }
-                if(ret != OC_EH_ERROR)
-                {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspGetFanDefault, rspFailureFan, payload, sizeof(payload));
-                }
+
+                OCRepPayloadSetUri(payload, gRoomResourceUri);
+
+                OCRepPayload *tempPayload = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload, gLightResourceUri);
+                OCRepPayloadSetPropBool(tempPayload, "state", false);
+                OCRepPayloadSetPropInt(tempPayload, "color", 0);
+                OCRepPayloadAppend(payload, tempPayload);
+
+                OCRepPayload *tempPayload2 = OCRepPayloadCreate();
+                OCRepPayloadSetUri(tempPayload2, gFanResourceUri);
+                OCRepPayloadSetPropBool(tempPayload, "state", true);
+                OCRepPayloadSetPropInt(tempPayload, "speed", 10);
+                OCRepPayloadAppend(payload, tempPayload2);
             }
             if (ret == OC_EH_OK)
             {
@@ -227,8 +168,7 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
                 response.requestHandle = ehRequest->requestHandle;
                 response.resourceHandle = ehRequest->resource;
                 response.ehResult = ret;
-                response.payload = payload;
-                response.payloadSize = strlen(payload);
+                response.payload = reinterpret_cast<OCPayload*>(payload);
                 response.numSendVendorSpecificHeaderOptions = 0;
                 memset(response.sendVendorSpecificHeaderOptions,
                         0, sizeof response.sendVendorSpecificHeaderOptions);
@@ -249,48 +189,50 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
             {
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest,
-                            rspPutRoomDefault, rspFailureRoom, payload, sizeof(payload));
+                    OCRepPayloadSetUri(payload, gRoomResourceUri);
+                    OCRepPayloadSetPropString(payload, "name", "John's Room");
                 }
             }
             if(query.find(OC_RSRVD_INTERFACE_LL) != std::string::npos)
             {
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest,
-                            rspPutRoomCollection, rspFailureRoom, payload, sizeof(payload));
+                    OCRepPayloadSetUri(payload, gRoomResourceUri);
                 }
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspPutLightCollection, rspFailureLight, payload, sizeof(payload));
+                    OCRepPayload *tempPayload = OCRepPayloadCreate();
+                    OCRepPayloadSetUri(tempPayload, gLightResourceUri);
+                    OCRepPayloadAppend(payload, tempPayload);
                 }
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspPutFanCollection, rspFailureFan, payload, sizeof(payload));
+                    OCRepPayload *tempPayload = OCRepPayloadCreate();
+                    OCRepPayloadSetUri(tempPayload, gFanResourceUri);
+                    OCRepPayloadAppend(payload, tempPayload);
                 }
             }
             if(query.find(OC_RSRVD_INTERFACE_BATCH ) != std::string::npos)
             {
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest,
-                            rspPutRoomCollection, rspFailureRoom, payload, sizeof(payload));
+                    OCRepPayloadSetUri(payload, gRoomResourceUri);
                 }
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspPutLightDefault, rspFailureLight, payload, sizeof(payload));
+                    OCRepPayload *tempPayload = OCRepPayloadCreate();
+                    OCRepPayloadSetUri(tempPayload, gLightResourceUri);
+                    OCRepPayloadSetPropBool(tempPayload, "state", true);
+                    OCRepPayloadSetPropInt(tempPayload, "color", 0);
+                    OCRepPayloadAppend(payload, tempPayload);
                 }
                 if(ret != OC_EH_ERROR)
                 {
-                    ret = HandleCallback(ehRequest, ",", ",", payload, sizeof(payload));
-                    ret = HandleCallback(ehRequest,
-                            rspPutFanDefault, rspFailureFan, payload, sizeof(payload));
+                    OCRepPayload *tempPayload = OCRepPayloadCreate();
+                    OCRepPayloadSetUri(tempPayload, gFanResourceUri);
+                    OCRepPayloadSetPropBool(tempPayload, "state", false);
+                    OCRepPayloadSetPropInt(tempPayload, "speed", 0);
+                    OCRepPayloadAppend(payload, tempPayload);
                 }
             }
             if (ret == OC_EH_OK)
@@ -299,8 +241,7 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
                 response.requestHandle = ehRequest->requestHandle;
                 response.resourceHandle = ehRequest->resource;
                 response.ehResult = ret;
-                response.payload = payload;
-                response.payloadSize = strlen(payload);
+                response.payload = reinterpret_cast<OCPayload*>(payload);
                 response.numSendVendorSpecificHeaderOptions = 0;
                 memset(response.sendVendorSpecificHeaderOptions,
                         0, sizeof response.sendVendorSpecificHeaderOptions);
@@ -334,7 +275,7 @@ OCEntityHandlerResult OCEntityHandlerLightCb(OCEntityHandlerFlag flag,
 {
     OCEntityHandlerResult ret = OC_EH_OK;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+    OCRepPayload* payload = OCRepPayloadCreate();
 
     OC_LOG_V(INFO, TAG, "Callback for Light");
     PrintReceivedMsgInfo(flag, ehRequest );
@@ -343,13 +284,15 @@ OCEntityHandlerResult OCEntityHandlerLightCb(OCEntityHandlerFlag flag,
     {
         if(OC_REST_GET == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest,
-                    rspGetLightDefault, rspFailureLight, payload, sizeof(payload));
+            OCRepPayloadSetUri(payload, gLightResourceUri);
+            OCRepPayloadSetPropBool(payload, "state", false);
+            OCRepPayloadSetPropInt(payload, "color", 0);
         }
         else if(OC_REST_PUT == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest,
-                    rspPutLightDefault, rspFailureLight, payload, sizeof(payload));
+            OCRepPayloadSetUri(payload, gLightResourceUri);
+            OCRepPayloadSetPropBool(payload, "state", true);
+            OCRepPayloadSetPropInt(payload, "color", 0);
         }
         else
         {
@@ -364,8 +307,7 @@ OCEntityHandlerResult OCEntityHandlerLightCb(OCEntityHandlerFlag flag,
             response.requestHandle = ehRequest->requestHandle;
             response.resourceHandle = ehRequest->resource;
             response.ehResult = ret;
-            response.payload = payload;
-            response.payloadSize = strlen(payload);
+            response.payload = reinterpret_cast<OCPayload*>(payload);
             response.numSendVendorSpecificHeaderOptions = 0;
             memset(response.sendVendorSpecificHeaderOptions,
                     0, sizeof response.sendVendorSpecificHeaderOptions);
@@ -394,7 +336,7 @@ OCEntityHandlerResult OCEntityHandlerFanCb(OCEntityHandlerFlag flag,
 {
     OCEntityHandlerResult ret = OC_EH_OK;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+    OCRepPayload* payload = OCRepPayloadCreate();
 
     OC_LOG_V(INFO, TAG, "Callback for Fan");
     PrintReceivedMsgInfo(flag, ehRequest );
@@ -403,13 +345,15 @@ OCEntityHandlerResult OCEntityHandlerFanCb(OCEntityHandlerFlag flag,
     {
         if(OC_REST_GET == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest, rspGetFanDefault,
-                    rspFailureFan, payload, sizeof(payload));
+            OCRepPayloadSetUri(payload, gFanResourceUri);
+            OCRepPayloadSetPropBool(payload, "state", true);
+            OCRepPayloadSetPropInt(payload, "speed", 10);
         }
         else if(OC_REST_PUT == ehRequest->method)
         {
-            ret = HandleCallback(ehRequest, rspPutFanDefault,
-                    rspFailureFan, payload, sizeof(payload));
+            OCRepPayloadSetUri(payload, gFanResourceUri);
+            OCRepPayloadSetPropBool(payload, "state", false);
+            OCRepPayloadSetPropInt(payload, "speed", 0);
         }
         else
         {
@@ -424,8 +368,7 @@ OCEntityHandlerResult OCEntityHandlerFanCb(OCEntityHandlerFlag flag,
             response.requestHandle = ehRequest->requestHandle;
             response.resourceHandle = ehRequest->resource;
             response.ehResult = ret;
-            response.payload = payload;
-            response.payloadSize = strlen(payload);
+            response.payload = reinterpret_cast<OCPayload*>(payload);
             response.numSendVendorSpecificHeaderOptions = 0;
             memset(response.sendVendorSpecificHeaderOptions,
                     0, sizeof response.sendVendorSpecificHeaderOptions);
@@ -551,6 +494,7 @@ int main(int argc, char* argv[])
 
     return 0;
 }
+
 void createResources()
 {
     light.state = false;
index 2c42f6f..99a0b52 100644 (file)
@@ -31,6 +31,7 @@
 #include "logger.h"
 #include "cJSON.h"
 #include "ocserverslow.h"
+#include "ocpayload.h"
 
 volatile sig_atomic_t gQuitFlag = 0;
 
@@ -47,21 +48,11 @@ char *gResourceUri= (char *)"/a/led";
 
 //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();
-
-    if(!json)
-    {
-        OC_LOG(ERROR, TAG, "CreateObject result in null for json");
-        return NULL;
-    }
-
-    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)
     {
@@ -78,63 +69,60 @@ char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
 
     if(OC_REST_PUT == ehRequest->method)
     {
-        cJSON *putJson = cJSON_Parse((char *)ehRequest->reqJSONPayload);
-
-        if(!putJson)
+        if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
         {
-            OC_LOG(ERROR, TAG, "CreateObject result in null for putJson");
-            cJSON_Delete(json);
-            return NULL;
+            OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
+            return nullptr;
         }
 
-        currLEDResource->state = ( !strcmp(cJSON_GetObjectItem(putJson,"state")->valuestring ,
-                "on") ? true:false);
-        currLEDResource->power = cJSON_GetObjectItem(putJson,"power")->valuedouble;
-        cJSON_Delete(putJson);
+        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);
-    format = cJSON_CreateObject();
+    OCRepPayload *response = OCRepPayloadCreate();
 
-    if(!format)
+    if (!response)
     {
-        OC_LOG(ERROR, TAG, "CreateObject result in null for format");
-        cJSON_Delete(json);
-        return NULL;
+        OC_LOG_V(ERROR, TAG, "Memory allocation for response payload failed.");
     }
 
-    cJSON_AddItemToObject(json, "rep", format);
-    cJSON_AddStringToObject(format, "state", (char *) (currLEDResource->state ? "on":"off"));
-    cJSON_AddNumberToObject(format, "power", currLEDResource->power);
+    OCRepPayloadSetUri (response, gResourceUri);
+    OCRepPayloadSetPropBool(response, "state", currLEDResource->state);
+    OCRepPayloadSetPropInt(response, "power", currLEDResource->power);
 
-    OC_LOG(INFO, TAG, "Before constructJsonResponse print");
-    jsonResponse = cJSON_Print(json);
-    OC_LOG(INFO, TAG, "Before constructJsonResponse delete");
-    cJSON_Delete(json);
-
-    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, "Entering ProcessGetPutRequest");
+
+    OCRepPayload *getResp = constructResponse(ehRequest);
 
     if(!getResp)
     {
-        OC_LOG(ERROR, TAG, "Failed to constructJsonResponse");
+        OC_LOG(ERROR, TAG, "Failed to construct response");
         return;
     }
-    OC_LOG(INFO, TAG, "After constructJsonResponse");
+
     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 = getResp;
-    response.payloadSize = strlen(getResp) + 1;
+    response.payload = reinterpret_cast<OCPayload*> (getResp);
     response.numSendVendorSpecificHeaderOptions = 0;
     memset(response.sendVendorSpecificHeaderOptions,
             0, sizeof response.sendVendorSpecificHeaderOptions);
@@ -154,46 +142,37 @@ void ProcessGetRequest (OCEntityHandlerRequest *ehRequest)
 OCEntityHandlerRequest *CopyRequest(OCEntityHandlerRequest *entityHandlerRequest)
 {
     OC_LOG(INFO, TAG, "Copying received request for slow response");
-    OCEntityHandlerRequest *request =
+
+    OCEntityHandlerRequest *copyOfRequest =
             (OCEntityHandlerRequest *)OICMalloc(sizeof(OCEntityHandlerRequest));
-    if (request)
+
+    if (copyOfRequest)
     {
         // Do shallow copy
-        memcpy(request, entityHandlerRequest, sizeof(OCEntityHandlerRequest));
-        // Do deep copy of query
-        request->query =
-                (char * )OICMalloc(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 = (char * )OICMalloc(
-                            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
-            {
-                OICFree(request->query);
-                OICFree(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)
         {
-            OICFree(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");
     }
@@ -201,17 +180,17 @@ OCEntityHandlerRequest *CopyRequest(OCEntityHandlerRequest *entityHandlerRequest
     {
         OC_LOG(ERROR, TAG, "Error copying client request");
     }
-    return request;
+    return copyOfRequest;
 }
 
-OCEntityHandlerResult
-OCEntityHandlerCb (OCEntityHandlerFlag flag,
+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_REQUEST_FLAG)
     {
         OC_LOG(INFO, TAG, "Flag includes OC_REQUEST_FLAG");
@@ -219,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)
             {
 
@@ -277,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
         {
@@ -286,7 +271,7 @@ void AlarmHandler(int sig)
         }
         // Free the request
         OICFree(entityHandlerRequest->query);
-        OICFree(entityHandlerRequest->reqJSONPayload);
+        OCPayloadDestroy(entityHandlerRequest->payload);
         OICFree(entityHandlerRequest);
 
         // If there are more requests in list, re-arm the alarm signal
@@ -307,10 +292,8 @@ int main(int argc, char* argv[])
         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);
@@ -326,7 +309,6 @@ int main(int argc, char* argv[])
             OC_LOG(ERROR, TAG, "OCStack process error");
             return 0;
         }
-
         sleep(2);
     }
 
@@ -338,7 +320,7 @@ int main(int argc, char* argv[])
         for (auto iter = gRequestList.begin(); iter != gRequestList.end(); ++iter)
         {
             OICFree((*iter)->query);
-            OICFree((*iter)->reqJSONPayload);
+            OCPayloadDestroy((*iter)->payload);
             OICFree(*iter);
         }
         gRequestList.clear();
index b6dd32c..12bc216 100644 (file)
@@ -63,6 +63,7 @@ samples_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 ######################################################################
 # Source files and Targets
 ######################################################################
+
 ocserverbasicops = samples_env.Program('ocserverbasicops', ['common.cpp', 'ocserverbasicops.cpp'])
 occlientbasicops = samples_env.Program('occlientbasicops', ['common.cpp', 'occlientbasicops.cpp'])
 
@@ -74,8 +75,8 @@ src_dir = samples_env.get('SRC_DIR')
 sec_samples_src_dir = src_dir + '/resource/csdk/stack/samples/linux/secure/'
 sec_samples_build_dir = env.get('BUILD_DIR') +'/resource/csdk/stack/samples/linux/secure'
 
-samples_env.Alias("install", samples_env.Install( sec_samples_build_dir, 
+samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
     sec_samples_src_dir + 'oic_svr_db_server.json'))
-samples_env.Alias("install", samples_env.Install( sec_samples_build_dir, 
+samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
     sec_samples_src_dir + 'oic_svr_db_client.json'))
 
index 3dabe56..1cde32b 100644 (file)
@@ -28,7 +28,7 @@
 #include "ocstack.h"
 #include "logger.h"
 #include "occlientbasicops.h"
-#include "cJSON.h"
+#include "ocpayload.h"
 #include "common.h"
 
 #define TAG "occlientbasicops"
@@ -41,7 +41,6 @@ static char UNICAST_DISCOVERY_QUERY[] = "coap://%s/oic/res";
 static char MULTICAST_DISCOVERY_QUERY[] = "/oic/res";
 OCConnectivityType discoveryReqConnType = CT_ADAPTER_IP;
 
-static std::string putPayload = "{\"oic\":[{\"rep\":{\"state\":\"off\",\"power\":10}}]}";
 static std::string coapServerIP;
 static std::string coapServerPort;
 static std::string coapServerResource;
@@ -66,6 +65,22 @@ void handleSigInt(int signum)
     }
 }
 
+OCPayload* putPayload()
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if(!payload)
+    {
+        std::cout << "Failed to create put payload object"<<std::endl;
+        std::exit(1);
+    }
+
+    OCRepPayloadSetPropInt(payload, "power", 15);
+    OCRepPayloadSetPropBool(payload, "state", true);
+
+    return (OCPayload*) payload;
+}
+
 static void PrintUsage()
 {
     OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1|2|3> -c <0|1>");
@@ -90,7 +105,7 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.cd = NULL;
 
     ret = OCDoResource(NULL, method, query.str().c_str(), 0,
-            (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload.c_str() : NULL,
+            (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload() : NULL,
             ocConnType, qos, &cbData, options, numOptions);
 
     if (ret != OC_STACK_OK)
@@ -107,8 +122,8 @@ OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse
 
     if(clientResponse)
     {
-        OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Put Response", clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Put Response"));
     }
     return OC_STACK_DELETE_TRANSACTION;
 }
@@ -120,8 +135,8 @@ OCStackApplicationResult postReqCB(void *ctx, OCDoHandle handle, OCClientRespons
     if(clientResponse)
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Post Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Post Response"));
     }
     return OC_STACK_DELETE_TRANSACTION;
 }
@@ -134,8 +149,8 @@ OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
         OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
-        OC_LOG_V(INFO, TAG, "JSON = %s =============> Get Response",
-                clientResponse->resJSONPayload);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
+        OC_LOG(INFO, TAG, PCF("=============> Get Response"));
     }
     return OC_STACK_DELETE_TRANSACTION;
 }
@@ -150,8 +165,10 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
     {
         OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result));
         OC_LOG_V(INFO, TAG,
-                "Device =============> Discovered %s @ %s:%d",
-                clientResponse->resJSONPayload, clientResponse->devAddr.addr, clientResponse->devAddr.port);
+                "Device =============> Discovered @ %s:%d",
+                clientResponse->devAddr.addr,
+                clientResponse->devAddr.port);
+        OC_LOG_PAYLOAD(INFO, TAG, clientResponse->payload);
 
         ocConnType = clientResponse->connType;
 
@@ -387,9 +404,7 @@ std::string getPortTBServer(OCClientResponse * clientResponse)
 
 int parseClientResponse(OCClientResponse * clientResponse)
 {
-    int port = -1;
-    cJSON * root = NULL;
-    cJSON * oc = NULL;
+    OCResourcePayload* res = ((OCDiscoveryPayload*)clientResponse->payload)->resources;
 
     // Initialize all global variables
     coapServerResource.clear();
@@ -397,90 +412,40 @@ int parseClientResponse(OCClientResponse * clientResponse)
     coapServerIP.clear();
     coapSecureResource = 0;
 
-    root = cJSON_Parse((char *)(clientResponse->resJSONPayload));
-    if (!root)
+    while(res)
     {
-        return -1;
-    }
+        coapServerResource.assign(res->uri);
+        OC_LOG_V(INFO, TAG, "Uri -- %s", coapServerResource.c_str());
 
-    oc = cJSON_GetObjectItem(root,"oic");
-    if (!oc || oc->type != cJSON_Array)
-    {
-        cJSON_Delete(root);
-        return -1;
-    }
+        if(res->secure)
+        {
+            coapSecureResource = 1;
+        }
 
-    cJSON * firstDevice = cJSON_GetArrayItem(oc, 0);
-    if (!firstDevice)
-    {
-        cJSON_Delete(root);
-        return -1;
-    }
+        OC_LOG_V(INFO, TAG, "Secure -- %s", coapSecureResource == 1 ? "YES" : "NO");
 
-    cJSON * links = cJSON_GetObjectItem(firstDevice,"links");
-    if (!links)
-    {
-        cJSON_Delete(root);
-        return -1;
-    }
+        std::ostringstream ss;
+        ss << res->port;
+        coapServerPort = ss.str();
+        std::cout<<"PORT: "<<coapServerPort;
 
-    if (links->type == cJSON_Array)
-    {
-        int numRsrcs =  cJSON_GetArraySize(links);
-        for(int i = 0; i < numRsrcs; i++)
+        // If we discovered a secure resource, exit from here
+        if (coapSecureResource)
         {
-            cJSON * resource = cJSON_GetArrayItem(links, i);
-            if (cJSON_GetObjectItem(resource, "href"))
-            {
-                coapServerResource.assign(cJSON_GetObjectItem(resource, "href")->valuestring);
-            }
-            else
-            {
-                coapServerResource = "";
-            }
-            OC_LOG_V(INFO, TAG, "Uri -- %s", coapServerResource.c_str());
-
-            {
-                cJSON * policy = cJSON_GetObjectItem(resource,"p");
-                if (policy)
-                {
-                    // If this is a secure resource, the info about the port at which the
-                    // resource is hosted on server is embedded inside discovery JSON response
-                    if (cJSON_GetObjectItem(policy, "sec"))
-                    {
-                        if ((cJSON_GetObjectItem(policy, "sec")->valueint) == 1)
-                        {
-                            coapSecureResource = 1;
-                        }
-                    }
-                    OC_LOG_V(INFO, TAG, "Secure -- %s", coapSecureResource == 1 ? "YES" : "NO");
-                    if (cJSON_GetObjectItem(policy, "port"))
-                    {
-                        port = cJSON_GetObjectItem(policy, "port")->valueint;
-                        OC_LOG_V(INFO, TAG, "Hosting Server Port (embedded inside JSON) -- %u", port);
-
-                        std::ostringstream ss;
-                        ss << port;
-                        coapServerPort = ss.str();
-                    }
-                }
-            }
-
-            // If we discovered a secure resource, exit from here
-            if (coapSecureResource)
-            {
-                break;
-            }
+            break;
         }
+
+        res = res->next;
     }
-    cJSON_Delete(root);
 
     coapServerIP = clientResponse->devAddr.addr;
-    if (port == -1)
+
+    if(coapServerPort.length() == 0 || coapServerPort == "0")
     {
         coapServerPort = getPortTBServer(clientResponse);
         OC_LOG_V(INFO, TAG, "Hosting Server Port -- %s", coapServerPort.c_str());
     }
+
     return 0;
 }
 
index 4dba110..6e212fe 100644 (file)
@@ -26,7 +26,7 @@
 #include <pthread.h>
 #include "ocstack.h"
 #include "logger.h"
-#include "cJSON.h"
+#include "ocpayload.h"
 #include "ocserverbasicops.h"
 #include "common.h"
 
@@ -46,88 +46,76 @@ char *gResourceUri= (char *)"/a/led";
 //of other devices which the server trusts
 static char CRED_FILE[] = "oic_svr_db_server.json";
 
+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;
+    }
+
+    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
-//in JSON format.
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest)
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest)
 {
-    cJSON *json = cJSON_CreateObject();
-    cJSON *putJson = NULL;
-    cJSON *format;
-    char *jsonResponse = NULL;
+    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);
+
     LEDResource *currLEDResource = &LED;
 
     if (ehRequest->resource == gLedInstance[0].handle)
     {
         currLEDResource = &gLedInstance[0];
-        gResourceUri = (char *) "a/led/0";
+        gResourceUri = (char *) "/a/led/0";
     }
     else if (ehRequest->resource == gLedInstance[1].handle)
     {
         currLEDResource = &gLedInstance[1];
-        gResourceUri = (char *) "a/led/1";
+        gResourceUri = (char *) "/a/led/1";
     }
 
     if(OC_REST_PUT == ehRequest->method)
     {
-        cJSON* jsonObj = NULL;
-        putJson = cJSON_Parse(ehRequest->reqJSONPayload);
-        if(putJson)
+        // Get pointer to query
+        int64_t pow;
+        if(OCRepPayloadGetPropInt(input, "power", &pow))
         {
-            jsonObj = cJSON_GetObjectItem(putJson,"oic");
-            if (jsonObj)
-            {
-                jsonObj = cJSON_GetArrayItem(jsonObj, 0);
-                if (jsonObj)
-                {
-                    jsonObj = cJSON_GetObjectItem(jsonObj, "rep");
-                }
-            }
+            currLEDResource->power =pow;
         }
-        if (NULL == jsonObj)
+
+        bool state;
+        if(OCRepPayloadGetPropBool(input, "state", &state))
         {
-            OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
-            goto exit;
+            currLEDResource->state = state;
         }
-
-        currLEDResource->state = ( !strcmp(cJSON_GetObjectItem(jsonObj,"state")->valuestring ,
-                    "on") ? true:false);
-        currLEDResource->power = cJSON_GetObjectItem(jsonObj,"power")->valuedouble;
     }
 
-    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);
-
-    jsonResponse = cJSON_Print(json);
-
-exit:
-    cJSON_Delete(putJson);
-    cJSON_Delete(json);
-    return jsonResponse;
+    return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state);
 }
 
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
-                        char *payload, size_t maxPayloadSize)
+        OCRepPayload **payload)
 {
     OCEntityHandlerResult ehResult;
 
-    char *getResp = constructJsonResponse(ehRequest);
+    OCRepPayload *getResp = constructResponse(ehRequest);
+
     if(getResp)
     {
-        if (maxPayloadSize > strlen (getResp))
-        {
-            strcpy(payload, getResp);
-            ehResult = OC_EH_OK;
-        }
-        else
-        {
-            OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                    maxPayloadSize);
-            ehResult = OC_EH_ERROR;
-        }
-
-        free(getResp);
+        *payload = getResp;
+        ehResult = OC_EH_OK;
     }
     else
     {
@@ -138,27 +126,16 @@ OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
 }
 
 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
-                        char *payload, size_t maxPayloadSize)
+        OCRepPayload **payload)
 {
     OCEntityHandlerResult ehResult;
 
-    char *putResp = constructJsonResponse(ehRequest);
+    OCRepPayload *putResp = constructResponse(ehRequest);
 
     if(putResp)
     {
-        if (maxPayloadSize > strlen (putResp))
-        {
-            strcpy(payload, putResp);
-            ehResult = OC_EH_OK;
-        }
-        else
-        {
-            OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                    maxPayloadSize);
-            ehResult = OC_EH_ERROR;
-        }
-
-        free(putResp);
+        *payload = putResp;
+        ehResult = OC_EH_OK;
     }
     else
     {
@@ -169,12 +146,10 @@ OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
 }
 
 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
-                        char *payload, size_t maxPayloadSize)
+        OCEntityHandlerResponse *response, OCRepPayload **payload)
 {
-    char *respPLPost_led = NULL;
-    cJSON *json;
-    cJSON *format;
-    OCEntityHandlerResult ehResult;
+    OCRepPayload *respPLPost_led = nullptr;
+    OCEntityHandlerResult ehResult = OC_EH_OK;
 
     /*
      * The entity handler determines how to process a POST request.
@@ -196,11 +171,9 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
             int newLedUriLength = strlen(newLedUri);
             snprintf (newLedUri + newLedUriLength, sizeof(newLedUri)-newLedUriLength, "%d", gCurrLedInstance);
 
-            json = cJSON_CreateObject();
-
-            cJSON_AddStringToObject(json,"href",gResourceUri);
-            cJSON_AddItemToObject(json, "rep", format=cJSON_CreateObject());
-            cJSON_AddStringToObject(format, "createduri", (char *) newLedUri);
+            respPLPost_led = OCRepPayloadCreate();
+            OCRepPayloadSetUri(respPLPost_led, gResourceUri);
+            OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri);
 
             if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0))
             {
@@ -208,14 +181,13 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
                 gLedInstance[gCurrLedInstance].state = 0;
                 gLedInstance[gCurrLedInstance].power = 0;
                 gCurrLedInstance++;
-                respPLPost_led = cJSON_Print(json);
+                strncpy ((char *)response->resourceUri, newLedUri, MAX_URI_LENGTH);
+                ehResult = OC_EH_RESOURCE_CREATED;
             }
-
-            cJSON_Delete(json);
         }
         else
         {
-            respPLPost_led = constructJsonResponse(ehRequest);
+            respPLPost_led = constructResponse(ehRequest);
         }
     }
     else
@@ -226,31 +198,28 @@ OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
             {
                 if (i == 0)
                 {
-                    respPLPost_led = constructJsonResponse(ehRequest);
+                    respPLPost_led = constructResponse(ehRequest);
                     break;
                 }
                 else if (i == 1)
                 {
-                    respPLPost_led = constructJsonResponse(ehRequest);
+                    respPLPost_led = constructResponse(ehRequest);
                 }
             }
         }
     }
 
-    if ((respPLPost_led != NULL) && (maxPayloadSize > strlen (respPLPost_led)))
+    if (respPLPost_led != NULL)
     {
-        strcpy(payload, respPLPost_led);
+        *payload = respPLPost_led;
         ehResult = OC_EH_OK;
     }
     else
     {
-        OC_LOG_V (INFO, TAG, "Response buffer: %d bytes is too small",
-                maxPayloadSize);
+        OC_LOG_V (INFO, TAG, "Payload was NULL");
         ehResult = OC_EH_ERROR;
     }
 
-    free(respPLPost_led);
-
     return ehResult;
 }
 
@@ -263,7 +232,15 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
 
     OCEntityHandlerResult ehResult = OC_EH_ERROR;
     OCEntityHandlerResponse response;
-    char payload[MAX_RESPONSE_LENGTH] = {0};
+
+    // Validate pointer
+    if (!entityHandlerRequest)
+    {
+        OC_LOG (ERROR, TAG, "Invalid request pointer");
+        return OC_EH_ERROR;
+    }
+
+    OCRepPayload* payload = nullptr;
 
     if (flag & OC_REQUEST_FLAG)
     {
@@ -273,17 +250,17 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
             if (OC_REST_GET == entityHandlerRequest->method)
             {
                 OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-                ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload));
+                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, sizeof(payload));
+                ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
             }
             else if (OC_REST_POST == entityHandlerRequest->method)
             {
                 OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
-                ehResult = ProcessPostRequest (entityHandlerRequest, payload, sizeof(payload));
+                ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
             }
             else
             {
@@ -292,14 +269,13 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
                 ehResult = OC_EH_ERROR;
             }
 
-            if (ehResult == OC_EH_OK)
+            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 = payload;
-                response.payloadSize = strlen(payload);
+                response.payload = reinterpret_cast<OCPayload*>(payload);
                 response.numSendVendorSpecificHeaderOptions = 0;
                 memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions);
                 memset(response.resourceUri, 0, sizeof(response.resourceUri));
@@ -315,6 +291,8 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
             }
         }
     }
+
+    OCPayloadDestroy(response.payload);
     return ehResult;
 }
 
index 4e1f7eb..f8b72db 100644 (file)
@@ -49,20 +49,18 @@ typedef struct LEDRESOURCE{
 int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower);
 
 /* This method converts the payload to JSON format */
-char* constructJsonResponse (OCEntityHandlerRequest *ehRequest);
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
 
 /* Following methods process the PUT, GET, POST
  * requests
  */
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         size_t maxPayloadSize);
+                                         OCRepPayload **payload);
 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
-                                         char *payload,
-                                         size_t maxPayloadSize);
+                                         OCRepPayload **payload);
 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
-                                          char *payload,
-                                          size_t maxPayloadSize);
+                                        OCEntityHandlerResponse *response,
+                                        OCRepPayload **payload);
 
 //-----------------------------------------------------------------------------
 // Callback functions
index 6e52718..4f89cd3 100644 (file)
@@ -150,6 +150,7 @@ void DeleteClientCB(ClientCB * cbNode)
         OC_LOG(INFO, TAG, PCF("deleting tokens"));
         OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, cbNode->tokenLength);
         CADestroyToken (cbNode->token);
+        OICFree(cbNode->devAddr);
         OICFree(cbNode->handle);
         OICFree(cbNode->requestUri);
         if(cbNode->deleteCallback)
index 83bbfec..a851da3 100644 (file)
@@ -34,6 +34,7 @@
 #include "cJSON.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
+#include "ocpayload.h"
 
 /// Module Name
 #include <stdio.h>
@@ -219,54 +220,6 @@ ValidateQuery (const char *query, OCResourceHandle resource,
     return OC_STACK_OK;
 }
 
-
-static OCStackResult BuildRootResourceJSON(OCResource *resource,
-        char * bufferPtr, uint16_t *remaining)
-{
-    OCStackResult ret = OC_STACK_ERROR;
-    cJSON *resObj = NULL;
-    char *jsonStr = NULL;
-    uint16_t jsonLen;
-
-    OC_LOG(INFO, TAG, PCF("Entering BuildRootResourceJSON"));
-    resObj = cJSON_CreateObject();
-
-    if ( ! resObj)
-    {
-        ret = OC_STACK_NO_MEMORY;
-    }
-    else if (resource)
-    {
-        cJSON_AddItemToObject (resObj, OC_RSRVD_HREF, cJSON_CreateString(resource->uri));
-        jsonStr = cJSON_PrintUnformatted (resObj);
-
-        if(!jsonStr)
-        {
-            cJSON_Delete(resObj);
-            return OC_STACK_NO_MEMORY;
-        }
-
-        jsonLen = strlen(jsonStr);
-        if (jsonLen < *remaining)
-        {
-            OICStrcpy(bufferPtr, *remaining, jsonStr);
-            *remaining -= jsonLen;
-            bufferPtr += jsonLen;
-            ret = OC_STACK_OK;
-        }
-    }
-    else
-    {
-        ret = OC_STACK_INVALID_PARAM;
-    }
-
-    cJSON_Delete (resObj);
-    OICFree(jsonStr);
-
-    return ret;
-}
-
-
 static OCStackResult
 HandleLinkedListInterface(OCEntityHandlerRequest *ehRequest, uint8_t filterOn, char *filterValue)
 {
@@ -275,86 +228,47 @@ HandleLinkedListInterface(OCEntityHandlerRequest *ehRequest, uint8_t filterOn, c
         return OC_STACK_INVALID_PARAM;
     }
 
-    OCStackResult ret = OC_STACK_ERROR;
-    char jsonbuffer[MAX_RESPONSE_LENGTH] = {};
-    size_t jsonbufferLength = 0;
-    uint16_t remaining = 0;
-    char *ptr = NULL;
+    OCStackResult ret = OC_STACK_OK;
     OCResource *collResource = (OCResource *)ehRequest->resource;
 
-    ptr = jsonbuffer;
-    remaining = MAX_RESPONSE_LENGTH;
-
-    ret = BuildRootResourceJSON(collResource, ptr, &remaining);
-
-    if (ret == OC_STACK_OK && remaining >= (sizeof (OC_JSON_SEPARATOR) + 1))
+    OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
+    if(!payload)
     {
-        ptr += strlen((char*)ptr);
-        *ptr = OC_JSON_SEPARATOR;
-        ptr++;
-        remaining--;
+        ret = OC_STACK_NO_MEMORY;
     }
-    else
+
+    if(ret == OC_STACK_OK)
     {
-        ret = OC_STACK_ERROR;
+        ret = BuildVirtualResourceResponse(collResource, payload,
+                CA_ADAPTER_IP);
     }
 
     if (ret == OC_STACK_OK)
     {
-        for  (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
+        for  (int i = 0; i < MAX_CONTAINED_RESOURCES && ret == OC_STACK_OK; i++)
         {
             OCResource* temp = collResource->rsrcResources[i];
             if (temp)
             {
                 //TODO : Add resource type filtering once collections
                 // start supporting queries.
-                ret = BuildVirtualResourceResponse(temp,
-                         (char*)ptr, &remaining, CA_ADAPTER_IP);
-
-                if (ret != OC_STACK_OK)
-                {
-                    break;
-                }
-                ptr += strlen((char*)ptr);
-
-                // Check if we have added all resources.
-                if ((i + 1) == MAX_CONTAINED_RESOURCES)
-                {
-                    break;
-                }
-                // Add separator if more resources and enough space present.
-                if (collResource->rsrcResources[i+1] && remaining > sizeof(OC_JSON_SEPARATOR))
-                {
-                    *ptr = OC_JSON_SEPARATOR;
-                    ptr++;
-                    remaining--;
-                }
-                // No point continuing as no more space on buffer
-                // and/or no more resources.
-                else
-                {
-                    break;
-                }
-            }
-            else
-            {
-                break;
+                ret = BuildVirtualResourceResponse(temp, payload,
+                        CA_ADAPTER_IP);
             }
         }
     }
 
-    jsonbufferLength = strlen((const char *)jsonbuffer);
-    if(ret == OC_STACK_OK && jsonbufferLength)
+    if(ret == OC_STACK_OK)
     {
         OCEntityHandlerResponse response = {};
         response.ehResult = OC_EH_OK;
-        response.payload = jsonbuffer;
-        response.payloadSize = jsonbufferLength + 1;
+        response.payload = (OCPayload*)payload;
         response.persistentBufferFlag = 0;
         response.requestHandle = (OCRequestHandle) ehRequest->requestHandle;
         response.resourceHandle = (OCResourceHandle) collResource;
         ret = OCDoResponse(&response);
     }
+    OCDiscoveryPayloadDestroy(payload);
     return ret;
 }
 
@@ -363,30 +277,31 @@ HandleBatchInterface(OCEntityHandlerRequest *ehRequest)
 {
     OCStackResult stackRet = OC_STACK_ERROR;
     OCEntityHandlerResult ehResult = OC_EH_ERROR;
-    char jsonbuffer[MAX_RESPONSE_LENGTH] = {0};
-    size_t jsonbufferLength = 0;
-    uint16_t remaining = 0;
-    char * ptr = NULL;
     OCResource * collResource = (OCResource *) ehRequest->resource;
 
-    ptr = jsonbuffer;
-    remaining = MAX_RESPONSE_LENGTH;
+    OCDiscoveryPayload* payload = OCDiscoveryPayloadCreate();
+    if(!payload)
+    {
+        stackRet = OC_STACK_NO_MEMORY;
+    }
 
-    stackRet = BuildRootResourceJSON(collResource, ptr, &remaining);
-    ptr += strlen((char*)ptr);
+    if(stackRet == OC_STACK_OK)
+    {
+        stackRet = BuildVirtualResourceResponse(collResource, payload,
+                CA_ADAPTER_IP);
+    }
 
-    jsonbufferLength = strlen((const char *)jsonbuffer);
-    if(jsonbufferLength)
+    if(stackRet == OC_STACK_OK)
     {
         OCEntityHandlerResponse response = {};
         response.ehResult = OC_EH_OK;
-        response.payload = jsonbuffer;
-        response.payloadSize = jsonbufferLength + 1;
+        response.payload = (OCPayload*)payload;
         response.persistentBufferFlag = 0;
         response.requestHandle = (OCRequestHandle) ehRequest->requestHandle;
         response.resourceHandle = (OCResourceHandle) collResource;
         stackRet = OCDoResponse(&response);
     }
+    OCDiscoveryPayloadDestroy(payload);
 
     if (stackRet == OC_STACK_OK)
     {
@@ -535,8 +450,8 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
 
             case STACK_IF_GROUP:
             {
-                OC_LOG_V(INFO, TAG, "IF_COLLECTION PUT with request ::\n%s\n ",
-                        ehRequest->reqJSONPayload);
+                OC_LOG(INFO, TAG, PCF("IF_COLLECTION PUT with request ::\n"));
+                OC_LOG_PAYLOAD(INFO, TAG, ehRequest->payload);
                 return BuildCollectionGroupActionJSONResponse(OC_REST_PUT/*flag*/,
                         (OCResource *) ehRequest->resource, ehRequest);
             }
@@ -551,8 +466,8 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
         {
             case STACK_IF_GROUP:
             {
-                OC_LOG_V(INFO, TAG, "IF_COLLECTION POST with request :: \n%s\n ",
-                        ehRequest->reqJSONPayload);
+                OC_LOG(INFO, TAG, PCF("IF_COLLECTION POST with request ::\n"));
+                OC_LOG_PAYLOAD(INFO, TAG, ehRequest->payload);
                 return BuildCollectionGroupActionJSONResponse(OC_REST_POST/*flag*/,
                         (OCResource *) ehRequest->resource, ehRequest);
             }
@@ -565,8 +480,8 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
 
         if(ifQueryParam == STACK_IF_GROUP)
         {
-            OC_LOG_V(INFO, TAG, "IF_COLLECTION POST with request :: \n%s\n ",
-                    ehRequest->reqJSONPayload);
+            OC_LOG(INFO, TAG, PCF("IF_COLLECTION POST with request ::\n"));
+            OC_LOG_PAYLOAD(INFO, TAG, ehRequest->payload);
             return BuildCollectionGroupActionJSONResponse(OC_REST_POST/*flag*/,
                     (OCResource *) ehRequest->resource, ehRequest);
         }
index 6ab5c58..c7d8a7d 100644 (file)
@@ -27,8 +27,8 @@
 #include "ocrandom.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
+#include "ocpayload.h"
 #include "ocserverrequest.h"
-#include "cJSON.h"
 
 #include "utlist.h"
 #include "pdu.h"
 #define VERIFY_NON_NULL(arg) { if (!arg) {OC_LOG(FATAL, TAG, #arg " is NULL"); goto exit;} }
 
 static struct ResourceObserver * serverObsList = NULL;
-#ifdef WITH_PRESENCE
-static char* GetJSONStringForPresence(uint32_t ttl, uint32_t nonce,
-        OCPresenceTrigger trigger, OCResourceType *resourceType)
-{
-    char *jsonEncodedInfo = NULL;
-    const char * triggerStr = NULL;
-
-    cJSON *rootObj = cJSON_CreateObject();
-    VERIFY_NON_NULL (rootObj);
-
-    cJSON_AddItemToObject (rootObj, OC_RSRVD_TTL, cJSON_CreateNumber(ttl));
-
-    cJSON_AddItemToObject (rootObj, OC_RSRVD_NONCE, cJSON_CreateNumber(nonce));
-
-    triggerStr = convertTriggerEnumToString(trigger);
-    cJSON_AddItemToObject (rootObj, OC_RSRVD_TRIGGER, cJSON_CreateString(triggerStr));
-
-    if(resourceType && resourceType->resourcetypename)
-    {
-        cJSON_AddItemToObject (rootObj, OC_RSRVD_RESOURCE_TYPE,
-                cJSON_CreateString(resourceType->resourcetypename));
-    }
-
-    jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
-
-exit:
-    cJSON_Delete(rootObj);
-
-    return jsonEncodedInfo;
-
-}
-
-static OCStackResult BuildPresenceResponse(char *out, uint16_t *remaining,
-        uint32_t ttl, uint32_t nonce, OCPresenceTrigger trigger,
-        OCResourceType *resourceType)
-{
-    if(!out || !remaining)
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    OCStackResult ret = OC_STACK_ERROR;
-    char *jsonStr = NULL;
-    uint16_t jsonLen = 0;
-
-    jsonStr = GetJSONStringForPresence(ttl, nonce, trigger, resourceType);
-
-    if(jsonStr)
-    {
-        jsonLen = strlen(jsonStr);
-
-        if (jsonLen < *remaining)
-        {
-            OICStrcpy(out, *remaining, jsonStr);
-            *remaining = *remaining - jsonLen;
-            ret = OC_STACK_OK;
-        }
-        else
-        {
-            ret = OC_STACK_ERROR;
-        }
-
-        OICFree(jsonStr);
-    }
-    else
-    {
-        OC_LOG(ERROR, TAG, PCF("Error encoding presence payload."));
-        ret = OC_STACK_ERROR;
-    }
-    return ret;
-}
-#endif // WITH_PRESENCE
 /**
  * Determine observe QOS based on the QOS of the request.
  * The qos passed as a parameter overrides what the client requested.
@@ -215,7 +143,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
                     {
                         result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
                                     request->method, (OCResourceHandle) resPtr, request->query,
-                                    request->reqJSONPayload,
+                                    request->payload, request->payloadSize,
                                     request->numRcvdVendorSpecificHeaderOptions,
                                     request->rcvdVendorSpecificHeaderOptions,
                                     OC_OBSERVE_NO_OPTION, 0);
@@ -235,7 +163,6 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
             else
             {
                 OCEntityHandlerResponse ehResponse = {};
-                char presenceResBuf[MAX_RESPONSE_LENGTH] = {};
 
                 //This is effectively the implementation for the presence entity handler.
                 OC_LOG(DEBUG, TAG, PCF("This notification is for Presence"));
@@ -248,17 +175,19 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
 
                 if(result == OC_STACK_OK)
                 {
-                    uint16_t remaining = MAX_RESPONSE_LENGTH;
-                    // create the payload here
-                    result = BuildPresenceResponse(presenceResBuf, &remaining,
-                            maxAge, resPtr->sequenceNum, trigger,
-                            resourceType);
+                    OCPresencePayload* presenceResBuf = OCPresencePayloadCreate(
+                            resPtr->sequenceNum, maxAge, trigger,
+                            resourceType ? resourceType->resourcetypename : NULL);
 
-                    if(result == OC_STACK_OK && remaining < MAX_RESPONSE_LENGTH)
+                    if(!presenceResBuf)
+                    {
+                        return OC_STACK_NO_MEMORY;
+                    }
+
+                    if(result == OC_STACK_OK)
                     {
                         ehResponse.ehResult = OC_EH_OK;
-                        ehResponse.payload = presenceResBuf;
-                        ehResponse.payloadSize = strlen((const char *)presenceResBuf) + 1;
+                        ehResponse.payload = (OCPayload*)presenceResBuf;
                         ehResponse.persistentBufferFlag = 0;
                         ehResponse.requestHandle = (OCRequestHandle) request;
                         ehResponse.resourceHandle = (OCResourceHandle) resPtr;
@@ -266,6 +195,8 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
                                 resourceObserver->resUri);
                         result = OCDoResponse(&ehResponse);
                     }
+
+                    OCPresencePayloadDestroy(presenceResBuf);
                 }
             }
             #endif
@@ -294,10 +225,11 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
 
 OCStackResult SendListObserverNotification (OCResource * resource,
         OCObservationId  *obsIdList, uint8_t numberOfIds,
-        const char *notificationJSONPayload, uint32_t maxAge,
+        const OCRepPayload *payload,
+        uint32_t maxAge,
         OCQualityOfService qos)
 {
-    if(!resource || !obsIdList || !notificationJSONPayload)
+    if(!resource || !obsIdList || !payload)
     {
         return OC_STACK_INVALID_PARAM;
     }
@@ -334,15 +266,13 @@ OCStackResult SendListObserverNotification (OCResource * resource,
                     {
                         OCEntityHandlerResponse ehResponse = {};
                         ehResponse.ehResult = OC_EH_OK;
-                        ehResponse.payload = (char *) OICMalloc(MAX_RESPONSE_LENGTH + 1);
+                        ehResponse.payload = (OCPayload*)OCRepPayloadCreate();
                         if(!ehResponse.payload)
                         {
                             FindAndDeleteServerRequest(request);
                             continue;
                         }
-                        OICStrcpy(ehResponse.payload, MAX_RESPONSE_LENGTH + 1,
-                                notificationJSONPayload);
-                        ehResponse.payloadSize = strlen(ehResponse.payload) + 1;
+                        memcpy(ehResponse.payload, payload, sizeof(*payload));
                         ehResponse.persistentBufferFlag = 0;
                         ehResponse.requestHandle = (OCRequestHandle) request;
                         ehResponse.resourceHandle = (OCResourceHandle) resource;
diff --git a/resource/csdk/stack/src/ocpayload.c b/resource/csdk/stack/src/ocpayload.c
new file mode 100644 (file)
index 0000000..69cab70
--- /dev/null
@@ -0,0 +1,1401 @@
+//******************************************************************
+//
+// 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 "ocpayload.h"
+#include "octypes.h"
+#include <string.h>
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocstackinternal.h"
+#include "ocresource.h"
+#include "logger.h"
+
+#define TAG "OCPayload"
+static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val);
+
+void OCPayloadDestroy(OCPayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    switch(payload->type)
+    {
+        case PAYLOAD_TYPE_REPRESENTATION:
+            OCRepPayloadDestroy((OCRepPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_DISCOVERY:
+            OCDiscoveryPayloadDestroy((OCDiscoveryPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_DEVICE:
+            OCDevicePayloadDestroy((OCDevicePayload*)payload);
+            break;
+        case PAYLOAD_TYPE_PLATFORM:
+            OCPlatformPayloadDestroy((OCPlatformPayload*)payload);
+            break;
+        case PAYLOAD_TYPE_PRESENCE:
+            OCPresencePayloadDestroy((OCPresencePayload*)payload);
+            break;
+        case PAYLOAD_TYPE_SECURITY:
+            OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
+            break;
+        default:
+            OC_LOG_V(ERROR, TAG, "Unsupported payload type in destroy: %d", payload->type);
+            OICFree(payload);
+            break;
+    }
+}
+OCRepPayload* OCRepPayloadCreate()
+{
+    OCRepPayload* payload = (OCRepPayload*)OICCalloc(1, sizeof(OCRepPayload));
+
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_REPRESENTATION;
+
+    return payload;
+}
+
+void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child)
+{
+    if(!parent)
+    {
+        return;
+    }
+
+    while(parent->next)
+    {
+        parent = parent->next;
+    }
+
+    parent->next= child;
+}
+
+static OCRepPayloadValue* OCRepPayloadFindValue(const OCRepPayload* payload, const char* name)
+{
+    if(!payload || !name)
+    {
+        return NULL;
+    }
+
+    OCRepPayloadValue* val = payload->values;
+    while(val)
+    {
+        if(0 == strcmp(val->name, name))
+        {
+            return val;
+        }
+        val = val->next;
+    }
+
+    return NULL;
+
+}
+
+static void OCCopyPropertyValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
+{
+    size_t dimTotal = calcDimTotal(source->arr.dimensions);
+    switch(source->arr.type)
+    {
+        case OCREP_PROP_INT:
+            dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
+            memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
+            break;
+        case OCREP_PROP_DOUBLE:
+            dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
+            memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
+            break;
+        case OCREP_PROP_BOOL:
+            dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
+            memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
+            break;
+        case OCREP_PROP_STRING:
+            dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
+            for(size_t i = 0; i < dimTotal; ++i)
+            {
+                dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
+            }
+            break;
+        case OCREP_PROP_ARRAY:
+            dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+            for(size_t i = 0; i < dimTotal; ++i)
+            {
+                dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
+            }
+            break;
+        default:
+            OC_LOG(ERROR, TAG, PCF("CopyPropertyValueArray invalid type"));
+            break;
+    }
+}
+
+static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
+{
+    if (!source || !dest)
+    {
+        return;
+    }
+
+    switch(source->type)
+    {
+        case OCREP_PROP_STRING:
+            dest->str = OICStrdup(source->str);
+            break;
+        case OCREP_PROP_OBJECT:
+            dest->obj = OCRepPayloadClone(source->obj);
+            break;
+        case OCREP_PROP_ARRAY:
+            OCCopyPropertyValueArray(dest, source);
+            break;
+        default:
+            // Nothing to do for the trivially copyable types.
+            break;
+    }
+}
+
+static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
+{
+    if(!val)
+    {
+        return;
+    }
+
+    if(val->type == OCREP_PROP_STRING)
+    {
+        OICFree(val->str);
+    }
+    else if (val->type == OCREP_PROP_OBJECT)
+    {
+        OCRepPayloadDestroy(val->obj);
+    }
+    else if (val->type == OCREP_PROP_ARRAY)
+    {
+        size_t dimTotal = calcDimTotal(val->arr.dimensions);
+        switch(val->arr.type)
+        {
+            case OCREP_PROP_INT:
+            case OCREP_PROP_DOUBLE:
+            case OCREP_PROP_BOOL:
+                // Since this is a union, iArray will
+                // point to all of the above
+                OICFree(val->arr.iArray);
+                break;
+            case OCREP_PROP_STRING:
+                for(size_t i = 0; i< dimTotal;++i)
+                {
+                    OICFree(val->arr.strArray[i]);
+                }
+                OICFree(val->arr.strArray);
+                break;
+            case OCREP_PROP_OBJECT:
+                for(size_t i = 0; i< dimTotal;++i)
+                {
+                    OCRepPayloadDestroy(val->arr.objArray[i]);
+                }
+                OICFree(val->arr.objArray);
+                break;
+            case OCREP_PROP_NULL:
+            case OCREP_PROP_ARRAY:
+                OC_LOG_V(ERROR, TAG, "FreeRepPayloadValueContents: Illegal type\
+                        inside an array: %d", val->arr.type);
+                break;
+        }
+    }
+}
+
+static void OCFreeRepPayloadValue(OCRepPayloadValue* val)
+{
+    if(!val)
+    {
+        return;
+    }
+
+    OICFree(val->name);
+    OCFreeRepPayloadValueContents(val);
+    OCFreeRepPayloadValue(val->next);
+    OICFree(val);
+}
+static OCRepPayloadValue* OCRepPayloadValueClone (OCRepPayloadValue* source)
+{
+    if (!source)
+    {
+        return NULL;
+    }
+
+    OCRepPayloadValue *sourceIter = source;
+    OCRepPayloadValue *destIter = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
+    if (!destIter)
+    {
+        return NULL;
+    }
+
+    OCRepPayloadValue *headOfClone = destIter;
+
+    // Copy payload type and non pointer types in union.
+    *destIter = *sourceIter;
+    destIter->name = OICStrdup (sourceIter->name);
+    OCCopyPropertyValue (destIter, sourceIter);
+
+    sourceIter = sourceIter->next;
+
+    while (sourceIter)
+    {
+        destIter->next = (OCRepPayloadValue*) OICCalloc(1, sizeof(OCRepPayloadValue));
+        if (!destIter->next)
+        {
+            OCFreeRepPayloadValue (headOfClone);
+            return NULL;
+        }
+
+        *(destIter->next) = *sourceIter;
+        destIter->next->name = OICStrdup (sourceIter->name);
+        OCCopyPropertyValue (destIter->next, sourceIter);
+
+        sourceIter = sourceIter->next;
+        destIter = destIter->next;
+    }
+    return headOfClone;
+}
+
+static OCRepPayloadValue* OCRepPayloadFindAndSetValue(OCRepPayload* payload, const char* name,
+        OCRepPayloadPropType type)
+{
+    if(!payload || !name)
+    {
+        return NULL;
+    }
+
+    OCRepPayloadValue* val = payload->values;
+    if(val == NULL)
+    {
+        payload->values = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
+        payload->values->name = OICStrdup(name);
+        payload->values->type =type;
+        return payload->values;
+    }
+
+    while(val)
+    {
+        if(0 == strcmp(val->name, name))
+        {
+            OCFreeRepPayloadValueContents(val);
+            val->type = type;
+            return val;
+        }
+        else if(val->next == NULL)
+        {
+            val->next = (OCRepPayloadValue*)OICCalloc(1, sizeof(OCRepPayloadValue));
+            val->next->name = OICStrdup(name);
+            val->next->type =type;
+            return val->next;
+        }
+
+        val = val->next;
+    }
+
+    OC_LOG(ERROR, TAG, PCF("FindAndSetValue reached point after while loop, pointer corruption?"));
+    return NULL;
+}
+
+bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType)
+{
+    return OCRepPayloadAddResourceTypeAsOwner(payload, OICStrdup(resourceType));
+}
+
+bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType)
+{
+    if(!payload || !resourceType)
+    {
+        return false;
+    }
+
+    if(payload->types)
+    {
+        OCStringLL* cur = payload->types;
+        while(cur->next)
+        {
+            cur = cur->next;
+        }
+        cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+
+        if(!cur->next)
+        {
+            return false;
+        }
+
+        cur->next->value = resourceType;
+        return true;
+    }
+    else
+    {
+        payload->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+        if(!payload->types)
+        {
+            return false;
+        }
+        payload->types->value = resourceType;
+        return true;
+    }
+}
+
+bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* interface)
+{
+    return OCRepPayloadAddInterfaceAsOwner(payload, OICStrdup(interface));
+}
+
+bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* interface)
+{
+    if(!payload || !interface)
+    {
+        return false;
+    }
+
+    if(payload->interfaces)
+    {
+        OCStringLL* cur = payload->interfaces;
+        while(cur->next)
+        {
+            cur = cur->next;
+        }
+        cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+
+        if(!cur->next)
+        {
+            return false;
+        }
+        cur->next->value = interface;
+        return true;
+    }
+    else
+    {
+        payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+        if(!payload->interfaces)
+        {
+            return false;
+        }
+        payload->interfaces->value = interface;
+        return true;
+    }
+}
+
+bool OCRepPayloadSetUri(OCRepPayload* payload, const char*  uri)
+{
+    if(!payload)
+    {
+        return false;
+    }
+
+    payload->uri = OICStrdup(uri);
+    return payload->uri != NULL;
+}
+
+bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    return val->type == OCREP_PROP_NULL;
+}
+
+bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_NULL);
+    return val != NULL;
+}
+
+bool OCRepPayloadSetPropInt(OCRepPayload* payload,
+        const char* name, int64_t value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_INT);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->i = value;
+    return true;
+}
+
+bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_INT)
+    {
+        return false;
+    }
+
+    *value = val->i;
+    return true;
+}
+
+bool OCRepPayloadSetPropDouble(OCRepPayload* payload,
+        const char* name, double value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_DOUBLE);
+
+    if(!val )
+    {
+        return false;
+    }
+
+    val->d = value;
+    return true;
+}
+
+bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_DOUBLE)
+    {
+        return false;
+    }
+
+    *value = val->d;
+    return true;
+}
+
+bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
+{
+    char* temp = OICStrdup(value);
+    bool b = OCRepPayloadSetPropStringAsOwner(payload, name, temp);
+
+    if(!b)
+    {
+        OICFree(temp);
+    }
+    return b;
+}
+
+bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_STRING);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->str = value;
+    return val->str != NULL;
+}
+
+bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, const char** value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_STRING)
+    {
+        return false;
+    }
+
+    *value = OICStrdup(val->str);
+    return *value != NULL;
+}
+
+bool OCRepPayloadSetPropBool(OCRepPayload* payload,
+        const char* name, bool value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_BOOL);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->b = value;
+    return true;
+}
+
+bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_BOOL)
+    {
+        return false;
+    }
+
+    *value = val->b;
+    return true;
+}
+
+bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value)
+{
+    OCRepPayload* temp = OCRepPayloadClone(value);
+    bool b = OCRepPayloadSetPropObjectAsOwner(payload, name, temp);
+
+    if(!b)
+    {
+        OCRepPayloadDestroy(temp);
+    }
+    return b;
+}
+
+bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_OBJECT);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->obj = value;
+    return true;
+}
+
+bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value)
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_OBJECT)
+    {
+        return false;
+    }
+
+    *value = OCRepPayloadClone(val->obj);
+    return *value != NULL;
+}
+
+size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    if(dimensions[0] == 0)
+    {
+        return 0;
+    }
+
+    size_t total = 1;
+    for(uint8_t i = 0; i < MAX_REP_ARRAY_DEPTH && dimensions[i] != 0; ++i)
+    {
+        total *= dimensions[i];
+    }
+    return total;
+}
+
+bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name,
+        int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->arr.type = OCREP_PROP_INT;
+    memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    val->arr.iArray = array;
+
+    return true;
+}
+
+bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name,
+        const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    size_t dimTotal = calcDimTotal(dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+
+    int64_t* newArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
+
+    if(!newArray)
+    {
+        return false;
+    }
+
+    memcpy(newArray, array, dimTotal * sizeof(int64_t));
+
+
+    bool b = OCRepPayloadSetIntArrayAsOwner(payload, name, newArray, dimensions);
+    if(!b)
+    {
+        OICFree(newArray);
+    }
+    return b;
+}
+
+bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name,
+        int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_INT
+            || !val->arr.iArray)
+    {
+        return false;
+    }
+
+    size_t dimTotal = calcDimTotal(val->arr.dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+    *array = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
+    if(!*array)
+    {
+        return false;
+    }
+
+    memcpy(*array, val->arr.iArray, dimTotal * sizeof(int64_t));
+    memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    return true;
+}
+
+bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name,
+        double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->arr.type = OCREP_PROP_DOUBLE;
+    memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    val->arr.dArray = array;
+
+    return true;
+}
+bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name,
+        const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    size_t dimTotal = calcDimTotal(dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+
+    double* newArray = (double*)OICMalloc(dimTotal * sizeof(double));
+
+    if(!newArray)
+    {
+        return false;
+    }
+
+    memcpy(newArray, array, dimTotal * sizeof(double));
+
+    bool b = OCRepPayloadSetDoubleArrayAsOwner(payload, name, newArray, dimensions);
+    if(!b)
+    {
+        OICFree(newArray);
+    }
+    return b;
+}
+
+bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
+        double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_DOUBLE
+            || !val->arr.dArray)
+    {
+        return false;
+    }
+
+    size_t dimTotal = calcDimTotal(val->arr.dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+    *array = (double*)OICMalloc(dimTotal * sizeof(double));
+    if(!*array)
+    {
+        return false;
+    }
+
+    memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
+    memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    return true;
+}
+
+bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name,
+        char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->arr.type = OCREP_PROP_STRING;
+    memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    val->arr.strArray = array;
+
+    return true;
+}
+bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name,
+        const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    size_t dimTotal = calcDimTotal(dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+
+    char** newArray = (char**)OICMalloc(dimTotal * sizeof(char*));
+
+    if(!newArray)
+    {
+        return false;
+    }
+
+    for(size_t i = 0; i < dimTotal; ++i)
+    {
+        newArray[i] = OICStrdup(array[i]);
+    }
+
+    bool b = OCRepPayloadSetStringArrayAsOwner(payload, name, newArray, dimensions);
+
+    if(!b)
+    {
+        for(size_t i = 0; i < dimTotal; ++i)
+        {
+            OICFree(newArray[i]);
+        }
+        OICFree(newArray);
+    }
+    return b;
+}
+
+bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name,
+        char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_STRING
+            || !val->arr.strArray)
+    {
+        return false;
+    }
+
+    size_t dimTotal = calcDimTotal(val->arr.dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+    *array = (char**)OICMalloc(dimTotal * sizeof(char*));
+    if(!*array)
+    {
+        return false;
+    }
+
+    memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+
+    for(size_t i = 0; i < dimTotal; ++i)
+    {
+        (*array)[i] = OICStrdup(val->arr.strArray[i]);
+    }
+
+    return true;
+
+}
+
+bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name,
+        bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->arr.type = OCREP_PROP_BOOL;
+    memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    val->arr.bArray = array;
+
+    return true;
+}
+bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name,
+        const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    size_t dimTotal = calcDimTotal(dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+
+    bool* newArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
+
+    if(!newArray)
+    {
+        return false;
+    }
+
+    memcpy(newArray, array, dimTotal * sizeof(bool));
+
+
+    bool b = OCRepPayloadSetBoolArrayAsOwner(payload, name, newArray, dimensions);
+    if(!b)
+    {
+        OICFree(newArray);
+    }
+    return b;
+}
+
+bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name,
+        bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_BOOL
+            || !val->arr.bArray)
+    {
+        return false;
+    }
+
+    size_t dimTotal = calcDimTotal(val->arr.dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+    *array = (bool*)OICMalloc(dimTotal * sizeof(bool));
+    if(!*array)
+    {
+        return false;
+    }
+
+    memcpy(*array, val->arr.bArray, dimTotal * sizeof(bool));
+    memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    return true;
+}
+
+bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name,
+        OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindAndSetValue(payload, name, OCREP_PROP_ARRAY);
+
+    if(!val)
+    {
+        return false;
+    }
+
+    val->arr.type = OCREP_PROP_OBJECT;
+    memcpy(val->arr.dimensions, dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+    val->arr.objArray = array;
+
+    return true;
+}
+
+bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name,
+        const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    size_t dimTotal = calcDimTotal(dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+
+    OCRepPayload** newArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+
+    if(!newArray)
+    {
+        return false;
+    }
+
+    for(size_t i = 0; i < dimTotal; ++i)
+    {
+        newArray[i] = OCRepPayloadClone(array[i]);
+    }
+
+    bool b = OCRepPayloadSetPropObjectArrayAsOwner(payload, name, newArray, dimensions);
+
+    if(!b)
+    {
+        for(size_t i = 0; i < dimTotal; ++i)
+        {
+           OCRepPayloadDestroy(newArray[i]);
+        }
+        OICFree(newArray);
+    }
+    return b;
+}
+
+bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name,
+        OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH])
+{
+    OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
+
+    if(!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_OBJECT
+            || !val->arr.objArray)
+    {
+        return false;
+    }
+
+    size_t dimTotal = calcDimTotal(val->arr.dimensions);
+    if(dimTotal == 0)
+    {
+        return false;
+    }
+    *array = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+    if(!*array)
+    {
+        return false;
+    }
+
+    memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
+
+    for(size_t i = 0; i < dimTotal; ++i)
+    {
+        (*array)[i] = OCRepPayloadClone(val->arr.objArray[i]);
+    }
+
+    return true;
+}
+
+void OCFreeOCStringLL(OCStringLL* ll)
+{
+    if(!ll)
+    {
+        return;
+    }
+
+    OCFreeOCStringLL(ll->next);
+    OICFree(ll->value);
+    OICFree(ll);
+}
+
+OCStringLL* CloneOCStringLL (OCStringLL* ll)
+{
+    if (!ll)
+    {
+        return NULL;
+    }
+
+    OCStringLL *sourceIter = ll;
+
+    OCStringLL *destIter = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
+    if (!destIter)
+    {
+        return NULL;
+    }
+    destIter->value = OICStrdup (sourceIter->value);
+
+    OCStringLL *headOfClone = destIter;
+
+    sourceIter = sourceIter->next;
+
+    while (sourceIter)
+    {
+        destIter->next  = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
+        if (!destIter->next)
+        {
+            OCFreeOCStringLL (headOfClone);
+            return NULL;
+        }
+        destIter->next->value = OICStrdup (sourceIter->value);
+
+        destIter = destIter->next;
+        sourceIter = sourceIter->next;
+    }
+    return headOfClone;
+}
+
+OCRepPayload* OCRepPayloadClone (const OCRepPayload* payload)
+{
+    if (!payload)
+    {
+        return NULL;
+    }
+
+    OCRepPayload *clone = OCRepPayloadCreate();
+
+    if (!clone)
+    {
+        return NULL;
+    }
+
+    clone->uri = OICStrdup (payload->uri);
+    clone->types = CloneOCStringLL (payload->types);
+    clone->interfaces = CloneOCStringLL (payload->interfaces);
+    clone->values = OCRepPayloadValueClone (payload->values);
+
+    return clone;
+}
+
+
+void OCRepPayloadDestroy(OCRepPayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    OICFree(payload->uri);
+    OCFreeOCStringLL(payload->types);
+    OCFreeOCStringLL(payload->interfaces);
+    OCFreeRepPayloadValue(payload->values);
+    OCRepPayloadDestroy(payload->next);
+    OICFree(payload);
+}
+
+OCDiscoveryPayload* OCDiscoveryPayloadCreate()
+{
+    OCDiscoveryPayload* payload = (OCDiscoveryPayload*)OICCalloc(1, sizeof(OCDiscoveryPayload));
+
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_DISCOVERY;
+
+    return payload;
+}
+
+OCSecurityPayload* OCSecurityPayloadCreate(char* securityData)
+{
+    OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_SECURITY;
+    payload->securityData = OICStrdup(securityData);
+
+    return payload;
+}
+
+void OCSecurityPayloadDestroy(OCSecurityPayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    OICFree(payload->securityData);
+    OICFree(payload);
+}
+
+size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload)
+{
+    size_t i = 0;
+    OCResourcePayload* p = payload->resources;
+    while(p)
+    {
+        ++i;
+        p = p->next;
+    }
+    return i;
+}
+
+OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index)
+{
+    size_t i = 0;
+    OCResourcePayload* p = payload->resources;
+    while(p)
+    {
+        if(i == index)
+        {
+            return p;
+        }
+        ++i;
+        p = p->next;
+    }
+    return NULL;
+}
+
+static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t port)
+{
+    OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload));
+    if(!pl)
+    {
+        return NULL;
+    }
+
+    pl->uri = OICStrdup(res->uri);
+    pl->sid = (uint8_t*)OICCalloc(1, UUID_SIZE);
+    memcpy(pl->sid, OCGetServerInstanceID(), UUID_SIZE);
+
+    // types
+    OCResourceType* typePtr = res->rsrcType;
+
+    if(typePtr != NULL)
+    {
+        pl->types = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+        pl->types->value = OICStrdup(typePtr->resourcetypename);
+
+        OCStringLL* cur = pl->types;
+        typePtr = typePtr->next;
+        while(typePtr)
+        {
+            cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+            cur->next->value = OICStrdup(typePtr->resourcetypename);
+            cur = cur->next;
+            typePtr = typePtr->next;
+        }
+    }
+
+    // interfaces
+    OCResourceInterface* ifPtr = res->rsrcInterface;
+    if(ifPtr != NULL)
+    {
+        pl->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+        pl->interfaces->value = OICStrdup(ifPtr->name);
+
+        OCStringLL* cur = pl->types;
+        ifPtr = ifPtr->next;
+        while(ifPtr)
+        {
+            cur->next = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+            cur->next->value = OICStrdup(ifPtr->name);
+            cur = cur->next;
+            ifPtr = ifPtr->next;
+        }
+    }
+
+    pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE);
+    pl->secure = (res->resourceProperties & OC_SECURE) != 0;
+    pl->port = port;
+
+    return pl;
+}
+
+void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
+        uint16_t port)
+{
+    OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, port));
+}
+
+void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res)
+{
+    if(!payload->resources)
+    {
+        payload->resources = res;
+    }
+    else
+    {
+        OCResourcePayload* p = payload->resources;
+        while(p->next)
+        {
+            p = p->next;
+        }
+        p->next = res;
+    }
+}
+
+void FreeOCDiscoveryResource(OCResourcePayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    OICFree(payload->uri);
+    OICFree(payload->sid);
+    OCFreeOCStringLL(payload->types);
+    OCFreeOCStringLL(payload->interfaces);
+    FreeOCDiscoveryResource(payload->next);
+    OICFree(payload);
+
+}
+void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    FreeOCDiscoveryResource(payload->resources);
+    OICFree(payload);
+}
+
+OCDevicePayload* OCDevicePayloadCreate(const char* uri, const uint8_t* sid, const char* dname,
+        const char* specVer, const char* dmVer)
+{
+
+    OCDevicePayload* payload = (OCDevicePayload*)OICCalloc(1, sizeof(OCDevicePayload));
+
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_DEVICE;
+
+    payload->uri = OICStrdup(uri);
+    if(uri && !payload->uri)
+    {
+        goto exit;
+    }
+
+    if(sid)
+    {
+        payload->sid = (uint8_t*)OICMalloc(UUID_SIZE);
+        if(!payload->sid)
+        {
+            goto exit;
+        }
+        memcpy(payload->sid, sid, UUID_SIZE);
+    }
+
+    payload->deviceName = OICStrdup(dname);
+    if(dname && !payload->deviceName)
+    {
+        goto exit;
+    }
+
+    payload->specVersion = OICStrdup(specVer);
+    if(specVer && !payload->specVersion)
+    {
+        goto exit;
+    }
+
+    payload->dataModelVersion = OICStrdup(dmVer);
+    if(dmVer && !payload->dataModelVersion)
+    {
+        goto exit;
+    }
+
+    return payload;
+
+exit:
+    OCDevicePayloadDestroy((OCDevicePayload*)payload);
+    return NULL;
+}
+
+void OCDevicePayloadDestroy(OCDevicePayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+
+    OICFree(payload->uri);
+    OICFree(payload->sid);
+    OICFree(payload->deviceName);
+    OICFree(payload->specVersion);
+    OICFree(payload->dataModelVersion);
+    OICFree(payload);
+}
+
+static void OCCopyPlatformInfo(const OCPlatformInfo* platformInfo, OCPlatformPayload* target)
+{
+    target->info.platformID = OICStrdup(platformInfo->platformID);
+    target->info.manufacturerName = OICStrdup(platformInfo->manufacturerName);
+    target->info.manufacturerUrl = OICStrdup(platformInfo->manufacturerUrl);
+    target->info.modelNumber = OICStrdup(platformInfo->modelNumber);
+    target->info.dateOfManufacture = OICStrdup(platformInfo->dateOfManufacture);
+    target->info.platformVersion = OICStrdup(platformInfo->platformVersion);
+    target->info.operatingSystemVersion = OICStrdup(platformInfo->operatingSystemVersion);
+    target->info.hardwareVersion = OICStrdup(platformInfo->hardwareVersion);
+    target->info.firmwareVersion = OICStrdup(platformInfo->firmwareVersion);
+    target->info.supportUrl = OICStrdup(platformInfo->supportUrl);
+    target->info.systemTime = OICStrdup(platformInfo->systemTime);
+}
+
+OCPlatformPayload* OCPlatformPayloadCreateAsOwner(char* uri, OCPlatformInfo* platformInfo)
+{
+    OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_PLATFORM;
+    payload->uri = uri;
+    payload->info = *platformInfo;
+
+    return payload;
+}
+
+OCPlatformPayload* OCPlatformPayloadCreate(const char* uri, const OCPlatformInfo* platformInfo)
+{
+    OCPlatformPayload* payload = (OCPlatformPayload*)OICCalloc(1, sizeof(OCPlatformPayload));
+
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_PLATFORM;
+    payload->uri = OICStrdup(uri);
+    OCCopyPlatformInfo(platformInfo, payload);
+
+    return payload;
+}
+
+void OCPlatformPayloadDestroy(OCPlatformPayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+    OICFree(payload->uri);
+    OICFree(payload->info.platformID);
+    OICFree(payload->info.manufacturerName);
+    OICFree(payload->info.manufacturerUrl);
+    OICFree(payload->info.modelNumber);
+    OICFree(payload->info.dateOfManufacture);
+    OICFree(payload->info.platformVersion);
+    OICFree(payload->info.operatingSystemVersion);
+    OICFree(payload->info.hardwareVersion);
+    OICFree(payload->info.firmwareVersion);
+    OICFree(payload->info.supportUrl);
+    OICFree(payload->info.systemTime);
+    OICFree(payload);
+}
+
+OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
+        OCPresenceTrigger trigger, const char* resourceType)
+{
+    OCPresencePayload* payload = (OCPresencePayload*)OICCalloc(1, sizeof(OCPresencePayload));
+    if(!payload)
+    {
+        return NULL;
+    }
+
+    payload->base.type = PAYLOAD_TYPE_PRESENCE;
+    payload->sequenceNumber = seqNum;
+    payload->maxAge = maxAge;
+    payload->trigger = trigger;
+    payload->resourceType = OICStrdup(resourceType);
+    return payload;
+}
+
+void OCPresencePayloadDestroy(OCPresencePayload* payload)
+{
+    if(!payload)
+    {
+        return;
+    }
+    OICFree(payload->resourceType);
+    OICFree(payload);
+}
diff --git a/resource/csdk/stack/src/ocpayloadconvert.c b/resource/csdk/stack/src/ocpayloadconvert.c
new file mode 100644 (file)
index 0000000..3b6bd02
--- /dev/null
@@ -0,0 +1,760 @@
+//******************************************************************
+//
+// 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 "ocpayloadcbor.h"
+#include <stdlib.h>
+#include "oic_malloc.h"
+#include "logger.h"
+#include "ocpayload.h"
+#include "ocrandom.h"
+#include "ocresourcehandler.h"
+#include "cbor.h"
+
+#define TAG PCF("OCPayloadConvert")
+
+static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t** outPayload,
+        size_t* size);
+static OCStackResult OCConvertDevicePayload(OCDevicePayload* payload, uint8_t** outPayload,
+        size_t* size);
+static OCStackResult OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t** outPayload,
+        size_t* size);
+static OCStackResult OCConvertRepPayload(OCRepPayload* payload, uint8_t** outPayload, size_t* size);
+static OCStackResult OCConvertPresencePayload(OCPresencePayload* payload, uint8_t** outPayload,
+        size_t* size);
+static OCStackResult OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t** outPayload,
+        size_t* size);
+
+bool AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
+        const char* value);
+
+bool ConditionalAddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
+        const char* value);
+
+
+OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t* size)
+{
+    OC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type);
+    switch(payload->type)
+    {
+        case PAYLOAD_TYPE_DISCOVERY:
+            return OCConvertDiscoveryPayload((OCDiscoveryPayload*)payload, outPayload, size);
+        case PAYLOAD_TYPE_DEVICE:
+            return OCConvertDevicePayload((OCDevicePayload*)payload, outPayload, size);
+        case PAYLOAD_TYPE_PLATFORM:
+            return OCConvertPlatformPayload((OCPlatformPayload*)payload, outPayload, size);
+        case PAYLOAD_TYPE_REPRESENTATION:
+            return OCConvertRepPayload((OCRepPayload*)payload, outPayload, size);
+        case PAYLOAD_TYPE_PRESENCE:
+            return OCConvertPresencePayload((OCPresencePayload*)payload, outPayload, size);
+        case PAYLOAD_TYPE_SECURITY:
+            return OCConvertSecurityPayload((OCSecurityPayload*)payload, outPayload, size);
+        default:
+            OC_LOG_V(INFO,TAG, "ConvertPayload default %d", payload->type);
+            return OC_STACK_NOTIMPL;
+    }
+}
+
+static OCStackResult OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t** outPayload,
+        size_t* size)
+{
+    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
+    *size = MAX_REQUEST_LENGTH;
+
+    if(!*outPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    CborEncoder encoder;
+    bool err = false;
+
+    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+
+    CborEncoder rootArray;
+    err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
+    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_SECURITY);
+
+    CborEncoder map;
+
+    err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
+
+    if(payload->securityData)
+    {
+        err = err || AddTextStringToMap(&map, OC_RSRVD_REPRESENTATION,
+                sizeof(OC_RSRVD_REPRESENTATION) - 1,
+                payload->securityData);
+    }
+
+    err = err || cbor_encoder_close_container(&rootArray, &map);
+
+    err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "Convert Security Payload failed", err);
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *size = encoder.ptr - *outPayload;
+    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+
+    if(!tempPayload)
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *outPayload = tempPayload;
+    return OC_STACK_OK;
+}
+
+static OCStackResult OCConvertDiscoveryPayload(OCDiscoveryPayload* payload, uint8_t** outPayload,
+        size_t* size)
+{
+    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
+    *size = MAX_REQUEST_LENGTH;
+
+    if(!*outPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    CborEncoder encoder = {};
+    bool err = false;
+    size_t resourceCount =  OCDiscoveryPayloadGetResourceCount(payload);
+
+    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+
+    CborEncoder rootArray;
+    err = err || cbor_encoder_create_array(&encoder, &rootArray, 1 + resourceCount);
+    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DISCOVERY);
+
+    for(size_t i = 0; i < resourceCount; ++i)
+    {
+        CborEncoder map;
+        OCResourcePayload* resource = OCDiscoveryPayloadGetResource(payload, i);
+        err = err || cbor_encoder_create_map(&rootArray, &map, 3);
+        // Uri
+        err = err || AddTextStringToMap(&map, OC_RSRVD_HREF,
+                sizeof(OC_RSRVD_HREF) - 1,
+                resource->uri);
+
+        // Server ID
+        err = err || cbor_encode_text_string(&map, OC_RSRVD_SERVER_INSTANCE_ID,
+                sizeof(OC_RSRVD_SERVER_INSTANCE_ID) - 1);
+        err = err || cbor_encode_byte_string(&map, resource->sid, UUID_SIZE);
+        // Prop Tag
+        {
+            CborEncoder propMap;
+            err = err || cbor_encode_text_string(&map, OC_RSRVD_PROPERTY,
+                    sizeof(OC_RSRVD_PROPERTY) -1 );
+            err = err || cbor_encoder_create_map(&map, &propMap, 3);
+
+            // Resource Type
+            {
+                CborEncoder rtArray;
+                err = err || cbor_encode_text_string(&propMap, OC_RSRVD_RESOURCE_TYPE,
+                    sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
+                err = err || cbor_encoder_create_array(&propMap, &rtArray, CborIndefiniteLength);
+
+                OCStringLL* rtPtr = resource->types;
+                while(rtPtr)
+                {
+                    err = err || cbor_encode_text_string(&rtArray, rtPtr->value,
+                            strlen(rtPtr->value));
+                    rtPtr = rtPtr->next;
+                }
+
+                err = err || cbor_encoder_close_container(&propMap, &rtArray);
+            }
+
+            // Interface Types
+            {
+                CborEncoder ifArray;
+                err = err || cbor_encode_text_string(&propMap, OC_RSRVD_INTERFACE,
+                        sizeof(OC_RSRVD_INTERFACE) - 1);
+                err = err || cbor_encoder_create_array(&propMap, &ifArray, CborIndefiniteLength);
+                OCStringLL* ifPtr = resource->interfaces;
+
+                while(ifPtr)
+                {
+                    err = err || cbor_encode_text_string(&ifArray, ifPtr->value,
+                        strlen(ifPtr->value));
+                    ifPtr= ifPtr->next;
+                }
+
+                err = err || cbor_encoder_close_container(&propMap, &ifArray);
+            }
+            // Policy
+            {
+                CborEncoder policyMap;
+                err = err || cbor_encode_text_string(&propMap, OC_RSRVD_POLICY,
+                        sizeof(OC_RSRVD_POLICY) - 1);
+                err = err || cbor_encoder_create_map(&propMap, &policyMap, CborIndefiniteLength);
+
+                // Bitmap
+                err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
+                        sizeof(OC_RSRVD_BITMAP) - 1);
+                err = err || cbor_encode_uint(&policyMap, resource->bitmap);
+
+                if(resource->secure)
+                {
+                    err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE,
+                            sizeof(OC_RSRVD_SECURE) - 1);
+                    err = err || cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE);
+
+                    if(resource->port != 0)
+                    {
+                        err = err || cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT,
+                                sizeof(OC_RSRVD_HOSTING_PORT) - 1);
+                        err = err || cbor_encode_uint(&policyMap, resource->port);
+                    }
+                }
+
+                err = err || cbor_encoder_close_container(&propMap, &policyMap);
+            }
+            // Close
+            err = err || cbor_encoder_close_container(&map, &propMap);
+        }
+        // Close Item
+        err = err || cbor_encoder_close_container(&rootArray, &map);
+    }
+    // Close main array
+    err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "Convert Discovery Payload failed with : %d", err);
+        return OC_STACK_ERROR;
+    }
+
+    *size = encoder.ptr - *outPayload;
+    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+
+    if(!tempPayload)
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *outPayload = tempPayload;
+    return OC_STACK_OK;
+}
+
+static OCStackResult OCConvertDevicePayload(OCDevicePayload* payload, uint8_t** outPayload,
+        size_t* size)
+{
+    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
+    *size = MAX_REQUEST_LENGTH;
+
+    if(!*outPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    CborEncoder encoder = {};
+    bool err = false;
+
+    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+    CborEncoder rootArray;
+    err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
+    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_DEVICE);
+
+    {
+        CborEncoder map;
+        err = err || cbor_encoder_create_map(&rootArray, &map, 2);
+
+        // uri
+        err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
+                payload->uri);
+
+        // Rep Map
+        {
+            CborEncoder repMap;
+            err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION,
+                    sizeof(OC_RSRVD_REPRESENTATION) - 1);
+            err = err || cbor_encoder_create_map(&map, &repMap, 4);
+
+            // Device ID
+            err = err || cbor_encode_text_string(&repMap, OC_RSRVD_DEVICE_ID,
+                    sizeof(OC_RSRVD_DEVICE_ID) - 1);
+            err = err || cbor_encode_byte_string(&repMap, payload->sid, UUID_SIZE);
+
+            // Device Name
+            err = err || AddTextStringToMap(&repMap, OC_RSRVD_DEVICE_NAME,
+                    sizeof(OC_RSRVD_DEVICE_NAME) - 1,
+                    payload->deviceName);
+
+            // Device Spec Version
+            err = err || AddTextStringToMap(&repMap, OC_RSRVD_SPEC_VERSION,
+                    sizeof(OC_RSRVD_SPEC_VERSION) - 1,
+                    payload->specVersion);
+
+            // Device data Model Version
+            err = err || AddTextStringToMap(&repMap, OC_RSRVD_DATA_MODEL_VERSION,
+                    sizeof(OC_RSRVD_DATA_MODEL_VERSION) - 1,
+                    payload->dataModelVersion);
+
+            err = err || cbor_encoder_close_container(&map, &repMap);
+        }
+
+        // Close Map
+        err = err || cbor_encoder_close_container(&rootArray, &map);
+    }
+
+    // Close main array
+    err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "Convert Device Payload failed with : %d", err);
+        return OC_STACK_ERROR;
+    }
+
+    *size = encoder.ptr - *outPayload;
+    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+
+    if(!tempPayload)
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *outPayload = tempPayload;
+    return OC_STACK_OK;
+}
+
+static OCStackResult OCConvertPlatformPayload(OCPlatformPayload* payload, uint8_t** outPayload,
+        size_t* size)
+{
+    *outPayload = (uint8_t*)OICCalloc(1, MAX_REQUEST_LENGTH);
+    *size = MAX_REQUEST_LENGTH;
+
+    if(!*outPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    CborEncoder encoder = {};
+    bool err = false;
+
+    cbor_encoder_init(&encoder, *outPayload, *size, 0);
+    CborEncoder rootArray;
+    err = err || cbor_encoder_create_array(&encoder, &rootArray, 2);
+    err = err || cbor_encode_uint(&rootArray, PAYLOAD_TYPE_PLATFORM);
+    {
+        CborEncoder map;
+        err = err || cbor_encoder_create_map(&rootArray, &map, CborIndefiniteLength);
+
+        // uri
+        err = err || AddTextStringToMap(&map, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
+                payload->uri);
+
+        // Rep Map
+        {
+            CborEncoder repMap;
+            err = err || cbor_encode_text_string(&map, OC_RSRVD_REPRESENTATION,
+                    sizeof(OC_RSRVD_REPRESENTATION) - 1);
+            err = err || cbor_encoder_create_map(&map, &repMap, CborIndefiniteLength);
+
+            // Platform ID
+            err = err || AddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_ID,
+                    sizeof(OC_RSRVD_PLATFORM_ID) - 1,
+                    payload->info.platformID);
+
+            // MFG Name
+            err = err || AddTextStringToMap(&repMap, OC_RSRVD_MFG_NAME,
+                    sizeof(OC_RSRVD_MFG_NAME) - 1,
+                    payload->info.manufacturerName);
+
+            // MFG Url
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_URL,
+                    sizeof(OC_RSRVD_MFG_URL) - 1,
+                    payload->info.manufacturerUrl);
+
+            // Model Num
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MODEL_NUM,
+                    sizeof(OC_RSRVD_MODEL_NUM) - 1,
+                    payload->info.modelNumber);
+
+            // Date of Mfg
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_MFG_DATE,
+                    sizeof(OC_RSRVD_MFG_DATE) - 1,
+                    payload->info.dateOfManufacture);
+
+            // Platform Version
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_PLATFORM_VERSION,
+                    sizeof(OC_RSRVD_PLATFORM_VERSION) - 1,
+                    payload->info.platformVersion);
+
+            // OS Version
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_OS_VERSION,
+                    sizeof(OC_RSRVD_OS_VERSION) - 1,
+                    payload->info.operatingSystemVersion);
+
+            // Hardware Version
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_HARDWARE_VERSION,
+                    sizeof(OC_RSRVD_HARDWARE_VERSION) - 1,
+                    payload->info.hardwareVersion);
+
+            // Firmware Version
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_FIRMWARE_VERSION,
+                    sizeof(OC_RSRVD_FIRMWARE_VERSION) - 1,
+                    payload->info.firmwareVersion);
+
+            // Support URL
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SUPPORT_URL,
+                    sizeof(OC_RSRVD_SUPPORT_URL) - 1,
+                    payload->info.supportUrl);
+
+            // System Time
+            err = err || ConditionalAddTextStringToMap(&repMap, OC_RSRVD_SYSTEM_TIME,
+                    sizeof(OC_RSRVD_SYSTEM_TIME) - 1,
+                    payload->info.systemTime);
+            err = err || cbor_encoder_close_container(&map, &repMap);
+        }
+
+        // Close Map
+        err = err || cbor_encoder_close_container(&rootArray, &map);
+    }
+
+    // Close main array
+    err = err || cbor_encoder_close_container(&encoder, &rootArray);
+
+    if(err)
+    {
+        OC_LOG_V(ERROR, TAG, "Convert Platform Payload failed with : %d", err);
+        return OC_STACK_ERROR;
+    }
+
+    *size = encoder.ptr - *outPayload;
+    uint8_t* tempPayload = (uint8_t*)OICRealloc(*outPayload, *size);
+
+    if(!tempPayload)
+    {
+        OC_LOG_V(ERROR, TAG, PCF("Payload realloc failed!"));
+        OICFree(*outPayload);
+        return OC_STACK_ERROR;
+    }
+
+    *outPayload = tempPayload;
+
+    return OC_STACK_OK;
+}
+
+static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload);
+
+static bool OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray* valArray)
+{
+    CborEncoder array;
+    bool err = false;
+
+    err = err || cbor_encoder_create_array(parent, &array, CborIndefiniteLength);
+    err = err || cbor_encode_uint(&array, valArray->type);
+    for(int i = 0; i < MAX_REP_ARRAY_DEPTH; ++i)
+    {
+        err = err || cbor_encode_uint(&array, valArray->dimensions[i]);
+    }
+
+    size_t dimTotal = calcDimTotal(valArray->dimensions);
+
+    for(size_t i = 0; i < dimTotal; ++i)
+    {
+        switch(valArray->type)
+        {
+            case OCREP_PROP_NULL:
+                OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid NULL"));
+                err = CborUnknownError;
+                break;
+            case OCREP_PROP_INT:
+                err = err || cbor_encode_int(&array, valArray->iArray[i]);
+                break;
+            case OCREP_PROP_DOUBLE:
+                err = err || cbor_encode_double(&array, valArray->dArray[i]);
+                break;
+            case OCREP_PROP_BOOL:
+                err = err || cbor_encode_boolean(&array, valArray->bArray[i]);
+                break;
+            case OCREP_PROP_STRING:
+                err = err || cbor_encode_text_string(&array, valArray->strArray[i],
+                        strlen(valArray->strArray[i]));
+                break;
+            case OCREP_PROP_OBJECT:
+                err = OCConvertSingleRepPayload(&array, valArray->objArray[i]);
+                break;
+            case OCREP_PROP_ARRAY:
+                OC_LOG(ERROR, TAG, PCF("ConvertArray Invalid child array"));
+                err = CborUnknownError;
+                break;
+        }
+    }
+
+    err = err || cbor_encoder_close_container(parent, &array);
+    return err;
+}
+
+static bool OCConvertSingleRepPayload(CborEncoder* parent, const OCRepPayload* payload)
+{
+    bool err = false;
+    CborEncoder map;
+    err = err || cbor_encoder_create_map(parent, &map, CborIndefiniteLength);
+
+    // Uri
+    err = err || ConditionalAddTextStringToMap(&map, OC_RSRVD_HREF,
+            sizeof(OC_RSRVD_HREF) - 1,
+            payload->uri);
+
+    // Prop Map
+    // resource types, interfaces
+    if(payload->types || payload->interfaces)
+    {
+        OC_LOG_V(INFO, TAG, "Payload has types or interfaces");
+        err = err || cbor_encode_text_string(&map,
+                OC_RSRVD_PROPERTY,
+                sizeof(OC_RSRVD_PROPERTY) - 1);
+        CborEncoder propMap;<